diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index 0983da397..8fd482b73 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -69,9 +69,7 @@ ASTAnnotation& ASTNode::annotation() const SourceUnitAnnotation& SourceUnit::annotation() const { - if (!m_annotation) - m_annotation = make_unique(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } set SourceUnit::referencedSourceUnits(bool _recurse, set _skipList) const @@ -93,9 +91,7 @@ set SourceUnit::referencedSourceUnits(bool _recurse, set(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } TypePointer ImportDirective::type() const @@ -262,16 +258,12 @@ TypePointer ContractDefinition::type() const ContractDefinitionAnnotation& ContractDefinition::annotation() const { - if (!m_annotation) - m_annotation = make_unique(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } TypeNameAnnotation& TypeName::annotation() const { - if (!m_annotation) - m_annotation = make_unique(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } TypePointer StructDefinition::type() const @@ -281,9 +273,7 @@ TypePointer StructDefinition::type() const TypeDeclarationAnnotation& StructDefinition::annotation() const { - if (!m_annotation) - m_annotation = make_unique(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } TypePointer EnumValue::type() const @@ -300,9 +290,7 @@ TypePointer EnumDefinition::type() const TypeDeclarationAnnotation& EnumDefinition::annotation() const { - if (!m_annotation) - m_annotation = make_unique(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } ContractKind FunctionDefinition::inContractKind() const @@ -314,11 +302,7 @@ ContractKind FunctionDefinition::inContractKind() const CallableDeclarationAnnotation& CallableDeclaration::annotation() const { - solAssert( - m_annotation, - "CallableDeclarationAnnotation is an abstract base, need to call annotation on the concrete class first." - ); - return dynamic_cast(*m_annotation); + return abstractAnnotation("CallableDeclarationAnnotation"); } @@ -375,9 +359,7 @@ string FunctionDefinition::externalIdentifierHex() const FunctionDefinitionAnnotation& FunctionDefinition::annotation() const { - if (!m_annotation) - m_annotation = make_unique(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } TypePointer ModifierDefinition::type() const @@ -387,9 +369,7 @@ TypePointer ModifierDefinition::type() const ModifierDefinitionAnnotation& ModifierDefinition::annotation() const { - if (!m_annotation) - m_annotation = make_unique(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } TypePointer EventDefinition::type() const @@ -407,16 +387,12 @@ FunctionTypePointer EventDefinition::functionType(bool _internal) const EventDefinitionAnnotation& EventDefinition::annotation() const { - if (!m_annotation) - m_annotation = make_unique(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } UserDefinedTypeNameAnnotation& UserDefinedTypeName::annotation() const { - if (!m_annotation) - m_annotation = make_unique(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } SourceUnit const& Scopable::sourceUnit() const @@ -451,9 +427,7 @@ string Scopable::sourceUnitName() const DeclarationAnnotation& Declaration::annotation() const { - if (!m_annotation) - m_annotation = make_unique(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } bool VariableDeclaration::isLValue() const @@ -641,86 +615,62 @@ FunctionTypePointer VariableDeclaration::functionType(bool _internal) const VariableDeclarationAnnotation& VariableDeclaration::annotation() const { - if (!m_annotation) - m_annotation = make_unique(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } StatementAnnotation& Statement::annotation() const { - if (!m_annotation) - m_annotation = make_unique(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } InlineAssemblyAnnotation& InlineAssembly::annotation() const { - if (!m_annotation) - m_annotation = make_unique(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } BlockAnnotation& Block::annotation() const { - if (!m_annotation) - m_annotation = make_unique(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } TryCatchClauseAnnotation& TryCatchClause::annotation() const { - if (!m_annotation) - m_annotation = make_unique(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } ForStatementAnnotation& ForStatement::annotation() const { - if (!m_annotation) - m_annotation = make_unique(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } ReturnAnnotation& Return::annotation() const { - if (!m_annotation) - m_annotation = make_unique(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } ExpressionAnnotation& Expression::annotation() const { - if (!m_annotation) - m_annotation = make_unique(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } MemberAccessAnnotation& MemberAccess::annotation() const { - if (!m_annotation) - m_annotation = make_unique(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } BinaryOperationAnnotation& BinaryOperation::annotation() const { - if (!m_annotation) - m_annotation = make_unique(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } FunctionCallAnnotation& FunctionCall::annotation() const { - if (!m_annotation) - m_annotation = make_unique(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } IdentifierAnnotation& Identifier::annotation() const { - if (!m_annotation) - m_annotation = make_unique(); - return dynamic_cast(*m_annotation); + return initAnnotation(); } ASTString Literal::valueWithoutUnderscores() const diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 3ef066f8a..28a5cc76e 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -108,10 +108,29 @@ public: protected: size_t const m_id = 0; - /// Annotation - is specialised in derived classes, is created upon request (because of polymorphism). - mutable std::unique_ptr m_annotation; + + template + T& initAnnotation() const + { + if (!m_annotation) + m_annotation = std::make_unique(); + return dynamic_cast(*m_annotation); + } + + template + T& abstractAnnotation(std::string _className) const + { + solAssert( + m_annotation, + _className + " is an abstract base, need to call annotation on the concrete class first." + ); + + return dynamic_cast(*m_annotation); + } private: + /// Annotation - is specialised in derived classes, is created upon request (because of polymorphism). + mutable std::unique_ptr m_annotation; SourceLocation m_location; };