Commit 755ee4af authored by aniket-engg's avatar aniket-engg Committed by Aniket

suggested changes done

parent aee19d30
...@@ -10,7 +10,13 @@ type ModuleObj = { ...@@ -10,7 +10,13 @@ type ModuleObj = {
export default class staticAnalysisRunner { 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 modules: ModuleObj[] = toRun.map((i) => {
const m: AnalyzerModule = this.modules()[i] const m: AnalyzerModule = this.modules()[i]
return { 'name': m.name, 'mod': m } return { 'name': m.name, 'mod': m }
...@@ -18,10 +24,16 @@ export default class staticAnalysisRunner { ...@@ -18,10 +24,16 @@ export default class staticAnalysisRunner {
this.runWithModuleList(compilationResult, modules, callback) 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 { runWithModuleList (compilationResult: CompilationResult, modules: ModuleObj[], callback: ((reports: AnalysisReport[]) => void)): void {
let reports: AnalysisReport[] = [] let reports: AnalysisReport[] = []
// Also provide convenience analysis via the AST walker. // Also provide convenience analysis via the AST walker.
const walker: AstWalker = new AstWalker() const walker = new AstWalker()
for (let k in compilationResult.sources) { for (let k in compilationResult.sources) {
walker.walkFull(compilationResult.sources[k].ast, walker.walkFull(compilationResult.sources[k].ast,
(node: any) => { (node: any) => {
...@@ -55,6 +67,9 @@ export default class staticAnalysisRunner { ...@@ -55,6 +67,9 @@ export default class staticAnalysisRunner {
callback(reports) callback(reports)
} }
/**
* Get list of all analysis modules
*/
modules (): any[] { modules (): any[] {
return list return list
} }
......
import { getStateVariableDeclarationsFromContractNode, getInheritsFromName, getContractName, import { getStateVariableDeclarationsFromContractNode, getInheritsFromName, getContractName,
getFunctionOrModifierDefinitionParameterPart, getType, getDeclaredVariableName, getFunctionDefinitionReturnParameterPart } from './staticAnalysisCommon' getFunctionOrModifierDefinitionParameterPart, getType, getDeclaredVariableName, getFunctionDefinitionReturnParameterPart } from './staticAnalysisCommon'
import { AstWalker } from 'remix-astwalker' 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[]) type WrapFunction = ((contracts: ContractHLAst[], isSameName: boolean) => ReportObj[])
...@@ -47,10 +48,9 @@ export default class abstractAstView { ...@@ -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. * @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 { build_visit (relevantNodeFilter: ((node:any) => boolean)): VisitFunction {
const that: abstractAstView = this return (node: any) => {
return function (node: any) {
if (node.nodeType === "ContractDefinition") { if (node.nodeType === "ContractDefinition") {
that.setCurrentContract(that, { this.setCurrentContract({
node: node, node: node,
functions: [], functions: [],
relevantNodes: [], relevantNodes: [],
...@@ -59,40 +59,40 @@ export default class abstractAstView { ...@@ -59,40 +59,40 @@ export default class abstractAstView {
stateVariables: getStateVariableDeclarationsFromContractNode(node) stateVariables: getStateVariableDeclarationsFromContractNode(node)
}) })
} else if (node.nodeType === "InheritanceSpecifier") { } else if (node.nodeType === "InheritanceSpecifier") {
const currentContract: ContractHLAst = that.getCurrentContract(that) const currentContract: ContractHLAst = this.getCurrentContract()
const inheritsFromName: string = getInheritsFromName(node) const inheritsFromName: string = getInheritsFromName(node)
currentContract.inheritsFrom.push(inheritsFromName) currentContract.inheritsFrom.push(inheritsFromName)
} else if (node.nodeType === "FunctionDefinition") { } else if (node.nodeType === "FunctionDefinition") {
that.setCurrentFunction(that, { this.setCurrentFunction({
node: node, node: node,
relevantNodes: [], relevantNodes: [],
modifierInvocations: [], modifierInvocations: [],
localVariables: that.getLocalVariables(node), localVariables: this.getLocalVariables(node),
parameters: that.getLocalParameters(node), parameters: this.getLocalParameters(node),
returns: that.getReturnParameters(node) returns: this.getReturnParameters(node)
}) })
// push back relevant nodes to their the current fn if any // 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) { if (item.referencedDeclaration === node.id) {
that.getCurrentFunction(that).relevantNodes.push(item.node) this.getCurrentFunction().relevantNodes.push(item.node)
} }
}) })
} else if (node.nodeType === "ModifierDefinition") { } else if (node.nodeType === "ModifierDefinition") {
that.setCurrentModifier(that, { this.setCurrentModifier({
node: node, node: node,
relevantNodes: [], relevantNodes: [],
localVariables: that.getLocalVariables(node), localVariables: this.getLocalVariables(node),
parameters: that.getLocalParameters(node) parameters: this.getLocalParameters(node)
}) })
} else if (node.nodeType === "ModifierInvocation") { } else if (node.nodeType === "ModifierInvocation") {
if (!that.isFunctionNotModifier) throw new Error('abstractAstView.js: Found modifier invocation outside of function scope.') if (!this.isFunctionNotModifier) throw new Error('abstractAstView.js: Found modifier invocation outside of function scope.')
that.getCurrentFunction(that).modifierInvocations.push(node) this.getCurrentFunction().modifierInvocations.push(node)
} else if (relevantNodeFilter(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) { if (scope) {
scope.relevantNodes.push(node) scope.relevantNodes.push(node)
} else { } 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) { if (scope && node.referencedDeclaration) {
scope.relevantNodes.push({ referencedDeclaration: node.referencedDeclaration, node: node }) scope.relevantNodes.push({ referencedDeclaration: node.referencedDeclaration, node: node })
} }
...@@ -102,10 +102,9 @@ export default class abstractAstView { ...@@ -102,10 +102,9 @@ export default class abstractAstView {
} }
build_report (wrap: WrapFunction): ReportFunction { build_report (wrap: WrapFunction): ReportFunction {
const that: abstractAstView = this return (compilationResult: CompilationResult) => {
return function (compilationResult: CompilationResult) { this.resolveStateVariablesInHierarchy(this.contracts)
that.resolveStateVariablesInHierarchy(that.contracts) return wrap(this.contracts, this.multipleContractsWithSameName)
return wrap(that.contracts, that.multipleContractsWithSameName)
} }
} }
...@@ -127,35 +126,35 @@ export default class abstractAstView { ...@@ -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) 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') 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 { private setCurrentFunction (func: FunctionHLAst): void {
that.isFunctionNotModifier = true this.isFunctionNotModifier = true
that.currentFunctionIndex = (that.getCurrentContract(that).functions.push(func) - 1) this.currentFunctionIndex = (this.getCurrentContract().functions.push(func) - 1)
} }
private setCurrentModifier (that, modi): void { private setCurrentModifier (modi): void {
that.isFunctionNotModifier = false this.isFunctionNotModifier = false
that.currentModifierIndex = (that.getCurrentContract(that).modifiers.push(modi) - 1) this.currentModifierIndex = (this.getCurrentContract().modifiers.push(modi) - 1)
} }
private getCurrentContract (that: abstractAstView): ContractHLAst { private getCurrentContract (): ContractHLAst {
return that.contracts[that.currentContractIndex] return this.contracts[this.currentContractIndex]
} }
private getCurrentFunction (that: abstractAstView): FunctionHLAst { private getCurrentFunction (): FunctionHLAst {
return that.getCurrentContract(that).functions[that.currentFunctionIndex] return this.getCurrentContract().functions[this.currentFunctionIndex]
} }
private getCurrentModifier (that:abstractAstView): ModifierHLAst { private getCurrentModifier (): ModifierHLAst {
return that.getCurrentContract(that).modifiers[that.currentModifierIndex] return this.getCurrentContract().modifiers[this.currentModifierIndex]
} }
private getLocalParameters (funcNode: FunctionDefinitionAstNode | ModifierDefinitionAstNode): string[] { private getLocalParameters (funcNode: FunctionDefinitionAstNode | ModifierDefinitionAstNode): string[] {
......
...@@ -12,7 +12,7 @@ export default class assignAndCompare implements AnalyzerModule { ...@@ -12,7 +12,7 @@ export default class assignAndCompare implements AnalyzerModule {
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
visit (node: BlockAstNode | IfStatementAstNode | WhileStatementAstNode | ForStatementAstNode): void { 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[] { report (compilationResults: CompilationResult): ReportObj[] {
......
...@@ -3,7 +3,7 @@ import { default as algorithm } from './algorithmCategories' ...@@ -3,7 +3,7 @@ import { default as algorithm } from './algorithmCategories'
import AbstractAst from './abstractAstView' import AbstractAst from './abstractAstView'
import { ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, CompiledContractObj, CompiledContract, VisitFunction, AnalyzerModule} from './../../types' import { ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, CompiledContractObj, CompiledContract, VisitFunction, AnalyzerModule} from './../../types'
type VisitedContract = { interface VisitedContract {
name: string name: string
object: CompiledContract object: CompiledContract
file: string file: string
......
...@@ -6,7 +6,7 @@ import { get } from 'fast-levenshtein' ...@@ -6,7 +6,7 @@ import { get } from 'fast-levenshtein'
import { util } from 'remix-lib' import { util } from 'remix-lib'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, ContractHLAst, FunctionHLAst, VariableDeclarationAstNode, VisitFunction, ReportFunction} from './../../types' import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, ContractHLAst, FunctionHLAst, VariableDeclarationAstNode, VisitFunction, ReportFunction} from './../../types'
type SimilarRecord = { interface SimilarRecord {
var1: string var1: string
var2: string var2: string
distance: number distance: number
......
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