diff --git a/CodeCompletion/DomSyntaxTreeVisitor.cs b/CodeCompletion/DomSyntaxTreeVisitor.cs index bd0b04c53..d753d34bd 100644 --- a/CodeCompletion/DomSyntaxTreeVisitor.cs +++ b/CodeCompletion/DomSyntaxTreeVisitor.cs @@ -4225,6 +4225,8 @@ namespace CodeCompletion _foreach_stmt.in_what.visit(this); if (returned_scope != null) returned_scope = returned_scope.GetElementType(); + if (returned_scope == null) + returned_scope = TypeTable.obj_type; } else { diff --git a/CodeCompletion/SymTable.cs b/CodeCompletion/SymTable.cs index 64787c851..d93b676e8 100644 --- a/CodeCompletion/SymTable.cs +++ b/CodeCompletion/SymTable.cs @@ -4239,7 +4239,21 @@ namespace CodeCompletion public override TypeScope GetElementType() { if (elementType != null) return elementType; - if (baseScope != null) return baseScope.GetElementType(); + TypeScope elem_ts = null; + if (baseScope != null) + { + elem_ts = baseScope.GetElementType(); + if (elem_ts != null) + return elem_ts; + } + + if (implemented_interfaces != null) + foreach (TypeScope ts in implemented_interfaces) + { + elem_ts = ts.GetElementType(); + if (elem_ts != null) + return elem_ts; + } return null; } diff --git a/TestSuite/intellisense_tests/foreach2.pas b/TestSuite/intellisense_tests/foreach2.pas new file mode 100644 index 000000000..27488b0eb --- /dev/null +++ b/TestSuite/intellisense_tests/foreach2.pas @@ -0,0 +1,14 @@ +type + t1 = class(System.Collections.Generic.IEnumerable) + end; + + t2 = class(System.Collections.IEnumerable) + public function GetEnumerator: System.Collections.IEnumerator := Arr(new object).GetEnumerator; + end; + +begin + foreach var o{@var o: real;@} in new t1 do + writeln(o.GetType); + foreach var o{@var o: Object;@} in new t2 do + writeln(o.GetType); +end. \ No newline at end of file diff --git a/TestSuite/intellisense_tests/foreach3.pas b/TestSuite/intellisense_tests/foreach3.pas new file mode 100644 index 000000000..3b03a00aa --- /dev/null +++ b/TestSuite/intellisense_tests/foreach3.pas @@ -0,0 +1,14 @@ +function test: sequence of char; +begin + yield 'a'; +end; + +function test2: sequence of array of T; +begin + yield new T[2]; +end; +begin + foreach var c in test do + writeln(c{@var c: char;@}); + foreach var o{@var o: array of real;@} in test2& 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 671cbef1f..b4fcf159f 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -5401,7 +5401,7 @@ namespace PascalABCCompiler.TreeConverter sil = nsn.find(id_right.name); if (templ_args_count != 0) { - SymbolInfo conv = ConvertTypeToInstance(sil.FirstOrDefault(), iwt.template_params.params_list, get_location(id_right)); + SymbolInfo conv = ConvertTypeToInstance(sil?.FirstOrDefault(), iwt.template_params.params_list, get_location(id_right)); if (conv != null) { sil = new List { conv };