diff --git a/TestSuite/lambdas_events.pas b/TestSuite/lambdas_events.pas new file mode 100644 index 000000000..893544555 --- /dev/null +++ b/TestSuite/lambdas_events.pas @@ -0,0 +1,31 @@ +var i: integer; + +procedure test; +begin + i := 1; +end; +type + t1 = class + + public event Elap: procedure; + + procedure p1(b:byte); + begin + + var p: procedure := ()-> + begin + b := 0; + if self.Elap <> nil then + self.Elap() + end; + p; + end; + + end; + +begin + var o := new t1; + o.Elap += test; + o.p1(2); + assert(i=1); +end. \ No newline at end of file diff --git a/TreeConverter/TreeConversion/LambdaHelper.cs b/TreeConverter/TreeConversion/LambdaHelper.cs index a5508e911..10b79fe4f 100644 --- a/TreeConverter/TreeConversion/LambdaHelper.cs +++ b/TreeConverter/TreeConversion/LambdaHelper.cs @@ -142,6 +142,17 @@ namespace PascalABCCompiler.TreeConverter return id.Contains(lambdaPrefix); } + public static bool IsCapturedSelf(expression_node ex) + { + if (ex is class_field_reference) + { + class_field fld = (ex as class_field_reference).field; + if (fld.name.Contains("<>local_variables_class")) + return true; + } + return false; + } + public static bool IsAuxiliaryLambdaName(ident id) { if (id == null) diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index ab9ead2a3..ca799edea 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -9171,7 +9171,7 @@ namespace PascalABCCompiler.TreeConverter private expression_node expression_value_reciving(SyntaxTree.ident id_right, List sil, expression_node en, bool expected_delegate) { general_node_type[] node_types; - if (en is this_node) + if (en is this_node || LambdaHelper.IsCapturedSelf(en)) node_types = new general_node_type[] { general_node_type.variable_node, general_node_type.function_node, general_node_type.property_node, general_node_type.constant_definition, general_node_type.event_node}; else @@ -16472,7 +16472,7 @@ namespace PascalABCCompiler.TreeConverter { if ((left as static_event_reference).en is compiled_event) AddError(left.location, "EVENT_{0}_MUST_BE_IN_LEFT_PART", (left as static_event_reference).en.name); - if (context.converted_type != null && context.converted_type != ((left as static_event_reference).en as common_event).cont_type) + if (context.converted_type != null && context.converted_type != ((left as static_event_reference).en as common_event).cont_type && !context.converted_type.name.Contains("<>local_variables_class")) AddError(left.location, "EVENT_{0}_MUST_BE_IN_LEFT_PART", (left as static_event_reference).en.name); } else if (right is static_event_reference)