diff --git a/TestSuite/errors/err0166.pas b/TestSuite/errors/err0166.pas index f231b7788..e0b3f6479 100644 --- a/TestSuite/errors/err0166.pas +++ b/TestSuite/errors/err0166.pas @@ -1,5 +1,5 @@ -#reference 'System.Windows.Forms.dll' -#reference 'System.Drawing.dll' +{$reference 'System.Windows.Forms.dll'} +{$reference 'System.Drawing.dll'} uses System, System.Windows.Forms; diff --git a/TestSuite/errors/err0167.pas b/TestSuite/errors/err0167.pas index 7db43ad81..f922e1804 100644 --- a/TestSuite/errors/err0167.pas +++ b/TestSuite/errors/err0167.pas @@ -1,5 +1,5 @@ -#reference 'System.Windows.Forms.dll' -#reference 'System.Drawing.dll' +{$reference 'System.Windows.Forms.dll'} +{$reference 'System.Drawing.dll'} uses System, System.Windows.Forms; diff --git a/TestSuite/lambdas_in_constructor1.pas b/TestSuite/lambdas_in_constructor1.pas new file mode 100644 index 000000000..f5bd7d677 --- /dev/null +++ b/TestSuite/lambdas_in_constructor1.pas @@ -0,0 +1,14 @@ +type + c1 = class + seq1: sequence of integer; + constructor create; + begin + var a := Arr(3.1, 3.7); + seq1 := a.Select(b -> Round(b)); + end; + end; + +begin + var obj := new c1; + assert(obj.seq1.ToArray[1] = 4); +end. diff --git a/TreeConverter/TreeConversion/compilation_context.cs b/TreeConverter/TreeConversion/compilation_context.cs index e4a6fef5c..f59f31459 100644 --- a/TreeConverter/TreeConversion/compilation_context.cs +++ b/TreeConverter/TreeConversion/compilation_context.cs @@ -278,7 +278,12 @@ namespace PascalABCCompiler.TreeConverter { syntax_tree_visitor.AddError(loc, ErrString, values); } - + + internal bool can_call_inherited_ctor_call(statements_list lst) + { + return lst.statements.Count == 0; + } + public void reset() { _cmn = null; diff --git a/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs b/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs index 4b524cbbc..196222362 100644 --- a/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs +++ b/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs @@ -100,7 +100,12 @@ namespace PascalABCCompiler.TreeConverter { return statement_list_stack.pop(); } - + + internal statements_list statement_list_stack_first() + { + return statement_list_stack.first(); + } + public type_constructor type_constructor { get @@ -436,7 +441,7 @@ namespace PascalABCCompiler.TreeConverter common_constructor_call ccc = new common_constructor_call((common_method_node)fn, loc); //(ssyy) По-видимому, здесь всегда можно присваивать false, так как при создании нового объекта мы сюда не заходим... ccc._new_obj_awaited = false; - if (!syntax_tree_visitor.context.allow_inherited_ctor_call) + if (!syntax_tree_visitor.context.allow_inherited_ctor_call && !syntax_tree_visitor.context.can_call_inherited_ctor_call(statement_list_stack_first())) { if (syntax_tree_visitor.inherited_ident_processing) syntax_tree_visitor.AddError(new SimpleSemanticError(loc, "INHERITED_CONSTRUCTOR_CALL_MUST_BE_FIRST")); @@ -490,7 +495,7 @@ namespace PascalABCCompiler.TreeConverter compiled_constructor_call ccc = new compiled_constructor_call(ccn, loc); ccc.parameters.AddRange(exprs); ccc._new_obj_awaited = false; - if (!syntax_tree_visitor.context.allow_inherited_ctor_call) + if (!syntax_tree_visitor.context.allow_inherited_ctor_call && !syntax_tree_visitor.context.can_call_inherited_ctor_call(statement_list_stack_first())) { throw new SimpleSemanticError(loc, "INHERITED_CONSTRUCTOR_CALL_MUST_BE_FIRST"); } diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index e3d406660..2bb3d8339 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -15485,7 +15485,7 @@ namespace PascalABCCompiler.TreeConverter } else { - if (!context.allow_inherited_ctor_call) + if (!context.allow_inherited_ctor_call && !context.can_call_inherited_ctor_call(convertion_data_and_alghoritms.statement_list_stack_first())) AddError(loc, "INHERITED_CONSTRUCTOR_CALL_MUST_BE_FIRST"); expressions_list exprs = new expressions_list(); foreach (common_parameter cp in cfn.parameters) @@ -16308,31 +16308,17 @@ namespace PascalABCCompiler.TreeConverter convertion_data_and_alghoritms.statement_list_stack_push(stl); for (var i=0; i< _statement_list.subnodes.Count; i++) // SSM 13.10.16 - поменял т.к. собираюсь менять узлы в процессе обхода - //foreach (statement syntax_statement in _statement_list.subnodes) { statement syntax_statement = _statement_list.subnodes[i]; try { - // SSM выкинул эти три строки - теперь внутриблочные описания обрабатываются как обычные операторы. - // При этом в конце visit(var_statement) стоит вызов ret.reset(), который возвращает нулевой semantic_statement - и всё работает эквивалентно - //if (syntax_statement is SyntaxTree.var_statement) - // visit(syntax_statement as SyntaxTree.var_statement); // Добавление в текущий statements_list происходит опосредованно !! - //else if (MustVisitBody) // MustVisitBody - всегда True!!! - //{ - //(ssyy) TODO Сделать по-другому!!! statement_node semantic_statement = convert_strong(syntax_statement); - //(ssyy) Проверка для C if (semantic_statement != null) { - //Обработать по другому - комментарий не мой - SSM - //if (context.CurrentScope.AddStatementsToFront) - // stl.statements.AddElementFirst(semantic_statement); - //else stl.statements.AddElement(semantic_statement); } context.allow_inherited_ctor_call = false; - //} } catch (Errors.Error ex) {