1
0
forked from aniani/vim

patch 9.0.2170: Vim9: no support for const/final class/objects vars

Problem:  Vim9: no support for const/final class/objects vars
Solution: Support final and const object and class variables

closes: #13655

Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Yegappan Lakshmanan
2023-12-16 14:11:19 +01:00
committed by Christian Brabandt
parent d8bf87c9fb
commit e5437c5427
12 changed files with 834 additions and 21 deletions

View File

@@ -9051,4 +9051,612 @@ def Test_compile_many_def_functions_in_funcref_instr()
assert_equal(0, v:shell_error)
enddef
" Test for 'final' class and object variables
def Test_final_class_object_variable()
# Test for changing a final object variable from an object function
var lines =<< trim END
vim9script
class A
final foo: string = "abc"
def Foo()
this.foo = "def"
enddef
endclass
defcompile A.Foo
END
v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
# Test for changing a final object variable from the 'new' function
lines =<< trim END
vim9script
class A
final s1: string
final s2: string
def new(this.s1)
this.s2 = 'def'
enddef
endclass
var a = A.new('abc')
assert_equal('abc', a.s1)
assert_equal('def', a.s2)
END
v9.CheckSourceSuccess(lines)
# Test for a final class variable
lines =<< trim END
vim9script
class A
static final s1: string = "abc"
endclass
assert_equal('abc', A.s1)
END
v9.CheckSourceSuccess(lines)
# Test for changing a final class variable from a class function
lines =<< trim END
vim9script
class A
static final s1: string = "abc"
static def Foo()
s1 = "def"
enddef
endclass
A.Foo()
END
v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
# Test for changing a public final class variable at script level
lines =<< trim END
vim9script
class A
public static final s1: string = "abc"
endclass
assert_equal('abc', A.s1)
A.s1 = 'def'
END
v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
# Test for changing a public final class variable from a class function
lines =<< trim END
vim9script
class A
public static final s1: string = "abc"
static def Foo()
s1 = "def"
enddef
endclass
A.Foo()
END
v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
# Test for changing a public final class variable from a function
lines =<< trim END
vim9script
class A
public static final s1: string = "abc"
endclass
def Foo()
A.s1 = 'def'
enddef
defcompile
END
v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
# Test for using a final variable of composite type
lines =<< trim END
vim9script
class A
public final l: list<number>
def new()
this.l = [1, 2]
enddef
def Foo()
this.l[0] = 3
this.l->add(4)
enddef
endclass
var a = A.new()
assert_equal([1, 2], a.l)
a.Foo()
assert_equal([3, 2, 4], a.l)
END
v9.CheckSourceSuccess(lines)
# Test for changing a final variable of composite type from another object
# function
lines =<< trim END
vim9script
class A
public final l: list<number> = [1, 2]
def Foo()
this.l = [3, 4]
enddef
endclass
var a = A.new()
a.Foo()
END
v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
# Test for modifying a final variable of composite type at script level
lines =<< trim END
vim9script
class A
public final l: list<number> = [1, 2]
endclass
var a = A.new()
a.l[0] = 3
a.l->add(4)
assert_equal([3, 2, 4], a.l)
END
v9.CheckSourceSuccess(lines)
# Test for modifying a final variable of composite type from a function
lines =<< trim END
vim9script
class A
public final l: list<number> = [1, 2]
endclass
def Foo()
var a = A.new()
a.l[0] = 3
a.l->add(4)
assert_equal([3, 2, 4], a.l)
enddef
Foo()
END
v9.CheckSourceSuccess(lines)
# Test for modifying a final variable of composite type from another object
# function
lines =<< trim END
vim9script
class A
public final l: list<number> = [1, 2]
def Foo()
this.l[0] = 3
this.l->add(4)
enddef
endclass
var a = A.new()
a.Foo()
assert_equal([3, 2, 4], a.l)
END
v9.CheckSourceSuccess(lines)
# Test for assigning a new value to a final variable of composite type at
# script level
lines =<< trim END
vim9script
class A
public final l: list<number> = [1, 2]
endclass
var a = A.new()
a.l = [3, 4]
END
v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
# Test for assigning a new value to a final variable of composite type from
# another object function
lines =<< trim END
vim9script
class A
public final l: list<number> = [1, 2]
def Foo()
this.l = [3, 4]
enddef
endclass
var a = A.new()
a.Foo()
END
v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
# Test for assigning a new value to a final variable of composite type from
# another function
lines =<< trim END
vim9script
class A
public final l: list<number> = [1, 2]
endclass
def Foo()
var a = A.new()
a.l = [3, 4]
enddef
Foo()
END
v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
# Error case: Use 'final' with just a variable name
lines =<< trim END
vim9script
class A
final foo
endclass
var a = A.new()
END
v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
# Error case: Use 'final' followed by 'public'
lines =<< trim END
vim9script
class A
final public foo: number
endclass
var a = A.new()
END
v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
# Error case: Use 'final' followed by 'static'
lines =<< trim END
vim9script
class A
final static foo: number
endclass
var a = A.new()
END
v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
# Error case: 'final' cannot be used in an interface
lines =<< trim END
vim9script
interface A
final foo: number = 10
endinterface
END
v9.CheckSourceFailure(lines, 'E1408: Final variable not supported in an interface', 3)
# Error case: 'final' not supported for an object method
lines =<< trim END
vim9script
class A
final def Foo()
enddef
endclass
END
v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
# Error case: 'final' not supported for a class method
lines =<< trim END
vim9script
class A
static final def Foo()
enddef
endclass
END
v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
enddef
" Test for 'const' class and object variables
def Test_const_class_object_variable()
# Test for changing a const object variable from an object function
var lines =<< trim END
vim9script
class A
const foo: string = "abc"
def Foo()
this.foo = "def"
enddef
endclass
defcompile A.Foo
END
v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
# Test for changing a const object variable from the 'new' function
lines =<< trim END
vim9script
class A
const s1: string
const s2: string
def new(this.s1)
this.s2 = 'def'
enddef
endclass
var a = A.new('abc')
assert_equal('abc', a.s1)
assert_equal('def', a.s2)
END
v9.CheckSourceSuccess(lines)
# Test for changing a const object variable from an object method called from
# the 'new' function
lines =<< trim END
vim9script
class A
const s1: string = 'abc'
def new()
this.ChangeStr()
enddef
def ChangeStr()
this.s1 = 'def'
enddef
endclass
var a = A.new()
END
v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
# Test for a const class variable
lines =<< trim END
vim9script
class A
static const s1: string = "abc"
endclass
assert_equal('abc', A.s1)
END
v9.CheckSourceSuccess(lines)
# Test for changing a const class variable from a class function
lines =<< trim END
vim9script
class A
static const s1: string = "abc"
static def Foo()
s1 = "def"
enddef
endclass
A.Foo()
END
v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
# Test for changing a public const class variable at script level
lines =<< trim END
vim9script
class A
public static const s1: string = "abc"
endclass
assert_equal('abc', A.s1)
A.s1 = 'def'
END
v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
# Test for changing a public const class variable from a class function
lines =<< trim END
vim9script
class A
public static const s1: string = "abc"
static def Foo()
s1 = "def"
enddef
endclass
A.Foo()
END
v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
# Test for changing a public const class variable from a function
lines =<< trim END
vim9script
class A
public static const s1: string = "abc"
endclass
def Foo()
A.s1 = 'def'
enddef
defcompile
END
v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
# Test for changing a const List item from an object function
lines =<< trim END
vim9script
class A
public const l: list<number>
def new()
this.l = [1, 2]
enddef
def Foo()
this.l[0] = 3
enddef
endclass
var a = A.new()
assert_equal([1, 2], a.l)
a.Foo()
END
v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
# Test for adding a value to a const List from an object function
lines =<< trim END
vim9script
class A
public const l: list<number>
def new()
this.l = [1, 2]
enddef
def Foo()
this.l->add(3)
enddef
endclass
var a = A.new()
a.Foo()
END
v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
# Test for reassigning a const List from an object function
lines =<< trim END
vim9script
class A
public const l: list<number> = [1, 2]
def Foo()
this.l = [3, 4]
enddef
endclass
var a = A.new()
a.Foo()
END
v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
# Test for changing a const List item at script level
lines =<< trim END
vim9script
class A
public const l: list<number> = [1, 2]
endclass
var a = A.new()
a.l[0] = 3
END
v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
# Test for adding a value to a const List item at script level
lines =<< trim END
vim9script
class A
public const l: list<number> = [1, 2]
endclass
var a = A.new()
a.l->add(4)
END
v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
# Test for changing a const List item from a function
lines =<< trim END
vim9script
class A
public const l: list<number> = [1, 2]
endclass
def Foo()
var a = A.new()
a.l[0] = 3
enddef
Foo()
END
v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 2)
# Test for adding a value to a const List item from a function
lines =<< trim END
vim9script
class A
public const l: list<number> = [1, 2]
endclass
def Foo()
var a = A.new()
a.l->add(4)
enddef
Foo()
END
v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 2)
# Test for changing a const List item from an object method
lines =<< trim END
vim9script
class A
public const l: list<number> = [1, 2]
def Foo()
this.l[0] = 3
enddef
endclass
var a = A.new()
a.Foo()
END
v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
# Test for adding a value to a const List item from an object method
lines =<< trim END
vim9script
class A
public const l: list<number> = [1, 2]
def Foo()
this.l->add(4)
enddef
endclass
var a = A.new()
a.Foo()
END
v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
# Test for reassigning a const List object variable at script level
lines =<< trim END
vim9script
class A
public const l: list<number> = [1, 2]
endclass
var a = A.new()
a.l = [3, 4]
END
v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
# Test for reassigning a const List object variable from an object method
lines =<< trim END
vim9script
class A
public const l: list<number> = [1, 2]
def Foo()
this.l = [3, 4]
enddef
endclass
var a = A.new()
a.Foo()
END
v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
# Test for reassigning a const List object variable from another function
lines =<< trim END
vim9script
class A
public const l: list<number> = [1, 2]
endclass
def Foo()
var a = A.new()
a.l = [3, 4]
enddef
Foo()
END
v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
# Error case: Use 'const' with just a variable name
lines =<< trim END
vim9script
class A
const foo
endclass
var a = A.new()
END
v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
# Error case: Use 'const' followed by 'public'
lines =<< trim END
vim9script
class A
const public foo: number
endclass
var a = A.new()
END
v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
# Error case: Use 'const' followed by 'static'
lines =<< trim END
vim9script
class A
const static foo: number
endclass
var a = A.new()
END
v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
# Error case: 'const' cannot be used in an interface
lines =<< trim END
vim9script
interface A
const foo: number = 10
endinterface
END
v9.CheckSourceFailure(lines, 'E1410: Const variable not supported in an interface', 3)
# Error case: 'const' not supported for an object method
lines =<< trim END
vim9script
class A
const def Foo()
enddef
endclass
END
v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
# Error case: 'const' not supported for a class method
lines =<< trim END
vim9script
class A
static const def Foo()
enddef
endclass
END
v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
enddef
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker