diff options
author | chriseth <c@ethdev.com> | 2015-11-23 03:39:10 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-11-27 00:49:39 +0800 |
commit | d71cd3aa2b235f877b7928b57c94159e2c16865c (patch) | |
tree | b24bc90e27cdc7e8cf2a5674aa9376bef72db2aa /libsolidity | |
parent | 09b2f9acb7f5f47f53c4b56fdf0f86946551bf12 (diff) | |
download | dexon-solidity-d71cd3aa2b235f877b7928b57c94159e2c16865c.tar.gz dexon-solidity-d71cd3aa2b235f877b7928b57c94159e2c16865c.tar.zst dexon-solidity-d71cd3aa2b235f877b7928b57c94159e2c16865c.zip |
Added the `using x for y` directive.
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/analysis/NameAndTypeResolver.h | 4 | ||||
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 11 | ||||
-rw-r--r-- | libsolidity/analysis/TypeChecker.h | 1 | ||||
-rw-r--r-- | libsolidity/ast/AST.h | 27 | ||||
-rw-r--r-- | libsolidity/ast/ASTVisitor.h | 4 | ||||
-rw-r--r-- | libsolidity/ast/AST_accept.h | 22 | ||||
-rw-r--r-- | libsolidity/parsing/Parser.cpp | 20 | ||||
-rw-r--r-- | libsolidity/parsing/Parser.h | 1 |
8 files changed, 87 insertions, 3 deletions
diff --git a/libsolidity/analysis/NameAndTypeResolver.h b/libsolidity/analysis/NameAndTypeResolver.h index 0d9b2477..1547a274 100644 --- a/libsolidity/analysis/NameAndTypeResolver.h +++ b/libsolidity/analysis/NameAndTypeResolver.h @@ -160,8 +160,8 @@ private: void fatalDeclarationError(SourceLocation _sourceLocation, std::string const& _description); std::map<ASTNode const*, DeclarationContainer>& m_scopes; - Declaration const* m_currentScope; - VariableScope* m_currentFunction; + Declaration const* m_currentScope = nullptr; + VariableScope* m_currentFunction = nullptr; ErrorList& m_errors; }; diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 1d2d0258..22fb1e96 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -356,7 +356,16 @@ void TypeChecker::endVisit(InheritanceSpecifier const& _inheritance) " to " + parameterTypes[i]->toString() + " requested." - ); + ); +} + +void TypeChecker::endVisit(UsingForDirective const& _usingFor) +{ + ContractDefinition const* library = dynamic_cast<ContractDefinition const*>( + _usingFor.libraryName().annotation().referencedDeclaration + ); + if (!library || !library->isLibrary()) + typeError(_usingFor.libraryName().location(), "Library name expected."); } bool TypeChecker::visit(StructDefinition const& _struct) diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h index 9563d4a9..7829a23d 100644 --- a/libsolidity/analysis/TypeChecker.h +++ b/libsolidity/analysis/TypeChecker.h @@ -76,6 +76,7 @@ private: void checkLibraryRequirements(ContractDefinition const& _contract); virtual void endVisit(InheritanceSpecifier const& _inheritance) override; + virtual void endVisit(UsingForDirective const& _usingFor) override; virtual bool visit(StructDefinition const& _struct) override; virtual bool visit(FunctionDefinition const& _function) override; virtual bool visit(VariableDeclaration const& _variable) override; diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index a28d9f4f..2d6e9cfc 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -335,6 +335,33 @@ private: std::vector<ASTPointer<Expression>> m_arguments; }; +/** + * `using LibraryName for uint` will attach all functions from the library LibraryName + * to `uint` if the first parameter matches the type. `using LibraryName for *` attaches + * the function to any matching type. + */ +class UsingForDirective: public ASTNode +{ +public: + UsingForDirective( + SourceLocation const& _location, + ASTPointer<Identifier> const& _libraryName, + ASTPointer<TypeName> const& _typeName + ): + ASTNode(_location), m_libraryName(_libraryName), m_typeName(_typeName) {} + + virtual void accept(ASTVisitor& _visitor) override; + virtual void accept(ASTConstVisitor& _visitor) const override; + + Identifier const& libraryName() const { return *m_libraryName; } + /// @returns the type name the library is attached to, null for `*`. + TypeName const* typeName() const { return m_typeName.get(); } + +private: + ASTPointer<Identifier> m_libraryName; + ASTPointer<TypeName> m_typeName; +}; + class StructDefinition: public Declaration { public: diff --git a/libsolidity/ast/ASTVisitor.h b/libsolidity/ast/ASTVisitor.h index 14c09fb4..f04d9682 100644 --- a/libsolidity/ast/ASTVisitor.h +++ b/libsolidity/ast/ASTVisitor.h @@ -47,6 +47,7 @@ public: virtual bool visit(ImportDirective& _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); } virtual bool visit(StructDefinition& _node) { return visitNode(_node); } virtual bool visit(EnumDefinition& _node) { return visitNode(_node); } virtual bool visit(EnumValue& _node) { return visitNode(_node); } @@ -88,6 +89,7 @@ public: virtual void endVisit(ImportDirective& _node) { endVisitNode(_node); } virtual void endVisit(ContractDefinition& _node) { endVisitNode(_node); } virtual void endVisit(InheritanceSpecifier& _node) { endVisitNode(_node); } + virtual void endVisit(UsingForDirective& _node) { endVisitNode(_node); } virtual void endVisit(StructDefinition& _node) { endVisitNode(_node); } virtual void endVisit(EnumDefinition& _node) { endVisitNode(_node); } virtual void endVisit(EnumValue& _node) { endVisitNode(_node); } @@ -142,6 +144,7 @@ public: 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); } + virtual bool visit(UsingForDirective const& _node) { return visitNode(_node); } virtual bool visit(EnumDefinition const& _node) { return visitNode(_node); } virtual bool visit(EnumValue const& _node) { return visitNode(_node); } virtual bool visit(ParameterList const& _node) { return visitNode(_node); } @@ -182,6 +185,7 @@ public: virtual void endVisit(ImportDirective 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); } virtual void endVisit(StructDefinition const& _node) { endVisitNode(_node); } virtual void endVisit(EnumDefinition const& _node) { endVisitNode(_node); } virtual void endVisit(EnumValue const& _node) { endVisitNode(_node); } diff --git a/libsolidity/ast/AST_accept.h b/libsolidity/ast/AST_accept.h index f65595b8..3f7b8d36 100644 --- a/libsolidity/ast/AST_accept.h +++ b/libsolidity/ast/AST_accept.h @@ -123,6 +123,28 @@ void EnumValue::accept(ASTConstVisitor& _visitor) const _visitor.endVisit(*this); } +void UsingForDirective::accept(ASTVisitor& _visitor) +{ + if (_visitor.visit(*this)) + { + if (m_libraryName) + m_libraryName->accept(_visitor); + m_typeName->accept(_visitor); + } + _visitor.endVisit(*this); +} + +void UsingForDirective::accept(ASTConstVisitor& _visitor) const +{ + if (_visitor.visit(*this)) + { + if (m_libraryName) + m_libraryName->accept(_visitor); + m_typeName->accept(_visitor); + } + _visitor.endVisit(*this); +} + void StructDefinition::accept(ASTVisitor& _visitor) { if (_visitor.visit(*this)) diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 9272eb4b..2b886121 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -168,6 +168,8 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition(bool _isLibrary) subNodes.push_back(parseModifierDefinition()); else if (currentTokenValue == Token::Event) subNodes.push_back(parseEventDefinition()); + else if (currentTokenValue == Token::Using) + subNodes.push_back(parseUsingDirective()); else fatalParserError(std::string("Function, variable, struct or modifier declaration expected.")); } @@ -475,6 +477,24 @@ ASTPointer<EventDefinition> Parser::parseEventDefinition() return nodeFactory.createNode<EventDefinition>(name, docstring, parameters, anonymous); } +ASTPointer<UsingForDirective> Parser::parseUsingDirective() +{ + ASTNodeFactory nodeFactory(*this); + + expectToken(Token::Using); + //@todo this should actually parse a full path. + ASTPointer<Identifier> library(parseIdentifier()); + ASTPointer<TypeName> typeName; + expectToken(Token::For); + if (m_scanner->currentToken() == Token::Mul) + m_scanner->next(); + else + typeName = parseTypeName(false); + nodeFactory.markEndPosition(); + expectToken(Token::Semicolon); + return nodeFactory.createNode<UsingForDirective>(library, typeName); +} + ASTPointer<ModifierInvocation> Parser::parseModifierInvocation() { ASTNodeFactory nodeFactory(*this); diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h index 663c0f92..5ff46242 100644 --- a/libsolidity/parsing/Parser.h +++ b/libsolidity/parsing/Parser.h @@ -74,6 +74,7 @@ private: ); ASTPointer<ModifierDefinition> parseModifierDefinition(); ASTPointer<EventDefinition> parseEventDefinition(); + ASTPointer<UsingForDirective> parseUsingDirective(); ASTPointer<ModifierInvocation> parseModifierInvocation(); ASTPointer<Identifier> parseIdentifier(); ASTPointer<TypeName> parseTypeName(bool _allowVar); |