//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)) { 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; }
private static type_intersection_node[] get_type_intersections(type_node left,type_node right) { type_intersection_node tin1=left.get_type_intersection(right); type_intersection_node tin2=right.get_type_intersection(left); if (tin1==null) { if (tin2==null) { return new type_intersection_node[0]; } else { type_intersection_node[] tinarr=new type_intersection_node[1]; type_intersection_node new_tin = new type_intersection_node(); new_tin.another_to_this = tin2.another_to_this; new_tin.this_to_another = tin2.this_to_another; if (tin2.type_compare == type_compare.greater_type) new_tin.type_compare = type_compare.less_type; else new_tin.type_compare = type_compare.greater_type; tinarr[0]= new_tin; return tinarr; } } else { if (tin2==null) { type_intersection_node[] tinarr2=new type_intersection_node[1]; tinarr2[0]=tin1; return tinarr2; } else { type_intersection_node[] tinarr3=new type_intersection_node[2]; tinarr3[0]=tin1; tinarr3[1]=tin2; return tinarr3; } } }
public static void add_type_conversion_from_defined(type_node from, type_node to, function_node convertion_method,type_compare comp,bool is_implicit,bool is_generated) { type_intersection_node tin=from.get_type_intersection(to); if (tin==null) { tin=new type_intersection_node(comp); from.add_intersection_node(to,tin,is_generated); } #if (DEBUG) else { if (tin.this_to_another!=null) { throw new PascalABCCompiler.TreeConverter.CompilerInternalError("Duplicate type conversion added"); } } #endif tin.this_to_another=new type_conversion(convertion_method,!is_implicit); }
private static type_intersection_node[] get_type_intersections_in_specific_order(type_node left,type_node right) { type_intersection_node tin1=left.get_type_intersection(right); type_intersection_node tin2=right.get_type_intersection(left); if (tin1==null) { if (tin2==null) { return new type_intersection_node[0]; } else { if (tin2.another_to_this != null && tin2.another_to_this.is_explicit) return new type_intersection_node[0]; type_intersection_node[] tinarr=new type_intersection_node[1]; type_intersection_node new_tin = null; if (tin2.type_compare == type_compare.greater_type) new_tin = new type_intersection_node(type_compare.less_type); else if (tin2.type_compare == type_compare.less_type) new_tin = new type_intersection_node(type_compare.greater_type); else new_tin = new type_intersection_node(type_compare.non_comparable_type); new_tin.another_to_this = tin2.another_to_this; new_tin.this_to_another = tin2.this_to_another; tinarr[0]=new_tin; return tinarr; } } else { if (tin2==null) { if (tin1.this_to_another != null && tin1.this_to_another.is_explicit) return new type_intersection_node[0]; type_intersection_node[] tinarr2=new type_intersection_node[1]; tinarr2[0]=tin1; return tinarr2; } else { type_intersection_node[] tinarr3=new type_intersection_node[2]; tinarr3[0]=tin1; tinarr3[1]=tin2; return tinarr3; } } }