Use paths instead of simple identifiers wherever possible.

This commit is contained in:
chriseth 2015-12-21 18:44:21 +01:00
parent 8fe89455b3
commit 0e2fa39fad
6 changed files with 27 additions and 24 deletions

View File

@ -264,7 +264,7 @@ void NameAndTypeResolver::linearizeBaseContracts(ContractDefinition& _contract)
list<list<ContractDefinition const*>> input(1, {}); list<list<ContractDefinition const*>> input(1, {});
for (ASTPointer<InheritanceSpecifier> const& baseSpecifier: _contract.baseContracts()) for (ASTPointer<InheritanceSpecifier> const& baseSpecifier: _contract.baseContracts())
{ {
Identifier const& baseName = baseSpecifier->name(); UserDefinedTypeName const& baseName = baseSpecifier->name();
auto base = dynamic_cast<ContractDefinition const*>(baseName.annotation().referencedDeclaration); auto base = dynamic_cast<ContractDefinition const*>(baseName.annotation().referencedDeclaration);
if (!base) if (!base)
reportFatalTypeError(baseName.createTypeError("Contract expected.")); reportFatalTypeError(baseName.createTypeError("Contract expected."));

View File

@ -340,7 +340,7 @@ class InheritanceSpecifier: public ASTNode
public: public:
InheritanceSpecifier( InheritanceSpecifier(
SourceLocation const& _location, SourceLocation const& _location,
ASTPointer<Identifier> const& _baseName, ASTPointer<UserDefinedTypeName> const& _baseName,
std::vector<ASTPointer<Expression>> _arguments std::vector<ASTPointer<Expression>> _arguments
): ):
ASTNode(_location), m_baseName(_baseName), m_arguments(_arguments) {} ASTNode(_location), m_baseName(_baseName), m_arguments(_arguments) {}
@ -348,11 +348,11 @@ public:
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override; virtual void accept(ASTConstVisitor& _visitor) const override;
Identifier const& name() const { return *m_baseName; } UserDefinedTypeName const& name() const { return *m_baseName; }
std::vector<ASTPointer<Expression>> const& arguments() const { return m_arguments; } std::vector<ASTPointer<Expression>> const& arguments() const { return m_arguments; }
private: private:
ASTPointer<Identifier> m_baseName; ASTPointer<UserDefinedTypeName> m_baseName;
std::vector<ASTPointer<Expression>> m_arguments; std::vector<ASTPointer<Expression>> m_arguments;
}; };
@ -366,7 +366,7 @@ class UsingForDirective: public ASTNode
public: public:
UsingForDirective( UsingForDirective(
SourceLocation const& _location, SourceLocation const& _location,
ASTPointer<Identifier> const& _libraryName, ASTPointer<UserDefinedTypeName> const& _libraryName,
ASTPointer<TypeName> const& _typeName ASTPointer<TypeName> const& _typeName
): ):
ASTNode(_location), m_libraryName(_libraryName), m_typeName(_typeName) {} ASTNode(_location), m_libraryName(_libraryName), m_typeName(_typeName) {}
@ -374,12 +374,12 @@ public:
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override; virtual void accept(ASTConstVisitor& _visitor) const override;
Identifier const& libraryName() const { return *m_libraryName; } UserDefinedTypeName const& libraryName() const { return *m_libraryName; }
/// @returns the type name the library is attached to, null for `*`. /// @returns the type name the library is attached to, null for `*`.
TypeName const* typeName() const { return m_typeName.get(); } TypeName const* typeName() const { return m_typeName.get(); }
private: private:
ASTPointer<Identifier> m_libraryName; ASTPointer<UserDefinedTypeName> m_libraryName;
ASTPointer<TypeName> m_typeName; ASTPointer<TypeName> m_typeName;
}; };

View File

@ -63,7 +63,7 @@ bool ASTPrinter::visit(ContractDefinition const& _node)
bool ASTPrinter::visit(InheritanceSpecifier const& _node) bool ASTPrinter::visit(InheritanceSpecifier const& _node)
{ {
writeLine("InheritanceSpecifier \"" + _node.name().name() + "\""); writeLine("InheritanceSpecifier");
printSourcePart(_node); printSourcePart(_node);
return goDeeper(); return goDeeper();
} }

View File

@ -238,7 +238,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition(bool _isLibrary)
ASTPointer<InheritanceSpecifier> Parser::parseInheritanceSpecifier() ASTPointer<InheritanceSpecifier> Parser::parseInheritanceSpecifier()
{ {
ASTNodeFactory nodeFactory(*this); ASTNodeFactory nodeFactory(*this);
ASTPointer<Identifier> name(parseIdentifier()); ASTPointer<UserDefinedTypeName> name(parseUserDefinedTypeName());
vector<ASTPointer<Expression>> arguments; vector<ASTPointer<Expression>> arguments;
if (m_scanner->currentToken() == Token::LParen) if (m_scanner->currentToken() == Token::LParen)
{ {
@ -533,8 +533,7 @@ ASTPointer<UsingForDirective> Parser::parseUsingDirective()
ASTNodeFactory nodeFactory(*this); ASTNodeFactory nodeFactory(*this);
expectToken(Token::Using); expectToken(Token::Using);
//@todo this should actually parse a full path. ASTPointer<UserDefinedTypeName> library(parseUserDefinedTypeName());
ASTPointer<Identifier> library(parseIdentifier());
ASTPointer<TypeName> typeName; ASTPointer<TypeName> typeName;
expectToken(Token::For); expectToken(Token::For);
if (m_scanner->currentToken() == Token::Mul) if (m_scanner->currentToken() == Token::Mul)
@ -570,6 +569,20 @@ ASTPointer<Identifier> Parser::parseIdentifier()
return nodeFactory.createNode<Identifier>(expectIdentifierToken()); return nodeFactory.createNode<Identifier>(expectIdentifierToken());
} }
ASTPointer<UserDefinedTypeName> Parser::parseUserDefinedTypeName()
{
ASTNodeFactory nodeFactory(*this);
nodeFactory.markEndPosition();
vector<ASTString> identifierPath{*expectIdentifierToken()};
while (m_scanner->currentToken() == Token::Period)
{
m_scanner->next();
nodeFactory.markEndPosition();
identifierPath.push_back(*expectIdentifierToken());
}
return nodeFactory.createNode<UserDefinedTypeName>(identifierPath);
}
ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar) ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar)
{ {
ASTNodeFactory nodeFactory(*this); ASTNodeFactory nodeFactory(*this);
@ -589,18 +602,7 @@ ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar)
else if (token == Token::Mapping) else if (token == Token::Mapping)
type = parseMapping(); type = parseMapping();
else if (token == Token::Identifier) else if (token == Token::Identifier)
{ type = parseUserDefinedTypeName();
ASTNodeFactory nodeFactory(*this);
nodeFactory.markEndPosition();
vector<ASTString> identifierPath{*expectIdentifierToken()};
while (m_scanner->currentToken() == Token::Period)
{
m_scanner->next();
nodeFactory.markEndPosition();
identifierPath.push_back(*expectIdentifierToken());
}
type = nodeFactory.createNode<UserDefinedTypeName>(identifierPath);
}
else else
fatalParserError(string("Expected type name")); fatalParserError(string("Expected type name"));

View File

@ -77,6 +77,7 @@ private:
ASTPointer<UsingForDirective> parseUsingDirective(); ASTPointer<UsingForDirective> parseUsingDirective();
ASTPointer<ModifierInvocation> parseModifierInvocation(); ASTPointer<ModifierInvocation> parseModifierInvocation();
ASTPointer<Identifier> parseIdentifier(); ASTPointer<Identifier> parseIdentifier();
ASTPointer<UserDefinedTypeName> parseUserDefinedTypeName();
ASTPointer<TypeName> parseTypeName(bool _allowVar); ASTPointer<TypeName> parseTypeName(bool _allowVar);
ASTPointer<Mapping> parseMapping(); ASTPointer<Mapping> parseMapping();
ASTPointer<ParameterList> parseParameterList( ASTPointer<ParameterList> parseParameterList(

View File

@ -97,7 +97,7 @@ BOOST_AUTO_TEST_CASE(simple_alias)
{ {
CompilerStack c; CompilerStack c;
c.addSource("a", "contract A {}"); c.addSource("a", "contract A {}");
c.addSource("dir/a/b/c", "import \"../../.././a\" as x; contract B { function() { x.A r = x.A(20); } }"); c.addSource("dir/a/b/c", "import \"../../.././a\" as x; contract B is x.A { function() { x.A r = x.A(20); } }");
BOOST_CHECK(c.compile()); BOOST_CHECK(c.compile());
} }