From d471e7946500ad1c0aef393372daf578707ec35a 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, 11 Mar 2018 17:47:53 +0100 Subject: [PATCH] bug fix #700 bug fix #709 --- NETGenerator/Helpers.cs | 11 +++++++++++ NETGenerator/NETGenerator.cs | 12 +++++++++--- TestSuite/generics14.pas | 21 +++++++++++++++++++++ TreeConverter/TreeRealization/type_table.cs | 2 +- 4 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 TestSuite/generics14.pas diff --git a/NETGenerator/Helpers.cs b/NETGenerator/Helpers.cs index 214d1a0a9..7511660c4 100644 --- a/NETGenerator/Helpers.cs +++ b/NETGenerator/Helpers.cs @@ -512,6 +512,7 @@ namespace PascalABCCompiler.NETGenerator { public class Helper { private Hashtable defs=new Hashtable(); + private Hashtable processing_types = new Hashtable(); private MethodInfo arr_mi=null; private Hashtable pas_defs = new Hashtable(); @@ -852,6 +853,16 @@ namespace PascalABCCompiler.NETGenerator { return TypeFactory.IEnumerableType.GetMethod("GetEnumerator", Type.EmptyTypes); } + public void SetAsProcessing(ICommonTypeNode type) + { + processing_types[type] = true; + } + + public bool IsProcessing(ICommonTypeNode type) + { + return processing_types[type] != null; + } + //получение типа public TypeInfo GetTypeReference(ITypeNode type) { diff --git a/NETGenerator/NETGenerator.cs b/NETGenerator/NETGenerator.cs index 0d7756ae6..96539a336 100644 --- a/NETGenerator/NETGenerator.cs +++ b/NETGenerator/NETGenerator.cs @@ -403,6 +403,8 @@ namespace PascalABCCompiler.NETGenerator private void AddTypeInstanceToFunction(ICommonFunctionNode func, IGenericTypeInstance gti) { + if (func == null) + return; List instances; //if (func == null) // SSM 3.07.16 Это решает проблему с оставшимся после перевода в сем. дерево узлом IEnumerable, но очень грубо - пробую найти ошибку раньше // return; @@ -1205,8 +1207,9 @@ namespace PascalABCCompiler.NETGenerator } } - if (helper.GetTypeReference(t) != null && !t.is_generic_parameter) return; - + if (helper.GetTypeReference(t) != null && !t.is_generic_parameter) + return; + helper.SetAsProcessing(t); if (t.is_generic_parameter) { //ConvertTypeHeaderInSpecialOrder(t.generic_container); @@ -1222,12 +1225,15 @@ namespace PascalABCCompiler.NETGenerator { if (gti.original_generic is ICommonTypeNode) { + ConvertTypeHeaderInSpecialOrder((ICommonTypeNode)gti.original_generic); } + foreach (ITypeNode itn in gti.generic_parameters) { - if (itn is ICommonTypeNode && !itn.is_generic_parameter) + if (itn is ICommonTypeNode && !itn.is_generic_parameter && !helper.IsProcessing(itn as ICommonTypeNode)) { + ConvertTypeHeaderInSpecialOrder((ICommonTypeNode)itn); } } diff --git a/TestSuite/generics14.pas b/TestSuite/generics14.pas new file mode 100644 index 000000000..e333b32da --- /dev/null +++ b/TestSuite/generics14.pas @@ -0,0 +1,21 @@ +type + I1 = interface + end; + + T1 = class(I1>)//нужно использовать T1 как тип для шаблона, I1>> тоже сработает + i: T; + constructor(i: T); + begin + self.i := i; + end; + procedure p1; + begin + var o:object := self;//Нельзя преобразовать тип T1 к object + end; + end; + +begin + var o: T1 := new T1(2); + o.p1; + assert(o.i = 2); +end. \ No newline at end of file diff --git a/TreeConverter/TreeRealization/type_table.cs b/TreeConverter/TreeRealization/type_table.cs index 80c7eda42..518691c93 100644 --- a/TreeConverter/TreeRealization/type_table.cs +++ b/TreeConverter/TreeRealization/type_table.cs @@ -864,7 +864,7 @@ namespace PascalABCCompiler.TreeRealization return ret; } - if (is_derived(to, from) || (from.IsInterface && to == SystemLibrary.SystemLibrary.object_type)) + 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);