private string GetGenericFlag(common_function_node cfn) { if (!cfn.is_generic_function) return ""; return "``"+cfn.get_generic_params_list().Count.ToString(); }
//\ssyy //(ssyy) "Я" бывают разные :) //Я хочу модифицировать этот метод так, чтобы в случае предописания наличия метода //он не выкидывал исключение, а понимал все правильно //Этот метод вызывается только для функций с телом /// <summary> /// Ищет предописание функции, производя необходимые проверки. Возвращает true-уникальная, false-предописанная /// </summary> /// <param name="fn">Проверяемая функция</param> /// <returns></returns> private bool check_unique_or_predefined(common_function_node fn) { SymbolInfo si=null; bool in_unit = false; if (_func_stack.size<=1) { if (_explicit_interface_type != null) { si = _explicit_interface_type.find_in_type(fn.name); } else if (_ctn!=null) { si=_ctn.Scope.FindOnlyInScope(fn.name); if (_ctn is compiled_generic_instance_type_node && fn is common_namespace_function_node) { si = (_ctn as compiled_generic_instance_type_node).compiled_original_generic.find_in_type(fn.name); SymbolInfo si_tmp = si; while (si_tmp != null) { if (si_tmp.sym_info.general_node_type != general_node_type.function_node) { TreeRealization.BasePCUReader.RestoreSymbols(si_tmp, fn.name); } common_namespace_function_node cnfn = si_tmp.sym_info as common_namespace_function_node; if (cnfn != null) { if (cnfn.namespace_node == (fn as common_namespace_function_node).namespace_node) { break; } } si_tmp = si_tmp.Next; } si = si_tmp; } } else if (_compiled_tn != null) { si = _compiled_tn.find_in_type(fn.name); } else { in_unit = true; si = _cmn.scope.FindOnlyInScope(fn.name); } } else { common_function_node temp=_func_stack.pop(); si = _func_stack.top().scope.FindOnlyInScope(fn.name); _func_stack.push(temp); } bool predef_find = false; SymbolInfo tmp_si = si; int overloads = 0; while(tmp_si!=null) { if (tmp_si.sym_info != fn && !(si.sym_info is basic_function_node)) { overloads++; } tmp_si = tmp_si.Next; } while(si!=null) { if (si.sym_info==fn) { si=si.Next; continue; } if (si.sym_info.general_node_type != general_node_type.function_node) { TreeRealization.BasePCUReader.RestoreSymbols(si, fn.name); } #if (DEBUG) if (si.sym_info.general_node_type!=general_node_type.function_node) { throw new CompilerInternalError("Function name is used to define not function."); } #endif if (si.sym_info is basic_function_node || si.sym_info is compiled_function_node) { si = si.Next; continue; } //compar - найденная функция common_function_node compar=((common_function_node)(si.sym_info)); //Проверяем, если мы нашли не предописание if (compar.function_code != null || is_order_independed_method_description) { if (compar.is_overload == false) { AddError(new FunctionMustBeWithOverloadDirective(compar, fn)); } if (convertion_data_and_alghoritms.function_eq_params(fn, compar, false) && fn.is_extension_method == compar.is_extension_method) { if (fn.IsOperator && (fn.name == compiler_string_consts.explicit_operator_name || fn.name == compiler_string_consts.implicit_operator_name)) { if (convertion_data_and_alghoritms.function_eq_params_and_result(fn,compar)) AddError(new FunctionDuplicateDefinition(compar, fn)); } else { if (fn is common_method_node && compar is common_method_node) { common_method_node cmn1 = fn as common_method_node; common_method_node cmn2 = compar as common_method_node; if (cmn1.explicit_interface == cmn2.explicit_interface) AddError(new FunctionDuplicateDefinition(compar, fn)); } else AddError(new FunctionDuplicateDefinition(compar, fn)); } } si = si.Next; continue; } bool is_find_predefinition=false; if (compar.is_overload==false || overloads == 1 && in_unit) { //Если нет параметров в описании тела функции if (fn.parameters.Count==0) { is_find_predefinition=true; } else { is_find_predefinition=is_predefinition(compar,fn,true); } } else { is_find_predefinition=is_predefinition(compar,fn,false); } if (!is_find_predefinition) { si = si.Next; continue; } else { predef_find = true; foreach (common_parameter par in fn.parameters) { if (par.default_value != null) { syntax_tree_visitor.AddError(par.loc, "DEFAULT_VALUE_MUST_BE_ONLY_IN_FIRST_DECLARATION"); } } } if (compar.function_code!=null) { AddError(fn.loc, "FUNCTION_{0}_ALREADY_HAVE_A_BODY", fn.name); } if ((compar.polymorphic_state == PascalABCCompiler.SemanticTree.polymorphic_state.ps_static) != (fn.polymorphic_state == PascalABCCompiler.SemanticTree.polymorphic_state.ps_static)) { syntax_tree_visitor.AddError(fn.loc, "CLASS_FUNCTION_ATTRIBUTE_MISMATCH"); } common_method_node compiled_meth = fn as common_method_node; if (compiled_meth != null) { common_method_node finded_method = (common_method_node)compar; if (compiled_meth.is_constructor) { if (finded_method.is_constructor == false) { AddError(compiled_meth.loc, "CONSTRUCTOR_MUST_BE_REALIZED_WITH_CONSTRUCTOR_KEYWORD"); } compiled_meth.return_value_type = finded_method.return_value_type; convertion_data_and_alghoritms.create_function_return_variable(finded_method,null); } } if (!convertion_data_and_alghoritms.eq_type_nodes(compar.return_value_type,fn.return_value_type) && fn.return_value_type != null) { AddError(fn.loc, "FUNCTION_PREDEFINITION_AND_DEFINITION_HAVE_DIFFERENT_RESULT_TYPES"); } //НУЖЕН СПИСОК ФУНКЦИЙ С ПРЕДОПРЕДЕЛЕНИЯМИ, ЧТОБЫ ОБНАРУЖИТЬ ОПИСАННЫЕ НО НЕ ОПРЕДЕЛЕННЫЕ //Или не нужен??? //TODO: СИНХРОНИЗИРОВАТЬ АТТРИБУТЫ!!!!! if (fn.is_overload) { compar.is_overload=true; } //TODO: Внимательно проверить следующий if. if (compar.is_overload) { fn.is_overload = true; last_created_function.symbol_kind = symbol_kind.sk_overload_function; } common_function_node cfn11=_func_stack.pop(); compar.scope = cfn11.scope; common_method_node cmnode=compar as common_method_node; if (cmnode != null) { SymbolInfo si_local = cfn11.scope.FindOnlyInScope(compiler_string_consts.self_word); if (si_local != null) { si_local.sym_info = cmnode.self_variable; } } //Удаляем текущую функцию SymbolInfo siint = null; switch(converting_block()) { case block_type.function_block: { _func_stack.top().functions_nodes_list.remove((common_in_function_function_node)fn); siint = _func_stack.top().scope.FindOnlyInScope(fn.name); break; } case block_type.namespace_block: { _cmn.functions.remove((common_namespace_function_node)fn); siint = _cmn.scope.FindOnlyInScope(fn.name); break; } case block_type.type_block: { //TODO: Доделать описание методов класса. _ctn.methods.remove((common_method_node)fn); siint = _ctn.scope.FindOnlyInScope(fn.name); break; } case block_type.compiled_type_block: { if (syntax_tree_visitor.compiled_unit.namespaces[0].functions.Contains((common_namespace_function_node)fn)) syntax_tree_visitor.compiled_unit.namespaces[0].functions.remove((common_namespace_function_node)fn); siint = _compiled_tn.find_in_type(fn.name); break; } default: { throw new CompilerInternalError("Undefined block type"); } } while (siint.sym_info != fn && siint.Next != null) { siint = siint.Next; } siint.sym_info = compar; //Мы удалили новую функцию. Сейчас мы должны перенести параметры из новой функции в старую. //TODO: У новой функции может вообще не быть параметров. Они все в старой. Разобраться с этим. А зачем вообще переносить параметры? if (compar.parameters.Count != 0) { if (fn.parameters.Count == 0) { foreach (common_parameter pr in compar.parameters) { compar.scope.AddSymbol(pr.name, new SymbolInfo(pr)); } } else { foreach (common_parameter pr in compar.parameters) { SymbolInfo par_sim_info = fn.scope.FindOnlyInScope(pr.name); par_sim_info.sym_info = pr; } } } if (fn.is_generic_function) { for (int i = 0; i < fn.generic_params.Count; ++i) { common_type_node t_fn = fn.generic_params[i] as common_type_node; common_type_node t_compar = compar.generic_params[i] as common_type_node; t_fn.is_class = t_compar.is_class; t_fn.internal_is_value = t_compar.internal_is_value; t_fn.SetImplementingInterfaces(t_compar.ImplementingInterfaces); (t_fn.Scope as SymbolTable.IInterfaceScope).TopInterfaceScopeArray = (t_compar.Scope as SymbolTable.IInterfaceScope).TopInterfaceScopeArray; t_fn.SetBaseType(t_compar.base_type); if (t_compar.has_default_constructor) { generic_parameter_eliminations.add_default_ctor(t_fn); } //t_fn.generic_function_container = compar; } //конверитируем параметры предописания в параметры описания. List<type_node> fn_types = fn.get_generic_params_list(); foreach (common_parameter par in compar.parameters) { par.type = generic_convertions.determine_type(par.type, fn_types, true); } if (compar.return_value_type != null) { compar.return_value_type = generic_convertions.determine_type(compar.return_value_type, fn_types, true); if (compar.return_variable != null) { compar.return_variable.type = compar.return_value_type; } } compar.generic_params = fn.generic_params; foreach (common_type_node tn in compar.generic_params) { tn.generic_function_container = compar; } } _func_stack.push(compar); compar.attributes.AddRange(fn.attributes); //si.sym_info=fn; break; } if (fn is common_method_node && !predef_find && syntax_tree_visitor.current_converted_method_not_in_class_defined && _explicit_interface_type == null) { AddError(new NoMethodInClassWithThisParams(fn as common_method_node, (fn as common_method_node).cont_type, fn.loc)); } return !predef_find; }