| 42 | using namespace solidity::langutil; |
| 43 | |
| 44 | TypeInference::TypeInference(Analysis& _analysis): |
| 45 | m_analysis(_analysis), |
| 46 | m_errorReporter(_analysis.errorReporter()), |
| 47 | m_typeSystem(_analysis.typeSystem()), |
| 48 | m_env(&m_typeSystem.env()), |
| 49 | m_voidType(m_typeSystem.type(PrimitiveType::Void, {})), |
| 50 | m_wordType(m_typeSystem.type(PrimitiveType::Word, {})), |
| 51 | m_integerType(m_typeSystem.type(PrimitiveType::Integer, {})), |
| 52 | m_unitType(m_typeSystem.type(PrimitiveType::Unit, {})), |
| 53 | m_boolType(m_typeSystem.type(PrimitiveType::Bool, {})) |
| 54 | { |
| 55 | TypeSystemHelpers helper{m_typeSystem}; |
| 56 | |
| 57 | auto declareBuiltinClass = [&](std::string _name, BuiltinClass _class) -> TypeClass { |
| 58 | auto result = m_typeSystem.declareTypeClass(_name, nullptr); |
| 59 | if (auto error = std::get_if<std::string>(&result)) |
| 60 | solAssert(!error, *error); |
| 61 | TypeClass declaredClass = std::get<TypeClass>(result); |
| 62 | // TODO: validation? |
| 63 | solAssert(annotation().builtinClassesByName.emplace(_name, _class).second); |
| 64 | return annotation().builtinClasses.emplace(_class, declaredClass).first->second; |
| 65 | }; |
| 66 | |
| 67 | auto registeredTypeClass = [&](BuiltinClass _builtinClass) -> TypeClass { |
| 68 | return annotation().builtinClasses.at(_builtinClass); |
| 69 | }; |
| 70 | |
| 71 | auto defineConversion = [&](BuiltinClass _builtinClass, PrimitiveType _fromType, std::string _functionName) { |
| 72 | annotation().typeClassFunctions[registeredTypeClass(_builtinClass)] = {{ |
| 73 | std::move(_functionName), |
| 74 | helper.functionType( |
| 75 | m_typeSystem.type(_fromType, {}), |
| 76 | m_typeSystem.typeClassInfo(registeredTypeClass(_builtinClass)).typeVariable |
| 77 | ), |
| 78 | }}; |
| 79 | }; |
| 80 | |
| 81 | auto defineBinaryMonoidalOperator = [&](BuiltinClass _builtinClass, Token _token, std::string _functionName) { |
| 82 | Type typeVar = m_typeSystem.typeClassInfo(registeredTypeClass(_builtinClass)).typeVariable; |
| 83 | annotation().operators.emplace(_token, std::make_tuple(registeredTypeClass(_builtinClass), _functionName)); |
| 84 | annotation().typeClassFunctions[registeredTypeClass(_builtinClass)] = {{ |
| 85 | std::move(_functionName), |
| 86 | helper.functionType( |
| 87 | helper.tupleType({typeVar, typeVar}), |
| 88 | typeVar |
| 89 | ) |
| 90 | }}; |
| 91 | }; |
| 92 | |
| 93 | auto defineBinaryCompareOperator = [&](BuiltinClass _builtinClass, Token _token, std::string _functionName) { |
| 94 | Type typeVar = m_typeSystem.typeClassInfo(registeredTypeClass(_builtinClass)).typeVariable; |
| 95 | annotation().operators.emplace(_token, std::make_tuple(registeredTypeClass(_builtinClass), _functionName)); |
| 96 | annotation().typeClassFunctions[registeredTypeClass(_builtinClass)] = {{ |
| 97 | std::move(_functionName), |
| 98 | helper.functionType( |
| 99 | helper.tupleType({typeVar, typeVar}), |
| 100 | m_typeSystem.type(PrimitiveType::Bool, {}) |
| 101 | ) |
nothing calls this directly
no test coverage detected