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_errorReporter(_analysis.errorReporter()),
|
||||||
m_typeSystem(_analysis.typeSystem())
|
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)
|
bool TypeClassRegistration::analyze(SourceUnit const& _sourceUnit)
|
||||||
|
@ -41,6 +41,8 @@ public:
|
|||||||
};
|
};
|
||||||
struct GlobalAnnotation
|
struct GlobalAnnotation
|
||||||
{
|
{
|
||||||
|
std::map<BuiltinClass, TypeClass> builtinClasses;
|
||||||
|
std::map<std::string, BuiltinClass> builtinClassesByName;
|
||||||
};
|
};
|
||||||
|
|
||||||
TypeClassRegistration(Analysis& _analysis);
|
TypeClassRegistration(Analysis& _analysis);
|
||||||
|
@ -53,23 +53,8 @@ TypeInference::TypeInference(Analysis& _analysis):
|
|||||||
{
|
{
|
||||||
TypeSystemHelpers helper{m_typeSystem};
|
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 {
|
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) {
|
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");
|
defineConversion(BuiltinClass::Integer, PrimitiveType::Integer, "fromInteger");
|
||||||
|
|
||||||
defineBinaryMonoidalOperator(BuiltinClass::Mul, Token::Mul, "mul");
|
defineBinaryMonoidalOperator(BuiltinClass::Mul, Token::Mul, "mul");
|
||||||
@ -640,8 +616,10 @@ bool TypeInference::visit(TypeClassInstantiation const& _typeClassInstantiation)
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
[&](Token _token) -> std::optional<TypeClass> {
|
[&](Token _token) -> std::optional<TypeClass> {
|
||||||
|
auto const& classRegistrationAnnotation = m_analysis.annotation<TypeClassRegistration>();
|
||||||
|
|
||||||
if (auto builtinClass = builtinClassFromToken(_token))
|
if (auto builtinClass = builtinClassFromToken(_token))
|
||||||
if (auto typeClass = util::valueOrNullptr(annotation().builtinClasses, *builtinClass))
|
if (auto typeClass = util::valueOrNullptr(classRegistrationAnnotation.builtinClasses, *builtinClass))
|
||||||
return *typeClass;
|
return *typeClass;
|
||||||
m_errorReporter.typeError(2658_error, _typeClassInstantiation.location(), "Invalid type class name.");
|
m_errorReporter.typeError(2658_error, _typeClassInstantiation.location(), "Invalid type class name.");
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
@ -1044,7 +1022,9 @@ bool TypeInference::visit(Literal const& _literal)
|
|||||||
m_errorReporter.typeError(2345_error, _literal.location(), "Only integers are supported.");
|
m_errorReporter.typeError(2345_error, _literal.location(), "Only integers are supported.");
|
||||||
return false;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1058,10 +1038,10 @@ TypeRegistration::TypeClassInstantiations const& typeClassInstantiations(Analysi
|
|||||||
if (typeClassDeclaration)
|
if (typeClassDeclaration)
|
||||||
return _analysis.annotation<TypeRegistration>(*typeClassDeclaration).instantiations;
|
return _analysis.annotation<TypeRegistration>(*typeClassDeclaration).instantiations;
|
||||||
// TODO: better mechanism than fetching by name.
|
// TODO: better mechanism than fetching by name.
|
||||||
auto const& annotation = _analysis.annotation<TypeRegistration>();
|
auto const& typeRegistrationAnnotation = _analysis.annotation<TypeRegistration>();
|
||||||
auto const& inferenceAnnotation = _analysis.annotation<TypeInference>();
|
auto const& classRegistrationAnnotation = _analysis.annotation<TypeClassRegistration>();
|
||||||
return annotation.builtinClassInstantiations.at(
|
return typeRegistrationAnnotation.builtinClassInstantiations.at(
|
||||||
inferenceAnnotation.builtinClassesByName.at(
|
classRegistrationAnnotation.builtinClassesByName.at(
|
||||||
_analysis.typeSystem().typeClassName(_class)
|
_analysis.typeSystem().typeClassName(_class)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -45,8 +45,6 @@ public:
|
|||||||
};
|
};
|
||||||
struct GlobalAnnotation
|
struct GlobalAnnotation
|
||||||
{
|
{
|
||||||
std::map<BuiltinClass, TypeClass> builtinClasses;
|
|
||||||
std::map<std::string, BuiltinClass> builtinClassesByName;
|
|
||||||
std::map<TypeClass, std::map<std::string, Type>> typeClassFunctions;
|
std::map<TypeClass, std::map<std::string, Type>> typeClassFunctions;
|
||||||
std::map<Token, std::tuple<TypeClass, std::string>> operators;
|
std::map<Token, std::tuple<TypeClass, std::string>> operators;
|
||||||
std::map<TypeConstructor, std::map<std::string, TypeMember>> members;
|
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;
|
return _context.analysis.annotation<TypeRegistration>(*typeClassDeclaration).instantiations;
|
||||||
// TODO: better mechanism than fetching by name.
|
// TODO: better mechanism than fetching by name.
|
||||||
auto& instantiations = _context.analysis.annotation<TypeRegistration>().builtinClassInstantiations;
|
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)));
|
return instantiations.at(builtinClassesByName.at(_context.analysis.typeSystem().typeClassName(_class)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user