From c4f43ddd508dc682113517b68e97ec15beec88db Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Thu, 27 Feb 2020 19:09:53 +0530 Subject: [PATCH] commons, modules & test ASTs updated --- .../modules/blockTimestamp.ts | 12 +- .../modules/deleteFromDynamicArray.ts | 8 +- .../modules/etherTransferInLoop.ts | 2 +- .../modules/guardConditions.ts | 6 +- .../src/solidity-analyzer/modules/noReturn.ts | 2 +- .../solidity-analyzer/modules/selfdestruct.ts | 5 +- .../modules/similarVariableNames.ts | 2 +- .../modules/staticAnalysisCommon.ts | 139 +++--- .../modules/stringBytesLength.ts | 12 +- .../solidity-analyzer/modules/thisLocal.ts | 2 +- remix-analyzer/src/types.ts | 12 +- .../test/analysis/astBlocks/assignment.json | 111 ++--- .../analysis/astBlocks/blockHashAccess.json | 25 +- .../analysis/astBlocks/doWhileLoopNode.json | 268 +++------- .../test/analysis/astBlocks/forLoopNode.json | 466 +++++++++--------- .../astBlocks/functionDefinition.json | 104 +++- .../test/analysis/astBlocks/inheritance.json | 27 +- .../analysis/astBlocks/inlineAssembly.json | 100 +++- .../test/analysis/astBlocks/libCall.json | 40 +- .../test/analysis/astBlocks/localCall.json | 57 ++- .../test/analysis/astBlocks/lowlevelCall.json | 180 +++++-- .../analysis/astBlocks/parameterFunction.json | 138 +++--- .../test/analysis/astBlocks/selfdestruct.json | 77 ++- .../astBlocks/stateVariableContractNode.json | 410 +++++++++++---- .../test/analysis/astBlocks/superLocal.json | 40 +- .../analysis/astBlocks/thisLocalCall.json | 42 +- .../analysis/astBlocks/whileLoopNode.json | 291 ++++------- .../analysis/staticAnalysisCommon-test.ts | 184 ++----- .../test-contracts/solidity-v0.5/library.sol | 6 +- 29 files changed, 1523 insertions(+), 1245 deletions(-) diff --git a/remix-analyzer/src/solidity-analyzer/modules/blockTimestamp.ts b/remix-analyzer/src/solidity-analyzer/modules/blockTimestamp.ts index 951cce3610..e525cc4782 100644 --- a/remix-analyzer/src/solidity-analyzer/modules/blockTimestamp.ts +++ b/remix-analyzer/src/solidity-analyzer/modules/blockTimestamp.ts @@ -1,19 +1,19 @@ import { default as category } from './categories' import { isNowAccess, isBlockTimestampAccess } from './staticAnalysisCommon' import { default as algorithm } from './algorithmCategories' -import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult} from './../../types' +import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult, IdentifierAstNode, MemberAccessAstNode} from './../../types' export default class blockTimestamp implements AnalyzerModule { - warningNowNodes: AstNodeLegacy[] = [] - warningblockTimestampNodes: AstNodeLegacy[] = [] + warningNowNodes: IdentifierAstNode[] = [] + warningblockTimestampNodes: MemberAccessAstNode[] = [] name: string = 'Block timestamp: ' description: string = 'Semantics maybe unclear' category: ModuleCategory = category.SECURITY algorithm: ModuleAlgorithm = algorithm.EXACT - visit (node: AstNodeLegacy): void { - if (isNowAccess(node)) this.warningNowNodes.push(node) - else if (isBlockTimestampAccess(node)) this.warningblockTimestampNodes.push(node) + visit (node: IdentifierAstNode | MemberAccessAstNode ): void { + if (node.nodeType === "Identifier" && isNowAccess(node)) this.warningNowNodes.push(node) + else if (node.nodeType === "MemberAccess" && isBlockTimestampAccess(node)) this.warningblockTimestampNodes.push(node) } report (compilationResults: CompilationResult): ReportObj[] { diff --git a/remix-analyzer/src/solidity-analyzer/modules/deleteFromDynamicArray.ts b/remix-analyzer/src/solidity-analyzer/modules/deleteFromDynamicArray.ts index f8410cc112..ab6cd268c0 100644 --- a/remix-analyzer/src/solidity-analyzer/modules/deleteFromDynamicArray.ts +++ b/remix-analyzer/src/solidity-analyzer/modules/deleteFromDynamicArray.ts @@ -1,17 +1,17 @@ import { default as category } from './categories' import { default as algorithm } from './algorithmCategories' import { isDeleteFromDynamicArray, isMappingIndexAccess } from './staticAnalysisCommon' -import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult} from './../../types' +import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, UnaryOperationAstNode} from './../../types' export default class deleteFromDynamicArray implements AnalyzerModule { - relevantNodes: AstNodeLegacy[] = [] + relevantNodes: UnaryOperationAstNode[] = [] name: string = 'Delete from dynamic Array: ' description: string = 'Using delete on an array leaves a gap' category: ModuleCategory = category.MISC algorithm: ModuleAlgorithm = algorithm.EXACT - visit (node: AstNodeLegacy): void { - if (isDeleteFromDynamicArray(node) && node.children && !isMappingIndexAccess(node.children[0])) this.relevantNodes.push(node) + visit (node: UnaryOperationAstNode): void { + if (isDeleteFromDynamicArray(node) && !isMappingIndexAccess(node.subExpression)) this.relevantNodes.push(node) } report (compilationResults: CompilationResult): ReportObj[] { diff --git a/remix-analyzer/src/solidity-analyzer/modules/etherTransferInLoop.ts b/remix-analyzer/src/solidity-analyzer/modules/etherTransferInLoop.ts index 43d8558718..9229653f10 100644 --- a/remix-analyzer/src/solidity-analyzer/modules/etherTransferInLoop.ts +++ b/remix-analyzer/src/solidity-analyzer/modules/etherTransferInLoop.ts @@ -1,6 +1,6 @@ import { default as category } from './categories' import { default as algorithm } from './algorithmCategories' -import { getLoopBlockStartIndex, isTransfer } from './staticAnalysisCommon' +import { isTransfer } from './staticAnalysisCommon' import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult, ForStatementAstNode, WhileStatementAstNode, CommonAstNode, ExpressionStatementAstNode} from './../../types' export default class etherTransferInLoop implements AnalyzerModule { diff --git a/remix-analyzer/src/solidity-analyzer/modules/guardConditions.ts b/remix-analyzer/src/solidity-analyzer/modules/guardConditions.ts index a1981d73a3..abf75e13c2 100644 --- a/remix-analyzer/src/solidity-analyzer/modules/guardConditions.ts +++ b/remix-analyzer/src/solidity-analyzer/modules/guardConditions.ts @@ -1,16 +1,16 @@ import { default as category } from './categories' import { isRequireCall, isAssertCall } from './staticAnalysisCommon' import { default as algorithm } from './algorithmCategories' -import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult} from './../../types' +import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, FunctionCallAstNode} from './../../types' export default class guardConditions implements AnalyzerModule { - guards: AstNodeLegacy[] = [] + guards: FunctionCallAstNode[] = [] name: string = 'Guard Conditions: ' description: string = 'Use require and appropriately' category: ModuleCategory = category.MISC algorithm: ModuleAlgorithm = algorithm.EXACT - visit (node: AstNodeLegacy): void { + visit (node: FunctionCallAstNode): void { if (isRequireCall(node) || isAssertCall(node)) this.guards.push(node) } diff --git a/remix-analyzer/src/solidity-analyzer/modules/noReturn.ts b/remix-analyzer/src/solidity-analyzer/modules/noReturn.ts index a1368a4d30..4540e47b24 100644 --- a/remix-analyzer/src/solidity-analyzer/modules/noReturn.ts +++ b/remix-analyzer/src/solidity-analyzer/modules/noReturn.ts @@ -2,7 +2,7 @@ import { default as category } from './categories' import { hasFunctionBody, getFullQuallyfiedFuncDefinitionIdent, getEffectedVariableName } from './staticAnalysisCommon' import { default as algorithm } from './algorithmCategories' import AbstractAst from './abstractAstView' -import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult, CommonAstNode, FunctionDefinitionAstNode} from './../../types' +import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, CommonAstNode, FunctionDefinitionAstNode} from './../../types' export default class noReturn implements AnalyzerModule { name: string = 'no return: ' diff --git a/remix-analyzer/src/solidity-analyzer/modules/selfdestruct.ts b/remix-analyzer/src/solidity-analyzer/modules/selfdestruct.ts index 635cc0518e..dd70e974f2 100644 --- a/remix-analyzer/src/solidity-analyzer/modules/selfdestruct.ts +++ b/remix-analyzer/src/solidity-analyzer/modules/selfdestruct.ts @@ -2,7 +2,7 @@ import { default as category } from './categories' import { isStatement, isSelfdestructCall } from './staticAnalysisCommon' import { default as algorithm } from './algorithmCategories' import AbstractAst from './abstractAstView' -import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult} from './../../types' +import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult} from './../../types' export default class selfdestruct implements AnalyzerModule { name: string = 'Selfdestruct: ' @@ -13,8 +13,7 @@ export default class selfdestruct implements AnalyzerModule { abstractAst = new AbstractAst() visit = this.abstractAst.build_visit( - (node: AstNodeLegacy) => isStatement(node) || - isSelfdestructCall(node) + (node: any) => isStatement(node) || isSelfdestructCall(node.expression) ) report = this.abstractAst.build_report(this._report.bind(this)) diff --git a/remix-analyzer/src/solidity-analyzer/modules/similarVariableNames.ts b/remix-analyzer/src/solidity-analyzer/modules/similarVariableNames.ts index ddeff8ce4a..f09576b6e7 100644 --- a/remix-analyzer/src/solidity-analyzer/modules/similarVariableNames.ts +++ b/remix-analyzer/src/solidity-analyzer/modules/similarVariableNames.ts @@ -70,7 +70,7 @@ export default class similarVariableNames implements AnalyzerModule { return varName2.match(ref) != null } - private getFunctionVariables (contract, func): string[] { + private getFunctionVariables (contract, func) { return contract.stateVariables.concat(func.localVariables) } } diff --git a/remix-analyzer/src/solidity-analyzer/modules/staticAnalysisCommon.ts b/remix-analyzer/src/solidity-analyzer/modules/staticAnalysisCommon.ts index 162418afe1..17ae62594a 100644 --- a/remix-analyzer/src/solidity-analyzer/modules/staticAnalysisCommon.ts +++ b/remix-analyzer/src/solidity-analyzer/modules/staticAnalysisCommon.ts @@ -1,6 +1,6 @@ 'use strict' -import { FunctionDefinitionAstNode, ModifierDefinitionAstNode, ParameterListAstNode, CommonAstNode, ForStatementAstNode, WhileStatementAstNode, VariableDeclarationAstNode, ContractDefinitionAstNode, InheritanceSpecifierAstNode, MemberAccessAstNode, BinaryOperationAstNode, FunctionCallAstNode, ExpressionStatementAstNode, UnaryOperationAstNode, IdentifierAstNode, MappingAstNode, IndexAccessAstNode } from "types" +import { FunctionDefinitionAstNode, ModifierDefinitionAstNode, ParameterListAstNode, CommonAstNode, ForStatementAstNode, WhileStatementAstNode, VariableDeclarationAstNode, ContractDefinitionAstNode, InheritanceSpecifierAstNode, MemberAccessAstNode, BinaryOperationAstNode, FunctionCallAstNode, ExpressionStatementAstNode, UnaryOperationAstNode, IdentifierAstNode, MappingAstNode, IndexAccessAstNode, UserDefinedTypeNameAstNode, BlockAstNode } from "types" const remixLib = require('remix-lib') const util = remixLib.util @@ -125,8 +125,8 @@ const abiNamespace = { // #################### Trivial Getters -function getType (node: CommonAstNode) { - return node.nodeType +function getType (node: any) { + return node.typeDescriptions.typeString } // #################### Complex Getters @@ -159,9 +159,9 @@ function getEffectedVariableName (effectNode) { * @localCallNode {ASTNode} Function call node * @return {string} name of the function called */ -function getLocalCallName (localCallNode) { +function getLocalCallName (localCallNode: FunctionCallAstNode): string { if (!isLocalCall(localCallNode) && !isAbiNamespaceCall(localCallNode)) throw new Error('staticAnalysisCommon.js: not an local call Node') - return localCallNode.children[0].attributes.value + return localCallNode.expression.name } /** @@ -170,9 +170,9 @@ function getLocalCallName (localCallNode) { * @localCallNode {ASTNode} Function call node * @return {string} name of the function called */ -function getThisLocalCallName (localCallNode) { - if (!isThisLocalCall(localCallNode)) throw new Error('staticAnalysisCommon.js: not an this local call Node') - return localCallNode.attributes.value +function getThisLocalCallName (localCallNode: FunctionCallAstNode): string { + if (!isThisLocalCall(localCallNode.expression)) throw new Error('staticAnalysisCommon.js: not an this local call Node') + return localCallNode.expression.memberName } /** @@ -181,9 +181,9 @@ function getThisLocalCallName (localCallNode) { * @localCallNode {ASTNode} Function call node * @return {string} name of the function called */ -function getSuperLocalCallName (localCallNode) { - if (!isSuperLocalCall(localCallNode)) throw new Error('staticAnalysisCommon.js: not an super local call Node') - return localCallNode.attributes.member_name +function getSuperLocalCallName (localCallNode: FunctionCallAstNode): string { + if (!isSuperLocalCall(localCallNode.expression)) throw new Error('staticAnalysisCommon.js: not an super local call Node') + return localCallNode.expression.memberName } /** @@ -209,9 +209,9 @@ function getExternalDirectCallContractName (extDirectCall) { * @thisLocalCall {ASTNode} Function call node * @return {string} name of the contract the function is defined in */ -function getThisLocalCallContractName (thisLocalCall) { - if (!isThisLocalCall(thisLocalCall)) throw new Error('staticAnalysisCommon.js: not an this local call Node') - return thisLocalCall.children[0].attributes.type.replace(new RegExp(basicRegex.CONTRACTTYPE), '') +function getThisLocalCallContractName (thisLocalCall: FunctionCallAstNode) { + if (!isThisLocalCall(thisLocalCall.expression)) throw new Error('staticAnalysisCommon.js: not an this local call Node') + return thisLocalCall.expression.expression.typeDescriptions.typeString.replace(new RegExp(basicRegex.CONTRACTTYPE), '') } /** @@ -257,7 +257,7 @@ function getFunctionDefinitionName (funcDef: FunctionDefinitionAstNode): string * @func {ASTNode} Inheritance specifier * @return {string} name of contract inherited from */ -function getInheritsFromName (inheritsNode: InheritanceSpecifierAstNode) { +function getInheritsFromName (inheritsNode: InheritanceSpecifierAstNode): UserDefinedTypeNameAstNode { return inheritsNode.baseName } @@ -268,7 +268,7 @@ function getInheritsFromName (inheritsNode: InheritanceSpecifierAstNode) { * @varDeclNode {ASTNode} Variable declaration node * @return {string} variable name */ -function getDeclaredVariableName (varDeclNode: VariableDeclarationAstNode) { +function getDeclaredVariableName (varDeclNode: VariableDeclarationAstNode): string { return varDeclNode.name } @@ -279,8 +279,8 @@ function getDeclaredVariableName (varDeclNode: VariableDeclarationAstNode) { * @varDeclNode {ASTNode} Variable declaration node * @return {string} variable type */ -function getDeclaredVariableType (varDeclNode: VariableDeclarationAstNode) { - return varDeclNode.typeName +function getDeclaredVariableType (varDeclNode: VariableDeclarationAstNode): string { + return varDeclNode.typeName.name } /** @@ -356,9 +356,9 @@ function getFunctionCallTypeParameterType (func) { * @funcCall {ASTNode} function call node * @return {string} name of the lib defined */ -function getLibraryCallContractName (funcCall) { - if (!isLibraryCall(funcCall)) throw new Error('staticAnalysisCommon.js: not an this library call Node') - const types = new RegExp(basicRegex.LIBRARYTYPE).exec(funcCall.children[0].attributes.type) +function getLibraryCallContractName (node: MemberAccessAstNode): string | undefined { + if (!isLibraryCall(node)) throw new Error('staticAnalysisCommon.js: not an this library call Node') + const types: RegExpExecArray | null = new RegExp(basicRegex.LIBRARYTYPE).exec(node.expression.typeDescriptions.typeString) if(types) return types[1] } @@ -373,9 +373,9 @@ function getLibraryCallContractName (funcCall) { * @func {ASTNode} function call node * @return {string} name of function called on the library */ -function getLibraryCallMemberName (funcCall) { +function getLibraryCallMemberName (funcCall: FunctionCallAstNode): string { // if (!isLibraryCall(funcCall)) throw new Error('staticAnalysisCommon.js: not an library call Node') - return funcCall.attributes.member_name + return funcCall.expression.memberName } /** @@ -407,13 +407,13 @@ function getUnAssignedTopLevelBinOps (subScope) { return subScope.children.filter(isBinaryOpInExpression) } -function getLoopBlockStartIndex (node: ForStatementAstNode | WhileStatementAstNode): 3|1 { - return node.nodeType === "ForStatement" ? 3 : 1 -} +// function getLoopBlockStartIndex (node: ForStatementAstNode | WhileStatementAstNode): 3|1 { +// return node.nodeType === "ForStatement" ? 3 : 1 +// } // #################### Trivial Node Identification -function isStatement (node: CommonAstNode) { +function isStatement (node: any): boolean { return nodeType(node, 'Statement$') || node.nodeType === "Block" || node.nodeType === "Return" } @@ -422,9 +422,9 @@ function isStatement (node: CommonAstNode) { * @node {ASTNode} some AstNode * @return {bool} */ -function isBinaryOperation (node) { - return nodeType(node, exactMatch(nodeTypes.BINARYOPERATION)) -} +// function isBinaryOperation (node) { +// return nodeType(node, exactMatch(nodeTypes.BINARYOPERATION)) +// } // #################### Complex Node Identification @@ -433,8 +433,8 @@ function isBinaryOperation (node) { * @funcNode {ASTNode} function defintion node * @return {bool} */ -function hasFunctionBody (funcNode: FunctionDefinitionAstNode) { - return funcNode.body != null +function hasFunctionBody (funcNode: FunctionDefinitionAstNode): boolean { + return funcNode.body !== null } /** @@ -442,7 +442,7 @@ function hasFunctionBody (funcNode: FunctionDefinitionAstNode) { * @node {ASTNode} node to check for * @return {bool} */ -function isDeleteOfDynamicArray (node: UnaryOperationAstNode) { +function isDeleteOfDynamicArray (node: UnaryOperationAstNode): boolean { return isDeleteUnaryOperation(node) && isDynamicArrayAccess(node.subExpression) } @@ -451,7 +451,7 @@ function isDeleteOfDynamicArray (node: UnaryOperationAstNode) { * @node {ASTNode} node to check for * @return {bool} */ -function isDynamicArrayAccess (node: IdentifierAstNode) { +function isDynamicArrayAccess (node: IdentifierAstNode): boolean { return typeDescription(node, '[] storage ref') || typeDescription(node, 'bytes storage ref') || typeDescription(node, 'string storage ref') } @@ -460,7 +460,7 @@ function isDynamicArrayAccess (node: IdentifierAstNode) { * @node {ASTNode} node to check for * @return {bool} */ -function isDynamicArrayLengthAccess (node: MemberAccessAstNode) { +function isDynamicArrayLengthAccess (node: MemberAccessAstNode): boolean { return (node.memberName === 'length') && // accessing 'length' member node.expression['typeDescriptions']['typeString'].indexOf('[]') !== -1 // member is accessed from dynamic array, notice [] without any number } @@ -470,8 +470,8 @@ function isDynamicArrayLengthAccess (node: MemberAccessAstNode) { * @node {ASTNode} node to check for * @return {bool} */ -function isDeleteFromDynamicArray (node) { - return isDeleteUnaryOperation(node) && isIndexAccess(node.children[0]) +function isDeleteFromDynamicArray (node: UnaryOperationAstNode): boolean { + return isDeleteUnaryOperation(node) && node.subExpression.nodeType === 'IndexAccess' } /** @@ -479,17 +479,17 @@ function isDeleteFromDynamicArray (node) { * @node {ASTNode} node to check for * @return {bool} */ -function isIndexAccess (node) { - return node && node.name === 'IndexAccess' -} +// function isIndexAccess (node) { +// return node && node.name === 'IndexAccess' +// } /** * True if node is the access of a mapping index * @node {ASTNode} node to check for * @return {bool} */ -function isMappingIndexAccess (node) { - return isIndexAccess(node) && node.children && node.children[0].attributes.type.startsWith('mapping') +function isMappingIndexAccess (node: IndexAccessAstNode): boolean { + return node.typeDescriptions.typeString.startsWith('mapping') } /** @@ -506,7 +506,7 @@ function isLocalCallGraphRelevantNode (node) { * @node {ASTNode} some AstNode * @return {bool} */ -function isBuiltinFunctionCall (node) { +function isBuiltinFunctionCall (node: FunctionCallAstNode): boolean { return (isLocalCall(node) && builtinFunctions[getLocalCallName(node) + '(' + getFunctionCallTypeParameterType(node) + ')'] === true) || isAbiNamespaceCall(node) } @@ -515,8 +515,8 @@ function isBuiltinFunctionCall (node) { * @node {ASTNode} some AstNode * @return {bool} */ -function isAbiNamespaceCall (node) { - return Object.keys(abiNamespace).some((key) => abiNamespace.hasOwnProperty(key) && node.children && node.children[0] && isSpecialVariableAccess(node.children[0], abiNamespace[key])) +function isAbiNamespaceCall (node: FunctionCallAstNode): boolean { + return Object.keys(abiNamespace).some((key) => abiNamespace.hasOwnProperty(key) && node.expression && isSpecialVariableAccess(node.expression, abiNamespace[key])) } /** @@ -524,7 +524,7 @@ function isAbiNamespaceCall (node) { * @node {ASTNode} some AstNode * @return {bool} */ -function isSelfdestructCall (node) { +function isSelfdestructCall (node: FunctionCallAstNode): boolean { return isBuiltinFunctionCall(node) && getLocalCallName(node) === 'selfdestruct' } @@ -533,7 +533,7 @@ function isSelfdestructCall (node) { * @node {ASTNode} some AstNode * @return {bool} */ -function isAssertCall (node) { +function isAssertCall (node: FunctionCallAstNode): boolean { return isBuiltinFunctionCall(node) && getLocalCallName(node) === 'assert' } @@ -542,7 +542,7 @@ function isAssertCall (node) { * @node {ASTNode} some AstNode * @return {bool} */ -function isRequireCall (node) { +function isRequireCall (node: FunctionCallAstNode): boolean { return isBuiltinFunctionCall(node) && getLocalCallName(node) === 'require' } @@ -625,7 +625,7 @@ function isConstructor (node: FunctionDefinitionAstNode): boolean { * @node {ASTNode} some AstNode * @return {bool} */ -function isIntDivision (node: BinaryOperationAstNode) { +function isIntDivision (node: BinaryOperationAstNode): boolean { return operator(node, exactMatch(util.escapeRegExp('/'))) && typeDescription(node.rightExpression, util.escapeRegExp('int')) } @@ -635,7 +635,7 @@ function isIntDivision (node: BinaryOperationAstNode) { * @return {bool} */ function isSubScopeWithTopLevelUnAssignedBinOp (node) { - return nodeType(node, exactMatch(nodeTypes.BLOCK)) && node.children && node.children.some(isBinaryOpInExpression) || + return nodeType(node, exactMatch(nodeTypes.BLOCK)) && node.statements.some(isBinaryOpInExpression) || isSubScopeStatement(node) && node.children && node.children.some(isBinaryOpInExpression) // Second Case for if without braces } @@ -652,7 +652,7 @@ function isSubScopeStatement (node) { * @node {ASTNode} some AstNode * @return {bool} */ -function isBinaryOpInExpression (node: ExpressionStatementAstNode) { +function isBinaryOpInExpression (node: ExpressionStatementAstNode): boolean { return node.nodeType === "ExpressionStatement" && node.expression.nodeType === "BinaryOperation" } @@ -661,7 +661,7 @@ function isBinaryOpInExpression (node: ExpressionStatementAstNode) { * @node {ASTNode} some AstNode * @return {bool} */ -function isPlusPlusUnaryOperation (node: UnaryOperationAstNode) { +function isPlusPlusUnaryOperation (node: UnaryOperationAstNode): boolean { return node.operator === '++' } @@ -670,7 +670,7 @@ function isPlusPlusUnaryOperation (node: UnaryOperationAstNode) { * @node {ASTNode} some AstNode * @return {bool} */ -function isDeleteUnaryOperation (node: UnaryOperationAstNode) { +function isDeleteUnaryOperation (node: UnaryOperationAstNode): boolean { return node.operator === 'delete' } @@ -679,7 +679,7 @@ function isDeleteUnaryOperation (node: UnaryOperationAstNode) { * @node {ASTNode} some AstNode * @return {bool} */ -function isMinusMinusUnaryOperation (node: UnaryOperationAstNode) { +function isMinusMinusUnaryOperation (node: UnaryOperationAstNode): boolean { return node.operator === '--' } @@ -688,7 +688,7 @@ function isMinusMinusUnaryOperation (node: UnaryOperationAstNode) { * @node {ASTNode} some AstNode * @return {bool} */ -function isFullyImplementedContract (node: ContractDefinitionAstNode) { +function isFullyImplementedContract (node: ContractDefinitionAstNode): boolean { return node.fullyImplemented === true } @@ -697,7 +697,7 @@ function isFullyImplementedContract (node: ContractDefinitionAstNode) { * @node {ASTNode} some AstNode * @return {bool} */ -function isLibrary (node: ContractDefinitionAstNode) { +function isLibrary (node: ContractDefinitionAstNode): boolean { return node.contractKind === 'library' } @@ -706,7 +706,7 @@ function isLibrary (node: ContractDefinitionAstNode) { * @node {ASTNode} some AstNode * @return {bool} */ -function isCallToNonConstLocalFunction (node: FunctionCallAstNode) { +function isCallToNonConstLocalFunction (node: FunctionCallAstNode): boolean { return isLocalCall(node) && !expressionType(node, basicRegex.CONSTANTFUNCTIONTYPE) } @@ -715,7 +715,7 @@ function isCallToNonConstLocalFunction (node: FunctionCallAstNode) { * @node {ASTNode} some AstNode * @return {bool} */ -function isLibraryCall (node: MemberAccessAstNode) { +function isLibraryCall (node: MemberAccessAstNode): boolean { return isMemberAccess(node, basicRegex.FUNCTIONTYPE, undefined, basicRegex.LIBRARYTYPE, undefined) } @@ -724,7 +724,7 @@ function isLibraryCall (node: MemberAccessAstNode) { * @node {ASTNode} some AstNode * @return {bool} */ -function isExternalDirectCall (node: MemberAccessAstNode) { +function isExternalDirectCall (node: MemberAccessAstNode): boolean { return isMemberAccess(node, basicRegex.EXTERNALFUNCTIONTYPE, undefined, basicRegex.CONTRACTTYPE, undefined) && !isThisLocalCall(node) && !isSuperLocalCall(node) } @@ -733,7 +733,7 @@ function isExternalDirectCall (node: MemberAccessAstNode) { * @node {ASTNode} some AstNode * @return {bool} */ -function isNowAccess (node: IdentifierAstNode) { +function isNowAccess (node: IdentifierAstNode): boolean { return node.name === "now" && typeDescription(node, exactMatch(basicTypes.UINT)) } @@ -751,7 +751,7 @@ function isBlockTimestampAccess (node: MemberAccessAstNode) { * @node {ASTNode} some AstNode * @return {bool} */ -function isBlockBlockHashAccess (node: MemberAccessAstNode) { +function isBlockBlockHashAccess (node) { return isSpecialVariableAccess(node, specialVariables.BLOCKHASH) || isBuiltinFunctionCall(node) && getLocalCallName(node) === 'blockhash' } @@ -782,7 +782,7 @@ function isLocalCall (node: FunctionCallAstNode) { return node.kind === 'functionCall' && node.expression.nodeType === 'Identifier' && expressionTypeDescription(node, basicRegex.FUNCTIONTYPE) && - !expressionTypeDescription(node, basicRegex.FUNCTIONTYPE) + !expressionTypeDescription(node, basicRegex.EXTERNALFUNCTIONTYPE) } /** @@ -888,7 +888,7 @@ function isTransfer (node: MemberAccessAstNode) { undefined, matches(basicTypes.ADDRESS, basicTypes.PAYABLE_ADDRESS), exactMatch(lowLevelCallTypes.TRANSFER.ident)) } -function isStringToBytesConversion (node) { +function isStringToBytesConversion (node: FunctionCallAstNode) { return isExplicitCast(node, util.escapeRegExp('string *'), util.escapeRegExp('bytes')) } @@ -926,11 +926,10 @@ function isBytesLengthCheck (node: MemberAccessAstNode) { // #################### Complex Node Identification - Private function isMemberAccess (node: MemberAccessAstNode, retType: string, accessor: string| undefined, accessorType, memberName: string | undefined) { - return nodeType(node, exactMatch(nodeTypes.MEMBERACCESS)) && - expressionType(node, retType) && + return typeDescription(node, retType) && memName(node, memberName) && memName(node.expression, accessor) && - expressionType(node.expression, accessorType) + expressionTypeDescription(node.expression, accessorType) } function isSpecialVariableAccess (node: MemberAccessAstNode, varType) { @@ -965,7 +964,7 @@ function nodeType (node, typeRegex) { function memName (node, memNameRegex) { const regex = new RegExp(memNameRegex) - return (node && !memNameRegex) || (node && node.attributes && (regex.test(node.attributes.value) || regex.test(node.attributes.member_name))) + return regex.test(node.name) || regex.test(node.memberName) } function operator (node, opRegex) { @@ -1058,7 +1057,7 @@ export { getFunctionOrModifierDefinitionParameterPart, getFunctionDefinitionReturnParameterPart, getUnAssignedTopLevelBinOps, - getLoopBlockStartIndex, + // getLoopBlockStartIndex, // #################### Complex Node Identification isDeleteOfDynamicArray, @@ -1067,7 +1066,7 @@ export { isSpecialVariableAccess, isDynamicArrayAccess, isDynamicArrayLengthAccess, - isIndexAccess, + // isIndexAccess, isMappingIndexAccess, isSubScopeWithTopLevelUnAssignedBinOp, hasFunctionBody, @@ -1126,7 +1125,7 @@ export { isStatement, // isExpressionStatement, // isBlock, - isBinaryOperation, + // isBinaryOperation, // #################### Constants nodeTypes, diff --git a/remix-analyzer/src/solidity-analyzer/modules/stringBytesLength.ts b/remix-analyzer/src/solidity-analyzer/modules/stringBytesLength.ts index e9f73205ee..691aced101 100644 --- a/remix-analyzer/src/solidity-analyzer/modules/stringBytesLength.ts +++ b/remix-analyzer/src/solidity-analyzer/modules/stringBytesLength.ts @@ -1,7 +1,7 @@ import { default as category } from './categories' import { default as algorithm } from './algorithmCategories' import { isStringToBytesConversion, isBytesLengthCheck } from './staticAnalysisCommon' -import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult} from './../../types' +import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, MemberAccessAstNode, FunctionCallAstNode} from './../../types' export default class stringBytesLength implements AnalyzerModule { name: string = 'String Length: ' @@ -9,13 +9,13 @@ export default class stringBytesLength implements AnalyzerModule { category: ModuleCategory = category.MISC algorithm: ModuleAlgorithm = algorithm.EXACT - stringToBytesConversions: AstNodeLegacy[] = [] - bytesLengthChecks: AstNodeLegacy[] = [] + stringToBytesConversions: FunctionCallAstNode[] = [] + bytesLengthChecks: MemberAccessAstNode[] = [] - visit (node: AstNodeLegacy): void { - if (isStringToBytesConversion(node)) this.stringToBytesConversions.push(node) - else if (isBytesLengthCheck(node)) this.bytesLengthChecks.push(node) + visit (node: FunctionCallAstNode | MemberAccessAstNode): void { + if (node.nodeType === "FunctionCall" && isStringToBytesConversion(node)) this.stringToBytesConversions.push(node) + else if (node.nodeType === "MemberAccess" && isBytesLengthCheck(node)) this.bytesLengthChecks.push(node) } report (compilationResults: CompilationResult): ReportObj[] { diff --git a/remix-analyzer/src/solidity-analyzer/modules/thisLocal.ts b/remix-analyzer/src/solidity-analyzer/modules/thisLocal.ts index 8592886570..0de9ca5946 100644 --- a/remix-analyzer/src/solidity-analyzer/modules/thisLocal.ts +++ b/remix-analyzer/src/solidity-analyzer/modules/thisLocal.ts @@ -1,7 +1,7 @@ import { default as category } from './categories' import { isThisLocalCall } from './staticAnalysisCommon' import { default as algorithm } from './algorithmCategories' -import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult, MemberAccessAstNode} from './../../types' +import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, MemberAccessAstNode} from './../../types' export default class thisLocal implements AnalyzerModule { warningNodes: MemberAccessAstNode[] = [] diff --git a/remix-analyzer/src/types.ts b/remix-analyzer/src/types.ts index 8ff2fca3b2..612ed5878a 100644 --- a/remix-analyzer/src/types.ts +++ b/remix-analyzer/src/types.ts @@ -169,7 +169,7 @@ export interface FunctionDefinitionAstNode { overrides: OverrideSpecifierAstNode | null parameters: ParameterListAstNode returnParameters: ParameterListAstNode - modifiers: Array + modifiers: Array body: object | null implemented: boolean scope: number @@ -182,7 +182,7 @@ export interface VariableDeclarationAstNode { nodeType: 'VariableDeclaration' src: string name: string - typeName: object + typeName: ElementaryTypeNameAstNode | UserDefinedTypeNameAstNode constant: boolean stateVariable: boolean storageLocation: 'storage' | 'memory' | 'calldata' | 'default' @@ -298,7 +298,7 @@ export interface BlockAstNode { id: number nodeType: 'Block' src: string - statements: Array + statements: Array } export interface PlaceholderStatementAstNode { @@ -481,10 +481,12 @@ export interface NewExpressionAstNode extends ExpressionAttributes { typeName: UserDefinedTypeNameAstNode | ElementaryTypeNameAstNode } -export interface MemberAccessAstNode extends CommonAstNode, ExpressionAttributes { +export interface MemberAccessAstNode extends ExpressionAttributes { + id: number nodeType: 'MemberAccess' + src: string memberName: string - expression: object + expression: any referencedDeclaration: number | null } diff --git a/remix-analyzer/test/analysis/astBlocks/assignment.json b/remix-analyzer/test/analysis/astBlocks/assignment.json index 1e368adef7..b5f7fd3010 100644 --- a/remix-analyzer/test/analysis/astBlocks/assignment.json +++ b/remix-analyzer/test/analysis/astBlocks/assignment.json @@ -1,62 +1,51 @@ { - "attributes": { - "operator": "=", - "type": "uint256" - }, - "children": [ - { - "attributes": { - "type": "uint256" - }, - "children": [ - { - "attributes": { - "type": "mapping(address => uint256)", - "value": "c" - }, - "id": 61, - "name": "Identifier", - "src": "873:1:0" - }, - { - "attributes": { - "member_name": "sender", - "type": "address" - }, - "children": [ - { - "attributes": { - "type": "msg", - "value": "msg" - }, - "id": 62, - "name": "Identifier", - "src": "875:3:0" - } - ], - "id": 63, - "name": "MemberAccess", - "src": "875:10:0" - } - ], - "id": 64, - "name": "IndexAccess", - "src": "873:13:0" - }, - { - "attributes": { - "hexvalue": "30", - "subdenomination": null, - "token": null, - "type": "int_const 0", - "value": "0" - }, - "id": 65, - "name": "Literal", - "src": "889:1:0" - } - ], - "id": 66, - "name": "Assignment", - "src": "873:17:0" - } \ No newline at end of file + "argumentTypes": null, + "id": 5, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "argumentTypes": null, + "id": 3, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22, + "src": "52:1:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "argumentTypes": null, + "hexValue": "31", + "id": 4, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "56:5:0", + "subdenomination": "wei", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "52:9:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } +} \ No newline at end of file diff --git a/remix-analyzer/test/analysis/astBlocks/blockHashAccess.json b/remix-analyzer/test/analysis/astBlocks/blockHashAccess.json index 42f01ef509..01de98986e 100644 --- a/remix-analyzer/test/analysis/astBlocks/blockHashAccess.json +++ b/remix-analyzer/test/analysis/astBlocks/blockHashAccess.json @@ -1,16 +1,19 @@ { - "attributes": { - "member_name": "blockhash", - "type": "function (uint256) returns (bytes32)" - }, - "children": [ + "argumentTypes":[ { - "attributes": { - "type": "block", - "value": "block" - }, - "name": "Identifier" + "typeIdentifier": "t_rational_3_by_1", + "typeString": "int_const 3" } ], - "name": "MemberAccess" + "id": 5, + "name": "blockhash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -5, + "src": "69:9:0", + "typeDescriptions": + { + "typeIdentifier": "t_function_blockhash_view$_t_uint256_$returns$_t_bytes32_$", + "typeString": "function (uint256) view returns (bytes32)" + } } \ No newline at end of file diff --git a/remix-analyzer/test/analysis/astBlocks/doWhileLoopNode.json b/remix-analyzer/test/analysis/astBlocks/doWhileLoopNode.json index 4b5d880707..cc5f6708bb 100644 --- a/remix-analyzer/test/analysis/astBlocks/doWhileLoopNode.json +++ b/remix-analyzer/test/analysis/astBlocks/doWhileLoopNode.json @@ -1,204 +1,96 @@ { - "children": - [ - { - "attributes": + "body": + { + "id": 10, + "nodeType": "Block", + "src": "113:2:0", + "statements": [] + }, + "condition": + { + "argumentTypes": null, + "expression": + { + "argumentTypes": null, + "components": + [ { "argumentTypes": null, - "commonType": - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, + "id": 13, "isConstant": false, "isLValue": false, "isPure": false, "lValueRequested": false, - "operator": "<", - "type": "bool" - }, - "children": - [ + "leftHandSide": { - "attributes": + "argumentTypes": null, + "id": 11, + "name": "c", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8, + "src": "123:1:0", + "typeDescriptions": { - "argumentTypes": null, - "overloadedDeclarations": - [ - null - ], - "referencedDeclaration": 69, - "type": "uint256", - "value": "i" - }, - "id": 82, - "name": "Identifier", - "src": "592:1:0" + "typeIdentifier": "t_struct$_S_$3_storage_ptr", + "typeString": "struct C.S storage pointer" + } }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { - "attributes": + "argumentTypes": null, + "id": 12, + "name": "s", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 5, + "src": "127:1:0", + "typeDescriptions": { - "argumentTypes": null, - "hexvalue": "3130", - "isConstant": false, - "isLValue": false, - "isPure": true, - "lValueRequested": false, - "subdenomination": null, - "token": "number", - "type": "int_const 10", - "value": "10" - }, - "id": 83, - "name": "Literal", - "src": "596:2:0" - } - ], - "id": 84, - "name": "BinaryOperation", - "src": "592:6:0" - }, - { - "children": - [ - { - "children": - [ - { - "attributes": - { - "argumentTypes": null, - "isConstant": false, - "isLValue": false, - "isPure": false, - "isStructConstructorCall": false, - "lValueRequested": false, - "names": - [ - null - ], - "type": "uint256", - "type_conversion": false - }, - "children": - [ - { - "attributes": - { - "argumentTypes": - [ - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "member_name": "push", - "referencedDeclaration": null, - "type": "function (uint256) returns (uint256)" - }, - "children": - [ - { - "attributes": - { - "argumentTypes": null, - "overloadedDeclarations": - [ - null - ], - "referencedDeclaration": 4, - "type": "uint256[] storage ref", - "value": "array" - }, - "id": 72, - "name": "Identifier", - "src": "544:5:0" - } - ], - "id": 74, - "name": "MemberAccess", - "src": "544:10:0" - }, - { - "attributes": - { - "argumentTypes": null, - "overloadedDeclarations": - [ - null - ], - "referencedDeclaration": 69, - "type": "uint256", - "value": "i" - }, - "id": 75, - "name": "Identifier", - "src": "555:1:0" - } - ], - "id": 76, - "name": "FunctionCall", - "src": "544:13:0" - } - ], - "id": 77, - "name": "ExpressionStatement", - "src": "544:13:0" + "typeIdentifier": "t_struct$_S_$3_storage", + "typeString": "struct C.S storage ref" + } }, + "src": "123:5:0", + "typeDescriptions": { - "children": - [ - { - "attributes": - { - "argumentTypes": null, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "operator": "++", - "prefix": false, - "type": "uint256" - }, - "children": - [ - { - "attributes": - { - "argumentTypes": null, - "overloadedDeclarations": - [ - null - ], - "referencedDeclaration": 69, - "type": "uint256", - "value": "i" - }, - "id": 78, - "name": "Identifier", - "src": "571:1:0" - } - ], - "id": 79, - "name": "UnaryOperation", - "src": "571:3:0" - } - ], - "id": 80, - "name": "ExpressionStatement", - "src": "571:3:0" + "typeIdentifier": "t_struct$_S_$3_storage_ptr", + "typeString": "struct C.S storage pointer" } - ], - "id": 81, - "name": "Block", - "src": "530:55:0" + } + ], + "id": 14, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "122:7:0", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_S_$3_storage_ptr", + "typeString": "struct C.S storage pointer" } - ], - "id": 85, - "name": "DoWhileStatement", - "src": "528:72:0" - } \ No newline at end of file + }, + "id": 15, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "f", + "nodeType": "MemberAccess", + "referencedDeclaration": 2, + "src": "122:9:0", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 16, + "nodeType": "DoWhileStatement", + "src": "110:23:0" +} \ No newline at end of file diff --git a/remix-analyzer/test/analysis/astBlocks/forLoopNode.json b/remix-analyzer/test/analysis/astBlocks/forLoopNode.json index 214467cbae..515813068f 100644 --- a/remix-analyzer/test/analysis/astBlocks/forLoopNode.json +++ b/remix-analyzer/test/analysis/astBlocks/forLoopNode.json @@ -1,264 +1,260 @@ { - "children": + "body": + { + "id": 20, + "nodeType": "Block", + "src": "81:58:0", + "statements": [ { - "attributes": - { - "assignments": - [ - 21 - ] - }, - "children": + "id": 13, + "nodeType": "Break", + "src": "95:5:0" + }, + { + "assignments": + [ + 15 + ], + "declarations": [ { - "attributes": + "constant": false, + "id": 15, + "name": "b", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 20, + "src": "114:6:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { - "constant": false, - "name": "i", - "scope": 39, - "stateVariable": false, - "storageLocation": "default", - "type": "uint256", - "value": null, - "visibility": "internal" + "typeIdentifier": "t_uint256", + "typeString": "uint256" }, - "children": - [ + "typeName": + { + "id": 14, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "114:4:0", + "typeDescriptions": { - "attributes": - { - "name": "uint", - "type": "uint256" - }, - "id": 20, - "name": "ElementaryTypeName", - "src": "207:4:0" + "typeIdentifier": "t_uint256", + "typeString": "uint256" } - ], - "id": 21, - "name": "VariableDeclaration", - "src": "207:6:0" - }, - { - "attributes": - { - "argumentTypes": null, - "overloadedDeclarations": - [ - null - ], - "referencedDeclaration": 17, - "type": "uint256", - "value": "index" }, - "id": 22, - "name": "Identifier", - "src": "216:5:0" + "value": null, + "visibility": "internal" } ], - "id": 23, - "name": "VariableDeclarationStatement", - "src": "207:14:0" - }, - { - "attributes": + "id": 17, + "initialValue": { "argumentTypes": null, - "commonType": - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, + "hexValue": "3432", + "id": 16, "isConstant": false, "isLValue": false, - "isPure": false, + "isPure": true, + "kind": "number", "lValueRequested": false, - "operator": "<", - "type": "bool" - }, - "children": - [ + "nodeType": "Literal", + "src": "123:2:0", + "subdenomination": null, + "typeDescriptions": { - "attributes": - { - "argumentTypes": null, - "overloadedDeclarations": - [ - null - ], - "referencedDeclaration": 21, - "type": "uint256", - "value": "i" - }, - "id": 24, - "name": "Identifier", - "src": "223:1:0" + "typeIdentifier": "t_rational_42_by_1", + "typeString": "int_const 42" }, - { - "attributes": - { - "argumentTypes": null, - "hexvalue": "3130", - "isConstant": false, - "isLValue": false, - "isPure": true, - "lValueRequested": false, - "subdenomination": null, - "token": "number", - "type": "int_const 10", - "value": "10" - }, - "id": 25, - "name": "Literal", - "src": "227:2:0" - } - ], - "id": 26, - "name": "BinaryOperation", - "src": "223:6:0" + "value": "42" + }, + "nodeType": "VariableDeclarationStatement", + "src": "114:11:0" }, { - "children": - [ + "expression": + { + "argumentTypes": null, + "id": 18, + "name": "b", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 15, + "src": "127:1:0", + "typeDescriptions": { - "attributes": - { - "argumentTypes": null, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "operator": "++", - "prefix": false, - "type": "uint256" - }, - "children": - [ - { - "attributes": - { - "argumentTypes": null, - "overloadedDeclarations": - [ - null - ], - "referencedDeclaration": 21, - "type": "uint256", - "value": "i" - }, - "id": 27, - "name": "Identifier", - "src": "231:1:0" - } - ], - "id": 28, - "name": "UnaryOperation", - "src": "231:3:0" + "typeIdentifier": "t_uint256", + "typeString": "uint256" } - ], - "id": 29, - "name": "ExpressionStatement", - "src": "231:3:0" + }, + "id": 19, + "nodeType": "ExpressionStatement", + "src": "127:1:0" + } + ] + }, + "condition": + { + "argumentTypes": null, + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 9, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "argumentTypes": null, + "id": 7, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4, + "src": "69:1:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": + { + "argumentTypes": null, + "hexValue": "31", + "id": 8, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "73:1:0", + "subdenomination": null, + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" }, + "value": "1" + }, + "src": "69:5:0", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21, + "initializationExpression": + { + "assignments": + [ + 4 + ], + "declarations": + [ { - "children": - [ + "constant": false, + "id": 4, + "name": "a", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 21, + "src": "57:6:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "57:4:0", + "typeDescriptions": { - "children": - [ - { - "attributes": - { - "argumentTypes": null, - "isConstant": false, - "isLValue": false, - "isPure": false, - "isStructConstructorCall": false, - "lValueRequested": false, - "names": - [ - null - ], - "type": "uint256", - "type_conversion": false - }, - "children": - [ - { - "attributes": - { - "argumentTypes": - [ - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "member_name": "push", - "referencedDeclaration": null, - "type": "function (uint256) returns (uint256)" - }, - "children": - [ - { - "attributes": - { - "argumentTypes": null, - "overloadedDeclarations": - [ - null - ], - "referencedDeclaration": 4, - "type": "uint256[] storage ref", - "value": "array" - }, - "id": 30, - "name": "Identifier", - "src": "250:5:0" - } - ], - "id": 32, - "name": "MemberAccess", - "src": "250:10:0" - }, - { - "attributes": - { - "argumentTypes": null, - "overloadedDeclarations": - [ - null - ], - "referencedDeclaration": 21, - "type": "uint256", - "value": "i" - }, - "id": 33, - "name": "Identifier", - "src": "261:1:0" - } - ], - "id": 34, - "name": "FunctionCall", - "src": "250:13:0" - } - ], - "id": 35, - "name": "ExpressionStatement", - "src": "250:13:0" + "typeIdentifier": "t_uint256", + "typeString": "uint256" } - ], - "id": 36, - "name": "Block", - "src": "236:38:0" + }, + "value": null, + "visibility": "internal" } ], - "id": 37, - "name": "ForStatement", - "src": "202:72:0" - } \ No newline at end of file + "id": 6, + "initialValue": + { + "argumentTypes": null, + "hexValue": "30", + "id": 5, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "66:1:0", + "subdenomination": null, + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "57:10:0" + }, + "loopExpression": + { + "expression": + { + "argumentTypes": null, + "id": 11, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "76:3:0", + "subExpression": + { + "argumentTypes": null, + "id": 10, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4, + "src": "76:1:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 12, + "nodeType": "ExpressionStatement", + "src": "76:3:0" + }, + "nodeType": "ForStatement", + "src": "52:87:0" +} \ No newline at end of file diff --git a/remix-analyzer/test/analysis/astBlocks/functionDefinition.json b/remix-analyzer/test/analysis/astBlocks/functionDefinition.json index 9c915d3992..3848db0dd9 100644 --- a/remix-analyzer/test/analysis/astBlocks/functionDefinition.json +++ b/remix-analyzer/test/analysis/astBlocks/functionDefinition.json @@ -1,24 +1,82 @@ { - "attributes": { - "constant": true, - "name": "winnerName", - "payable": false, - "visibility": "public" - }, - "children": [ - { - "children": [ - ], - "name": "ParameterList" - }, - { - "children": [], - "name": "ParameterList" - }, - { - "children": [], - "name": "Block" - } - ], - "name": "FunctionDefinition" - } \ No newline at end of file + "body": + { + "id": 6, + "nodeType": "Block", + "src": "42:23:0", + "statements": + [ + { + "assignments": + [ + 4 + ], + "declarations": + [ + { + "constant": false, + "id": 4, + "name": "a", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 6, + "src": "52:6:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "52:4:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 5, + "initialValue": null, + "nodeType": "VariableDeclarationStatement", + "src": "52:6:0" + } + ] + }, + "documentation": null, + "functionSelector": "26121ff0", + "id": 7, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nodeType": "FunctionDefinition", + "overrides": null, + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "27:2:0" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "42:0:0" + }, + "scope": 8, + "src": "17:48:0", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" +} \ No newline at end of file diff --git a/remix-analyzer/test/analysis/astBlocks/inheritance.json b/remix-analyzer/test/analysis/astBlocks/inheritance.json index 5a1fc15ce7..d84ecf0cc3 100644 --- a/remix-analyzer/test/analysis/astBlocks/inheritance.json +++ b/remix-analyzer/test/analysis/astBlocks/inheritance.json @@ -1,15 +1,20 @@ { - "children": [ + "arguments": null, + "baseName": + { + "contractScope": null, + "id": 19, + "name": "A", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 9, + "src": "176:1:0", + "typeDescriptions": { - "attributes": { - "name": "r" - }, - "id": 7, - "name": "UserDefinedTypeName", - "src": "84:1:0" + "typeIdentifier": "t_contract$_A_$9", + "typeString": "contract A" } - ], - "id": 8, - "name": "InheritanceSpecifier", - "src": "84:1:0" + }, + "id": 20, + "nodeType": "InheritanceSpecifier", + "src": "176:1:0" } \ No newline at end of file diff --git a/remix-analyzer/test/analysis/astBlocks/inlineAssembly.json b/remix-analyzer/test/analysis/astBlocks/inlineAssembly.json index 6136ab3060..03e5acbb23 100644 --- a/remix-analyzer/test/analysis/astBlocks/inlineAssembly.json +++ b/remix-analyzer/test/analysis/astBlocks/inlineAssembly.json @@ -1,7 +1,95 @@ { - "children": [ - ], - "id": 21, - "name": "InlineAssembly", - "src": "809:41:0" - } \ No newline at end of file + "AST": + { + "nodeType": "YulBlock", + "src": "148:83:0", + "statements": + [ + { + "nodeType": "YulVariableDeclaration", + "src": "162:11:0", + "value": + { + "name": "x", + "nodeType": "YulIdentifier", + "src": "172:1:0" + }, + "variables": + [ + { + "name": "c1", + "nodeType": "YulTypedName", + "src": "166:2:0", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "186:11:0", + "value": + { + "name": "b", + "nodeType": "YulIdentifier", + "src": "196:1:0" + }, + "variables": + [ + { + "name": "c2", + "nodeType": "YulTypedName", + "src": "190:2:0", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "210:11:0", + "value": + { + "name": "s", + "nodeType": "YulIdentifier", + "src": "220:1:0" + }, + "variables": + [ + { + "name": "c3", + "nodeType": "YulTypedName", + "src": "214:2:0", + "type": "" + } + ] + } + ] + }, + "evmVersion": "istanbul", + "externalReferences": + [ + { + "declaration": 8, + "isOffset": false, + "isSlot": false, + "src": "196:1:0", + "valueSize": 1 + }, + { + "declaration": 11, + "isOffset": false, + "isSlot": false, + "src": "220:1:0", + "valueSize": 1 + }, + { + "declaration": 5, + "isOffset": false, + "isSlot": false, + "src": "172:1:0", + "valueSize": 1 + } + ], + "id": 14, + "nodeType": "InlineAssembly", + "src": "139:92:0" +} \ No newline at end of file diff --git a/remix-analyzer/test/analysis/astBlocks/libCall.json b/remix-analyzer/test/analysis/astBlocks/libCall.json index ebb7cfbbd1..f99e793e6f 100644 --- a/remix-analyzer/test/analysis/astBlocks/libCall.json +++ b/remix-analyzer/test/analysis/astBlocks/libCall.json @@ -1,16 +1,32 @@ { - "attributes": { - "member_name": "insert", - "type": "function (struct Set.Data storage pointer,uint256) returns (bool)" - }, - "children": [ + "argumentTypes": null, + "expression": + { + "argumentTypes": null, + "id": 33, + "name": "L", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21, + "src": "244:1:0", + "typeDescriptions": { - "attributes": { - "type": "type(library Set)", - "value": "Set" - }, - "name": "Identifier" + "typeIdentifier": "t_type$_t_contract$_L_$21_$", + "typeString": "type(library L)" } - ], - "name": "MemberAccess" + }, + "id": 34, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "f", + "nodeType": "MemberAccess", + "referencedDeclaration": 6, + "src": "244:3:0", + "typeDescriptions": + { + "typeIdentifier": "t_function_delegatecall_nonpayable$_t_uint256_$returns$__$", + "typeString": "function (uint256)" + } } \ No newline at end of file diff --git a/remix-analyzer/test/analysis/astBlocks/localCall.json b/remix-analyzer/test/analysis/astBlocks/localCall.json index 35372abe41..0963998caa 100644 --- a/remix-analyzer/test/analysis/astBlocks/localCall.json +++ b/remix-analyzer/test/analysis/astBlocks/localCall.json @@ -1,29 +1,34 @@ { - "attributes": { - "type": "tuple()", - "type_conversion": false - }, - "children": [ - { - "attributes": { - "type": "function (struct Ballot.Voter storage pointer)", - "value": "bli" - }, - "id": 37, - "name": "Identifier", - "src": "540:3:0" - }, + "argumentTypes": null, + "arguments": [], + "expression": + { + "argumentTypes": [], + "id": 13, + "name": "sha3", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8, + "src": "129:4:0", + "typeDescriptions": { - "attributes": { - "type": "struct Ballot.Voter storage pointer", - "value": "x" - }, - "id": 38, - "name": "Identifier", - "src": "544:1:0" + "typeIdentifier": "t_function_internal_pure$__$returns$_t_bool_$", + "typeString": "function () pure returns (bool)" } - ], - "id": 39, - "name": "FunctionCall", - "src": "540:6:0" - } \ No newline at end of file + }, + "id": 14, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "129:6:0", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } +} \ No newline at end of file diff --git a/remix-analyzer/test/analysis/astBlocks/lowlevelCall.json b/remix-analyzer/test/analysis/astBlocks/lowlevelCall.json index e5795ba82e..684bcc9a38 100644 --- a/remix-analyzer/test/analysis/astBlocks/lowlevelCall.json +++ b/remix-analyzer/test/analysis/astBlocks/lowlevelCall.json @@ -1,42 +1,142 @@ { - "sendAst": { "name": "MemberAccess", - "children": [ - { - "attributes": { - "value": "d", - "type": "address" - } - }], - "attributes": { - "value": "send", - "type": "function (uint256) returns (bool)" } - }, - "callAst": { "name": "MemberAccess", "children": [{ - "attributes": { - "value": "f", - "type": "address" - }}], - "attributes": { - "member_name": "call", - "type": "function () payable returns (bool)" } }, - "callcodeAst": { - "name": "MemberAccess", - "children": [{ - "attributes": { - "value": "f", - "type": "address" - }}], - "attributes": { - "member_name": "callcode", - "type": "function () payable returns (bool)" } }, - "delegatecallAst": { - "name": "MemberAccess", - "children": [{ - "attributes": { - "value": "g", - "type": "address" - }}], - "attributes": { - "member_name": "delegatecall", - "type": "function () returns (bool)" } } + "sendAst": { + "argumentTypes": + [ + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + } + ], + "expression": + { + "argumentTypes": null, + "id": 27, + "name": "addr", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4, + "src": "227:4:0", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "id": 28, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "send", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "227:9:0", + "typeDescriptions": + { + "typeIdentifier": "t_function_send_nonpayable$_t_uint256_$returns$_t_bool_$", + "typeString": "function (uint256) returns (bool)" + } + }, + "callAst": { + "argumentTypes": null, + "expression": + { + "argumentTypes": null, + "id": 9, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 6, + "src": "91:1:0", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 12, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "call", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "91:6:0", + "typeDescriptions": + { + "typeIdentifier": "t_function_barecall_payable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$", + "typeString": "function (bytes memory) payable returns (bool,bytes memory)" + } + }, + "callcodeAst": { + "argumentTypes": [], + "expression": + { + "argumentTypes": null, + "id": 3, + "name": "test", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10, + "src": "62:4:0", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_contract$_test_$10_$", + "typeString": "type(contract test)" + } + }, + "id": 5, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "callcode", + "nodeType": "MemberAccess", + "referencedDeclaration": 9, + "src": "62:13:0", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "delegatecallAst": { + "argumentTypes": + [ + { + "typeIdentifier": "t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "typeString": "literal_string \"\"" + } + ], + "expression": + { + "argumentTypes": null, + "id": 20, + "name": "addr", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4, + "src": "181:4:0", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "id": 21, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "delegatecall", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "181:17:0", + "typeDescriptions": + { + "typeIdentifier": "t_function_baredelegatecall_nonpayable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$", + "typeString": "function (bytes memory) returns (bool,bytes memory)" + } + } } \ No newline at end of file diff --git a/remix-analyzer/test/analysis/astBlocks/parameterFunction.json b/remix-analyzer/test/analysis/astBlocks/parameterFunction.json index a5c44f8255..b112f20898 100644 --- a/remix-analyzer/test/analysis/astBlocks/parameterFunction.json +++ b/remix-analyzer/test/analysis/astBlocks/parameterFunction.json @@ -1,71 +1,93 @@ { - "attributes": { + "argumentTypes": null, + "arguments": + [ + { "argumentTypes": null, + "hexValue": "32", + "id": 37, "isConstant": false, "isLValue": false, - "isPure": false, - "isStructConstructorCall": false, + "isPure": true, + "kind": "number", "lValueRequested": false, - "names": [ - null - ], - "type": "uint256", - "type_conversion": false + "nodeType": "Literal", + "src": "234:1:0", + "subdenomination": null, + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" }, - "children": [ + { + "argumentTypes": null, + "hexValue": "31", + "id": 38, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "240:1:0", + "subdenomination": null, + "typeDescriptions": { - "attributes": { - "argumentTypes": [ - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "overloadedDeclarations": [ - null - ], - "referencedDeclaration": 25, - "type": "function (uint256,uint256) pure returns (uint256)", - "value": "f" - }, - "id": 34, - "name": "Identifier", - "src": "267:1:0" + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" }, + "value": "1" + } + ], + "expression": + { + "argumentTypes": + [ { - "attributes": { - "argumentTypes": null, - "overloadedDeclarations": [ - null - ], - "referencedDeclaration": 27, - "type": "uint256", - "value": "x" - }, - "id": 35, - "name": "Identifier", - "src": "269:1:0" + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" }, { - "attributes": { - "argumentTypes": null, - "overloadedDeclarations": [ - null - ], - "referencedDeclaration": 29, - "type": "uint256", - "value": "y" - }, - "id": 36, - "name": "Identifier", - "src": "272:1:0" + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" } ], - "id": 37, - "name": "FunctionCall", - "src": "267:7:0" - } \ No newline at end of file + "id": 36, + "name": "f", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + 6, + 14, + 24 + ], + "referencedDeclaration": 14, + "src": "228:1:0", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (uint256,uint256)" + } + }, + "id": 39, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": + [ + "y", + "x" + ], + "nodeType": "FunctionCall", + "src": "228:15:0", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } +} \ No newline at end of file diff --git a/remix-analyzer/test/analysis/astBlocks/selfdestruct.json b/remix-analyzer/test/analysis/astBlocks/selfdestruct.json index 66f29de42d..04ef87be36 100644 --- a/remix-analyzer/test/analysis/astBlocks/selfdestruct.json +++ b/remix-analyzer/test/analysis/astBlocks/selfdestruct.json @@ -1,23 +1,56 @@ { - "attributes": { - "type": "tuple()", - "type_conversion": false - }, - "children": [ - { - "attributes": { - "type": "function (address)", - "value": "selfdestruct" - }, - "name": "Identifier" - }, - { - "attributes": { - "type": "address", - "value": "a" - }, - "name": "Identifier" - } - ], - "name": "FunctionCall" - } \ No newline at end of file + "argumentTypes": null, + "arguments": + [ + { + "argumentTypes": null, + "id": 6, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2, + "src": "77:1:0", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + ], + "id": 5, + "name": "selfdestruct", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -21, + "src": "64:12:0", + "typeDescriptions": + { + "typeIdentifier": "t_function_selfdestruct_nonpayable$_t_address_payable_$returns$__$", + "typeString": "function (address payable)" + } + }, + "id": 7, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "64:15:0", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } +} \ No newline at end of file diff --git a/remix-analyzer/test/analysis/astBlocks/stateVariableContractNode.json b/remix-analyzer/test/analysis/astBlocks/stateVariableContractNode.json index 1474c59b23..68bd3f3985 100644 --- a/remix-analyzer/test/analysis/astBlocks/stateVariableContractNode.json +++ b/remix-analyzer/test/analysis/astBlocks/stateVariableContractNode.json @@ -1,108 +1,336 @@ { - "attributes": { - "fullyImplemented": true, - "isLibrary": false, - "linearizedBaseContracts": [ - 274 - ], - "name": "Ballot" - }, - "children": [ + "abstract": false, + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 24, + "linearizedBaseContracts": + [ + 24 + ], + "name": "C", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": { - "attributes": { - "name": "Voter" - }, - "children": [], - "name": "StructDefinition" - }, - { - "attributes": { - "name": "Proposal" - }, - "children": [], - "name": "StructDefinition" - }, - { - "attributes": { - "name": "chairperson", - "type": "address" - }, - "children": [ - { - "attributes": { - "name": "address" - }, - "name": "ElementaryTypeName" - } - ], - "name": "VariableDeclaration" - }, - { - "attributes": { - "name": "voters", - "type": "mapping(address => struct Ballot.Voter storage ref)" - }, - "children": [ + "id": 22, + "nodeType": "Block", + "src": "52:69:0", + "statements": + [ { - "children": [ + "assignments": + [ + 10 + ], + "declarations": + [ { - "attributes": { - "name": "address" + "constant": false, + "id": 10, + "name": "z", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 22, + "src": "62:17:0", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint8_$4_memory_ptr", + "typeString": "uint8[4]" }, - "name": "ElementaryTypeName" - }, - { - "attributes": { - "name": "Voter" + "typeName": + { + "baseType": + { + "id": 8, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "62:5:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "id": 9, + "length": + { + "argumentTypes": null, + "hexValue": "34", + "id": 7, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "68:1:0", + "subdenomination": null, + "typeDescriptions": + { + "typeIdentifier": "t_rational_4_by_1", + "typeString": "int_const 4" + }, + "value": "4" + }, + "nodeType": "ArrayTypeName", + "src": "62:8:0", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint8_$4_storage_ptr", + "typeString": "uint8[4]" + } }, - "name": "UserDefinedTypeName" + "value": null, + "visibility": "internal" } ], - "name": "Mapping" + "id": 16, + "initialValue": + { + "argumentTypes": null, + "components": + [ + { + "argumentTypes": null, + "hexValue": "31", + "id": 11, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "83:1:0", + "subdenomination": null, + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + { + "argumentTypes": null, + "hexValue": "32", + "id": 12, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "85:1:0", + "subdenomination": null, + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + { + "argumentTypes": null, + "hexValue": "33", + "id": 13, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "87:1:0", + "subdenomination": null, + "typeDescriptions": + { + "typeIdentifier": "t_rational_3_by_1", + "typeString": "int_const 3" + }, + "value": "3" + }, + { + "argumentTypes": null, + "hexValue": "35", + "id": 14, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "89:1:0", + "subdenomination": null, + "typeDescriptions": + { + "typeIdentifier": "t_rational_5_by_1", + "typeString": "int_const 5" + }, + "value": "5" + } + ], + "id": 15, + "isConstant": false, + "isInlineArray": true, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "82:9:0", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint8_$4_memory_ptr", + "typeString": "uint8[4] memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "62:29:0" + }, + { + "expression": + { + "argumentTypes": null, + "components": + [ + { + "argumentTypes": null, + "baseExpression": + { + "argumentTypes": null, + "id": 17, + "name": "z", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10, + "src": "109:1:0", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint8_$4_memory_ptr", + "typeString": "uint8[4] memory" + } + }, + "id": 19, + "indexExpression": + { + "argumentTypes": null, + "hexValue": "30", + "id": 18, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "111:1:0", + "subdenomination": null, + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "109:4:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + } + ], + "id": 20, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "108:6:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "functionReturnParameters": 4, + "id": 21, + "nodeType": "Return", + "src": "101:13:0" } - ], - "name": "VariableDeclaration" + ] + }, + "documentation": null, + "functionSelector": "26121ff0", + "id": 23, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nodeType": "FunctionDefinition", + "overrides": null, + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "27:2:0" }, + "returnParameters": { - "attributes": { - "name": "proposals", - "type": "struct Ballot.Proposal storage ref[] storage ref" - }, - "children": [ + "id": 4, + "nodeType": "ParameterList", + "parameters": + [ { - "children": [ + "constant": false, + "id": 3, + "name": "", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 23, + "src": "46:4:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "46:4:0", + "typeDescriptions": { - "attributes": { - "name": "Proposal" - }, - "name": "UserDefinedTypeName" + "typeIdentifier": "t_uint256", + "typeString": "uint256" } - ], - "name": "ArrayTypeName" + }, + "value": null, + "visibility": "internal" } ], - "name": "VariableDeclaration" - }, - { - "attributes": { - "constant": false, - "name": "Ballot", - "payable": false, - "visibility": "public" - }, - "children": [], - "name": "FunctionDefinition" + "src": "45:6:0" }, - { - "attributes": { - "constant": false, - "name": "giveRightToVote", - "payable": false, - "visibility": "public" - }, - "children": [], - "name": "FunctionDefinition" - } - ], - "name": "ContractDefinition" - } \ No newline at end of file + "scope": 24, + "src": "17:104:0", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 25, + "src": "0:123:0" +} \ No newline at end of file diff --git a/remix-analyzer/test/analysis/astBlocks/superLocal.json b/remix-analyzer/test/analysis/astBlocks/superLocal.json index 7a5b8b7bdf..7655966f1d 100644 --- a/remix-analyzer/test/analysis/astBlocks/superLocal.json +++ b/remix-analyzer/test/analysis/astBlocks/superLocal.json @@ -1,16 +1,32 @@ { - "attributes": { - "member_name": "duper", - "type": "function ()" - }, - "children": [ + "argumentTypes": [], + "expression": + { + "argumentTypes": null, + "id": 10, + "name": "super", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -25, + "src": "162:5:0", + "typeDescriptions": { - "attributes": { - "type": "contract super a", - "value": "super" - }, - "name": "Identifier" + "typeIdentifier": "t_super$_B_$17", + "typeString": "contract super B" } - ], - "name": "MemberAccess" + }, + "id": 12, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "x", + "nodeType": "MemberAccess", + "referencedDeclaration": 4, + "src": "162:7:0", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_pure$__$returns$__$", + "typeString": "function () pure" + } } \ No newline at end of file diff --git a/remix-analyzer/test/analysis/astBlocks/thisLocalCall.json b/remix-analyzer/test/analysis/astBlocks/thisLocalCall.json index df88de3247..5cbcebe82a 100644 --- a/remix-analyzer/test/analysis/astBlocks/thisLocalCall.json +++ b/remix-analyzer/test/analysis/astBlocks/thisLocalCall.json @@ -1,10 +1,32 @@ -{ - "name": "MemberAccess", - "children": [ { - "attributes": { - "value": "this", - "type": "contract test" }, - "name": "Identifier" } ], - "attributes": { - "value": "b", - "type": "function (bytes32,address) returns (bool)" } } \ No newline at end of file +{ + "argumentTypes": null, + "expression": + { + "argumentTypes": null, + "id": 13, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -28, + "src": "138:4:0", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_C_$21", + "typeString": "contract C" + } + }, + "id": 14, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "h", + "nodeType": "MemberAccess", + "referencedDeclaration": 4, + "src": "138:6:0", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_payable$__$returns$__$", + "typeString": "function () payable external" + } +} \ No newline at end of file diff --git a/remix-analyzer/test/analysis/astBlocks/whileLoopNode.json b/remix-analyzer/test/analysis/astBlocks/whileLoopNode.json index 85dcb5a327..0f05c2c6ce 100644 --- a/remix-analyzer/test/analysis/astBlocks/whileLoopNode.json +++ b/remix-analyzer/test/analysis/astBlocks/whileLoopNode.json @@ -1,204 +1,101 @@ { - "children": - [ + "body": + { + "id": 13, + "nodeType": "Block", + "src": "89:27:0", + "statements": + [ + { + "expression": + { + "argumentTypes": null, + "id": 9, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { - "attributes": + "argumentTypes": null, + "id": 7, + "name": "x", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4, + "src": "91:1:0", + "typeDescriptions": { - "argumentTypes": null, - "commonType": - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "operator": "<", - "type": "bool" + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "argumentTypes": null, + "hexValue": "31", + "id": 8, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "95:1:0", + "subdenomination": null, + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" }, - "children": - [ - { - "attributes": - { - "argumentTypes": null, - "overloadedDeclarations": - [ - null - ], - "referencedDeclaration": 45, - "type": "uint256", - "value": "i" - }, - "id": 48, - "name": "Identifier", - "src": "372:1:0" - }, - { - "attributes": - { - "argumentTypes": null, - "hexvalue": "3130", - "isConstant": false, - "isLValue": false, - "isPure": true, - "lValueRequested": false, - "subdenomination": null, - "token": "number", - "type": "int_const 10", - "value": "10" - }, - "id": 49, - "name": "Literal", - "src": "376:2:0" - } - ], - "id": 50, - "name": "BinaryOperation", - "src": "372:6:0" + "value": "1" }, + "src": "91:5:0", + "typeDescriptions": { - "children": - [ - { - "children": - [ - { - "attributes": - { - "argumentTypes": null, - "isConstant": false, - "isLValue": false, - "isPure": false, - "isStructConstructorCall": false, - "lValueRequested": false, - "names": - [ - null - ], - "type": "uint256", - "type_conversion": false - }, - "children": - [ - { - "attributes": - { - "argumentTypes": - [ - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "member_name": "push", - "referencedDeclaration": null, - "type": "function (uint256) returns (uint256)" - }, - "children": - [ - { - "attributes": - { - "argumentTypes": null, - "overloadedDeclarations": - [ - null - ], - "referencedDeclaration": 4, - "type": "uint256[] storage ref", - "value": "array" - }, - "id": 51, - "name": "Identifier", - "src": "394:5:0" - } - ], - "id": 53, - "name": "MemberAccess", - "src": "394:10:0" - }, - { - "attributes": - { - "argumentTypes": null, - "overloadedDeclarations": - [ - null - ], - "referencedDeclaration": 45, - "type": "uint256", - "value": "i" - }, - "id": 54, - "name": "Identifier", - "src": "405:1:0" - } - ], - "id": 55, - "name": "FunctionCall", - "src": "394:13:0" - } - ], - "id": 56, - "name": "ExpressionStatement", - "src": "394:13:0" - }, - { - "children": - [ - { - "attributes": - { - "argumentTypes": null, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "operator": "++", - "prefix": false, - "type": "uint256" - }, - "children": - [ - { - "attributes": - { - "argumentTypes": null, - "overloadedDeclarations": - [ - null - ], - "referencedDeclaration": 45, - "type": "uint256", - "value": "i" - }, - "id": 57, - "name": "Identifier", - "src": "421:1:0" - } - ], - "id": 58, - "name": "UnaryOperation", - "src": "421:3:0" - } - ], - "id": 59, - "name": "ExpressionStatement", - "src": "421:3:0" - } - ], - "id": 60, - "name": "Block", - "src": "380:55:0" + "typeIdentifier": "t_uint256", + "typeString": "uint256" } - ], - "id": 61, - "name": "WhileStatement", - "src": "365:70:0" - } \ No newline at end of file + }, + "id": 10, + "nodeType": "ExpressionStatement", + "src": "91:5:0" + }, + { + "id": 11, + "nodeType": "Break", + "src": "98:5:0" + }, + { + "id": 12, + "nodeType": "Continue", + "src": "105:8:0" + } + ] + }, + "condition": + { + "argumentTypes": null, + "hexValue": "74727565", + "id": 6, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "83:4:0", + "subdenomination": null, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "id": 14, + "nodeType": "WhileStatement", + "src": "76:40:0" +} \ No newline at end of file diff --git a/remix-analyzer/test/analysis/staticAnalysisCommon-test.ts b/remix-analyzer/test/analysis/staticAnalysisCommon-test.ts index 8dcfa00f22..6abacf753b 100644 --- a/remix-analyzer/test/analysis/staticAnalysisCommon-test.ts +++ b/remix-analyzer/test/analysis/staticAnalysisCommon-test.ts @@ -103,36 +103,36 @@ test('staticAnalysisCommon.helpers.expressionType', function (t) { lowlevelAccessersCommon(t, common.helpers.expressionType, node) }) -test('staticAnalysisCommon.helpers.nrOfChildren', function (t) { - t.plan(10) - const node = { name: 'Identifier', children: ['a', 'b'], attributes: { value: 'now', type: 'uint256' } } - const node2 = { name: 'FunctionCall', children: [], attributes: { member_name: 'call', type: 'function () payable returns (bool)' } } - const node3 = { name: 'FunctionCall', attributes: { member_name: 'call', type: 'function () payable returns (bool)' } } - - t.ok(common.helpers.nrOfChildren(node, 2), 'should work for 2 children') - t.notOk(common.helpers.nrOfChildren(node, '1+2'), 'regex should not work') - t.ok(common.helpers.nrOfChildren(node2, 0), 'should work for 0 children') - t.ok(common.helpers.nrOfChildren(node3, 0), 'should work without children arr') - - lowlevelAccessersCommon(t, common.helpers.nrOfChildren, node) -}) - -test('staticAnalysisCommon.helpers.minNrOfChildren', function (t) { - t.plan(13) - const node = { name: 'Identifier', children: ['a', 'b'], attributes: { value: 'now', type: 'uint256' } } - const node2 = { name: 'FunctionCall', children: [], attributes: { member_name: 'call', type: 'function () payable returns (bool)' } } - const node3 = { name: 'FunctionCall', attributes: { member_name: 'call', type: 'function () payable returns (bool)' } } - - t.ok(common.helpers.minNrOfChildren(node, 2), 'should work for 2 children') - t.ok(common.helpers.minNrOfChildren(node, 1), 'should work for 1 children') - t.ok(common.helpers.minNrOfChildren(node, 0), 'should work for 0 children') - t.notOk(common.helpers.minNrOfChildren(node, 3), 'has less than 3 children') - t.notOk(common.helpers.minNrOfChildren(node, '1+2'), 'regex should not work') - t.ok(common.helpers.minNrOfChildren(node2, 0), 'should work for 0 children') - t.ok(common.helpers.minNrOfChildren(node3, 0), 'should work without children arr') +// test('staticAnalysisCommon.helpers.nrOfChildren', function (t) { +// t.plan(10) +// const node = { name: 'Identifier', children: ['a', 'b'], attributes: { value: 'now', type: 'uint256' } } +// const node2 = { name: 'FunctionCall', children: [], attributes: { member_name: 'call', type: 'function () payable returns (bool)' } } +// const node3 = { name: 'FunctionCall', attributes: { member_name: 'call', type: 'function () payable returns (bool)' } } + +// t.ok(common.helpers.nrOfChildren(node, 2), 'should work for 2 children') +// t.notOk(common.helpers.nrOfChildren(node, '1+2'), 'regex should not work') +// t.ok(common.helpers.nrOfChildren(node2, 0), 'should work for 0 children') +// t.ok(common.helpers.nrOfChildren(node3, 0), 'should work without children arr') + +// lowlevelAccessersCommon(t, common.helpers.nrOfChildren, node) +// }) - lowlevelAccessersCommon(t, common.helpers.minNrOfChildren, node) -}) +// test('staticAnalysisCommon.helpers.minNrOfChildren', function (t) { +// t.plan(13) +// const node = { name: 'Identifier', children: ['a', 'b'], attributes: { value: 'now', type: 'uint256' } } +// const node2 = { name: 'FunctionCall', children: [], attributes: { member_name: 'call', type: 'function () payable returns (bool)' } } +// const node3 = { name: 'FunctionCall', attributes: { member_name: 'call', type: 'function () payable returns (bool)' } } + +// t.ok(common.helpers.minNrOfChildren(node, 2), 'should work for 2 children') +// t.ok(common.helpers.minNrOfChildren(node, 1), 'should work for 1 children') +// t.ok(common.helpers.minNrOfChildren(node, 0), 'should work for 0 children') +// t.notOk(common.helpers.minNrOfChildren(node, 3), 'has less than 3 children') +// t.notOk(common.helpers.minNrOfChildren(node, '1+2'), 'regex should not work') +// t.ok(common.helpers.minNrOfChildren(node2, 0), 'should work for 0 children') +// t.ok(common.helpers.minNrOfChildren(node3, 0), 'should work without children arr') + +// lowlevelAccessersCommon(t, common.helpers.minNrOfChildren, node) +// }) function lowlevelAccessersCommon (t, f, someNode) { t.ok(f(someNode), 'always ok if type is undefinded') @@ -146,14 +146,22 @@ function lowlevelAccessersCommon (t, f, someNode) { // #################### Trivial Getter Test test('staticAnalysisCommon.getType', function (t) { - t.plan(3) - const node = { name: 'Identifier', children: ['a', 'b'], attributes: { value: 'now', type: 'uint256' } } - const node2 = { name: 'FunctionCall', children: [], attributes: { member_name: 'call', type: 'function () payable returns (bool)' } } - const node3 = { name: 'FunctionCall', attributes: { member_name: 'call', type: 'function () payable returns (bool)' } } - + t.plan(2) + const node = { "argumentTypes": null, + "id": 3, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22, + "src": "52:1:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + t.ok(common.getType(blockHashAccess) === 'function (uint256) view returns (bytes32)', 'gettype should work for different nodes') t.ok(common.getType(node) === 'uint256', 'gettype should work for different nodes') - t.ok(common.getType(node2) === 'function () payable returns (bool)', 'gettype should work for different nodes') - t.ok(common.getType(node3) === 'function () payable returns (bool)', 'gettype should work for different nodes') }) // #################### Complex Getter Test @@ -297,110 +305,6 @@ test('staticAnalysisCommon.getFullQuallyfiedFuncDefinitionIdent', function (t) { t.throws(() => common.getFullQuallyfiedFuncDefinitionIdent({ name: 'FunctionCall' }, fullyQualifiedFunctionDefinition, ['uint256', 'bool']), Error, 'throws on wrong nodes') }) -test('staticAnalysisCommon.getLoopBlockStartIndex', function (t) { - t.plan(3) - t.equal(common.getLoopBlockStartIndex(forLoopNode), 3) // 'for' loop - t.equal(common.getLoopBlockStartIndex(doWhileLoopNode), 1) // 'do-while' loop - t.equal(common.getLoopBlockStartIndex(whileLoopNode), 1) // 'while' loop -}) - -// #################### Trivial Node Identification - -// test('staticAnalysisCommon.isFunctionDefinition', function (t) { -// t.plan(3) -// const node1 = { name: 'FunctionDefinition' } -// const node2 = { name: 'MemberAccess' } -// const node3 = { name: 'FunctionDefinitionBLABLA' } - -// t.ok(common.isFunctionDefinition(node1), 'is exact match should work') -// t.notOk(common.isFunctionDefinition(node2), 'different node should not work') -// t.notOk(common.isFunctionDefinition(node3), 'substring should not work') -// }) - -// test('staticAnalysisCommon.isModifierDefinition', function (t) { -// t.plan(3) -// const node1 = { name: 'ModifierDefinition' } -// const node2 = { name: 'MemberAccess' } -// const node3 = { name: 'ModifierDefinitionBLABLA' } - -// t.ok(common.isModifierDefinition(node1), 'is exact match should work') -// t.notOk(common.isModifierDefinition(node2), 'different node should not work') -// t.notOk(common.isModifierDefinition(node3), 'substring should not work') -// }) - -// test('staticAnalysisCommon.isModifierInvocation', function (t) { -// t.plan(3) -// const node1 = { name: 'ModifierInvocation' } -// const node2 = { name: 'MemberAccess' } -// const node3 = { name: 'ModifierInvocationBLABLA' } - -// t.ok(common.isModifierInvocation(node1), 'is exact match should work') -// t.notOk(common.isModifierInvocation(node2), 'different node should not work') -// t.notOk(common.isModifierInvocation(node3), 'substring should not work') -// }) - -// test('staticAnalysisCommon.isVariableDeclaration', function (t) { -// t.plan(3) -// const node1 = { name: 'VariableDeclaration' } -// const node2 = { name: 'MemberAccess' } -// const node3 = { name: 'VariableDeclarationBLABLA' } - -// t.ok(common.isVariableDeclaration(node1), 'is exact match should work') -// t.notOk(common.isVariableDeclaration(node2), 'different node should not work') -// t.notOk(common.isVariableDeclaration(node3), 'substring should not work') -// }) - -// test('staticAnalysisCommon.isInheritanceSpecifier', function (t) { -// t.plan(3) -// const node1 = { name: 'InheritanceSpecifier' } -// const node2 = { name: 'MemberAccess' } -// const node3 = { name: 'InheritanceSpecifierBLABLA' } - -// t.ok(common.isInheritanceSpecifier(node1), 'is exact match should work') -// t.notOk(common.isInheritanceSpecifier(node2), 'different node should not work') -// t.notOk(common.isInheritanceSpecifier(node3), 'substring should not work') -// }) - -// test('staticAnalysisCommon.isAssignment', function (t) { -// t.plan(3) -// const node1 = { name: 'Assignment' } -// const node2 = { name: 'MemberAccess' } -// const node3 = { name: 'AssignmentBLABLA' } - -// t.ok(common.isAssignment(node1), 'is exact match should work') -// t.notOk(common.isAssignment(node2), 'different node should not work') -// t.notOk(common.isAssignment(node3), 'substring should not work') -// }) - -// test('staticAnalysisCommon.isContractDefinition', function (t) { -// t.plan(3) -// const node1 = { name: 'ContractDefinition' } -// const node2 = { name: 'MemberAccess' } -// const node3 = { name: 'ContractDefinitionBLABLA' } - -// t.ok(common.isContractDefinition(node1), 'is exact match should work') -// t.notOk(common.isContractDefinition(node2), 'different node should not work') -// t.notOk(common.isContractDefinition(node3), 'substring should not work') -// }) - -// test('staticAnalysisCommon.isInlineAssembly', function (t) { -// t.plan(3) -// const node1 = { name: 'InlineAssembly' } -// const node2 = { name: 'MemberAccess' } -// const node3 = { name: 'InlineAssemblyBLABLA' } - -// t.ok(common.isInlineAssembly(node1), 'is exact match should work') -// t.notOk(common.isInlineAssembly(node2), 'different node should not work') -// t.notOk(common.isInlineAssembly(node3), 'substring should not work') -// }) - -// test('staticAnalysisCommon.isLoop', function (t) { -// t.plan(3) -// t.equal(common.isLoop(forLoopNode), true) -// t.equal(common.isLoop(doWhileLoopNode), true) -// t.equal(common.isLoop(whileLoopNode), true) -// }) - // #################### Complex Node Identification test('staticAnalysisCommon.isBuiltinFunctionCall', function (t) { diff --git a/remix-analyzer/test/analysis/test-contracts/solidity-v0.5/library.sol b/remix-analyzer/test/analysis/test-contracts/solidity-v0.5/library.sol index 0f89a014f3..5405b5f3f0 100644 --- a/remix-analyzer/test/analysis/test-contracts/solidity-v0.5/library.sol +++ b/remix-analyzer/test/analysis/test-contracts/solidity-v0.5/library.sol @@ -1,4 +1,4 @@ -pragma solidity >=0.4.9 <0.6.0; +pragma solidity >=0.4.9 <0.7.0; library Set { // We define a new struct datatype that will be used to @@ -50,5 +50,9 @@ contract C { if (!Set.insert(knownValues, value)) revert(); } + + function tests2() public { + this.register(10); + } // In this contract, we can also directly access knownValues.flags, if we want. } \ No newline at end of file