diff --git a/TestSuite/generics8.pas b/TestSuite/generics8.pas new file mode 100644 index 000000000..c8c20573d --- /dev/null +++ b/TestSuite/generics8.pas @@ -0,0 +1,19 @@ +program generics8; +type TClass = class +class function Test: integer; +begin + Result := 2; +end; +class function Test2: T1; +begin + Result := default(T1); +end; +end; + +begin + var c := System.Collections.Generic.Comparer&.Default; + assert(System.Collections.Generic.Comparer&.Equals(nil, nil) = true); + assert(TClass&.Test=2); + assert(generics8.TClass&.Test=2); + assert(generics8.TClass&.Test2& =0); +end. \ No newline at end of file diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 3718fed9b..8e1c077f1 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -17801,6 +17801,7 @@ namespace PascalABCCompiler.TreeConverter { SyntaxTree.expression ex = _ident_with_templateparams.name; SyntaxTree.ident id_ex = _ident_with_templateparams.name as SyntaxTree.ident; + dot_node dn = _ident_with_templateparams.name as dot_node; int par_count = _ident_with_templateparams.template_params.params_list.Count; if (id_ex != null) { @@ -17819,6 +17820,48 @@ namespace PascalABCCompiler.TreeConverter return; } } + else if (dn != null && dn.right is ident) + { + semantic_node sn = convert_semantic_strong(dn.left); + id_ex = dn.right as SyntaxTree.ident; + type_node tn = null; + namespace_node nn = null; + unit_node un = null; + switch (sn.general_node_type) + { + case general_node_type.expression: tn = (sn as expression_node).type; break; + case general_node_type.type_node: tn = sn as type_node; break; + case general_node_type.namespace_node: nn = sn as namespace_node; break; + case general_node_type.unit_node: un = sn as unit_node; break; + default: + AddError(get_location(dn.left), "EXPECTED_ANOTHER_KIND_OF_OBJECT"); break; + } + SymbolInfo type_si = null; + if (tn != null) + type_si = tn.find_in_type(id_ex.name + compiler_string_consts.generic_params_infix + par_count.ToString()); + else if (nn != null) + type_si = nn.find(id_ex.name + compiler_string_consts.generic_params_infix + par_count.ToString()); + else if (un != null) + type_si = un.find_only_in_namespace(id_ex.name + compiler_string_consts.generic_params_infix + par_count.ToString()); + if (type_si != null) + { + return_value(get_generic_instance(type_si, _ident_with_templateparams.template_params.params_list)); + return; + } + if (tn != null) + type_si = tn.find_in_type(id_ex.name); + else if (nn != null) + type_si = nn.find(id_ex.name); + else if (un != null) + type_si = un.find_only_in_namespace(id_ex.name); + if (type_si != null && type_si.sym_info.general_node_type == general_node_type.template_type) + { + template_class tc = type_si.sym_info as template_class; + List tpars = visit_type_list(_ident_with_templateparams.template_params.params_list); + return_value(instance_any(tc, tpars, get_location(_ident_with_templateparams))); + return; + } + } expression_node adr = ret.visit(ex); typed_expression te = adr as typed_expression; if (te != null)