diff --git a/SemanticTree/SemanticTree.cs b/SemanticTree/SemanticTree.cs index 5095460d1..94ccc68ff 100644 --- a/SemanticTree/SemanticTree.cs +++ b/SemanticTree/SemanticTree.cs @@ -2351,15 +2351,15 @@ namespace PascalABCCompiler.SemanticTree get; } - ITypeNode ElementType - { - get; - } + ITypeNode ElementType + { + get; + } - bool IsGeneric - { - get; - } + bool IsGeneric + { + get; + } } public interface ILockStatement : IStatementNode, ILocated diff --git a/TestSuite/errors/err0540_foreach_resolver.pas b/TestSuite/errors/err0540_foreach_resolver.pas new file mode 100644 index 000000000..f57f7c1b2 --- /dev/null +++ b/TestSuite/errors/err0540_foreach_resolver.pas @@ -0,0 +1,20 @@ +//!Невозможно выполнить оператор foreach или yield sequence по выражению типа c1 + +uses System.Collections, System.Collections.Generic; + +type + c1 = class (IEnumerable, IEnumerable) + public + function IEnumerable.GetEnumerator: IEnumerator; + begin end; + + function IEnumerable.GetEnumerator: IEnumerator; + begin end; + + function IEnumerable.GetEnumerator: IEnumerator; + begin end; + end; + +begin + foreach var item in new c1 do ; +end. \ No newline at end of file diff --git a/TestSuite/foreach_resolver2.pas b/TestSuite/foreach_resolver2.pas new file mode 100644 index 000000000..70333207e --- /dev/null +++ b/TestSuite/foreach_resolver2.pas @@ -0,0 +1,67 @@ +uses System.Collections, System.Collections.Generic; + +type + c1 = class (IEnumerable) + public + + function IEnumerable.GetEnumerator: IEnumerator; + begin + Assert(false); + end; + + function GetEnumerator: IEnumerator; + begin + result:= Seq&().GetEnumerator; + end; + end; + + c2 = class (IEnumerable) + public + function GetEnumerator: IEnumerator; + begin + result:= Seq&().GetEnumerator; + end; + + function IEnumerable.GetEnumerator: IEnumerator; + begin + Assert(false); + end; + end; + + c3 = class (IEnumerable, IEnumerable) + public + function GetEnumerator: IEnumerator; + begin + result:= Seq&().GetEnumerator; + end; + + function IEnumerable.GetEnumerator: IEnumerator; + begin + Assert(false); + end; + + function IEnumerable.GetEnumerator: IEnumerator; + begin + Assert(false); + end; + end; + + c4 = class (c2) + + end; + +begin + + var v1:= new c1; + foreach var item in v1 do ; + + var v2:= new c2; + 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. \ No newline at end of file diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index fe7e1f809..34f643f94 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -18577,7 +18577,7 @@ namespace PascalABCCompiler.TreeConverter } } - private bool IsIEnumerableInterface(ITypeNode t) + private bool IsIEnumerableInterface(type_node t) { compiled_type_node orig; @@ -18594,7 +18594,7 @@ namespace PascalABCCompiler.TreeConverter /// /// Собирает интерфейсы, реализованные типом и его предками /// - private List CollectInterfacesFromTypeNode(type_node node) + private List CollectInterfacesFromTypeNode(type_node node) { var result = new List(); result.AddRange(node.ImplementingInterfaces); @@ -18605,7 +18605,7 @@ namespace PascalABCCompiler.TreeConverter result.AddRange(interfInBase); } - return result; + return result.Cast().ToList(); } private bool IsIEnumeratorInterface(type_node t) @@ -18629,7 +18629,6 @@ namespace PascalABCCompiler.TreeConverter var filteredInterfaces = CollectInterfacesFromTypeNode(node) .Where(item => IsIEnumerableInterface(item)) - .Cast() .ToArray(); var genericInterfaceCount = filteredInterfaces.Count(item => item.is_generic_type_instance);