Fix result variable case sensitive comparing (#3282)

* Fix result variable case sensitive comparing

* Make code shorter

* Refactor code again

* Add ToLower in LambdaHelper
This commit is contained in:
AlexanderZemlyak 2025-06-18 23:56:23 +03:00 committed by GitHub
parent da6d44fc33
commit a07b6447d9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 47 additions and 43 deletions

View file

@ -308,7 +308,7 @@ namespace PascalABCCompiler
private static string of_word = "of"; private static string of_word = "of";
private static string space = " "; private static string space = " ";
public static string result_variable_name = "result"; public static string result_var_name = "Result";
public static string event_add_method_nameformat = event_add_method_prefix + "{0}"; public static string event_add_method_nameformat = event_add_method_prefix + "{0}";
public static string event_remove_method_nameformat = event_remove_method_prefix + "{0}"; public static string event_remove_method_nameformat = event_remove_method_prefix + "{0}";

View file

@ -5,8 +5,8 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using PascalABCCompiler.SemanticTree; using PascalABCCompiler.SemanticTree;
using PascalABCCompiler.SyntaxTree; using PascalABCCompiler.SyntaxTree;
using PascalABCCompiler.TreeConverter;
using PascalABCCompiler.TreeRealization; using PascalABCCompiler.TreeRealization;
using static PascalABCCompiler.StringConstants;
namespace TreeConverter.LambdaExpressions.Closure namespace TreeConverter.LambdaExpressions.Closure
{ {
@ -171,10 +171,8 @@ namespace TreeConverter.LambdaExpressions.Closure
{ {
var varName = ((IVAriableDefinitionNode)symbolInfo.SymbolInfo.sym_info).name; //.ToLower(); var varName = ((IVAriableDefinitionNode)symbolInfo.SymbolInfo.sym_info).name; //.ToLower();
StringComparison stringComparison = symbolInfo.SymbolInfo.scope.CaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;
var ff = symbolInfo.SymbolInfo.sym_info.GetType(); var ff = symbolInfo.SymbolInfo.sym_info.GetType();
var isSelfWordInClass = scope is CapturedVariablesTreeNodeClassScope && varName.Equals(PascalABCCompiler.StringConstants.self_word, stringComparison); var isSelfWordInClass = scope is CapturedVariablesTreeNodeClassScope && varName.Equals(self_word, symbolInfo.SymbolInfo.scope.StringComparison);
SourceContext sourceCtxt = null; SourceContext sourceCtxt = null;
if (symbolInfo.SymbolInfo.sym_info.location != null) if (symbolInfo.SymbolInfo.sym_info.location != null)
sourceCtxt = new SourceContext(symbolInfo.SymbolInfo.sym_info.location.begin_line_num, symbolInfo.SymbolInfo.sym_info.location.begin_column_num, sourceCtxt = new SourceContext(symbolInfo.SymbolInfo.sym_info.location.begin_line_num, symbolInfo.SymbolInfo.sym_info.location.begin_column_num,

View file

@ -213,6 +213,7 @@ namespace TreeConverter.LambdaExpressions.Closure
} }
var stringComparer = _visitor.context.CurrentScope.CaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase; var stringComparer = _visitor.context.CurrentScope.CaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase;
var stringComparison = _visitor.context.CurrentScope.StringComparison;
if (si.sym_info.semantic_node_type == semantic_node_type.namespace_variable || if (si.sym_info.semantic_node_type == semantic_node_type.namespace_variable ||
si.sym_info.semantic_node_type == semantic_node_type.common_namespace_function_node || si.sym_info.semantic_node_type == semantic_node_type.common_namespace_function_node ||
@ -399,12 +400,12 @@ namespace TreeConverter.LambdaExpressions.Closure
_visitor.AddError(new ThisTypeOfVariablesCannotBeCaptured(_visitor.get_location(id))); _visitor.AddError(new ThisTypeOfVariablesCannotBeCaptured(_visitor.get_location(id)));
} }
}*/ }*/
if (si.sym_info.semantic_node_type == semantic_node_type.common_parameter && prScope.FunctionNode.parameters.First(v => stringComparer.Compare(v.name, idName) == 0).parameter_type != parameter_type.value && InLambdaContext) if (si.sym_info.semantic_node_type == semantic_node_type.common_parameter && prScope.FunctionNode.parameters.First(v => v.name.Equals(idName, stringComparison)).parameter_type != parameter_type.value && InLambdaContext)
{ {
_visitor.AddError(new CannotCaptureNonValueParameters(_visitor.get_location(id))); _visitor.AddError(new CannotCaptureNonValueParameters(_visitor.get_location(id)));
} }
if (stringComparer.Compare(idName, PascalABCCompiler.StringConstants.self_word) == 0 && si.scope is SymbolTable.ClassMethodScope && if (idName.Equals(PascalABCCompiler.StringConstants.self_word, stringComparison) && si.scope is SymbolTable.ClassMethodScope &&
_classScope != null) _classScope != null)
{ {
var selfField = _classScope.VariablesDefinedInScope.Find(var => var.SymbolInfo == si); var selfField = _classScope.VariablesDefinedInScope.Find(var => var.SymbolInfo == si);
@ -427,7 +428,7 @@ namespace TreeConverter.LambdaExpressions.Closure
var found = false; var found = false;
foreach (var v in prScope.VariablesDefinedInScope) // и не было с таким же именем foreach (var v in prScope.VariablesDefinedInScope) // и не было с таким же именем
{ {
if (v.SymbolInfo.sym_info is var_definition_node vdn && stringComparer.Compare(vdn.name, idName) == 0) // SSM попытка бороться с #2001 - исключаю одноимённые if (v.SymbolInfo.sym_info is var_definition_node vdn && vdn.name.Equals(idName, stringComparison)) // SSM попытка бороться с #2001 - исключаю одноимённые
{ {
found = true; found = true;
break; break;
@ -471,7 +472,7 @@ namespace TreeConverter.LambdaExpressions.Closure
var index = -1; var index = -1;
for (var i=0; i < sc.VariablesDefinedInScope.Count; i++) for (var i=0; i < sc.VariablesDefinedInScope.Count; i++)
{ {
if (sc.VariablesDefinedInScope[i].SymbolInfo.sym_info is var_definition_node vdn && stringComparer.Compare(vdn.name, idName) == 0) // SSM #2001 и подобные - исключаю одноимённые if (sc.VariablesDefinedInScope[i].SymbolInfo.sym_info is var_definition_node vdn && vdn.name.Equals(idName, stringComparison)) // SSM #2001 и подобные - исключаю одноимённые
{ {
index = i; index = i;
si = sc.VariablesDefinedInScope[i].SymbolInfo; si = sc.VariablesDefinedInScope[i].SymbolInfo;

View file

@ -5,12 +5,12 @@ using System.Collections.Generic;
using PascalABCCompiler.SyntaxTree; using PascalABCCompiler.SyntaxTree;
using PascalABCCompiler.TreeConverter; using PascalABCCompiler.TreeConverter;
using PascalABCCompiler.TreeRealization; using PascalABCCompiler.TreeRealization;
using static PascalABCCompiler.StringConstants;
namespace TreeConverter.LambdaExpressions namespace TreeConverter.LambdaExpressions
{ {
internal class LambdaResultTypeInferrer : WalkingVisitorNew internal class LambdaResultTypeInferrer : WalkingVisitorNew
{ {
private const string RESULT_KEY_WORD = "result";
private readonly List<Tuple<type_node, expression, expression_node>> resultExpressionsTypes; private readonly List<Tuple<type_node, expression, expression_node>> resultExpressionsTypes;
private readonly syntax_tree_visitor syntaxTreeVisitor; private readonly syntax_tree_visitor syntaxTreeVisitor;
private readonly proc_block lambdaBody; private readonly proc_block lambdaBody;
@ -103,7 +103,7 @@ namespace TreeConverter.LambdaExpressions
var from = assignment.from; var from = assignment.from;
if (to != null && if (to != null &&
assignment.operator_type == Operators.Assignment && assignment.operator_type == Operators.Assignment &&
to.name.ToLower() == RESULT_KEY_WORD) to.name.Equals(result_var_name, syntaxTreeVisitor.context.CurrentScope.StringComparison))
{ {
var converted = syntaxTreeVisitor.convert_strong(from); var converted = syntaxTreeVisitor.convert_strong(from);
if (converted is typed_expression) if (converted is typed_expression)
@ -113,10 +113,10 @@ namespace TreeConverter.LambdaExpressions
converted = syntaxTreeVisitor.convert_typed_expression_to_function_call(converted as typed_expression); converted = syntaxTreeVisitor.convert_typed_expression_to_function_call(converted as typed_expression);
} }
resultExpressionsTypes.Add(new Tuple<type_node, expression, expression_node>(converted.type, from, converted)); resultExpressionsTypes.Add(new Tuple<type_node, expression, expression_node>(converted.type, from, converted));
var si_list = syntaxTreeVisitor.context.find(RESULT_KEY_WORD); var si_list = syntaxTreeVisitor.context.find(result_var_name);
if (si_list != null && si_list.Count > 0 && si_list[0].sym_info == null) if (si_list != null && si_list.Count > 0 && si_list[0].sym_info == null)
{ {
si_list[0].sym_info = new local_variable(RESULT_KEY_WORD, converted.type, syntaxTreeVisitor.context.top_function, null); si_list[0].sym_info = new local_variable(result_var_name, converted.type, syntaxTreeVisitor.context.top_function, null);
} }
} }
} }

View file

@ -69,7 +69,7 @@ namespace PascalABCCompiler.TreeConverter
if (Variables[i].name.StartsWith("$rv_")) if (Variables[i].name.StartsWith("$rv_"))
{ {
TreeRealization.local_variable OldResult = Variables[i] as TreeRealization.local_variable; TreeRealization.local_variable OldResult = Variables[i] as TreeRealization.local_variable;
TreeRealization.local_variable NewResult = new PascalABCCompiler.TreeRealization.local_variable("result", OldResult.type, OldResult.function, OldResult.loc); TreeRealization.local_variable NewResult = new PascalABCCompiler.TreeRealization.local_variable(StringConstants.result_var_name, OldResult.type, OldResult.function, OldResult.loc);
Variables[i] = NewResult; Variables[i] = NewResult;
} }
} }

View file

@ -166,6 +166,9 @@ namespace SymbolTable
public Scope TopScope; public Scope TopScope;
public int ScopeNum; public int ScopeNum;
public StringComparison StringComparison => CaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;
public Scope(DSSymbolTable vSymbolTable, Scope TopScope, string Name) public Scope(DSSymbolTable vSymbolTable, Scope TopScope, string Name)
{ {
SymbolTable=vSymbolTable; SymbolTable=vSymbolTable;

View file

@ -2,12 +2,11 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using System.Linq; using System.Linq;
using PascalABCCompiler.TreeRealization; using PascalABCCompiler.TreeRealization;
using System.Collections;
using PascalABCCompiler.SyntaxTree; using PascalABCCompiler.SyntaxTree;
using TreeConverter.LambdaExpressions; using TreeConverter.LambdaExpressions;
using static PascalABCCompiler.StringConstants;
namespace PascalABCCompiler.TreeConverter namespace PascalABCCompiler.TreeConverter
{ {
@ -203,7 +202,7 @@ namespace PascalABCCompiler.TreeConverter
lambdaDef.formal_parameters.params_list[i].vars_type, lambdaDef.formal_parameters.params_list[i].vars_type,
null)); null));
if (lambdaDef.return_type != null) if (lambdaDef.return_type != null)
stmtList.subnodes.Add(SyntaxTreeNodesConstructor.CreateVarStatementNode("result", lambdaDef.return_type, null)); // переделать, не сработает, если тип возвращаемого значения не указан stmtList.subnodes.Add(SyntaxTreeNodesConstructor.CreateVarStatementNode(result_var_name, lambdaDef.return_type, null)); // переделать, не сработает, если тип возвращаемого значения не указан
stmtList.subnodes.AddRange((lambdaDef.proc_body as statement_list).subnodes); stmtList.subnodes.AddRange((lambdaDef.proc_body as statement_list).subnodes);
block resBlock = new block(); block resBlock = new block();
resBlock.program_code = stmtList; resBlock.program_code = stmtList;
@ -235,7 +234,7 @@ namespace PascalABCCompiler.TreeConverter
// Очищаем от Result := , который мы создали на предыдущем этапе // Очищаем от Result := , который мы создали на предыдущем этапе
var ass = stl.list[0] as assign; var ass = stl.list[0] as assign;
if (ass != null && ass.to is ident && (ass.to as ident).name.ToLower() == "result") if (ass != null && ass.to is ident && (ass.to as ident).name.ToLower() == result_var_name.ToLower())
{ {
var f = ass.from; var f = ass.from;
if (f is method_call) if (f is method_call)
@ -449,7 +448,7 @@ namespace PascalABCCompiler.TreeConverter
public override void visit(assign value) public override void visit(assign value)
{ {
var to = value.to as ident; var to = value.to as ident;
if (to != null && value.operator_type == Operators.Assignment && to.name.ToLower() == "result") if (to != null && value.operator_type == Operators.Assignment && to.name.Equals(result_var_name, SemanticRulesConstants.SymbolTableCaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase))
{ {
exprList.Add(value.from); exprList.Add(value.from);
} }

View file

@ -61,7 +61,9 @@ namespace PascalABCCompiler.TreeConverter
if (stflambda.Count > 0) // мы находимся внутри лямбды - возможно, вложенной if (stflambda.Count > 0) // мы находимся внутри лямбды - возможно, вложенной
{ {
var fld = stflambda.Peek(); var fld = stflambda.Peek();
if (_assign.to is ident && (_assign.to as ident).name.ToLower() == "result" && fld.RealSemTypeOfResExpr == null) if (_assign.to is ident
&& (_assign.to as ident).name.Equals(StringConstants.result_var_name, context.CurrentScope.StringComparison)
&& fld.RealSemTypeOfResExpr == null)
// если это - первое присваивание Result // если это - первое присваивание Result
{ {
fld.RealSemTypeOfResExpr = from.type; fld.RealSemTypeOfResExpr = from.type;

View file

@ -804,8 +804,8 @@ namespace PascalABCCompiler.TreeConverter
int i = 0; int i = 0;
if (si.sym_info == null) if (si.sym_info == null)
{ {
if (name.ToLower() == "result") if (name.Equals(StringConstants.result_var_name, CurrentScope.StringComparison))
AddError(loc, "CAN_NOT_DEDUCE_TYPE_{0}", "Result"); AddError(loc, "CAN_NOT_DEDUCE_TYPE_{0}", StringConstants.result_var_name);
else else
AddError(new ExpectedType(loc)); AddError(new ExpectedType(loc));
} }
@ -1175,7 +1175,7 @@ namespace PascalABCCompiler.TreeConverter
public SymbolInfo create_special_names() public SymbolInfo create_special_names()
{ {
SymbolInfo si= new SymbolInfo(top_function.return_variable); SymbolInfo si= new SymbolInfo(top_function.return_variable);
top_function.scope.AddSymbol(StringConstants.result_variable_name, si); top_function.scope.AddSymbol(StringConstants.result_var_name, si);
return si; return si;
} }

View file

@ -1232,7 +1232,7 @@ namespace PascalABCCompiler.TreeConverter
factparams[i].location))); factparams[i].location)));
//parameters[ii-1].location))); //parameters[ii-1].location)));
SyntaxTree.expression ex = new SyntaxTree.new_expr(rettype,el); SyntaxTree.expression ex = new SyntaxTree.new_expr(rettype,el);
sl.Add(new SyntaxTree.assign("Result", ex)); sl.Add(new SyntaxTree.assign(StringConstants.result_var_name, ex));
// Определим функцию преобразования на внешнем уровне // Определим функцию преобразования на внешнем уровне
var fun = BuildSimpleFunctionOneParameter("_conv" + UniqueString(), "x", var fun = BuildSimpleFunctionOneParameter("_conv" + UniqueString(), "x",
new SyntaxTree.semantic_type_node(factparams[i].type), new SyntaxTree.semantic_type_node(factparams[i].type),

View file

@ -22,6 +22,7 @@ using repeat_node = PascalABCCompiler.TreeRealization.repeat_node;
using sizeof_operator = PascalABCCompiler.TreeRealization.sizeof_operator; using sizeof_operator = PascalABCCompiler.TreeRealization.sizeof_operator;
using typeof_operator = PascalABCCompiler.TreeRealization.typeof_operator; using typeof_operator = PascalABCCompiler.TreeRealization.typeof_operator;
using while_node = PascalABCCompiler.TreeRealization.while_node; using while_node = PascalABCCompiler.TreeRealization.while_node;
using static PascalABCCompiler.StringConstants;
using TreeConverter.LambdaExpressions.Closure; using TreeConverter.LambdaExpressions.Closure;
using TreeConverter.LambdaExpressions; using TreeConverter.LambdaExpressions;
using PascalABCCompiler.TreeConverter.TreeConversion; using PascalABCCompiler.TreeConverter.TreeConversion;
@ -2515,11 +2516,11 @@ namespace PascalABCCompiler.TreeConverter
function_node fn = null; function_node fn = null;
if (exl.Count > 1) if (exl.Count > 1)
{ {
fn = convertion_data_and_alghoritms.select_function(exl, (SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node).find_in_type(StringConstants.default_constructor_name), loc); fn = convertion_data_and_alghoritms.select_function(exl, (SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node).find_in_type(default_constructor_name), loc);
} }
else else
{ {
fn = convertion_data_and_alghoritms.select_function(exl, (SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node).find_in_type(StringConstants.default_constructor_name), loc); fn = convertion_data_and_alghoritms.select_function(exl, (SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node).find_in_type(default_constructor_name), loc);
} }
//expression_node expr = convertion_data_and_alghoritms.create_simple_function_call(fn, null, exl.ToArray()); //expression_node expr = convertion_data_and_alghoritms.create_simple_function_call(fn, null, exl.ToArray());
expression_node expr = create_static_method_call_with_params(fn, loc, tn, false, exl); expression_node expr = create_static_method_call_with_params(fn, loc, tn, false, exl);
@ -2854,7 +2855,7 @@ namespace PascalABCCompiler.TreeConverter
//Пытаемся добавить вызов .ctor() предка... //Пытаемся добавить вызов .ctor() предка...
//Для начала проверим, есть ли у предка таковой. //Для начала проверим, есть ли у предка таковой.
bool not_found = true; bool not_found = true;
List<SymbolInfo> sym = context.converted_type.base_type.find_in_type(StringConstants.default_constructor_name, context.CurrentScope); List<SymbolInfo> sym = context.converted_type.base_type.find_in_type(default_constructor_name, context.CurrentScope);
if (sym != null) if (sym != null)
{ {
foreach (SymbolInfo sym_unit in sym) foreach (SymbolInfo sym_unit in sym)
@ -2890,7 +2891,7 @@ namespace PascalABCCompiler.TreeConverter
{ {
//Генерируем вызов .ctor() предка //Генерируем вызов .ctor() предка
SyntaxTree.inherited_ident ii = new SyntaxTree.inherited_ident(); SyntaxTree.inherited_ident ii = new SyntaxTree.inherited_ident();
ii.name = StringConstants.default_constructor_name; ii.name = default_constructor_name;
_block.program_code.subnodes.Insert(0, new SyntaxTree.procedure_call(ii)); _block.program_code.subnodes.Insert(0, new SyntaxTree.procedure_call(ii));
//context.allow_inherited_ctor_call = false; //context.allow_inherited_ctor_call = false;
} }
@ -3335,13 +3336,13 @@ namespace PascalABCCompiler.TreeConverter
if (_constructor.name == null) if (_constructor.name == null)
{ {
SyntaxTree.ident name = new SyntaxTree.ident(StringConstants.default_constructor_name); SyntaxTree.ident name = new SyntaxTree.ident(default_constructor_name);
_constructor.name = new PascalABCCompiler.SyntaxTree.method_name(null, null, name, null); _constructor.name = new PascalABCCompiler.SyntaxTree.method_name(null, null, name, null);
_constructor.name.source_context = _constructor.name.meth_name.source_context = _constructor.source_context; _constructor.name.source_context = _constructor.name.meth_name.source_context = _constructor.source_context;
} }
if (_constructor.name.meth_name.name.ToLower() != StringConstants.default_constructor_name.ToLower()) if (_constructor.name.meth_name.name.ToLower() != default_constructor_name.ToLower())
AddError(get_location(_constructor.name), "CONSTRUCTOR_CAN_HAVE_ONLY_{0}_NAME", StringConstants.default_constructor_name); AddError(get_location(_constructor.name), "CONSTRUCTOR_CAN_HAVE_ONLY_{0}_NAME", default_constructor_name);
if ((_constructor.name.class_name == null) && (context.converting_block() != block_type.type_block)) if ((_constructor.name.class_name == null) && (context.converting_block() != block_type.type_block))
{ {
AddError(get_location(_constructor.name), "ONLY_CONSTRUCTOR_OF_TYPE_ALLOWED"); AddError(get_location(_constructor.name), "ONLY_CONSTRUCTOR_OF_TYPE_ALLOWED");
@ -4379,7 +4380,7 @@ namespace PascalABCCompiler.TreeConverter
SyntaxTree.procedure_attributes_list pal = new PascalABCCompiler.SyntaxTree.procedure_attributes_list(); SyntaxTree.procedure_attributes_list pal = new PascalABCCompiler.SyntaxTree.procedure_attributes_list();
//pal.proc_attributes.Add(new PascalABCCompiler.SyntaxTree.procedure_attribute(SyntaxTree.proc_attribute.attr_overload)); attr_overload - убрал отовсюду! ССМ //pal.proc_attributes.Add(new PascalABCCompiler.SyntaxTree.procedure_attribute(SyntaxTree.proc_attribute.attr_overload)); attr_overload - убрал отовсюду! ССМ
SyntaxTree.constructor constr = new PascalABCCompiler.SyntaxTree.constructor(); SyntaxTree.constructor constr = new PascalABCCompiler.SyntaxTree.constructor();
constr.name = new SyntaxTree.method_name(null, null, new PascalABCCompiler.SyntaxTree.ident(StringConstants.default_constructor_name), null); constr.name = new SyntaxTree.method_name(null, null, new PascalABCCompiler.SyntaxTree.ident(default_constructor_name), null);
constr.proc_attributes = pal; constr.proc_attributes = pal;
SyntaxTree.block bl = new SyntaxTree.block(); SyntaxTree.block bl = new SyntaxTree.block();
bl.program_code = new SyntaxTree.statement_list(); bl.program_code = new SyntaxTree.statement_list();
@ -8065,7 +8066,7 @@ namespace PascalABCCompiler.TreeConverter
{ {
if (SystemLibrary.SystemLibInitializer.PointerOutputConstructor == null) if (SystemLibrary.SystemLibInitializer.PointerOutputConstructor == null)
{ {
List<SymbolInfo> sil = (SystemLibrary.SystemLibInitializer.PointerOutputType.sym_info as common_type_node).find_in_type(StringConstants.default_constructor_name); List<SymbolInfo> sil = (SystemLibrary.SystemLibInitializer.PointerOutputType.sym_info as common_type_node).find_in_type(default_constructor_name);
common_method_node cnode = null; common_method_node cnode = null;
int cur_si_ind = 0; int cur_si_ind = 0;
do do
@ -8098,7 +8099,7 @@ namespace PascalABCCompiler.TreeConverter
{ {
if (SystemLibrary.SystemLibInitializer.PointerOutputConstructor == null) if (SystemLibrary.SystemLibInitializer.PointerOutputConstructor == null)
{ {
List<SymbolInfo> sil = (SystemLibrary.SystemLibInitializer.PointerOutputType.sym_info as compiled_type_node).find_in_type(StringConstants.default_constructor_name); List<SymbolInfo> sil = (SystemLibrary.SystemLibInitializer.PointerOutputType.sym_info as compiled_type_node).find_in_type(default_constructor_name);
compiled_constructor_node cnode = null; compiled_constructor_node cnode = null;
int cur_si_index = 0; int cur_si_index = 0;
do do
@ -12787,7 +12788,7 @@ namespace PascalABCCompiler.TreeConverter
if (attr.qualifier != null) if (attr.qualifier != null)
if (j == 0) if (j == 0)
{ {
if (string.Compare(attr.qualifier.name, "return", true) == 0 || string.Compare(attr.qualifier.name, "result", true) == 0) if (attr.qualifier.name.Equals("return", context.CurrentScope.StringComparison) || attr.qualifier.name.Equals(result_var_name, context.CurrentScope.StringComparison))
{ {
if (context.top_function == null) if (context.top_function == null)
AddError(get_location(attr), "ATTRIBUTE_APPLICABLE_ONLY_TO_METHOD"); AddError(get_location(attr), "ATTRIBUTE_APPLICABLE_ONLY_TO_METHOD");
@ -13533,7 +13534,7 @@ namespace PascalABCCompiler.TreeConverter
AddError(get_location(fh.name), "ONLY_IN_SHORT_FUNC_DEFS_RETURN_TYPE_CANBE_OMITTED"); AddError(get_location(fh.name), "ONLY_IN_SHORT_FUNC_DEFS_RETURN_TYPE_CANBE_OMITTED");
var ass = bl.program_code.subnodes[0] as SyntaxTree.assign; 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 != null && ass.to is ident && (ass.to as ident).name.Equals(result_var_name, context.CurrentScope.StringComparison))
{ {
if (ass.from is nil_const) if (ass.from is nil_const)
AddError(get_location(ass.from), "CAN_NOT_DEDUCE_TYPE_{0}","nil"); AddError(get_location(ass.from), "CAN_NOT_DEDUCE_TYPE_{0}","nil");
@ -17861,7 +17862,7 @@ namespace PascalABCCompiler.TreeConverter
List<SymbolInfo> sil = null; List<SymbolInfo> sil = null;
if (cmn.is_constructor) if (cmn.is_constructor)
sil = context.converted_type.base_type.find_in_type(StringConstants.default_constructor_name, context.CurrentScope); sil = context.converted_type.base_type.find_in_type(default_constructor_name, context.CurrentScope);
else else
sil = context.converted_type.base_type.find_in_type(cmn.name, context.CurrentScope); sil = context.converted_type.base_type.find_in_type(cmn.name, context.CurrentScope);
if (sil != null) if (sil != null)
@ -19857,7 +19858,7 @@ namespace PascalABCCompiler.TreeConverter
{ {
AddError(loc, "ABSTRACT_CONSTRUCTOR_{0}_CALL", tn.name); AddError(loc, "ABSTRACT_CONSTRUCTOR_{0}_CALL", tn.name);
} }
List<SymbolInfo> sil = tn.find_in_type(StringConstants.default_constructor_name, context.CurrentScope); //tn.Scope); List<SymbolInfo> sil = tn.find_in_type(default_constructor_name, context.CurrentScope); //tn.Scope);
delete_inherited_constructors(ref sil, tn); delete_inherited_constructors(ref sil, tn);
if (sil == null) if (sil == null)
AddError(loc, "CONSTRUCTOR_NOT_FOUND"); AddError(loc, "CONSTRUCTOR_NOT_FOUND");
@ -20458,7 +20459,7 @@ namespace PascalABCCompiler.TreeConverter
return; return;
{ {
var fn = _ctn.base_type.find_in_type(StringConstants.default_constructor_name, _ctn.base_type.Scope) var fn = _ctn.base_type.find_in_type(default_constructor_name, _ctn.base_type.Scope)
?.Select(si => si.sym_info).OfType<function_node>() ?.Select(si => si.sym_info).OfType<function_node>()
.FirstOrDefault(_fn => _fn.parameters.Count == 0); .FirstOrDefault(_fn => _fn.parameters.Count == 0);
var base_constructor_call = make_base_constructor_call(fn, out _, out _); var base_constructor_call = make_base_constructor_call(fn, out _, out _);
@ -20492,7 +20493,7 @@ namespace PascalABCCompiler.TreeConverter
return; return;
} }
//Получили список процедур предка, имеющих имя Create //Получили список процедур предка, имеющих имя Create
List<SymbolInfo> sil = _ctn.base_type.find_in_type(StringConstants.default_constructor_name, _ctn.base_type.Scope); List<SymbolInfo> sil = _ctn.base_type.find_in_type(default_constructor_name, _ctn.base_type.Scope);
delete_inherited_constructors(ref sil, _ctn.base_type); delete_inherited_constructors(ref sil, _ctn.base_type);
if (sil != null) if (sil != null)
{ {
@ -20522,12 +20523,12 @@ namespace PascalABCCompiler.TreeConverter
// Иначе partial классам генерирует кучу копий дефолтных конструкторов // Иначе partial классам генерирует кучу копий дефолтных конструкторов
if (_ctn.methods.Any(m => if (_ctn.methods.Any(m =>
m.is_constructor && m.name == StringConstants.default_constructor_name && m.is_constructor && m.name == default_constructor_name &&
m.parameters.Count == fn.parameters.Count && m.parameters.Count == fn.parameters.Count &&
m.parameters.Zip(fn.parameters, (par1, par2) => par1.type == par2.type).All(b => b) m.parameters.Zip(fn.parameters, (par1, par2) => par1.type == par2.type).All(b => b)
)) continue; )) continue;
var gen_constr = context.create_function(StringConstants.default_constructor_name, loc) as common_method_node; var gen_constr = context.create_function(default_constructor_name, loc) as common_method_node;
gen_constr.polymorphic_state = ps; gen_constr.polymorphic_state = ps;
gen_constr.is_overload = true; gen_constr.is_overload = true;
gen_constr.is_constructor = true; gen_constr.is_constructor = true;
@ -21170,7 +21171,7 @@ namespace PascalABCCompiler.TreeConverter
if (_function_lambda_definition.return_type is lambda_inferred_type && stl != null && stl.list.Count == 1 && _function_lambda_definition.usedkeyword == 0) if (_function_lambda_definition.return_type is lambda_inferred_type && stl != null && stl.list.Count == 1 && _function_lambda_definition.usedkeyword == 0)
{ {
var ass = stl.list[0] as assign; var ass = stl.list[0] as assign;
if (ass != null && ass.to is ident && (ass.to as ident).name.ToLower() == "result") if (ass != null && ass.to is ident && (ass.to as ident).name.Equals(result_var_name, context.CurrentScope.StringComparison))
{ {
var f = ass.from; var f = ass.from;
if (f is method_call) if (f is method_call)