ethereum / solidity

Solidity, the Smart Contract Programming Language
https://soliditylang.org
GNU General Public License v3.0
23.29k stars 5.77k forks source link

[AST] Reference id to import directive alias inconsistency #14192

Open michprev opened 1 year ago

michprev commented 1 year ago

Description

Import directives allow creating of symbol aliases, for example:

import { symbol as symbolAlias } from "./Foo.sol";

and source unit aliases:

import * as unitAlias from "./Foo.sol";

When referencing these aliases through an Identifier node, there is an inconsistency. When referencing symbolAlias, referenced declaration AST node ID is the ID of the symbol itself (can be a contract definition, for example) and not the ID of the import directive, where the symbol alias was declared.

When referencing unitAlias, referenced declaration AST node ID points to the import directive, where the unit alias was declared and not to the source unit itself.

Environment

Steps to Reproduce

Please see the example here: https://github.com/michprev/solc-ast-import-alias-inconsistency. It contains generated ASTs of all files.

In file A, Base (https://github.com/michprev/solc-ast-import-alias-inconsistency/blob/c399cdcda566c5e2b86472422ac5ca47425d8b0b/contracts/A.sol#L8) is an Identifier node and it's referenced declaration ID points to the import directive (https://github.com/michprev/solc-ast-import-alias-inconsistency/blob/c399cdcda566c5e2b86472422ac5ca47425d8b0b/contracts/A.sol#L4).

In file B, Base2 (https://github.com/michprev/solc-ast-import-alias-inconsistency/blob/c399cdcda566c5e2b86472422ac5ca47425d8b0b/contracts/B.sol#L8) is an Identifier node and it's referenced declaration ID points to the contract definition (https://github.com/michprev/solc-ast-import-alias-inconsistency/blob/c399cdcda566c5e2b86472422ac5ca47425d8b0b/contracts/Base.sol#L4-L6).

This introduces inconsistency - an import directive is referenced from a source unit alias but is not referenced from a symbol alias.

michprev commented 1 year ago

I have created one more example with red arrows showing actual referenced declaration IDs and the green arrow showing what I would expect as the correct behavior. There is one problem though. Symbol aliases inside an import directive do not have AST IDs and so cannot be directly referenced.

Because of this issue, many language servers do not correctly perform LSP rename of the Bar2 symbol (https://marketplace.visualstudio.com/items?itemName=AckeeBlockchain.tools-for-solidity, https://marketplace.visualstudio.com/items?itemName=NomicFoundation.hardhat-solidity). image