From 602c29ffd7a67d9b01d34ac2081b3e78f0e51e46 Mon Sep 17 00:00:00 2001 From: Amir Date: Tue, 23 Jul 2024 12:18:29 -0500 Subject: [PATCH 1/9] working solution to conditionally dump overrides --- analyze/aps-bind.c | 4 +- analyze/aps-bind.h | 3 ++ aps2scala/dump-scala.cc | 89 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 89 insertions(+), 7 deletions(-) diff --git a/analyze/aps-bind.c b/analyze/aps-bind.c index 5b6b0daf..cac4c151 100644 --- a/analyze/aps-bind.c +++ b/analyze/aps-bind.c @@ -42,8 +42,8 @@ struct env_item { }; typedef struct env_item *SCOPE; -static Declaration module_TYPE; -static Declaration module_PHYLUM; +Declaration module_TYPE; +Declaration module_PHYLUM; static TypeEnvironment current_type_env = 0; diff --git a/analyze/aps-bind.h b/analyze/aps-bind.h index 82ee8fa4..f5e38b43 100644 --- a/analyze/aps-bind.h +++ b/analyze/aps-bind.h @@ -33,4 +33,7 @@ extern int decl_namespaces(Declaration d); extern int bind_debug; #define PRAGMA_ACTIVATION 1 +extern Declaration module_TYPE; +extern Declaration module_PHYLUM; + #endif diff --git a/aps2scala/dump-scala.cc b/aps2scala/dump-scala.cc index 61923f99..8a4fcb70 100644 --- a/aps2scala/dump-scala.cc +++ b/aps2scala/dump-scala.cc @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -217,10 +218,10 @@ void dump_formal(Declaration formal, ostream&os) if (KEYseq_formal == Declaration_KEY(formal)) os << "*"; } -void dump_function_prototype(string name, Type ft, ostream& oss) +void dump_function_prototype(string name, Type ft, bool override_needed, ostream& oss) { - oss << indent() << "val v_" << name << " = f_" << name << " _;\n"; - oss << indent() << "def f_" << name << "("; + oss << indent() << (override_needed ? "override " : "") << "val v_" << name << " = f_" << name << " _;\n"; + oss << indent() << (override_needed ? "override " : "") << "def f_" << name << "("; Declarations formals = function_type_formals(ft); for (Declaration formal = first_Declaration(formals); @@ -1388,7 +1389,7 @@ static void dump_scala_pattern_function( if (!body) { // the constructor function: - dump_function_prototype(name,ft,oss); + dump_function_prototype(name,ft,false,oss); oss << " = c_" << name << args; if (is_syntax) oss << ".register"; oss << ";\n"; @@ -1447,6 +1448,82 @@ void dump_scala_Declaration_header(Declaration decl, ostream& oss) } } +bool check_override_decl(Declaration decl, Declaration fdecl, std::set visited) { + if (visited.find(decl) != visited.end()) { + return false; + } + + visited.insert(decl); + + switch (Declaration_KEY(decl)) { + case KEYphylum_decl: + return check_override_decl(module_PHYLUM, fdecl, visited); + case KEYtype_decl: + return check_override_decl(module_TYPE, fdecl, visited); + case KEYsome_class_decl: { + Declaration result = some_class_decl_result_type(decl); + switch (Declaration_KEY(result)) { + case KEYsome_type_decl: { + Type rtype = some_type_decl_type(result); + if (Type_KEY(rtype) == KEYno_type) { + return check_override_decl(result, fdecl, visited); + } + break; + } + default: + break; + } + + Block body = some_class_decl_contents(decl); + Declaration item; + int i = 0; + for (item = first_Declaration(block_body(body)); item != NULL; item = DECL_NEXT(item)) { + switch (Declaration_KEY(item)) { + case KEYsome_function_decl: + if (!strcmp( + symbol_name(def_name(some_function_decl_def(item))), + symbol_name(def_name(some_function_decl_def(fdecl))))) { + + return true; + } + break; + default: + break; + } + } + + return check_override_decl(result, fdecl, visited); + } + default: + break; + } + + return false; +} + +Declaration get_enclosing_some_class_decl(void * node) { + while (node != NULL) { + switch (ABSTRACT_APS_tnode_phylum(node)) { + case KEYDeclaration: { + Declaration decl = (Declaration) node; + switch (Declaration_KEY(decl)) { + case KEYsome_class_decl: + return decl; + default: + break; + } + break; + } + default: + break; + } + + node = tnode_parent(node); + } + + return NULL; +} + void dump_scala_Declaration(Declaration decl,ostream& oss) { const char *name = 0; @@ -1914,7 +1991,9 @@ void dump_scala_Declaration(Declaration decl,ostream& oss) Type fty = function_decl_type(decl); Declaration rdecl = first_Declaration(function_type_return_values(fty)); Block b = function_decl_body(decl); - dump_function_prototype(name,fty,oss); + Declaration mdecl = get_enclosing_some_class_decl(decl); + std::set visisted; + dump_function_prototype(name,fty, check_override_decl(some_class_decl_result_type(mdecl), decl, visisted), oss); // three kinds of definitions: // 1. the whole thing: a non-empty body: From cf3a08a35ff9bbeb60b0ae641ec8a77257d77095 Mon Sep 17 00:00:00 2001 From: Amir Date: Tue, 23 Jul 2024 12:21:00 -0500 Subject: [PATCH 2/9] small updates --- aps2scala/dump-scala.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/aps2scala/dump-scala.cc b/aps2scala/dump-scala.cc index 8a4fcb70..67a20cf3 100644 --- a/aps2scala/dump-scala.cc +++ b/aps2scala/dump-scala.cc @@ -1501,7 +1501,8 @@ bool check_override_decl(Declaration decl, Declaration fdecl, std::set Date: Tue, 23 Jul 2024 16:37:11 -0500 Subject: [PATCH 3/9] updated the code according to the feedback --- aps2scala/dump-scala.cc | 49 +++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/aps2scala/dump-scala.cc b/aps2scala/dump-scala.cc index 67a20cf3..f46f2168 100644 --- a/aps2scala/dump-scala.cc +++ b/aps2scala/dump-scala.cc @@ -1456,34 +1456,29 @@ bool check_override_decl(Declaration decl, Declaration fdecl, std::set visisted; - dump_function_prototype(name,fty, check_override_decl(some_class_decl_result_type(mdecl), decl, visisted), oss); + bool override_needed = false; + if (mdecl != NULL) { + std::set visisted; + override_needed = check_override_decl(some_class_decl_result_type(mdecl), decl, visisted); + } + dump_function_prototype(name,fty, override_needed, oss); // three kinds of definitions: // 1. the whole thing: a non-empty body: From 843690cc29cfff93d58d99779701e75749aa0a49 Mon Sep 17 00:00:00 2001 From: Amir Date: Tue, 23 Jul 2024 17:33:27 -0500 Subject: [PATCH 4/9] visited stuff wan't needed --- aps2scala/dump-scala.cc | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/aps2scala/dump-scala.cc b/aps2scala/dump-scala.cc index f46f2168..a716acab 100644 --- a/aps2scala/dump-scala.cc +++ b/aps2scala/dump-scala.cc @@ -1448,13 +1448,7 @@ void dump_scala_Declaration_header(Declaration decl, ostream& oss) } } -bool check_override_decl(Declaration decl, Declaration fdecl, std::set visited) { - if (visited.find(decl) != visited.end()) { - return false; - } - - visited.insert(decl); - +bool check_override_decl(Declaration decl, Declaration fdecl) { switch (Declaration_KEY(decl)) { case KEYsome_type_decl: { Type type = some_type_decl_type(decl); @@ -1462,12 +1456,12 @@ bool check_override_decl(Declaration decl, Declaration fdecl, std::set visisted; - override_needed = check_override_decl(some_class_decl_result_type(mdecl), decl, visisted); + override_needed = check_override_decl(some_class_decl_result_type(mdecl), decl); } dump_function_prototype(name,fty, override_needed, oss); From da5f21eaa65943c6fad31f3d9c32e641b85065c7 Mon Sep 17 00:00:00 2001 From: Amir Date: Tue, 23 Jul 2024 17:34:00 -0500 Subject: [PATCH 5/9] set import wasn't needed --- aps2scala/dump-scala.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/aps2scala/dump-scala.cc b/aps2scala/dump-scala.cc index a716acab..9aa22e45 100644 --- a/aps2scala/dump-scala.cc +++ b/aps2scala/dump-scala.cc @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include From de617bafaef74ae4a79d23618eb71b14fdc09372 Mon Sep 17 00:00:00 2001 From: Amir Date: Tue, 25 Nov 2025 23:03:44 -0600 Subject: [PATCH 6/9] Fixed merge error and updated code according to feedback --- analyze/aps-type.c | 3 --- analyze/canonical-signature.c | 2 -- aps2scala/dump-scala.cc | 21 +++++++++++++-------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/analyze/aps-type.c b/analyze/aps-type.c index f2409657..c040ed91 100644 --- a/analyze/aps-type.c +++ b/analyze/aps-type.c @@ -456,9 +456,6 @@ static void* validate_canonicals(void* ignore, void*node) { return node; } -static Declaration module_TYPE; -static Declaration module_PHYLUM; - static void* set_root_phylum(void *ignore, void *node) { switch (ABSTRACT_APS_tnode_phylum(node)) diff --git a/analyze/canonical-signature.c b/analyze/canonical-signature.c index fea01ac9..2184b25b 100644 --- a/analyze/canonical-signature.c +++ b/analyze/canonical-signature.c @@ -10,8 +10,6 @@ static CanonicalSignatureSet from_declaration(Declaration decl); static CanonicalSignatureSet substitute_canonical_signature_set_actuals(CanonicalType* source, CanonicalSignatureSet sig_set); static int canonical_signature_compare(CanonicalSignature *sig1, CanonicalSignature *sig2); -static Declaration module_TYPE; -static Declaration module_PHYLUM; static bool initialized = false; /** diff --git a/aps2scala/dump-scala.cc b/aps2scala/dump-scala.cc index 9aa22e45..6ae9d947 100644 --- a/aps2scala/dump-scala.cc +++ b/aps2scala/dump-scala.cc @@ -1447,7 +1447,10 @@ void dump_scala_Declaration_header(Declaration decl, ostream& oss) } } -bool check_override_decl(Declaration decl, Declaration fdecl) { +// recursive helper function to check given a surrounding declaration (module_decl, class_decl or type_decl) +// if it contains a function declaration that matches the given name and return type +// if true then override would be needed otherwise not needed +static bool check_override_decl(Declaration decl, Symbol fdecl_name, Type fdecl_rtype) { switch (Declaration_KEY(decl)) { case KEYsome_type_decl: { Type type = some_type_decl_type(decl); @@ -1455,12 +1458,12 @@ bool check_override_decl(Declaration decl, Declaration fdecl) { { case KEYno_type: { bool is_phylum = Declaration_KEY(decl) == KEYphylum_decl; - return check_override_decl(is_phylum ? module_PHYLUM : module_TYPE, fdecl); + return check_override_decl(is_phylum ? module_PHYLUM : module_TYPE, fdecl_name, fdecl_rtype); } case KEYtype_use: - return check_override_decl(canonical_type_decl(canonical_type(type)), fdecl); + return check_override_decl(canonical_type_decl(canonical_type(type)), fdecl_name, fdecl_rtype); case KEYtype_inst: - return check_override_decl(USE_DECL(module_use_use(type_inst_module(type))), fdecl); + return check_override_decl(USE_DECL(module_use_use(type_inst_module(type))), fdecl_name, fdecl_rtype); default: return false; } @@ -1471,7 +1474,9 @@ bool check_override_decl(Declaration decl, Declaration fdecl) { for (item = first_Declaration(block_body(body)); item != NULL; item = DECL_NEXT(item)) { switch (Declaration_KEY(item)) { case KEYsome_function_decl: - if (def_name(some_function_decl_def(item)) == def_name(some_function_decl_def(fdecl))) { + if (def_name(some_function_decl_def(item)) == fdecl_name && + // using canonical type to check type equality + canonical_type_compare(canonical_type(function_type_return_type(some_function_decl_type(item))), canonical_type(fdecl_rtype)) == 0) { return true; } break; @@ -1482,9 +1487,9 @@ bool check_override_decl(Declaration decl, Declaration fdecl) { if (decl == module_PHYLUM || decl == module_TYPE) { return false; + } else { + return check_override_decl(some_class_decl_result_type(decl), fdecl_name, fdecl_rtype); } - - return check_override_decl(some_class_decl_result_type(decl), fdecl); } default: break; @@ -1987,7 +1992,7 @@ void dump_scala_Declaration(Declaration decl,ostream& oss) Declaration mdecl = get_enclosing_some_class_decl(decl); bool override_needed = false; if (mdecl != NULL) { - override_needed = check_override_decl(some_class_decl_result_type(mdecl), decl); + override_needed = check_override_decl(some_class_decl_result_type(mdecl), def_name(declaration_def(decl)), function_type_return_type(fty)); } dump_function_prototype(name,fty, override_needed, oss); From 23318b9a0e18ff169669d331a19db9f5fd4e5186 Mon Sep 17 00:00:00 2001 From: Amir Date: Sat, 13 Dec 2025 19:22:33 -0600 Subject: [PATCH 7/9] Improvement to handle different return type but same name which causes bad invalid scala code to be generated --- aps2scala/dump-scala.cc | 52 +++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/aps2scala/dump-scala.cc b/aps2scala/dump-scala.cc index 6ae9d947..38d80c28 100644 --- a/aps2scala/dump-scala.cc +++ b/aps2scala/dump-scala.cc @@ -1447,10 +1447,10 @@ void dump_scala_Declaration_header(Declaration decl, ostream& oss) } } -// recursive helper function to check given a surrounding declaration (module_decl, class_decl or type_decl) +// Recursive helper function to check given a surrounding declaration (module_decl, class_decl or type_decl) // if it contains a function declaration that matches the given name and return type // if true then override would be needed otherwise not needed -static bool check_override_decl(Declaration decl, Symbol fdecl_name, Type fdecl_rtype) { +static void type_has_service_function(Declaration decl, Symbol fdecl_name, vector& found_decls) { switch (Declaration_KEY(decl)) { case KEYsome_type_decl: { Type type = some_type_decl_type(decl); @@ -1458,14 +1458,14 @@ static bool check_override_decl(Declaration decl, Symbol fdecl_name, Type fdecl_ { case KEYno_type: { bool is_phylum = Declaration_KEY(decl) == KEYphylum_decl; - return check_override_decl(is_phylum ? module_PHYLUM : module_TYPE, fdecl_name, fdecl_rtype); + return type_has_service_function(is_phylum ? module_PHYLUM : module_TYPE, fdecl_name, found_decls); } case KEYtype_use: - return check_override_decl(canonical_type_decl(canonical_type(type)), fdecl_name, fdecl_rtype); + return type_has_service_function(canonical_type_decl(canonical_type(type)), fdecl_name, found_decls); case KEYtype_inst: - return check_override_decl(USE_DECL(module_use_use(type_inst_module(type))), fdecl_name, fdecl_rtype); + return type_has_service_function(USE_DECL(module_use_use(type_inst_module(type))), fdecl_name, found_decls); default: - return false; + break; } } case KEYsome_class_decl: { @@ -1474,11 +1474,10 @@ static bool check_override_decl(Declaration decl, Symbol fdecl_name, Type fdecl_ for (item = first_Declaration(block_body(body)); item != NULL; item = DECL_NEXT(item)) { switch (Declaration_KEY(item)) { case KEYsome_function_decl: - if (def_name(some_function_decl_def(item)) == fdecl_name && - // using canonical type to check type equality - canonical_type_compare(canonical_type(function_type_return_type(some_function_decl_type(item))), canonical_type(fdecl_rtype)) == 0) { - return true; + if (def_name(some_function_decl_def(item)) == fdecl_name) { + found_decls.push_back(item); } + break; default: break; @@ -1486,16 +1485,14 @@ static bool check_override_decl(Declaration decl, Symbol fdecl_name, Type fdecl_ } if (decl == module_PHYLUM || decl == module_TYPE) { - return false; + return; } else { - return check_override_decl(some_class_decl_result_type(decl), fdecl_name, fdecl_rtype); + type_has_service_function(some_class_decl_result_type(decl), fdecl_name, found_decls); } } default: break; } - - return false; } Declaration get_enclosing_some_class_decl(Declaration source) { @@ -1992,7 +1989,32 @@ void dump_scala_Declaration(Declaration decl,ostream& oss) Declaration mdecl = get_enclosing_some_class_decl(decl); bool override_needed = false; if (mdecl != NULL) { - override_needed = check_override_decl(some_class_decl_result_type(mdecl), def_name(declaration_def(decl)), function_type_return_type(fty)); + vector found_fdecls; + type_has_service_function(some_class_decl_result_type(mdecl), def_name(declaration_def(decl)), found_fdecls); + + auto cftype2 = (struct Canonical_function_type *)canonical_type(fty); + for (auto& found_fdecl : found_fdecls) { + auto cftype1 = (struct Canonical_function_type *)canonical_type(some_function_decl_type(found_fdecl)); + if (cftype1->num_formals == cftype2->num_formals) { + bool formals_type_match = true; + // start from 1 to skip "this" (or Result) formal + for (int i = 1; i < cftype1->num_formals; ++i) { + if (canonical_type_compare(cftype1->param_types[i], cftype2->param_types[i]) != 0) { + formals_type_match = false; + } + } + + if (formals_type_match) { + if (canonical_type_compare(cftype1->return_type, cftype2->return_type) == 0) { + override_needed = true; + break; + } else { + aps_error(decl, "Function %s has same name as inherited function but different return type; overriding not possible since return types are incompatible", decl_name(decl)); + return; + } + } + } + } } dump_function_prototype(name,fty, override_needed, oss); From 58c9b104ef531a6fe7b40b10666c0aa99ae90a22 Mon Sep 17 00:00:00 2001 From: Amir Date: Sat, 7 Mar 2026 02:43:01 -0600 Subject: [PATCH 8/9] fix merge issue --- aps2scala/dump-scala.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aps2scala/dump-scala.cc b/aps2scala/dump-scala.cc index 1fb03910..9d17e412 100644 --- a/aps2scala/dump-scala.cc +++ b/aps2scala/dump-scala.cc @@ -2025,7 +2025,7 @@ void dump_scala_Declaration(Declaration decl,ostream& oss) } } - dump_function_prototype(name, fty, override_needed, false /* dump_anchor_actual */,oss); + dump_function_prototype(name, fty, false /* dump_anchor_actual */, override_needed, oss); // three kinds of definitions: // 1. the whole thing: a non-empty body: From e38e0515fe687794c1de4733ef3962d009f4b9fa Mon Sep 17 00:00:00 2001 From: Amir Date: Sun, 8 Mar 2026 00:41:33 -0600 Subject: [PATCH 9/9] Attempting to fix canonical types, instead of skipping Result argument --- analyze/canonical-signature.c | 4 ++-- analyze/canonical-type.c | 25 ++++++++++++++++--------- analyze/canonical-type.h | 22 +++++++++++++++++++--- aps2scala/dump-scala.cc | 14 ++++++++++---- 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/analyze/canonical-signature.c b/analyze/canonical-signature.c index 2184b25b..9573a494 100644 --- a/analyze/canonical-signature.c +++ b/analyze/canonical-signature.c @@ -350,9 +350,9 @@ static int canonical_signature_compare(CanonicalSignature *sig1, CanonicalSignat return sig1->is_var - sig2->is_var; } - if (tnode_line_number(sig1->source_class) != tnode_line_number(sig2->source_class)) + if (sig1->source_class != sig2->source_class) { - return tnode_line_number(sig1->source_class) - tnode_line_number(sig2->source_class); + return (sig1->source_class > sig2->source_class) ? 1 : -1; } if (sig1->num_actuals != sig2->num_actuals) diff --git a/analyze/canonical-type.c b/analyze/canonical-type.c index e6860d52..e74e347b 100755 --- a/analyze/canonical-type.c +++ b/analyze/canonical-type.c @@ -1006,9 +1006,12 @@ CanonicalType *canonical_type_join(CanonicalType *ctype_outer, CanonicalType *ct * Comparator for two canonical types * @param ctype1 first canonical type * @param ctype2 second canonical type + * @param ctype1_mdecl_result Result decl from the source (inherited) module, or NULL + * @param ctype2_mdecl_result Result decl from the target (implementing) module, or NULL * @return integer value representing the comparison */ -int canonical_type_compare(CanonicalType *ctype1, CanonicalType *ctype2) +int canonical_type_compare2(CanonicalType *ctype1, CanonicalType *ctype2, + Declaration ctype1_mdecl_result, Declaration ctype2_mdecl_result) { if (ctype1->key != ctype2->key) { @@ -1022,19 +1025,23 @@ int canonical_type_compare(CanonicalType *ctype1, CanonicalType *ctype2) struct Canonical_use_type *canonical_use_type1 = (struct Canonical_use_type *)ctype1; struct Canonical_use_type *canonical_use_type2 = (struct Canonical_use_type *)ctype2; - return tnode_line_number(canonical_use_type1->decl) - tnode_line_number(canonical_use_type2->decl); + Declaration d1 = (ctype1_mdecl_result != NULL && canonical_use_type1->decl == ctype1_mdecl_result) ? ctype2_mdecl_result : canonical_use_type1->decl; + Declaration d2 = canonical_use_type2->decl; + return (d1 > d2) ? 1 : (d1 < d2) ? -1 : 0; } case KEY_CANONICAL_QUAL: { struct Canonical_qual_type *canonical_qual_type1 = (struct Canonical_qual_type *)ctype1; struct Canonical_qual_type *canonical_qual_type2 = (struct Canonical_qual_type *)ctype2; - if (tnode_line_number(canonical_qual_type1->decl) != tnode_line_number(canonical_qual_type2->decl)) + Declaration d1 = (ctype1_mdecl_result != NULL && canonical_qual_type1->decl == ctype1_mdecl_result) ? ctype2_mdecl_result : canonical_qual_type1->decl; + Declaration d2 = canonical_qual_type2->decl; + if (d1 != d2) { - return tnode_line_number(canonical_qual_type1->decl) - tnode_line_number(canonical_qual_type2->decl); + return (d1 > d2) ? 1 : -1; } - return canonical_type_compare(canonical_qual_type1->source, canonical_qual_type2->source); + return canonical_type_compare2(canonical_qual_type1->source, canonical_qual_type2->source, ctype1_mdecl_result, ctype2_mdecl_result); } case KEY_CANONICAL_FUNC: { @@ -1043,10 +1050,10 @@ int canonical_type_compare(CanonicalType *ctype1, CanonicalType *ctype2) if (canonical_function_type1->num_formals != canonical_function_type2->num_formals) { - return canonical_function_type1->num_formals - canonical_function_type2->num_formals > 0 ? 1 : -1; + return (canonical_function_type1->num_formals > canonical_function_type2->num_formals) ? 1 : -1; } - int return_type_comp = canonical_type_compare(canonical_function_type1->return_type, canonical_function_type2->return_type); + int return_type_comp = canonical_type_compare2(canonical_function_type1->return_type, canonical_function_type2->return_type, ctype1_mdecl_result, ctype2_mdecl_result); if (return_type_comp != 0) { return return_type_comp; @@ -1055,7 +1062,7 @@ int canonical_type_compare(CanonicalType *ctype1, CanonicalType *ctype2) int i; for (i = 0; i < canonical_function_type1->num_formals; i++) { - int formal_type_comp = canonical_type_compare(canonical_function_type1->param_types[i], canonical_function_type2->param_types[i]); + int formal_type_comp = canonical_type_compare2(canonical_function_type1->param_types[i], canonical_function_type2->param_types[i], ctype1_mdecl_result, ctype2_mdecl_result); if (formal_type_comp != 0) { return formal_type_comp; @@ -1065,7 +1072,7 @@ int canonical_type_compare(CanonicalType *ctype1, CanonicalType *ctype2) return 0; } default: - fatal_error("canonical_type_compare failed"); + fatal_error("canonical_type_compare2 failed"); return 0; } } diff --git a/analyze/canonical-type.h b/analyze/canonical-type.h index 68338162..8d616f20 100755 --- a/analyze/canonical-type.h +++ b/analyze/canonical-type.h @@ -65,13 +65,29 @@ CanonicalType *canonical_type_join(CanonicalType *ctype_outer, CanonicalType *ct */ CanonicalType *new_canonical_type_use(Declaration decl); +/** + * Compares two canonical types with Result-decl substitution. + * The inherited module's Result maps to the implementing module's Result. + * @param ctype1 Canonical type to compare + * @param ctype2 Canonical type to compare against + * @param ctype1_mdecl_result Result decl of ctype1's enclosing module + * @param ctype2_mdecl_result Result decl of ctype2's enclosing module + * @return Integer value representing comparison of two canonical types + */ +int canonical_type_compare2(CanonicalType *ctype1, CanonicalType *ctype2, + Declaration ctype1_mdecl_result, + Declaration ctype2_mdecl_result); + /** * Compares two canonical types - * @param ctype1 Canonical type A - * @param ctype2 Canonical type B + * @param ctype1 Canonical type to compare + * @param ctype2 Canonical type to compare against * @return Integer value representing comparison of two canonical types */ -int canonical_type_compare(CanonicalType *ctype1, CanonicalType *ctype2); +static inline int canonical_type_compare(CanonicalType *ctype1, CanonicalType *ctype2) +{ + return canonical_type_compare2(ctype1, ctype2, NULL, NULL); +} /** * Given a canonical type, it returns a Declaration diff --git a/aps2scala/dump-scala.cc b/aps2scala/dump-scala.cc index 9d17e412..b3910da5 100644 --- a/aps2scala/dump-scala.cc +++ b/aps2scala/dump-scala.cc @@ -2001,19 +2001,25 @@ void dump_scala_Declaration(Declaration decl,ostream& oss) type_has_service_function(some_class_decl_result_type(mdecl), def_name(declaration_def(decl)), found_fdecls); auto cftype2 = (struct Canonical_function_type *)canonical_type(fty); + // Result declaration of the current (implementing) module + Declaration current_result = some_class_decl_result_type(mdecl); for (auto& found_fdecl : found_fdecls) { auto cftype1 = (struct Canonical_function_type *)canonical_type(some_function_decl_type(found_fdecl)); + // Result declaration of the inherited (source) module + Declaration found_mdecl = get_enclosing_some_class_decl(found_fdecl); + Declaration ctype1_mdecl_result = found_mdecl ? some_class_decl_result_type(found_mdecl) : NULL; if (cftype1->num_formals == cftype2->num_formals) { bool formals_type_match = true; - // start from 1 to skip "this" (or Result) formal - for (int i = 1; i < cftype1->num_formals; ++i) { - if (canonical_type_compare(cftype1->param_types[i], cftype2->param_types[i]) != 0) { + for (int i = 0; i < cftype1->num_formals; ++i) { + if (canonical_type_compare2(cftype1->param_types[i], cftype2->param_types[i], + ctype1_mdecl_result, current_result) != 0) { formals_type_match = false; } } if (formals_type_match) { - if (canonical_type_compare(cftype1->return_type, cftype2->return_type) == 0) { + if (canonical_type_compare2(cftype1->return_type, cftype2->return_type, + ctype1_mdecl_result, current_result) == 0) { override_needed = true; break; } else {