From d990bf08d85d83e14fc51fd99a66ebe2f36d2fcd Mon Sep 17 00:00:00 2001 From: Yegappan Lakshmanan Date: Fri, 22 Mar 2024 19:56:17 +0100 Subject: patch 9.1.0198: Vim9: compound operators broken for lambdas in an object Problem: Vim9: compound operators broken for lambdas in an object (girishji) Solution: When using an object from the outer scope, use the LOADOUTER instruction to load the object (Yegappan Lakshmanan). fixes: #14236 closes: #14266 Signed-off-by: Yegappan Lakshmanan Signed-off-by: Christian Brabandt --- src/testdir/test_vim9_class.vim | 71 +++++++++++++++++++++++++++++++++++ src/testdir/test_vim9_disassemble.vim | 32 ++++++++++++++++ 2 files changed, 103 insertions(+) (limited to 'src/testdir') diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim index 17252605f7..d6c55bfffa 100644 --- a/src/testdir/test_vim9_class.vim +++ b/src/testdir/test_vim9_class.vim @@ -10349,4 +10349,75 @@ def Test_Ref_Class_Within_Same_Class() v9.CheckScriptFailure(lines, 'E1347: Not a valid interface: A', 3) enddef +" Test for using a compound operator from a lambda function in an object method +def Test_compound_op_in_objmethod_lambda() + # Test using the "+=" operator + var lines =<< trim END + vim9script + class A + var n: number = 10 + def Foo() + var Fn = () => { + this.n += 1 + } + Fn() + enddef + endclass + + var a = A.new() + a.Foo() + assert_equal(11, a.n) + END + v9.CheckScriptSuccess(lines) + + # Test using the "..=" operator + lines =<< trim END + vim9script + class A + var s: string = "a" + def Foo() + var Fn = () => { + this.s ..= "a" + } + Fn() + enddef + endclass + + var a = A.new() + a.Foo() + a.Foo() + assert_equal("aaa", a.s) + END + v9.CheckScriptSuccess(lines) +enddef + +" call a lambda function in one object from another object +def Test_lambda_invocation_across_classes() + var lines =<< trim END + vim9script + class A + var s: string = "foo" + def GetFn(): func + var Fn = (): string => { + return this.s + } + return Fn + enddef + endclass + + class B + var s: string = "bar" + def GetFn(): func + var a = A.new() + return a.GetFn() + enddef + endclass + + var b = B.new() + var Fn = b.GetFn() + assert_equal("foo", Fn()) + END + v9.CheckScriptSuccess(lines) +enddef + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim index 645b04bdd0..1daef222db 100644 --- a/src/testdir/test_vim9_disassemble.vim +++ b/src/testdir/test_vim9_disassemble.vim @@ -3436,4 +3436,36 @@ def Test_disassemble_object_len() unlet g:instr enddef +" Disassemble instructions for using a compound operator in a closure +def Test_disassemble_compound_op_in_closure() + var lines =<< trim END + vim9script + class A + var foo: number = 1 + def Foo(): func + var Fn = () => { + this.foo += 1 + } + return Fn + enddef + endclass + var a = A.new() + var Lambda = a.Foo() + var num = matchstr(string(Lambda), '\d\+') + g:instr = execute($'disassemble {num}') + END + v9.CheckScriptSuccess(lines) + assert_match('\d\+\_s*' .. + 'this.foo += 1\_s*' .. + '0 LOADOUTER level 0 $0\_s*' .. + '1 OBJ_MEMBER 0\_s*' .. + '2 PUSHNR 1\_s*' .. + '3 OPNR +\_s*' .. + '4 PUSHNR 0\_s*' .. + '5 LOADOUTER level 0 $0\_s*' .. + '6 STOREINDEX object\_s*' .. + '7 RETURN void', g:instr) + unlet g:instr +enddef + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker -- cgit v1.2.3