From 7a8c9974388bf07b80bf47fa80069dbe98f499c6 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 21 Jun 2023 01:50:00 +0200 Subject: [PATCH] tmp --- .../analysis/experimental/TypeInference.cpp | 26 +++++++++ .../analysis/experimental/TypeInference.h | 3 ++ libsolidity/ast/AST.h | 34 ++++++++++++ libsolidity/ast/ASTVisitor.h | 4 ++ libsolidity/ast/AST_accept.h | 24 +++++++++ libsolidity/parsing/Parser.cpp | 54 +++++++++++++++++++ libsolidity/parsing/Parser.h | 1 + .../semanticTests/experimental/stub.sol | 9 ++-- 8 files changed, 150 insertions(+), 5 deletions(-) diff --git a/libsolidity/analysis/experimental/TypeInference.cpp b/libsolidity/analysis/experimental/TypeInference.cpp index a149d2c0c..1e78b5401 100644 --- a/libsolidity/analysis/experimental/TypeInference.cpp +++ b/libsolidity/analysis/experimental/TypeInference.cpp @@ -282,6 +282,32 @@ bool TypeInference::visit(Identifier const& _identifier) return true; } +bool TypeInference::visit(IdentifierPath const& _identifier) +{ + // TODO: deduplicate with Identifier visit + auto& identifierAnnotation = annotation(_identifier); + solAssert(!identifierAnnotation.type); + + auto const* referencedDeclaration = _identifier.annotation().referencedDeclaration; + solAssert(referencedDeclaration); + + auto& declarationAnnotation = annotation(*referencedDeclaration); + if (!declarationAnnotation.type) + referencedDeclaration->accept(*this); + + solAssert(declarationAnnotation.type); + identifierAnnotation.type = declarationAnnotation.type; + + return true; +} + +bool TypeInference::visit(TypeClassInstantiation const& _typeClassInstantiation) +{ + for (auto subNode: _typeClassInstantiation.subNodes()) + subNode->accept(*this); + return false; +} + bool TypeInference::visit(FunctionCall const&) { return true; } void TypeInference::endVisit(FunctionCall const& _functionCall) { diff --git a/libsolidity/analysis/experimental/TypeInference.h b/libsolidity/analysis/experimental/TypeInference.h index 4e54eb9e6..e7b84ac4b 100644 --- a/libsolidity/analysis/experimental/TypeInference.h +++ b/libsolidity/analysis/experimental/TypeInference.h @@ -52,12 +52,15 @@ private: bool visit(Assignment const&) override; void endVisit(Assignment const&) override; bool visit(Identifier const&) override; + bool visit(IdentifierPath const&) override; bool visit(FunctionCall const& _functionCall) override; void endVisit(FunctionCall const& _functionCall) override; bool visit(Return const&) override { return true; } void endVisit(Return const& _return) override; + // TODO: properly account for it bool visit(TypeClassDefinition const&) override { return true; } + bool visit(TypeClassInstantiation const&) override; bool visitNode(ASTNode const& _node) override; diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index d9a1220f8..24dd2b82a 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -2485,6 +2485,40 @@ private: ASTPointer m_typeVariable; std::vector> m_subNodes; }; +class TypeClassInstantiation: public ASTNode, public ScopeOpener +{ +public: + TypeClassInstantiation( + int64_t _id, + SourceLocation const& _location, + ASTPointer _typeConstructor, + std::vector> const& _argumentSorts, + ASTPointer _sort, + std::vector> _subNodes + ): + ASTNode(_id, _location), + m_typeConstructor(std::move(_typeConstructor)), + m_argumentSorts(std::move(_argumentSorts)), + m_sort(std::move(_sort)), + m_subNodes(std::move(_subNodes)) + {} + + void accept(ASTVisitor& _visitor) override; + void accept(ASTConstVisitor& _visitor) const override; + + TypeName const& typeConstructor() const { return *m_typeConstructor; } + std::vector> const& argumentSorts() const { return m_argumentSorts; } + IdentifierPath const& sort() const { return *m_sort; } + std::vector> const& subNodes() const { return m_subNodes; } + + bool experimentalSolidityOnly() const override { return true; } + +private: + ASTPointer m_typeConstructor; + std::vector> m_argumentSorts; + ASTPointer m_sort; + std::vector> m_subNodes; +}; /// @} diff --git a/libsolidity/ast/ASTVisitor.h b/libsolidity/ast/ASTVisitor.h index c38c270b8..ba044a378 100644 --- a/libsolidity/ast/ASTVisitor.h +++ b/libsolidity/ast/ASTVisitor.h @@ -112,6 +112,7 @@ public: /// Experimental Solidity nodes /// @{ virtual bool visit(TypeClassDefinition& _node) { return visitNode(_node); } + virtual bool visit(TypeClassInstantiation& _node) { return visitNode(_node); } /// @} virtual void endVisit(SourceUnit& _node) { endVisitNode(_node); } @@ -172,6 +173,7 @@ public: /// Experimental Solidity nodes /// @{ virtual void endVisit(TypeClassDefinition& _node) { endVisitNode(_node); } + virtual void endVisit(TypeClassInstantiation& _node) { endVisitNode(_node); } /// @} protected: @@ -254,6 +256,7 @@ public: /// Experimental Solidity nodes /// @{ virtual bool visit(TypeClassDefinition const& _node) { return visitNode(_node); } + virtual bool visit(TypeClassInstantiation const& _node) { return visitNode(_node); } /// @} virtual void endVisit(SourceUnit const& _node) { endVisitNode(_node); } @@ -314,6 +317,7 @@ public: /// Experimental Solidity nodes /// @{ virtual void endVisit(TypeClassDefinition const& _node) { endVisitNode(_node); } + virtual void endVisit(TypeClassInstantiation const& _node) { endVisitNode(_node); } /// @} protected: diff --git a/libsolidity/ast/AST_accept.h b/libsolidity/ast/AST_accept.h index fb9f17896..7e5c34794 100644 --- a/libsolidity/ast/AST_accept.h +++ b/libsolidity/ast/AST_accept.h @@ -1049,6 +1049,30 @@ void TypeClassDefinition::accept(ASTConstVisitor& _visitor) const } _visitor.endVisit(*this); } + +void TypeClassInstantiation::accept(ASTVisitor& _visitor) +{ + if (_visitor.visit(*this)) + { + m_typeConstructor->accept(_visitor); + listAccept(m_argumentSorts, _visitor); + m_sort->accept(_visitor); + listAccept(m_subNodes, _visitor); + } + _visitor.endVisit(*this); +} + +void TypeClassInstantiation::accept(ASTConstVisitor& _visitor) const +{ + if (_visitor.visit(*this)) + { + m_typeConstructor->accept(_visitor); + listAccept(m_argumentSorts, _visitor); + m_sort->accept(_visitor); + listAccept(m_subNodes, _visitor); + } + _visitor.endVisit(*this); +} /// @} } diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 3d0ddc662..b4d9f0f17 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -138,6 +138,10 @@ ASTPointer Parser::parse(CharStream& _charStream) solAssert(m_experimentalSolidityEnabledInCurrentSourceUnit); nodes.push_back(parseTypeClassDefinition()); break; + case Token::Instantiation: + solAssert(m_experimentalSolidityEnabledInCurrentSourceUnit); + nodes.push_back(parseTypeClassInstantiation()); + break; default: if ( // Workaround because `error` is not a keyword. @@ -1732,6 +1736,7 @@ ASTPointer Parser::parsePostfixVariableDeclaration() ASTPointer Parser::parseTypeClassDefinition() { + solAssert(m_experimentalSolidityEnabledInCurrentSourceUnit); RecursionGuard recursionGuard(*this); ASTNodeFactory nodeFactory(*this); @@ -1778,6 +1783,55 @@ ASTPointer Parser::parseTypeClassDefinition() ); } +ASTPointer Parser::parseTypeClassInstantiation() +{ + solAssert(m_experimentalSolidityEnabledInCurrentSourceUnit); + RecursionGuard recursionGuard(*this); + ASTNodeFactory nodeFactory(*this); + + vector> subNodes; + + expectToken(Token::Instantiation); + // TODO: parseTypeConstructor() + ASTPointer typeConstructor = parseTypeName(); + expectToken(Token::Colon); + vector> argumentSorts; + if (m_scanner->currentToken() == Token::LParen) + { + expectToken(Token::LParen); + if (m_scanner->currentToken() != Token::RParen) + { + argumentSorts.emplace_back(parseIdentifierPath()); + while (m_scanner->currentToken() == Token::Comma) + { + expectToken(Token::Comma); + argumentSorts.emplace_back(parseIdentifierPath()); + } + } + expectToken(Token::RParen); + } + ASTPointer sort = parseIdentifierPath(); + expectToken(Token::LBrace); + while (true) + { + Token currentTokenValue = m_scanner->currentToken(); + if (currentTokenValue == Token::RBrace) + break; + expectToken(Token::Function, false); + // TODO: require body already during parsing? + subNodes.push_back(parseFunctionDefinition(false, true)); + } + nodeFactory.markEndPosition(); + expectToken(Token::RBrace); + + return nodeFactory.createNode( + typeConstructor, + argumentSorts, + sort, + subNodes + ); +} + ASTPointer Parser::parseSimpleStatement(ASTPointer const& _docString) { RecursionGuard recursionGuard(*this); diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h index cd5af9b3b..c005d3e7e 100644 --- a/libsolidity/parsing/Parser.h +++ b/libsolidity/parsing/Parser.h @@ -177,6 +177,7 @@ private: ); ASTPointer parsePostfixVariableDeclaration(); ASTPointer parseTypeClassDefinition(); + ASTPointer parseTypeClassInstantiation(); ///@} ///@{ diff --git a/test/libsolidity/semanticTests/experimental/stub.sol b/test/libsolidity/semanticTests/experimental/stub.sol index 3998fbf7c..561df62e0 100644 --- a/test/libsolidity/semanticTests/experimental/stub.sol +++ b/test/libsolidity/semanticTests/experimental/stub.sol @@ -4,13 +4,12 @@ pragma experimental solidity; class a:StackType { function stackSize() -> x:integer; } -/* -instantiate uint256 : StackType { - function stackSize() -> (integer) { - return 1; + +instantiation word : StackType { + function stackSize() -> x:integer { + return x; } } -*/ function f(a) -> b { return a;