summaryrefslogtreecommitdiffstats
path: root/src/testdir
diff options
context:
space:
mode:
authorYegappan Lakshmanan <yegappan@yahoo.com>2023-10-27 19:35:26 +0200
committerChristian Brabandt <cb@256bit.org>2023-10-27 19:35:26 +0200
commitec3cebbd2b6b7583d2f683f5e66345163ec122aa (patch)
tree66f0c9b69e88fa4a0d35ae738f687b5679bc56e0 /src/testdir
parent4bca4897a12dfb91b3b27e3083fd5f370bd857d1 (diff)
patch 9.0.2076: Vim9: No support for type aliasesv9.0.2076
Problem: Vim9: No support for type aliases Solution: Implement :type command A type definition is giving a name to a type specification. This also known type alias. :type ListOfStrings = list<string> The type alias can be used wherever a built-in type can be used. The type alias name must start with an upper case character. closes: #13407 Signed-off-by: Christian Brabandt <cb@256bit.org> Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Diffstat (limited to 'src/testdir')
-rw-r--r--src/testdir/test_vim9_class.vim12
-rw-r--r--src/testdir/test_vim9_script.vim380
2 files changed, 385 insertions, 7 deletions
diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim
index 1c309e4f0c..a8d0fd6697 100644
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -170,7 +170,7 @@ def Test_class_basic()
if A
endif
END
- v9.CheckSourceFailure(lines, 'E1319: Using a class as a Number', 4)
+ v9.CheckSourceFailure(lines, 'E1319: Using a Class as a Number', 4)
# Test for using object as a bool
lines =<< trim END
@@ -181,7 +181,7 @@ def Test_class_basic()
if a
endif
END
- v9.CheckSourceFailure(lines, 'E1320: Using an object as a Number', 5)
+ v9.CheckSourceFailure(lines, 'E1320: Using an Object as a Number', 5)
# Test for using class as a float
lines =<< trim END
@@ -190,7 +190,7 @@ def Test_class_basic()
endclass
sort([1.1, A], 'f')
END
- v9.CheckSourceFailure(lines, 'E1321: Using a class as a Float', 4)
+ v9.CheckSourceFailure(lines, 'E1321: Using a Class as a Float', 4)
# Test for using object as a float
lines =<< trim END
@@ -200,7 +200,7 @@ def Test_class_basic()
var a = A.new()
sort([1.1, a], 'f')
END
- v9.CheckSourceFailure(lines, 'E1322: Using an object as a Float', 5)
+ v9.CheckSourceFailure(lines, 'E1322: Using an Object as a Float', 5)
# Test for using class as a string
lines =<< trim END
@@ -209,7 +209,7 @@ def Test_class_basic()
endclass
:exe 'call ' .. A
END
- v9.CheckSourceFailure(lines, 'E1323: Using a class as a String', 4)
+ v9.CheckSourceFailure(lines, 'E1323: Using a Class as a String', 4)
# Test for using object as a string
lines =<< trim END
@@ -219,7 +219,7 @@ def Test_class_basic()
var a = A.new()
:exe 'call ' .. a
END
- v9.CheckSourceFailure(lines, 'E1324: Using an object as a String', 5)
+ v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 5)
# Test creating a class with member variables and methods, calling a object
# method. Check for using type() and typename() with a class and an object.
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index cac8484977..2bc9b14aa3 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -4722,7 +4722,7 @@ def Test_defer_after_exception()
assert_equal([2, 3, 1, 4, 5, 6, 7], callTrace)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
" Test for multiple deferred function which throw exceptions.
@@ -4780,6 +4780,384 @@ def Test_multidefer_with_exception()
assert_equal('E605: Exception not caught: InnerException', v:errmsg)
assert_equal([11, 9, 10, 7, 8, 5, 1, 3, 4, 12, 15, 16], callTrace)
END
+ v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for :type command to create type aliases
+def Test_typealias()
+ var lines =<< trim END
+ vim9script
+ type ListOfStrings = list<string>
+ var a: ListOfStrings = ['a', 'b']
+ assert_equal(['a', 'b'], a)
+ def Foo(b: ListOfStrings): ListOfStrings
+ var c: ListOfStrings = ['c', 'd']
+ assert_equal(['c', 'd'], c)
+ return b
+ enddef
+ assert_equal(['e', 'f'], Foo(['e', 'f']))
+ assert_equal('typealias<list<string>>', typename(ListOfStrings))
+ assert_equal(v:t_typealias, type(ListOfStrings))
+ assert_equal('ListOfStrings', string(ListOfStrings))
+ assert_equal(false, null == ListOfStrings)
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Use :type outside a Vim9 script
+ lines =<< trim END
+ type Index = number
+ END
+ v9.CheckSourceFailure(lines, 'E1393: Type can only be defined in Vim9 script', 1)
+
+ # Use :type without any arguments
+ lines =<< trim END
+ vim9script
+ type
+ END
+ v9.CheckSourceFailure(lines, 'E1397: Missing type alias name', 2)
+
+ # Use :type with a name but no type
+ lines =<< trim END
+ vim9script
+ type MyType
+ END
+ v9.CheckSourceFailure(lines, "E398: Missing '=': ", 2)
+
+ # Use :type with a name but no type following "="
+ lines =<< trim END
+ vim9script
+ type MyType =
+ END
+ v9.CheckSourceFailure(lines, 'E1398: Missing type alias type', 2)
+
+ # No space before or after "="
+ lines =<< trim END
+ vim9script
+ type MyType=number
+ END
+ v9.CheckSourceFailure(lines, 'E1315: White space required after name: MyType=number', 2)
+
+ # No space after "="
+ lines =<< trim END
+ vim9script
+ type MyType =number
+ END
+ v9.CheckSourceFailure(lines, "E1069: White space required after '=': =number", 2)
+
+ # type alias without "="
+ lines =<< trim END
+ vim9script
+ type Index number
+ END
+ v9.CheckSourceFailure(lines, "E398: Missing '=': number", 2)
+
+ # type alias for a non-existing type
+ lines =<< trim END
+ vim9script
+ type Index = integer
+ END
+ v9.CheckSourceFailure(lines, 'E1010: Type not recognized: integer', 2)
+
+ # type alias starting with lower-case letter
+ lines =<< trim END
+ vim9script
+ type index number
+ END
+ v9.CheckSourceFailure(lines, 'E1394: Type name must start with an uppercase letter: index number', 2)
+
+ # No white space following the alias name
+ lines =<< trim END
+ vim9script
+ type Index:number
+ END
+ v9.CheckSourceFailure(lines, 'E1315: White space required after name: Index:number', 2)
+
+ # something following the type alias
+ lines =<< trim END
+ vim9script
+ type ListOfNums = list<number> string
+ END
+ v9.CheckSourceFailure(lines, 'E488: Trailing characters: string', 2)
+
+ # type alias name collides with a variable name
+ lines =<< trim END
+ vim9script
+ var ListOfNums: number = 10
+ type ListOfNums = list<number>
+ END
+ v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "ListOfNums"', 3)
+
+ # duplicate type alias name
+ lines =<< trim END
+ vim9script
+ type MyList = list<number>
+ type MyList = list<string>
+ END
+ v9.CheckSourceFailure(lines, 'E1396: Type alias "MyList" already exists', 3)
+
+ # Sourcing a script twice (which will free script local variables)
+ lines =<< trim END
+ vim9script
+ class C
+ endclass
+ type AC = C
+ assert_equal('typealias<object<C>>', typename(AC))
+ END
+ new
+ setline(1, lines)
+ :source
+ :source
+ bw!
+
+ # Assigning to a type alias (script level)
+ lines =<< trim END
+ vim9script
+ type MyType = list<number>
+ MyType = [1, 2, 3]
+ END
+ v9.CheckSourceFailure(lines, 'E1395: Type alias "MyType" cannot be used as a variable', 3)
+
+ # Assigning a type alias (def function level)
+ lines =<< trim END
+ vim9script
+ type A = list<string>
+ def Foo()
+ var x = A
+ enddef
+ Foo()
+ END
+ v9.CheckSourceFailure(lines, 'E1395: Type alias "A" cannot be used as a variable', 1)
+
+ # Using type alias in an expression (script level)
+ lines =<< trim END
+ vim9script
+ type MyType = list<number>
+ assert_fails('var m = MyType', 'E1395: Type alias "MyType" cannot be used as a variable')
+ assert_fails('var i = MyType + 1', 'E1395: Type alias "MyType" cannot be used as a variable')
+ assert_fails('var f = 1.0 + MyType', 'E1395: Type alias "MyType" cannot be used as a variable')
+ assert_fails('MyType += 10', 'E1395: Type alias "MyType" cannot be used as a variable')
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Using type alias in an expression (def function level)
+ lines =<< trim END
+ vim9script
+ type MyType = list<number>
+ def Foo()
+ var x = MyType + 1
+ enddef
+ Foo()
+ END
+ v9.CheckSourceFailure(lines, 'E1395: Type alias "MyType" cannot be used as a variable', 1)
+
+ # Using type alias in an expression (def function level)
+ lines =<< trim END
+ vim9script
+ type MyType = list<number>
+ def Foo()
+ MyType = list<string>
+ enddef
+ Foo()
+ END
+ v9.CheckSourceFailure(lines, 'E46: Cannot change read-only variable "MyType"', 1)
+
+ # Using type alias in an expression (def function level)
+ lines =<< trim END
+ vim9script
+ type MyType = list<number>
+ def Foo()
+ MyType += 10
+ enddef
+ Foo()
+ END
+ v9.CheckSourceFailure(lines, 'E46: Cannot change read-only variable "MyType"', 1)
+
+ # Creating a typealias in a def function
+ lines =<< trim END
+ vim9script
+ def Foo()
+ var n: number = 10
+ type A = list<string>
+ enddef
+ defcompile
+ END
+ v9.CheckSourceFailure(lines, 'E1399: Type can only be used in a script', 2)
+
+ # json_encode should fail with a type alias
+ lines =<< trim END
+ vim9script
+ type A = list<string>
+ var x = json_encode(A)
+ END
+ v9.CheckSourceFailure(lines, 'E1161: Cannot json encode a typealias', 3)
+
+ # Comparing type alias with a number (script level)
+ lines =<< trim END
+ vim9script
+ type A = list<string>
+ var n: number
+ var x = A == n
+ END
+ v9.CheckSourceFailure(lines, 'E1072: Cannot compare typealias with number', 4)
+
+ # Comparing type alias with a number (def function level)
+ lines =<< trim END
+ vim9script
+ type A = list<string>
+ def Foo()
+ var n: number
+ var x = A == n
+ enddef
+ Foo()
+ END
+ v9.CheckSourceFailure(lines, 'E1395: Type alias "A" cannot be used as a variable', 2)
+enddef
+
+" Test for exporting and importing type aliases
+def Test_import_typealias()
+ var lines =<< trim END
+ vim9script
+ export type MyType = list<number>
+ END
+ writefile(lines, 'Xtypeexport.vim', 'D')
+
+ lines =<< trim END
+ vim9script
+ import './Xtypeexport.vim' as A
+
+ var myList: A.MyType = [1, 2, 3]
+ def Foo(l: A.MyType)
+ assert_equal([1, 2, 3], l)
+ enddef
+ Foo(myList)
+ END
+ v9.CheckScriptSuccess(lines)
+
+ # Use a non existing type alias
+ lines =<< trim END
+ vim9script
+ import './Xtypeexport.vim' as A
+
+ var myNum: A.SomeType = 10
+ END
+ v9.CheckScriptFailure(lines, 'E1010: Type not recognized: A.SomeType = 10', 4)
+
+ # Use a type alias that is not exported
+ lines =<< trim END
+ vim9script
+ type NewType = dict<string>
+ END
+ writefile(lines, 'Xtypeexport2.vim', 'D')
+ lines =<< trim END
+ vim9script
+ import './Xtypeexport2.vim' as A
+
+ var myDict: A.NewType = {}
+ END
+ v9.CheckScriptFailure(lines, 'E1049: Item not exported in script: NewType', 4)
+
+ # Using the same name as an imported type alias
+ lines =<< trim END
+ vim9script
+ export type MyType2 = list<number>
+ END
+ writefile(lines, 'Xtypeexport3.vim', 'D')
+ lines =<< trim END
+ vim9script
+ import './Xtypeexport3.vim' as A
+
+ type MyType2 = A.MyType2
+ var myList1: A.MyType2 = [1, 2, 3]
+ var myList2: MyType2 = [4, 5, 6]
+ assert_equal([1, 2, 3], myList1)
+ assert_equal([4, 5, 6], myList2)
+ END
+ v9.CheckScriptSuccess(lines)
+enddef
+
+" Test for using typealias as a def function argument and return type
+def Test_typealias_func_argument()
+ var lines =<< trim END
+ vim9script
+ type A = list<number>
+ def Foo(l: A): A
+ assert_equal([1, 2], l)
+ return l
+ enddef
+ var x: A = [1, 2]
+ assert_equal([1, 2], Foo(x))
+ END
+ v9.CheckScriptSuccess(lines)
+
+ # passing a type alias variable to a function expecting a specific type
+ lines =<< trim END
+ vim9script
+ type A = list<number>
+ def Foo(l: list<number>)
+ assert_equal([1, 2], l)
+ enddef
+ var x: A = [1, 2]
+ Foo(x)
+ END
+ v9.CheckScriptSuccess(lines)
+
+ # passing a type alias variable to a function expecting any
+ lines =<< trim END
+ vim9script
+ type A = list<number>
+ def Foo(l: any)
+ assert_equal([1, 2], l)
+ enddef
+ var x: A = [1, 2]
+ Foo(x)
+ END
+ v9.CheckScriptSuccess(lines)
+enddef
+
+" Using a type alias with a builtin function
+def Test_typealias_with_builtin_functions()
+ var lines =<< trim END
+ vim9script
+ type A = list<func>
+ assert_equal(0, empty(A))
+ END
+ v9.CheckScriptSuccess(lines)
+
+ # Using a type alias with len()
+ lines =<< trim END
+ vim9script
+ type A = list<func>
+ var x = len(A)
+ END
+ v9.CheckScriptFailure(lines, 'E701: Invalid type for len()', 3)
+
+ # Using a type alias with eval()
+ lines =<< trim END
+ vim9script
+ type A = number
+ def Foo()
+ var x = eval("A")
+ enddef
+ Foo()
+ END
+ v9.CheckScriptFailure(lines, 'E1395: Type alias "A" cannot be used as a variable', 1)
+enddef
+
+" Test for type alias refcount
+def Test_typealias_refcount()
+ var lines =<< trim END
+ vim9script
+ type A = list<func>
+ assert_equal(1, test_refcount(A))
+ END
+ v9.CheckScriptSuccess(lines)
+
+ lines =<< trim END
+ vim9script
+ type B = list<number>
+ var x: B = []
+ assert_equal(1, test_refcount(B))
+ END
v9.CheckScriptSuccess(lines)
enddef