This commit is contained in:
Christian Parpart 2020-05-27 13:42:02 +02:00
parent 2130c446e2
commit 1966438472
6 changed files with 35 additions and 7 deletions

View File

@ -48,7 +48,6 @@ importDeclaration
interfaceDefinition
: 'interface' identifier 'from' StringLiteralFragment
| 'interface' identifier 'as' AbiString
| 'interface' identifier contractInheritanceDefinition? contractBody ;
AbiString

View File

@ -132,6 +132,15 @@ public:
return ElementaryTypeNameToken(m_tokens[Current].token, firstSize, secondSize);
}
/// Tests if current keyword is an identifier and matches the given value @p _name.
///
/// This is best used for directives that cannot be reserved as keywords but
/// in some context should be treated like one.
bool isIdentifier(std::string const& _name) const
{
return currentToken() == Token::Identifier && currentLiteral() == _name;
}
SourceLocation currentLocation() const { return m_tokens[Current].location; }
std::string const& currentLiteral() const { return m_tokens[Current].literal; }
std::tuple<unsigned, unsigned> const& currentTokenInfo() const { return m_tokens[Current].extendedTokenInfo; }

View File

@ -160,7 +160,6 @@ namespace solidity::langutil
K(External, "external", 0) \
K(Fallback, "fallback", 0) \
K(For, "for", 0) \
K(From, "from", 0) \
K(Function, "function", 0) \
K(Hex, "hex", 0) \
K(If, "if", 0) \

View File

@ -171,7 +171,7 @@ public:
SourceUnitAnnotation& annotation() const override;
std::optional<std::string> const& licenseString() const { return m_licenseString; }
std::vector<ASTPointer<ASTNode>> nodes() const { return m_nodes; }
std::vector<ASTPointer<ASTNode>> const& nodes() const { return m_nodes; }
/// Replaces given top-level AST node with a new AST node.
void replaceNode(ASTPointer<ASTNode> _oldNode, ASTPointer<ASTNode> _newNode);
@ -453,6 +453,24 @@ protected:
/// @}
class ImportedContractDefinition: public Declaration
{
public:
ImportedContractDefinition(
int64_t _id,
SourceLocation const& _location,
ASTPointer<ASTString> const& _name,
ASTPointer<ASTString> const& _path
);
void accept(ASTVisitor& _visitor) override;
void accept(ASTConstVisitor& _visitor) const override;
private:
ASTPointer<ASTString> m_name;
ASTPointer<ASTString> m_path;
};
/**
* Definition of a contract or library. This is the only AST nodes where child nodes are not visited in
* document order. It first visits all struct declarations, then all variable declarations and

View File

@ -278,9 +278,12 @@ void CompilerStack::loadMissingInterfaces()
{
for (auto const& sourcePair: m_sources)
{
ASTPointer<SourceUnit> const& source = sourcePair.second.ast;;
ASTPointer<SourceUnit> const& source = sourcePair.second.ast;
if (!source)
// This can happen if the input source code contained invalid source code.
continue;
for (auto const& astNode: source->nodes())
for (ASTPointer<ASTNode> const& astNode: source->nodes())
{
if (auto* contract = dynamic_cast<ContractDefinition*>(astNode.get()))
{

View File

@ -250,7 +250,7 @@ ASTPointer<ImportDirective> Parser::parseImportDirective()
fatalParserError(9478_error, "Expected string literal (path), \"*\" or alias list.");
// "from" is not a keyword but parsed as an identifier because of backwards
// compatibility and because it is a really common word.
if (m_scanner->currentToken() != Token::Identifier || m_scanner->currentLiteral() != "from")
if (!m_scanner->isIdentifier("from"))
fatalParserError(8208_error, "Expected \"from\".");
m_scanner->next();
if (m_scanner->currentToken() != Token::StringLiteral)
@ -307,7 +307,7 @@ ASTPointer<ContractDefinition> Parser::parseInterfaceDefinition()
ASTPointer<StructuredDocumentation> documentation = parseStructuredDocumentation();
vector<ASTPointer<InheritanceSpecifier>> baseContracts;
if (m_scanner->currentToken() == Token::From)
if (m_scanner->isIdentifier("from"))
{
m_scanner->next();
if (m_scanner->currentToken() != Token::StringLiteral)