bug fix #709
This commit is contained in:
Бондарев Иван 2018-03-11 17:47:53 +01:00
parent d7811599f6
commit d471e79465
4 changed files with 42 additions and 4 deletions

View file

@ -512,6 +512,7 @@ namespace PascalABCCompiler.NETGenerator {
public class Helper { public class Helper {
private Hashtable defs=new Hashtable(); private Hashtable defs=new Hashtable();
private Hashtable processing_types = new Hashtable();
private MethodInfo arr_mi=null; private MethodInfo arr_mi=null;
private Hashtable pas_defs = new Hashtable(); private Hashtable pas_defs = new Hashtable();
@ -852,6 +853,16 @@ namespace PascalABCCompiler.NETGenerator {
return TypeFactory.IEnumerableType.GetMethod("GetEnumerator", Type.EmptyTypes); 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) public TypeInfo GetTypeReference(ITypeNode type)
{ {

View file

@ -403,6 +403,8 @@ namespace PascalABCCompiler.NETGenerator
private void AddTypeInstanceToFunction(ICommonFunctionNode func, IGenericTypeInstance gti) private void AddTypeInstanceToFunction(ICommonFunctionNode func, IGenericTypeInstance gti)
{ {
if (func == null)
return;
List<IGenericTypeInstance> instances; List<IGenericTypeInstance> instances;
//if (func == null) // SSM 3.07.16 Это решает проблему с оставшимся после перевода в сем. дерево узлом IEnumerable<UnknownType>, но очень грубо - пробую найти ошибку раньше //if (func == null) // SSM 3.07.16 Это решает проблему с оставшимся после перевода в сем. дерево узлом IEnumerable<UnknownType>, но очень грубо - пробую найти ошибку раньше
// return; // 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) if (t.is_generic_parameter)
{ {
//ConvertTypeHeaderInSpecialOrder(t.generic_container); //ConvertTypeHeaderInSpecialOrder(t.generic_container);
@ -1222,12 +1225,15 @@ namespace PascalABCCompiler.NETGenerator
{ {
if (gti.original_generic is ICommonTypeNode) if (gti.original_generic is ICommonTypeNode)
{ {
ConvertTypeHeaderInSpecialOrder((ICommonTypeNode)gti.original_generic); ConvertTypeHeaderInSpecialOrder((ICommonTypeNode)gti.original_generic);
} }
foreach (ITypeNode itn in gti.generic_parameters) 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); ConvertTypeHeaderInSpecialOrder((ICommonTypeNode)itn);
} }
} }

21
TestSuite/generics14.pas Normal file
View file

@ -0,0 +1,21 @@
type
I1<T> = interface
end;
T1<T> = class(I1<T1<T>>)//нужно использовать T1<T> как тип для шаблона, I1<I1<T1<T>>> тоже сработает
i: T;
constructor(i: T);
begin
self.i := i;
end;
procedure p1;
begin
var o:object := self;//Нельзя преобразовать тип T1<T> к object
end;
end;
begin
var o: T1<integer> := new T1<integer>(2);
o.p1;
assert(o.i = 2);
end.

View file

@ -864,7 +864,7 @@ namespace PascalABCCompiler.TreeRealization
return ret; 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, TreeConverter.convertion_data_and_alghoritms.get_empty_conversion(from, to, true), from, to);
//add_conversion(ret, SystemLibrary.SystemLibrary.empty_method, from, to); //add_conversion(ret, SystemLibrary.SystemLibrary.empty_method, from, to);