public override void visit(SyntaxTree.block _block) { if (context.converting_block() != block_type.namespace_block && _block.defs != null && _block.defs.defs != null) { foreach (var def in _block.defs.defs.Where(d => d is const_definition || d is consts_definitions_list || d is variable_definitions)) { var lambdaSearcher = new LambdaSearcher(def); if (lambdaSearcher.CheckIfContainsLambdas()) { AddError(new LambdasNotAllowedInDeclarationsSection(get_location(lambdaSearcher.FoundLambda))); // SSM 6.06.15 - Хочется убрать это. В разделе описаний лямбды нужны - пусть и без замыканий. Если внутри подпрограммы - не нужны, но Вы же запретили везде! } } } weak_node_test_and_visit(_block.defs); //ssyy добавил генерацию вызова конструктора предка без параметров if (context.converting_block() == block_type.function_block) { common_method_node cmn = context.top_function as common_method_node; if (cmn != null && cmn.is_constructor && !(cmn.polymorphic_state == SemanticTree.polymorphic_state.ps_static)) { context.allow_inherited_ctor_call = true; if (_block.program_code != null && _block.program_code.subnodes != null) { //(ssyy) Для записей конструктор предка не вызываем. bool should_ctor_add = context.converted_type.is_class; if (should_ctor_add) { if (_block.program_code.subnodes.Count > 0) { SyntaxTree.procedure_call pc = _block.program_code.subnodes[0] as SyntaxTree.procedure_call; if (pc != null || _block.program_code.subnodes[0] is SyntaxTree.inherited_message) { //SyntaxTree.inherited_ident ii = pc.func_name as SyntaxTree.inherited_ident; //SyntaxTree.method_call mc = pc.func_name as SyntaxTree.method_call; //SyntaxTree.ident id = pc.func_name as SyntaxTree.ident; //if (/*ii != null*/id != null || mc != null /*&& mc.dereferencing_value is SyntaxTree.inherited_ident*/) { //(ssyy) Не уверен, что следующий оператор необходим. convertion_data_and_alghoritms.check_node_parser_error(_block.program_code); statement_node inh = convert_strong(_block.program_code.subnodes[0]); compiled_constructor_call c1 = inh as compiled_constructor_call; if (c1 != null && !c1._new_obj_awaited) { should_ctor_add = false; } else { common_constructor_call c2 = inh as common_constructor_call; if (c2 != null && !c2._new_obj_awaited) { should_ctor_add = false; } } } } } } if (should_ctor_add) { //Пытаемся добавить вызов .ctor() предка... //Для начала проверим, есть ли у предка таковой. bool not_found = true; SymbolInfo sym = context.converted_type.base_type.find_in_type(compiler_string_consts.default_constructor_name, context.CurrentScope); while (not_found && sym != null) { compiled_constructor_node ccn = sym.sym_info as compiled_constructor_node; if (ccn != null && ccn.parameters.Count == 0) { not_found = false; } else { common_method_node cnode = sym.sym_info as common_method_node; if (cnode != null && cnode.is_constructor && (cnode.parameters.Count == 0 || cnode.parameters[0].default_value != null)) { not_found = false; } } sym = sym.Next; } if (not_found) { //У предка нет конструктора по умолчанию AddError(get_location(_block.program_code), "INHERITED_CONSTRUCTOR_CALL_EXPECTED"); } else { //Генерируем вызов .ctor() предка SyntaxTree.inherited_ident ii = new SyntaxTree.inherited_ident(); ii.name = compiler_string_consts.default_constructor_name; _block.program_code.subnodes.Insert(0, new SyntaxTree.procedure_call(ii)); //context.allow_inherited_ctor_call = false; } } } } } //\ssyy //ssyy if (context.converting_block() == block_type.namespace_block) { context.check_predefinition_defined(); } if (lambdaProcessingState == LambdaProcessingState.None && _block.program_code != null) { var lambdaSearcher = new LambdaSearcher(_block.program_code); var lambdaIsFound = lambdaSearcher.CheckIfContainsLambdas(); if ((context.converting_block() == block_type.function_block || context.converting_block() == block_type.namespace_block) && lambdaIsFound) // TODO: Пока обрабатываются только блок функции и основной блок, необходимо обрабатывать случаи появлений лямбд в var_def_statement { if (context.converting_block() == block_type.function_block) { if (context.func_stack.top().functions_nodes_list.Count > 0) { AddError(new LambdasNotAllowedWhenNestedSubprogrammesAreUsed(get_location(lambdaSearcher.FoundLambda))); } } lambdaProcessingState = LambdaProcessingState.TypeInferencePhase; visit_program_code(_block.program_code); lambdaProcessingState = LambdaProcessingState.ClosuresProcessingPhase; CapturedVariablesSubstitutionsManager.Substitute(this, _block.defs, _block.program_code); lambdaProcessingState = LambdaProcessingState.FinishPhase; context.code = visit_program_code(_block.program_code); lambdaProcessingState = LambdaProcessingState.None; } else { context.code = visit_program_code(_block.program_code); } } else { context.code = visit_program_code(_block.program_code); } }
public void lambda_body_visit(SyntaxTree.block _block) { //weak_node_test_and_visit(_block.defs); //ssyy добавил генерацию вызова конструктора предка без параметров if (context.converting_block() == block_type.function_block) { common_method_node cmn = context.top_function as common_method_node; if (cmn != null && cmn.is_constructor && !(cmn.polymorphic_state == SemanticTree.polymorphic_state.ps_static)) { context.allow_inherited_ctor_call = true; if (_block.program_code != null && _block.program_code.subnodes != null) { //(ssyy) Для записей конструктор предка не вызываем. bool should_ctor_add = context.converted_type.is_class; if (should_ctor_add) { if (_block.program_code.subnodes.Count > 0) { SyntaxTree.procedure_call pc = _block.program_code.subnodes[0] as SyntaxTree.procedure_call; if (pc != null || _block.program_code.subnodes[0] is SyntaxTree.inherited_message) { //SyntaxTree.inherited_ident ii = pc.func_name as SyntaxTree.inherited_ident; //SyntaxTree.method_call mc = pc.func_name as SyntaxTree.method_call; //SyntaxTree.ident id = pc.func_name as SyntaxTree.ident; //if (/*ii != null*/id != null || mc != null /*&& mc.dereferencing_value is SyntaxTree.inherited_ident*/) { //(ssyy) Не уверен, что следующий оператор необходим. convertion_data_and_alghoritms.check_node_parser_error(_block.program_code); statement_node inh = convert_strong(_block.program_code.subnodes[0]); compiled_constructor_call c1 = inh as compiled_constructor_call; if (c1 != null && !c1._new_obj_awaited) { should_ctor_add = false; } else { common_constructor_call c2 = inh as common_constructor_call; if (c2 != null && !c2._new_obj_awaited) { should_ctor_add = false; } } } } } } if (should_ctor_add) { //Пытаемся добавить вызов .ctor() предка... //Для начала проверим, есть ли у предка таковой. bool not_found = true; SymbolInfo sym = context.converted_type.base_type.find_in_type(compiler_string_consts.default_constructor_name, context.CurrentScope); while (not_found && sym != null) { compiled_constructor_node ccn = sym.sym_info as compiled_constructor_node; if (ccn != null && ccn.parameters.Count == 0) { not_found = false; } else { common_method_node cnode = sym.sym_info as common_method_node; if (cnode != null && cnode.is_constructor && (cnode.parameters.Count == 0 || cnode.parameters[0].default_value != null)) { not_found = false; } } sym = sym.Next; } if (not_found) { //У предка нет конструктора по умолчанию AddError(get_location(_block.program_code), "INHERITED_CONSTRUCTOR_CALL_EXPECTED"); } else { //Генерируем вызов .ctor() предка SyntaxTree.inherited_ident ii = new SyntaxTree.inherited_ident(); ii.name = compiler_string_consts.default_constructor_name; _block.program_code.subnodes.Insert(0, new SyntaxTree.procedure_call(ii)); //context.allow_inherited_ctor_call = false; } } } } } //\ssyy //ssyy if (context.converting_block() == block_type.namespace_block) { context.check_predefinition_defined(); } context.enter_code_block_with_bind(); statement_node sn = convert_strong(_block.program_code); context.leave_code_block(); context.code = sn; }