forked from aniani/vim
patch 9.0.2076: Vim9: No support for type aliases
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>
This commit is contained in:
committed by
Christian Brabandt
parent
4bca4897a1
commit
ec3cebbd2b
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user