diff --git a/Changelog.md b/Changelog.md index ff183e22b2e9..aad7b2a53a62 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,6 +8,7 @@ Compiler Features: * Commandline Interface: Accept nested brackets in step sequences passed to ``--yul-optimizations``. * Commandline Interface: Add ``--debug-info`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code. * Commandline Interface: Use different colors when printing errors, warnings and infos. + * JSON AST: Set absolute paths of imports earlier, in the ``parsing`` stage. * SMTChecker: Output values for ``block.*``, ``msg.*`` and ``tx.*`` variables that are present in the called functions. * SMTChecker: Report contract invariants and reentrancy properties. This can be enabled via the CLI option ``--model-checker-invariants`` or the Standard JSON option ``settings.modelChecker.invariants``. * Standard JSON: Accept nested brackets in step sequences passed to ``settings.optimizer.details.yulDetails.optimizerSteps``. diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 9fa3cb1645e0..27e0f9d3ae8a 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -350,8 +350,22 @@ bool CompilerStack::parse() else { source.ast->annotation().path = path; + + for (auto const& import: ASTNode::filteredNodes(source.ast->nodes())) + { + solAssert(!import->path().empty(), "Import path cannot be empty."); + + // The current value of `path` is the absolute path as seen from this source file. + // We first have to apply remappings before we can store the actual absolute path + // as seen globally. + import->annotation().absolutePath = applyRemapping(util::absolutePath( + import->path(), + path + ), path); + } + if (m_stopAfter >= ParsedAndImported) - for (auto const& newSource: loadMissingSources(*source.ast, path)) + for (auto const& newSource: loadMissingSources(*source.ast)) { string const& newPath = newSource.first; string const& newContents = newSource.second; @@ -1091,7 +1105,7 @@ string const& CompilerStack::Source::ipfsUrl() const return ipfsUrlCached; } -StringMap CompilerStack::loadMissingSources(SourceUnit const& _ast, std::string const& _sourcePath) +StringMap CompilerStack::loadMissingSources(SourceUnit const& _ast) { solAssert(m_stackState < ParsedAndImported, ""); StringMap newSources; @@ -1100,14 +1114,8 @@ StringMap CompilerStack::loadMissingSources(SourceUnit const& _ast, std::string for (auto const& node: _ast.nodes()) if (ImportDirective const* import = dynamic_cast(node.get())) { - solAssert(!import->path().empty(), "Import path cannot be empty."); + string const& importPath = *import->annotation().absolutePath; - string importPath = util::absolutePath(import->path(), _sourcePath); - // The current value of `path` is the absolute path as seen from this source file. - // We first have to apply remappings before we can store the actual absolute path - // as seen globally. - importPath = applyRemapping(importPath, _sourcePath); - import->annotation().absolutePath = importPath; if (m_sources.count(importPath) || newSources.count(importPath)) continue; diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index c97581a651d2..3609662e02de 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -392,9 +392,9 @@ class CompilerStack: public langutil::CharStreamProvider void findAndReportCyclicContractDependencies(); /// Loads the missing sources from @a _ast (named @a _path) using the callback - /// @a m_readFile and stores the absolute paths of all imports in the AST annotations. + /// @a m_readFile /// @returns the newly loaded sources. - StringMap loadMissingSources(SourceUnit const& _ast, std::string const& _path); + StringMap loadMissingSources(SourceUnit const& _ast); std::string applyRemapping(std::string const& _path, std::string const& _context); void resolveImports(); diff --git a/test/cmdlineTests/standard_parsing_import_absolute_paths/input.json b/test/cmdlineTests/standard_parsing_import_absolute_paths/input.json new file mode 100644 index 000000000000..3a49cff46e39 --- /dev/null +++ b/test/cmdlineTests/standard_parsing_import_absolute_paths/input.json @@ -0,0 +1,12 @@ +{ + "language": "Solidity", + "sources": { + "/project/../C.sol": {"content": "import \"../L.sol\";"}, + "/lib/L.sol": {"content": ""} + }, + "settings": { + "stopAfter": "parsing", + "remappings": [":/project/=/lib/"], + "outputSelection": {"*": {"": ["ast"]}} + } +} diff --git a/test/cmdlineTests/standard_parsing_import_absolute_paths/output.json b/test/cmdlineTests/standard_parsing_import_absolute_paths/output.json new file mode 100644 index 000000000000..be033a8d7428 --- /dev/null +++ b/test/cmdlineTests/standard_parsing_import_absolute_paths/output.json @@ -0,0 +1,7 @@ +{"errors":[{"component":"general","errorCode":"1878","formattedMessage":"Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: \" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information. +--> /lib/L.sol + +","message":"SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: \" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.","severity":"warning","sourceLocation":{"end":-1,"file":"/lib/L.sol","start":-1},"type":"Warning"},{"component":"general","errorCode":"1878","formattedMessage":"Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: \" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information. +--> /project/../C.sol + +","message":"SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: \" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.","severity":"warning","sourceLocation":{"end":-1,"file":"/project/../C.sol","start":-1},"type":"Warning"}],"sources":{"/lib/L.sol":{"ast":{"absolutePath":"/lib/L.sol","id":1,"nodeType":"SourceUnit","nodes":[],"src":"0:0:0"},"id":0},"/project/../C.sol":{"ast":{"absolutePath":"/project/../C.sol","id":3,"nodeType":"SourceUnit","nodes":[{"absolutePath":"/lib/L.sol","file":"../L.sol","id":2,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","src":"0:18:1","symbolAliases":[],"unitAlias":""}],"src":"0:18:1"},"id":1}}} diff --git a/test/libsolidity/ASTJSON/not_existing_import_parseOnly.json b/test/libsolidity/ASTJSON/not_existing_import_parseOnly.json index a42a10aed4ae..a36c59fffb4b 100644 --- a/test/libsolidity/ASTJSON/not_existing_import_parseOnly.json +++ b/test/libsolidity/ASTJSON/not_existing_import_parseOnly.json @@ -5,6 +5,7 @@ "nodes": [ { + "absolutePath": "notexisting.sol", "file": "notexisting.sol", "id": 1, "nameLocation": "28:11:1",