mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Move builtin type class registration to TypeClassRegistration
This commit is contained in:
parent
201259d50b
commit
4960de7b42
@ -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<std::string>(&result))
|
||||
solAssert(!error, *error);
|
||||
TypeClass declaredClass = std::get<TypeClass>(result);
|
||||
// TODO: validation?
|
||||
GlobalAnnotation& annotation = m_analysis.annotation<TypeClassRegistration>();
|
||||
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)
|
||||
|
@ -41,6 +41,8 @@ public:
|
||||
};
|
||||
struct GlobalAnnotation
|
||||
{
|
||||
std::map<BuiltinClass, TypeClass> builtinClasses;
|
||||
std::map<std::string, BuiltinClass> builtinClassesByName;
|
||||
};
|
||||
|
||||
TypeClassRegistration(Analysis& _analysis);
|
||||
|
@ -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<std::string>(&result))
|
||||
solAssert(!error, *error);
|
||||
TypeClass declaredClass = std::get<TypeClass>(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<TypeClassRegistration>().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<TypeClass> {
|
||||
auto const& classRegistrationAnnotation = m_analysis.annotation<TypeClassRegistration>();
|
||||
|
||||
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<TypeClassRegistration>().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<TypeRegistration>(*typeClassDeclaration).instantiations;
|
||||
// TODO: better mechanism than fetching by name.
|
||||
auto const& annotation = _analysis.annotation<TypeRegistration>();
|
||||
auto const& inferenceAnnotation = _analysis.annotation<TypeInference>();
|
||||
return annotation.builtinClassInstantiations.at(
|
||||
inferenceAnnotation.builtinClassesByName.at(
|
||||
auto const& typeRegistrationAnnotation = _analysis.annotation<TypeRegistration>();
|
||||
auto const& classRegistrationAnnotation = _analysis.annotation<TypeClassRegistration>();
|
||||
return typeRegistrationAnnotation.builtinClassInstantiations.at(
|
||||
classRegistrationAnnotation.builtinClassesByName.at(
|
||||
_analysis.typeSystem().typeClassName(_class)
|
||||
)
|
||||
);
|
||||
|
@ -45,8 +45,6 @@ public:
|
||||
};
|
||||
struct GlobalAnnotation
|
||||
{
|
||||
std::map<BuiltinClass, TypeClass> builtinClasses;
|
||||
std::map<std::string, BuiltinClass> builtinClassesByName;
|
||||
std::map<TypeClass, std::map<std::string, Type>> typeClassFunctions;
|
||||
std::map<Token, std::tuple<TypeClass, std::string>> operators;
|
||||
std::map<TypeConstructor, std::map<std::string, TypeMember>> members;
|
||||
|
@ -219,7 +219,7 @@ TypeRegistration::TypeClassInstantiations const& typeClassInstantiations(IRGener
|
||||
return _context.analysis.annotation<TypeRegistration>(*typeClassDeclaration).instantiations;
|
||||
// TODO: better mechanism than fetching by name.
|
||||
auto& instantiations = _context.analysis.annotation<TypeRegistration>().builtinClassInstantiations;
|
||||
auto& builtinClassesByName = _context.analysis.annotation<TypeInference>().builtinClassesByName;
|
||||
auto& builtinClassesByName = _context.analysis.annotation<TypeClassRegistration>().builtinClassesByName;
|
||||
return instantiations.at(builtinClassesByName.at(_context.analysis.typeSystem().typeClassName(_class)));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user