diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 6a7c3cb19..11b86d3b7 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -453,21 +453,28 @@ protected: /// @} -class ImportedContractDefinition: public Declaration +/** + * TODO: docstring + */ +class ImportedContractDefinition: public Declaration // TODO(needed?), public StructurallyDocumented { public: ImportedContractDefinition( int64_t _id, SourceLocation const& _location, - ASTPointer const& _name, - ASTPointer const& _path - ); + ASTPointer _name, + ASTPointer _path + ): + Declaration(_id, _location, _name), + m_path{ std::move(_path) } + {} void accept(ASTVisitor& _visitor) override; void accept(ASTConstVisitor& _visitor) const override; + ASTPointer const& path() const noexcept { return m_path; } + private: - ASTPointer m_name; ASTPointer m_path; }; diff --git a/libsolidity/ast/ASTForward.h b/libsolidity/ast/ASTForward.h index 38da35218..dd20a70ff 100644 --- a/libsolidity/ast/ASTForward.h +++ b/libsolidity/ast/ASTForward.h @@ -43,6 +43,7 @@ class ImportDirective; class Declaration; class CallableDeclaration; class OverrideSpecifier; +class ImportedContractDefinition; class ContractDefinition; class InheritanceSpecifier; class UsingForDirective; diff --git a/libsolidity/ast/ASTVisitor.h b/libsolidity/ast/ASTVisitor.h index 52e90b0d7..f6cf38cb3 100644 --- a/libsolidity/ast/ASTVisitor.h +++ b/libsolidity/ast/ASTVisitor.h @@ -56,6 +56,7 @@ public: virtual bool visit(SourceUnit& _node) { return visitNode(_node); } virtual bool visit(PragmaDirective& _node) { return visitNode(_node); } virtual bool visit(ImportDirective& _node) { return visitNode(_node); } + virtual bool visit(ImportedContractDefinition& _node) { return visitNode(_node); } virtual bool visit(ContractDefinition& _node) { return visitNode(_node); } virtual bool visit(InheritanceSpecifier& _node) { return visitNode(_node); } virtual bool visit(UsingForDirective& _node) { return visitNode(_node); } @@ -108,6 +109,7 @@ public: virtual void endVisit(SourceUnit& _node) { endVisitNode(_node); } virtual void endVisit(PragmaDirective& _node) { endVisitNode(_node); } virtual void endVisit(ImportDirective& _node) { endVisitNode(_node); } + virtual void endVisit(ImportedContractDefinition& _node) { endVisitNode(_node); } virtual void endVisit(ContractDefinition& _node) { endVisitNode(_node); } virtual void endVisit(InheritanceSpecifier& _node) { endVisitNode(_node); } virtual void endVisit(UsingForDirective& _node) { endVisitNode(_node); } @@ -182,6 +184,7 @@ public: virtual bool visit(SourceUnit const& _node) { return visitNode(_node); } virtual bool visit(PragmaDirective const& _node) { return visitNode(_node); } virtual bool visit(ImportDirective const& _node) { return visitNode(_node); } + virtual bool visit(ImportedContractDefinition const& _node) { return visitNode(_node); } virtual bool visit(ContractDefinition const& _node) { return visitNode(_node); } virtual bool visit(InheritanceSpecifier const& _node) { return visitNode(_node); } virtual bool visit(StructDefinition const& _node) { return visitNode(_node); } @@ -234,6 +237,7 @@ public: virtual void endVisit(SourceUnit const& _node) { endVisitNode(_node); } virtual void endVisit(PragmaDirective const& _node) { endVisitNode(_node); } virtual void endVisit(ImportDirective const& _node) { endVisitNode(_node); } + virtual void endVisit(ImportedContractDefinition const& _node) { endVisitNode(_node); } virtual void endVisit(ContractDefinition const& _node) { endVisitNode(_node); } virtual void endVisit(InheritanceSpecifier const& _node) { endVisitNode(_node); } virtual void endVisit(UsingForDirective const& _node) { endVisitNode(_node); } diff --git a/libsolidity/ast/AST_accept.h b/libsolidity/ast/AST_accept.h index e597ce46b..b6fe25dd4 100644 --- a/libsolidity/ast/AST_accept.h +++ b/libsolidity/ast/AST_accept.h @@ -79,6 +79,18 @@ void StructuredDocumentation::accept(ASTConstVisitor& _visitor) const _visitor.endVisit(*this); } +void ImportedContractDefinition::accept(ASTVisitor& _visitor) +{ + _visitor.visit(*this); + _visitor.endVisit(*this); +} + +void ImportedContractDefinition::accept(ASTConstVisitor& _visitor) const +{ + _visitor.visit(*this); + _visitor.endVisit(*this); +} + void ContractDefinition::accept(ASTVisitor& _visitor) { if (_visitor.visit(*this)) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index f38d83420..1c327cdce 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -264,7 +264,7 @@ bool CompilerStack::parse() sourcesToParse.push_back(newPath); } - loadMissingInterfaces(); + loadMissingInterfaces(parser.nextID()); } } @@ -274,8 +274,17 @@ bool CompilerStack::parse() return !m_hasError; } -void CompilerStack::loadMissingInterfaces() +void CompilerStack::loadMissingInterfaces(int64_t _baseNodeID) { + vector> importedSources; + for (ASTPointer importedSourceUnit: importedSources) + { + Source source; + source.ast = importedSourceUnit; + auto const name = "__imported_interface_" + to_string(importedSourceUnit->id()); + // TODO: maybe we want to make sure this isn't used already + m_sources[name] = move(source); + } for (auto const& sourcePair: m_sources) { ASTPointer const& source = sourcePair.second.ast; @@ -285,32 +294,34 @@ void CompilerStack::loadMissingInterfaces() for (ASTPointer const& astNode: source->nodes()) { - if (auto* contract = dynamic_cast(astNode.get())) + if (auto const* importedContract = dynamic_cast(astNode.get())) { - if (auto const fileName = contract->jsonSourceFile(); fileName.has_value()) + string const fileName = *importedContract->path(); + ReadCallback::Result result{false, string("File not supplied initially.")}; + if (m_readFile) + result = m_readFile(ReadCallback::kindString(ReadCallback::Kind::ReadFile), fileName); + if (result.success) { - printf("%s needs replacement\n", fileName->string().c_str()); + string const& jsonString = result.responseOrErrorMessage; + Json::Value json; + util::jsonParseStrict(jsonString, json, nullptr); + ASTPointer jsonContract = ASTJsonImporter{m_evmVersion}.jsonToContract(json); - ReadCallback::Result result{false, string("File not supplied initially.")}; - if (m_readFile) - result = m_readFile(ReadCallback::kindString(ReadCallback::Kind::ReadFile), fileName.value().string()); - if (result.success) - { - string const& jsonString = result.responseOrErrorMessage; - printf("jsonString: %s\n", jsonString.c_str()); - Json::Value json; - util::jsonParseStrict(jsonString, json, nullptr); - ASTPointer jsonContract = ASTJsonImporter{m_evmVersion}.jsonToContract(json); - //TODO: contract = *jsonContract; - } - else - { - m_errorReporter.fatalParserError( - 31415_error, // TODO - contract->location(), - "Cannot load JSON source." - ); - } + auto importedSource = make_shared( + _baseNodeID++, + SourceLocation{}, + source->licenseString(), + vector{ jsonContract } + ); + importedSources.push_back(importedSource); + } + else + { + m_errorReporter.fatalParserError( + 31415_error, // TODO: ensure this number is unique (we should have a CI for that) + astNode->location(), + "Cannot load JSON source." + ); } } } diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 3ed2e872b..f7196d6af 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -360,7 +361,7 @@ private: std::string applyRemapping(std::string const& _path, std::string const& _context); void resolveImports(); - void loadMissingInterfaces(); + void loadMissingInterfaces(int64_t _baseNodeID); /// @returns true if the source is requested to be compiled. bool isRequestedSource(std::string const& _sourceName) const; diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h index 2262f2433..a1cab3283 100644 --- a/libsolidity/parsing/Parser.h +++ b/libsolidity/parsing/Parser.h @@ -48,6 +48,9 @@ public: ASTPointer parse(std::shared_ptr const& _scanner); + /// Returns the next AST node ID + int64_t nextID() { return ++m_currentNodeID; } + private: class ASTNodeFactory; @@ -180,9 +183,6 @@ private: std::optional findLicenseString(std::vector> const& _nodes); - /// Returns the next AST node ID - int64_t nextID() { return ++m_currentNodeID; } - std::pair tryParseIndexAccessedPath(); /// Performs limited look-ahead to distinguish between variable declaration and expression statement. /// For source code of the form "a[][8]" ("IndexAccessStructure"), this is not possible to