/// <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); }