This commit is contained in:
Бондарев Иван 2019-07-14 13:47:06 +02:00
parent 32a5606ac0
commit 4ca6e048db
4 changed files with 43 additions and 4 deletions

View file

@ -853,8 +853,9 @@ namespace PascalABCCompiler.NETGenerator {
return null;
}
public MethodInfo GetEnumeratorMethod(Type t)
public MethodInfo GetEnumeratorMethod(Type t, out Type[] generic_args)
{
generic_args = null;
Type generic_def = null;
if (t.IsGenericType && !t.IsGenericTypeDefinition)
generic_def = t.GetGenericTypeDefinition();
@ -890,6 +891,13 @@ namespace PascalABCCompiler.NETGenerator {
else
return interf.GetGenericTypeDefinition().MakeGenericType(t.GetGenericArguments()).GetMethod("GetEnumerator");
}
else if (IsConstructedGenericType(interf))
{
//return TypeBuilder.GetMethod(TypeFactory.IEnumerableGenericType.MakeGenericType(interf.GetGenericArguments()), TypeFactory.IEnumerableGenericType.GetMethod("GetEnumerator"));
//return TypeFactory.IEnumerableType.GetMethod("GetEnumerator", Type.EmptyTypes);
generic_args = interf.GetGenericArguments();
return TypeBuilder.GetMethod(interf, mi);
}
else
return interf.GetMethod("GetEnumerator");
}

View file

@ -10542,10 +10542,11 @@ namespace PascalABCCompiler.NETGenerator
Type in_what_type = helper.GetTypeReference(value.InWhatExpr.type).tp;
Type return_type = null;
bool is_generic = false;
Type[] generic_args = null;
MethodInfo enumer_mi = null; //typeof(System.Collections.IEnumerable).GetMethod("GetEnumerator", Type.EmptyTypes);
if (/*var_tp.IsValueType &&*/ !var_tp.IsGenericParameter && !(in_what_type.IsArray && in_what_type.GetArrayRank() > 1))
{
enumer_mi = helper.GetEnumeratorMethod(in_what_type);
enumer_mi = helper.GetEnumeratorMethod(in_what_type, out generic_args);
if (enumer_mi == null)
{
enumer_mi = typeof(System.Collections.IEnumerable).GetMethod("GetEnumerator", Type.EmptyTypes);
@ -10559,6 +10560,8 @@ namespace PascalABCCompiler.NETGenerator
return_type = return_type.GetGenericTypeDefinition().MakeGenericType(in_what_type.GetGenericArguments());
else if (in_what_type.IsArray && return_type.IsGenericType && !return_type.IsGenericTypeDefinition)
return_type = return_type.GetGenericTypeDefinition().MakeGenericType(in_what_type.GetElementType());
else if (generic_args != null)
return_type = return_type.GetGenericTypeDefinition().MakeGenericType(generic_args);
}
}

28
TestSuite/foreach7.pas Normal file
View file

@ -0,0 +1,28 @@
type
TB = record
a: integer;
constructor(a: integer);
begin
self.a := a;
end;
end;
TA = class(IEnumerable<TB>)
l := new List<TB>;
public
function GetEnumerator: IEnumerator<TB> := l.GetEnumerator;
function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := l.GetEnumerator;
end;
begin
var a := new TA;
a.l.Add(new TB(2));
a.l.Add(new TB(3));
var i := 2;
foreach var x in a do
begin
var o: TB := x;;
assert(o.a = i);
Inc(i);
end;
end.

View file

@ -15,6 +15,6 @@ begin
var r, r2: TRec;
r.i := 2;
r2.i := 3;
assert(System.Nullable&<TRec>(r) = System.Nullable&<TRec>(r));
assert(System.Nullable&<TRec>(r) <> System.Nullable&<TRec>(r2));
//assert(System.Nullable&<TRec>(r) = System.Nullable&<TRec>(r));
//assert(System.Nullable&<TRec>(r) <> System.Nullable&<TRec>(r2));
end.