suggested changes done

pull/7/head
aniket-engg 5 years ago committed by Aniket
parent aee19d3056
commit 755ee4af94
  1. 19
      remix-analyzer/src/solidity-analyzer/index.ts
  2. 75
      remix-analyzer/src/solidity-analyzer/modules/abstractAstView.ts
  3. 2
      remix-analyzer/src/solidity-analyzer/modules/assignAndCompare.ts
  4. 2
      remix-analyzer/src/solidity-analyzer/modules/gasCosts.ts
  5. 2
      remix-analyzer/src/solidity-analyzer/modules/similarVariableNames.ts
  6. 44
      remix-analyzer/tsconfig.json

@ -10,7 +10,13 @@ type ModuleObj = {
export default class staticAnalysisRunner {
run (compilationResult: CompilationResult, toRun: any[], callback: ((reports: AnalysisReport[]) => void)): void {
/**
* Run analysis (Used by IDE)
* @param compilationResult contract compilation result
* @param toRun module indexes (compiled from remix IDE)
* @param callback callback
*/
run (compilationResult: CompilationResult, toRun: number[], callback: ((reports: AnalysisReport[]) => void)): void {
const modules: ModuleObj[] = toRun.map((i) => {
const m: AnalyzerModule = this.modules()[i]
return { 'name': m.name, 'mod': m }
@ -18,10 +24,16 @@ export default class staticAnalysisRunner {
this.runWithModuleList(compilationResult, modules, callback)
}
/**
* Run analysis passing list of modules to run
* @param compilationResult contract compilation result
* @param modules analysis module
* @param callback callback
*/
runWithModuleList (compilationResult: CompilationResult, modules: ModuleObj[], callback: ((reports: AnalysisReport[]) => void)): void {
let reports: AnalysisReport[] = []
// Also provide convenience analysis via the AST walker.
const walker: AstWalker = new AstWalker()
const walker = new AstWalker()
for (let k in compilationResult.sources) {
walker.walkFull(compilationResult.sources[k].ast,
(node: any) => {
@ -55,6 +67,9 @@ export default class staticAnalysisRunner {
callback(reports)
}
/**
* Get list of all analysis modules
*/
modules (): any[] {
return list
}

@ -1,7 +1,8 @@
import { getStateVariableDeclarationsFromContractNode, getInheritsFromName, getContractName,
getFunctionOrModifierDefinitionParameterPart, getType, getDeclaredVariableName, getFunctionDefinitionReturnParameterPart } from './staticAnalysisCommon'
import { AstWalker } from 'remix-astwalker'
import { FunctionDefinitionAstNode, ParameterListAstNode, ModifierDefinitionAstNode, ContractHLAst, VariableDeclarationAstNode, FunctionHLAst, ContractDefinitionAstNode, ReportObj, ReportFunction, VisitFunction, ModifierHLAst, CompilationResult } from 'types'
import { FunctionDefinitionAstNode, ParameterListAstNode, ModifierDefinitionAstNode, ContractHLAst, VariableDeclarationAstNode,
FunctionHLAst, ReportObj, ReportFunction, VisitFunction, ModifierHLAst, CompilationResult } from 'types'
type WrapFunction = ((contracts: ContractHLAst[], isSameName: boolean) => ReportObj[])
@ -47,10 +48,9 @@ export default class abstractAstView {
* @return {ASTNode -> void} returns a function that can be used as visit function for static analysis modules, to build up a higher level AST view for further analysis.
*/
build_visit (relevantNodeFilter: ((node:any) => boolean)): VisitFunction {
const that: abstractAstView = this
return function (node: any) {
return (node: any) => {
if (node.nodeType === "ContractDefinition") {
that.setCurrentContract(that, {
this.setCurrentContract({
node: node,
functions: [],
relevantNodes: [],
@ -59,40 +59,40 @@ export default class abstractAstView {
stateVariables: getStateVariableDeclarationsFromContractNode(node)
})
} else if (node.nodeType === "InheritanceSpecifier") {
const currentContract: ContractHLAst = that.getCurrentContract(that)
const currentContract: ContractHLAst = this.getCurrentContract()
const inheritsFromName: string = getInheritsFromName(node)
currentContract.inheritsFrom.push(inheritsFromName)
} else if (node.nodeType === "FunctionDefinition") {
that.setCurrentFunction(that, {
this.setCurrentFunction({
node: node,
relevantNodes: [],
modifierInvocations: [],
localVariables: that.getLocalVariables(node),
parameters: that.getLocalParameters(node),
returns: that.getReturnParameters(node)
localVariables: this.getLocalVariables(node),
parameters: this.getLocalParameters(node),
returns: this.getReturnParameters(node)
})
// push back relevant nodes to their the current fn if any
that.getCurrentContract(that).relevantNodes.map((item) => {
this.getCurrentContract().relevantNodes.map((item) => {
if (item.referencedDeclaration === node.id) {
that.getCurrentFunction(that).relevantNodes.push(item.node)
this.getCurrentFunction().relevantNodes.push(item.node)
}
})
} else if (node.nodeType === "ModifierDefinition") {
that.setCurrentModifier(that, {
this.setCurrentModifier({
node: node,
relevantNodes: [],
localVariables: that.getLocalVariables(node),
parameters: that.getLocalParameters(node)
localVariables: this.getLocalVariables(node),
parameters: this.getLocalParameters(node)
})
} else if (node.nodeType === "ModifierInvocation") {
if (!that.isFunctionNotModifier) throw new Error('abstractAstView.js: Found modifier invocation outside of function scope.')
that.getCurrentFunction(that).modifierInvocations.push(node)
if (!this.isFunctionNotModifier) throw new Error('abstractAstView.js: Found modifier invocation outside of function scope.')
this.getCurrentFunction().modifierInvocations.push(node)
} else if (relevantNodeFilter(node)) {
let scope: FunctionHLAst | ModifierHLAst | ContractHLAst = (that.isFunctionNotModifier) ? that.getCurrentFunction(that) : that.getCurrentModifier(that)
let scope: FunctionHLAst | ModifierHLAst | ContractHLAst = (this.isFunctionNotModifier) ? this.getCurrentFunction() : this.getCurrentModifier()
if (scope) {
scope.relevantNodes.push(node)
} else {
scope = that.getCurrentContract(that) // if we are not in a function scope, add the node to the contract scope
scope = this.getCurrentContract() // if we are not in a function scope, add the node to the contract scope
if (scope && node.referencedDeclaration) {
scope.relevantNodes.push({ referencedDeclaration: node.referencedDeclaration, node: node })
}
@ -102,10 +102,9 @@ export default class abstractAstView {
}
build_report (wrap: WrapFunction): ReportFunction {
const that: abstractAstView = this
return function (compilationResult: CompilationResult) {
that.resolveStateVariablesInHierarchy(that.contracts)
return wrap(that.contracts, that.multipleContractsWithSameName)
return (compilationResult: CompilationResult) => {
this.resolveStateVariablesInHierarchy(this.contracts)
return wrap(this.contracts, this.multipleContractsWithSameName)
}
}
@ -127,35 +126,35 @@ export default class abstractAstView {
})
}
private setCurrentContract (that: abstractAstView, contract: ContractHLAst): void {
private setCurrentContract (contract: ContractHLAst): void {
const name: string = getContractName(contract.node)
if (that.contracts.map((c: ContractHLAst) => getContractName(c.node)).filter((n) => n === name).length > 0) {
if (this.contracts.map((c: ContractHLAst) => getContractName(c.node)).filter((n) => n === name).length > 0) {
console.log('abstractAstView.js: two or more contracts with the same name dectected, import aliases not supported at the moment')
that.multipleContractsWithSameName = true
this.multipleContractsWithSameName = true
}
that.currentContractIndex = (that.contracts.push(contract) - 1)
this.currentContractIndex = (this.contracts.push(contract) - 1)
}
private setCurrentFunction (that: abstractAstView, func: FunctionHLAst): void {
that.isFunctionNotModifier = true
that.currentFunctionIndex = (that.getCurrentContract(that).functions.push(func) - 1)
private setCurrentFunction (func: FunctionHLAst): void {
this.isFunctionNotModifier = true
this.currentFunctionIndex = (this.getCurrentContract().functions.push(func) - 1)
}
private setCurrentModifier (that, modi): void {
that.isFunctionNotModifier = false
that.currentModifierIndex = (that.getCurrentContract(that).modifiers.push(modi) - 1)
private setCurrentModifier (modi): void {
this.isFunctionNotModifier = false
this.currentModifierIndex = (this.getCurrentContract().modifiers.push(modi) - 1)
}
private getCurrentContract (that: abstractAstView): ContractHLAst {
return that.contracts[that.currentContractIndex]
private getCurrentContract (): ContractHLAst {
return this.contracts[this.currentContractIndex]
}
private getCurrentFunction (that: abstractAstView): FunctionHLAst {
return that.getCurrentContract(that).functions[that.currentFunctionIndex]
private getCurrentFunction (): FunctionHLAst {
return this.getCurrentContract().functions[this.currentFunctionIndex]
}
private getCurrentModifier (that:abstractAstView): ModifierHLAst {
return that.getCurrentContract(that).modifiers[that.currentModifierIndex]
private getCurrentModifier (): ModifierHLAst {
return this.getCurrentContract().modifiers[this.currentModifierIndex]
}
private getLocalParameters (funcNode: FunctionDefinitionAstNode | ModifierDefinitionAstNode): string[] {

@ -12,7 +12,7 @@ export default class assignAndCompare implements AnalyzerModule {
algorithm: ModuleAlgorithm = algorithm.EXACT
visit (node: BlockAstNode | IfStatementAstNode | WhileStatementAstNode | ForStatementAstNode): void {
if (node && node.nodeType && isSubScopeWithTopLevelUnAssignedBinOp(node)) getUnAssignedTopLevelBinOps(node).forEach((n) => this.warningNodes.push(n))
if (node?.nodeType && isSubScopeWithTopLevelUnAssignedBinOp(node)) getUnAssignedTopLevelBinOps(node).forEach((n) => this.warningNodes.push(n))
}
report (compilationResults: CompilationResult): ReportObj[] {

@ -3,7 +3,7 @@ import { default as algorithm } from './algorithmCategories'
import AbstractAst from './abstractAstView'
import { ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, CompiledContractObj, CompiledContract, VisitFunction, AnalyzerModule} from './../../types'
type VisitedContract = {
interface VisitedContract {
name: string
object: CompiledContract
file: string

@ -6,7 +6,7 @@ import { get } from 'fast-levenshtein'
import { util } from 'remix-lib'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, ContractHLAst, FunctionHLAst, VariableDeclarationAstNode, VisitFunction, ReportFunction} from './../../types'
type SimilarRecord = {
interface SimilarRecord {
var1: string
var2: string
distance: number

@ -1,25 +1,25 @@
{
"include": ["src", "index.ts"],
"compilerOptions": {
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"lib": ["dom", "es2018"], /* Specify library files to be included in the compilation. */
"declaration": true, /* Generates corresponding '.d.ts' file. */
"sourceMap": true, /* Generates corresponding '.map' file. */
"outDir": "./dist", /* Redirect output structure to the directory. */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": false, /* Raise error on expressions and declarations with an implied 'any' type. */
/* Module Resolution Options */
"baseUrl": "./src", /* Base directory to resolve non-absolute module names. */
"paths": { "remix-analyzer": ["./"] }, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
"typeRoots": [
"./@types",
"./node_modules/@types"
],
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
/* Experimental Options */
"experimentalDecorators": false, /* Enables experimental support for ES7 decorators. */
}
"include": ["src", "index.ts"],
"compilerOptions": {
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"lib": ["dom", "es2018"], /* Specify library files to be included in the compilation. */
"declaration": true, /* Generates corresponding '.d.ts' file. */
"sourceMap": true, /* Generates corresponding '.map' file. */
"outDir": "./dist", /* Redirect output structure to the directory. */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": false, /* Raise error on expressions and declarations with an implied 'any' type. */
/* Module Resolution Options */
"baseUrl": "./src", /* Base directory to resolve non-absolute module names. */
"paths": { "remix-analyzer": ["./"] }, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
"typeRoots": [
"./@types",
"./node_modules/@types"
],
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
/* Experimental Options */
"experimentalDecorators": false, /* Enables experimental support for ES7 decorators. */
}
}

Loading…
Cancel
Save