public override void visit(SyntaxTree.ident_with_templateparams _ident_with_templateparams) { 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) { SymbolInfo type_si = context.find(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; } type_si = context.find(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<type_node> tpars = visit_type_list(_ident_with_templateparams.template_params.params_list); return_value(instance_any(tc, tpars, get_location(_ident_with_templateparams))); 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<type_node> 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) { delegated_methods dm = te.type as delegated_methods; if (dm != null) { List<type_node> ptypes = visit_type_list(_ident_with_templateparams.template_params.params_list); base_function_call_list bfcl = new base_function_call_list(); common_method_node cnode; compiled_function_node comp_node; function_node fnode; int generic_count = 0; foreach (base_function_call bfc in dm.proper_methods) { if (bfc.simple_function_node.is_generic_function) { generic_count++; } } bool one_function = false; switch (generic_count) { case 0: AddError(get_location(_ident_with_templateparams), "TRIANGLE_BRACKETS_NOT_ALLOWED_WITH_COMMON_FUNCTIONS"); break; case 1: one_function = true; break; default: one_function = false; break; } foreach (base_function_call bfc in dm.proper_methods) { if (!bfc.simple_function_node.is_generic_function) { continue; } switch (bfc.semantic_node_type) { case semantic_node_type.common_namespace_function_call: common_namespace_function_node cnfn = bfc.simple_function_node.get_instance(ptypes, one_function, get_location(_ident_with_templateparams)) as common_namespace_function_node; if (cnfn != null) { bfcl.AddElement(new common_namespace_function_call(cnfn, bfc.location)); } break; case semantic_node_type.common_method_call: cnode = bfc.simple_function_node.get_instance(ptypes, one_function, get_location(_ident_with_templateparams)) as common_method_node; if (cnode != null) { bfcl.AddElement(new common_method_call(cnode, (bfc as common_method_call).obj, bfc.location)); } break; case semantic_node_type.compiled_function_call: fnode = bfc.simple_function_node.get_instance(ptypes, one_function, get_location(_ident_with_templateparams)); cnode = fnode as common_method_node; if (cnode != null) { bfcl.AddElement(new common_method_call(cnode, (bfc as compiled_function_call).obj, bfc.location)); } else { comp_node = fnode as compiled_function_node; if (comp_node != null) { bfcl.AddElement(new compiled_function_call(comp_node, (bfc as compiled_function_call).obj, bfc.location)); } } break; case semantic_node_type.common_static_method_call: case semantic_node_type.compiled_static_method_call: fnode = bfc.simple_function_node.get_instance(ptypes, one_function, get_location(_ident_with_templateparams)); cnode = fnode as common_method_node; if (cnode != null) { bfcl.AddElement(new common_static_method_call(cnode, bfc.location)); } else { comp_node = fnode as compiled_function_node; if (comp_node != null) { bfcl.AddElement(new compiled_static_method_call(comp_node, bfc.location)); } } break; } } if (bfcl.Count == 0) { AddError(get_location(_ident_with_templateparams.template_params), "NO_FUNCTIONS_{0}_CAN_BE_USED_WITH_THIS_SPECIFICATION", dm.proper_methods[0].function.name); } delegated_methods dm1 = new delegated_methods(); dm1.proper_methods.AddRange(bfcl); typed_expression te1 = new typed_expression(dm1, te.location); return_value(te1); return; } } AddError(get_location(_ident_with_templateparams.name), "TRIANGLE_BRACKETS_NOT_AWAITED"); }
private base_function_call_list convert_functions_to_calls(expression_node obj, function_node_list fnl, location loc, bool is_static) { base_function_call_list ret = new base_function_call_list(); foreach (function_node fnode in fnl) { base_function_call bfc = null; switch (fnode.semantic_node_type) { case semantic_node_type.common_namespace_function_node: { common_namespace_function_node cmfn = fnode as common_namespace_function_node; common_namespace_function_call cnfc = new common_namespace_function_call(cmfn, loc); if (cmfn.ConnectedToType != null) cnfc.parameters.AddElement(obj); if (cmfn.is_generic_function && !cmfn.is_generic_function_instance && cmfn.ConnectedToType != null && cmfn.parameters.Count == 1) { expressions_list parameters = new expressions_list(); parameters.AddElement(obj); function_node inst = null; try { inst = generic_convertions.DeduceFunction(cmfn, parameters, true, loc); } catch { continue; } cnfc = new common_namespace_function_call((common_namespace_function_node)inst, loc); if (cmfn.ConnectedToType != null) cnfc.parameters.AddElement(obj); } /*if (cmfn.parameters.Count >= 1 && cmfn.parameters[cmfn.parameters.Count - 1].is_params) { convertion_data_and_alghoritms.select_function(cnfc.parameters, new SymbolInfo(cmfn), loc); }*/ bfc = cnfc; break; } case semantic_node_type.basic_function_node: { //Может здесь стоит и выругаться, но я не буду пока этого делать. break; } case semantic_node_type.common_in_function_function_node: { common_in_function_function_node ciffn = fnode as common_in_function_function_node; int depth = convertion_data_and_alghoritms.symbol_table.GetRelativeScopeDepth(ciffn.scope, context.top_function.scope); common_in_function_function_call ciffc = new common_in_function_function_call(ciffn, depth, loc); bfc = ciffc; break; } case semantic_node_type.common_method_node: { common_method_node cmn = fnode as common_method_node; //Если cmn конструктор - то плохо, но его не должно сюда попасть. if (cmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) { if (!is_static) { if (obj == null) obj = GetCurrentObjectReference(cmn.cont_type.Scope, cmn, loc);//new this_node(context.converted_type, loc); common_method_call cmc = new common_method_call(cmn, obj, loc); cmc.virtual_call = !inherited_ident_processing; bfc = cmc; } //ssyy!!! Мне сложно понять предназначение данного кода, но, по-видимому, //следует его переписать так. else if (cmn.is_constructor) { if (cmn.parameters.Count == 0) { if (cmn.cont_type.IsAbstract) AddError(loc, "ABSTRACT_CONSTRUCTOR_{0}_CALL", cmn.cont_type.name); ret.clear(); ret.AddElement(new common_constructor_call(cmn, loc)); return ret; } } } else { if (is_static) { common_static_method_call csmc = new common_static_method_call(cmn, loc); bfc = csmc; } } break; } case semantic_node_type.compiled_function_node: { compiled_function_node cfn = fnode as compiled_function_node; if (cfn.cont_type.Scope == null && cfn is compiled_function_node) (cfn.cont_type as compiled_type_node).init_scope(); if (cfn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) { //ispravleno ibond //if (is_static) { if (cfn.is_generic_function && !cfn.is_generic_function_instance && cfn.ConnectedToType != null && cfn.parameters.Count == 1) { expressions_list parameters = new expressions_list(); parameters.AddElement(obj); function_node inst = null; try { inst = generic_convertions.DeduceFunction(cfn, parameters, true, loc); } catch { continue; } if (inst is common_namespace_function_node) bfc = new common_namespace_function_call((common_namespace_function_node)inst, loc); else if (inst is compiled_function_node) bfc = new compiled_static_method_call((compiled_function_node)inst, loc); else bfc = new compiled_static_method_call(cfn, loc); } else { compiled_static_method_call csmc = new compiled_static_method_call(cfn, loc); bfc = csmc; } if (cfn.ConnectedToType != null) bfc.parameters.AddElement(obj); } } else { if (!is_static) { if (obj == null) obj = GetCurrentObjectReference(cfn.cont_type.Scope, cfn, loc);//new this_node(context.converted_type, loc); compiled_function_call cfc = new compiled_function_call(cfn, obj, loc); cfc.virtual_call = !inherited_ident_processing; bfc = cfc; } } break; } case semantic_node_type.compiled_constructor_node: { //Этот код мы вроде не должны вызывать, но если он все-же вызовется. compiled_constructor_node ccn = fnode as compiled_constructor_node; compiled_constructor_call ccc = new compiled_constructor_call(ccn, loc); bfc = ccc; break; } default: { throw new CompilerInternalError("Undefined method type."); } } if (bfc != null) { ret.AddElement(bfc); } } return ret; }