better class interloop

This commit is contained in:
ProgramSnail 2023-05-16 14:15:17 +03:00
parent c433448952
commit a1d9e6b190
4 changed files with 66 additions and 20 deletions

View file

@ -213,6 +213,45 @@ public:
return &global_info_.namespaces_[GetCurrentNamespaceId()];
}
std::optional<utils::IdType> GetCurrentNamespaceTypeId() {
if (!GetCurrentNamespace()->any_node.has_value()) {
return std::nullopt;
}
return GetCurrentNamespace()->any_node.value()->link_type_id_;
}
std::optional<definition::Type*> GetCurrentNamespaceAnyType() {
std::optional<utils::IdType> id = GetCurrentNamespaceTypeId();
if (!id.has_value()) {
return std::nullopt;
}
return &global_info_.GetAnyTypeInfo(id.value());
}
template<typename T>
std::optional<T*> GetCurrentNamespaceType() {
std::optional<utils::IdType> id = GetCurrentNamespaceTypeId();
if (!id.has_value()) {
return std::nullopt;
}
return global_info_.GetTypeInfo<T>(id.value());
}
std::optional<utils::IdType> GetCurrentNamespaceTypeclassId() {
if (!GetCurrentNamespace()->any_node.has_value()) {
return std::nullopt;
}
return GetCurrentNamespace()->any_node.value()->link_typeclass_id_;
}
std::optional<definition::Typeclass*> GetCurrentNamespaceTypeclass() {
std::optional<utils::IdType> id = GetCurrentNamespaceTypeclassId();
if (!id.has_value()) {
return std::nullopt;
}
return &global_info_.GetTypeclassInfo(id.value());
}
bool IsInGlobalNamespace() {
return namespace_stack_.size() == 1;
}

View file

@ -2,6 +2,7 @@
// for clangd
#include "interpreter_tree.hpp"
#include "typeclass_graph.hpp"
#include "types.hpp"
#include "contexts.hpp"
#include "utils.hpp"
@ -17,7 +18,10 @@ class TypeCheckVisitor : public Visitor {
public:
explicit TypeCheckVisitor(info::GlobalInfo& global_info,
info::ContextManager<info::type::Type, info::type::TypeManager>& context_manager)
: namespace_visitor_(global_info.CreateVisitor()), context_manager_(context_manager) {}
: namespace_visitor_(global_info.CreateVisitor()),
global_info_(global_info),
typeclass_graph_(*global_info.GetTypeclassGraph()),
context_manager_(context_manager) {}
private:
// Sources -----------------
@ -138,6 +142,8 @@ private:
private:
info::GlobalInfo::NamespaceVisitor namespace_visitor_;
info::GlobalInfo& global_info_;
info::TypeclassGraph& typeclass_graph_;
info::ContextManager<info::type::Type, info::type::TypeManager>& context_manager_;
std::unordered_set<utils::IdType> type_namespaces_;

Binary file not shown.

View file

@ -34,7 +34,7 @@ void TypeCheckVisitor::Visit(NamespaceSources* node) {
void TypeCheckVisitor::Visit(Namespace* node) {
if (node->link_typeclass_id_.has_value()) {
utils::IdType graph_id = namespace_visitor_.GetGlobalInfo()->GetTypeclassInfo(node->link_typeclass_id_.value()).graph_id_;
utils::IdType graph_id = global_info_.GetTypeclassInfo(node->link_typeclass_id_.value()).graph_id_;
std::vector<utils::IdType> requirements = namespace_visitor_.GetTypeclassGraph()->GetTypeclassDependencies(graph_id);
requirements.push_back(graph_id);
@ -51,7 +51,7 @@ void TypeCheckVisitor::Visit(Namespace* node) {
context_manager_.DefineLocalType(node->type, abstract_type);
} else if (node->link_type_id_.has_value()) {
if (node->modifier != utils::ClassInternalsModifier::Static) {
auto maybe_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo<info::definition::AnyType>(node->link_type_id_.value());
auto maybe_type_info = global_info_.GetTypeInfo<info::definition::AnyType>(node->link_type_id_.value());
if (!maybe_type_info.has_value()) {
error_handling::HandleTypecheckError("Namespace type is not AnyType", node->base);
@ -127,10 +127,11 @@ void TypeCheckVisitor::Visit(FunctionDeclaration* node) {
bool was_in_statement = is_in_statement_;
is_in_statement_ = true;
context_manager_.EnterContext();
for (auto& parameter : node->parameters) { // declaration correctness check // TODO: needed??
std::vector<utils::IdType> requirements =
namespace_visitor_.GetGlobalInfo()->GetAnnotatedTypeTypeclasses(parameter.get());
global_info_.GetAnnotatedTypeTypeclasses(parameter.get());
current_type_ = context_manager_.AddValue(
info::type::AbstractType(utils::AbstractTypeModifier::Abstract,
parameter->type,
@ -153,7 +154,7 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) {
is_in_statement_ = true;
context_manager_.EnterContext();
info::definition::Function& function_info = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(node->function_id_);
info::definition::Function& function_info = global_info_.GetFunctionInfo(node->function_id_);
if (!function_info.declaration.has_value()) {
error_handling::HandleTypecheckError("Function defined, but not declared", node->base);
@ -163,7 +164,7 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) {
for (auto parameter : declaration.parameters) {
std::vector<utils::IdType> requirements =
namespace_visitor_.GetGlobalInfo()->GetAnnotatedTypeTypeclasses(parameter.node);
global_info_.GetAnnotatedTypeTypeclasses(parameter.node);
current_type_ = context_manager_.AddValue(info::type::AbstractType(utils::AbstractTypeModifier::Abstract,
parameter.type,
requirements),
@ -208,7 +209,7 @@ void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) {
is_in_statement_ = true;
std::vector<utils::IdType> requirements =
namespace_visitor_.GetGlobalInfo()->GetAnnotatedTypeTypeclasses(node->type.get());
global_info_.GetAnnotatedTypeTypeclasses(node->type.get());
current_type_ = context_manager_.AddValue(info::type::AbstractType(node->modifier, node->type->type, requirements),
utils::ValueType::Tmp);
if (!context_manager_.DefineLocalType(node->type->type, current_type_)) {
@ -279,7 +280,7 @@ void TypeCheckVisitor::Visit(TypeConstructorPattern* node) { // TODO: match name
utils::IdType constructor_id = node->constructor->constructor_id_.value();
info::definition::Constructor constructor_info = namespace_visitor_.GetGlobalInfo()->GetConstructorInfo(constructor_id);
info::definition::Constructor constructor_info = global_info_.GetConstructorInfo(constructor_id);
utils::IdType type_id = constructor_info.type_id;
@ -288,7 +289,7 @@ void TypeCheckVisitor::Visit(TypeConstructorPattern* node) { // TODO: match name
// TODO: handle alias types
std::optional<info::definition::AnyType*> maybe_type_info =
namespace_visitor_.GetGlobalInfo()->GetTypeInfo<info::definition::AnyType>(type_id);
global_info_.GetTypeInfo<info::definition::AnyType>(type_id);
if (!maybe_type_info.has_value()) { // TODO
error_handling::HandleInternalError("Implemented only for AnyType",
@ -597,7 +598,7 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
node->is_method_ = false;
if (maybe_operator_id.has_value()) {
operator_info = &namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value());
operator_info = &global_info_.GetFunctionInfo(maybe_operator_id.value());
node->is_method_ = false;
} else {
Visitor::Visit(node->left_expression);
@ -609,7 +610,7 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
error_handling::HandleTypecheckError("Operator not found (type is not DefinedType)", node->base);
}
auto maybe_left_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo<info::definition::AnyType>(maybe_left_type.value()->GetTypeId());
auto maybe_left_type_info = global_info_.GetTypeInfo<info::definition::AnyType>(maybe_left_type.value()->GetTypeId());
std::string left_type_name = maybe_left_type_info.value()->type.type;
@ -637,7 +638,7 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
maybe_operator_id = maybe_const_operator_id;
}
operator_info = &namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value());
operator_info = &global_info_.GetFunctionInfo(maybe_operator_id.value());
node->is_method_ = true;
}
@ -743,7 +744,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
utils::IdType type_id = maybe_expression_type.value()->GetTypeId();
std::optional<info::definition::AnyType*> maybe_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo<info::definition::AnyType>(type_id);
std::optional<info::definition::AnyType*> maybe_type_info = global_info_.GetTypeInfo<info::definition::AnyType>(type_id);
if (!maybe_type_info.has_value()) {
error_handling::HandleInternalError("Functions/Methods implemented only for AnyType",
@ -751,7 +752,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
}
// TODO: better decision ??
std::optional<utils::IdType> maybe_const_function_id = namespace_visitor_.GetGlobalInfo()->GetNamespaceInfo(namespace_visitor_.GetGlobalInfo()->GetNamespaceInfo(maybe_type_info.value()->parent_namespace).const_namespaces.at(maybe_type_info.value()->type.type)).functions[node->name];
std::optional<utils::IdType> maybe_const_function_id = global_info_.GetNamespaceInfo(global_info_.GetNamespaceInfo(maybe_type_info.value()->parent_namespace).const_namespaces.at(maybe_type_info.value()->type.type)).functions[node->name];
utils::ValueType expression_value_type = context_manager_.GetValueType(current_type_);
@ -762,7 +763,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
if (expression_value_type == utils::ValueType::Var || expression_value_type == utils::ValueType::Tmp) {
// TODO: choose expression value types
maybe_function_id = namespace_visitor_.GetGlobalInfo()->GetNamespaceInfo(namespace_visitor_.GetGlobalInfo()->GetNamespaceInfo(maybe_type_info.value()->parent_namespace).var_namespaces.at(maybe_type_info.value()->type.type)).functions[node->name];
maybe_function_id = global_info_.GetNamespaceInfo(global_info_.GetNamespaceInfo(maybe_type_info.value()->parent_namespace).var_namespaces.at(maybe_type_info.value()->type.type)).functions[node->name];
}
if (maybe_const_function_id.has_value() && maybe_function_id.has_value()) { // TODO: handle on link_types stage
@ -802,7 +803,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
}
std::optional<info::definition::FunctionDeclaration> maybe_function_declaration =
namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_function_id.value()).declaration;
global_info_.GetFunctionInfo(maybe_function_id.value()).declaration;
if (!maybe_function_declaration.has_value()) {
error_handling::HandleTypecheckError("No function declaration found for function in function call expression", node->base);
}
@ -904,7 +905,7 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) {
utils::IdType constructor_id = node->constructor->constructor_id_.value();
info::definition::Constructor constructor_info = namespace_visitor_.GetGlobalInfo()->GetConstructorInfo(constructor_id);
info::definition::Constructor constructor_info = global_info_.GetConstructorInfo(constructor_id);
utils::IdType type_id = constructor_info.type_id;
@ -913,7 +914,7 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) {
// TODO: handle alias types
std::optional<info::definition::AnyType*> maybe_type_info =
namespace_visitor_.GetGlobalInfo()->GetTypeInfo<info::definition::AnyType>(type_id);
global_info_.GetTypeInfo<info::definition::AnyType>(type_id);
if (!maybe_type_info.has_value()) { // TODO
error_handling::HandleInternalError("Implemented only for AnyType", "TypeCheckVisitor.TypeConstructor");
@ -1254,7 +1255,7 @@ void TypeCheckVisitor::Visit(TypeExpression* node) {
} else if (node->type.type_id_.has_value()) { // TODO: chack that names are different (always true ??)
std::optional<info::definition::AnyType*> maybe_type_info =
namespace_visitor_.GetGlobalInfo()->GetTypeInfo<info::definition::AnyType>(node->type.type_id_.value());
global_info_.GetTypeInfo<info::definition::AnyType>(node->type.type_id_.value());
if (!maybe_type_info.has_value()) { // TODO: add alias, abstract, ... types
error_handling::HandleInternalError("No AnyType found", "TypeCheckVisitor.TypeExpression");
@ -1352,7 +1353,7 @@ void TypeCheckVisitor::CollectTypeContext(const ParametrizedType& type,
}
std::optional<info::definition::AnyType*> maybe_type_info =
namespace_visitor_.GetGlobalInfo()->GetTypeInfo<info::definition::AnyType>(type.type_id_.value());
global_info_.GetTypeInfo<info::definition::AnyType>(type.type_id_.value());
if (!maybe_type_info.has_value()) {
error_handling::HandleInternalError("Wrong type id", "TypeCheckVisitor.CollectTypeContext");