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 {
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)
{

View file

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

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