diff options
author | Yegappan Lakshmanan <yegappan@yahoo.com> | 2023-10-04 19:47:52 +0200 |
---|---|---|
committer | Christian Brabandt <cb@256bit.org> | 2023-10-04 19:47:52 +0200 |
commit | fe7b20a1a39dc645a6ea7ae925512f9227fd1695 (patch) | |
tree | d7bdcc5c9d3617324dbbab0dd13ae44e64ebc0fd /src/testdir/test_vim9_class.vim | |
parent | b9a974df9e22c7b56d8faac3246fb5f80a9351d4 (diff) |
patch 9.0.1977: Vim9: object members can change typev9.0.1977
Problem: Vim9: object members can change type
Solution: Check type during assignment to object/class var
closes: #13127
closes: #13262
Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Diffstat (limited to 'src/testdir/test_vim9_class.vim')
-rw-r--r-- | src/testdir/test_vim9_class.vim | 386 |
1 files changed, 386 insertions, 0 deletions
diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim index 4a92a3d3a2..2aa5c08339 100644 --- a/src/testdir/test_vim9_class.vim +++ b/src/testdir/test_vim9_class.vim @@ -6418,4 +6418,390 @@ def Test_extended_obj_method_type_check() v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<B>): object<A>', 20) enddef +" Test type checking for class variable in assignments +func Test_class_variable_complex_type_check() + " class variable with a specific type. Try assigning a different type at + " script level. + let lines =<< trim END + vim9script + def Foo(l: list<dict<number>>): dict<list<number>> + return {} + enddef + class A + public static Fn: func(list<dict<number>>): dict<list<number>> = Foo + endclass + test_garbagecollect_now() + A.Fn = "abc" + END + call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 9) + + " class variable with a specific type. Try assigning a different type at + " class def method level. + let lines =<< trim END + vim9script + def Foo(l: list<dict<number>>): dict<list<number>> + return {} + enddef + class A + public static Fn: func(list<dict<number>>): dict<list<number>> = Foo + def Bar() + Fn = "abc" + enddef + endclass + var a = A.new() + test_garbagecollect_now() + a.Bar() + END + call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 1) + + " class variable with a specific type. Try assigning a different type at + " script def method level. + let lines =<< trim END + vim9script + def Foo(l: list<dict<number>>): dict<list<number>> + return {} + enddef + class A + public static Fn: func(list<dict<number>>): dict<list<number>> = Foo + endclass + def Bar() + A.Fn = "abc" + enddef + test_garbagecollect_now() + Bar() + END + call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 1) + + " class variable without any type. Should be set to the initialization + " expression type. Try assigning a different type from script level. + let lines =<< trim END + vim9script + def Foo(l: list<dict<number>>): dict<list<number>> + return {} + enddef + class A + public static Fn = Foo + endclass + test_garbagecollect_now() + A.Fn = "abc" + END + call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 9) + + " class variable without any type. Should be set to the initialization + " expression type. Try assigning a different type at class def level. + let lines =<< trim END + vim9script + def Foo(l: list<dict<number>>): dict<list<number>> + return {} + enddef + class A + public static Fn = Foo + def Bar() + Fn = "abc" + enddef + endclass + var a = A.new() + test_garbagecollect_now() + a.Bar() + END + call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 1) + + " class variable without any type. Should be set to the initialization + " expression type. Try assigning a different type at script def level. + let lines =<< trim END + vim9script + def Foo(l: list<dict<number>>): dict<list<number>> + return {} + enddef + class A + public static Fn = Foo + endclass + def Bar() + A.Fn = "abc" + enddef + test_garbagecollect_now() + Bar() + END + call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 1) + + " class variable with 'any" type. Can be assigned different types. + let lines =<< trim END + vim9script + def Foo(l: list<dict<number>>): dict<list<number>> + return {} + enddef + class A + public static Fn: any = Foo + public static Fn2: any + endclass + test_garbagecollect_now() + assert_equal('func(list<dict<number>>): dict<list<number>>', typename(A.Fn)) + A.Fn = "abc" + test_garbagecollect_now() + assert_equal('string', typename(A.Fn)) + A.Fn2 = Foo + test_garbagecollect_now() + assert_equal('func(list<dict<number>>): dict<list<number>>', typename(A.Fn2)) + A.Fn2 = "xyz" + test_garbagecollect_now() + assert_equal('string', typename(A.Fn2)) + END + call v9.CheckSourceSuccess(lines) + + " class variable with 'any" type. Can be assigned different types. + let lines =<< trim END + vim9script + def Foo(l: list<dict<number>>): dict<list<number>> + return {} + enddef + class A + public static Fn: any = Foo + public static Fn2: any + + def Bar() + assert_equal('func(list<dict<number>>): dict<list<number>>', typename(Fn)) + Fn = "abc" + assert_equal('string', typename(Fn)) + Fn2 = Foo + assert_equal('func(list<dict<number>>): dict<list<number>>', typename(Fn2)) + Fn2 = "xyz" + assert_equal('string', typename(Fn2)) + enddef + endclass + var a = A.new() + test_garbagecollect_now() + a.Bar() + test_garbagecollect_now() + A.Fn = Foo + a.Bar() + END + call v9.CheckSourceSuccess(lines) + + " class variable with 'any" type. Can be assigned different types. + let lines =<< trim END + vim9script + def Foo(l: list<dict<number>>): dict<list<number>> + return {} + enddef + class A + public static Fn: any = Foo + public static Fn2: any + endclass + + def Bar() + assert_equal('func(list<dict<number>>): dict<list<number>>', typename(A.Fn)) + A.Fn = "abc" + assert_equal('string', typename(A.Fn)) + A.Fn2 = Foo + assert_equal('func(list<dict<number>>): dict<list<number>>', typename(A.Fn2)) + A.Fn2 = "xyz" + assert_equal('string', typename(A.Fn2)) + enddef + Bar() + test_garbagecollect_now() + A.Fn = Foo + Bar() + END + call v9.CheckSourceSuccess(lines) +endfunc + +" Test type checking for object variable in assignments +func Test_object_variable_complex_type_check() + " object variable with a specific type. Try assigning a different type at + " script level. + let lines =<< trim END + vim9script + def Foo(l: list<dict<number>>): dict<list<number>> + return {} + enddef + class A + public this.Fn: func(list<dict<number>>): dict<list<number>> = Foo + endclass + var a = A.new() + test_garbagecollect_now() + a.Fn = "abc" + END + call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 10) + + " object variable with a specific type. Try assigning a different type at + " object def method level. + let lines =<< trim END + vim9script + def Foo(l: list<dict<number>>): dict<list<number>> + return {} + enddef + class A + public this.Fn: func(list<dict<number>>): dict<list<number>> = Foo + def Bar() + this.Fn = "abc" + this.Fn = Foo + enddef + endclass + var a = A.new() + test_garbagecollect_now() + a.Bar() + END + call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 1) + + " object variable with a specific type. Try assigning a different type at + " script def method level. + let lines =<< trim END + vim9script + def Foo(l: list<dict<number>>): dict<list<number>> + return {} + enddef + class A + public this.Fn: func(list<dict<number>>): dict<list<number>> = Foo + endclass + def Bar() + var a = A.new() + a.Fn = "abc" + a.Fn = Foo + enddef + test_garbagecollect_now() + Bar() + END + call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 2) + + " object variable without any type. Should be set to the initialization + " expression type. Try assigning a different type from script level. + let lines =<< trim END + vim9script + def Foo(l: list<dict<number>>): dict<list<number>> + return {} + enddef + class A + public this.Fn = Foo + endclass + var a = A.new() + test_garbagecollect_now() + a.Fn = "abc" + END + call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 10) + + " object variable without any type. Should be set to the initialization + " expression type. Try assigning a different type at object def level. + let lines =<< trim END + vim9script + def Foo(l: list<dict<number>>): dict<list<number>> + return {} + enddef + class A + public this.Fn = Foo + def Bar() + this.Fn = "abc" + this.Fn = Foo + enddef + endclass + var a = A.new() + test_garbagecollect_now() + a.Bar() + END + call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 1) + + " object variable without any type. Should be set to the initialization + " expression type. Try assigning a different type at script def level. + let lines =<< trim END + vim9script + def Foo(l: list<dict<number>>): dict<list<number>> + return {} + enddef + class A + public this.Fn = Foo + endclass + def Bar() + var a = A.new() + a.Fn = "abc" + a.Fn = Foo + enddef + test_garbagecollect_now() + Bar() + END + call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 2) + + " object variable with 'any" type. Can be assigned different types. + let lines =<< trim END + vim9script + def Foo(l: list<dict<number>>): dict<list<number>> + return {} + enddef + class A + public this.Fn: any = Foo + public this.Fn2: any + endclass + + var a = A.new() + test_garbagecollect_now() + assert_equal('func(list<dict<number>>): dict<list<number>>', typename(a.Fn)) + a.Fn = "abc" + test_garbagecollect_now() + assert_equal('string', typename(a.Fn)) + a.Fn2 = Foo + test_garbagecollect_now() + assert_equal('func(list<dict<number>>): dict<list<number>>', typename(a.Fn2)) + a.Fn2 = "xyz" + test_garbagecollect_now() + assert_equal('string', typename(a.Fn2)) + END + call v9.CheckSourceSuccess(lines) + + " object variable with 'any" type. Can be assigned different types. + let lines =<< trim END + vim9script + def Foo(l: list<dict<number>>): dict<list<number>> + return {} + enddef + class A + public this.Fn: any = Foo + public this.Fn2: any + + def Bar() + assert_equal('func(list<dict<number>>): dict<list<number>>', typename(this.Fn)) + this.Fn = "abc" + assert_equal('string', typename(this.Fn)) + this.Fn2 = Foo + assert_equal('func(list<dict<number>>): dict<list<number>>', typename(this.Fn2)) + this.Fn2 = "xyz" + assert_equal('string', typename(this.Fn2)) + enddef + endclass + + var a = A.new() + test_garbagecollect_now() + a.Bar() + test_garbagecollect_now() + a.Fn = Foo + a.Bar() + END + call v9.CheckSourceSuccess(lines) + + " object variable with 'any" type. Can be assigned different types. + let lines =<< trim END + vim9script + def Foo(l: list<dict<number>>): dict<list<number>> + return {} + enddef + class A + public this.Fn: any = Foo + public this.Fn2: any + endclass + + def Bar() + var a = A.new() + assert_equal('func(list<dict<number>>): dict<list<number>>', typename(a.Fn)) + a.Fn = "abc" + assert_equal('string', typename(a.Fn)) + a.Fn2 = Foo + assert_equal('func(list<dict<number>>): dict<list<number>>', typename(a.Fn2)) + a.Fn2 = "xyz" + assert_equal('string', typename(a.Fn2)) + enddef + test_garbagecollect_now() + Bar() + test_garbagecollect_now() + Bar() + END + call v9.CheckSourceSuccess(lines) +endfunc + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker |