diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index 7f4ca542f..1e6257647 100644 --- a/Configuration/GlobalAssemblyInfo.cs +++ b/Configuration/GlobalAssemblyInfo.cs @@ -15,7 +15,7 @@ internal static class RevisionClass public const string Major = "3"; public const string Minor = "7"; public const string Build = "2"; - public const string Revision = "2814"; + public const string Revision = "2818"; public const string MainVersion = Major + "." + Minor; public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision; diff --git a/Configuration/Version.defs b/Configuration/Version.defs index 78ee1fff7..1e1144352 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ %COREVERSION%=2 -%REVISION%=2814 +%REVISION%=2818 %MINOR%=7 %MAJOR%=3 diff --git a/Localization/DefaultLang.resources b/Localization/DefaultLang.resources index 659081eef..1c59f8f4e 100644 Binary files a/Localization/DefaultLang.resources and b/Localization/DefaultLang.resources differ diff --git a/Release/pabcversion.txt b/Release/pabcversion.txt index 4f8e22e4d..bd0e37807 100644 --- a/Release/pabcversion.txt +++ b/Release/pabcversion.txt @@ -1 +1 @@ -3.7.2.2814 +3.7.2.2818 diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index 20a283e0e..9f443c846 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.7.2.2814' +!define VERSION '3.7.2.2818' diff --git a/TestSuite/lam3_captureparam.pas b/TestSuite/lam3_captureparam.pas new file mode 100644 index 000000000..2badaca4d --- /dev/null +++ b/TestSuite/lam3_captureparam.pas @@ -0,0 +1,4 @@ +begin + var b := Arr(0, 1); + Assert(b.SelectMany(x -> b.SelectMany(y -> b.Select(z -> y).Select(w -> 1))).SequenceEqual(Arr(1)*8)); +end. diff --git a/TreeConverter/TreeConversion/HasCapturedLambdaParameterInInternalLambdaBody.cs b/TreeConverter/TreeConversion/HasCapturedLambdaParameterInInternalLambdaBody.cs new file mode 100644 index 000000000..7e364c055 --- /dev/null +++ b/TreeConverter/TreeConversion/HasCapturedLambdaParameterInInternalLambdaBody.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using PascalABCCompiler.SyntaxTree; + +namespace PascalABCCompiler.TreeConverter +{ + public class HasCapturedLambdaParameterInInternalLambdaBody : BaseEnterExitVisitor + { + public bool HasCapturedParameter = false; + public List idents = new List(); + public bool InLambda = false; + public HasCapturedLambdaParameterInInternalLambdaBody(function_lambda_definition fld) + { + idents = fld.ident_list.idents; + } + public static HasCapturedLambdaParameterInInternalLambdaBody New(function_lambda_definition fld) + { + return new HasCapturedLambdaParameterInInternalLambdaBody(fld); + } + public override void visit(var_def_statement vds) + { + //ProcessNode(vds.vars_type); + } + public override void visit(ident id) + { + if (!InLambda) // мы ищем только в лямбдах + return; + if (HasCapturedParameter) + return; + if (idents.Select(i => i.name).Contains(id.name,StringComparer.OrdinalIgnoreCase)) + { + HasCapturedParameter = true; + } + } + public override void visit(function_lambda_definition fld) + { + InLambda = true; + ProcessNode(fld.proc_body); + } + + + + } +} diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 6a4790e55..4257a4dbd 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -20027,9 +20027,14 @@ namespace PascalABCCompiler.TreeConverter int err_cnt = ErrorsList.Count; try { - expression_node yyy; - if (ff.parameters.expressions.Count > 0) - yyy = convert_strong(ff.parameters.expressions[0]); + // Видимо, дело только в лямбде. Попробовать всё обойти и найти захваченные параметры + // Если они есть, то ничего не делать и выйти + + var vis = HasCapturedLambdaParameterInInternalLambdaBody.New(_function_lambda_definition); + vis.ProcessNode(ff.dereferencing_value); + if (vis.HasCapturedParameter) // SSM 28/01/2021 считать это функцией. Будет слабый вывод в редком числе случаев + return; + qq = convert_strong(ff.dereferencing_value); if (qq is exit_procedure && stl.list.Count == 1 || qq is local_block_variable_reference && qq.type is compiled_type_node && (qq.type as compiled_type_node).compiled_type == typeof(Action)) { diff --git a/TreeConverter/TreeConverter.csproj b/TreeConverter/TreeConverter.csproj index 783886235..0988c2c6d 100644 --- a/TreeConverter/TreeConverter.csproj +++ b/TreeConverter/TreeConverter.csproj @@ -110,6 +110,7 @@ + Code