Исправление вызовов методов без скобочек для языков с отличающихся от PascalABC.NET этим поведением (#3289)

* Fix method calls without parentheses in SPython

* Move condition above loop to make code cleaner
This commit is contained in:
AlexanderZemlyak 2025-06-22 17:32:22 +03:00 committed by GitHub
parent 239be2d202
commit 6298fdb655
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 118 additions and 108 deletions

View file

@ -48,6 +48,7 @@ namespace Languages.Pascal
SemanticRulesConstants.StrongPointersTypeCheckForDotNet = true;
SemanticRulesConstants.AllowChangeLoopVariable = false;
SemanticRulesConstants.AllowGlobalVisibilityForPABCDll = true;
SemanticRulesConstants.AllowMethodCallsWithoutParentheses = true;
}
public override void SetSyntaxTreeToSemanticTreeConverter()

View file

@ -135,6 +135,11 @@ namespace PascalABCCompiler.TreeConverter
public static bool AddressOfOperatorNonOverloaded = true;
public static bool GenerateNativeCode = false;
/// <summary>
/// Разрешить вызов методов, не имеющих параметров (или со всеми параметрами по умолчанию) без скобок
/// </summary>
public static bool AllowMethodCallsWithoutParentheses = true;
}
}

View file

@ -10243,7 +10243,8 @@ namespace PascalABCCompiler.TreeConverter
only_extension_methods = false;
else
{
if (tmp_fn.parameters.Count == 1 || tmp_fn.parameters.Count == 2 && (tmp_fn.parameters[1].is_params || tmp_fn.parameters[1].default_value != null))
if (SemanticRulesConstants.AllowMethodCallsWithoutParentheses &&
(tmp_fn.parameters.Count == 1 || tmp_fn.parameters.Count == 2 && (tmp_fn.parameters[1].is_params || tmp_fn.parameters[1].default_value != null)))
has_empty_methods = true;
}
}
@ -10590,7 +10591,7 @@ namespace PascalABCCompiler.TreeConverter
}
foreach (SymbolInfo tmp_si in tmp_list)
{
if (tmp_si.sym_info is function_node && (tmp_si.sym_info as function_node).is_extension_method && !has_property(ref sil)
if (SemanticRulesConstants.AllowMethodCallsWithoutParentheses && tmp_si.sym_info is function_node && (tmp_si.sym_info as function_node).is_extension_method && !has_property(ref sil)
|| tmp_si.sym_info is common_method_node && (tmp_si.sym_info as common_method_node).is_constructor
|| tmp_si.sym_info is compiled_constructor_node)
return true;

View file

@ -1160,7 +1160,7 @@ namespace PascalABCCompiler.TreeRealization
}
}
if (dii.parameters.Count == 0)
if (dii.parameters.Count == 0 && TreeConverter.SemanticRulesConstants.AllowMethodCallsWithoutParentheses)
{
if (dii.return_value_type == to)
{

View file

@ -4631,126 +4631,129 @@ namespace PascalABCCompiler.TreeRealization
public override function_node get_implicit_conversion_to(type_node ctn)
{
foreach (base_function_call fn in _proper_methods)
if (SemanticRulesConstants.AllowMethodCallsWithoutParentheses)
{
if (fn.simple_function_node.parameters.Count == 0
|| (fn.simple_function_node is common_namespace_function_node && (fn.simple_function_node as common_namespace_function_node).ConnectedToType != null
|| fn.simple_function_node is compiled_function_node && (fn.simple_function_node as compiled_function_node).ConnectedToType != null)
&& fn.simple_function_node.parameters.Count == 1 && !fn.simple_function_node.parameters[0].is_params)
foreach (base_function_call fn in _proper_methods)
{
if (fn.simple_function_node.return_value_type == ctn)
if (fn.simple_function_node.parameters.Count == 0
|| (fn.simple_function_node is common_namespace_function_node && (fn.simple_function_node as common_namespace_function_node).ConnectedToType != null
|| fn.simple_function_node is compiled_function_node && (fn.simple_function_node as compiled_function_node).ConnectedToType != null)
&& fn.simple_function_node.parameters.Count == 1 && !fn.simple_function_node.parameters[0].is_params)
{
convert_function_to_function_call cftfc = new convert_function_to_function_call(fn);
return (new convert_types_function_node(cftfc.compile_time_executor, true));
if (fn.simple_function_node.return_value_type == ctn)
{
convert_function_to_function_call cftfc = new convert_function_to_function_call(fn);
return (new convert_types_function_node(cftfc.compile_time_executor, true));
}
if (fn.simple_function_node.return_value_type == null)
{
continue;
}
//TODO: Очень внимательно рассмотреть. Если преобразование типов должно идти через compile_time_executor.
possible_type_convertions ptc = type_table.get_convertions(fn.simple_function_node.return_value_type, ctn);
if ((ptc.first == null) || (ptc.first.convertion_method == null))
{
continue;
}
expression_node ennew = type_table.type_table_function_call_maker(ptc.first.convertion_method, null, fn);
convert_function_to_function_call cftfc2 = new convert_function_to_function_call(ennew);
return (new convert_types_function_node(cftfc2.compile_time_executor, false));
}
if (fn.simple_function_node.return_value_type == null)
else if (fn.simple_function_node.parameters.Count == 1 && fn.simple_function_node.parameters[0].is_params ||
(fn.simple_function_node is common_namespace_function_node && (fn.simple_function_node as common_namespace_function_node).ConnectedToType != null || fn.simple_function_node is compiled_function_node && (fn.simple_function_node as compiled_function_node).ConnectedToType != null)
&& fn.simple_function_node.parameters.Count == 2 && fn.simple_function_node.parameters[1].is_params)
{
continue;
}
//TODO: Очень внимательно рассмотреть. Если преобразование типов должно идти через compile_time_executor.
possible_type_convertions ptc=type_table.get_convertions(fn.simple_function_node.return_value_type, ctn);
if ((ptc.first == null) || (ptc.first.convertion_method == null))
{
continue;
}
expression_node ennew=type_table.type_table_function_call_maker(ptc.first.convertion_method, null, fn);
convert_function_to_function_call cftfc2 = new convert_function_to_function_call(ennew);
return (new convert_types_function_node(cftfc2.compile_time_executor, false));
}
else if (fn.simple_function_node.parameters.Count == 1 && fn.simple_function_node.parameters[0].is_params ||
(fn.simple_function_node is common_namespace_function_node && (fn.simple_function_node as common_namespace_function_node).ConnectedToType != null || fn.simple_function_node is compiled_function_node && (fn.simple_function_node as compiled_function_node).ConnectedToType != null)
&& fn.simple_function_node.parameters.Count == 2 && fn.simple_function_node.parameters[1].is_params)
{
base_function_call copy_fn = get_function_call_copy(fn);
int param_num = (fn.simple_function_node is common_namespace_function_node && (fn.simple_function_node as common_namespace_function_node).ConnectedToType != null || fn.simple_function_node is compiled_function_node && (fn.simple_function_node as compiled_function_node).ConnectedToType != null) ? 1 : 0;
if (fn.simple_function_node.return_value_type == ctn)
{
common_namespace_function_call cnfc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.NewArrayProcedureDecl,null);
cnfc.parameters.AddElement(new typeof_operator(fn.simple_function_node.parameters[param_num].type, null));
cnfc.parameters.AddElement(new int_const_node(0,null));
base_function_call copy_fn = get_function_call_copy(fn);
int param_num = (fn.simple_function_node is common_namespace_function_node && (fn.simple_function_node as common_namespace_function_node).ConnectedToType != null || fn.simple_function_node is compiled_function_node && (fn.simple_function_node as compiled_function_node).ConnectedToType != null) ? 1 : 0;
if (fn.simple_function_node.return_value_type == ctn)
{
common_namespace_function_call cnfc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.NewArrayProcedureDecl, null);
cnfc.parameters.AddElement(new typeof_operator(fn.simple_function_node.parameters[param_num].type, null));
cnfc.parameters.AddElement(new int_const_node(0, null));
if (copy_fn.parameters.Count < fn.simple_function_node.parameters.Count)
copy_fn.parameters.AddElement(cnfc);
convert_function_to_function_call cftfc = new convert_function_to_function_call(copy_fn);
return (new convert_types_function_node(cftfc.compile_time_executor, true));
}
if (fn.simple_function_node.return_value_type == null)
{
continue;
}
//TODO: Очень внимательно рассмотреть. Если преобразование типов должно идти через compile_time_executor.
possible_type_convertions ptc = type_table.get_convertions(fn.simple_function_node.return_value_type, ctn);
if ((ptc.first == null) || (ptc.first.convertion_method == null))
{
continue;
}
common_namespace_function_call cnfc2 = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.NewArrayProcedureDecl, null);
cnfc2.parameters.AddElement(new typeof_operator(fn.simple_function_node.parameters[param_num].type, null));
cnfc2.parameters.AddElement(new int_const_node(0, null));
if (copy_fn.parameters.Count < fn.simple_function_node.parameters.Count)
copy_fn.parameters.AddElement(cnfc);
convert_function_to_function_call cftfc = new convert_function_to_function_call(copy_fn);
return (new convert_types_function_node(cftfc.compile_time_executor, true));
copy_fn.parameters.AddElement(cnfc2);
expression_node ennew = type_table.type_table_function_call_maker(ptc.first.convertion_method, null, copy_fn);
convert_function_to_function_call cftfc2 = new convert_function_to_function_call(ennew);
return (new convert_types_function_node(cftfc2.compile_time_executor, false));
}
if (fn.simple_function_node.return_value_type == null)
{
continue;
}
//TODO: Очень внимательно рассмотреть. Если преобразование типов должно идти через compile_time_executor.
possible_type_convertions ptc=type_table.get_convertions(fn.simple_function_node.return_value_type, ctn);
if ((ptc.first == null) || (ptc.first.convertion_method == null))
{
continue;
}
common_namespace_function_call cnfc2 = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.NewArrayProcedureDecl,null);
cnfc2.parameters.AddElement(new typeof_operator(fn.simple_function_node.parameters[param_num].type, null));
cnfc2.parameters.AddElement(new int_const_node(0,null));
if (copy_fn.parameters.Count < fn.simple_function_node.parameters.Count)
copy_fn.parameters.AddElement(cnfc2);
expression_node ennew=type_table.type_table_function_call_maker(ptc.first.convertion_method, null, copy_fn);
convert_function_to_function_call cftfc2 = new convert_function_to_function_call(ennew);
return (new convert_types_function_node(cftfc2.compile_time_executor, false));
}
else if (fn.simple_function_node.parameters.Count == 1 && fn.simple_function_node.parameters[0].default_value != null ||
(fn.simple_function_node is common_namespace_function_node && (fn.simple_function_node as common_namespace_function_node).ConnectedToType != null
|| fn.simple_function_node is compiled_function_node && (fn.simple_function_node as compiled_function_node).ConnectedToType != null)
&& fn.simple_function_node.parameters.Count == 2 && fn.simple_function_node.parameters[1].default_value != null)
{
int param_num = (fn.simple_function_node is common_namespace_function_node && (fn.simple_function_node as common_namespace_function_node).ConnectedToType != null || fn.simple_function_node is compiled_function_node && (fn.simple_function_node as compiled_function_node).ConnectedToType != null) ? 1 : 0;
base_function_call copy_fn = null;
if (fn.simple_function_node.return_value_type == ctn)
else if (fn.simple_function_node.parameters.Count == 1 && fn.simple_function_node.parameters[0].default_value != null ||
(fn.simple_function_node is common_namespace_function_node && (fn.simple_function_node as common_namespace_function_node).ConnectedToType != null
|| fn.simple_function_node is compiled_function_node && (fn.simple_function_node as compiled_function_node).ConnectedToType != null)
&& fn.simple_function_node.parameters.Count == 2 && fn.simple_function_node.parameters[1].default_value != null)
{
int param_num = (fn.simple_function_node is common_namespace_function_node && (fn.simple_function_node as common_namespace_function_node).ConnectedToType != null || fn.simple_function_node is compiled_function_node && (fn.simple_function_node as compiled_function_node).ConnectedToType != null) ? 1 : 0;
base_function_call copy_fn = null;
if (fn.simple_function_node.return_value_type == ctn)
{
copy_fn = get_function_call_copy(fn);
copy_fn.parameters.AddElement(fn.simple_function_node.parameters[param_num].default_value);
convert_function_to_function_call cftfc = new convert_function_to_function_call(copy_fn);
return (new convert_types_function_node(cftfc.compile_time_executor, true));
}
if (fn.simple_function_node.return_value_type == null)
{
continue;
}
//TODO: Очень внимательно рассмотреть. Если преобразование типов должно идти через compile_time_executor.
possible_type_convertions ptc = type_table.get_convertions(fn.simple_function_node.return_value_type, ctn);
if ((ptc.first == null) || (ptc.first.convertion_method == null))
{
continue;
}
copy_fn = get_function_call_copy(fn);
copy_fn.parameters.AddElement(fn.simple_function_node.parameters[param_num].default_value);
convert_function_to_function_call cftfc = new convert_function_to_function_call(copy_fn);
return (new convert_types_function_node(cftfc.compile_time_executor, true));
expression_node ennew = type_table.type_table_function_call_maker(ptc.first.convertion_method, null, copy_fn);
convert_function_to_function_call cftfc2 = new convert_function_to_function_call(ennew);
return (new convert_types_function_node(cftfc2.compile_time_executor, false));
}
if (fn.simple_function_node.return_value_type == null)
{
continue;
}
//TODO: Очень внимательно рассмотреть. Если преобразование типов должно идти через compile_time_executor.
possible_type_convertions ptc = type_table.get_convertions(fn.simple_function_node.return_value_type, ctn);
if ((ptc.first == null) || (ptc.first.convertion_method == null))
{
continue;
}
copy_fn = get_function_call_copy(fn);
copy_fn.parameters.AddElement(fn.simple_function_node.parameters[param_num].default_value);
expression_node ennew = type_table.type_table_function_call_maker(ptc.first.convertion_method, null, copy_fn);
convert_function_to_function_call cftfc2 = new convert_function_to_function_call(ennew);
return (new convert_types_function_node(cftfc2.compile_time_executor, false));
}
else if (fn.simple_function_node.parameters.Count == fn.simple_function_node.num_of_default_parameters)
{
base_function_call copy_fn = get_function_call_copy(fn);
if (fn.simple_function_node.return_value_type == ctn)
else if (fn.simple_function_node.parameters.Count == fn.simple_function_node.num_of_default_parameters)
{
base_function_call copy_fn = get_function_call_copy(fn);
if (fn.simple_function_node.return_value_type == ctn)
{
foreach (parameter p in fn.simple_function_node.parameters)
copy_fn.parameters.AddElement(p.default_value);
convert_function_to_function_call cftfc = new convert_function_to_function_call(copy_fn);
return (new convert_types_function_node(cftfc.compile_time_executor, true));
}
if (fn.simple_function_node.return_value_type == null)
{
continue;
}
//TODO: Очень внимательно рассмотреть. Если преобразование типов должно идти через compile_time_executor.
possible_type_convertions ptc = type_table.get_convertions(fn.simple_function_node.return_value_type, ctn);
if ((ptc.first == null) || (ptc.first.convertion_method == null))
{
continue;
}
foreach (parameter p in fn.simple_function_node.parameters)
copy_fn.parameters.AddElement(p.default_value);
convert_function_to_function_call cftfc = new convert_function_to_function_call(copy_fn);
return (new convert_types_function_node(cftfc.compile_time_executor, true));
expression_node ennew = type_table.type_table_function_call_maker(ptc.first.convertion_method, null, copy_fn);
convert_function_to_function_call cftfc2 = new convert_function_to_function_call(ennew);
return (new convert_types_function_node(cftfc2.compile_time_executor, false));
}
if (fn.simple_function_node.return_value_type == null)
{
continue;
}
//TODO: Очень внимательно рассмотреть. Если преобразование типов должно идти через compile_time_executor.
possible_type_convertions ptc = type_table.get_convertions(fn.simple_function_node.return_value_type, ctn);
if ((ptc.first == null) || (ptc.first.convertion_method == null))
{
continue;
}
foreach (parameter p in fn.simple_function_node.parameters)
copy_fn.parameters.AddElement(p.default_value);
expression_node ennew = type_table.type_table_function_call_maker(ptc.first.convertion_method, null, copy_fn);
convert_function_to_function_call cftfc2 = new convert_function_to_function_call(ennew);
return (new convert_types_function_node(cftfc2.compile_time_executor, false));
}
}