public void write_semantic_type_node(semantic_type_node _semantic_type_node)
		{
			write_type_definition(_semantic_type_node);
			bw.Write((byte)_semantic_type_node.type);
		}
        //\lroman//
		
        public override void visit(SyntaxTree.procedure_definition _procedure_definition)
        {
            // SSM 20.07.13 если это - узел с коротким определением функции без типа возвращаемого значения, то вывести этот тип
            var fh = (_procedure_definition.proc_header as SyntaxTree.function_header);
            if (fh != null && fh.return_type == null)
            {
                var bl = _procedure_definition.proc_body as SyntaxTree.block;
                if (bl != null && bl.program_code != null)
                {
                    if (bl.program_code.subnodes.Count != 1)
                        AddError(get_location(fh.name), "ONLY_IN_SHORT_FUNC_DEFS_RETURN_TYPE_CANBE_OMITTED");

                    var ass = bl.program_code.subnodes[0] as SyntaxTree.assign;
                    if (ass != null && ass.to is ident && (ass.to as ident).name.ToLower()=="result")
                    {
                        if (ass.from is nil_const)
                            AddError(get_location(ass.from), "CAN_NOT_DEDUCE_TYPE_{0}","nil");
                        
                        // undefined_type означает, что где-то в будущем это надо исправить. Потому что и Result будет этого типа
                        var typ = new semantic_type_node(new undefined_type("#Und",null));//SyntaxTreeBuilder.BuildSameType(ass.from);
                        fh.return_type = typ;
                    }
                    else AddError(get_location(fh.name), "ONLY_IN_SHORT_FUNC_DEFS_RETURN_TYPE_CANBE_OMITTED");
                }
            }
            //\ SSM

            var proc_name = _procedure_definition.proc_header != null && _procedure_definition.proc_header.name != null
                                ? _procedure_definition.proc_header.name.meth_name
                                : null;
            if (_procedure_definition.proc_header.attributes != null && context.converted_func_stack.size >= 1)
                AddError(get_location(_procedure_definition.proc_header), "ATTRIBUTES_FOR_NESTED_FUNCTIONS_NOT_ALLOWED");
            if (context.top_function != null && context.top_function.generic_params != null && !LambdaHelper.IsLambdaName(proc_name))
                AddError(get_location(_procedure_definition.proc_header), "NESTED_FUNCTIONS_IN_GENERIC_FUNCTIONS_NOT_ALLOWED");
            if (context.top_function != null && _procedure_definition.proc_header.template_args != null && !LambdaHelper.IsLambdaName(proc_name))
                AddError(get_location(_procedure_definition.proc_header), "GENERIC_NESTED_FUNCTIONS_NOT_ALLOWED");
        	if (_procedure_definition.proc_header.name != null)
                current_converted_method_not_in_class_defined = _procedure_definition.proc_header.name.class_name != null;
            else
            {
                if (_procedure_definition.proc_header is SyntaxTree.constructor)
                {
                    current_converted_method_not_in_class_defined = false;
                }
            }
            bool must_visit_body = true;
            if (SemanticRules.OrderIndependedMethodNames && !disable_order_independ && context.converting_block() == block_type.type_block && _procedure_definition.proc_body != null)
            {
            	if (_procedure_definition.proc_header.name != null)
            	{
            		if (_procedure_definition.proc_header.name.class_name == null)
            		{
            			must_visit_body = false;
            			context.is_order_independed_method_description = true;
            		}
            	}
            	else
            	{
            		must_visit_body = false;
            		context.is_order_independed_method_description = true;
            	}
            }
            if (SemanticRules.OrderIndependedFunctionNames && !disable_order_independ && context.converting_block() == block_type.namespace_block && _procedure_definition.proc_body != null && _procedure_definition.proc_header.name.class_name == null)
            {
            	if (_procedure_definition.proc_header.name != null)
            	{
            		if (_procedure_definition.proc_header.name.class_name == null)
            		{
            			must_visit_body = false;
            			context.is_order_independed_method_description = true;
            		}
            	}
            	else
            	{
            		must_visit_body = false;
            		context.is_order_independed_method_description = true;
            	}
            }
            //ssyy
            if (context.converting_block() == block_type.type_block &&
                context.converted_type.IsInterface)
            {
                AddError(get_location(_procedure_definition), "INVALID_INTERFACE_MEMBER");
            }
            //\ssyy

            //ssyy добавил
            if (context.converting_block() == block_type.function_block)
            {
                common_method_node cmnode = context.top_function as common_method_node;
                if (cmnode != null && cmnode.is_constructor)
                {
                    //throw new NotSupportedError(get_location(_procedure_definition));
                }
            }
            //\ssyy

            if (_procedure_definition.proc_body == null)
            {
                body_exists = false;
            }
            else
            {
                body_exists = true;
            }

            //lroman//
            if (_procedure_definition != null &&
                _procedure_definition.proc_header != null &&
                _procedure_definition.proc_header is SyntaxTree.function_header && 
                _procedure_definition.proc_header.name != null &&
                _procedure_definition.proc_header.name.meth_name != null &&
                LambdaHelper.IsLambdaName(_procedure_definition.proc_header.name.meth_name))
            {
                //!!!!!!!!!!!!!!!!!! 
                convertion_data_and_alghoritms.check_node_parser_error(_procedure_definition.proc_header);
                visit_lambda_header(_procedure_definition.proc_header as SyntaxTree.function_header, _procedure_definition.proc_body);
            }
            else
            {
                hard_node_test_and_visit(_procedure_definition.proc_header);
            }
            //\lroman//
            

            //ssyy
            if (context.converted_template_type != null)
            {
                if ((context.converted_template_type.type_dec.type_def as SyntaxTree.class_definition).keyword == PascalABCCompiler.SyntaxTree.class_keyword.Interface)
                {
                    AddError(new InterfaceFunctionWithBody(get_location(_procedure_definition)));
                }
                context.converted_template_type.external_methods.Add(
                    new procedure_definition_info(context.converted_namespace, _procedure_definition));
                context.converted_template_type = null;
                return;
            }
            //\ssyy
            if (context.top_function == null)
            {
                return;
            }
            if (context.converted_explicit_interface_type != null)
                (context.top_function as common_method_node).explicit_interface = context.converted_explicit_interface_type;
            if (has_dll_import_attribute(context.top_function))
            {
                if (_procedure_definition.proc_body != null)
                    if (!is_pinvoke(_procedure_definition.proc_body))
                        AddError(get_location(_procedure_definition.proc_body), "EXPECTED_EXTERNAL_STATEMENT");
            }

            if (contextChanger.IsActive())
            {
                must_visit_body = true;
            }

            if (context.top_function.return_value_type is undefined_type) // значит, это короткое определение функции, и тело есть, и его надо обойти
            {
                must_visit_body = true;
            }

            // try
            {

                if (context.top_function.is_forward)
                {
                    if (_procedure_definition.proc_body != null)
                    {
                        AddError(context.top_function.loc, "FORWARD_DEFINITION_WITH_FUNCTION_BODY");
                    }
                }
                else
                {
                    if (must_visit_body)
                    {
                        common_method_node cmn = context.top_function as common_method_node;
                        if (cmn != null && !cmn.IsStatic)
                        {
                            //if (cmn.find_only_in_namespace(compiler_string_consts.self_word) == null)
                            //self variable
                            //добавляем self, обращение к ней заменяется на this_node
                            type_node self_type = cmn.cont_type;
                            if (cmn.cont_type.is_generic_type_definition)
                                self_type = cmn.cont_type.get_instance(cmn.cont_type.generic_params.ConvertAll<type_node>(o => (type_node)o));
                            local_variable lv = new local_variable(compiler_string_consts.self_word, self_type, cmn, null);
                            cmn.scope.AddSymbol(compiler_string_consts.self_word, new SymbolInfo(lv));
                            cmn.self_variable = lv;
                        }
                        if (_procedure_definition.proc_body != null)
                        {
                            hard_node_test_and_visit(_procedure_definition.proc_body);
                        }

                        // SSM 12/04/16 - short func definitions - calc return_value_type
                        var ttt = context.top_function.return_value_type;
                        if (ttt is undefined_type)
                        {
                            var cd = context.top_function.function_code as statements_list;

                            if (cd == null || cd.statements == null || cd.statements.Count == 0)
                            {
                                AddError(context.top_function.loc, "IMPOSSIBLE!SHORT_FUNC_WITHOUT_BODY");
                            }

                            // Проблема в том, что если в теле короткого определения функции - лямбда
                            // и происходит захват переменной, то в тело выносится вызов конструктора сгенерированного класса
                            // Поэтому result := ... - это не первый оператор, а последний!!!
                            statement_node aa = cd.statements[cd.statements.Count-1];
                            var bfc = aa as basic_function_call;
                            if (bfc != null)
                            {
                                var ttt1 = bfc.type;
                                context.top_function.return_value_type = ttt1;
                                context.top_function.var_definition_nodes_list[0].type = ttt1;
                            }
                        }

                        add_clip_for_set(context.top_function);
                    }
                    else // if (!must_visit_body)
                    {
                        context.add_method_header(_procedure_definition, context.top_function);
                    }

                }
            }
            //finally
            {
                if (_procedure_definition.proc_header.name.class_name != null)
                {
                    context.leave_type_method();
                }
                context.is_order_independed_method_description = false;
                context.leave_block();
            }
        }
		public void visit(semantic_type_node _semantic_type_node)
		{
			bw.Write((Int16)194);
			write_semantic_type_node(_semantic_type_node);
		}
Example #4
0
 public override void visit(semantic_type_node stn) // SSM 
 {
 }
		public void read_semantic_type_node(semantic_type_node _semantic_type_node)
		{
			read_type_definition(_semantic_type_node);
			_semantic_type_node.type = (Object)br.ReadByte();
		}
		public void visit(semantic_type_node _semantic_type_node)
		{
			read_semantic_type_node(_semantic_type_node);
		}
 // frninja 29/05/16 - выявляем тип перемнной в foreach
 public override void visit(SyntaxTree.yield_unknown_foreach_type _unk)
 {
     var t = new semantic_type_node(new ienumerable_auto_type(get_location(_unk)));
     t.visit(this);
 }
 public override void visit(SyntaxTree.yield_unknown_expression_type _unk_expr)
 {
     // Отвечает за типизацию всех переменных с автовыведением типа
     // Пробую сделать по-другому: перевести в auto_type и потом на присваивании перехватить
     var t = new semantic_type_node(new auto_type(get_location(_unk_expr)));
     t.visit(this);
 }