Commit 2657a39e authored by aniket-engg's avatar aniket-engg

separate ast blocks

parent 4507a805
{
"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
{
"children":
[
{
"attributes":
{
"argumentTypes": null,
"commonType":
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"operator": "<",
"type": "bool"
},
"children":
[
{
"attributes":
{
"argumentTypes": null,
"overloadedDeclarations":
[
null
],
"referencedDeclaration": 69,
"type": "uint256",
"value": "i"
},
"id": 82,
"name": "Identifier",
"src": "592: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": 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"
},
{
"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"
}
],
"id": 81,
"name": "Block",
"src": "530:55:0"
}
],
"id": 85,
"name": "DoWhileStatement",
"src": "528:72:0"
}
\ No newline at end of file
{
"attributes": {
"member_name": "info",
"type": "function () payable external returns (uint256)"
},
"children": [
{
"attributes": {
"type": "contract InfoFeed",
"value": "f"
},
"id": 30,
"name": "Identifier",
"src": "405:1:0"
}
],
"id": 32,
"name": "MemberAccess",
"src": "405:6:0"
}
\ No newline at end of file
{
"children":
[
{
"attributes":
{
"assignments":
[
21
]
},
"children":
[
{
"attributes":
{
"constant": false,
"name": "i",
"scope": 39,
"stateVariable": false,
"storageLocation": "default",
"type": "uint256",
"value": null,
"visibility": "internal"
},
"children":
[
{
"attributes":
{
"name": "uint",
"type": "uint256"
},
"id": 20,
"name": "ElementaryTypeName",
"src": "207:4:0"
}
],
"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"
}
],
"id": 23,
"name": "VariableDeclarationStatement",
"src": "207:14:0"
},
{
"attributes":
{
"argumentTypes": null,
"commonType":
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"operator": "<",
"type": "bool"
},
"children":
[
{
"attributes":
{
"argumentTypes": null,
"overloadedDeclarations":
[
null
],
"referencedDeclaration": 21,
"type": "uint256",
"value": "i"
},
"id": 24,
"name": "Identifier",
"src": "223: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": 25,
"name": "Literal",
"src": "227:2:0"
}
],
"id": 26,
"name": "BinaryOperation",
"src": "223:6: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": 21,
"type": "uint256",
"value": "i"
},
"id": 27,
"name": "Identifier",
"src": "231:1:0"
}
],
"id": 28,
"name": "UnaryOperation",
"src": "231:3:0"
}
],
"id": 29,
"name": "ExpressionStatement",
"src": "231:3: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": 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"
}
],
"id": 36,
"name": "Block",
"src": "236:38:0"
}
],
"id": 37,
"name": "ForStatement",
"src": "202:72:0"
}
\ No newline at end of file
module.exports = {
localCall: require('./localCall.json'),
thisLocalCall: require('./thisLocalCall.json'),
libCall: require('./libCall.json'),
externalDirect: require('./externalDirect.json'),
superLocal: require('./superLocal.json'),
assignment: require('./assignment.json'),
inlineAssembly: require('./inlineAssembly.json'),
forLoopNode: require('./forLoopNode.json'),
whileLoopNode: require('./whileLoopNode.json'),
doWhileLoopNode: require('./doWhileLoopNode.json')
}
{
"children": [
],
"id": 21,
"name": "InlineAssembly",
"src": "809:41:0"
}
\ No newline at end of file
{
"attributes": {
"member_name": "insert",
"type": "function (struct Set.Data storage pointer,uint256) returns (bool)"
},
"children": [
{
"attributes": {
"type": "type(library Set)",
"value": "Set"
},
"name": "Identifier"
}
],
"name": "MemberAccess"
}
\ No newline at end of file
{
"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"
},
{
"attributes": {
"type": "struct Ballot.Voter storage pointer",
"value": "x"
},
"id": 38,
"name": "Identifier",
"src": "544:1:0"
}
],
"id": 39,
"name": "FunctionCall",
"src": "540:6:0"
}
\ No newline at end of file
{
"attributes": {
"member_name": "duper",
"type": "function ()"
},
"children": [
{
"attributes": {
"type": "contract super a",
"value": "super"
},
"name": "Identifier"
}
],
"name": "MemberAccess"
}
\ No newline at end of file
{
"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
{
"children":
[
{
"attributes":
{
"argumentTypes": null,
"commonType":
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"operator": "<",
"type": "bool"
},
"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"
},
{
"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"
}
],
"id": 61,
"name": "WhileStatement",
"src": "365:70:0"
}
\ No newline at end of file
var test = require('tape')
var common = require('../../src/solidity-analyzer/modules/staticAnalysisCommon')
var { localCall, thisLocalCall, libCall, externalDirect, superLocal, assignment,
inlineAssembly, forLoopNode, whileLoopNode, doWhileLoopNode } = require('./astBlocks')
function escapeRegExp (str) {
return str.replace(/[-[\]/{}()+?.\\^$|]/g, '\\$&')
......@@ -157,2416 +158,517 @@ test('staticAnalysisCommon.getType', function (t) {
test('staticAnalysisCommon.getFunctionCallType', function (t) {
t.plan(5)
var localCall = {
'attributes': {
'type': 'tuple()',
'type_conversion': false
},
t.equal(common.getFunctionCallType(libCall), 'function (struct Set.Data storage pointer,uint256) returns (bool)', 'this lib call returns correct type')
t.equal(common.getFunctionCallType(thisLocalCall), 'function (bytes32,address) returns (bool)', 'this local call returns correct type')
t.equal(common.getFunctionCallType(externalDirect), 'function () payable external returns (uint256)', 'external direct call returns correct type')
t.equal(common.getFunctionCallType(localCall), 'function (struct Ballot.Voter storage pointer)', 'local call returns correct type')
t.throws(() => common.getFunctionCallType({ name: 'MemberAccess' }), undefined, 'throws on wrong type')
})
test('staticAnalysisCommon.getEffectedVariableName', function (t) {
t.plan(3)
t.throws(() => common.getEffectedVariableName(inlineAssembly), 'staticAnalysisCommon.js: not an effect Node or inline assembly', 'get from inline assembly should throw')
t.ok(common.getEffectedVariableName(assignment) === 'c', 'get right name for assignment')
t.throws(() => common.getEffectedVariableName({ name: 'MemberAccess' }), undefined, 'should throw on all other nodes')
})
test('staticAnalysisCommon.getLocalCallName', function (t) {
t.plan(3)
t.ok(common.getLocalCallName(localCall) === 'bli', 'getLocal call name from node')
t.throws(() => common.getLocalCallName(externalDirect), undefined, 'throws on other nodes')
t.throws(() => common.getLocalCallName(thisLocalCall), undefined, 'throws on other nodes')
})
test('staticAnalysisCommon.getThisLocalCallName', function (t) {
t.plan(3)
t.ok(common.getThisLocalCallName(thisLocalCall) === 'b', 'get this Local call name from node')
t.throws(() => common.getThisLocalCallName(externalDirect), undefined, 'throws on other nodes')
t.throws(() => common.getThisLocalCallName(localCall), undefined, 'throws on other nodes')
})
test('staticAnalysisCommon.getSuperLocalCallName', function (t) {
t.plan(4)
t.equal(common.getSuperLocalCallName(superLocal), 'duper', 'get local name from super local call')
t.throws(() => common.getSuperLocalCallName(thisLocalCall), 'throws on other nodes')
t.throws(() => common.getSuperLocalCallName(externalDirect), undefined, 'throws on other nodes')
t.throws(() => common.getSuperLocalCallName(localCall), undefined, 'throws on other nodes')
})
test('staticAnalysisCommon.getExternalDirectCallContractName', function (t) {
t.plan(3)
t.ok(common.getExternalDirectCallContractName(externalDirect) === 'InfoFeed', 'external direct call contract name from node')
t.throws(() => common.getExternalDirectCallContractName(thisLocalCall), undefined, 'throws on other nodes')
t.throws(() => common.getExternalDirectCallContractName(localCall), undefined, 'throws on other nodes')
})
test('staticAnalysisCommon.getThisLocalCallContractName', function (t) {
t.plan(3)
t.ok(common.getThisLocalCallContractName(thisLocalCall) === 'test', 'this local call contract name from node')
t.throws(() => common.getThisLocalCallContractName(localCall), undefined, 'throws on other nodes')
t.throws(() => common.getThisLocalCallContractName(externalDirect), undefined, 'throws on other nodes')
})
test('staticAnalysisCommon.getExternalDirectCallMemberName', function (t) {
t.plan(3)
t.ok(common.getExternalDirectCallMemberName(externalDirect) === 'info', 'external direct call name from node')
t.throws(() => common.getExternalDirectCallMemberName(thisLocalCall), undefined, 'throws on other nodes')
t.throws(() => common.getExternalDirectCallMemberName(localCall), undefined, 'throws on other nodes')
})
test('staticAnalysisCommon.getContractName', function (t) {
t.plan(2)
var contract = { name: 'ContractDefinition', attributes: { name: 'baz' } }
t.ok(common.getContractName(contract) === 'baz', 'returns right contract name')
t.throws(() => common.getContractName({ name: 'InheritanceSpecifier' }), undefined, 'throws on other nodes')
})
test('staticAnalysisCommon.getFunctionDefinitionName', function (t) {
t.plan(2)
var func = { name: 'FunctionDefinition', attributes: { name: 'foo' } }
t.ok(common.getFunctionDefinitionName(func) === 'foo', 'returns right contract name')
t.throws(() => common.getFunctionDefinitionName({ name: 'InlineAssembly' }), undefined, 'throws on other nodes')
})
test('staticAnalysisCommon.getInheritsFromName', function (t) {
t.plan(2)
var inh = {
'children': [
{
'attributes': {
'type': 'function (struct Ballot.Voter storage pointer)',
'value': 'bli'
},
'id': 37,
'name': 'Identifier',
'src': '540:3:0'
},
{
'attributes': {
'type': 'struct Ballot.Voter storage pointer',
'value': 'x'
},
'id': 38,
'name': 'Identifier',
'src': '544:1:0'
}
],
'id': 39,
'name': 'FunctionCall',
'src': '540:6:0'
}
var thisLocalCall = { name: 'MemberAccess', children: [ { attributes: { value: 'this', type: 'contract test' }, name: 'Identifier' } ], attributes: { value: 'b', type: 'function (bytes32,address) returns (bool)' } }
var externalDirect = {
attributes: {
member_name: 'info',
type: 'function () payable external returns (uint256)'
},
children: [
{
attributes: {
type: 'contract InfoFeed',
value: 'f'
'name': 'r'
},
id: 30,
name: 'Identifier',
src: '405:1:0'
'id': 7,
'name': 'UserDefinedTypeName',
'src': '84:1:0'
}
],
id: 32,
name: 'MemberAccess',
src: '405:6:0'
'id': 8,
'name': 'InheritanceSpecifier',
'src': '84:1:0'
}
var libCall = {
t.ok(common.getInheritsFromName(inh) === 'r', 'returns right contract name')
t.throws(() => common.getInheritsFromName({ name: 'ElementaryTypeName' }), undefined, 'throws on other nodes')
})
test('staticAnalysisCommon.getDeclaredVariableName', function (t) {
t.plan(2)
var node1 = {
'attributes': {
'member_name': 'insert',
'type': 'function (struct Set.Data storage pointer,uint256) returns (bool)'
'name': 'x',
'type': 'struct Ballot.Voter storage pointer'
},
'children': [
{
'attributes': {
'type': 'type(library Set)',
'value': 'Set'
'name': 'Voter'
},
'name': 'Identifier'
'id': 43,
'name': 'UserDefinedTypeName',
'src': '604:5:0'
}
],
'name': 'MemberAccess'
'id': 44,
'name': 'VariableDeclaration',
'src': '604:15:0'
}
t.equal(common.getFunctionCallType(libCall), 'function (struct Set.Data storage pointer,uint256) returns (bool)', 'this lib call returns correct type')
t.equal(common.getFunctionCallType(thisLocalCall), 'function (bytes32,address) returns (bool)', 'this local call returns correct type')
t.equal(common.getFunctionCallType(externalDirect), 'function () payable external returns (uint256)', 'external direct call returns correct type')
t.equal(common.getFunctionCallType(localCall), 'function (struct Ballot.Voter storage pointer)', 'local call returns correct type')
t.throws(() => common.getFunctionCallType({ name: 'MemberAccess' }), undefined, 'throws on wrong type')
t.ok(common.getDeclaredVariableName(node1) === 'x', 'extract right variable name')
node1.name = 'FunctionCall'
t.throws(() => common.getDeclaredVariableName(node1) === 'x', undefined, 'throw if wrong node')
})
test('staticAnalysisCommon.getEffectedVariableName', function (t) {
t.plan(3)
var assignment = {
test('staticAnalysisCommon.getStateVariableDeclarationsFormContractNode', function (t) {
t.plan(4)
var contract = {
'attributes': {
'operator': '=',
'type': 'uint256'
'fullyImplemented': true,
'isLibrary': false,
'linearizedBaseContracts': [
274
],
'name': 'Ballot'
},
'children': [
{
'attributes': {
'type': 'uint256'
'name': 'Voter'
},
'children': [],
'name': 'StructDefinition'
},
'children': [
{
'attributes': {
'type': 'mapping(address => uint256)',
'value': 'c'
'name': 'Proposal'
},
'id': 61,
'name': 'Identifier',
'src': '873:1:0'
'children': [],
'name': 'StructDefinition'
},
{
'attributes': {
'member_name': 'sender',
'name': 'chairperson',
'type': 'address'
},
'children': [
{
'attributes': {
'type': 'msg',
'value': 'msg'
'name': 'address'
},
'id': 62,
'name': 'Identifier',
'src': '875:3:0'
}
],
'id': 63,
'name': 'MemberAccess',
'src': '875:10:0'
'name': 'ElementaryTypeName'
}
],
'id': 64,
'name': 'IndexAccess',
'src': '873:13:0'
'name': 'VariableDeclaration'
},
{
'attributes': {
'hexvalue': '30',
'subdenomination': null,
'token': null,
'type': 'int_const 0',
'value': '0'
'name': 'voters',
'type': 'mapping(address => struct Ballot.Voter storage ref)'
},
'id': 65,
'name': 'Literal',
'src': '889:1:0'
}
],
'id': 66,
'name': 'Assignment',
'src': '873:17:0'
}
var inlineAssembly = {
'children': [
],
'id': 21,
'name': 'InlineAssembly',
'src': '809:41:0'
}
t.throws(() => common.getEffectedVariableName(inlineAssembly), 'staticAnalysisCommon.js: not an effect Node or inline assembly', 'get from inline assembly should throw')
t.ok(common.getEffectedVariableName(assignment) === 'c', 'get right name for assignment')
t.throws(() => common.getEffectedVariableName({ name: 'MemberAccess' }), undefined, 'should throw on all other nodes')
})
test('staticAnalysisCommon.getLocalCallName', function (t) {
t.plan(3)
var localCall = {
'attributes': {
'type': 'tuple()',
'type_conversion': false
},
{
'children': [
{
'attributes': {
'type': 'function (struct Ballot.Voter storage pointer)',
'value': 'bli'
'name': 'address'
},
'id': 37,
'name': 'Identifier',
'src': '540:3:0'
'name': 'ElementaryTypeName'
},
{
'attributes': {
'type': 'struct Ballot.Voter storage pointer',
'value': 'x'
'name': 'Voter'
},
'id': 38,
'name': 'Identifier',
'src': '544:1:0'
'name': 'UserDefinedTypeName'
}
],
'id': 39,
'name': 'FunctionCall',
'src': '540:6:0'
'name': 'Mapping'
}
var thisLocalCall = { name: 'MemberAccess', children: [ { attributes: { value: 'this', type: 'contract test' }, name: 'Identifier' } ], attributes: { value: 'b', type: 'function (bytes32,address) returns (bool)' } }
var externalDirect = {
attributes: {
member_name: 'info',
type: 'function () payable external returns (uint256)'
},
children: [
],
'name': 'VariableDeclaration'
},
{
attributes: {
type: 'contract InfoFeed',
value: 'f'
'attributes': {
'name': 'proposals',
'type': 'struct Ballot.Proposal storage ref[] storage ref'
},
id: 30,
name: 'Identifier',
src: '405:1:0'
'children': [
{
'children': [
{
'attributes': {
'name': 'Proposal'
},
'name': 'UserDefinedTypeName'
}
],
id: 32,
name: 'MemberAccess',
src: '405:6:0'
'name': 'ArrayTypeName'
}
t.ok(common.getLocalCallName(localCall) === 'bli', 'getLocal call name from node')
t.throws(() => common.getLocalCallName(externalDirect), undefined, 'throws on other nodes')
t.throws(() => common.getLocalCallName(thisLocalCall), undefined, 'throws on other nodes')
})
test('staticAnalysisCommon.getThisLocalCallName', function (t) {
t.plan(3)
var localCall = {
'attributes': {
'type': 'tuple()',
'type_conversion': false
],
'name': 'VariableDeclaration'
},
'children': [
{
'attributes': {
'type': 'function (struct Ballot.Voter storage pointer)',
'value': 'bli'
'constant': false,
'name': 'Ballot',
'payable': false,
'visibility': 'public'
},
'id': 37,
'name': 'Identifier',
'src': '540:3:0'
'children': [],
'name': 'FunctionDefinition'
},
{
'attributes': {
'type': 'struct Ballot.Voter storage pointer',
'value': 'x'
'constant': false,
'name': 'giveRightToVote',
'payable': false,
'visibility': 'public'
},
'id': 38,
'name': 'Identifier',
'src': '544:1:0'
'children': [],
'name': 'FunctionDefinition'
}
],
'id': 39,
'name': 'FunctionCall',
'src': '540:6:0'
'name': 'ContractDefinition'
}
var thisLocalCall = { name: 'MemberAccess', children: [ { attributes: { value: 'this', type: 'contract test' }, name: 'Identifier' } ], attributes: { value: 'b', type: 'function (bytes32,address) returns (bool)' } }
var externalDirect = {
attributes: {
member_name: 'info',
type: 'function () payable external returns (uint256)'
var res = common.getStateVariableDeclarationsFormContractNode(contract).map(common.getDeclaredVariableName)
t.ok(res[0] === 'chairperson', 'var 1 should be ')
t.ok(res[1] === 'voters', 'var 2 should be ')
t.ok(res[2] === 'proposals', 'var 3 should be ')
t.ok(res[3] === undefined, 'var 4 should be undefined')
})
test('staticAnalysisCommon.getFunctionOrModifierDefinitionParameterPart', function (t) {
t.plan(2)
var funDef = {
'attributes': {
'constant': true,
'name': 'winnerName',
'payable': false,
'visibility': 'public'
},
children: [
'children': [
{
attributes: {
type: 'contract InfoFeed',
value: 'f'
'children': [
],
'name': 'ParameterList'
},
id: 30,
name: 'Identifier',
src: '405:1:0'
{
'children': [],
'name': 'ParameterList'
},
{
'children': [],
'name': 'Block'
}
],
id: 32,
name: 'MemberAccess',
src: '405:6:0'
'name': 'FunctionDefinition'
}
t.ok(common.getThisLocalCallName(thisLocalCall) === 'b', 'get this Local call name from node')
t.throws(() => common.getThisLocalCallName(externalDirect), undefined, 'throws on other nodes')
t.throws(() => common.getThisLocalCallName(localCall), undefined, 'throws on other nodes')
t.ok(common.helpers.nodeType(common.getFunctionOrModifierDefinitionParameterPart(funDef), 'ParameterList'), 'should return a parameterList')
t.throws(() => common.getFunctionOrModifierDefinitionParameterPart({ name: 'SourceUnit' }), undefined, 'throws on other nodes')
})
test('staticAnalysisCommon.getSuperLocalCallName', function (t) {
test('staticAnalysisCommon.getFunctionCallTypeParameterType', function (t) {
t.plan(4)
var superLocal = {
t.ok(common.getFunctionCallTypeParameterType(thisLocalCall) === 'bytes32,address', 'this local call returns correct type')
t.ok(common.getFunctionCallTypeParameterType(externalDirect) === '', 'external direct call returns correct type')
t.ok(common.getFunctionCallTypeParameterType(localCall) === 'struct Ballot.Voter storage pointer', 'local call returns correct type')
t.throws(() => common.getFunctionCallTypeParameterType({ name: 'MemberAccess' }), undefined, 'throws on wrong type')
})
test('staticAnalysisCommon.getLibraryCallContractName', function (t) {
t.plan(2)
var node = {
'attributes': {
'member_name': 'duper',
'type': 'function ()'
'member_name': 'insert',
'type': 'function (struct Set.Data storage pointer,uint256) returns (bool)'
},
'children': [
{
'attributes': {
'type': 'contract super a',
'value': 'super'
'type': 'type(library Set)',
'value': 'Set'
},
'name': 'Identifier'
}
],
'name': 'MemberAccess'
}
var localCall = {
t.equal(common.getLibraryCallContractName(node), 'Set', 'should return correct contract name')
t.throws(() => common.getLibraryCallContractName({ name: 'Identifier' }), undefined, 'should throw on wrong node')
})
test('staticAnalysisCommon.getLibraryCallMemberName', function (t) {
t.plan(2)
var node = {
'attributes': {
'type': 'tuple()',
'type_conversion': false
'member_name': 'insert',
'type': 'function (struct Set.Data storage pointer,uint256) returns (bool)'
},
'children': [
{
'attributes': {
'type': 'function (struct Ballot.Voter storage pointer)',
'value': 'bli'
},
'id': 37,
'name': 'Identifier',
'src': '540:3:0'
},
{
'attributes': {
'type': 'struct Ballot.Voter storage pointer',
'value': 'x'
},
'id': 38,
'name': 'Identifier',
'src': '544:1:0'
}
],
'id': 39,
'name': 'FunctionCall',
'src': '540:6:0'
}
var thisLocalCall = { name: 'MemberAccess', children: [ { attributes: { value: 'this', type: 'contract test' }, name: 'Identifier' } ], attributes: { value: 'b', type: 'function (bytes32,address) returns (bool)' } }
var externalDirect = {
attributes: {
member_name: 'info',
type: 'function () payable external returns (uint256)'
},
children: [
{
attributes: {
type: 'contract InfoFeed',
value: 'f'
'type': 'type(library Set)',
'value': 'Set'
},
id: 30,
name: 'Identifier',
src: '405:1:0'
'name': 'Identifier'
}
],
id: 32,
name: 'MemberAccess',
src: '405:6:0'
'name': 'MemberAccess'
}
t.equal(common.getSuperLocalCallName(superLocal), 'duper', 'get local name from super local call')
t.throws(() => common.getSuperLocalCallName(thisLocalCall), 'throws on other nodes')
t.throws(() => common.getSuperLocalCallName(externalDirect), undefined, 'throws on other nodes')
t.throws(() => common.getSuperLocalCallName(localCall), undefined, 'throws on other nodes')
t.equal(common.getLibraryCallMemberName(node), 'insert', 'should return correct member name')
t.throws(() => common.getLibraryCallMemberName({ name: 'Identifier' }), undefined, 'should throw on wrong node')
})
test('staticAnalysisCommon.getExternalDirectCallContractName', function (t) {
test('staticAnalysisCommon.getFullQualifiedFunctionCallIdent', function (t) {
t.plan(4)
var contract = { name: 'ContractDefinition', attributes: { name: 'baz' } }
t.ok(common.getFullQualifiedFunctionCallIdent(contract, thisLocalCall) === 'test.b(bytes32,address)', 'this local call returns correct type')
t.ok(common.getFullQualifiedFunctionCallIdent(contract, externalDirect) === 'InfoFeed.info()', 'external direct call returns correct type')
t.ok(common.getFullQualifiedFunctionCallIdent(contract, localCall) === 'baz.bli(struct Ballot.Voter storage pointer)', 'local call returns correct type')
t.throws(() => common.getFullQualifiedFunctionCallIdent(contract, { name: 'MemberAccess' }), undefined, 'throws on wrong type')
})
test('staticAnalysisCommon.getFullQuallyfiedFuncDefinitionIdent', function (t) {
t.plan(3)
var localCall = {
var contract = { name: 'ContractDefinition', attributes: { name: 'baz' } }
var funDef = {
'attributes': {
'type': 'tuple()',
'type_conversion': false
'constant': false,
'name': 'getY',
'payable': false,
'visibility': 'public'
},
'children': [
{
'children': [
{
'attributes': {
'type': 'function (struct Ballot.Voter storage pointer)',
'value': 'bli'
},
'id': 37,
'name': 'Identifier',
'src': '540:3:0'
'name': 'z',
'type': 'uint256'
},
'children': [
{
'attributes': {
'type': 'struct Ballot.Voter storage pointer',
'value': 'x'
'name': 'uint'
},
'id': 38,
'name': 'Identifier',
'src': '544:1:0'
'name': 'ElementaryTypeName'
}
],
'id': 39,
'name': 'FunctionCall',
'src': '540:6:0'
}
var thisLocalCall = { name: 'MemberAccess', children: [ { attributes: { value: 'this', type: 'contract test' }, name: 'Identifier' } ], attributes: { value: 'b', type: 'function (bytes32,address) returns (bool)' } }
var externalDirect = {
attributes: {
member_name: 'info',
type: 'function () payable external returns (uint256)'
'name': 'VariableDeclaration'
},
children: [
{
attributes: {
type: 'contract InfoFeed',
value: 'f'
'attributes': {
'name': 'r',
'type': 'bool'
},
id: 30,
name: 'Identifier',
src: '405:1:0'
'children': [
{
'attributes': {
'name': 'bool'
},
'name': 'ElementaryTypeName'
}
],
id: 32,
name: 'MemberAccess',
src: '405:6:0'
'name': 'VariableDeclaration'
}
t.ok(common.getExternalDirectCallContractName(externalDirect) === 'InfoFeed', 'external direct call contract name from node')
t.throws(() => common.getExternalDirectCallContractName(thisLocalCall), undefined, 'throws on other nodes')
t.throws(() => common.getExternalDirectCallContractName(localCall), undefined, 'throws on other nodes')
})
test('staticAnalysisCommon.getThisLocalCallContractName', function (t) {
t.plan(3)
var localCall = {
'attributes': {
'type': 'tuple()',
'type_conversion': false
],
'name': 'ParameterList'
},
{
'children': [
{
'attributes': {
'type': 'function (struct Ballot.Voter storage pointer)',
'value': 'bli'
},
'id': 37,
'name': 'Identifier',
'src': '540:3:0'
'name': '',
'type': 'uint256'
},
'children': [
{
'attributes': {
'type': 'struct Ballot.Voter storage pointer',
'value': 'x'
'name': 'uint'
},
'id': 38,
'name': 'Identifier',
'src': '544:1:0'
'id': 34,
'name': 'ElementaryTypeName',
'src': '285:4:0'
}
],
'id': 39,
'name': 'FunctionCall',
'src': '540:6:0'
'id': 35,
'name': 'VariableDeclaration',
'src': '285:4:0'
}
var thisLocalCall = { name: 'MemberAccess', children: [ { attributes: { value: 'this', type: 'contract test' }, name: 'Identifier' } ], attributes: { value: 'b', type: 'function (bytes32,address) returns (bool)' } }
var externalDirect = {
attributes: {
member_name: 'info',
type: 'function () payable external returns (uint256)'
],
'name': 'ParameterList'
},
children: [
{
attributes: {
type: 'contract InfoFeed',
value: 'f'
},
id: 30,
name: 'Identifier',
src: '405:1:0'
'children': [],
'name': 'Block'
}
],
id: 32,
name: 'MemberAccess',
src: '405:6:0'
'name': 'FunctionDefinition'
}
t.ok(common.getThisLocalCallContractName(thisLocalCall) === 'test', 'this local call contract name from node')
t.throws(() => common.getThisLocalCallContractName(localCall), undefined, 'throws on other nodes')
t.throws(() => common.getThisLocalCallContractName(externalDirect), undefined, 'throws on other nodes')
t.ok(common.getFullQuallyfiedFuncDefinitionIdent(contract, funDef, ['uint256', 'bool']) === 'baz.getY(uint256,bool)', 'creates right signature')
t.throws(() => common.getFullQuallyfiedFuncDefinitionIdent(contract, { name: 'MemberAccess' }, ['uint256', 'bool']), undefined, 'throws on wrong nodes')
t.throws(() => common.getFullQuallyfiedFuncDefinitionIdent({ name: 'FunctionCall' }, funDef, ['uint256', 'bool']), undefined, 'throws on wrong nodes')
})
test('staticAnalysisCommon.getExternalDirectCallMemberName', function (t) {
test('staticAnalysisCommon.getLoopBlockStartIndex', function (t) {
t.plan(3)
var localCall = {
'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'
},
{
'attributes': {
'type': 'struct Ballot.Voter storage pointer',
'value': 'x'
},
'id': 38,
'name': 'Identifier',
'src': '544:1:0'
}
],
'id': 39,
'name': 'FunctionCall',
'src': '540:6:0'
}
var thisLocalCall = { name: 'MemberAccess', children: [ { attributes: { value: 'this', type: 'contract test' }, name: 'Identifier' } ], attributes: { value: 'b', type: 'function (bytes32,address) returns (bool)' } }
var externalDirect = {
attributes: {
member_name: 'info',
type: 'function () payable external returns (uint256)'
},
children: [
{
attributes: {
type: 'contract InfoFeed',
value: 'f'
},
id: 30,
name: 'Identifier',
src: '405:1:0'
}
],
id: 32,
name: 'MemberAccess',
src: '405:6:0'
}
t.ok(common.getExternalDirectCallMemberName(externalDirect) === 'info', 'external direct call name from node')
t.throws(() => common.getExternalDirectCallMemberName(thisLocalCall), undefined, 'throws on other nodes')
t.throws(() => common.getExternalDirectCallMemberName(localCall), undefined, 'throws on other nodes')
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
})
test('staticAnalysisCommon.getContractName', function (t) {
t.plan(2)
var contract = { name: 'ContractDefinition', attributes: { name: 'baz' } }
t.ok(common.getContractName(contract) === 'baz', 'returns right contract name')
t.throws(() => common.getContractName({ name: 'InheritanceSpecifier' }), undefined, 'throws on other nodes')
// #################### Trivial Node Identification
test('staticAnalysisCommon.isFunctionDefinition', function (t) {
t.plan(3)
var node1 = { name: 'FunctionDefinition' }
var node2 = { name: 'MemberAccess' }
var 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.getFunctionDefinitionName', function (t) {
t.plan(2)
var func = { name: 'FunctionDefinition', attributes: { name: 'foo' } }
t.ok(common.getFunctionDefinitionName(func) === 'foo', 'returns right contract name')
t.throws(() => common.getFunctionDefinitionName({ name: 'InlineAssembly' }), undefined, 'throws on other nodes')
test('staticAnalysisCommon.isModifierDefinition', function (t) {
t.plan(3)
var node1 = { name: 'ModifierDefinition' }
var node2 = { name: 'MemberAccess' }
var 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.getInheritsFromName', function (t) {
t.plan(2)
var inh = {
'children': [
{
'attributes': {
'name': 'r'
},
'id': 7,
'name': 'UserDefinedTypeName',
'src': '84:1:0'
}
],
'id': 8,
'name': 'InheritanceSpecifier',
'src': '84:1:0'
}
t.ok(common.getInheritsFromName(inh) === 'r', 'returns right contract name')
t.throws(() => common.getInheritsFromName({ name: 'ElementaryTypeName' }), undefined, 'throws on other nodes')
test('staticAnalysisCommon.isModifierInvocation', function (t) {
t.plan(3)
var node1 = { name: 'ModifierInvocation' }
var node2 = { name: 'MemberAccess' }
var 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.getDeclaredVariableName', function (t) {
t.plan(2)
var node1 = {
'attributes': {
'name': 'x',
'type': 'struct Ballot.Voter storage pointer'
},
'children': [
{
'attributes': {
'name': 'Voter'
},
'id': 43,
'name': 'UserDefinedTypeName',
'src': '604:5:0'
}
],
'id': 44,
'name': 'VariableDeclaration',
'src': '604:15:0'
}
t.ok(common.getDeclaredVariableName(node1) === 'x', 'extract right variable name')
node1.name = 'FunctionCall'
t.throws(() => common.getDeclaredVariableName(node1) === 'x', undefined, 'throw if wrong node')
test('staticAnalysisCommon.isVariableDeclaration', function (t) {
t.plan(3)
var node1 = { name: 'VariableDeclaration' }
var node2 = { name: 'MemberAccess' }
var 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.getStateVariableDeclarationsFormContractNode', function (t) {
t.plan(4)
var contract = {
'attributes': {
'fullyImplemented': true,
'isLibrary': false,
'linearizedBaseContracts': [
274
],
'name': 'Ballot'
},
'children': [
{
'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': [
{
'children': [
{
'attributes': {
'name': 'address'
},
'name': 'ElementaryTypeName'
},
{
'attributes': {
'name': 'Voter'
},
'name': 'UserDefinedTypeName'
}
],
'name': 'Mapping'
}
],
'name': 'VariableDeclaration'
},
{
'attributes': {
'name': 'proposals',
'type': 'struct Ballot.Proposal storage ref[] storage ref'
},
'children': [
{
'children': [
{
'attributes': {
'name': 'Proposal'
},
'name': 'UserDefinedTypeName'
}
],
'name': 'ArrayTypeName'
}
],
'name': 'VariableDeclaration'
},
{
'attributes': {
'constant': false,
'name': 'Ballot',
'payable': false,
'visibility': 'public'
},
'children': [],
'name': 'FunctionDefinition'
},
{
'attributes': {
'constant': false,
'name': 'giveRightToVote',
'payable': false,
'visibility': 'public'
},
'children': [],
'name': 'FunctionDefinition'
}
],
'name': 'ContractDefinition'
}
var res = common.getStateVariableDeclarationsFormContractNode(contract).map(common.getDeclaredVariableName)
test('staticAnalysisCommon.isInheritanceSpecifier', function (t) {
t.plan(3)
var node1 = { name: 'InheritanceSpecifier' }
var node2 = { name: 'MemberAccess' }
var node3 = { name: 'InheritanceSpecifierBLABLA' }
t.ok(res[0] === 'chairperson', 'var 1 should be ')
t.ok(res[1] === 'voters', 'var 2 should be ')
t.ok(res[2] === 'proposals', 'var 3 should be ')
t.ok(res[3] === undefined, 'var 4 should be undefined')
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.getFunctionOrModifierDefinitionParameterPart', function (t) {
t.plan(2)
var funDef = {
'attributes': {
'constant': true,
'name': 'winnerName',
'payable': false,
'visibility': 'public'
},
'children': [
{
'children': [
],
'name': 'ParameterList'
},
{
'children': [],
'name': 'ParameterList'
},
{
'children': [],
'name': 'Block'
}
],
'name': 'FunctionDefinition'
}
t.ok(common.helpers.nodeType(common.getFunctionOrModifierDefinitionParameterPart(funDef), 'ParameterList'), 'should return a parameterList')
t.throws(() => common.getFunctionOrModifierDefinitionParameterPart({ name: 'SourceUnit' }), undefined, 'throws on other nodes')
})
test('staticAnalysisCommon.isAssignment', function (t) {
t.plan(3)
var node1 = { name: 'Assignment' }
var node2 = { name: 'MemberAccess' }
var node3 = { name: 'AssignmentBLABLA' }
test('staticAnalysisCommon.getFunctionCallTypeParameterType', function (t) {
t.plan(4)
var localCall = {
'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'
},
{
'attributes': {
'type': 'struct Ballot.Voter storage pointer',
'value': 'x'
},
'id': 38,
'name': 'Identifier',
'src': '544:1:0'
}
],
'id': 39,
'name': 'FunctionCall',
'src': '540:6:0'
}
var thisLocalCall = { name: 'MemberAccess', children: [ { attributes: { value: 'this', type: 'contract test' }, name: 'Identifier' } ], attributes: { value: 'b', type: 'function (bytes32,address) returns (bool)' } }
var externalDirect = {
attributes: {
member_name: 'info',
type: 'function () payable external returns (uint256)'
},
children: [
{
attributes: {
type: 'contract InfoFeed',
value: 'f'
},
id: 30,
name: 'Identifier',
src: '405:1:0'
}
],
id: 32,
name: 'MemberAccess',
src: '405:6:0'
}
t.ok(common.getFunctionCallTypeParameterType(thisLocalCall) === 'bytes32,address', 'this local call returns correct type')
t.ok(common.getFunctionCallTypeParameterType(externalDirect) === '', 'external direct call returns correct type')
t.ok(common.getFunctionCallTypeParameterType(localCall) === 'struct Ballot.Voter storage pointer', 'local call returns correct type')
t.throws(() => common.getFunctionCallTypeParameterType({ name: 'MemberAccess' }), undefined, 'throws on wrong type')
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.getLibraryCallContractName', function (t) {
t.plan(2)
var node = {
'attributes': {
'member_name': 'insert',
'type': 'function (struct Set.Data storage pointer,uint256) returns (bool)'
},
'children': [
{
'attributes': {
'type': 'type(library Set)',
'value': 'Set'
},
'name': 'Identifier'
}
],
'name': 'MemberAccess'
}
t.equal(common.getLibraryCallContractName(node), 'Set', 'should return correct contract name')
t.throws(() => common.getLibraryCallContractName({ name: 'Identifier' }), undefined, 'should throw on wrong node')
test('staticAnalysisCommon.isContractDefinition', function (t) {
t.plan(3)
var node1 = { name: 'ContractDefinition' }
var node2 = { name: 'MemberAccess' }
var 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.getLibraryCallMemberName', function (t) {
t.plan(2)
var node = {
'attributes': {
'member_name': 'insert',
'type': 'function (struct Set.Data storage pointer,uint256) returns (bool)'
},
'children': [
{
'attributes': {
'type': 'type(library Set)',
'value': 'Set'
},
'name': 'Identifier'
}
],
'name': 'MemberAccess'
}
t.equal(common.getLibraryCallMemberName(node), 'insert', 'should return correct member name')
t.throws(() => common.getLibraryCallMemberName({ name: 'Identifier' }), undefined, 'should throw on wrong node')
test('staticAnalysisCommon.isInlineAssembly', function (t) {
t.plan(3)
var node1 = { name: 'InlineAssembly' }
var node2 = { name: 'MemberAccess' }
var 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.getFullQualifiedFunctionCallIdent', function (t) {
t.plan(4)
var contract = { name: 'ContractDefinition', attributes: { name: 'baz' } }
var localCall = {
'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'
},
{
'attributes': {
'type': 'struct Ballot.Voter storage pointer',
'value': 'x'
},
'id': 38,
'name': 'Identifier',
'src': '544:1:0'
}
],
'id': 39,
'name': 'FunctionCall',
'src': '540:6:0'
}
var thisLocalCall = { name: 'MemberAccess', children: [ { attributes: { value: 'this', type: 'contract test' }, name: 'Identifier' } ], attributes: { value: 'b', type: 'function (bytes32,address) returns (bool)' } }
var externalDirect = {
attributes: {
member_name: 'info',
type: 'function () payable external returns (uint256)'
},
children: [
{
attributes: {
type: 'contract InfoFeed',
value: 'f'
},
id: 30,
name: 'Identifier',
src: '405:1:0'
}
],
id: 32,
name: 'MemberAccess',
src: '405:6:0'
}
t.ok(common.getFullQualifiedFunctionCallIdent(contract, thisLocalCall) === 'test.b(bytes32,address)', 'this local call returns correct type')
t.ok(common.getFullQualifiedFunctionCallIdent(contract, externalDirect) === 'InfoFeed.info()', 'external direct call returns correct type')
t.ok(common.getFullQualifiedFunctionCallIdent(contract, localCall) === 'baz.bli(struct Ballot.Voter storage pointer)', 'local call returns correct type')
t.throws(() => common.getFullQualifiedFunctionCallIdent(contract, { name: 'MemberAccess' }), undefined, 'throws on wrong type')
})
test('staticAnalysisCommon.getFullQuallyfiedFuncDefinitionIdent', function (t) {
t.plan(3)
var contract = { name: 'ContractDefinition', attributes: { name: 'baz' } }
var funDef = {
'attributes': {
'constant': false,
'name': 'getY',
'payable': false,
'visibility': 'public'
},
'children': [
{
'children': [
{
'attributes': {
'name': 'z',
'type': 'uint256'
},
'children': [
{
'attributes': {
'name': 'uint'
},
'name': 'ElementaryTypeName'
}
],
'name': 'VariableDeclaration'
},
{
'attributes': {
'name': 'r',
'type': 'bool'
},
'children': [
{
'attributes': {
'name': 'bool'
},
'name': 'ElementaryTypeName'
}
],
'name': 'VariableDeclaration'
}
],
'name': 'ParameterList'
},
{
'children': [
{
'attributes': {
'name': '',
'type': 'uint256'
},
'children': [
{
'attributes': {
'name': 'uint'
},
'id': 34,
'name': 'ElementaryTypeName',
'src': '285:4:0'
}
],
'id': 35,
'name': 'VariableDeclaration',
'src': '285:4:0'
}
],
'name': 'ParameterList'
},
{
'children': [],
'name': 'Block'
}
],
'name': 'FunctionDefinition'
}
t.ok(common.getFullQuallyfiedFuncDefinitionIdent(contract, funDef, ['uint256', 'bool']) === 'baz.getY(uint256,bool)', 'creates right signature')
t.throws(() => common.getFullQuallyfiedFuncDefinitionIdent(contract, { name: 'MemberAccess' }, ['uint256', 'bool']), undefined, 'throws on wrong nodes')
t.throws(() => common.getFullQuallyfiedFuncDefinitionIdent({ name: 'FunctionCall' }, funDef, ['uint256', 'bool']), undefined, 'throws on wrong nodes')
})
test('staticAnalysisCommon.getLoopBlockStartIndex', function (t) {
test('staticAnalysisCommon.isLoop', function (t) {
t.plan(3)
var node1 = {
'children':
[
{
'attributes':
{
'assignments':
[
21
]
},
'children':
[
{
'attributes':
{
'constant': false,
'name': 'i',
'scope': 39,
'stateVariable': false,
'storageLocation': 'default',
'type': 'uint256',
'value': null,
'visibility': 'internal'
},
'children':
[
{
'attributes':
{
'name': 'uint',
'type': 'uint256'
},
'id': 20,
'name': 'ElementaryTypeName',
'src': '207:4:0'
}
],
'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'
}
],
'id': 23,
'name': 'VariableDeclarationStatement',
'src': '207:14:0'
},
{
'attributes':
{
'argumentTypes': null,
'commonType':
{
'typeIdentifier': 't_uint256',
'typeString': 'uint256'
},
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'operator': '<',
'type': 'bool'
},
'children':
[
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 21,
'type': 'uint256',
'value': 'i'
},
'id': 24,
'name': 'Identifier',
'src': '223: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': 25,
'name': 'Literal',
'src': '227:2:0'
}
],
'id': 26,
'name': 'BinaryOperation',
'src': '223:6: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': 21,
'type': 'uint256',
'value': 'i'
},
'id': 27,
'name': 'Identifier',
'src': '231:1:0'
}
],
'id': 28,
'name': 'UnaryOperation',
'src': '231:3:0'
}
],
'id': 29,
'name': 'ExpressionStatement',
'src': '231:3: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': 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'
}
],
'id': 36,
'name': 'Block',
'src': '236:38:0'
}
],
'id': 37,
'name': 'ForStatement',
'src': '202:72:0'
}
var node2 = {
'children':
[
{
'attributes':
{
'argumentTypes': null,
'commonType':
{
'typeIdentifier': 't_uint256',
'typeString': 'uint256'
},
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'operator': '<',
'type': 'bool'
},
'children':
[
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 69,
'type': 'uint256',
'value': 'i'
},
'id': 82,
'name': 'Identifier',
'src': '592: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': 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'
},
{
'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'
}
],
'id': 81,
'name': 'Block',
'src': '530:55:0'
}
],
'id': 85,
'name': 'DoWhileStatement',
'src': '528:72:0'
}
var node3 = {
'children':
[
{
'attributes':
{
'argumentTypes': null,
'commonType':
{
'typeIdentifier': 't_uint256',
'typeString': 'uint256'
},
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'operator': '<',
'type': 'bool'
},
'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'
},
{
'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'
}
],
'id': 61,
'name': 'WhileStatement',
'src': '365:70:0'
}
t.equal(common.getLoopBlockStartIndex(node1), 3) // 'for' loop
t.equal(common.getLoopBlockStartIndex(node2), 1) // 'do-while' loop
t.equal(common.getLoopBlockStartIndex(node3), 1) // 'while' loop
})
// #################### Trivial Node Identification
test('staticAnalysisCommon.isFunctionDefinition', function (t) {
t.plan(3)
var node1 = { name: 'FunctionDefinition' }
var node2 = { name: 'MemberAccess' }
var 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)
var node1 = { name: 'ModifierDefinition' }
var node2 = { name: 'MemberAccess' }
var 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)
var node1 = { name: 'ModifierInvocation' }
var node2 = { name: 'MemberAccess' }
var 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)
var node1 = { name: 'VariableDeclaration' }
var node2 = { name: 'MemberAccess' }
var 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)
var node1 = { name: 'InheritanceSpecifier' }
var node2 = { name: 'MemberAccess' }
var 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)
var node1 = { name: 'Assignment' }
var node2 = { name: 'MemberAccess' }
var 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)
var node1 = { name: 'ContractDefinition' }
var node2 = { name: 'MemberAccess' }
var 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)
var node1 = { name: 'InlineAssembly' }
var node2 = { name: 'MemberAccess' }
var 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)
var node1 = {
'children':
[
{
'attributes':
{
'assignments':
[
21
]
},
'children':
[
{
'attributes':
{
'constant': false,
'name': 'i',
'scope': 39,
'stateVariable': false,
'storageLocation': 'default',
'type': 'uint256',
'value': null,
'visibility': 'internal'
},
'children':
[
{
'attributes':
{
'name': 'uint',
'type': 'uint256'
},
'id': 20,
'name': 'ElementaryTypeName',
'src': '207:4:0'
}
],
'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'
}
],
'id': 23,
'name': 'VariableDeclarationStatement',
'src': '207:14:0'
},
{
'attributes':
{
'argumentTypes': null,
'commonType':
{
'typeIdentifier': 't_uint256',
'typeString': 'uint256'
},
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'operator': '<',
'type': 'bool'
},
'children':
[
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 21,
'type': 'uint256',
'value': 'i'
},
'id': 24,
'name': 'Identifier',
'src': '223: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': 25,
'name': 'Literal',
'src': '227:2:0'
}
],
'id': 26,
'name': 'BinaryOperation',
'src': '223:6: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': 21,
'type': 'uint256',
'value': 'i'
},
'id': 27,
'name': 'Identifier',
'src': '231:1:0'
}
],
'id': 28,
'name': 'UnaryOperation',
'src': '231:3:0'
}
],
'id': 29,
'name': 'ExpressionStatement',
'src': '231:3: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': 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'
}
],
'id': 36,
'name': 'Block',
'src': '236:38:0'
}
],
'id': 37,
'name': 'ForStatement',
'src': '202:72:0'
}
var node2 = {
'children':
[
{
'attributes':
{
'argumentTypes': null,
'commonType':
{
'typeIdentifier': 't_uint256',
'typeString': 'uint256'
},
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'operator': '<',
'type': 'bool'
},
'children':
[
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 69,
'type': 'uint256',
'value': 'i'
},
'id': 82,
'name': 'Identifier',
'src': '592: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': 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'
},
{
'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'
}
],
'id': 81,
'name': 'Block',
'src': '530:55:0'
}
],
'id': 85,
'name': 'DoWhileStatement',
'src': '528:72:0'
}
var node3 = {
'children':
[
{
'attributes':
{
'argumentTypes': null,
'commonType':
{
'typeIdentifier': 't_uint256',
'typeString': 'uint256'
},
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'operator': '<',
'type': 'bool'
},
'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'
},
{
'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'
}
],
'id': 61,
'name': 'WhileStatement',
'src': '365:70:0'
}
t.equal(common.isLoop(node1), true)
t.equal(common.isLoop(node2), true)
t.equal(common.isLoop(node3), true)
t.equal(common.isLoop(forLoopNode), true)
t.equal(common.isLoop(doWhileLoopNode), true)
t.equal(common.isLoop(whileLoopNode), true)
})
// #################### Complex Node Identification
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment