Allow path syntax for super constructor calls

This commit is contained in:
Mathias Baumann
2020-10-13 14:32:11 +02:00
parent 0b7b174945
commit 006e5f2e1f
57 changed files with 579 additions and 893 deletions
@@ -301,7 +301,7 @@ void ContractLevelChecker::checkBaseConstructorArguments(ContractDefinition cons
if (FunctionDefinition const* constructor = contract->constructor())
for (auto const& modifier: constructor->modifiers())
if (auto baseContract = dynamic_cast<ContractDefinition const*>(
modifier->name()->annotation().referencedDeclaration
modifier->name().annotation().referencedDeclaration
))
{
if (modifier->arguments())
+1 -1
View File
@@ -290,7 +290,7 @@ bool ControlFlowBuilder::visit(ModifierInvocation const& _modifierInvocation)
appendControlFlow(*argument);
auto modifierDefinition = dynamic_cast<ModifierDefinition const*>(
_modifierInvocation.name()->annotation().referencedDeclaration
_modifierInvocation.name().annotation().referencedDeclaration
);
if (!modifierDefinition) return false;
solAssert(!!modifierDefinition, "");
@@ -133,7 +133,7 @@ void DeclarationTypeChecker::endVisit(UserDefinedTypeName const& _typeName)
if (_typeName.annotation().type)
return;
Declaration const* declaration = _typeName.annotation().referencedDeclaration;
Declaration const* declaration = _typeName.pathNode().annotation().referencedDeclaration;
solAssert(declaration, "");
if (StructDefinition const* structDef = dynamic_cast<StructDefinition const*>(declaration))
@@ -390,7 +390,6 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable)
}
_variable.annotation().type = type;
}
void DeclarationTypeChecker::endVisit(UsingForDirective const& _usingFor)
@@ -122,6 +122,18 @@ bool ImmutableValidator::visit(WhileStatement const& _whileStatement)
return false;
}
void ImmutableValidator::endVisit(IdentifierPath const& _identifierPath)
{
if (auto const callableDef = dynamic_cast<CallableDeclaration const*>(_identifierPath.annotation().referencedDeclaration))
visitCallableIfNew(
*_identifierPath.annotation().requiredLookup == VirtualLookup::Virtual ?
callableDef->resolveVirtual(m_currentContract) :
*callableDef
);
solAssert(!dynamic_cast<VariableDeclaration const*>(_identifierPath.annotation().referencedDeclaration), "");
}
void ImmutableValidator::endVisit(Identifier const& _identifier)
{
if (auto const callableDef = dynamic_cast<CallableDeclaration const*>(_identifier.annotation().referencedDeclaration))
@@ -53,6 +53,7 @@ private:
bool visit(MemberAccess const& _memberAccess);
bool visit(IfStatement const& _ifStatement);
bool visit(WhileStatement const& _whileStatement);
void endVisit(IdentifierPath const& _identifierPath);
void endVisit(Identifier const& _identifier);
void endVisit(Return const& _return);
+1 -1
View File
@@ -400,7 +400,7 @@ void NameAndTypeResolver::linearizeBaseContracts(ContractDefinition& _contract)
list<list<ContractDefinition const*>> input(1, list<ContractDefinition const*>{});
for (ASTPointer<InheritanceSpecifier> const& baseSpecifier: _contract.baseContracts())
{
UserDefinedTypeName const& baseName = baseSpecifier->name();
IdentifierPath const& baseName = baseSpecifier->name();
auto base = dynamic_cast<ContractDefinition const*>(baseName.annotation().referencedDeclaration);
if (!base)
m_errorReporter.fatalTypeError(8758_error, baseName.location(), "Contract expected.");
+5 -5
View File
@@ -154,12 +154,12 @@ vector<ContractDefinition const*> resolveDirectBaseContracts(ContractDefinition
return resolvedContracts;
}
vector<ASTPointer<UserDefinedTypeName>> sortByContract(vector<ASTPointer<UserDefinedTypeName>> const& _list)
vector<ASTPointer<IdentifierPath>> sortByContract(vector<ASTPointer<IdentifierPath>> const& _list)
{
auto sorted = _list;
stable_sort(sorted.begin(), sorted.end(),
[] (ASTPointer<UserDefinedTypeName> _a, ASTPointer<UserDefinedTypeName> _b) {
[] (ASTPointer<IdentifierPath> _a, ASTPointer<IdentifierPath> _b) {
if (!_a || !_b)
return _a < _b;
@@ -773,7 +773,7 @@ set<ContractDefinition const*, OverrideChecker::CompareByID> OverrideChecker::re
{
set<ContractDefinition const*, CompareByID> resolved;
for (ASTPointer<UserDefinedTypeName> const& override: _overrides.overrides())
for (ASTPointer<IdentifierPath> const& override: _overrides.overrides())
{
Declaration const* decl = override->annotation().referencedDeclaration;
solAssert(decl, "Expected declaration to be resolved.");
@@ -798,7 +798,7 @@ void OverrideChecker::checkOverrideList(OverrideProxy _item, OverrideProxyBySign
if (_item.overrides() && specifiedContracts.size() != _item.overrides()->overrides().size())
{
// Sort by contract id to find duplicate for error reporting
vector<ASTPointer<UserDefinedTypeName>> list =
vector<ASTPointer<IdentifierPath>> list =
sortByContract(_item.overrides()->overrides());
// Find duplicates and output error
@@ -818,7 +818,7 @@ void OverrideChecker::checkOverrideList(OverrideProxy _item, OverrideProxyBySign
list[i]->location(),
ssl,
"Duplicate contract \"" +
joinHumanReadable(list[i]->namePath(), ".") +
joinHumanReadable(list[i]->path(), ".") +
"\" found in override list of \"" +
_item.name() +
"\"."
+1 -1
View File
@@ -217,7 +217,7 @@ struct OverrideSpecifierChecker: public PostTypeChecker::Checker
void endVisit(OverrideSpecifier const& _overrideSpecifier) override
{
for (ASTPointer<UserDefinedTypeName> const& override: _overrideSpecifier.overrides())
for (ASTPointer<IdentifierPath> const& override: _overrideSpecifier.overrides())
{
Declaration const* decl = override->annotation().referencedDeclaration;
solAssert(decl, "Expected declaration to be resolved.");
@@ -183,11 +183,6 @@ void ReferencesResolver::endVisit(IdentifierPath const& _path)
_path.annotation().referencedDeclaration = declaration;
}
void ReferencesResolver::endVisit(UserDefinedTypeName const& _typeName)
{
_typeName.annotation().referencedDeclaration = _typeName.pathNode()->annotation().referencedDeclaration;
}
bool ReferencesResolver::visit(InlineAssembly const& _inlineAssembly)
{
m_resolver.warnVariablesNamedLikeInstructions();
+1 -2
View File
@@ -82,8 +82,7 @@ private:
void endVisit(FunctionDefinition const& _functionDefinition) override;
bool visit(ModifierDefinition const& _modifierDefinition) override;
void endVisit(ModifierDefinition const& _modifierDefinition) override;
void endVisit(IdentifierPath const& _typeName) override;
void endVisit(UserDefinedTypeName const& _typeName) override;
void endVisit(IdentifierPath const& _path) override;
bool visit(InlineAssembly const& _inlineAssembly) override;
bool visit(Return const& _return) override;
+27 -7
View File
@@ -351,6 +351,9 @@ bool TypeChecker::visit(FunctionDefinition const& _function)
if (_function.overrides() && _function.isFree())
m_errorReporter.syntaxError(1750_error, _function.location(), "Free functions cannot override.");
if (!_function.modifiers().empty() && _function.isFree())
m_errorReporter.syntaxError(5811_error, _function.location(), "Free functions cannot have modifiers.");
if (_function.isPayable())
{
if (_function.libraryFunction())
@@ -443,7 +446,7 @@ bool TypeChecker::visit(FunctionDefinition const& _function)
*modifier,
_function.isConstructor() ? baseContracts : vector<ContractDefinition const*>()
);
Declaration const* decl = &dereference(*modifier->name());
Declaration const* decl = &dereference(modifier->name());
if (modifiers.count(decl))
{
if (dynamic_cast<ContractDefinition const*>(decl))
@@ -627,9 +630,9 @@ void TypeChecker::visitManually(
for (ASTPointer<Expression> const& argument: arguments)
argument->accept(*this);
_modifier.name()->accept(*this);
_modifier.name().accept(*this);
auto const* declaration = &dereference(*_modifier.name());
auto const* declaration = &dereference(_modifier.name());
vector<ASTPointer<VariableDeclaration>> emptyParameterList;
vector<ASTPointer<VariableDeclaration>> const* parameters = nullptr;
if (auto modifierDecl = dynamic_cast<ModifierDefinition const*>(declaration))
@@ -2534,7 +2537,7 @@ void TypeChecker::endVisit(NewExpression const& _newExpression)
if (auto contractName = dynamic_cast<UserDefinedTypeName const*>(&_newExpression.typeName()))
{
auto contract = dynamic_cast<ContractDefinition const*>(&dereference(*contractName));
auto contract = dynamic_cast<ContractDefinition const*>(&dereference(contractName->pathNode()));
if (!contract)
m_errorReporter.fatalTypeError(5540_error, _newExpression.location(), "Identifier is not a contract.");
@@ -3196,6 +3199,23 @@ bool TypeChecker::visit(Identifier const& _identifier)
return false;
}
void TypeChecker::endVisit(IdentifierPath const& _identifierPath)
{
if (
dynamic_cast<CallableDeclaration const*>(_identifierPath.annotation().referencedDeclaration) &&
_identifierPath.path().size() == 1
)
_identifierPath.annotation().requiredLookup = VirtualLookup::Virtual;
else
_identifierPath.annotation().requiredLookup = VirtualLookup::Static;
}
void TypeChecker::endVisit(UserDefinedTypeName const& _userDefinedTypeName)
{
if (!_userDefinedTypeName.annotation().type)
_userDefinedTypeName.annotation().type = _userDefinedTypeName.pathNode().annotation().referencedDeclaration->type();
}
void TypeChecker::endVisit(ElementaryTypeNameExpression const& _expr)
{
_expr.annotation().type = TypeProvider::typeType(TypeProvider::fromElementaryTypeName(_expr.type().typeName(), _expr.type().stateMutability()));
@@ -3293,10 +3313,10 @@ Declaration const& TypeChecker::dereference(Identifier const& _identifier) const
return *_identifier.annotation().referencedDeclaration;
}
Declaration const& TypeChecker::dereference(UserDefinedTypeName const& _typeName) const
Declaration const& TypeChecker::dereference(IdentifierPath const& _path) const
{
solAssert(!!_typeName.annotation().referencedDeclaration, "Declaration not stored.");
return *_typeName.annotation().referencedDeclaration;
solAssert(!!_path.annotation().referencedDeclaration, "Declaration not stored.");
return *_path.annotation().referencedDeclaration;
}
bool TypeChecker::expectType(Expression const& _expression, Type const& _expectedType)
+3 -1
View File
@@ -141,6 +141,8 @@ private:
bool visit(IndexAccess const& _indexAccess) override;
bool visit(IndexRangeAccess const& _indexRangeAccess) override;
bool visit(Identifier const& _identifier) override;
void endVisit(IdentifierPath const& _identifierPath) override;
void endVisit(UserDefinedTypeName const& _userDefinedTypeName) override;
void endVisit(ElementaryTypeNameExpression const& _expr) override;
void endVisit(Literal const& _literal) override;
void endVisit(UsingForDirective const& _usingForDirective) override;
@@ -153,7 +155,7 @@ private:
/// @returns the referenced declaration and throws on error.
Declaration const& dereference(Identifier const& _identifier) const;
/// @returns the referenced declaration and throws on error.
Declaration const& dereference(UserDefinedTypeName const& _typeName) const;
Declaration const& dereference(IdentifierPath const& _path) const;
std::vector<Declaration const*> cleanOverloadedDeclarations(
Identifier const& _reference,
+2 -3
View File
@@ -432,13 +432,12 @@ void ViewPureChecker::endVisit(IndexRangeAccess const& _indexRangeAccess)
void ViewPureChecker::endVisit(ModifierInvocation const& _modifier)
{
solAssert(_modifier.name(), "");
if (ModifierDefinition const* mod = dynamic_cast<decltype(mod)>(_modifier.name()->annotation().referencedDeclaration))
if (ModifierDefinition const* mod = dynamic_cast<decltype(mod)>(_modifier.name().annotation().referencedDeclaration))
{
MutabilityAndLocation const& mutAndLocation = modifierMutability(*mod);
reportMutability(mutAndLocation.mutability, _modifier.location(), mutAndLocation.location);
}
else
solAssert(dynamic_cast<ContractDefinition const*>(_modifier.name()->annotation().referencedDeclaration), "");
solAssert(dynamic_cast<ContractDefinition const*>(_modifier.name().annotation().referencedDeclaration), "");
}