public static expression_node convert_delegate_to_return_value_type(location call_location, params expression_node[] parameters) { expression_node par = parameters[0]; internal_interface ii = par.type.get_internal_interface(internal_interface_kind.delegate_interface); delegate_internal_interface dii = (delegate_internal_interface)ii; common_method_node cmn = dii.invoke_method as common_method_node; if (cmn != null) { expression_node exp = new common_method_call(cmn, par, call_location); return(exp); } compiled_function_node cfn = dii.invoke_method as compiled_function_node; if (cfn != null) { expression_node exp = new compiled_function_call(cfn, par, call_location); return(exp); } return(null); }
private void mark_if_delegate() { //До того как мы добавили в стандартную библиотеку MulticastDelegate других делегатов не добавляем. //Это важно при инициализации стандартной библиотеки. if (SystemLibrary.SystemLibrary.delegate_base_type != null) { if (base_type == SystemLibrary.SystemLibrary.delegate_base_type) { SymbolInfo si_int = this.find_in_type(compiler_string_consts.invoke_method_name); #if DEBUG if (si_int == null) { throw new CompilerInternalError("No invoke method in class derived from MulticastDelegate"); } #endif compiled_function_node invoke = si_int.sym_info as compiled_function_node; #if DEBUG if (invoke == null) { throw new CompilerInternalError("No invoke method in class derived from MulticastDelegate"); } #endif SymbolInfo si_cons = this.find_in_type(compiler_string_consts.net_constructor_name); compiled_constructor_node ctor = si_cons.sym_info as compiled_constructor_node; #if DEBUG if (ctor == null) { throw new CompilerInternalError("No constructor in class derived from MulticastDelegate"); } #endif delegate_internal_interface dii = new delegate_internal_interface(invoke.return_value_type, invoke, ctor); dii.parameters.AddRange(invoke.parameters); this.add_internal_interface(dii); add_delegate_operator(compiler_string_consts.plusassign_name, type_constructor.instance.delegate_add_assign_compile_time_executor); add_delegate_operator(compiler_string_consts.plus_name, type_constructor.instance.delegate_add_compile_time_executor); add_delegate_operator(compiler_string_consts.minusassign_name, type_constructor.instance.delegate_sub_assign_compile_time_executor); add_delegate_operator(compiler_string_consts.minus_name, type_constructor.instance.delegate_sub_compile_time_executor); } } }
private definition_node CreateInterfaceCommonType(string name, int offset) { definition_node dn = null; if (members.TryGetValue(offset, out dn)) return dn as common_type_node; common_type_node ctn = null; bool is_interface = br.ReadBoolean(); int ind = br.ReadInt32(); if (is_interface)//пропускаем флаг - интерфейсности { name = GetString(br.ReadInt32()); } else { name = br.ReadString(); } //br.ReadInt32(); //Читаем, является ли тип интерфейсом bool type_is_interface = (br.ReadByte() == 1); //Читаем, является ли тип делегатом bool type_is_delegate = (br.ReadByte() == 1); //Читаем, является ли тип описанием дженерика bool type_is_generic_definition = (br.ReadByte() == 1); List<SemanticTree.ICommonTypeNode> type_params = null; if (type_is_generic_definition) { type_params = ReadGenericParams((is_interface) ? cun.namespaces[0] : cun.namespaces[1]); } WrappedInterfaceScope iscope = null; WrappedClassScope scope; if (type_is_interface) { iscope = new WrappedInterfaceScope(this, cun.scope, null); scope = iscope; } else { scope = new WrappedClassScope(this, cun.scope, null); } ctn = new wrapped_common_type_node(this, null, name, SemanticTree.type_access_level.tal_public, cun.namespaces[0], scope, null, offset); if (is_interface) AddTypeToOrderList(ctn, ind); else AddImplTypeToOrderList(ctn, ind); if (type_is_generic_definition) { ctn.is_generic_type_definition = true; ctn.generic_params = type_params; } AddMember(ctn, offset); int_members.Insert(0,ctn); type_node base_type = GetTypeReference(); bool is_value_type = br.ReadBoolean(); //Читаем поддерживаемые интерфейсы List<SemanticTree.ITypeNode> interf_implemented = ReadImplementingInterfaces(); //int interf_count = br.ReadInt32(); //List<SemanticTree.ITypeNode> interf_implemented = new List<SemanticTree.ITypeNode>(interf_count); //for (int i = 0; i < interf_count; i++) //{ // interf_implemented.Add(GetTypeReference()); //} constant_node low_val=null; constant_node upper_val=null; SemanticTree.type_access_level tal = (SemanticTree.type_access_level)br.ReadByte(); SemanticTree.type_special_kind tsk = (SemanticTree.type_special_kind)br.ReadByte(); ctn.SetIsSealed(br.ReadBoolean()); ctn.SetIsAbstract(br.ReadBoolean()); ctn.IsPartial = br.ReadBoolean(); if (tsk == SemanticTree.type_special_kind.diap_type) { low_val = CreateExpression() as constant_node; upper_val = CreateExpression() as constant_node; } if (type_is_interface) { //Добавляем ссылки на области видимости предков интерфейса List<SymbolTable.Scope> interf_scopes = new List<SymbolTable.Scope>(); foreach (type_node tnode in interf_implemented) { interf_scopes.Add(tnode.Scope); } iscope.TopInterfaceScopeArray = interf_scopes.ToArray(); } //ctn = new wrapped_common_type_node(this, base_type, name, tal, cun.namespaces[0], scope, null, offset); //AddMember(ctn, offset); //int_members.Insert(0,ctn); ctn.SetBaseType(base_type); ctn.IsInterface = type_is_interface; ctn.IsDelegate = type_is_delegate; ctn.ImplementingInterfaces.AddRange(interf_implemented); ctn.internal_is_value = is_value_type; ctn.type_special_kind = tsk; if (ctn.full_name == "PABCSystem.BinaryFile") ctn.type_special_kind = SemanticTree.type_special_kind.binary_file; if (type_is_generic_definition) { foreach (common_type_node par in type_params) { par.generic_type_container = ctn; ReadTypeParameterEliminations(par); } } type_node elemnet_type = null; if (CanReadObject()) elemnet_type = GetTypeReference(); ctn.element_type = elemnet_type; if (ctn.type_special_kind != SemanticTree.type_special_kind.set_type) { SystemLibrary.SystemLibrary.init_reference_type(ctn); } if (ctn.type_special_kind == SemanticTree.type_special_kind.set_type) { ctn = compilation_context.AddTypeToSetTypeList(ctn); } if (ctn.type_special_kind == SemanticTree.type_special_kind.typed_file) { ctn = compilation_context.AddTypeToTypedFileList(ctn); } br.ReadInt32();//comprehensive unit; ctn.attributes.AddRange(GetAttributes()); //common_namespace_node ns = cun.namespaces[0]; byte flag = br.ReadByte(); int def_prop_off=0; if (flag == 1) { def_prop_off = br.ReadInt32(); } location loc= ReadDebugInfo(); ctn.loc = loc; if (type_is_delegate) { SystemLibrary.SystemLibrary.type_constructor.AddOperatorsToDelegate(ctn, loc); } //создаем scope для класса //ctn = new wrapped_common_type_node(this, base_type, name, tal, ns, scope, loc, offset); //members[offset] = ctn; //AddMember(ctn, offset); class_names[ctn] = AddClassMemberNames(scope); if (flag == 1) ctn.default_property = GetPropertyNode(def_prop_off); //ivan if (ctn.IsEnum) { AddEnumOperators(ctn); MakeTypeAsOrdinal(ctn,0,class_names.Count); ctn.add_additional_enum_operations(); } if (ctn.type_special_kind == SemanticTree.type_special_kind.diap_type) { type_constructor.add_convertions_to_diap(ctn,low_val,upper_val); } if (ctn.type_special_kind == SemanticTree.type_special_kind.array_kind) { if (!(ctn.element_type is compiled_type_node)) { type_constructor.make_array_interface(ctn); } } //RestoreAllFields(ctn); if(!waited_types_to_restore_fields.Contains(ctn)) waited_types_to_restore_fields.Add(ctn); if (type_is_delegate) { SymbolInfo sim = ctn.find_in_type(compiler_string_consts.invoke_method_name); common_method_node invoke_method = sim.sym_info as common_method_node; sim = ctn.find_in_type(compiler_string_consts.default_constructor_name); common_method_node constructor = sim.sym_info as common_method_node; delegate_internal_interface dii = new delegate_internal_interface(invoke_method.return_value_type, invoke_method, constructor); dii.parameters.AddRange(invoke_method.parameters); ctn.add_internal_interface(dii); } /*if (ctn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.array_wrapper) { bounded_array_interface bai = new bounded_array_interface(oti_indexer, ctn.element_type, cpn, oti_indexer.lower_value.type, int_arr); ctn.add_internal_interface(bai); }*/ if (type_is_interface) { RestoreAllFields(ctn); } if (ctn.is_value) { RestoreAllFields(ctn); } if (ctn.is_generic_type_definition) { foreach (common_type_node par in ctn.generic_params) { SymbolInfo tsi = ctn.find_in_type(compiler_string_consts.generic_param_kind_prefix + par.name); if (tsi != null) { par.runtime_initialization_marker = tsi.sym_info as class_field; } } } /*if (ctn.type_special_kind == SemanticTree.type_special_kind.array_wrapper) { RestoreAllFields(ctn); }*/ return ctn; }
//Попытка вычислить типы после подстановки типов формальных параметров public static bool TryToDeduceTypesInLambda(function_lambda_definition lambda_syntax_node, delegate_internal_interface formal_delegate, type_node[] deduced, List<int> nils, out Exception exception_on_body_compilation) { var there_are_undeduced_params = false; var param_counter = 0; var visitor = SystemLibrary.SystemLibrary.syn_visitor; var result = true; exception_on_body_compilation = null; if (lambda_syntax_node.formal_parameters == null || lambda_syntax_node.formal_parameters.params_list == null || lambda_syntax_node.formal_parameters.params_list.Count == 0) { return false; } foreach (var t in lambda_syntax_node.formal_parameters.params_list) { var lambdaInfType = t.vars_type as lambda_inferred_type; if (lambdaInfType != null && lambdaInfType.real_type is lambda_any_type_node) { if (!CheckIfTypeDependsOnUndeducedGenericParameters(formal_delegate.parameters[param_counter].type, deduced)) //Если тип параметра не зависит от невыведенных дженерик-параметров, то можем вычислить этот тип явно { lambdaInfType.real_type = generic_convertions.determine_type(formal_delegate.parameters[param_counter].type, deduced.ToList(), true); //инстанцируем и записываем вычесленный тип } else { there_are_undeduced_params = true; //иначе мы не сможем вывести тип возвращаемого значения break; } } param_counter += t.idents.idents.Count; } if (!there_are_undeduced_params && lambda_syntax_node.return_type is lambda_inferred_type && ((lambda_inferred_type)lambda_syntax_node.return_type).real_type is lambda_any_type_node) { var lambdaName = lambda_syntax_node.lambda_name; var fl = lambda_syntax_node.lambda_visit_mode; lambda_syntax_node.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; var aux_name = LambdaHelper.GetAuxiliaryLambdaName(lambda_syntax_node.lambda_name); lambda_syntax_node.lambda_name = aux_name; try { visitor.visit(lambda_syntax_node); //пробуем скомпилировать тело лямбды, вычислим тип возвращаемого значения } catch (Exception exc) { exception_on_body_compilation = exc; // Если произошло исключение то запишем его в выходной параметр, оно потом будет обработано вызывающим методом result = false; } finally { var context = visitor.context; //Далее надо удалить ненужный узел из списка функций LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, lambda_syntax_node); lambda_syntax_node.lambda_name = lambdaName; lambda_syntax_node.lambda_visit_mode = fl; if (result) { if (!DeduceInstanceTypes(formal_delegate.return_value_type, (type_node)((lambda_inferred_type)lambda_syntax_node.return_type).real_type, deduced, nils)) //Выводим дженерик-параметры после того как вычислили тип возвращаемого значения { result = false; } } } } return result; }
public static void init_generic_instance(type_node original, generic_instance_type_node instance, /*SymbolTable.ClassScope instance_scope,*/ List<type_node> param_types) { instance.IsInterface = original.IsInterface; instance.is_class = original.is_class; instance.internal_is_value = original.is_value; instance.SetIsSealed(original.IsSealed); instance.IsDelegate = original.IsDelegate; instance.type_special_kind = original.type_special_kind; //Определяем базовый тип type_node btype = determine_type( original.base_type, param_types, false); instance.SetBaseTypeIgnoringScope(btype); //instance._scope = new SymbolTable.GenericTypeInstanceScope(instance, instance.original_generic.Scope, btype.Scope); foreach (type_node interf in original.ImplementingInterfaces) { instance.ImplementingInterfaces.Add( determine_type(interf, param_types, false) ); } SystemLibrary.SystemLibrary.init_reference_type(instance); instance.conform_basic_functions(); //(ssyy) Нужно, чтобы добавились конструкторы //ctnode.find_in_type(compiler_string_consts.default_constructor_name); instance.instance_params = param_types; property_node orig_pn = original.default_property_node; if (orig_pn != null) { if (orig_pn.comprehensive_type == original) { //Свойство по умолчанию описано в оригинальном коде generic-a; //конвертируем его instance.default_property = instance.ConvertMember(orig_pn) as common_property_node; } else { //Свойство по умолчанию описано в каком-то предке оригинального generic-a if (orig_pn.comprehensive_type.is_generic_type_definition) { instance.default_property = instance.find_instance_type_from(orig_pn.comprehensive_type).default_property; } } } var shouldAddToAllTypeInstances = true; if (LambdaHelper.processingLambdaParametersForTypeInference != 0) { foreach (var par in instance.generic_parameters) { if (par is lambda_any_type_node) { shouldAddToAllTypeInstances = false; break; } } } if (shouldAddToAllTypeInstances) //lroman// Если зашли сюда при выведении типов параметров лямбды, то тип инстанцироваться может с типом lambda_any_type_node. Поэтому, если выводим типы. То данную инстанцию не добавляем generic_convertions.all_type_instances.Add(instance); internal_interface ii = original.get_internal_interface(internal_interface_kind.delegate_interface); if (ii != null) { delegate_internal_interface dii = ii as delegate_internal_interface; common_method_node inv = instance.ConvertMember(dii.invoke_method) as common_method_node; common_method_node constr = instance.ConvertMember(dii.constructor) as common_method_node; constr.function_code = new runtime_statement(SemanticTree.runtime_statement_type.ctor_delegate, null); delegate_internal_interface converted_dii = new delegate_internal_interface(inv.return_value_type, inv, constr); converted_dii.parameters.AddRange(inv.parameters); instance.add_internal_interface(converted_dii); } }
public expression_node convert_delegates_to_delegates(location call_location, expression_node[] parameters) { if (parameters.Length != 1) { throw new PascalABCCompiler.TreeConverter.CompilerInternalError("Invalid delegates convertion"); } delegate_internal_interface dii_to = (delegate_internal_interface)_to.get_internal_interface(internal_interface_kind.delegate_interface); delegate_internal_interface dii = (delegate_internal_interface)parameters[0].type.get_internal_interface(internal_interface_kind.delegate_interface); expression_node pr = parameters[0]; base_function_call ifnotnull = null; if (_to.semantic_node_type == semantic_node_type.compiled_type_node) { ifnotnull = new compiled_constructor_call((compiled_constructor_node)dii_to.constructor, call_location); } else { ifnotnull = new common_constructor_call((common_method_node)dii_to.constructor, call_location); } //ccc = new common_constructor_call(dii_to.constructor, call_location); expression_node par = null; if (parameters[0].type.semantic_node_type == semantic_node_type.compiled_type_node) { par = new compiled_function_call((compiled_function_node)dii.invoke_method, parameters[0], call_location); } else { par = new common_method_call((common_method_node)dii.invoke_method, parameters[0], call_location); } ifnotnull.parameters.AddElement(par); null_const_node ncn = new null_const_node(_to, call_location); null_const_node ncn2 = new null_const_node(_to, call_location); PascalABCCompiler.TreeConverter.SymbolInfo si = pr.type.find_first_in_type(PascalABCCompiler.TreeConverter.compiler_string_consts.eq_name); basic_function_node fn = si.sym_info as basic_function_node; expression_node condition = null; if (fn != null) { basic_function_call condition_bfc = new basic_function_call(fn, call_location); condition_bfc.parameters.AddElement(pr); condition_bfc.parameters.AddElement(ncn); condition = condition_bfc; } else if (si.sym_info is compiled_function_node) { compiled_static_method_call condition_cfc = new compiled_static_method_call(si.sym_info as compiled_function_node, call_location); condition_cfc.parameters.AddElement(pr); condition_cfc.parameters.AddElement(ncn); condition = condition_cfc; } question_colon_expression qce = new question_colon_expression(condition, ncn2, ifnotnull, call_location); return(qce); }
//TODO: Возможно стоит если пересечение типов найдено в откомпилированных типах, добавлять к нашим структурам и не искать повторно. public static possible_type_convertions get_convertions(type_node from, type_node to, bool is_implicit) { possible_type_convertions ret = new possible_type_convertions(); ret.first = null; ret.second = null; if ((from == null) || (to == null)) { return(ret); } type_intersection_node tin_from = from.get_type_intersection(to); type_intersection_node tin_to = to.get_type_intersection(from); if (tin_from != null) { if (tin_from.this_to_another != null) { if ((!is_implicit) || (!(tin_from.this_to_another.is_explicit))) { add_conversion(ret, tin_from.this_to_another.convertion_method, from, to); } } } if (tin_to != null) { if (tin_to.another_to_this != null) { if ((!is_implicit) || (!(tin_to.another_to_this.is_explicit))) { add_conversion(ret, tin_to.another_to_this.convertion_method, from, to); } } } if (ret.second != null) { return(ret); } if (is_derived(to, from) || (from.IsInterface && to == SystemLibrary.SystemLibrary.object_type) || from.is_generic_type_instance && to == SystemLibrary.SystemLibrary.object_type) { add_conversion(ret, TreeConverter.convertion_data_and_alghoritms.get_empty_conversion(from, to, true), from, to); //add_conversion(ret, SystemLibrary.SystemLibrary.empty_method, from, to); } if (ret.second != null) { return(ret); } wrapped_type ctn_to = to as wrapped_type; wrapped_type ctn_from = from as wrapped_type; if (ctn_to != null) { function_node fnode1 = null; fnode1 = ctn_to.get_implicit_conversion_from(from); add_conversion(ret, fnode1, from, to); if (ret.second != null) { return(ret); } fnode1 = null; if (!is_implicit) { fnode1 = ctn_to.get_explicit_conversion_from(from); } add_conversion(ret, fnode1, from, to); if (ret.second != null) { return(ret); } } if (ctn_from != null) { function_node fnode2 = null; fnode2 = ctn_from.get_implicit_conversion_to(to); add_conversion(ret, fnode2, from, to); if (ret.second != null) { return(ret); } fnode2 = null; if (!is_implicit) { fnode2 = ctn_from.get_explicit_conversion_to(to); } add_conversion(ret, fnode2, from, to); if (ret.second != null) { return(ret); } } //TODO: Вот это должно быть в каком нибудь другом месте. internal_interface ii = from.get_internal_interface(internal_interface_kind.delegate_interface); if (ii != null) { delegate_internal_interface dii = (delegate_internal_interface)ii; internal_interface to_ii = to.get_internal_interface(internal_interface_kind.delegate_interface); if (to_ii != null) { delegate_internal_interface to_dii = (delegate_internal_interface)to_ii; if (dii.parameters.Count == to_dii.parameters.Count) { //ms100 error fixed (DS) bool eq = TreeConverter.convertion_data_and_alghoritms.function_eq_params_and_result(dii.invoke_method, to_dii.invoke_method); if (eq) { delegate_to_delegate_type_converter dtdtc = new delegate_to_delegate_type_converter(to); add_conversion(ret, new convert_types_function_node(dtdtc.convert_delegates_to_delegates, false), from, to); } } } if (dii.parameters.Count == 0) { if (dii.return_value_type == to) { add_conversion(ret, new convert_types_function_node(convert_delegate_to_return_value_type, true), from, to); } else { possible_type_convertions ptcc = get_convertions(dii.return_value_type, to); if ((ptcc.first != null) && (ptcc.first.convertion_method != null)) { delegate_type_converter dtc = new delegate_type_converter(ptcc.first.convertion_method); add_conversion(ret, new convert_types_function_node(dtc.convert_delegate_to_return_value_type_with_convertion, false), from, to); } if ((ptcc.second != null) && (ptcc.second.convertion_method != null)) { delegate_type_converter dtc = new delegate_type_converter(ptcc.second.convertion_method); add_conversion(ret, new convert_types_function_node(dtc.convert_delegate_to_return_value_type_with_convertion, false), from, to); } } } } return(ret); }
public void init_delegate(common_type_node ctn, type_node return_value_type, parameter_list parameters, location loc) { common_method_node constructor=new common_method_node(compiler_string_consts.default_constructor_name,null,loc,ctn,SemanticTree.polymorphic_state.ps_common, SemanticTree.field_access_level.fal_public, convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope)); constructor.is_constructor = true; constructor.return_value_type = ctn; constructor.function_code=new runtime_statement(SemanticTree.runtime_statement_type.ctor_delegate,loc); common_method_node invoke=new common_method_node(compiler_string_consts.invoke_method_name, return_value_type,loc,ctn,SemanticTree.polymorphic_state.ps_virtual, SemanticTree.field_access_level.fal_public, convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope)); ctn.add_name(compiler_string_consts.invoke_method_name,new SymbolInfo(invoke)); for (int i=0; i<parameters.Count; i++) { if (parameters[i] is compiled_parameter) { parameters[i] = new common_parameter(parameters[i].name,parameters[i].type,parameters[i].parameter_type,invoke,concrete_parameter_type.cpt_none,null,null); } } invoke.parameters.AddRange(parameters); invoke.function_code = new runtime_statement(SemanticTree.runtime_statement_type.invoke_delegate, loc); common_method_node begin_invoke = new common_method_node(compiler_string_consts.begin_invoke_method_name, begin_invoke_result_type, loc, ctn, SemanticTree.polymorphic_state.ps_virtual, SemanticTree.field_access_level.fal_public, convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope)); ctn.add_name(compiler_string_consts.begin_invoke_method_name,new SymbolInfo(begin_invoke)); parameter_list begin_invoke_params=new parameter_list(); begin_invoke_params.AddRange(parameters); common_parameter cp=new common_parameter(compiler_string_consts.callback_string,begin_invoke_parameter_type, SemanticTree.parameter_type.value,begin_invoke,concrete_parameter_type.cpt_none, null,loc); begin_invoke_params.AddElement(cp); cp = new common_parameter(compiler_string_consts.object_in_par_string, SystemLibrary.SystemLibrary.object_type, SemanticTree.parameter_type.value,begin_invoke, concrete_parameter_type.cpt_none, null, loc); begin_invoke_params.AddElement(cp); begin_invoke.parameters.AddRange(begin_invoke_params); begin_invoke.function_code = new runtime_statement(SemanticTree.runtime_statement_type.begin_invoke_delegate, loc); common_method_node end_invoke = new common_method_node(compiler_string_consts.end_invoke_method_name, return_value_type, loc, ctn, SemanticTree.polymorphic_state.ps_virtual, SemanticTree.field_access_level.fal_public, convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope)); ctn.add_name(compiler_string_consts.end_invoke_method_name,new SymbolInfo(end_invoke)); cp = new common_parameter(compiler_string_consts.result_string, begin_invoke_result_type, SemanticTree.parameter_type.value, end_invoke, concrete_parameter_type.cpt_none, null, loc); end_invoke.parameters.AddElement(cp); end_invoke.function_code = new runtime_statement(SemanticTree.runtime_statement_type.end_invoke_delegate, loc); ctn.methods.AddElement(constructor); ctn.methods.AddElement(invoke); ctn.methods.AddElement(begin_invoke); ctn.methods.AddElement(end_invoke); SystemLibrary.SystemLibrary.init_reference_type(ctn); delegate_internal_interface dii = new delegate_internal_interface(return_value_type, invoke, constructor); dii.parameters.AddRange(parameters); ctn.add_internal_interface(dii); AddOperatorsToDelegate(ctn, loc); }