cleanup and more tests
This commit is contained in:
parent
464dc794a8
commit
7d66f26d4f
|
|
@ -2351,15 +2351,15 @@ namespace PascalABCCompiler.SemanticTree
|
||||||
get;
|
get;
|
||||||
}
|
}
|
||||||
|
|
||||||
ITypeNode ElementType
|
ITypeNode ElementType
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsGeneric
|
bool IsGeneric
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface ILockStatement : IStatementNode, ILocated
|
public interface ILockStatement : IStatementNode, ILocated
|
||||||
|
|
|
||||||
20
TestSuite/errors/err0540_foreach_resolver.pas
Normal file
20
TestSuite/errors/err0540_foreach_resolver.pas
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
//!Невозможно выполнить оператор foreach или yield sequence по выражению типа c1
|
||||||
|
|
||||||
|
uses System.Collections, System.Collections.Generic;
|
||||||
|
|
||||||
|
type
|
||||||
|
c1 = class (IEnumerable<integer>, IEnumerable<string>)
|
||||||
|
public
|
||||||
|
function IEnumerable<string>.GetEnumerator: IEnumerator<string>;
|
||||||
|
begin end;
|
||||||
|
|
||||||
|
function IEnumerable<integer>.GetEnumerator: IEnumerator<integer>;
|
||||||
|
begin end;
|
||||||
|
|
||||||
|
function IEnumerable.GetEnumerator: IEnumerator;
|
||||||
|
begin end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
foreach var item in new c1 do ;
|
||||||
|
end.
|
||||||
67
TestSuite/foreach_resolver2.pas
Normal file
67
TestSuite/foreach_resolver2.pas
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
uses System.Collections, System.Collections.Generic;
|
||||||
|
|
||||||
|
type
|
||||||
|
c1 = class (IEnumerable<integer>)
|
||||||
|
public
|
||||||
|
|
||||||
|
function IEnumerable<integer>.GetEnumerator: IEnumerator<integer>;
|
||||||
|
begin
|
||||||
|
Assert(false);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GetEnumerator: IEnumerator;
|
||||||
|
begin
|
||||||
|
result:= Seq&<object>().GetEnumerator;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
c2<T1, T2> = class (IEnumerable<T2>)
|
||||||
|
public
|
||||||
|
function GetEnumerator: IEnumerator<T2>;
|
||||||
|
begin
|
||||||
|
result:= Seq&<T2>().GetEnumerator;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function IEnumerable.GetEnumerator: IEnumerator;
|
||||||
|
begin
|
||||||
|
Assert(false);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
c3 = class (IEnumerable<integer>, IEnumerable<string>)
|
||||||
|
public
|
||||||
|
function GetEnumerator: IEnumerator<string>;
|
||||||
|
begin
|
||||||
|
result:= Seq&<string>().GetEnumerator;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function IEnumerable<integer>.GetEnumerator: IEnumerator<integer>;
|
||||||
|
begin
|
||||||
|
Assert(false);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function IEnumerable.GetEnumerator: IEnumerator;
|
||||||
|
begin
|
||||||
|
Assert(false);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
c4 = class (c2<integer, int64>)
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
var v1:= new c1;
|
||||||
|
foreach var item in v1 do ;
|
||||||
|
|
||||||
|
var v2:= new c2<byte, string>;
|
||||||
|
foreach var item in v2 do ;
|
||||||
|
|
||||||
|
var v3:= new c3;
|
||||||
|
foreach var item in v3 do ;
|
||||||
|
|
||||||
|
var v4:= new c4;
|
||||||
|
foreach var item in v4 do ;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
@ -18577,7 +18577,7 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsIEnumerableInterface(ITypeNode t)
|
private bool IsIEnumerableInterface(type_node t)
|
||||||
{
|
{
|
||||||
compiled_type_node orig;
|
compiled_type_node orig;
|
||||||
|
|
||||||
|
|
@ -18594,7 +18594,7 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Собирает интерфейсы, реализованные типом и его предками
|
/// Собирает интерфейсы, реализованные типом и его предками
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private List<ITypeNode> CollectInterfacesFromTypeNode(type_node node)
|
private List<type_node> CollectInterfacesFromTypeNode(type_node node)
|
||||||
{
|
{
|
||||||
var result = new List<ITypeNode>();
|
var result = new List<ITypeNode>();
|
||||||
result.AddRange(node.ImplementingInterfaces);
|
result.AddRange(node.ImplementingInterfaces);
|
||||||
|
|
@ -18605,7 +18605,7 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
result.AddRange(interfInBase);
|
result.AddRange(interfInBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result.Cast<type_node>().ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsIEnumeratorInterface(type_node t)
|
private bool IsIEnumeratorInterface(type_node t)
|
||||||
|
|
@ -18629,7 +18629,6 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
|
|
||||||
var filteredInterfaces = CollectInterfacesFromTypeNode(node)
|
var filteredInterfaces = CollectInterfacesFromTypeNode(node)
|
||||||
.Where(item => IsIEnumerableInterface(item))
|
.Where(item => IsIEnumerableInterface(item))
|
||||||
.Cast<type_node>()
|
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
var genericInterfaceCount = filteredInterfaces.Count(item => item.is_generic_type_instance);
|
var genericInterfaceCount = filteredInterfaces.Count(item => item.is_generic_type_instance);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue