/// <summary>
        /// Этот метод вызывается если мы встречаем простой вызов функии, например f(1).
        /// Он определяет является ли эта функция методом класса, вложенной функцией и т.д. и создает соответствующее обращение.
        /// Например, для метода класса он добавляет this, а для вложенной функции вычисляет статическую глубину.
        /// </summary>
        /// <param name="exprs">Список параметров.</param>
        /// <param name="si">Список методов.</param>
        /// <param name="loc">Расположение вызова.</param>
        /// <param name="converted_type">Тип в котором мы находимся. null, если мы вне типа.</param>
        /// <param name="top_function">Функция в которой мы находимся.</param>
        /// <param name="allow_procedure">Может ли это быть вызов процедуры. false если вызов стоит в выражении или правой части опреатора присваивания.</param>
        /// <returns>Возвращает узел вызова метода.</returns>
		public expression_node create_full_function_call(expressions_list exprs,SymbolInfo si,location loc,
			common_type_node converted_type,common_function_node top_function,bool allow_procedure)
		{
			function_node fn=select_function(exprs,si,loc);

            /*
            if (fn.compile_time_executor != null)
            {
                expression_node ex = fn.compile_time_executor(loc, exprs.ToArray());
                if (ex != null)
                {
                    return ex;
                }
            }
            */
            //allow_procedure = true;
			if ((!allow_procedure)&&(fn.return_value_type==null))
			{
                throw new SimpleSemanticError(loc, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", fn.name);
			}

			expression_node expr_node=null;
			switch (fn.semantic_node_type)
			{
				case semantic_node_type.basic_function_node:
				case semantic_node_type.common_namespace_function_node:
				{
					expr_node=create_simple_function_call(fn,loc,exprs.ToArray());
					break;
				}
				case semantic_node_type.common_method_node:
				case semantic_node_type.compiled_function_node:
				{
					SemanticTree.IClassMemberNode icmn=(SemanticTree.IClassMemberNode)fn;
					if (icmn.polymorphic_state==SemanticTree.polymorphic_state.ps_static)
					{
						expr_node=create_simple_function_call(fn,loc,exprs.ToArray());
						break;
					}
                    //expression_node tn = new this_node(converted_type,loc);
					base_function_call cmc=null;
					switch (fn.semantic_node_type)
					{
						case semantic_node_type.common_method_node:
						{
                            //ssyy добавил
                            if (((common_method_node)fn).is_constructor)
                            {
                                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)
                                {
                                    throw new SimpleSemanticError(loc, "INHERITED_CONSTRUCTOR_CALL_MUST_BE_FIRST");
                                }
                                cmc = ccc;
                            }
                            else
                            //\ssyy
                            {
                                cmc = new common_method_call((common_method_node)fn, syntax_tree_visitor.GetCurrentObjectReference(((common_method_node)fn).cont_type.Scope, fn, loc), loc);
                                (cmc as common_method_call).virtual_call = !syntax_tree_visitor.inherited_ident_processing;
                            }
							break;
						}
						case semantic_node_type.compiled_function_node:
						{
                            cmc = new compiled_function_call((compiled_function_node)fn, syntax_tree_visitor.GetCurrentObjectReference(((compiled_function_node)fn).cont_type.Scope, fn, loc), loc);
                            (cmc as compiled_function_call).virtual_call = !syntax_tree_visitor.inherited_ident_processing;
							break;
						}
					}
					cmc.parameters.AddRange(exprs);
					expr_node=cmc;
					break;
				}
				case semantic_node_type.common_in_function_function_node:
				{
					common_in_function_function_node cffn=(common_in_function_function_node)fn;
					common_in_function_function_call cffc=new common_in_function_function_call(cffn,
						symtab.GetRelativeScopeDepth(cffn.function.scope,top_function.scope),loc);
					cffc.parameters.AddRange(exprs);
					expr_node=cffc;
					break;
				}
                //ssyy добавил
                case semantic_node_type.compiled_constructor_node:
                {
                    compiled_constructor_node ccn = fn as compiled_constructor_node;
                    if (ccn == null)
                    {
                        throw new CompilerInternalError("compiled_constructor_node expected");
                    }
                    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)
                    {
                        throw new SimpleSemanticError(loc, "INHERITED_CONSTRUCTOR_CALL_MUST_BE_FIRST");
                    }
                    expr_node = ccc;
                    break;
                }
                case semantic_node_type.indefinite_definition_node:
                {
                    indefinite_function_call ifc = new indefinite_function_call(fn, loc);
                    ifc.parameters.AddRange(exprs);
                    expr_node = ifc;
                    break;
                }
                //\ssyy
				default:
				{
                    throw new NotSupportedError(loc);
				}
			}
			return expr_node;
		}
 private base_function_call create_not_static_method_call(function_node fn, expression_node en, location loc, bool procedure_allowed)
 {
     try_convert_typed_expression_to_function_call(ref en);
     if ((!procedure_allowed) && (fn.return_value_type == null))
     {
         AddError(loc, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", fn);
     }
     if (fn.semantic_node_type == semantic_node_type.common_method_node)
     {
         common_method_node cmn = (common_method_node)fn;
         if (cmn.is_constructor)
         {
             AddError(loc, "CAN_NOT_CALL_CONSTRUCTOR_AS_PROCEDURE");
         }
         if (cmn.original_function != null && cmn.original_function is compiled_function_node && (cmn.original_function as compiled_function_node).ConnectedToType != null)
         {
             common_static_method_call csmc = new common_static_method_call(cmn, loc);
             return csmc;
         }
         if (cmn.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
         {
             AddError(new CanNotCallStaticMethodWithExpression(en, fn));
         }
         
         common_method_call cmc = new common_method_call(cmn, en, loc);
         cmc.virtual_call = !inherited_ident_processing;
         return cmc;
     }
     if (fn.semantic_node_type == semantic_node_type.compiled_function_node)
     {
         compiled_function_node cfn = (compiled_function_node)fn;
         if (cfn.ConnectedToType != null)
         {
             compiled_static_method_call csmc = new compiled_static_method_call(cfn, loc);
             return csmc;
         }
         else
         {
             if (cfn.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
             {
                 if (!cfn.is_extension_method)
                     AddError(new CanNotCallStaticMethodWithExpression(en, fn));
                 else
                     return new compiled_static_method_call(cfn, loc);
             }
             compiled_function_call cfc = new compiled_function_call(cfn, en, loc);
             cfc.virtual_call = !inherited_ident_processing;
             return cfc;
         }
     }
     if (fn.semantic_node_type == semantic_node_type.compiled_constructor_node)
     {
         AddError(loc, "CAN_NOT_CALL_CONSTRUCTOR_AS_PROCEDURE");
     }
     if (fn.semantic_node_type == semantic_node_type.common_namespace_function_node && (fn as common_namespace_function_node).ConnectedToType != null)
     {
     	common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node,loc);
     	//cnfc.parameters.AddElement(en);
     	return cnfc;
     }
     if (fn.semantic_node_type == semantic_node_type.indefinite_definition_node)
     {
         indefinite_function_call ifc = new indefinite_function_call(fn, loc);
         return ifc;
     }
     throw new CompilerInternalError("Invalid method kind");
 }
		//Метод только для внутнреннего использования.
		//НЕ ПРЕОБРАЗУЕТ ТИПЫ. Только создает узел вызова метода.
		//Этот метод и используется для создания узлов преобразования типов.
        //TODO: Переименовать.
        public expression_node create_simple_function_call(function_node fn, location loc, params expression_node[] exprs)
        {

            if (fn.compile_time_executor != null)
            {
                expression_node ex = fn.compile_time_executor(loc, exprs);
                if (ex != null)
                {
                    return ex;
                }
            }

            switch (fn.semantic_node_type)
            {
                /*
                case semantic_node_type.empty_function_node:
				{
#if (DEBUG)
					if (exprs.Length!=1)
					{
						throw new CompilerInternalError("Epty functions with only single parameter allowed.");
					}
#endif
					return exprs[0];
				}
                */
                case semantic_node_type.basic_function_node:
                    {
                        return create_basic_function_call((basic_function_node)fn, loc, exprs);
                    }
                case semantic_node_type.common_namespace_function_node:
                    {
                        return create_common_namespace_function_call((common_namespace_function_node)fn, loc, exprs);
                    }
                case semantic_node_type.common_method_node:
                    {
                        common_method_node cmn = (common_method_node)fn;
                        if (cmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static)
                        {
                            break;
                        }
                        return create_common_static_method_call(cmn, loc, exprs);
                    }
                /*
				case semantic_node_type.pseudo_function:
				{
					pseudo_function pf=(pseudo_function)fn;
					return pf.execute_pseudo_function_algorithm(loc,exprs);
				}
                */
                case semantic_node_type.common_in_function_function_node: break;
                case semantic_node_type.compiled_function_node:
                    {
                        compiled_function_node cfn = (compiled_function_node)fn;
                        if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static)
                        {
                            break;
                        }
                        return create_compiled_static_method_call(cfn, loc, exprs);
                    }
                case semantic_node_type.compiled_constructor_node:
                    {
                        compiled_constructor_call ccc = new compiled_constructor_call((compiled_constructor_node)fn,loc);
                        ccc.parameters.AddRange(exprs);
                        return ccc;

                    }
                case semantic_node_type.indefinite_definition_node:
                    {
                        indefinite_function_call ifc = new indefinite_function_call(fn, loc);
                        ifc.parameters.AddRange(exprs);
                        return ifc;
                    }
                default: throw new CompilerInternalError("Unknown function type");
            }
            throw new CanNotReferenceToNonStaticMethodWithType(fn.name, loc);
        }