adding types to typeclass tree, part 1

This commit is contained in:
ProgramSnail 2023-05-19 11:55:46 +03:00
parent 17328b842c
commit d841e2754b
7 changed files with 260 additions and 167 deletions

View file

@ -350,19 +350,19 @@ public:
return &typeclass_graph_;
}
std::unordered_set<utils::IdType>
GetAnnotatedTypeTypeclassesSet(interpreter::tokens::AnnotatedType* node);
std::vector<utils::IdType>
GetAnnotatedTypeTypeclassesVector(interpreter::tokens::AnnotatedType* node);
std::unordered_map<std::string, TypeclassGraph::FunctionInfo>
GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node,
const interpreter::tokens::BaseNode& base_node);
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>>
GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node,
const interpreter::tokens::BaseNode& base_node);
// std::unordered_set<utils::IdType>
// GetAnnotatedTypeTypeclassesSet(interpreter::tokens::AnnotatedType* node);
//
// std::vector<utils::IdType>
// GetAnnotatedTypeTypeclassesVector(interpreter::tokens::AnnotatedType* node);
//
// std::unordered_map<std::string, TypeclassGraph::FunctionInfo>
// GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node,
// const interpreter::tokens::BaseNode& base_node);
//
// std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>>
// GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node,
// const interpreter::tokens::BaseNode& base_node);
std::unordered_map<std::string, utils::IdType>* ChooseNamespaces(
utils::ClassInternalsModifier modifier,
@ -370,6 +370,9 @@ public:
std::optional<utils::IdType> AddTypeclassToGraph(utils::IdType typeclass);
// function declarations & definitions should be added latter
std::optional<utils::IdType> AddAnnotatedTypeToGraph(interpreter::tokens::AnnotatedType* node);
private:
void CollectFunctionInfo(
utils::IdType current_namespace,

View file

@ -17,9 +17,7 @@ public:
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");
}
namespace_visitor_.GetTypeclassGraph()->CalculateGraph();
}
private:
@ -39,7 +37,7 @@ private:
// // void Visit(VariableDefinitionStatement* node) override;
// // void Visit(FunctionDeclaration* node) override;
// // void Visit(FunctionDefinitionStatement* node) override;
// // void Visit(TypeDefinitionStatement* node) override;
void Visit(TypeDefinitionStatement* node) override;
// // void Visit(AbstractTypeDefinitionStatement* node) override;
void Visit(TypeclassDefinitionStatement* node) override;
// // void Visit(PartitionStatement* node) override;

View file

@ -12,57 +12,77 @@
namespace info {
// move constructor parameters ??
class TypeclassGraph {
public:
enum class Modifier {
Typeclass = 0,
Type = 1,
};
struct FunctionInfo {
utils::ClassInternalsModifier modifier = utils::ClassInternalsModifier::Static;
interpreter::tokens::FunctionDeclaration* declaration = nullptr;
std::optional<interpreter::tokens::FunctionDefinitionStatement*> definition;
bool is_defined_in_owner = false;
};
struct TypeclassVertex {
struct Vertex { // make constructor ??
std::string name;
interpreter::tokens::TypeclassDefinitionStatement* definition = nullptr;
std::unordered_map<std::string, FunctionInfo> functions;
std::unordered_set<std::string> dependencies; // TODO: parameters
interpreter::tokens::BaseNode* base_node; // for error handling
Modifier modifier;
};
std::optional<utils::IdType> AddTypeclass( // move parameters ??
utils::IdType AddVertex(
const std::string& name,
interpreter::tokens::TypeclassDefinitionStatement* definition,
const std::vector<std::string>& dependencies, // TODO: parameters
const std::vector<std::string>& dependencies,
const std::vector<std::pair<std::string, std::pair<utils::ClassInternalsModifier, interpreter::tokens::FunctionDeclaration*>>>& function_declarations,
const std::vector<std::pair<std::string, interpreter::tokens::FunctionDefinitionStatement*>>& function_definitions);
const std::vector<std::pair<std::string, interpreter::tokens::FunctionDefinitionStatement*>>& function_definitions,
interpreter::tokens::BaseNode* base_node,
Modifier modifier);
std::optional<utils::IdType> FindFunctionTypeclass(const std::string& name);
bool IsFunctionInTypeclass(const std::string& name, utils::IdType typeclass_id) {
return typeclasses_[typeclass_id].functions.count(name) != 0;
bool IsFunctionInVertex(const std::string& name, utils::IdType vertex_id) {
return verticles_[vertex_id].functions.count(name) != 0;
}
// if vertex_id == std::nullopt, info can be not complete
std::optional<FunctionInfo*> GetFunctionInfo(const std::string& name,
std::optional<utils::IdType> typeclass_id);
std::optional<utils::IdType> vertex_id);
const TypeclassVertex& GetTypeclass(utils::IdType typeclass_id) { // check, if calculated ??
return typeclasses_.at(typeclass_id);
const Vertex& GetVertex(utils::IdType id) {
return verticles_.at(id);
}
std::optional<Vertex*> GetTypeVertex(utils::IdType id) {
if (verticles_.at(id).modifier == Modifier::Type) {
return &verticles_[id];
}
return std::nullopt;
}
// cache ??
std::vector<utils::IdType> GetTypeclassDependencies(utils::IdType id);
std::unordered_set<utils::IdType> GetDependenciesSet(utils::IdType id);
std::vector<utils::IdType> GetDependenciesVector(utils::IdType id);
// cache ??
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo*>> GetTypeclassFunctions(utils::IdType id);
const std::unordered_map<std::string, FunctionInfo>& GetVertexFunctions(utils::IdType id) {
return verticles_.at(id).functions;
}
bool IsCalculated() {
return is_calculated_;
}
bool CalculateGraph();
// can exit by typecheck error
void CalculateGraph();
private:
std::unordered_map<std::string, utils::IdType> method_to_typeclass_;
std::unordered_map<std::string, utils::IdType> method_to_vertex_;
std::unordered_map<std::string, utils::IdType> name_to_typeclass_;
std::vector<TypeclassVertex> typeclasses_;
std::vector<Vertex> verticles_;
bool is_calculated_ = true;
};

View file

@ -49,6 +49,8 @@ void FindSymbolsVisitor::Visit(AliasDefinitionStatement* node) {
info.type = std::move(alias_info);
node->type_id_ = namespace_visitor_.AddType(node->type, std::move(info), node->base);
Visitor::Visit(node->value.get()); // to visit all tree
}
void FindSymbolsVisitor::Visit(FunctionDeclaration* node) {
@ -69,6 +71,8 @@ void FindSymbolsVisitor::Visit(FunctionDeclaration* node) {
info.node = node;
node->function_id_ = namespace_visitor_.AddFunctionDeclaration(node->name, std::move(info), node->base);
Visitor::Visit(node->type.get()); // to visit all tree
}
void FindSymbolsVisitor::Visit(FunctionDefinitionStatement* node) {
@ -84,6 +88,9 @@ void FindSymbolsVisitor::Visit(FunctionDefinitionStatement* node) {
info.node = node;
node->function_id_ = namespace_visitor_.AddFunctionDefinition(definition->name, std::move(info), node->base);
Visitor::Visit(definition); // to visit all tree
Visitor::Visit(node->value); // to visit all tree
}
void FindSymbolsVisitor::Visit(TypeDefinitionStatement* node) {
@ -113,6 +120,9 @@ void FindSymbolsVisitor::Visit(TypeDefinitionStatement* node) {
info.type = std::move(any_type_info);
node->type_id_ = namespace_visitor_.AddType(type, std::move(info), node->base);
// definition visited earlier
Visitor::Visit(node->value); // to visit all tree
}
void FindSymbolsVisitor::Visit(AbstractTypeDefinitionStatement* node) {
@ -153,10 +163,14 @@ void FindSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
info.parent_namespace = namespace_visitor_.GetCurrentNamespaceId();
node->typeclass_id_ = namespace_visitor_.AddTypeclass(typeclass_name, std::move(info), node->base);
// no need to visit definition->type, because it is typeclass
}
void FindSymbolsVisitor::Visit(PartitionStatement* node) {
node->executable_id_ = namespace_visitor_.AddPartition(node->name.path, node, node->base);
Visitor::Visit(node->value); // to visit all tree
}
// Definition parts
@ -171,8 +185,19 @@ void FindSymbolsVisitor::Visit(AnyAnnotatedType* node) {
info.typeclass_nodes[i] = node->typeclasses[i].get();
}
for (auto& typeclass : node->typeclasses) {
Visitor::Visit(typeclass.get()); // to visit all tree
}
info.node = node;
auto maybe_graph_id = namespace_visitor_.GetGlobalInfo()->AddAnnotatedTypeToGraph(node); // definitions and declarations should be added latter
if (!maybe_graph_id.has_value()) {
error_handling::HandleInternalError("Can't add annotated type to typeclass graph",
"FindSymbolsVisitor.AnyAnnotatedType");
}
current_info_ = std::move(info);
}

View file

@ -460,79 +460,79 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindNamespaceIn(
//
// cache ??
std::unordered_set<utils::IdType>
GlobalInfo::GetAnnotatedTypeTypeclassesSet(interpreter::tokens::AnnotatedType* node) {
std::unordered_set<utils::IdType> typeclasses;
for (auto& typeclass : node->typeclasses) {
utils::IdType graph_id = typeclasses_[typeclass->typeclass_id_].graph_id_;
std::vector<utils::IdType> dependencies = typeclass_graph_.GetTypeclassDependencies(graph_id);
for (auto& dependency : dependencies) {
typeclasses.insert(dependency);
}
typeclasses.insert(graph_id);
}
return typeclasses;
}
std::vector<utils::IdType>
GlobalInfo::GetAnnotatedTypeTypeclassesVector(interpreter::tokens::AnnotatedType* node) {
std::unordered_set<utils::IdType> typeclasses_set = GetAnnotatedTypeTypeclassesSet(node);
std::vector<utils::IdType> typeclasses_vector;
typeclasses_vector.reserve(typeclasses_vector.size());
for (auto& typeclass : typeclasses_set) {
typeclasses_vector.push_back(typeclass);
}
return typeclasses_vector;
}
std::unordered_map<std::string, TypeclassGraph::FunctionInfo> // TODO: optimize, cache
GlobalInfo::GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node,
const interpreter::tokens::BaseNode& base_node) {
std::unordered_map<std::string, TypeclassGraph::FunctionInfo> functions;
for (auto& typeclass : node->typeclasses) {
utils::IdType graph_id = typeclasses_[typeclass->typeclass_id_].graph_id_;
auto requirements = typeclass_graph_.GetTypeclassFunctions(graph_id);
for (auto& requirement : requirements) {
auto requirement_iter = functions.find(requirement.first);
if (requirement_iter == functions.end()) {
functions[requirement.first] = *requirement.second;
} else {
if (requirement_iter->second.definition.has_value()) {
if (requirement.second->definition.has_value()) {
error_handling::HandleTypecheckError("Function defined more then in one type requirement", base_node);
}
} else {
requirement_iter->second.definition = requirement.second->definition;
}
}
}
}
return functions;
}
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>> // TODO: optimize, cache
GlobalInfo::GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node,
const interpreter::tokens::BaseNode& base_node) {
auto functions_set = GetAnnotatedTypeFunctionsMap(node, base_node);
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>> functions_vector;
functions_vector.reserve(functions_vector.size());
for (auto& typeclass : functions_set) {
functions_vector.push_back(typeclass);
}
return functions_vector;
}
// // cache ??
// std::unordered_set<utils::IdType>
// GlobalInfo::GetAnnotatedTypeTypeclassesSet(interpreter::tokens::AnnotatedType* node) {
//
// std::unordered_set<utils::IdType> typeclasses;
//
// for (auto& typeclass : node->typeclasses) {
// utils::IdType graph_id = typeclasses_[typeclass->typeclass_id_].graph_id_;
//
// std::vector<utils::IdType> dependencies = typeclass_graph_.GetTypeclassDependencies(graph_id);
// for (auto& dependency : dependencies) {
// typeclasses.insert(dependency);
// }
//
// typeclasses.insert(graph_id);
// }
// return typeclasses;
// }
//
// std::vector<utils::IdType>
// GlobalInfo::GetAnnotatedTypeTypeclassesVector(interpreter::tokens::AnnotatedType* node) {
//
// std::unordered_set<utils::IdType> typeclasses_set = GetAnnotatedTypeTypeclassesSet(node);
//
// std::vector<utils::IdType> typeclasses_vector;
// typeclasses_vector.reserve(typeclasses_vector.size());
// for (auto& typeclass : typeclasses_set) {
// typeclasses_vector.push_back(typeclass);
// }
// return typeclasses_vector;
// }
//
// std::unordered_map<std::string, TypeclassGraph::FunctionInfo> // TODO: optimize, cache
// GlobalInfo::GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node,
// const interpreter::tokens::BaseNode& base_node) {
//
// std::unordered_map<std::string, TypeclassGraph::FunctionInfo> functions;
//
// for (auto& typeclass : node->typeclasses) {
// utils::IdType graph_id = typeclasses_[typeclass->typeclass_id_].graph_id_;
//
// auto requirements = typeclass_graph_.GetTypeclassFunctions(graph_id);
// for (auto& requirement : requirements) {
// auto requirement_iter = functions.find(requirement.first);
// if (requirement_iter == functions.end()) {
// functions[requirement.first] = *requirement.second;
// } else {
// if (requirement_iter->second.definition.has_value()) {
// if (requirement.second->definition.has_value()) {
// error_handling::HandleTypecheckError("Function defined more then in one type requirement", base_node);
// }
// } else {
// requirement_iter->second.definition = requirement.second->definition;
// }
// }
// }
// }
// return functions;
// }
//
// std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>> // TODO: optimize, cache
// GlobalInfo::GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node,
// const interpreter::tokens::BaseNode& base_node) {
//
// auto functions_set = GetAnnotatedTypeFunctionsMap(node, base_node);
//
// std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>> functions_vector;
// functions_vector.reserve(functions_vector.size());
// for (auto& typeclass : functions_set) {
// functions_vector.push_back(typeclass);
// }
// return functions_vector;
// }
std::unordered_map<std::string, utils::IdType>*
GlobalInfo::ChooseNamespaces(utils::ClassInternalsModifier modifier,
@ -558,6 +558,7 @@ std::optional<utils::IdType> GlobalInfo::AddTypeclassToGraph(utils::IdType typec
definition::Namespace* parent_namespace = &GetNamespaceInfo(typeclass_info->parent_namespace);
std::string name = typeclass_info->node->definition->type->type;
interpreter::tokens::BaseNode* base_node = &typeclass_info->node->base;
std::vector<std::string> dependencies;
std::vector<std::pair<std::string, std::pair<utils::ClassInternalsModifier, interpreter::tokens::FunctionDeclaration*>>> function_declarations;
std::vector<std::pair<std::string, interpreter::tokens::FunctionDefinitionStatement*>> function_definitions;
@ -566,7 +567,7 @@ std::optional<utils::IdType> GlobalInfo::AddTypeclassToGraph(utils::IdType typec
std::string dependency = dependency_node->typeclass;
if (dependency_node->parameters.size() > 0) {
error_handling::HandleInternalError("Paramtrized typeclass requirements are not implemented yet",
"TypeclassGraph.AddTypeclassByNode");
"GlobalInfo.AddTypeclassToGraph");
}
dependencies.push_back(dependency);
}
@ -595,11 +596,34 @@ std::optional<utils::IdType> GlobalInfo::AddTypeclassToGraph(utils::IdType typec
function_definitions);
}
return typeclass_graph_.AddTypeclass(name,
typeclass_info->node,
return typeclass_graph_.AddVertex(name,
dependencies,
function_declarations,
function_definitions);
function_definitions,
base_node,
TypeclassGraph::Modifier::Typeclass);
}
std::optional<utils::IdType> GlobalInfo::AddAnnotatedTypeToGraph(interpreter::tokens::AnnotatedType* node) {
std::string name = node->type;
interpreter::tokens::BaseNode* base_node = &node->base;
std::vector<std::string> dependencies;
for (auto& dependency_node : node->typeclasses) {
std::string dependency = dependency_node->typeclass;
if (dependency_node->parameters.size() > 0) {
error_handling::HandleInternalError("Paramtrized typeclass requirements are not implemented yet",
"GlobalInfo.AddAnnotatedTypeToGraph");
}
dependencies.push_back(dependency);
}
return typeclass_graph_.AddVertex(name,
dependencies,
{},
{},
base_node,
TypeclassGraph::Modifier::Type);
}
void GlobalInfo::CollectFunctionInfo(

View file

@ -47,6 +47,13 @@ void LinkSymbolsVisitor::Visit(Namespace* node) {
// Definitions -----------------
void LinkSymbolsVisitor::Visit(TypeDefinitionStatement* node) {
Visitor::Visit(node->definition.get());
Visitor::Visit(node->value);
// TODO: add type declarations / definitions
}
void LinkSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
Visitor::Visit(node->definition.get());
for (auto& function_requirement : node->requirements) {

View file

@ -1,31 +1,41 @@
// for clangd
#include "../include/typeclass_graph.hpp"
#include "../include/error_handling.hpp"
namespace info {
std::optional<utils::IdType> TypeclassGraph::AddTypeclass(
utils::IdType TypeclassGraph::AddVertex(
const std::string& name,
interpreter::tokens::TypeclassDefinitionStatement* definition,
const std::vector<std::string>& dependencies, // TODO: parameters
const std::vector<std::pair<std::string, std::pair<utils::ClassInternalsModifier, interpreter::tokens::FunctionDeclaration*>>>& function_declarations,
const std::vector<std::pair<std::string, interpreter::tokens::FunctionDefinitionStatement*>>& function_definitions) {
const std::vector<std::pair<std::string, interpreter::tokens::FunctionDefinitionStatement*>>& function_definitions,
interpreter::tokens::BaseNode* base_node,
Modifier modifier) {
if (name_to_typeclass_.count(name) != 0) {
error_handling::HandleTypecheckError("Typeclass \"" + name + "\" already defined (other type / typeclass can't have this name)", *base_node);
}
if (modifier == Modifier::Typeclass) {
for (auto& method : function_declarations) {
if (method_to_typeclass_.count(method.first) != 0) {
return std::nullopt;
if (method_to_vertex_.count(method.first) != 0) {
error_handling::HandleTypecheckError("Typeclass \"" + name + "\" method \"" + method.first + "\" already declaret in another typeclass", *base_node);
}
}
}
is_calculated_ = false;
utils::IdType id = typeclasses_.size();
utils::IdType id = verticles_.size();
typeclasses_.emplace_back();
TypeclassVertex& typeclass = typeclasses_.back();
typeclass.name = name;
typeclass.definition = definition;
verticles_.emplace_back();
Vertex& vertex = verticles_.back();
vertex.name = name;
vertex.base_node = base_node;
vertex.modifier = modifier;
for (auto& dependency : dependencies) {
typeclass.dependencies.insert(dependency);
vertex.dependencies.insert(dependency);
}
for (auto& method : function_declarations) {
@ -33,31 +43,37 @@ std::optional<utils::IdType> TypeclassGraph::AddTypeclass(
function_info.modifier = method.second.first;
function_info.declaration = method.second.second;
typeclass.functions[method.first] = function_info;
vertex.functions[method.first] = function_info;
method_to_typeclass_[method.first] = id;
if (modifier == Modifier::Typeclass) {
method_to_vertex_[method.first] = id;
}
}
if (modifier == Modifier::Typeclass) {
name_to_typeclass_[name] = id;
}
for (auto& method : function_definitions) {
typeclass.functions[method.first].definition = method.second;
FunctionInfo& function_info = vertex.functions[method.first];
function_info.definition = method.second;
function_info.is_defined_in_owner = true;
}
return id;
}
std::optional<utils::IdType> TypeclassGraph::FindFunctionTypeclass(const std::string& name) {
auto function_iter = method_to_typeclass_.find(name);
if (function_iter == method_to_typeclass_.end()) {
auto function_iter = method_to_vertex_.find(name);
if (function_iter == method_to_vertex_.end()) {
return std::nullopt;
}
return function_iter->second;
}
std::optional<TypeclassGraph::FunctionInfo*> TypeclassGraph::GetFunctionInfo(const std::string& name,
std::optional<utils::IdType> typeclass_id) {
if (typeclass_id.has_value()) {
return &typeclasses_[typeclass_id.value()].functions[name];
std::optional<utils::IdType> vertex_id) {
if (vertex_id.has_value()) {
return &verticles_[vertex_id.value()].functions[name];
}
auto maybe_function_typeclass_id = FindFunctionTypeclass(name);
@ -66,47 +82,45 @@ std::optional<TypeclassGraph::FunctionInfo*> TypeclassGraph::GetFunctionInfo(con
return std::nullopt;
}
return &typeclasses_[maybe_function_typeclass_id.value()].functions[name];
return &verticles_[maybe_function_typeclass_id.value()].functions[name];
}
// cache ??
std::vector<utils::IdType> TypeclassGraph::GetTypeclassDependencies(utils::IdType id) {
std::unordered_set<utils::IdType> TypeclassGraph::GetDependenciesSet(utils::IdType id) {
std::unordered_set<utils::IdType> dependencies;
dependencies.reserve(verticles_.at(id).dependencies.size());
for (auto& dependency : verticles_[id].dependencies) {
dependencies.insert(name_to_typeclass_[dependency]);
}
return dependencies;
}
std::vector<utils::IdType> TypeclassGraph::GetDependenciesVector(utils::IdType id) {
std::vector<utils::IdType> dependencies;
dependencies.reserve(typeclasses_.at(id).dependencies.size());
for (auto& dependency : typeclasses_[id].dependencies) {
dependencies.reserve(verticles_.at(id).dependencies.size());
for (auto& dependency : verticles_[id].dependencies) {
dependencies.push_back(name_to_typeclass_[dependency]);
}
return dependencies;
}
// cache ??
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo*>> TypeclassGraph::GetTypeclassFunctions(utils::IdType id) {
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo*>> functions;
functions.reserve(typeclasses_.at(id).functions.size());
for (auto& function : typeclasses_[id].functions) {
functions.push_back({function.first, &function.second});
}
return functions;
}
bool TypeclassGraph::CalculateGraph() {
void TypeclassGraph::CalculateGraph() {
if (is_calculated_) {
return true;
return;
}
std::vector<std::vector<size_t>> edges(typeclasses_.size());
std::vector<std::vector<size_t>> edges(verticles_.size());
for (size_t i = 0; i < typeclasses_.size(); ++i) {
edges[i].reserve(typeclasses_[i].dependencies.size());
for (auto& dependency :typeclasses_[i].dependencies) {
for (size_t i = 0; i < verticles_.size(); ++i) {
edges[i].reserve(verticles_[i].dependencies.size());
for (auto& dependency : verticles_[i].dependencies) {
auto dependency_iter = name_to_typeclass_.find(dependency);
if (dependency_iter == name_to_typeclass_.end()) {
return false;
error_handling::HandleTypecheckError("Dependency typeclass \"" + dependency + "\" not found", *verticles_[i].base_node);
}
edges[i].push_back(dependency_iter->second);
@ -117,26 +131,28 @@ bool TypeclassGraph::CalculateGraph() {
std::reverse(sorted_verticles.begin(), sorted_verticles.end());
for (auto& id : sorted_verticles) {
for (auto& dependency : typeclasses_[id].dependencies) {
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;
for (auto& dependency : verticles_[id].dependencies) {
for (auto& method : verticles_[name_to_typeclass_[dependency]].functions) {
auto function_iter = verticles_[id].functions.find(method.first);
if (function_iter == verticles_[id].functions.end()) {
verticles_[id].functions[method.first] = method.second;
} else {
if (!function_iter->second.definition.has_value()) {
function_iter->second.definition = method.second.definition;
} else {
if (!function_iter->second.is_defined_in_owner) {
error_handling::HandleTypecheckError("Method \"" + method.first + "\" defined in more then one dependency of type / typeclass \"" + verticles_[id].name + "\"", *verticles_[id].base_node);
}
}
}
for (auto& inherited_dependency : typeclasses_[name_to_typeclass_[dependency]].dependencies) {
typeclasses_[id].dependencies.insert(inherited_dependency);
}
for (auto& inherited_dependency : verticles_[method_to_vertex_[dependency]].dependencies) {
verticles_[id].dependencies.insert(inherited_dependency);
}
}
}
is_calculated_ = true;
return true;
}
} // namespace info