mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Allow path syntax for super constructor calls
This commit is contained in:
@@ -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())
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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.");
|
||||
|
||||
@@ -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() +
|
||||
"\"."
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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), "");
|
||||
}
|
||||
|
||||
|
||||
@@ -460,11 +460,6 @@ EventDefinitionAnnotation& EventDefinition::annotation() const
|
||||
return initAnnotation<EventDefinitionAnnotation>();
|
||||
}
|
||||
|
||||
UserDefinedTypeNameAnnotation& UserDefinedTypeName::annotation() const
|
||||
{
|
||||
return initAnnotation<UserDefinedTypeNameAnnotation>();
|
||||
}
|
||||
|
||||
SourceUnit const& Scopable::sourceUnit() const
|
||||
{
|
||||
ASTNode const* s = scope();
|
||||
|
||||
+18
-18
@@ -558,7 +558,7 @@ private:
|
||||
};
|
||||
|
||||
/**
|
||||
* A sequence of identifiers separated by dots
|
||||
* A sequence of identifiers separated by dots used outside the expression context. Inside the expression context, this is a sequence of Identifier and MemberAccess.
|
||||
*/
|
||||
class IdentifierPath: public ASTNode
|
||||
{
|
||||
@@ -584,7 +584,7 @@ public:
|
||||
InheritanceSpecifier(
|
||||
int64_t _id,
|
||||
SourceLocation const& _location,
|
||||
ASTPointer<UserDefinedTypeName> _baseName,
|
||||
ASTPointer<IdentifierPath> _baseName,
|
||||
std::unique_ptr<std::vector<ASTPointer<Expression>>> _arguments
|
||||
):
|
||||
ASTNode(_id, _location), m_baseName(std::move(_baseName)), m_arguments(std::move(_arguments))
|
||||
@@ -595,14 +595,14 @@ public:
|
||||
void accept(ASTVisitor& _visitor) override;
|
||||
void accept(ASTConstVisitor& _visitor) const override;
|
||||
|
||||
UserDefinedTypeName const& name() const { return *m_baseName; }
|
||||
IdentifierPath const& name() const { return *m_baseName; }
|
||||
// Returns nullptr if no argument list was given (``C``).
|
||||
// If an argument list is given (``C(...)``), the arguments are returned
|
||||
// as a vector of expressions. Note that this vector can be empty (``C()``).
|
||||
std::vector<ASTPointer<Expression>> const* arguments() const { return m_arguments.get(); }
|
||||
|
||||
private:
|
||||
ASTPointer<UserDefinedTypeName> m_baseName;
|
||||
ASTPointer<IdentifierPath> m_baseName;
|
||||
std::unique_ptr<std::vector<ASTPointer<Expression>>> m_arguments;
|
||||
};
|
||||
|
||||
@@ -617,7 +617,7 @@ public:
|
||||
UsingForDirective(
|
||||
int64_t _id,
|
||||
SourceLocation const& _location,
|
||||
ASTPointer<UserDefinedTypeName> _libraryName,
|
||||
ASTPointer<IdentifierPath> _libraryName,
|
||||
ASTPointer<TypeName> _typeName
|
||||
):
|
||||
ASTNode(_id, _location), m_libraryName(std::move(_libraryName)), m_typeName(std::move(_typeName))
|
||||
@@ -628,12 +628,12 @@ public:
|
||||
void accept(ASTVisitor& _visitor) override;
|
||||
void accept(ASTConstVisitor& _visitor) const override;
|
||||
|
||||
UserDefinedTypeName const& libraryName() const { return *m_libraryName; }
|
||||
IdentifierPath 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<UserDefinedTypeName> m_libraryName;
|
||||
ASTPointer<IdentifierPath> m_libraryName;
|
||||
ASTPointer<TypeName> m_typeName;
|
||||
};
|
||||
|
||||
@@ -792,7 +792,7 @@ public:
|
||||
OverrideSpecifier(
|
||||
int64_t _id,
|
||||
SourceLocation const& _location,
|
||||
std::vector<ASTPointer<UserDefinedTypeName>> _overrides
|
||||
std::vector<ASTPointer<IdentifierPath>> _overrides
|
||||
):
|
||||
ASTNode(_id, _location),
|
||||
m_overrides(std::move(_overrides))
|
||||
@@ -803,10 +803,10 @@ public:
|
||||
void accept(ASTConstVisitor& _visitor) const override;
|
||||
|
||||
/// @returns the list of specific overrides, if any
|
||||
std::vector<ASTPointer<UserDefinedTypeName>> const& overrides() const { return m_overrides; }
|
||||
std::vector<ASTPointer<IdentifierPath>> const& overrides() const { return m_overrides; }
|
||||
|
||||
protected:
|
||||
std::vector<ASTPointer<UserDefinedTypeName>> m_overrides;
|
||||
std::vector<ASTPointer<IdentifierPath>> m_overrides;
|
||||
};
|
||||
|
||||
class FunctionDefinition: public CallableDeclaration, public StructurallyDocumented, public ImplementationOptional, public ScopeOpener
|
||||
@@ -1077,7 +1077,7 @@ public:
|
||||
ModifierInvocation(
|
||||
int64_t _id,
|
||||
SourceLocation const& _location,
|
||||
ASTPointer<Identifier> _name,
|
||||
ASTPointer<IdentifierPath> _name,
|
||||
std::unique_ptr<std::vector<ASTPointer<Expression>>> _arguments
|
||||
):
|
||||
ASTNode(_id, _location), m_modifierName(std::move(_name)), m_arguments(std::move(_arguments))
|
||||
@@ -1088,14 +1088,14 @@ public:
|
||||
void accept(ASTVisitor& _visitor) override;
|
||||
void accept(ASTConstVisitor& _visitor) const override;
|
||||
|
||||
ASTPointer<Identifier> const& name() const { return m_modifierName; }
|
||||
IdentifierPath& name() const { return *m_modifierName; }
|
||||
// Returns nullptr if no argument list was given (``mod``).
|
||||
// If an argument list is given (``mod(...)``), the arguments are returned
|
||||
// as a vector of expressions. Note that this vector can be empty (``mod()``).
|
||||
std::vector<ASTPointer<Expression>> const* arguments() const { return m_arguments.get(); }
|
||||
|
||||
private:
|
||||
ASTPointer<Identifier> m_modifierName;
|
||||
ASTPointer<IdentifierPath> m_modifierName;
|
||||
std::unique_ptr<std::vector<ASTPointer<Expression>>> m_arguments;
|
||||
};
|
||||
|
||||
@@ -1225,15 +1225,15 @@ class UserDefinedTypeName: public TypeName
|
||||
{
|
||||
public:
|
||||
UserDefinedTypeName(int64_t _id, SourceLocation const& _location, ASTPointer<IdentifierPath> _namePath):
|
||||
TypeName(_id, _location), m_namePath(std::move(_namePath)) {}
|
||||
|
||||
TypeName(_id, _location), m_namePath(std::move(_namePath))
|
||||
{
|
||||
solAssert(m_namePath != nullptr, "Name cannot be null.");
|
||||
}
|
||||
void accept(ASTVisitor& _visitor) override;
|
||||
void accept(ASTConstVisitor& _visitor) const override;
|
||||
|
||||
std::vector<ASTString> const& namePath() const { return m_namePath->path(); }
|
||||
ASTPointer<IdentifierPath> const& pathNode() const { return m_namePath; }
|
||||
|
||||
UserDefinedTypeNameAnnotation& annotation() const override;
|
||||
IdentifierPath& pathNode() const { return *m_namePath; }
|
||||
|
||||
private:
|
||||
ASTPointer<IdentifierPath> m_namePath;
|
||||
|
||||
@@ -233,16 +233,12 @@ struct TypeNameAnnotation: ASTAnnotation
|
||||
TypePointer type = nullptr;
|
||||
};
|
||||
|
||||
struct IdentifierPathAnnotation: TypeNameAnnotation
|
||||
{
|
||||
/// Referenced declaration, set during reference resolution stage.
|
||||
Declaration const* referencedDeclaration = nullptr;
|
||||
};
|
||||
|
||||
struct UserDefinedTypeNameAnnotation: TypeNameAnnotation
|
||||
struct IdentifierPathAnnotation: ASTAnnotation
|
||||
{
|
||||
/// Referenced declaration, set during reference resolution stage.
|
||||
Declaration const* referencedDeclaration = nullptr;
|
||||
/// What kind of lookup needs to be done (static, virtual, super) find the declaration.
|
||||
SetOnce<VirtualLookup> requiredLookup;
|
||||
};
|
||||
|
||||
struct ExpressionAnnotation: ASTAnnotation
|
||||
|
||||
@@ -493,7 +493,7 @@ bool ASTJsonConverter::visit(ModifierDefinition const& _node)
|
||||
bool ASTJsonConverter::visit(ModifierInvocation const& _node)
|
||||
{
|
||||
setJsonNode(_node, "ModifierInvocation", {
|
||||
make_pair("modifierName", toJson(*_node.name())),
|
||||
make_pair("modifierName", toJson(_node.name())),
|
||||
make_pair("arguments", _node.arguments() ? toJson(*_node.arguments()) : Json::nullValue)
|
||||
});
|
||||
return false;
|
||||
@@ -528,8 +528,8 @@ bool ASTJsonConverter::visit(ElementaryTypeName const& _node)
|
||||
bool ASTJsonConverter::visit(UserDefinedTypeName const& _node)
|
||||
{
|
||||
setJsonNode(_node, "UserDefinedTypeName", {
|
||||
make_pair("pathNode", toJson(*_node.pathNode())),
|
||||
make_pair("referencedDeclaration", idOrNull(_node.annotation().referencedDeclaration)),
|
||||
make_pair("pathNode", toJson(_node.pathNode())),
|
||||
make_pair("referencedDeclaration", idOrNull(_node.pathNode().annotation().referencedDeclaration)),
|
||||
make_pair("typeDescriptions", typePointerToJson(_node.annotation().type, true))
|
||||
});
|
||||
return false;
|
||||
|
||||
@@ -116,7 +116,7 @@ ASTPointer<ASTNode> ASTJsonImporter::convertJsonToASTNode(Json::Value const& _js
|
||||
if (nodeType == "ContractDefinition")
|
||||
return createContractDefinition(_json);
|
||||
if (nodeType == "IdentifierPath")
|
||||
return createIdentifier(_json);
|
||||
return createIdentifierPath(_json);
|
||||
if (nodeType == "InheritanceSpecifier")
|
||||
return createInheritanceSpecifier(_json);
|
||||
if (nodeType == "UsingForDirective")
|
||||
@@ -309,12 +309,13 @@ ASTPointer<IdentifierPath> ASTJsonImporter::createIdentifierPath(Json::Value con
|
||||
vector<string> strs;
|
||||
string nameString = member(_node, "name").asString();
|
||||
boost::algorithm::split(strs, nameString, boost::is_any_of("."));
|
||||
astAssert(!strs.empty(), "Expected at least one element in IdentifierPath.");
|
||||
for (string s: strs)
|
||||
{
|
||||
astAssert(!s.empty(), "Expected non-empty string for IdentifierPath element.");
|
||||
namePath.emplace_back(s);
|
||||
return createASTNode<IdentifierPath>(
|
||||
_node,
|
||||
namePath
|
||||
);
|
||||
}
|
||||
return createASTNode<IdentifierPath>(_node, namePath);
|
||||
}
|
||||
|
||||
ASTPointer<InheritanceSpecifier> ASTJsonImporter::createInheritanceSpecifier(Json::Value const& _node)
|
||||
@@ -324,7 +325,7 @@ ASTPointer<InheritanceSpecifier> ASTJsonImporter::createInheritanceSpecifier(Jso
|
||||
arguments.push_back(convertJsonToASTNode<Expression>(arg));
|
||||
return createASTNode<InheritanceSpecifier>(
|
||||
_node,
|
||||
createUserDefinedTypeName(member(_node, "baseName")),
|
||||
createIdentifierPath(member(_node, "baseName")),
|
||||
member(_node, "arguments").isNull() ? nullptr : make_unique<std::vector<ASTPointer<Expression>>>(arguments)
|
||||
);
|
||||
}
|
||||
@@ -333,7 +334,7 @@ ASTPointer<UsingForDirective> ASTJsonImporter::createUsingForDirective(Json::Val
|
||||
{
|
||||
return createASTNode<UsingForDirective>(
|
||||
_node,
|
||||
createUserDefinedTypeName(member(_node, "libraryName")),
|
||||
createIdentifierPath(member(_node, "libraryName")),
|
||||
_node["typeName"].isNull() ? nullptr : convertJsonToASTNode<TypeName>(_node["typeName"])
|
||||
);
|
||||
}
|
||||
@@ -383,10 +384,10 @@ ASTPointer<ParameterList> ASTJsonImporter::createParameterList(Json::Value const
|
||||
|
||||
ASTPointer<OverrideSpecifier> ASTJsonImporter::createOverrideSpecifier(Json::Value const& _node)
|
||||
{
|
||||
std::vector<ASTPointer<UserDefinedTypeName>> overrides;
|
||||
std::vector<ASTPointer<IdentifierPath>> overrides;
|
||||
|
||||
for (auto& param: _node["overrides"])
|
||||
overrides.push_back(createUserDefinedTypeName(param));
|
||||
overrides.push_back(createIdentifierPath(param));
|
||||
|
||||
return createASTNode<OverrideSpecifier>(
|
||||
_node,
|
||||
@@ -499,7 +500,7 @@ ASTPointer<ModifierInvocation> ASTJsonImporter::createModifierInvocation(Json::V
|
||||
arguments.push_back(convertJsonToASTNode<Expression>(arg));
|
||||
return createASTNode<ModifierInvocation>(
|
||||
_node,
|
||||
createIdentifier(member(_node, "modifierName")),
|
||||
createIdentifierPath(member(_node, "modifierName")),
|
||||
member(_node, "arguments").isNull() ? nullptr : make_unique<std::vector<ASTPointer<Expression>>>(arguments)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -381,14 +381,14 @@ void ElementaryTypeName::accept(ASTConstVisitor& _visitor) const
|
||||
void UserDefinedTypeName::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
this->pathNode()->accept(_visitor);
|
||||
this->pathNode().accept(_visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void UserDefinedTypeName::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
this->pathNode()->accept(_visitor);
|
||||
this->pathNode().accept(_visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
|
||||
@@ -1293,14 +1293,14 @@ void ContractCompiler::appendModifierOrFunctionCode()
|
||||
ASTPointer<ModifierInvocation> const& modifierInvocation = m_currentFunction->modifiers()[m_modifierDepth];
|
||||
|
||||
// constructor call should be excluded
|
||||
if (dynamic_cast<ContractDefinition const*>(modifierInvocation->name()->annotation().referencedDeclaration))
|
||||
if (dynamic_cast<ContractDefinition const*>(modifierInvocation->name().annotation().referencedDeclaration))
|
||||
appendModifierOrFunctionCode();
|
||||
else
|
||||
{
|
||||
solAssert(*modifierInvocation->name()->annotation().requiredLookup == VirtualLookup::Virtual, "");
|
||||
solAssert(*modifierInvocation->name().annotation().requiredLookup == VirtualLookup::Virtual, "");
|
||||
|
||||
ModifierDefinition const& modifier = dynamic_cast<ModifierDefinition const&>(
|
||||
*modifierInvocation->name()->annotation().referencedDeclaration
|
||||
*modifierInvocation->name().annotation().referencedDeclaration
|
||||
).resolveVirtual(m_context.mostDerivedContract());
|
||||
CompilerContext::LocationSetter locationSetter(m_context, modifier);
|
||||
std::vector<ASTPointer<Expression>> const& modifierArguments =
|
||||
|
||||
@@ -444,7 +444,7 @@ pair<string, map<ContractDefinition const*, vector<string>>> IRGenerator::evalua
|
||||
if (FunctionDefinition const* constructor = _contract.constructor())
|
||||
for (ASTPointer<ModifierInvocation> const& modifier: constructor->modifiers())
|
||||
if (auto const* baseContract = dynamic_cast<ContractDefinition const*>(
|
||||
modifier->name()->annotation().referencedDeclaration
|
||||
modifier->name().annotation().referencedDeclaration
|
||||
))
|
||||
if (
|
||||
FunctionDefinition const* baseConstructor = baseContract->constructor();
|
||||
|
||||
@@ -58,7 +58,7 @@ bool SMTEncoder::visit(ContractDefinition const& _contract)
|
||||
if (auto const& constructor = base->constructor())
|
||||
for (auto const& invocation: constructor->modifiers())
|
||||
{
|
||||
auto refDecl = invocation->name()->annotation().referencedDeclaration;
|
||||
auto refDecl = invocation->name().annotation().referencedDeclaration;
|
||||
if (auto const& baseContract = dynamic_cast<ContractDefinition const*>(refDecl))
|
||||
{
|
||||
solAssert(!m_baseConstructorCalls.count(baseContract), "");
|
||||
@@ -164,7 +164,7 @@ void SMTEncoder::visitFunctionOrModifier()
|
||||
ASTPointer<ModifierInvocation> const& modifierInvocation =
|
||||
function.modifiers()[static_cast<size_t>(m_modifierDepthStack.back())];
|
||||
solAssert(modifierInvocation, "");
|
||||
auto refDecl = modifierInvocation->name()->annotation().referencedDeclaration;
|
||||
auto refDecl = modifierInvocation->name().annotation().referencedDeclaration;
|
||||
if (dynamic_cast<ContractDefinition const*>(refDecl))
|
||||
visitFunctionOrModifier();
|
||||
else if (auto modifierDef = dynamic_cast<ModifierDefinition const*>(refDecl))
|
||||
|
||||
@@ -83,7 +83,7 @@ void VariableUsage::endVisit(FunctionDefinition const&)
|
||||
|
||||
void VariableUsage::endVisit(ModifierInvocation const& _modifierInv)
|
||||
{
|
||||
auto const& modifierDef = dynamic_cast<ModifierDefinition const*>(_modifierInv.name()->annotation().referencedDeclaration);
|
||||
auto const& modifierDef = dynamic_cast<ModifierDefinition const*>(_modifierInv.name().annotation().referencedDeclaration);
|
||||
if (modifierDef)
|
||||
modifierDef->accept(*this);
|
||||
}
|
||||
|
||||
@@ -389,7 +389,7 @@ ASTPointer<InheritanceSpecifier> Parser::parseInheritanceSpecifier()
|
||||
{
|
||||
RecursionGuard recursionGuard(*this);
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
ASTPointer<UserDefinedTypeName> name(parseUserDefinedTypeName());
|
||||
ASTPointer<IdentifierPath> name(parseIdentifierPath());
|
||||
unique_ptr<vector<ASTPointer<Expression>>> arguments;
|
||||
if (m_scanner->currentToken() == Token::LParen)
|
||||
{
|
||||
@@ -433,7 +433,7 @@ ASTPointer<OverrideSpecifier> Parser::parseOverrideSpecifier()
|
||||
solAssert(m_scanner->currentToken() == Token::Override, "");
|
||||
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
std::vector<ASTPointer<UserDefinedTypeName>> overrides;
|
||||
std::vector<ASTPointer<IdentifierPath>> overrides;
|
||||
|
||||
nodeFactory.markEndPosition();
|
||||
m_scanner->next();
|
||||
@@ -443,7 +443,7 @@ ASTPointer<OverrideSpecifier> Parser::parseOverrideSpecifier()
|
||||
m_scanner->next();
|
||||
while (true)
|
||||
{
|
||||
overrides.push_back(parseUserDefinedTypeName());
|
||||
overrides.push_back(parseIdentifierPath());
|
||||
|
||||
if (m_scanner->currentToken() == Token::RParen)
|
||||
break;
|
||||
@@ -900,7 +900,7 @@ ASTPointer<UsingForDirective> Parser::parseUsingDirective()
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
|
||||
expectToken(Token::Using);
|
||||
ASTPointer<UserDefinedTypeName> library(parseUserDefinedTypeName());
|
||||
ASTPointer<IdentifierPath> library(parseIdentifierPath());
|
||||
ASTPointer<TypeName> typeName;
|
||||
expectToken(Token::For);
|
||||
if (m_scanner->currentToken() == Token::Mul)
|
||||
@@ -916,7 +916,7 @@ ASTPointer<ModifierInvocation> Parser::parseModifierInvocation()
|
||||
{
|
||||
RecursionGuard recursionGuard(*this);
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
ASTPointer<Identifier> name(parseIdentifier());
|
||||
ASTPointer<IdentifierPath> name(parseIdentifierPath());
|
||||
unique_ptr<vector<ASTPointer<Expression>>> arguments;
|
||||
if (m_scanner->currentToken() == Token::LParen)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user