From 56a02897d4ef2e277edfa45e899efa5b8c9f3aac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=BE=D0=BD=D0=B4=D0=B0=D1=80=D0=B5=D0=B2=20=D0=98?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD?= Date: Sun, 13 Mar 2016 12:27:05 +0100 Subject: [PATCH] bug fix issue #108 --- TestSuite/implicitexplicit3.pas | 39 +++ TreeConverter/TreeRealization/type_table.cs | 281 -------------------- TreeConverter/TreeRealization/types.cs | 45 +++- VisualPascalABCNET/Program.cs | 20 +- 4 files changed, 88 insertions(+), 297 deletions(-) create mode 100644 TestSuite/implicitexplicit3.pas diff --git a/TestSuite/implicitexplicit3.pas b/TestSuite/implicitexplicit3.pas new file mode 100644 index 000000000..4c934fb37 --- /dev/null +++ b/TestSuite/implicitexplicit3.pas @@ -0,0 +1,39 @@ +function operator implicit(f: System.Func): System.Action; extensionmethod; +begin + Result := procedure()->f(); +end; + +function operator implicit(f: System.Func): System.Func; extensionmethod; +begin + Result := ()->f(default(T)); +end; + +function operator implicit(f: System.Action): System.Func; extensionmethod; +begin + Result := ()->begin f(); Result := default(T) end; +end; + +var i: integer; + +function ff(): integer; +begin + i := 2; +end; + +function ff2(j: integer): integer; +begin + i := 3; +end; + +begin + var fff: System.Func := ff; + var a: System.Action := fff; + a; + assert(i=2); + fff := a; + assert(fff() = 0); + var fff2: System.Func := ff2; + fff := fff2; + fff(); + assert(i=3); +end. \ No newline at end of file diff --git a/TreeConverter/TreeRealization/type_table.cs b/TreeConverter/TreeRealization/type_table.cs index fe3cb839c..114ccc107 100644 --- a/TreeConverter/TreeRealization/type_table.cs +++ b/TreeConverter/TreeRealization/type_table.cs @@ -166,16 +166,6 @@ namespace PascalABCCompiler.TreeRealization 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]; - /*type_intersection_node new_tin = null; - if (tin1.type_compare == type_compare.greater_type) - new_tin = new type_intersection_node(type_compare.less_type); - else if (tin1.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 = tin1.another_to_this; - new_tin.this_to_another = tin1.this_to_another; - tinarr2[0]=new_tin;*/ tinarr2[0]=tin1; return tinarr2; } @@ -233,19 +223,6 @@ namespace PascalABCCompiler.TreeRealization } } - //(ssyy) Это не используется - я закомментировал. - /*private static void add_type_intersection(type_node left,type_node right,type_intersection_node intersection) - { - left.add_intersection_node(right,intersection); - }*/ - - //(ssyy) Это не используется - я закомментировал. - /*public static void add_type_conversion_from_defined(type_node from, type_node to, - function_node convertion_method, type_compare comp) - { - add_type_conversion_from_defined(from, to, convertion_method, comp, true); - }*/ - public static void add_type_conversion_from_defined(type_node from, type_node to, function_node convertion_method, type_compare comp, bool is_implicit) { @@ -276,47 +253,6 @@ namespace PascalABCCompiler.TreeRealization #endif tin.this_to_another=new type_conversion(convertion_method,!is_implicit); } - - //(ssyy) Это не используется - я закомментировал. - /*public static void add_type_conversion_to_defined(type_node from, type_node to, - function_node convertion_method, type_compare comp) - { - add_type_conversion_to_defined(from, to, convertion_method, comp, true); - }*/ - - //(ssyy) Это не используется - я закомментировал. - /*public static void add_type_conversion_to_defined(type_node from,type_node to, - function_node convertion_method,type_compare comp,bool is_implicit) - { - type_intersection_node tin=to.get_type_intersection(from); - if (tin==null) - { - tin=new type_intersection_node(comp); - to.add_intersection_node(from,tin); - } -#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); - }*/ - - //(ssyy) Это не используется - я закомментировал. - /*public static void add_type_conversion_from_defined(type_node from,type_node to,function_node convertion_method) - { - add_type_conversion_from_defined(from,to,convertion_method,type_compare.non_comparable_type); - }*/ - - //(ssyy) Это не используется - я закомментировал. - /*public static void add_type_conversion_to_defined(type_node from,type_node to,function_node convertion_method) - { - add_type_conversion_to_defined(from,to,convertion_method,type_compare.non_comparable_type); - }*/ public static bool is_with_nil_allowed(type_node tn) { @@ -380,7 +316,6 @@ namespace PascalABCCompiler.TreeRealization //Добавляет интерфейс и всех его предков в список реализуемых данным классом. public static void AddInterface(common_type_node cnode, type_node _interface, location loc) { - //if (_interface == cnode) if (original_types_equals(_interface, cnode)) throw new TreeConverter.UndefinedNameReference(_interface.name, loc); if (!_interface.IsInterface) @@ -417,11 +352,6 @@ namespace PascalABCCompiler.TreeRealization return true; else return false; - /*if (base_class.semantic_node_type == semantic_node_type.null_type_node) - if (!derived_class.is_value || derived_class.IsPointer) - return true; - else if (!is_with_nil_allowed(derived_class)) return false; - else return true;*/ if (base_class.type_special_kind == SemanticTree.type_special_kind.short_string && derived_class.type_special_kind == SemanticTree.type_special_kind.short_string) return true; else if (derived_class == SystemLibrary.SystemLibrary.string_type && base_class.type_special_kind == SemanticTree.type_special_kind.short_string) return true; else if (base_class == SystemLibrary.SystemLibrary.string_type && derived_class.type_special_kind == SemanticTree.type_special_kind.short_string) return true; @@ -592,8 +522,6 @@ namespace PascalABCCompiler.TreeRealization return !tin.this_to_another.is_explicit; } } - // if (base_class is common_type_node && (base_class as common_type_node).IsEnum && derived_class == SystemLibrary.SystemLibrary.integer_type) - // return true; //ssyy Рассматриваем случай интерфейса if (base_class.IsInterface) { @@ -605,21 +533,8 @@ namespace PascalABCCompiler.TreeRealization tnode = tnode.base_type; } return implements; - //return derived_class.ImplementingInterfaces.Contains(base_class); } //\ssyy - /*if (base_class.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type) - { - if (derived_class.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type) - return is_derived(base_class.base_type,derived_class.base_type); - else return is_derived(base_class.base_type,derived_class); - } - else if (derived_class.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type) - { - //if (derived_class.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type) - return is_derived(base_class,derived_class.base_type); - //else return is_derived(base_class.base_type,derived_class); - }*/ if (base_class.type_special_kind == SemanticTree.type_special_kind.diap_type && derived_class.type_special_kind == SemanticTree.type_special_kind.diap_type) { @@ -633,103 +548,7 @@ namespace PascalABCCompiler.TreeRealization } return !tin.this_to_another.is_explicit; } - else if (base_class.type_special_kind != SemanticTree.type_special_kind.diap_type && derived_class.type_special_kind == SemanticTree.type_special_kind.diap_type) - { - /*if (base_class == derived_class.base_type) return true; - type_compare tc = get_table_type_compare(base_class,derived_class.base_type); - if (tc == type_compare.non_comparable_type) return false; - type_intersection_node tin = base_class.get_type_intersection(derived_class.base_type); - if (tin == null || tin.this_to_another == null) - { - if ((base_class == SystemLibrary.SystemLibrary.real_type || base_class == SystemLibrary.SystemLibrary.float_type) && derived_class.base_type != SystemLibrary.SystemLibrary.char_type) - { - return true; - } - else if (base_class == SystemLibrary.SystemLibrary.string_type && derived_class.base_type == SystemLibrary.SystemLibrary.char_type) - { - return true; - } - //else if (base_class == SystemLibrary.SystemLibrary.char_type) return - return false; - } - return true;*///!tin.this_to_another.is_explicit; - } - else if (base_class.type_special_kind == SemanticTree.type_special_kind.diap_type && derived_class.type_special_kind != SemanticTree.type_special_kind.diap_type) - { - /*if (base_class.base_type == derived_class) return true; - type_compare tc = get_table_type_compare(base_class.base_type,derived_class); - if (tc == type_compare.non_comparable_type) return false; - type_intersection_node tin = base_class.base_type.get_type_intersection(derived_class); - if (tin == null || tin.this_to_another == null) - { - return false; - } - return true;*/// !tin.this_to_another.is_explicit; - } -// if (base_class.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type) -// { -//// if (derived_class.type_special_kind != PascalABCCompiler.SemanticTree.type_special_kind.diap_type) -//// { -//// if (base_class.base_type == derived_class) return true; -//// return get_table_type_compare(base_class.base_type,derived_class) == type_compare.greater_type || get_table_type_compare(base_class.base_type,derived_class) == type_compare.less_type ; -//// } -//// else -//// { -//// if (base_class.base_type == derived_class.base_type) return true; -//// return get_table_type_compare(base_class.base_type,derived_class.base_type) == type_compare.greater_type || get_table_type_compare(base_class.base_type,derived_class.base_type) == type_compare.less_type; -//// } -// if (derived_class.type_special_kind != PascalABCCompiler.SemanticTree.type_special_kind.diap_type) -// { -// if (base_class.base_type == derived_class) return true; -// if (base_class.base_type != SystemLibrary.SystemLibrary.bool_type && base_class.base_type != SystemLibrary.SystemLibrary.char_type) -// { -// if (derived_class == SystemLibrary.SystemLibrary.integer_type || derived_class == SystemLibrary.SystemLibrary.byte_type //|| derived_class == SystemLibrary.SystemLibrary.sbyte_type -// || derived_class == SystemLibrary.SystemLibrary.short_type || derived_class == SystemLibrary.SystemLibrary.ushort_type || derived_class == SystemLibrary.SystemLibrary.uint_type -// || derived_class == SystemLibrary.SystemLibrary.long_type || derived_class == SystemLibrary.SystemLibrary.ulong_type) -// return true; -// } -// else -// return get_table_type_compare(base_class,derived_class.base_type) == type_compare.less_type || get_table_type_compare(base_class,derived_class.base_type) == type_compare.greater_type; -// } -// else -// { -// if (base_class.base_type == derived_class.base_type) return true; -// return is_derived(base_class.base_type,derived_class); -// } -// } -// else if (derived_class.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type) -// { -// if (base_class.type_special_kind != PascalABCCompiler.SemanticTree.type_special_kind.diap_type) -// { -// if (base_class == derived_class.base_type) return true; -// if (base_class == SystemLibrary.SystemLibrary.bool_type || base_class == SystemLibrary.SystemLibrary.sbyte_type) return false; -// else if (derived_class.base_type != SystemLibrary.SystemLibrary.bool_type && derived_class.base_type != SystemLibrary.SystemLibrary.char_type) -// { -// if (base_class == SystemLibrary.SystemLibrary.integer_type || base_class == SystemLibrary.SystemLibrary.byte_type //|| base_class == SystemLibrary.SystemLibrary.sbyte_type -// || base_class == SystemLibrary.SystemLibrary.short_type || base_class == SystemLibrary.SystemLibrary.ushort_type || base_class == SystemLibrary.SystemLibrary.uint_type -// || base_class == SystemLibrary.SystemLibrary.long_type || base_class == SystemLibrary.SystemLibrary.ulong_type) -// return true; -// } -// else -// return get_table_type_compare(base_class,derived_class.base_type) == type_compare.less_type || get_table_type_compare(base_class,derived_class.base_type) == type_compare.greater_type; -// } -// else -// { -// if (base_class.base_type == derived_class.base_type) return true; -//// if (base_class.base_type == SystemLibrary.SystemLibrary.bool_type || base_class.base_type == SystemLibrary.SystemLibrary.sbyte_type) return false; -//// else if (base_class.base_type != SystemLibrary.SystemLibrary.bool_type && base_class.base_type != SystemLibrary.SystemLibrary.char_type) -//// { -//// if (base_class == SystemLibrary.SystemLibrary.integer_type || base_class == SystemLibrary.SystemLibrary.byte_type || base_class == SystemLibrary.SystemLibrary.sbyte_type -//// || base_class == SystemLibrary.SystemLibrary.short_type || base_class == SystemLibrary.SystemLibrary.ushort_type || base_class == SystemLibrary.SystemLibrary.uint_type -//// || base_class == SystemLibrary.SystemLibrary.long_type || base_class == SystemLibrary.SystemLibrary.ulong_type) -//// return true; -//// } -//// else -// return is_derived(base_class.base_type,derived_class); -// //return get_table_type_compare(base_class.base_type,derived_class.base_type) == type_compare.less_type || get_table_type_compare(base_class.base_type,derived_class.base_type) == type_compare.greater_type; -// } -// } while((tn!=null)&&(tn!=base_class)) { tn=tn.base_type; @@ -820,10 +639,6 @@ namespace PascalABCCompiler.TreeRealization { return type_compare.less_type; } - /*if (left.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type || right.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type) - { - return type_compare.less_type; - }*/ return type_compare.non_comparable_type; } @@ -842,29 +657,9 @@ namespace PascalABCCompiler.TreeRealization { return type_compare.less_type; } - /*if (left.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type || right.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type) - { - return type_compare.less_type; - }*/ return type_compare.non_comparable_type; } - /* - public static void add_explicit_type_conversion(type_node from, type_node to, function_node conversion_method) - { - //В этом методе преобразование типа добавляется только в один из них. - //Возможно следует сделать пару методов, для добавления преобразования к типу из которого мы преобразуем - //и для добавления преобразования типа к которому мы преобразуем. - to.add_explicit_type_conversion(from, conversion_method); - } - - public static function_node get_explicit_type_conversion(type_node from,type_node to) - { - //Возможно этот метод должен возвращать possible_type_conversions. - return to.get_explicit_type_conversion(from); - } - */ - private static void add_conversion(possible_type_convertions ptc, function_node fn,type_node from,type_node to) { if (fn==null) @@ -883,66 +678,6 @@ namespace PascalABCCompiler.TreeRealization ptc.to = to; } - /* - if (ctn_to != null) - { - function_node ccfn2 = ctn_to.get_implicit_conversion_from(from); - if (ccfn2 != null) - { - if (ret.first == null) - { - ret.first = new type_conversion(ccfn2); - } - else - { - ret.second = new type_conversion(ccfn2); - } - } - else - { - ccfn2 = ctn_from.get_implicit_conversion_to(to); - if (ccfn2 != null) - { - if (ret.first == null) - { - ret.first = new type_conversion(ccfn2); - } - else - { - ret.second = new type_conversion(ccfn2); - } - } - } - } - else - { - function_node ccfn2 = ctn_from.get_implicit_conversion_to(to); - if (ccfn2 != null) - { - if (ret.first == null) - { - ret.first = new type_conversion(ccfn2); - } - else - { - ret.second = new type_conversion(ccfn2); - } - } - else - { - ccfn2 = ctn_to.get_implicit_conversion_from(from); - if (ret.first == null) - { - ret.first = new type_conversion(ccfn2); - } - else - { - ret.second = new type_conversion(ccfn2); - } - } - } - */ - public static expression_node convert_delegate_to_return_value_type(location call_location, params expression_node[] parameters) { expression_node par=parameters[0]; @@ -1157,15 +892,6 @@ namespace PascalABCCompiler.TreeRealization //TODO: Вот это должно быть в каком нибудь другом месте. internal_interface ii = from.get_internal_interface(internal_interface_kind.delegate_interface); -// if (ii == null) -// { -// delegate_methods dels = ctn_from as delegated_methods; -// if (dels != null && (ctn_to is compiled_type_node) && (ctn_to as compiled_type_node).compiled_type == NetHelper.NetHelper.DelegateType) -// { -// PascalABCCompiler.TreeConverter.type_constructor.instance.create_delegate(); -// } -// } -// else if (ii != null) { delegate_internal_interface dii = (delegate_internal_interface)ii; @@ -1178,13 +904,6 @@ namespace PascalABCCompiler.TreeRealization { //ms100 error fixed (DS) bool eq = TreeConverter.convertion_data_and_alghoritms.function_eq_params_and_result(dii.invoke_method, to_dii.invoke_method); - /*bool eq = true; - int i = 0; - while ((eq)&&(i instance_params1 = this.instance_params; + List instance_params2 = cctn.instance_params; + compiled_type_node orig_generic = this; + if (this.is_generic_type_instance) + orig_generic = compiled_type_node.get_type_node(_compiled_type.GetGenericTypeDefinition()); + compiled_type_node orig_generic2 = cctn; + if (cctn.is_generic_type_instance) + orig_generic2 = compiled_type_node.get_type_node(cctn.compiled_type.GetGenericTypeDefinition()); fn = NetHelper.NetHelper.get_implicit_conversion(orig_generic, orig_generic, orig_generic2, orig_generic.scope); if (fn != null) { - //fn = fn.get_instance(this.ge) - _implicit_convertions_to.Add(cctn, fn); + List instance_params; + if (instance_params1.Count > 0) + instance_params = instance_params1; + else + instance_params = instance_params2; + fn = fn.get_instance(instance_params, false, null); + return fn; } - }*/ + } } return fn; @@ -3432,6 +3443,28 @@ namespace PascalABCCompiler.TreeRealization fn = NetHelper.NetHelper.get_implicit_conversion(this, cctn, this, scope); if (fn is compiled_function_node) _implicit_convertions_from.Add(cctn, fn); + else if (fn == null && (cctn.is_generic_type_instance || this.is_generic_type_instance)) + { + List instance_params1 = this.instance_params; + List instance_params2 = cctn.instance_params; + compiled_type_node orig_generic = cctn; + if (cctn.is_generic_type_instance) + orig_generic = compiled_type_node.get_type_node(cctn.compiled_type.GetGenericTypeDefinition()); + compiled_type_node orig_generic2 = this; + if (this.is_generic_type_instance) + orig_generic2 = compiled_type_node.get_type_node(this.compiled_type.GetGenericTypeDefinition()); + fn = NetHelper.NetHelper.get_implicit_conversion(orig_generic2, orig_generic, orig_generic2, orig_generic2.scope); + if (fn != null) + { + List instance_params; + if (instance_params1.Count > 0) + instance_params = instance_params1; + else + instance_params = instance_params2; + fn = fn.get_instance(instance_params, false, null); + return fn; + } + } } return fn; } diff --git a/VisualPascalABCNET/Program.cs b/VisualPascalABCNET/Program.cs index 9c5be0930..2f12c0713 100644 --- a/VisualPascalABCNET/Program.cs +++ b/VisualPascalABCNET/Program.cs @@ -67,9 +67,9 @@ namespace VisualPascalABC ShowWindow(handle, 3/*SW_MAXIMIZE*/); else if (IsIconic(handle) != 0) - ShowWindow(handle, 9/*SW_RESTORE*/); - else - ShowWindow(handle, 5/*SW_SHOW*/); + ShowWindow(handle, 9/*SW_RESTORE*/); + else + ShowWindow(handle, 5/*SW_SHOW*/); if (args.Length > 0) { //for (int j = 0; j < args.Length; j++) @@ -94,16 +94,16 @@ namespace VisualPascalABC catch { - } + } try { - if (Environment.OSVersion.Version.Major >= 6) SetProcessDPIAware(); - CommandLineArgs = args; - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - MainForm = new Form1(); - Application.Run(MainForm); + if (Environment.OSVersion.Version.Major >= 6) SetProcessDPIAware(); + CommandLineArgs = args; + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + MainForm = new Form1(); + Application.Run(MainForm); } catch (Exception e) {