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); } } }
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); }
//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); }