diff --git a/src/ast/definitions.ts b/src/ast/definitions.ts index 51133dd4..282c022d 100644 --- a/src/ast/definitions.ts +++ b/src/ast/definitions.ts @@ -285,16 +285,29 @@ function* lookupInFunctionDefinition( /** * Lookup the definition corresponding to `name` in the `Block|UncheckedBlock` `scope`. Yield all matches. */ -function* lookupInBlock(name: string, scope: Block | UncheckedBlock): Iterable { - for (const node of scope.children) { - if (!(node instanceof VariableDeclarationStatement)) { - continue; - } +function* lookupInBlock( + name: string, + scope: Block | UncheckedBlock, + inference: InferType +): Iterable { + let declarations: VariableDeclaration[]; - for (const decl of node.vDeclarations) { - if (decl.name === name) { - yield decl; - } + if (lt(inference.version, "0.5.0")) { + declarations = scope.getChildrenByType(VariableDeclaration); + } else { + declarations = scope.children + .filter((node) => node instanceof VariableDeclarationStatement) + .reduce( + (declarations: VariableDeclaration[], statement) => [ + ...declarations, + ...(statement as VariableDeclarationStatement).vDeclarations + ], + [] + ); + } + for (const declaration of declarations) { + if (declaration.name === name) { + yield declaration; } } } @@ -325,7 +338,7 @@ function lookupInScope( } else if (scope instanceof VariableDeclarationStatement) { results = scope.vDeclarations.filter((decl) => decl.name === name); } else if (scope instanceof Block || scope instanceof UncheckedBlock) { - results = lookupInBlock(name, scope); + results = lookupInBlock(name, scope, inference); } else if (scope instanceof TryCatchClause) { results = scope.vParameters ? scope.vParameters.vParameters.filter((param) => param.name === name) diff --git a/test/samples/solidity/resolving/block_04.sol b/test/samples/solidity/resolving/block_04.sol index 3bd449f3..9d730e8c 100644 --- a/test/samples/solidity/resolving/block_04.sol +++ b/test/samples/solidity/resolving/block_04.sol @@ -8,5 +8,27 @@ contract Foo { foo memory m = foo(bar); uint bar = m.x; + + uint m1 = k; + {uint k;} + } + + uint256 x1; + uint256 x2; + uint256 x3; + uint256 x4; + + function second() internal { + { + uint256 x1 = 1; + if (x1 > 0) { + uint256 x2 = 2; + } + { + uint256 x3 = 3; + } + } + for (uint256 x4; x4 < 10; x4++) {} + uint256 y = x1 + x2 + x3 + x4; } } diff --git a/test/samples/solidity/resolving/block_05.sol b/test/samples/solidity/resolving/block_05.sol index 564d5088..5c3d30e6 100644 --- a/test/samples/solidity/resolving/block_05.sol +++ b/test/samples/solidity/resolving/block_05.sol @@ -13,4 +13,23 @@ contract Foo { foo = 2; } + + uint256 x1; + uint256 x2; + uint256 x3; + uint256 x4; + + function second() internal { + { + uint256 x1 = 1; + if (x1 > 0) { + uint256 x2 = 2; + } + { + uint256 x3 = 3; + } + } + for (uint256 x4; x4 < 10; x4++) {} + uint256 y = x1 + x2 + x3 + x4; + } }