Unverified Commit 4af124d3 authored by David Disu's avatar David Disu Committed by GitHub

Merge pull request #1104 from ethereum/refactoring-static-analyser

refactor: static analyser plugin from yo-yo to react
parents b7b54a72 bb2ca8fe
......@@ -40,7 +40,7 @@ function runTests (browser: NightwatchBrowser) {
.pause(10000)
.testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2'])
.clickLaunchIcon('solidityStaticAnalysis')
.click('#staticanalysisView button')
.click('#staticanalysisButton button')
.waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () {
listSelectorContains(['Use of tx.origin',
'Fallback function of contract TooMuchGas requires too much gas',
......
import React from 'react' // eslint-disable-line
import { ViewPlugin } from '@remixproject/engine-web'
import ReactDOM from 'react-dom'
import { EventEmitter } from 'events'
import {RemixUiStaticAnalyser} from '@remix-ui/static-analyser' // eslint-disable-line
import * as packageJson from '../../../../../package.json'
var Renderer = require('../ui/renderer')
var yo = require('yo-yo')
var StaticAnalysis = require('./staticanalysis/staticAnalysisView')
var EventManager = require('../../lib/events')
const profile = {
......@@ -25,23 +27,49 @@ class AnalysisTab extends ViewPlugin {
this.event = new EventManager()
this.events = new EventEmitter()
this.registry = registry
this.element = document.createElement('div')
this.element.setAttribute('id', 'staticAnalyserView')
this._components = {
renderer: new Renderer(this)
}
this._components.registry = this.registry
this._deps = {
offsetToLineColumnConverter: this.registry.get(
'offsettolinecolumnconverter').api
}
}
onActivation () {
this.renderComponent()
}
render () {
this.staticanalysis = new StaticAnalysis(this.registry, this)
this.staticanalysis.event.register('staticAnaysisWarning', (count) => {
if (count > 0) {
this.emit('statusChanged', { key: count, title: `${count} warning${count === 1 ? '' : 's'}`, type: 'warning' })
} else if (count === 0) {
this.emit('statusChanged', { key: 'succeed', title: 'no warning', type: 'success' })
} else {
// count ==-1 no compilation result
this.emit('statusChanged', { key: 'none' })
}
})
this.registry.put({ api: this.staticanalysis, name: 'staticanalysis' })
return this.element
}
return yo`<div class="px-3 pb-1" id="staticanalysisView">${this.staticanalysis.render()}</div>`
renderComponent () {
ReactDOM.render(
<RemixUiStaticAnalyser
analysisRunner={this.runner}
registry={this.registry}
staticanalysis={this.staticanalysis}
analysisModule={this}
event={this.event}
/>,
this.element,
() => {
this.event.register('staticAnaysisWarning', (count) => {
if (count > 0) {
this.emit('statusChanged', { key: count, title: `${count} warning${count === 1 ? '' : 's'}`, type: 'warning' })
} else if (count === 0) {
this.emit('statusChanged', { key: 'succeed', title: 'no warning', type: 'success' })
} else {
// count ==-1 no compilation result
this.emit('statusChanged', { key: 'none' })
}
})
}
)
}
}
......
var csjs = require('csjs-inject')
var css = csjs`
.analysis {
display: flex;
flex-direction: column;
}
.result {
margin-top: 1%;
max-height: 300px;
word-break: break-word;
}
.buttons {
margin: 1rem 0;
}
.label {
display: flex;
align-items: center;
}
.label {
display: flex;
align-items: center;
user-select: none;
}
.block input[type='radio']:checked ~ .entries{
height: auto;
transition: .5s ease-in;
}
.entries{
height: 0;
overflow: hidden;
transition: .5s ease-out;
}
`
module.exports = css
{
"presets": ["@nrwl/react/babel"],
"plugins": []
}
{
"env": {
"browser": true,
"es6": true
},
"extends": "../../../.eslintrc",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 11,
"sourceType": "module"
},
"rules": {
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": "error"
}
}
# remix-ui-checkbox
This library was generated with [Nx](https://nx.dev).
## Running unit tests
Run `nx test remix-ui-checkbox` to execute the unit tests via [Jest](https://jestjs.io).
export * from './lib/remix-ui-checkbox'
import React from 'react' //eslint-disable-line
import './remix-ui-checkbox.css'
/* eslint-disable-next-line */
export interface RemixUiCheckboxProps {
onClick?: (event) => void
onChange?: (event) => void
label?: string
inputType?: string
name?: string
checked?: boolean
id?: string
itemName?: string
categoryId?: string
}
export const RemixUiCheckbox = ({
id,
label,
onClick,
inputType,
name,
checked,
onChange,
itemName,
categoryId
}: RemixUiCheckboxProps) => {
return (
<div className="listenOnNetwork_2A0YE0 custom-control custom-checkbox" style={{ display: 'flex', alignItems: 'center' }} onClick={onClick}>
<input
id={id}
type={inputType}
onChange={onChange}
style={{ verticalAlign: 'bottom' }}
name={name}
className="custom-control-input"
checked={checked}
/>
<label className="form-check-label custom-control-label" id={`heading${categoryId}`} style={{ paddingTop: '0.15rem' }}>
{name ? <div className="font-weight-bold">{itemName}</div> : ''}
{label}
</label>
</div>
)
}
export default RemixUiCheckbox
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"jsx": "react",
"allowJs": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
}
]
}
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../dist/out-tsc",
"types": ["node"]
},
"files": [
"../../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../../node_modules/@nrwl/react/typings/image.d.ts"
],
"exclude": ["**/*.spec.ts", "**/*.spec.tsx"],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}
{
"presets": ["@nrwl/react/babel"],
"plugins": []
}
{
"env": {
"browser": true,
"es6": true
},
"extends": "../../../.eslintrc",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 11,
"sourceType": "module"
},
"rules": {
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": "error"
}
}
# remix-ui-static-analyser
This library was generated with [Nx](https://nx.dev).
## Running unit tests
Run `nx test remix-ui-static-analyser` to execute the unit tests via [Jest](https://jestjs.io).
export * from './lib/remix-ui-static-analyser'
import React from 'react' //eslint-disable-line
interface StaticAnalyserButtonProps {
onClick: (event) => void
buttonText: string,
disabled?: boolean
}
const StaticAnalyserButton = ({
onClick,
buttonText,
disabled
}: StaticAnalyserButtonProps) => {
return (
<button className="btn btn-sm w-25 btn-primary" onClick={onClick} disabled={disabled}>
{buttonText}
</button>
)
}
export default StaticAnalyserButton
import React from 'react' //eslint-disable-line
interface ErrorRendererProps {
message: any;
opt: any,
warningErrors: any
editor: any
}
const ErrorRenderer = ({ message, opt, editor }: ErrorRendererProps) => {
const getPositionDetails = (msg: any) => {
const result = { } as Record<string, number | string>
// To handle some compiler warning without location like SPDX license warning etc
if (!msg.includes(':')) return { errLine: -1, errCol: -1, errFile: msg }
// extract line / column
let position = msg.match(/^(.*?):([0-9]*?):([0-9]*?)?/)
result.errLine = position ? parseInt(position[2]) - 1 : -1
result.errCol = position ? parseInt(position[3]) : -1
// extract file
position = msg.match(/^(https:.*?|http:.*?|.*?):/)
result.errFile = position ? position[1] : ''
return result
}
const handlePointToErrorOnClick = (location, fileName) => {
editor.call('editor', 'discardHighlight')
editor.call('editor', 'highlight', location, fileName)
}
if (!message) return
let position = getPositionDetails(message)
if (!position.errFile || (opt.errorType && opt.errorType === position.errFile)) {
// Updated error reported includes '-->' before file details
const errorDetails = message.split('-->')
// errorDetails[1] will have file details
if (errorDetails.length > 1) position = getPositionDetails(errorDetails[1])
}
opt.errLine = position.errLine
opt.errCol = position.errCol
opt.errFile = position.errFile.trim()
const classList = opt.type === 'error' ? 'alert alert-danger' : 'alert alert-warning'
return (
<div>
<div className={`sol ${opt.type} ${classList}`}>
<div className="close" data-id="renderer">
<i className="fas fa-times"></i>
</div>
<span className='d-flex flex-column' onClick={() => handlePointToErrorOnClick(opt.location, opt.fileName)}>
<span className='h6 font-weight-bold'>{opt.name}</span>
{ opt.item.warning }
{opt.item.more
? <span><a href={opt.item.more} target='_blank'>more</a></span>
: <span> </span>
}
<span title={`Position in ${opt.errFile}`}>Pos: {opt.locationString}</span>
</span>
</div>
</div>
)
}
export default ErrorRenderer
import React from 'react' //eslint-disable-line
export const compilation = (analysisModule, dispatch) => {
if (analysisModule) {
analysisModule.on(
'solidity',
'compilationFinished',
(file, source, languageVersion, data) => {
if (languageVersion.indexOf('soljson') !== 0) return
dispatch({ type: 'compilationFinished', payload: { file, source, languageVersion, data } })
}
)
}
}
export const initialState = {
file: null,
source: null,
languageVersion: null,
data: null
}
export const analysisReducer = (state, action) => {
switch (action.type) {
case 'compilationFinished':
return {
...state,
file: action.payload.file,
source: action.payload.source,
languageVersion: action.payload.languageVersion,
data: action.payload.data
}
default:
return initialState
}
}
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"jsx": "react",
"allowJs": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
}
]
}
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../dist/out-tsc",
"types": ["node"]
},
"files": [
"../../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../../node_modules/@nrwl/react/typings/image.d.ts"
],
"exclude": ["**/*.spec.ts", "**/*.spec.tsx"],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}
......@@ -95,6 +95,12 @@
},
"remix-ui-workspace": {
"tags": []
},
"remix-ui-static-analyser": {
"tags": []
},
"remix-ui-checkbox": {
"tags": []
}
}
}
......@@ -41,7 +41,7 @@
"workspace-schematic": "nx workspace-schematic",
"dep-graph": "nx dep-graph",
"help": "nx help",
"lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui,remix-ui-workspace",
"lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox",
"build:libs": "nx run-many --target=build --parallel=false --with-deps=true --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd",
"test:libs": "nx run-many --target=test --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd",
"publish:libs": "npm run build:libs & lerna publish --skip-git & npm run bumpVersion:libs",
......@@ -159,6 +159,7 @@
"isbinaryfile": "^3.0.2",
"jquery": "^3.3.1",
"jszip": "^3.6.0",
"lodash": "^4.17.21",
"latest-version": "^5.1.0",
"lodash": "^4.17.21",
"merge": "^1.2.0",
......
......@@ -11,7 +11,7 @@
"target": "es2015",
"module": "commonjs",
"typeRoots": ["node_modules/@types"],
"lib": ["es2017", "dom"],
"lib": ["es2017", "es2019", "dom"],
"skipLibCheck": true,
"skipDefaultLibCheck": true,
"baseUrl": ".",
......@@ -38,7 +38,9 @@
"@remix-ui/modal-dialog": ["libs/remix-ui/modal-dialog/src/index.ts"],
"@remix-ui/toaster": ["libs/remix-ui/toaster/src/index.ts"],
"@remix-ui/file-explorer": ["libs/remix-ui/file-explorer/src/index.ts"],
"@remix-ui/workspace": ["libs/remix-ui/workspace/src/index.ts"]
"@remix-ui/workspace": ["libs/remix-ui/workspace/src/index.ts"],
"@remix-ui/static-analyser": ["libs/remix-ui/static-analyser/src/index.ts"],
"@remix-ui/checkbox": ["libs/remix-ui/checkbox/src/index.ts"]
}
},
"exclude": ["node_modules", "tmp"]
......
......@@ -725,6 +725,41 @@
}
}
}
},
"remix-ui-static-analyser": {
"root": "libs/remix-ui/static-analyser",
"sourceRoot": "libs/remix-ui/static-analyser/src",
"projectType": "library",
"schematics": {},
"architect": {
"lint": {
"builder": "@nrwl/linter:lint",
"options": {
"linter": "eslint",
"tsConfig": ["libs/remix-ui/static-analyser/tsconfig.lib.json"],
"exclude": [
"**/node_modules/**",
"!libs/remix-ui/static-analyser/**/*"
]
}
}
}
},
"remix-ui-checkbox": {
"root": "libs/remix-ui/checkbox",
"sourceRoot": "libs/remix-ui/checkbox/src",
"projectType": "library",
"schematics": {},
"architect": {
"lint": {
"builder": "@nrwl/linter:lint",
"options": {
"linter": "eslint",
"tsConfig": ["libs/remix-ui/checkbox/tsconfig.lib.json"],
"exclude": ["**/node_modules/**", "!libs/remix-ui/checkbox/**/*"]
}
}
}
}
},
"cli": {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment