Hey, everyone. Was recently working with SolcJS AST and noticed something strange, what I would really like to ask about.
contract A {}
pragma solidity 0.5.12;
import {A as X, A as Y} from "./external.sol";
contract Z is X {}
By compiling current.sol with solc-js 0.5.12 I'm getting following ImportDirective AST node:
{
"absolutePath": "../external.sol",
"file": "./external.sol",
"id": 4,
"nodeType": "ImportDirective",
"scope": 8,
"sourceUnit": 10,
"src": "25:46:0",
"symbolAliases": [
{
"foreign": 2,
"local": "X"
},
{
"foreign": 3,
"local": "Y"
}
],
"unitAlias": ""
}
{
"attributes": {
"SourceUnit": 10,
"absolutePath": "../external.sol",
"file": "./external.sol",
"scope": 8,
"symbolAliases": [
{
"foreign": 2,
"local": "X"
},
{
"foreign": 3,
"local": "Y"
}
],
"unitAlias": ""
},
"id": 4,
"name": "ImportDirective",
"src": "25:46:0"
}
I was expecting that symbolAliases will contain foreign property to point to external declaration of contract A, but it actually is pointing to nowhere (there is no nodes with ID = 2 or ID = 3). Also, there is an ID gap between PragmaDirective (ID = 1) and sequentially following node ImportDirective (ID = 4), which maybe gives an idea that there is something off here...
Is foreign referencing external declarations by some another way (and I'm missing something here)? Shouldn't it have value of referenced contract declaration node id (9) instead (like UserDefinedTypeName does)?
{
"contractScope": null,
"id": 5,
"name": "X",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 9,
"src": "87:1:0",
"typeDescriptions": {
"typeIdentifier": "t_contract$_A_$9",
"typeString": "contract A"
}
}
Thanks for clarification and your time. Regards.
You are completely right with your assumptions. The foreign part is simply missing here.
Lucky for you we already fixed that in the upcoming release 0.6.0 (any day now).
The new output looks like this:
======= current.sol =======
{
"absolutePath": "current.sol",
"exportedSymbols":
{
"Z":
[
6
]
},
"id": 7,
"nodeType": "SourceUnit",
"nodes":
[
{
"absolutePath": "external.sol",
"file": "./external.sol",
"id": 3,
"nodeType": "ImportDirective",
"scope": 7,
"sourceUnit": 9,
"src": "0:46:0",
"symbolAliases":
[
{
"foreign":
{
"argumentTypes": null,
"id": 1,
"name": "A",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": null,
"src": "8:1:0",
"typeDescriptions":
{
"typeIdentifier": null,
"typeString": null
}
},
"local": "X"
},
{
"foreign":
{
"argumentTypes": null,
"id": 2,
"name": "A",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": null,
"src": "16:1:0",
"typeDescriptions":
{
"typeIdentifier": null,
"typeString": null
}
},
"local": "Y"
}
],
"unitAlias": ""
},
{
"abstract": false,
"baseContracts":
[
{
"arguments": null,
"baseName":
{
"contractScope": null,
"id": 4,
"name": "X",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 8,
"src": "62:1:0",
"typeDescriptions":
{
"typeIdentifier": "t_contract$_A_$8",
"typeString": "contract A"
}
},
"id": 5,
"nodeType": "InheritanceSpecifier",
"src": "62:1:0"
}
],
"contractDependencies":
[
8
],
"contractKind": "contract",
"documentation": null,
"fullyImplemented": true,
"id": 6,
"linearizedBaseContracts":
[
6,
8
],
"name": "Z",
"nodeType": "ContractDefinition",
"nodes": [],
"scope": 7,
"src": "48:18:0"
}
],
"src": "0:67:0"
}
======= external.sol =======
{
"absolutePath": "external.sol",
"exportedSymbols":
{
"A":
[
8
]
},
"id": 9,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": null,
"fullyImplemented": true,
"id": 8,
"linearizedBaseContracts":
[
8
],
"name": "A",
"nodeType": "ContractDefinition",
"nodes": [],
"scope": 9,
"src": "0:13:1"
}
],
"src": "0:14:1"
}
Feel free to reopen this if you still think the output is not correct.
Most helpful comment
You are completely right with your assumptions. The
foreignpart is simply missing here.Lucky for you we already fixed that in the upcoming release
0.6.0(any day now).The new output looks like this:
Feel free to reopen this if you still think the output is not correct.