From 4960de7b42b6bbcd7389be358bbe27d789d3b92d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 19 Sep 2023 17:13:25 +0200 Subject: [PATCH] Move builtin type class registration to TypeClassRegistration --- .../analysis/TypeClassRegistration.cpp | 24 +++++++++++ .../analysis/TypeClassRegistration.h | 2 + .../experimental/analysis/TypeInference.cpp | 42 +++++-------------- .../experimental/analysis/TypeInference.h | 2 - .../codegen/IRGeneratorForStatements.cpp | 2 +- 5 files changed, 38 insertions(+), 34 deletions(-) diff --git a/libsolidity/experimental/analysis/TypeClassRegistration.cpp b/libsolidity/experimental/analysis/TypeClassRegistration.cpp index 10d3d6c3f..3dd41d922 100644 --- a/libsolidity/experimental/analysis/TypeClassRegistration.cpp +++ b/libsolidity/experimental/analysis/TypeClassRegistration.cpp @@ -32,6 +32,30 @@ TypeClassRegistration::TypeClassRegistration(Analysis& _analysis): m_errorReporter(_analysis.errorReporter()), m_typeSystem(_analysis.typeSystem()) { + auto declareBuiltinClass = [&](std::string _name, BuiltinClass _class) -> TypeClass { + Type type = m_typeSystem.freshTypeVariable({}); + auto result = m_typeSystem.declareTypeClass( + type, + _name, + nullptr + ); + if (auto error = std::get_if(&result)) + solAssert(!error, *error); + TypeClass declaredClass = std::get(result); + // TODO: validation? + GlobalAnnotation& annotation = m_analysis.annotation(); + solAssert(annotation.builtinClassesByName.emplace(_name, _class).second); + return annotation.builtinClasses.emplace(_class, declaredClass).first->second; + }; + + declareBuiltinClass("integer", BuiltinClass::Integer); + declareBuiltinClass("*", BuiltinClass::Mul); + declareBuiltinClass("+", BuiltinClass::Add); + declareBuiltinClass("==", BuiltinClass::Equal); + declareBuiltinClass("<", BuiltinClass::Less); + declareBuiltinClass("<=", BuiltinClass::LessOrEqual); + declareBuiltinClass(">", BuiltinClass::Greater); + declareBuiltinClass(">=", BuiltinClass::GreaterOrEqual); } bool TypeClassRegistration::analyze(SourceUnit const& _sourceUnit) diff --git a/libsolidity/experimental/analysis/TypeClassRegistration.h b/libsolidity/experimental/analysis/TypeClassRegistration.h index c0c1c3549..15923b78a 100644 --- a/libsolidity/experimental/analysis/TypeClassRegistration.h +++ b/libsolidity/experimental/analysis/TypeClassRegistration.h @@ -41,6 +41,8 @@ public: }; struct GlobalAnnotation { + std::map builtinClasses; + std::map builtinClassesByName; }; TypeClassRegistration(Analysis& _analysis); diff --git a/libsolidity/experimental/analysis/TypeInference.cpp b/libsolidity/experimental/analysis/TypeInference.cpp index e0265ab6f..97b09ea04 100644 --- a/libsolidity/experimental/analysis/TypeInference.cpp +++ b/libsolidity/experimental/analysis/TypeInference.cpp @@ -53,23 +53,8 @@ TypeInference::TypeInference(Analysis& _analysis): { TypeSystemHelpers helper{m_typeSystem}; - auto declareBuiltinClass = [&](std::string _name, BuiltinClass _class) -> TypeClass { - Type type = m_typeSystem.freshTypeVariable({}); - auto result = m_typeSystem.declareTypeClass( - type, - _name, - nullptr - ); - if (auto error = std::get_if(&result)) - solAssert(!error, *error); - TypeClass declaredClass = std::get(result); - // TODO: validation? - solAssert(annotation().builtinClassesByName.emplace(_name, _class).second); - return annotation().builtinClasses.emplace(_class, declaredClass).first->second; - }; - auto registeredTypeClass = [&](BuiltinClass _builtinClass) -> TypeClass { - return annotation().builtinClasses.at(_builtinClass); + return m_analysis.annotation().builtinClasses.at(_builtinClass); }; auto defineConversion = [&](BuiltinClass _builtinClass, PrimitiveType _fromType, std::string _functionName) { @@ -106,15 +91,6 @@ TypeInference::TypeInference(Analysis& _analysis): }}; }; - declareBuiltinClass("integer", BuiltinClass::Integer); - declareBuiltinClass("*", BuiltinClass::Mul); - declareBuiltinClass("+", BuiltinClass::Add); - declareBuiltinClass("==", BuiltinClass::Equal); - declareBuiltinClass("<", BuiltinClass::Less); - declareBuiltinClass("<=", BuiltinClass::LessOrEqual); - declareBuiltinClass(">", BuiltinClass::Greater); - declareBuiltinClass(">=", BuiltinClass::GreaterOrEqual); - defineConversion(BuiltinClass::Integer, PrimitiveType::Integer, "fromInteger"); defineBinaryMonoidalOperator(BuiltinClass::Mul, Token::Mul, "mul"); @@ -640,8 +616,10 @@ bool TypeInference::visit(TypeClassInstantiation const& _typeClassInstantiation) } }, [&](Token _token) -> std::optional { + auto const& classRegistrationAnnotation = m_analysis.annotation(); + if (auto builtinClass = builtinClassFromToken(_token)) - if (auto typeClass = util::valueOrNullptr(annotation().builtinClasses, *builtinClass)) + if (auto typeClass = util::valueOrNullptr(classRegistrationAnnotation.builtinClasses, *builtinClass)) return *typeClass; m_errorReporter.typeError(2658_error, _typeClassInstantiation.location(), "Invalid type class name."); return std::nullopt; @@ -1044,7 +1022,9 @@ bool TypeInference::visit(Literal const& _literal) m_errorReporter.typeError(2345_error, _literal.location(), "Only integers are supported."); return false; } - literalAnnotation.type = m_typeSystem.freshTypeVariable(Sort{{annotation().builtinClasses.at(BuiltinClass::Integer)}}); + + TypeClass integerClass = m_analysis.annotation().builtinClasses.at(BuiltinClass::Integer); + literalAnnotation.type = m_typeSystem.freshTypeVariable(Sort{{integerClass}}); return false; } @@ -1058,10 +1038,10 @@ TypeRegistration::TypeClassInstantiations const& typeClassInstantiations(Analysi if (typeClassDeclaration) return _analysis.annotation(*typeClassDeclaration).instantiations; // TODO: better mechanism than fetching by name. - auto const& annotation = _analysis.annotation(); - auto const& inferenceAnnotation = _analysis.annotation(); - return annotation.builtinClassInstantiations.at( - inferenceAnnotation.builtinClassesByName.at( + auto const& typeRegistrationAnnotation = _analysis.annotation(); + auto const& classRegistrationAnnotation = _analysis.annotation(); + return typeRegistrationAnnotation.builtinClassInstantiations.at( + classRegistrationAnnotation.builtinClassesByName.at( _analysis.typeSystem().typeClassName(_class) ) ); diff --git a/libsolidity/experimental/analysis/TypeInference.h b/libsolidity/experimental/analysis/TypeInference.h index eb1b03f69..7f873e11f 100644 --- a/libsolidity/experimental/analysis/TypeInference.h +++ b/libsolidity/experimental/analysis/TypeInference.h @@ -45,8 +45,6 @@ public: }; struct GlobalAnnotation { - std::map builtinClasses; - std::map builtinClassesByName; std::map> typeClassFunctions; std::map> operators; std::map> members; diff --git a/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp b/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp index 589fe6787..a579a8369 100644 --- a/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp +++ b/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp @@ -219,7 +219,7 @@ TypeRegistration::TypeClassInstantiations const& typeClassInstantiations(IRGener return _context.analysis.annotation(*typeClassDeclaration).instantiations; // TODO: better mechanism than fetching by name. auto& instantiations = _context.analysis.annotation().builtinClassInstantiations; - auto& builtinClassesByName = _context.analysis.annotation().builtinClassesByName; + auto& builtinClassesByName = _context.analysis.annotation().builtinClassesByName; return instantiations.at(builtinClassesByName.at(_context.analysis.typeSystem().typeClassName(_class))); } }