From c4334489520cc70b176c0ce5702f9a5d2a2f0e7d Mon Sep 17 00:00:00 2001 From: ProgramSnail Date: Tue, 16 May 2023 12:43:55 +0300 Subject: [PATCH] abstract types typecheck, fixes --- include/definitions.hpp | 10 ++++-- include/error_handling.hpp | 13 +++++++ include/global_info.hpp | 25 +++++++++++++- include/link_symbols_visitor.hpp | 8 +++++ include/typeclass_graph.hpp | 44 ++++++++++++++---------- src/find_symbols_visitor.cpp | 14 ++++---- src/global_info.cpp | 58 ++++++++++++++------------------ src/link_symbols_visitor.cpp | 29 ++++++++++------ src/type_check_visitor.cpp | 36 ++++++++------------ 9 files changed, 143 insertions(+), 94 deletions(-) diff --git a/include/definitions.hpp b/include/definitions.hpp index 821d4f0..6445bc3 100644 --- a/include/definitions.hpp +++ b/include/definitions.hpp @@ -26,6 +26,8 @@ struct TypeUsage { struct Parameter { std::string type; std::vector typeclass_nodes; + + interpreter::tokens::AnyAnnotatedType* node = nullptr; }; struct AbstractType { @@ -82,15 +84,16 @@ struct Typeclass { interpreter::tokens::TypeclassDefinitionStatement* node; utils::IdType parent_namespace; + + utils::IdType graph_id_; // TODO: make safe?? }; struct Import { std::string module_name; - std::vector symbols; // size = 0 => all symbols imported + std::vector symbols; // size == 0 => all symbols imported }; struct Namespace { - std::unordered_map types; std::unordered_map functions; std::unordered_map constructors; @@ -103,7 +106,8 @@ struct Namespace { utils::ClassInternalsModifier modifier = utils::ClassInternalsModifier::Static; std::string type_name; - std::optional node; + // all nodes have same info + std::optional any_node; }; } // namespace info::definition diff --git a/include/error_handling.hpp b/include/error_handling.hpp index fa06cab..690cb72 100644 --- a/include/error_handling.hpp +++ b/include/error_handling.hpp @@ -55,4 +55,17 @@ inline void HandleRuntimeError(const std::string& message, exit(1); } +inline void HandleNamesError(const std::string& message, + const interpreter::tokens::BaseNode& node) { + std::cerr << "\x1b[1;31mNames Error:\x1b[0m " << message << " at "; + PrintPosition(std::cerr, node.start_position, node.end_position); + std::cerr << ".\n"; + exit(1); +} + +template +inline void DebugPrint(const T& value) { + std::cerr << "\x1b[1;33mDebug:\x1b[0m " << value << '\n'; +} + } // namespace error_handling diff --git a/include/global_info.hpp b/include/global_info.hpp index 2e2aae4..c0f5195 100644 --- a/include/global_info.hpp +++ b/include/global_info.hpp @@ -3,6 +3,7 @@ #include #include #include +#include // for clangd #include "definitions.hpp" @@ -12,7 +13,6 @@ namespace info { -// TODO: better test / executable partitions support (tree, etc.) // TODO: add classes / structs and functions module interface class GlobalInfo { friend class NamespaceVisitor; @@ -300,6 +300,29 @@ public: return &typeclass_graph_; } + // cache ?? + std::vector GetAnnotatedTypeTypeclasses(interpreter::tokens::AnnotatedType* node) { + std::unordered_set typeclasses; + + for (auto& typeclass : node->typeclasses) { + utils::IdType graph_id = typeclasses_[typeclass->typeclass_id_].graph_id_; + + std::vector dependencies = typeclass_graph_.GetTypeclassDependencies(graph_id); + for (auto& dependency : dependencies) { + typeclasses.insert(dependency); + } + + typeclasses.insert(graph_id); + } + + std::vector collected_typeclasses; + collected_typeclasses.reserve(typeclasses.size()); + for (auto& typeclass : typeclasses) { + collected_typeclasses.push_back(typeclass); + } + return collected_typeclasses; + } + std::optional AddTypeclassToGraph(utils::IdType typeclass); private: diff --git a/include/link_symbols_visitor.hpp b/include/link_symbols_visitor.hpp index 963796f..f54aa5d 100644 --- a/include/link_symbols_visitor.hpp +++ b/include/link_symbols_visitor.hpp @@ -3,6 +3,7 @@ #include // for clangd +#include "error_handling.hpp" #include "visitor.hpp" #include "global_info.hpp" @@ -14,6 +15,13 @@ public: explicit LinkSymbolsVisitor(info::GlobalInfo& global_info) : namespace_visitor_(global_info.CreateVisitor()) {} + void VisitSourceFile(SourceFile* source_file) override { + Visitor::Visit(source_file); + if (!namespace_visitor_.GetTypeclassGraph()->CalculateGraph()) { + error_handling::HandleInternalError("Can't calculate typeclass graph", "LinkSymbolsVisitor.VisitSourceFile"); + } + } + private: // Sources ----------------- diff --git a/include/typeclass_graph.hpp b/include/typeclass_graph.hpp index 2440d94..9ca4448 100644 --- a/include/typeclass_graph.hpp +++ b/include/typeclass_graph.hpp @@ -3,13 +3,11 @@ #include #include #include +#include // for clangd -#include "error_handling.hpp" -#include "global_info.hpp" #include "utils.hpp" #include "interpreter_tree.hpp" -#include "definitions.hpp" namespace info { @@ -21,23 +19,17 @@ public: std::optional definition; }; - struct ParametrizedTypeclass { - std::string typeclass; - // TODO: parameters - }; - struct TypeclassVertex { std::string name; interpreter::tokens::TypeclassDefinitionStatement* definition = nullptr; std::unordered_map functions; - std::vector dependencies; - // TODO: parameters + std::unordered_set dependencies; // TODO: parameters }; std::optional AddTypeclass( // move parameters ?? const std::string& name, interpreter::tokens::TypeclassDefinitionStatement* definition, - const std::vector& dependencies, + const std::vector& dependencies, // TODO: parameters const std::vector>>& function_declarations, const std::vector>& function_definitions) { for (auto& method : function_declarations) { @@ -52,7 +44,10 @@ public: TypeclassVertex& typeclass = typeclasses_.back(); typeclass.name = name; typeclass.definition = definition; - typeclass.dependencies = dependencies; + + for (auto& dependency : dependencies) { + typeclass.dependencies.insert(dependency); + } for (auto& method : function_declarations) { FunctionInfo function_info; @@ -84,6 +79,18 @@ public: return typeclasses_.at(id); } + // cache ?? + const std::vector GetTypeclassDependencies(utils::IdType id) { + std::vector dependencies; + + dependencies.reserve(typeclasses_.at(id).dependencies.size()); + for (auto& dependency : typeclasses_[id].dependencies) { + dependencies.push_back(name_to_typeclass_[dependency]); + } + + return dependencies; + } + bool IsCalculated() { return is_calculated_; } @@ -96,15 +103,15 @@ public: std::vector> edges(typeclasses_.size()); for (size_t i = 0; i < typeclasses_.size(); ++i) { - edges[i].resize(typeclasses_[i].dependencies.size()); - for (size_t j = 0; j < edges[i].size(); ++j) { - auto dependency_iter = name_to_typeclass_.find(typeclasses_[i].dependencies[j].typeclass); + edges[i].reserve(typeclasses_[i].dependencies.size()); + for (auto& dependency :typeclasses_[i].dependencies) { + auto dependency_iter = name_to_typeclass_.find(dependency); if (dependency_iter == name_to_typeclass_.end()) { return false; } - edges[i][j] = dependency_iter->second; + edges[i].push_back(dependency_iter->second); } } @@ -113,7 +120,7 @@ public: for (auto& id : sorted_verticles) { for (auto& dependency : typeclasses_[id].dependencies) { - for (auto& method : typeclasses_[name_to_typeclass_[dependency.typeclass]].functions) { + for (auto& method : typeclasses_[name_to_typeclass_[dependency]].functions) { auto function_iter = typeclasses_[id].functions.find(method.first); if (function_iter == typeclasses_[id].functions.end()) { typeclasses_[id].functions[method.first] = method.second; @@ -123,6 +130,9 @@ public: } } } + for (auto& inherited_dependency : typeclasses_[name_to_typeclass_[dependency]].dependencies) { + typeclasses_[id].dependencies.insert(inherited_dependency); + } } } diff --git a/src/find_symbols_visitor.cpp b/src/find_symbols_visitor.cpp index 3c5d000..d153976 100644 --- a/src/find_symbols_visitor.cpp +++ b/src/find_symbols_visitor.cpp @@ -1,6 +1,7 @@ #include // for clangd +#include "../include/error_handling.hpp" #include "../include/find_symbols_visitor.hpp" namespace interpreter { @@ -44,11 +45,6 @@ void FindSymbolsVisitor::Visit(AliasDefinitionStatement* node) { } void FindSymbolsVisitor::Visit(FunctionDeclaration* node) { - info::definition::Namespace* current_namespace = namespace_visitor_.GetCurrentNamespace(); - if (current_namespace->node.has_value() && current_namespace->node.value()->link_typeclass_id_.has_value()) { - error_handling::HandleTypecheckError("Can't declare typeclass methods not as requirements", node->base); - } - info::definition::FunctionDeclaration info; info.parameters.resize(node->parameters.size()); @@ -131,7 +127,7 @@ void FindSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) { auto definition = node->definition.get(); - std::string& type_name = definition->type.get()->type; + std::string& typeclass_name = definition->type.get()->type; info.parameters.resize(definition->parameters.size()); for (size_t i = 0; i < definition->parameters.size(); ++i) { @@ -141,7 +137,7 @@ void FindSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) { } for (size_t i = 0; i < node->requirements.size(); ++i) { - namespace_visitor_.AddEnterNamespace(type_name, node->requirements[i].first, std::nullopt, node->base); + namespace_visitor_.AddEnterNamespace(typeclass_name, node->requirements[i].first, std::nullopt, node->base); Visit(node->requirements[i].second.get()); namespace_visitor_.ExitNamespace(); } @@ -149,7 +145,7 @@ void FindSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) { info.node = node; info.parent_namespace = namespace_visitor_.GetCurrentNamespaceId(); - node->typeclass_id_ = namespace_visitor_.AddTypeclass(type_name, std::move(info), node->base); + node->typeclass_id_ = namespace_visitor_.AddTypeclass(typeclass_name, std::move(info), node->base); } void FindSymbolsVisitor::Visit(PartitionStatement* node) { @@ -168,6 +164,8 @@ void FindSymbolsVisitor::Visit(AnyAnnotatedType* node) { info.typeclass_nodes[i] = node->typeclasses[i].get(); } + info.node = node; + current_info_ = std::move(info); } diff --git a/src/global_info.cpp b/src/global_info.cpp index 17e902c..719b68c 100644 --- a/src/global_info.cpp +++ b/src/global_info.cpp @@ -22,7 +22,7 @@ void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name, std::optional node, const interpreter::tokens::BaseNode& base_node) { if (type::ToInternalType(name).has_value()) { - error_handling::HandleTypecheckError("Can't define basic type namespace", base_node); + error_handling::HandleNamesError("Can't define basic type namespace", base_node); } auto current_namespaces = ChooseNamespaces(modifier, namespace_stack_.back()); @@ -36,12 +36,16 @@ void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name, global_info_.namespaces_.emplace_back(); global_info_.namespaces_.back().modifier = modifier; - global_info_.namespaces_.back().node = node; } else { id = namespace_iter->second; } + definition::Namespace* namespace_info = &global_info_.namespaces_[id]; + if (!namespace_info->any_node.has_value()) { // ?? + namespace_info->any_node = node; + } + namespace_info->parent_namespace = namespace_stack_.back(); namespace_info->type_name = name; @@ -99,12 +103,12 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddFunctionDeclaration( } else { id = function_id_iter->second; if (global_info_.functions_[id].argument_count != function_declaration_info.argument_types.size()) { - error_handling::HandleTypecheckError("Function declaration: not same argument count in function definition and declaration", base_node); + error_handling::HandleNamesError("Function declaration: not same argument count in function definition and declaration", base_node); } } if (global_info_.functions_[id].declaration.has_value()) { - error_handling::HandleTypecheckError("Second function declaration", base_node); + error_handling::HandleNamesError("Second function declaration", base_node); } global_info_.functions_[id].declaration = std::move(function_declaration_info); @@ -126,12 +130,12 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddFunctionDefinition( } else { id = function_id_iter->second; if (global_info_.functions_[id].argument_count != function_definition_info.argument_names.size() + 1) { - error_handling::HandleTypecheckError("Function definition: not same argument count in function definition and declaration", base_node); + error_handling::HandleNamesError("Function definition: not same argument count in function definition and declaration", base_node); } } if (global_info_.functions_[id].definition.has_value()) { - error_handling::HandleTypecheckError("Second function definition", base_node); + error_handling::HandleNamesError("Second function definition", base_node); } global_info_.functions_[id].definition = std::move(function_definition_info); @@ -144,7 +148,7 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddType(const std::string& type, definition::Type&& type_info, const interpreter::tokens::BaseNode& base_node) { if (type::ToInternalType(type).has_value()) { - error_handling::HandleTypecheckError("Can't redefine basic type", base_node); + error_handling::HandleNamesError("Can't redefine basic type", base_node); } utils::IdType id = 0; @@ -156,8 +160,8 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddType(const std::string& type, global_info_.namespaces_[namespace_stack_.back()].types[type] = id; global_info_.types_.push_back(std::move(type_info)); } else { - error_handling::HandleTypecheckError("More then one type with the same name in namespace", base_node); - } // TODO: typecheck error?? + error_handling::HandleNamesError("More then one type with the same name in namespace", base_node); + } definition::Type& moved_type_info = global_info_.types_.back(); @@ -207,12 +211,11 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddAbstractType(const std::string& a definition::AbstractType&& abstract_type_info, const interpreter::tokens::BaseNode& base_node) { if (type::ToInternalType(abstract_type).has_value()) { - error_handling::HandleTypecheckError("Can't redefine basic type as abstract type", base_node); + error_handling::HandleNamesError("Can't redefine basic type as abstract type", base_node); } if (FindAbstractType(abstract_type).has_value()) { - error_handling::HandleTypecheckError("More then one abstract type with the same name in namespace", - base_node); + error_handling::HandleNamesError("More then one abstract type with the same name in namespace", base_node); } utils::IdType id = global_info_.abstract_types_.size(); @@ -227,23 +230,17 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddTypeclass(const std::string& type definition::Typeclass&& typeclass_info, const interpreter::tokens::BaseNode& base_node) { if (type::ToInternalType(typeclass).has_value()) { - error_handling::HandleTypecheckError("Can't redefine basic type as typeclass", base_node); + error_handling::HandleNamesError("Can't redefine basic type as typeclass", base_node); } if (FindTypeclass(typeclass).has_value()) { - error_handling::HandleTypecheckError("More then one typeclass with the same name in namespace", base_node); + error_handling::HandleNamesError("More then one typeclass with the same name", base_node); } utils::IdType id = global_info_.typeclasses_.size(); global_info_.name_to_typeclass_[typeclass] = id; global_info_.typeclasses_.push_back(std::move(typeclass_info)); - definition::Typeclass& moved_typeclass_info = global_info_.typeclasses_.back(); - - // global_info_.typeclass_graph_.AddTypeclassByNode(moved_typeclass_info.node); // TODO - error_handling::HandleInternalError("Typeclasses are not implemented properly yet", - "GlobalInfo.NamespaceVisitor.AddTypeclass"); - return id; } @@ -251,13 +248,13 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddConstructor(const std::string& co definition::Constructor&& constructor_info, const interpreter::tokens::BaseNode& base_node) { if (type::ToInternalType(constructor).has_value()) { - error_handling::HandleTypecheckError("Can't redefine basic type as constructor", base_node); + error_handling::HandleNamesError("Can't redefine basic type as constructor", base_node); } auto constructor_id_iter = global_info_.namespaces_[namespace_stack_.back()].constructors.find(constructor); if (constructor_id_iter != global_info_.namespaces_[namespace_stack_.back()].constructors.end()) { - error_handling::HandleTypecheckError("More then one constructor with the same name in namespace", base_node); + error_handling::HandleNamesError("More then one constructor with the same name in namespace", base_node); } utils::IdType id = global_info_.constructors_.size(); @@ -316,8 +313,6 @@ std::optional GlobalInfo::NamespaceVisitor::FindMethodId( const std::string& type, const std::string& name, utils::IsConstModifier modifier) { - // TODO: remove overhead - return GlobalInfo::NamespaceVisitor::FindSomething(path, [type, name, modifier, this] (utils::IdType current_namespace) -> std::optional { @@ -471,13 +466,12 @@ std::optional GlobalInfo::AddTypeclassToGraph(utils::IdType typec definition::Namespace* parent_namespace = &GetNamespaceInfo(typeclass_info->parent_namespace); std::string name = typeclass_info->node->definition->type->type; - std::vector dependencies; + std::vector dependencies; std::vector>> function_declarations; std::vector> function_definitions; for (auto& dependency_node : typeclass_info->node->definition->type->typeclasses) { - TypeclassGraph::ParametrizedTypeclass dependency; - dependency.typeclass = dependency_node->typeclass; + std::string dependency = dependency_node->typeclass; if (dependency_node->parameters.size() > 0) { error_handling::HandleInternalError("Paramtrized typeclass requirements are not implemented yet", "TypeclassGraph.AddTypeclassByNode"); @@ -494,23 +488,21 @@ std::optional GlobalInfo::AddTypeclassToGraph(utils::IdType typec } auto const_namespace_iter = parent_namespace->const_namespaces.find(name); - if (namespace_iter != parent_namespace->const_namespaces.end()) { - CollectFunctionInfo(namespace_iter->second, + if (const_namespace_iter != parent_namespace->const_namespaces.end()) { + CollectFunctionInfo(const_namespace_iter->second, utils::ClassInternalsModifier::Const, function_declarations, function_definitions); } auto var_namespace_iter = parent_namespace->var_namespaces.find(name); - if (namespace_iter != parent_namespace->var_namespaces.end()) { - CollectFunctionInfo(namespace_iter->second, + if (var_namespace_iter != parent_namespace->var_namespaces.end()) { + CollectFunctionInfo(var_namespace_iter->second, utils::ClassInternalsModifier::Var, function_declarations, function_definitions); } - // TODO - return typeclass_graph_.AddTypeclass(name, typeclass_info->node, dependencies, diff --git a/src/link_symbols_visitor.cpp b/src/link_symbols_visitor.cpp index 57c79fa..5c2bf26 100644 --- a/src/link_symbols_visitor.cpp +++ b/src/link_symbols_visitor.cpp @@ -15,12 +15,12 @@ void LinkSymbolsVisitor::Visit(Namespace* node) { std::optional maybe_type = namespace_visitor_.FindLocalTypeId(node->type); std::optional maybe_typeclass; - if (namespace_visitor_.GetCurrentPath().size() == 0) { + if (namespace_visitor_.IsInGlobalNamespace()) { maybe_typeclass = namespace_visitor_.FindTypeclassId(node->type); } if (maybe_type.has_value() && maybe_typeclass.has_value()) { - error_handling::HandleTypecheckError("Ambigious namespace name (typeclass or type)", node->base); + error_handling::HandleNamesError("Ambigious namespace name (typeclass or type)", node->base); } if (maybe_type.has_value()) { @@ -39,21 +39,26 @@ void LinkSymbolsVisitor::Visit(Namespace* node) { // Definitions ----------------- -// TODO: add to typeclass graph, etc. (+ check) void LinkSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) { Visitor::Visit(node->definition.get()); for (auto& function_requirement : node->requirements) { + namespace_visitor_.EnterNamespace(node->definition->type->type, function_requirement.first); Visitor::Visit(function_requirement.second.get()); + namespace_visitor_.ExitNamespace(); } - namespace_visitor_.GetGlobalInfo()->AddTypeclassToGraph(node->typeclass_id_); + auto maybe_graph_id = namespace_visitor_.GetGlobalInfo()->AddTypeclassToGraph(node->typeclass_id_); + if (!maybe_graph_id.has_value()) { + error_handling::HandleNamesError("Can't add typeclass to graph", node->base); + } + namespace_visitor_.GetGlobalInfo()->GetTypeclassInfo(node->typeclass_id_).graph_id_ = maybe_graph_id.value(); } // Type, typeclass, etc. ----------------- // Type -void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check +void LinkSymbolsVisitor::Visit(TypeExpression* node) { std::vector path; path.reserve(node->path.size()); @@ -67,11 +72,11 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check // internal type if (info::type::ToInternalType(node->type.type).has_value()) { if (!node->path.empty()) { - error_handling::HandleTypecheckError("Internal type is not in namespace", node->base); + error_handling::HandleNamesError("Internal type is not in namespace", node->base); } if (!node->type.parameters.empty()) { - error_handling::HandleTypecheckError("Can't parametrize internal type", node->base); + error_handling::HandleNamesError("Can't parametrize internal type", node->base); } return; } @@ -93,7 +98,7 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check utils::IdType constructor_type_id = namespace_visitor_.GetGlobalInfo()->GetConstructorInfo(node->constructor_id_.value()).type_id; if (node->type_id_.has_value() && node->type_id_.value() != constructor_type_id) { - error_handling::HandleTypecheckError("Contructor and type with same name have different types", node->base); + error_handling::HandleNamesError("Contructor and type with same name have different types", node->base); } node->type_id_ = constructor_type_id; @@ -122,13 +127,17 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check // Typeclass -void LinkSymbolsVisitor::Visit(ParametrizedTypeclass* node) { // TODO: check +void LinkSymbolsVisitor::Visit(ParametrizedTypeclass* node) { std::optional maybe_typeclass = namespace_visitor_.FindTypeclassId(node->typeclass); if (maybe_typeclass.has_value()) { node->typeclass_id_ = maybe_typeclass.value(); } else { - error_handling::HandleTypecheckError("Typeclass not found", node->base); + error_handling::HandleNamesError("Typeclass not found", node->base); + } + + if (node->parameters.size() > 0) { + error_handling::HandleNamesError("Parametrized typeclasses not implemented yet", node->base); } } diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index 323578e..0af9348 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -32,10 +32,12 @@ void TypeCheckVisitor::Visit(NamespaceSources* node) { node->base.type_ = current_type_; } -void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for class: const and var - if (node->link_typeclass_id_.has_value()) { // TODO: think about typeclass +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_; - std::vector requirements {node->link_typeclass_id_.value()}; + std::vector requirements = namespace_visitor_.GetTypeclassGraph()->GetTypeclassDependencies(graph_id); + requirements.push_back(graph_id); utils::IdType abstract_type = context_manager_.AddValue( info::type::AbstractType(utils::AbstractTypeModifier::Abstract, node->type, requirements), ClassInternalsModifierToValueType(node->modifier)); @@ -95,7 +97,6 @@ void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for c void TypeCheckVisitor::Visit(ImportStatement* node) {} // TODO -// + TODO: let bindings for abstract types void TypeCheckVisitor::Visit(AliasDefinitionStatement* node) { error_handling::HandleInternalError("Unimplemented", "TypeCheckVisitor.AliasDefinitionStatement"); @@ -128,12 +129,12 @@ void TypeCheckVisitor::Visit(FunctionDeclaration* node) { context_manager_.EnterContext(); for (auto& parameter : node->parameters) { // declaration correctness check // TODO: needed?? - std::vector requirements; - // TODO: + std::vector requirements = + namespace_visitor_.GetGlobalInfo()->GetAnnotatedTypeTypeclasses(parameter.get()); current_type_ = context_manager_.AddValue( info::type::AbstractType(utils::AbstractTypeModifier::Abstract, parameter->type, - requirements), // TODO: typeclasses-requirements + requirements), utils::ValueType::Tmp); context_manager_.DefineLocalType(parameter->type, current_type_); } @@ -161,15 +162,11 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) { info::definition::FunctionDeclaration& declaration = function_info.declaration.value(); for (auto parameter : declaration.parameters) { - std::vector requirements; - requirements.reserve(parameter.typeclass_nodes.size()); - for (ParametrizedTypeclass* typeclass : parameter.typeclass_nodes) { - requirements.push_back(typeclass->typeclass_id_); - } - // TODO: add recursive typeclasses from typeclass tree + std::vector requirements = + namespace_visitor_.GetGlobalInfo()->GetAnnotatedTypeTypeclasses(parameter.node); current_type_ = context_manager_.AddValue(info::type::AbstractType(utils::AbstractTypeModifier::Abstract, - parameter.type, - requirements), + parameter.type, + requirements), utils::ValueType::Tmp); if (!context_manager_.DefineLocalType(parameter.type, current_type_)) { error_handling::HandleTypecheckError("Can't define function parameter type: abstract type redefinition", node->base); @@ -210,13 +207,8 @@ void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) { void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) { is_in_statement_ = true; - std::vector requirements; - requirements.reserve(node->type->typeclasses.size()); - for (auto& typeclass : node->type->typeclasses) { - requirements.push_back(typeclass->typeclass_id_); - } - // TODO: add recursive typeclasses from typeclass tree - + std::vector requirements = + namespace_visitor_.GetGlobalInfo()->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_)) {