patch 9.0.2038: Vim9: object method funcref not cleaned up after use
Problem: Vim9: object method funcref not cleaned up after use
Solution: Clean up type stack after using object method funcref,
remove now longer used ISN_DEFEROBJ instrunction
closes: #13360
Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim
index b9f2910..8b08dc1 100644
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -8022,4 +8022,256 @@
v9.CheckSourceSuccess(lines)
enddef
+" Test for using object methods as popup callback functions
+def Test_objmethod_popup_callback()
+ # Use the popup from the script level
+ var lines =<< trim END
+ vim9script
+
+ class A
+ this.selection: number = -1
+ this.filterkeys: list<string> = []
+
+ def PopupFilter(id: number, key: string): bool
+ add(this.filterkeys, key)
+ return popup_filter_yesno(id, key)
+ enddef
+
+ def PopupCb(id: number, result: number)
+ this.selection = result ? 100 : 200
+ enddef
+ endclass
+
+ var a = A.new()
+ feedkeys('', 'xt')
+ var winid = popup_create('Y/N?',
+ {filter: a.PopupFilter, callback: a.PopupCb})
+ feedkeys('y', 'xt')
+ popup_close(winid)
+ assert_equal(100, a.selection)
+ assert_equal(['y'], a.filterkeys)
+ feedkeys('', 'xt')
+ winid = popup_create('Y/N?',
+ {filter: a.PopupFilter, callback: a.PopupCb})
+ feedkeys('n', 'xt')
+ popup_close(winid)
+ assert_equal(200, a.selection)
+ assert_equal(['y', 'n'], a.filterkeys)
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Use the popup from a def function
+ lines =<< trim END
+ vim9script
+
+ class A
+ this.selection: number = -1
+ this.filterkeys: list<string> = []
+
+ def PopupFilter(id: number, key: string): bool
+ add(this.filterkeys, key)
+ return popup_filter_yesno(id, key)
+ enddef
+
+ def PopupCb(id: number, result: number)
+ this.selection = result ? 100 : 200
+ enddef
+ endclass
+
+ def Foo()
+ var a = A.new()
+ feedkeys('', 'xt')
+ var winid = popup_create('Y/N?',
+ {filter: a.PopupFilter, callback: a.PopupCb})
+ feedkeys('y', 'xt')
+ popup_close(winid)
+ assert_equal(100, a.selection)
+ assert_equal(['y'], a.filterkeys)
+ feedkeys('', 'xt')
+ winid = popup_create('Y/N?',
+ {filter: a.PopupFilter, callback: a.PopupCb})
+ feedkeys('n', 'xt')
+ popup_close(winid)
+ assert_equal(200, a.selection)
+ assert_equal(['y', 'n'], a.filterkeys)
+ enddef
+ Foo()
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for using class methods as popup callback functions
+def Test_classmethod_popup_callback()
+ # Use the popup from the script level
+ var lines =<< trim END
+ vim9script
+
+ class A
+ static selection: number = -1
+ static filterkeys: list<string> = []
+
+ static def PopupFilter(id: number, key: string): bool
+ add(filterkeys, key)
+ return popup_filter_yesno(id, key)
+ enddef
+
+ static def PopupCb(id: number, result: number)
+ selection = result ? 100 : 200
+ enddef
+ endclass
+
+ feedkeys('', 'xt')
+ var winid = popup_create('Y/N?',
+ {filter: A.PopupFilter, callback: A.PopupCb})
+ feedkeys('y', 'xt')
+ popup_close(winid)
+ assert_equal(100, A.selection)
+ assert_equal(['y'], A.filterkeys)
+ feedkeys('', 'xt')
+ winid = popup_create('Y/N?',
+ {filter: A.PopupFilter, callback: A.PopupCb})
+ feedkeys('n', 'xt')
+ popup_close(winid)
+ assert_equal(200, A.selection)
+ assert_equal(['y', 'n'], A.filterkeys)
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Use the popup from a def function
+ lines =<< trim END
+ vim9script
+
+ class A
+ static selection: number = -1
+ static filterkeys: list<string> = []
+
+ static def PopupFilter(id: number, key: string): bool
+ add(filterkeys, key)
+ return popup_filter_yesno(id, key)
+ enddef
+
+ static def PopupCb(id: number, result: number)
+ selection = result ? 100 : 200
+ enddef
+ endclass
+
+ def Foo()
+ feedkeys('', 'xt')
+ var winid = popup_create('Y/N?',
+ {filter: A.PopupFilter, callback: A.PopupCb})
+ feedkeys('y', 'xt')
+ popup_close(winid)
+ assert_equal(100, A.selection)
+ assert_equal(['y'], A.filterkeys)
+ feedkeys('', 'xt')
+ winid = popup_create('Y/N?',
+ {filter: A.PopupFilter, callback: A.PopupCb})
+ feedkeys('n', 'xt')
+ popup_close(winid)
+ assert_equal(200, A.selection)
+ assert_equal(['y', 'n'], A.filterkeys)
+ enddef
+ Foo()
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for using an object method as a timer callback function
+def Test_objmethod_timer_callback()
+ # Use the timer callback from script level
+ var lines =<< trim END
+ vim9script
+
+ class A
+ this.timerTick: number = -1
+ def TimerCb(timerID: number)
+ this.timerTick = 6
+ enddef
+ endclass
+
+ var a = A.new()
+ timer_start(0, a.TimerCb)
+ var maxWait = 5
+ while maxWait > 0 && a.timerTick == -1
+ :sleep 10m
+ maxWait -= 1
+ endwhile
+ assert_equal(6, a.timerTick)
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Use the timer callback from a def function
+ lines =<< trim END
+ vim9script
+
+ class A
+ this.timerTick: number = -1
+ def TimerCb(timerID: number)
+ this.timerTick = 6
+ enddef
+ endclass
+
+ def Foo()
+ var a = A.new()
+ timer_start(0, a.TimerCb)
+ var maxWait = 5
+ while maxWait > 0 && a.timerTick == -1
+ :sleep 10m
+ maxWait -= 1
+ endwhile
+ assert_equal(6, a.timerTick)
+ enddef
+ Foo()
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for using a class method as a timer callback function
+def Test_classmethod_timer_callback()
+ # Use the timer callback from script level
+ var lines =<< trim END
+ vim9script
+
+ class A
+ static timerTick: number = -1
+ static def TimerCb(timerID: number)
+ timerTick = 6
+ enddef
+ endclass
+
+ timer_start(0, A.TimerCb)
+ var maxWait = 5
+ while maxWait > 0 && A.timerTick == -1
+ :sleep 10m
+ maxWait -= 1
+ endwhile
+ assert_equal(6, A.timerTick)
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Use the timer callback from a def function
+ lines =<< trim END
+ vim9script
+
+ class A
+ static timerTick: number = -1
+ static def TimerCb(timerID: number)
+ timerTick = 6
+ enddef
+ endclass
+
+ def Foo()
+ timer_start(0, A.TimerCb)
+ var maxWait = 5
+ while maxWait > 0 && A.timerTick == -1
+ :sleep 10m
+ maxWait -= 1
+ endwhile
+ assert_equal(6, A.timerTick)
+ enddef
+ Foo()
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker