mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-05 22:48:42 +00:00
fixes, function definition search in typecheck
This commit is contained in:
parent
0b53b2f218
commit
afecbd64f5
6 changed files with 123 additions and 129 deletions
|
|
@ -205,15 +205,21 @@ public:
|
||||||
return current_path_;
|
return current_path_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<utils::IdType>& GetCurrentPathNamespaces() {
|
||||||
|
return namespace_stack_;
|
||||||
|
}
|
||||||
|
|
||||||
// use only after LinkSymbolsVisitor
|
// use only after LinkSymbolsVisitor
|
||||||
std::vector<utils::IdType> GetCurrentPathTypes() {
|
std::vector<std::optional<utils::IdType>> GetCurrentPathTypes() {
|
||||||
std::vector<utils::IdType> types;
|
std::vector<std::optional<utils::IdType>> types;
|
||||||
|
|
||||||
types.reserve(namespace_stack_.size());
|
types.reserve(namespace_stack_.size());
|
||||||
for (auto& namespace_id : namespace_stack_) {
|
for (auto& namespace_id : namespace_stack_) {
|
||||||
definition::Namespace& namespace_info = global_info_.GetNamespaceInfo(namespace_id);
|
definition::Namespace& namespace_info = global_info_.GetNamespaceInfo(namespace_id);
|
||||||
if (namespace_info.any_node.has_value() && namespace_info.any_node.value()->link_type_id_.has_value()) {
|
if (namespace_info.any_node.has_value() && namespace_info.any_node.value()->link_type_id_.has_value()) {
|
||||||
types.push_back(namespace_info.any_node.value()->link_type_id_.value());
|
types.push_back(namespace_info.any_node.value()->link_type_id_.value());
|
||||||
|
} else {
|
||||||
|
types.push_back(std::nullopt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -522,7 +522,7 @@ struct FunctionCallExpression {
|
||||||
|
|
||||||
// only one from two is present
|
// only one from two is present
|
||||||
std::optional<utils::IdType> function_id_;
|
std::optional<utils::IdType> function_id_;
|
||||||
std::optional<utils::IdType> typeclass_graph_id_;
|
std::optional<utils::IdType> graph_id_; // for type or typeclass
|
||||||
bool is_method_of_first_argument_ = false;
|
bool is_method_of_first_argument_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,8 @@ private:
|
||||||
|
|
||||||
void AddTypeFunctionsToTypeclassGraph(utils::IdType type_id,
|
void AddTypeFunctionsToTypeclassGraph(utils::IdType type_id,
|
||||||
utils::IdType graph_id,
|
utils::IdType graph_id,
|
||||||
utils::ClassInternalsModifier namespace_modifier);
|
utils::ClassInternalsModifier namespace_modifier,
|
||||||
|
const BaseNode& base_node);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
info::GlobalInfo::NamespaceVisitor namespace_visitor_;
|
info::GlobalInfo::NamespaceVisitor namespace_visitor_;
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,7 @@ private:
|
||||||
bool is_method);
|
bool is_method);
|
||||||
|
|
||||||
std::optional<FunctionDeclaration*>
|
std::optional<FunctionDeclaration*>
|
||||||
FindDefinedTypeTypeclassFunctionAndUpdate(
|
FindDefinedTypeFunctionAndUpdate(
|
||||||
FunctionCallExpression* node,
|
FunctionCallExpression* node,
|
||||||
info::definition::AnyType* defined_type,
|
info::definition::AnyType* defined_type,
|
||||||
bool is_method);
|
bool is_method);
|
||||||
|
|
|
||||||
|
|
@ -55,15 +55,18 @@ void LinkSymbolsVisitor::Visit(TypeDefinitionStatement* node) {
|
||||||
|
|
||||||
AddTypeFunctionsToTypeclassGraph(node->type_id_,
|
AddTypeFunctionsToTypeclassGraph(node->type_id_,
|
||||||
graph_id,
|
graph_id,
|
||||||
utils::ClassInternalsModifier::Static);
|
utils::ClassInternalsModifier::Static,
|
||||||
|
node->base);
|
||||||
|
|
||||||
AddTypeFunctionsToTypeclassGraph(node->type_id_,
|
AddTypeFunctionsToTypeclassGraph(node->type_id_,
|
||||||
graph_id,
|
graph_id,
|
||||||
utils::ClassInternalsModifier::Const);
|
utils::ClassInternalsModifier::Const,
|
||||||
|
node->base);
|
||||||
|
|
||||||
AddTypeFunctionsToTypeclassGraph(node->type_id_,
|
AddTypeFunctionsToTypeclassGraph(node->type_id_,
|
||||||
graph_id,
|
graph_id,
|
||||||
utils::ClassInternalsModifier::Var);
|
utils::ClassInternalsModifier::Var,
|
||||||
|
node->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
|
void LinkSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
|
||||||
|
|
@ -164,7 +167,8 @@ void LinkSymbolsVisitor::Visit(ParametrizedTypeclass* node) {
|
||||||
|
|
||||||
void LinkSymbolsVisitor::AddTypeFunctionsToTypeclassGraph(utils::IdType type_id,
|
void LinkSymbolsVisitor::AddTypeFunctionsToTypeclassGraph(utils::IdType type_id,
|
||||||
utils::IdType graph_id,
|
utils::IdType graph_id,
|
||||||
utils::ClassInternalsModifier namespace_modifier) {
|
utils::ClassInternalsModifier namespace_modifier,
|
||||||
|
const BaseNode& base_node) {
|
||||||
auto maybe_type_graph_info = typeclass_graph_.GetTypeVertex(graph_id);
|
auto maybe_type_graph_info = typeclass_graph_.GetTypeVertex(graph_id);
|
||||||
if (!maybe_type_graph_info.has_value()) {
|
if (!maybe_type_graph_info.has_value()) {
|
||||||
error_handling::HandleInternalError("Type in typeclass graph is not marked as type",
|
error_handling::HandleInternalError("Type in typeclass graph is not marked as type",
|
||||||
|
|
@ -198,10 +202,12 @@ void LinkSymbolsVisitor::AddTypeFunctionsToTypeclassGraph(utils::IdType type_id,
|
||||||
|
|
||||||
type_graph_info->functions[function.first] = function_graph_info;
|
type_graph_info->functions[function.first] = function_graph_info;
|
||||||
} else {
|
} else {
|
||||||
if (function_info.definition.has_value()) {
|
if (namespace_modifier != function_graph_iter->second.modifier) {
|
||||||
function_graph_iter->second.is_defined_in_owner = true;
|
error_handling::HandleTypecheckError("Type function \"" + function.first + "\" has definitions / declarations with different modifiers (static / const /var)", base_node);
|
||||||
function_graph_iter->second.definition = function_info.definition.value().node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
error_handling::HandleInternalError("This code should be unreachable",
|
||||||
|
"LinkSymbolsVisitor.AddTypeFunctionsToTypeclassGraph");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -713,6 +713,7 @@ void TypeCheckVisitor::Visit(AccessExpression* node) {
|
||||||
// Other Expressions
|
// Other Expressions
|
||||||
|
|
||||||
// TODO: builtin functions / methods
|
// TODO: builtin functions / methods
|
||||||
|
// TODO: find & check definitions
|
||||||
void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
||||||
std::optional<FunctionDeclaration*> maybe_function_declaration;
|
std::optional<FunctionDeclaration*> maybe_function_declaration;
|
||||||
|
|
||||||
|
|
@ -776,7 +777,27 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
||||||
context_manager_.AddValueRequirement(current_type_, argument_type);
|
context_manager_.AddValueRequirement(current_type_, argument_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// node->function_id_ = maybe_function_id.value(); // IMPORTANT // TODO: do in functions
|
if (node->function_id_.has_value()) {
|
||||||
|
if (!global_info_.GetFunctionInfo(node->function_id_.value()).definition.has_value()) {
|
||||||
|
error_handling::HandleTypecheckError("No function definition found (non-type function)", node->base);
|
||||||
|
}
|
||||||
|
} else if (node->graph_id_.has_value()) {
|
||||||
|
if (typeclass_graph_.GetVertex(node->graph_id_.value()).modifier != info::TypeclassGraph::Modifier::Typeclass) {
|
||||||
|
auto maybe_graph_function_info = typeclass_graph_.GetFunctionInfo(node->name, node->graph_id_.value());
|
||||||
|
|
||||||
|
if (!maybe_graph_function_info.has_value()) {
|
||||||
|
error_handling::HandleInternalError("FunctionInfo by graph_id_ not found",
|
||||||
|
"TypeCheckVisitor.FunctionCallExpression");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!maybe_graph_function_info.value()->definition.has_value()) {
|
||||||
|
error_handling::HandleTypecheckError("No function definition found (type function)", node->base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error_handling::HandleInternalError("No function_id_ and graph_id_ found",
|
||||||
|
"TypeCheckVisitor.FunctionCallExpression");
|
||||||
|
}
|
||||||
|
|
||||||
Visitor::Visit(function_declaration->type->types.back());
|
Visitor::Visit(function_declaration->type->types.back());
|
||||||
current_type_ = TypeInContext(current_type_, context);
|
current_type_ = TypeInContext(current_type_, context);
|
||||||
|
|
@ -1372,7 +1393,6 @@ void TypeCheckVisitor::CheckPattern(Pattern& node, const BaseNode& base_node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: internal types ??
|
// TODO: internal types ??
|
||||||
// TODO: find & check definitions
|
|
||||||
std::optional<FunctionDeclaration*>
|
std::optional<FunctionDeclaration*>
|
||||||
TypeCheckVisitor::FindExpressionMethodAndUpdate(FunctionCallExpression* node,
|
TypeCheckVisitor::FindExpressionMethodAndUpdate(FunctionCallExpression* node,
|
||||||
utils::IdType expression_type) {
|
utils::IdType expression_type) {
|
||||||
|
|
@ -1399,35 +1419,9 @@ std::optional<FunctionDeclaration*>
|
||||||
}
|
}
|
||||||
info::definition::AnyType* type_info = maybe_type_info.value();
|
info::definition::AnyType* type_info = maybe_type_info.value();
|
||||||
|
|
||||||
std::optional<utils::IdType> maybe_const_function_id = global_info_.GetNamespaceInfo(global_info_.GetNamespaceInfo(type_info->parent_namespace).const_namespaces.at(type_info->type.type)).functions[node->name];
|
maybe_function_declaration = FindDefinedTypeFunctionAndUpdate(node,
|
||||||
|
type_info,
|
||||||
utils::ValueType expression_value_type = context_manager_.GetValueType(expression_type);
|
true);
|
||||||
|
|
||||||
std::optional<utils::IdType> maybe_function_id;
|
|
||||||
if (expression_value_type == utils::ValueType::Var || expression_value_type == utils::ValueType::Tmp) {
|
|
||||||
// TODO: choose expression value types
|
|
||||||
maybe_function_id = global_info_.GetNamespaceInfo(global_info_.GetNamespaceInfo(type_info->parent_namespace).var_namespaces.at(type_info->type.type)).functions[node->name];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maybe_const_function_id.has_value() && maybe_function_id.has_value()) { // TODO: handle on link_types stage
|
|
||||||
error_handling::HandleTypecheckError("Redefinition of method: const & var", node->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!maybe_function_id.has_value()) {
|
|
||||||
maybe_function_id = maybe_const_function_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maybe_function_id.has_value()) {
|
|
||||||
node->function_id_ = maybe_function_id.value();
|
|
||||||
maybe_function_declaration =
|
|
||||||
global_info_.GetFunctionInfo(maybe_function_id.value()).declaration.value().node;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!maybe_function_declaration.has_value()) {
|
|
||||||
maybe_function_declaration = FindDefinedTypeTypeclassFunctionAndUpdate(node,
|
|
||||||
type_info,
|
|
||||||
true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return maybe_function_declaration;
|
return maybe_function_declaration;
|
||||||
}
|
}
|
||||||
|
|
@ -1467,26 +1461,26 @@ std::optional<FunctionDeclaration*>
|
||||||
}
|
}
|
||||||
path.push_back(type_node->type.type);
|
path.push_back(type_node->type.type);
|
||||||
|
|
||||||
std::optional<utils::IdType> maybe_function_id = namespace_visitor_.FindFunctionId(path, node->name);
|
|
||||||
|
|
||||||
CollectTypeExpressionContext(*type_node, context);
|
CollectTypeExpressionContext(*type_node, context);
|
||||||
|
|
||||||
if (maybe_function_id.has_value()) {
|
if (type_node->type_id_.has_value()) {
|
||||||
node->function_id_ = maybe_function_id.value();
|
|
||||||
maybe_function_declaration =
|
|
||||||
global_info_.GetFunctionInfo(maybe_function_id.value()).declaration.value().node;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!maybe_function_declaration.has_value() && type_node->type_id_.has_value()) {
|
|
||||||
auto maybe_type_info = global_info_.GetTypeInfo<info::definition::AnyType>(type_node->type_id_.value());
|
auto maybe_type_info = global_info_.GetTypeInfo<info::definition::AnyType>(type_node->type_id_.value());
|
||||||
if (!maybe_type_info.has_value()) {
|
if (!maybe_type_info.has_value()) {
|
||||||
error_handling::HandleInternalError("typeclass functions / methods implemented only for AnyType",
|
error_handling::HandleInternalError("typeclass functions / methods implemented only for AnyType",
|
||||||
"TypeCheckVisitor.FindTypeFunctionAndUpdate");
|
"TypeCheckVisitor.FindTypeFunctionAndUpdate");
|
||||||
}
|
}
|
||||||
|
|
||||||
maybe_function_declaration = FindDefinedTypeTypeclassFunctionAndUpdate(node,
|
maybe_function_declaration = FindDefinedTypeFunctionAndUpdate(node,
|
||||||
maybe_type_info.value(),
|
maybe_type_info.value(),
|
||||||
false);
|
false);
|
||||||
|
} else {
|
||||||
|
std::optional<utils::IdType> maybe_function_id = namespace_visitor_.FindFunctionId(path, node->name);
|
||||||
|
|
||||||
|
if (maybe_function_id.has_value()) {
|
||||||
|
node->function_id_ = maybe_function_id.value();
|
||||||
|
maybe_function_declaration =
|
||||||
|
global_info_.GetFunctionInfo(maybe_function_id.value()).declaration.value().node;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return maybe_function_declaration;
|
return maybe_function_declaration;
|
||||||
|
|
@ -1494,36 +1488,63 @@ std::optional<FunctionDeclaration*>
|
||||||
|
|
||||||
std::optional<FunctionDeclaration*> TypeCheckVisitor::FindFunctionAndUpdate(FunctionCallExpression* node) {
|
std::optional<FunctionDeclaration*> TypeCheckVisitor::FindFunctionAndUpdate(FunctionCallExpression* node) {
|
||||||
std::optional<FunctionDeclaration*> maybe_function_declaration;
|
std::optional<FunctionDeclaration*> maybe_function_declaration;
|
||||||
std::optional<utils::IdType> maybe_function_id;
|
|
||||||
|
|
||||||
if (namespace_visitor_.GetCurrentNamespace()->modifier != utils::ClassInternalsModifier::Static) {
|
const std::vector<utils::IdType>& path_namespaces = namespace_visitor_.GetCurrentPathNamespaces();
|
||||||
std::string namespace_name =
|
auto path_types = namespace_visitor_.GetCurrentPathTypes();
|
||||||
namespace_visitor_.GetCurrentNamespace()->type_name;
|
for (ssize_t i = (ssize_t)path_types.size() - 1; i >= 0; --i) { // optimize ??
|
||||||
utils::ClassInternalsModifier namespace_modifier =
|
if (path_types[i].has_value()) {
|
||||||
namespace_visitor_.GetCurrentNamespace()->modifier;
|
auto maybe_type_info = global_info_.GetTypeInfo<info::definition::AnyType>(path_types[i].value());
|
||||||
namespace_visitor_.ExitNamespace();
|
if (!maybe_type_info.has_value()) {
|
||||||
|
error_handling::HandleInternalError("typeclass functions / methods implemented only for AnyType",
|
||||||
|
"TypeCheckVisitor.FindTypeFunctionAndUpdate");
|
||||||
|
}
|
||||||
|
|
||||||
maybe_function_id = namespace_visitor_.FindFunctionId(std::nullopt, node->name);
|
maybe_function_declaration =
|
||||||
if (!maybe_function_id.has_value()) {
|
FindDefinedTypeFunctionAndUpdate(node,
|
||||||
// call functions from static namespace of current type
|
maybe_type_info.value(),
|
||||||
std::vector<std::string> current_type_path { namespace_visitor_.GetCurrentNamespace()->type_name };
|
false);
|
||||||
maybe_function_id = namespace_visitor_.FindFunctionId(current_type_path, node->name); // TODO: check !!!
|
} else {
|
||||||
|
auto function_iter = global_info_.GetNamespaceInfo(path_namespaces[i]).functions.find(node->name);
|
||||||
|
if (function_iter != global_info_.GetNamespaceInfo(path_namespaces[i]).functions.end()) {
|
||||||
|
auto& maybe_declaration_info = global_info_.GetFunctionInfo(function_iter->second).declaration;
|
||||||
|
|
||||||
|
if (maybe_declaration_info.has_value()) {
|
||||||
|
maybe_function_declaration = maybe_declaration_info.value().node;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace_visitor_.EnterNamespace(namespace_name, namespace_modifier);
|
if (maybe_function_declaration.has_value()) {
|
||||||
} else {
|
break;
|
||||||
maybe_function_id = namespace_visitor_.FindFunctionId(std::nullopt, node->name);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maybe_function_id.has_value() && global_info_.GetFunctionInfo(maybe_function_id.value()).declaration.has_value()) {
|
// ------------------ replaced ------------------
|
||||||
node->function_id_ = maybe_function_id.value();
|
// if (namespace_visitor_.GetCurrentNamespace()->modifier != utils::ClassInternalsModifier::Static) {
|
||||||
maybe_function_declaration =
|
// std::string namespace_name =
|
||||||
global_info_.GetFunctionInfo(maybe_function_id.value()).declaration.value().node;
|
// namespace_visitor_.GetCurrentNamespace()->type_name;
|
||||||
} else {
|
// utils::ClassInternalsModifier namespace_modifier =
|
||||||
maybe_function_declaration = std::nullopt;
|
// namespace_visitor_.GetCurrentNamespace()->modifier;
|
||||||
}
|
// namespace_visitor_.ExitNamespace();
|
||||||
|
//
|
||||||
|
// maybe_function_id = namespace_visitor_.FindFunctionId(std::nullopt, node->name);
|
||||||
|
// if (!maybe_function_id.has_value()) {
|
||||||
|
// // call functions from static namespace of current type
|
||||||
|
// std::vector<std::string> current_type_path { namespace_visitor_.GetCurrentNamespace()->type_name };
|
||||||
|
// maybe_function_id = namespace_visitor_.FindFunctionId(current_type_path, node->name);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// namespace_visitor_.EnterNamespace(namespace_name, namespace_modifier);
|
||||||
|
// } else {
|
||||||
|
// maybe_function_id = namespace_visitor_.FindFunctionId(std::nullopt, node->name);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (maybe_function_id.has_value() && global_info_.GetFunctionInfo(maybe_function_id.value()).declaration.has_value()) {
|
||||||
|
// node->function_id_ = maybe_function_id.value();
|
||||||
|
// maybe_function_declaration =
|
||||||
|
// global_info_.GetFunctionInfo(maybe_function_id.value()).declaration.value().node;
|
||||||
|
// }
|
||||||
|
|
||||||
// call as method of first argument // TODO: earlier??
|
|
||||||
if (!maybe_function_declaration.has_value() && node->is_binary_operator_expression && node->arguments.size() > 0) {
|
if (!maybe_function_declaration.has_value() && node->is_binary_operator_expression && node->arguments.size() > 0) {
|
||||||
Visitor::Visit(node->arguments[0]);
|
Visitor::Visit(node->arguments[0]);
|
||||||
maybe_function_declaration = FindExpressionMethodAndUpdate(node, current_type_);
|
maybe_function_declaration = FindExpressionMethodAndUpdate(node, current_type_);
|
||||||
|
|
@ -1532,30 +1553,6 @@ std::optional<FunctionDeclaration*> TypeCheckVisitor::FindFunctionAndUpdate(Func
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to find typeclass function in for parent namespaces (check definition ??)
|
|
||||||
if (!maybe_function_declaration.has_value()) {
|
|
||||||
// TODO: check
|
|
||||||
auto path_types = namespace_visitor_.GetCurrentPathTypes();
|
|
||||||
if (!path_types.empty()) {
|
|
||||||
for (ssize_t i = (ssize_t)path_types.size() - 1; i >= 0; --i) { // optimize
|
|
||||||
auto maybe_type_info = global_info_.GetTypeInfo<info::definition::AnyType>(path_types[i]);
|
|
||||||
if (!maybe_type_info.has_value()) {
|
|
||||||
error_handling::HandleInternalError("typeclass functions / methods implemented only for AnyType",
|
|
||||||
"TypeCheckVisitor.FindTypeFunctionAndUpdate");
|
|
||||||
}
|
|
||||||
|
|
||||||
maybe_function_declaration =
|
|
||||||
FindDefinedTypeTypeclassFunctionAndUpdate(node,
|
|
||||||
maybe_type_info.value(),
|
|
||||||
false);
|
|
||||||
|
|
||||||
if (maybe_function_declaration.has_value()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return maybe_function_declaration;
|
return maybe_function_declaration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1589,44 +1586,28 @@ std::optional<FunctionDeclaration*>
|
||||||
error_handling::HandleTypecheckError("Typeclass function has wrong modifier (abstract type)", node->base);
|
error_handling::HandleTypecheckError("Typeclass function has wrong modifier (abstract type)", node->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
node->typeclass_graph_id_ = maybe_typeclass_graph_id;
|
node->graph_id_ = maybe_typeclass_graph_id;
|
||||||
maybe_function_declaration = maybe_typeclass_function_info.value()->declaration;
|
maybe_function_declaration = maybe_typeclass_function_info.value()->declaration;
|
||||||
|
|
||||||
return maybe_function_declaration;
|
return maybe_function_declaration;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<FunctionDeclaration*>
|
std::optional<FunctionDeclaration*>
|
||||||
TypeCheckVisitor::FindDefinedTypeTypeclassFunctionAndUpdate(
|
TypeCheckVisitor::FindDefinedTypeFunctionAndUpdate(
|
||||||
FunctionCallExpression* node,
|
FunctionCallExpression* node,
|
||||||
info::definition::AnyType* defined_type,
|
info::definition::AnyType* defined_type,
|
||||||
bool is_method) {
|
bool is_method) {
|
||||||
std::optional<FunctionDeclaration*> maybe_function_declaration;
|
std::optional<FunctionDeclaration*> maybe_function_declaration;
|
||||||
|
|
||||||
auto maybe_typeclass_graph_id = typeclass_graph_.FindFunctionTypeclass(node->name);
|
auto maybe_type_function_info = typeclass_graph_.GetFunctionInfo(node->name, defined_type->type.node->graph_id_);
|
||||||
if (!maybe_typeclass_graph_id.has_value()) {
|
|
||||||
|
if (!maybe_type_function_info.has_value()) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
// error_handling::HandleTypecheckError("Function is not declared in type", node->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto typeclasses = typeclass_graph_.GetDependenciesSet(defined_type->type.node->graph_id_);
|
node->graph_id_ = defined_type->type.node->graph_id_;
|
||||||
auto function_typeclass_iter = typeclasses.find(maybe_typeclass_graph_id.value());
|
maybe_function_declaration = maybe_type_function_info.value()->declaration;
|
||||||
|
|
||||||
if (function_typeclass_iter == typeclasses.end()) {
|
|
||||||
error_handling::HandleTypecheckError("Function typeclass not pesent in type typeclasses list (defined type)", node->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto maybe_typeclass_function_info = typeclass_graph_.GetFunctionInfo(node->name,
|
|
||||||
maybe_typeclass_graph_id.value());
|
|
||||||
if (!maybe_typeclass_function_info.has_value()) {
|
|
||||||
error_handling::HandleInternalError("Typeclass function info found, but typeclass id not found (definied type)",
|
|
||||||
"TypeCheckVisitor.FindDefinedTypeTypeclassFunctionAndUpdate");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((maybe_typeclass_function_info.value()->modifier == utils::ClassInternalsModifier::Static) != is_method) {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
node->typeclass_graph_id_ = maybe_typeclass_graph_id;
|
|
||||||
maybe_function_declaration = maybe_typeclass_function_info.value()->declaration;
|
|
||||||
|
|
||||||
return maybe_function_declaration;
|
return maybe_function_declaration;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue