patch 9.0.1898: Vim9: restrict access to static vars

Problem:  Vim9: restrict access to static vars and methods
Solution: Class members are accesible only from the class where they are
          defined.

Based on the #13004 discussion, the following changes are made:

    1) Static variables and methods are accessible only using the class
       name and inside the class where they are defined.
    2) Static variables and methods can be used without the class name in
       the class where they are defined.
    3) Static variables of a super class are not copied to the sub class.
    4) A sub class can declare a class variable with the same name as the
       super class.
    5) When a method or member is found during compilation, use more
       specific error messages.

This aligns the Vim9 class variable/method implementation with the Dart
implementation.

Also while at it, ignore duplicate class and object methods.

The access level of an object method can however be changed in a
subclass.

For the tests, use the new CheckSourceFailure() function instead of the
CheckScriptFailure() function in the tests.

closes: #13086

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 be4eb2e..1796f5f 100644
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -8,56 +8,56 @@
       class NotWorking
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1316:')
+  v9.CheckSourceFailure(lines, 'E1316:')
 
   lines =<< trim END
       vim9script
       class notWorking
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1314:')
+  v9.CheckSourceFailure(lines, 'E1314:')
 
   lines =<< trim END
       vim9script
       class Not@working
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1315:')
+  v9.CheckSourceFailure(lines, 'E1315:')
 
   lines =<< trim END
       vim9script
       abstract noclass Something
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E475:')
+  v9.CheckSourceFailure(lines, 'E475:')
 
   lines =<< trim END
       vim9script
       abstract classy Something
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E475:')
+  v9.CheckSourceFailure(lines, 'E475:')
 
   lines =<< trim END
       vim9script
       class Something
       endcl
   END
-  v9.CheckScriptFailure(lines, 'E1065:')
+  v9.CheckSourceFailure(lines, 'E1065:')
 
   lines =<< trim END
       vim9script
       class Something
       endclass school's out
   END
-  v9.CheckScriptFailure(lines, 'E488:')
+  v9.CheckSourceFailure(lines, 'E488:')
 
   lines =<< trim END
       vim9script
       class Something
       endclass | echo 'done'
   END
-  v9.CheckScriptFailure(lines, 'E488:')
+  v9.CheckSourceFailure(lines, 'E488:')
 
   lines =<< trim END
       vim9script
@@ -65,7 +65,7 @@
         this
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1317:')
+  v9.CheckSourceFailure(lines, 'E1317:')
 
   lines =<< trim END
       vim9script
@@ -73,7 +73,7 @@
         this.
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1317:')
+  v9.CheckSourceFailure(lines, 'E1317:')
 
   lines =<< trim END
       vim9script
@@ -81,7 +81,7 @@
         this .count
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1317:')
+  v9.CheckSourceFailure(lines, 'E1317:')
 
   lines =<< trim END
       vim9script
@@ -89,7 +89,7 @@
         this. count
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1317:')
+  v9.CheckSourceFailure(lines, 'E1317:')
 
   lines =<< trim END
       vim9script
@@ -98,7 +98,7 @@
         that.count
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1318: Not a valid command in a class: that.count')
+  v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: that.count')
 
   lines =<< trim END
       vim9script
@@ -106,7 +106,7 @@
         this.count
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1022:')
+  v9.CheckSourceFailure(lines, 'E1022:')
 
   lines =<< trim END
       vim9script
@@ -117,7 +117,7 @@
       endclass
       var obj = Something.new()
   END
-  v9.CheckScriptFailure(lines, 'E1089:')
+  v9.CheckSourceFailure(lines, 'E1089:')
 
   lines =<< trim END
       vim9script
@@ -125,7 +125,7 @@
         this.count : number
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1059:')
+  v9.CheckSourceFailure(lines, 'E1059:')
 
   lines =<< trim END
       vim9script
@@ -133,7 +133,7 @@
         this.count:number
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1069:')
+  v9.CheckSourceFailure(lines, 'E1069:')
 
   # Test for unsupported comment specifier
   lines =<< trim END
@@ -143,7 +143,7 @@
       #{
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1170:')
+  v9.CheckSourceFailure(lines, 'E1170:')
 
   lines =<< trim END
       vim9script
@@ -171,7 +171,7 @@
       assert_equal('class<TextPosition>', typename(TextPosition))
       assert_equal('object<TextPosition>', typename(pos))
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # When referencing object methods, space cannot be used after a "."
   lines =<< trim END
@@ -184,7 +184,7 @@
     var a = A.new()
     var v = a. Foo()
   END
-  v9.CheckScriptFailure(lines, 'E1202:')
+  v9.CheckSourceFailure(lines, 'E1202:')
 
   # Using an object without specifying a method or a member variable
   lines =<< trim END
@@ -197,7 +197,7 @@
     var a = A.new()
     var v = a.
   END
-  v9.CheckScriptFailure(lines, 'E15:')
+  v9.CheckSourceFailure(lines, 'E15:')
 
   # Error when parsing the arguments of an object method.
   lines =<< trim END
@@ -209,7 +209,7 @@
     var a = A.new()
     var v = a.Foo(,)
   END
-  v9.CheckScriptFailure(lines, 'E15:')
+  v9.CheckSourceFailure(lines, 'E15:')
 
   lines =<< trim END
   vim9script
@@ -220,7 +220,7 @@
   endclass
   var a = A.new()
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 def Test_class_defined_twice()
@@ -232,7 +232,7 @@
       class There
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1041: Redefining script item: "There"')
+  v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "There"')
 
   # one class, reload same script twice is OK
   lines =<< trim END
@@ -259,7 +259,7 @@
       var buffers = BufferList.new()
       echo buffers.Current()
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 def Test_using_null_class()
@@ -276,7 +276,7 @@
         this.member = 'text'
       endinterface
   END
-  v9.CheckScriptFailure(lines, 'E476: Invalid command: endinterface, expected endclass')
+  v9.CheckSourceFailure(lines, 'E476: Invalid command: endinterface, expected endclass')
 
   lines =<< trim END
       vim9script
@@ -284,7 +284,7 @@
         this.member: string
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E476: Invalid command: endclass, expected endinterface')
+  v9.CheckSourceFailure(lines, 'E476: Invalid command: endclass, expected endinterface')
 enddef
 
 def Test_object_not_set()
@@ -299,7 +299,7 @@
       var db = {'xyz': 789}
       echo db[state.value]
   END
-  v9.CheckScriptFailure(lines, 'E1360:')
+  v9.CheckSourceFailure(lines, 'E1360:')
 
   lines =<< trim END
       vim9script
@@ -317,7 +317,7 @@
       enddef
       Func()
   END
-  v9.CheckScriptFailure(lines, 'E1360:')
+  v9.CheckSourceFailure(lines, 'E1360:')
 
   lines =<< trim END
       vim9script
@@ -337,7 +337,7 @@
       var bg: Background           # UNINITIALIZED
       echo Colorscheme.new(bg).GetBackground()
   END
-  v9.CheckScriptFailure(lines, 'E1360:')
+  v9.CheckSourceFailure(lines, 'E1360:')
 
   # TODO: this should not give an error but be handled at runtime
   lines =<< trim END
@@ -356,7 +356,7 @@
       enddef
       Func()
   END
-  v9.CheckScriptFailure(lines, 'E1363:')
+  v9.CheckSourceFailure(lines, 'E1363:')
 enddef
 
 def Test_null_object_assign_compare()
@@ -396,7 +396,7 @@
     o2 = null_object
     assert_true(o2 == null)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 def Test_class_member_initializer()
@@ -432,7 +432,7 @@
             '\d\+ RETURN object.*',
             instr)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 def Test_member_any_used_as_object()
@@ -456,7 +456,7 @@
       F(outer_obj)
       assert_equal(1, inner_obj.value)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   lines =<< trim END
       vim9script
@@ -482,7 +482,51 @@
 
       Test_assign_to_nested_typed_member()
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
+
+  # Try modifying a private variable using an "any" object
+  lines =<< trim END
+    vim9script
+
+    class Inner
+      this._value: string = ''
+    endclass
+
+    class Outer
+      this.inner: any
+    endclass
+
+    def F(outer: Outer)
+      outer.inner._value = 'b'
+    enddef
+
+    var inner_obj = Inner.new('a')
+    var outer_obj = Outer.new(inner_obj)
+    F(outer_obj)
+  END
+  v9.CheckSourceFailure(lines, 'E1333: Cannot access private member: _value')
+
+  # Try modifying a non-existing variable using an "any" object
+  lines =<< trim END
+    vim9script
+
+    class Inner
+      this.value: string = ''
+    endclass
+
+    class Outer
+      this.inner: any
+    endclass
+
+    def F(outer: Outer)
+      outer.inner.someval = 'b'
+    enddef
+
+    var inner_obj = Inner.new('a')
+    var outer_obj = Outer.new(inner_obj)
+    F(outer_obj)
+  END
+  v9.CheckSourceFailure(lines, 'E1326: Member not found on object "Inner": someval')
 enddef
 
 def Test_assignment_with_operator()
@@ -508,7 +552,7 @@
       AddToFoo(f)
       assert_equal(23, f.x)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # do the same thing, but through an interface
   lines =<< trim END
@@ -538,7 +582,7 @@
       AddToFoo(f)
       assert_equal(23, f.x)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 def Test_list_of_objects()
@@ -559,7 +603,7 @@
       var l: list<Foo> = [Foo.new()]
       ProcessList(l)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 def Test_expr_after_using_object()
@@ -578,7 +622,7 @@
 
       Foo()
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 def Test_class_default_new()
@@ -606,7 +650,7 @@
       assert_equal(1, pos.lnum)
       assert_equal(33, pos.col)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   lines =<< trim END
       vim9script
@@ -629,7 +673,7 @@
       assert_equal(4, chris.age)
       assert_equal("none", chris.education)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   lines =<< trim END
       vim9script
@@ -644,7 +688,7 @@
 
       var missing = Person.new()
   END
-  v9.CheckScriptFailure(lines, 'E119:')
+  v9.CheckSourceFailure(lines, 'E119:')
 enddef
 
 
@@ -677,7 +721,7 @@
 
       Check()
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   lines =<< trim END
       vim9script
@@ -699,7 +743,7 @@
 
       Check()
   END
-  v9.CheckScriptFailure(lines, 'E1013:')
+  v9.CheckSourceFailure(lines, 'E1013:')
 
   lines =<< trim END
       vim9script
@@ -721,7 +765,7 @@
 
       Check()
   END
-  v9.CheckScriptFailure(lines, 'E1013:')
+  v9.CheckSourceFailure(lines, 'E1013:')
 enddef
 
 def Test_class_object_member_inits()
@@ -738,7 +782,7 @@
       assert_equal(1, pos.col)
       assert_equal(2, pos.addcol)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   lines =<< trim END
       vim9script
@@ -747,7 +791,7 @@
         this.col = 1
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1022:')
+  v9.CheckSourceFailure(lines, 'E1022:')
 
   # If the type is not specified for a member, then it should be set during
   # object creation and not when defining the class.
@@ -770,7 +814,7 @@
       var a = A.new()
       assert_equal(init_count, 2)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # Test for initializing an object member with an unknown variable/type
   lines =<< trim END
@@ -780,10 +824,11 @@
     endclass
     var a = A.new()
   END
-  v9.CheckScriptFailure(lines, 'E1001:')
+  v9.CheckSourceFailure(lines, 'E1001:')
 enddef
 
-def Test_class_object_member_access()
+" Test for instance variable access
+def Test_instance_variable_access()
   var lines =<< trim END
       vim9script
       class Triple
@@ -807,9 +852,9 @@
       trip.three = 33
       assert_equal(33, trip.three)
 
-      assert_fails('trip.four = 4', 'E1334')
+      assert_fails('trip.four = 4', 'E1326')
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # Test for a public member variable name beginning with an underscore
   lines =<< trim END
@@ -818,7 +863,7 @@
       public this._val = 10
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1332:')
+  v9.CheckSourceFailure(lines, 'E1332:')
 
   lines =<< trim END
       vim9script
@@ -854,7 +899,7 @@
       enddef
       CheckCar()
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   lines =<< trim END
       vim9script
@@ -870,7 +915,7 @@
       var c = MyCar.new("abc")
       var c = MyCar.new("def")
   END
-  v9.CheckScriptFailure(lines, 'E1041:')
+  v9.CheckSourceFailure(lines, 'E1041:')
 
   lines =<< trim END
       vim9script
@@ -896,7 +941,7 @@
             .Add(2)
             .x
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # Test for "public" cannot be abbreviated
   lines =<< trim END
@@ -905,7 +950,7 @@
       pub this.val = 1
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1065:')
+  v9.CheckSourceFailure(lines, 'E1065:')
 
   # Test for "public" keyword must be followed by "this" or "static".
   lines =<< trim END
@@ -914,25 +959,53 @@
       public val = 1
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1331:')
+  v9.CheckSourceFailure(lines, 'E1331:')
 
-  # Test for "static" cannot be abbreviated
+  # Modify a instance variable using the class name in the script context
   lines =<< trim END
     vim9script
-    class Something
-      stat this.val = 1
+    class A
+      public this.val = 1
     endclass
+    A.val = 1
   END
-  v9.CheckScriptFailure(lines, 'E1065:')
+  v9.CheckSourceFailure(lines, 'E1376: Object member "val" accessible only using class "A" object')
 
-  # Test for "static" cannot be followed by "this".
+  # Read a instance variable using the class name in the script context
   lines =<< trim END
     vim9script
-    class Something
-      static this.val = 1
+    class A
+      public this.val = 1
     endclass
+    var i = A.val
   END
-  v9.CheckScriptFailure(lines, 'E1368: Static cannot be followed by "this" in a member name')
+  v9.CheckSourceFailure(lines, 'E1376: Object member "val" accessible only using class "A" object')
+
+  # Modify a instance variable using the class name in a def function
+  lines =<< trim END
+    vim9script
+    class A
+      public this.val = 1
+    endclass
+    def T()
+      A.val = 1
+    enddef
+    T()
+  END
+  v9.CheckSourceFailure(lines, 'E1376: Object member "val" accessible only using class "A" object')
+
+  # Read a instance variable using the class name in a def function
+  lines =<< trim END
+    vim9script
+    class A
+      public this.val = 1
+    endclass
+    def T()
+      var i = A.val
+    enddef
+    T()
+  END
+  v9.CheckSourceFailure(lines, 'E1376: Object member "val" accessible only using class "A" object')
 
   # Access from child class extending a class:
   lines =<< trim END
@@ -941,10 +1014,6 @@
         this.ro_obj_var = 10
         public this.rw_obj_var = 20
         this._priv_obj_var = 30
-
-        static ro_class_var = 40
-        public static rw_class_var = 50
-        static _priv_class_var = 60
       endclass
 
       class B extends A
@@ -956,19 +1025,89 @@
           this.rw_obj_var = 0
           x = this._priv_obj_var
           this._priv_obj_var = 0
+        enddef
+      endclass
 
-          x = ro_class_var
-          ro_class_var = 0
-          x = rw_class_var
-          rw_class_var = 0
-          x = _priv_class_var
-          _priv_class_var = 0
+      var b = B.new()
+      b.Foo()
+  END
+  v9.CheckSourceSuccess(lines)
+enddef
 
-          x = A.ro_class_var
-          A.ro_class_var = 0
-          x = A.rw_class_var
-          A.rw_class_var = 0
-          x = A._priv_class_var
+" Test for class variable access
+def Test_class_variable_access()
+  # Test for "static" cannot be abbreviated
+  var lines =<< trim END
+    vim9script
+    class Something
+      stat this.val = 1
+    endclass
+  END
+  v9.CheckSourceFailure(lines, 'E1065:')
+
+  # Test for "static" cannot be followed by "this".
+  lines =<< trim END
+    vim9script
+    class Something
+      static this.val = 1
+    endclass
+  END
+  v9.CheckSourceFailure(lines, 'E1368: Static cannot be followed by "this" in a member name')
+
+  # Test for "static" cannot be followed by "public".
+  lines =<< trim END
+    vim9script
+    class Something
+      static public val = 1
+    endclass
+  END
+  v9.CheckSourceFailure(lines, 'E1022: Type or initialization required')
+
+  # A readonly class variable cannot be modified from a child class
+  lines =<< trim END
+      vim9script
+      class A
+        static ro_class_var = 40
+      endclass
+
+      class B extends A
+        def Foo()
+          A.ro_class_var = 50
+        enddef
+      endclass
+
+      var b = B.new()
+      b.Foo()
+  END
+  v9.CheckSourceFailure(lines, 'E46: Cannot change read-only variable "ro_class_var"')
+
+  # A private class variable cannot be accessed from a child class
+  lines =<< trim END
+      vim9script
+      class A
+        static _priv_class_var = 60
+      endclass
+
+      class B extends A
+        def Foo()
+          var i = A._priv_class_var
+        enddef
+      endclass
+
+      var b = B.new()
+      b.Foo()
+  END
+  v9.CheckSourceFailure(lines, 'E1333: Cannot access private member: _priv_class_var')
+
+  # A private class variable cannot be modified from a child class
+  lines =<< trim END
+      vim9script
+      class A
+        static _priv_class_var = 60
+      endclass
+
+      class B extends A
+        def Foo()
           A._priv_class_var = 0
         enddef
       endclass
@@ -976,7 +1115,37 @@
       var b = B.new()
       b.Foo()
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceFailure(lines, 'E1333: Cannot access private member: _priv_class_var')
+
+  # Access from child class extending a class and from script context
+  lines =<< trim END
+      vim9script
+      class A
+        static ro_class_var = 10
+        public static rw_class_var = 20
+        static _priv_class_var = 30
+      endclass
+
+      class B extends A
+        def Foo()
+          var x: number
+          x = A.ro_class_var
+          assert_equal(10, x)
+          x = A.rw_class_var
+          assert_equal(25, x)
+          A.rw_class_var = 20
+          assert_equal(20, A.rw_class_var)
+        enddef
+      endclass
+
+      assert_equal(10, A.ro_class_var)
+      assert_equal(20, A.rw_class_var)
+      A.rw_class_var = 25
+      assert_equal(25, A.rw_class_var)
+      var b = B.new()
+      b.Foo()
+  END
+  v9.CheckSourceSuccess(lines)
 enddef
 
 def Test_class_object_compare()
@@ -1005,8 +1174,8 @@
       assert_notequal(i1, io2)
   END
 
-  v9.CheckScriptSuccess(class_lines + test_lines)
-  v9.CheckScriptSuccess(
+  v9.CheckSourceSuccess(class_lines + test_lines)
+  v9.CheckSourceSuccess(
       class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
 
   for op in ['>', '>=', '<', '<=', '=~', '!~']
@@ -1015,8 +1184,8 @@
           'var i2 = Item.new()',
           'echo i1 ' .. op .. ' i2',
           ]
-    v9.CheckScriptFailure(class_lines + op_lines, 'E1153: Invalid operation for object')
-    v9.CheckScriptFailure(class_lines
+    v9.CheckSourceFailure(class_lines + op_lines, 'E1153: Invalid operation for object')
+    v9.CheckSourceFailure(class_lines
           + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
   endfor
 enddef
@@ -1042,7 +1211,7 @@
 
       t = m
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   lines =<< trim END
       vim9script
@@ -1056,7 +1225,7 @@
 
       var o: One = Two.new()
   END
-  v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>')
+  v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>')
 
   lines =<< trim END
       vim9script
@@ -1074,7 +1243,7 @@
       var o: One = Two.new(5)
       assert_equal(5, o.GetMember())
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   lines =<< trim END
       vim9script
@@ -1094,7 +1263,7 @@
 
       echo Fn(Num.new(4))
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 def Test_class_member()
@@ -1116,7 +1285,7 @@
       assert_equal(0, TextPos.counter)
       TextPos.AddToCounter(3)
       assert_equal(3, TextPos.counter)
-      assert_fails('echo TextPos.noSuchMember', 'E1338:')
+      assert_fails('echo TextPos.noSuchMember', 'E1337:')
 
       def GetCounter(): number
         return TextPos.counter
@@ -1136,7 +1305,7 @@
       TextPos.anybody += 5
       assert_equal(17, TextPos.anybody)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # example in the help
   lines =<< trim END
@@ -1155,7 +1324,7 @@
         var to7 = OtherThing.new(7)
         assert_equal(10, OtherThing.totalSize)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # using static class member twice
   lines =<< trim END
@@ -1172,7 +1341,7 @@
       assert_equal('some text', HTML.MacroSubstitute('some text'))
       assert_equal('some text', HTML.MacroSubstitute('some text'))
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # access private member in lambda
   lines =<< trim END
@@ -1190,7 +1359,7 @@
       var foo = Foo.new()
       assert_equal(5, foo.Add(5))
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # access private member in lambda body
   lines =<< trim END
@@ -1211,7 +1380,7 @@
       var foo = Foo.new()
       assert_equal(13, foo.Add(7))
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # check shadowing
   lines =<< trim END
@@ -1227,7 +1396,7 @@
       var s = Some.new()
       s.Method(7)
   END
-  v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count')
+  v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count')
 
   lines =<< trim END
       vim9script
@@ -1243,7 +1412,7 @@
       var s = Some.new()
       s.Method(7)
   END
-  v9.CheckScriptFailure(lines, 'E1341: Variable already declared in the class: count')
+  v9.CheckSourceFailure(lines, 'E1341: Variable already declared in the class: count')
 
   # Test for using an invalid type for a member variable
   lines =<< trim END
@@ -1252,7 +1421,7 @@
       this.val: xxx
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1010:')
+  v9.CheckSourceFailure(lines, 'E1010:')
 
   # Test for setting a member on a null object
   lines =<< trim END
@@ -1267,7 +1436,7 @@
     enddef
     F()
   END
-  v9.CheckScriptFailure(lines, 'E1360: Using a null object')
+  v9.CheckSourceFailure(lines, 'E1360: Using a null object')
 
   # Test for accessing a member on a null object
   lines =<< trim END
@@ -1282,7 +1451,7 @@
     enddef
     F()
   END
-  v9.CheckScriptFailure(lines, 'E1360: Using a null object')
+  v9.CheckSourceFailure(lines, 'E1360: Using a null object')
 
   # Test for setting a member on a null object, at script level
   lines =<< trim END
@@ -1295,7 +1464,7 @@
     obj.val = ""
   END
   # FIXME(in source): this should give E1360 as well!
-  v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<A> but got string')
+  v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<A> but got string')
 
   # Test for accessing a member on a null object, at script level
   lines =<< trim END
@@ -1307,7 +1476,7 @@
     var obj: A
     echo obj.val
   END
-  v9.CheckScriptFailure(lines, 'E1360: Using a null object')
+  v9.CheckSourceFailure(lines, 'E1360: Using a null object')
 
   # Test for no space before or after the '=' when initializing a member
   # variable
@@ -1317,14 +1486,14 @@
       this.val: number= 10
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1004:')
+  v9.CheckSourceFailure(lines, 'E1004:')
   lines =<< trim END
     vim9script
     class A
       this.val: number =10
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1004:')
+  v9.CheckSourceFailure(lines, 'E1004:')
 
   # Access a non-existing member
   lines =<< trim END
@@ -1334,7 +1503,7 @@
     var a = A.new()
     var v = a.bar
   END
-  v9.CheckScriptFailure(lines, 'E1326:')
+  v9.CheckSourceFailure(lines, 'E1326: Member not found on object "A": bar')
 enddef
 
 func Test_class_garbagecollect()
@@ -1351,7 +1520,7 @@
       call test_garbagecollect_now()
       echo Point.pl Point.pd
   END
-  call v9.CheckScriptSuccess(lines)
+  call v9.CheckSourceSuccess(lines)
 
   let lines =<< trim END
       vim9script
@@ -1378,7 +1547,7 @@
       view = MyView.new()
       test_garbagecollect_now()
   END
-  call v9.CheckScriptSuccess(lines)
+  call v9.CheckSourceSuccess(lines)
 endfunc
 
 " Test interface garbage collection
@@ -1432,7 +1601,7 @@
     assert_equal(60, A.ClassFoo())
     assert_equal(150, o.ObjFoo())
   END
-  call v9.CheckScriptSuccess(lines)
+  call v9.CheckSourceSuccess(lines)
 endfunc
 
 def Test_class_function()
@@ -1458,7 +1627,7 @@
       var v2 = Value.new(7)
       assert_equal(2, Value.GetCount())
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # Test for cleaning up after a class definition failure when using class
   # functions.
@@ -1470,7 +1639,7 @@
       aaa
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1318:')
+  v9.CheckSourceFailure(lines, 'E1318:')
 enddef
 
 def Test_class_defcompile()
@@ -1485,7 +1654,7 @@
 
       defcompile C.Fo
   END
-  v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number')
+  v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number')
 
   lines =<< trim END
       vim9script
@@ -1498,7 +1667,7 @@
 
       defcompile C.Fc
   END
-  v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected number but got string')
+  v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string')
 
   lines =<< trim END
       vim9script
@@ -1510,14 +1679,14 @@
 
       defcompile C.new
   END
-  v9.CheckScriptFailure(lines, 'E1370: Cannot define a "new" function as static')
+  v9.CheckSourceFailure(lines, 'E1370: Cannot define a "new" function as static')
 
   # Trying to compile a function using a non-existing class variable
   lines =<< trim END
     vim9script
     defcompile x.Foo()
   END
-  v9.CheckScriptFailure(lines, 'E475:')
+  v9.CheckSourceFailure(lines, 'E475:')
 
   # Trying to compile a function using a variable which is not a class
   lines =<< trim END
@@ -1525,7 +1694,7 @@
     var x: number
     defcompile x.Foo()
   END
-  v9.CheckScriptFailure(lines, 'E475:')
+  v9.CheckSourceFailure(lines, 'E475:')
 
   # Trying to compile a function without specifying the name
   lines =<< trim END
@@ -1534,7 +1703,7 @@
     endclass
     defcompile A.
   END
-  v9.CheckScriptFailure(lines, 'E475:')
+  v9.CheckSourceFailure(lines, 'E475:')
 
   # Trying to compile a non-existing class object member function
   lines =<< trim END
@@ -1544,7 +1713,7 @@
     var a = A.new()
     defcompile a.Foo()
   END
-  v9.CheckScriptFailureList(lines, ['E1334:', 'E475:'])
+  v9.CheckSourceFailureList(lines, ['E1326:', 'E475:'])
 enddef
 
 def Test_class_object_to_string()
@@ -1560,7 +1729,7 @@
       var pos = TextPosition.new()
       assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 def Test_interface_basics()
@@ -1572,14 +1741,14 @@
         def GetCount(): number
       endinterface
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   lines =<< trim END
       interface SomethingWrong
         static count = 7
       endinterface
   END
-  v9.CheckScriptFailure(lines, 'E1342:')
+  v9.CheckSourceFailure(lines, 'E1342:')
 
   lines =<< trim END
       vim9script
@@ -1589,7 +1758,7 @@
         def Method(count: number)
       endinterface
   END
-  v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count', 5)
+  v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count', 5)
 
   lines =<< trim END
       vim9script
@@ -1601,7 +1770,7 @@
   END
   # The argument name and the object member name are the same, but this is not a
   # problem because object members are always accessed with the "this." prefix.
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   lines =<< trim END
       vim9script
@@ -1609,7 +1778,7 @@
         static count = 7
       endinterface
   END
-  v9.CheckScriptFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong')
+  v9.CheckSourceFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong')
 
   lines =<< trim END
       vim9script
@@ -1619,7 +1788,7 @@
         def GetCount(): number
       endinterface
   END
-  v9.CheckScriptFailure(lines, 'E1344:')
+  v9.CheckSourceFailure(lines, 'E1344:')
 
   lines =<< trim END
       vim9script
@@ -1631,7 +1800,7 @@
         enddef
       endinterface
   END
-  v9.CheckScriptFailure(lines, 'E1345: Not a valid command in an interface: return 5')
+  v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5')
 
   lines =<< trim END
       vim9script
@@ -1699,7 +1868,7 @@
         enddef
       endclass
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   lines =<< trim END
       vim9script
@@ -1712,7 +1881,7 @@
         static count: number
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1350:')
+  v9.CheckSourceFailure(lines, 'E1350:')
 
   lines =<< trim END
       vim9script
@@ -1725,7 +1894,7 @@
         static count: number
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1351: Duplicate interface after "implements": Some')
+  v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some')
 
   lines =<< trim END
       vim9script
@@ -1742,7 +1911,7 @@
         enddef
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1348: Member "counter" of interface "Some" not implemented')
+  v9.CheckSourceFailure(lines, 'E1348: Member "counter" of interface "Some" not implemented')
 
   lines =<< trim END
       vim9script
@@ -1759,7 +1928,7 @@
         enddef
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1349: Function "Methods" of interface "Some" not implemented')
+  v9.CheckSourceFailure(lines, 'E1349: Function "Methods" of interface "Some" not implemented')
 
   # Check different order of members in class and interface works.
   lines =<< trim END
@@ -1789,7 +1958,7 @@
 
       Test()
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # Interface name after "extends" doesn't end in a space or NUL character
   lines =<< trim END
@@ -1799,7 +1968,7 @@
     class B extends A"
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1315:')
+  v9.CheckSourceFailure(lines, 'E1315:')
 
   # Trailing characters after a class name
   lines =<< trim END
@@ -1807,7 +1976,7 @@
     class A bbb
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E488:')
+  v9.CheckSourceFailure(lines, 'E488:')
 
   # using "implements" with a non-existing class
   lines =<< trim END
@@ -1815,7 +1984,7 @@
     class A implements B
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1346:')
+  v9.CheckSourceFailure(lines, 'E1346:')
 
   # using "implements" with a regular class
   lines =<< trim END
@@ -1825,7 +1994,7 @@
     class B implements A
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1347:')
+  v9.CheckSourceFailure(lines, 'E1347:')
 
   # using "implements" with a variable
   lines =<< trim END
@@ -1834,7 +2003,7 @@
     class A implements T
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1347:')
+  v9.CheckSourceFailure(lines, 'E1347:')
 
   # all the class methods in an "interface" should be implemented
   lines =<< trim END
@@ -1845,7 +2014,7 @@
     class B implements A
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1349:')
+  v9.CheckSourceFailure(lines, 'E1349:')
 
   # implements should be followed by a white space
   lines =<< trim END
@@ -1855,7 +2024,7 @@
     class B implements A;
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1315:')
+  v9.CheckSourceFailure(lines, 'E1315:')
 
   lines =<< trim END
       vim9script
@@ -1871,7 +2040,7 @@
         static matching: bool
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1406: Member "not_matching": type mismatch, expected number but got string')
+  v9.CheckSourceFailure(lines, 'E1406: Member "not_matching": type mismatch, expected number but got string')
 
   lines =<< trim END
       vim9script
@@ -1884,7 +2053,7 @@
         enddef
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1407: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string')
+  v9.CheckSourceFailure(lines, 'E1407: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string')
 
   lines =<< trim END
       vim9script
@@ -1897,7 +2066,7 @@
         enddef
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1407: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool')
+  v9.CheckSourceFailure(lines, 'E1407: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool')
 
   lines =<< trim END
       vim9script
@@ -1910,7 +2079,7 @@
         enddef
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1407: Method "IsEven": type mismatch, expected func(number): bool but got func(number, ...list<number>): bool')
+  v9.CheckSourceFailure(lines, 'E1407: Method "IsEven": type mismatch, expected func(number): bool but got func(number, ...list<number>): bool')
 
   # access superclass interface members from subclass, mix variable order
   lines =<< trim END
@@ -1939,8 +2108,6 @@
 
     class B extends A
         def new()
-            svar1 = 21
-            svar2 = 22
             this.mvar1 = 121
             this.mvar2 = 122
         enddef
@@ -1948,8 +2115,6 @@
 
     class C extends B
         def new()
-            svar1 = 31
-            svar2 = 32
             this.mvar1 = 131
             this.mvar2 = 132
         enddef
@@ -1967,7 +2132,7 @@
     assert_equal([121, 122], F2(ob))
     assert_equal([131, 132], F2(oc))
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # Access superclass interface members from subclass, mix variable order.
   # Two interfaces, one on A, one on B; each has both kinds of variables
@@ -2007,8 +2172,6 @@
         public this.mvar3: number
         public this.mvar4: number
         def new()
-            svar1 = 21
-            svar2 = 22
             svar3 = 23
             svar4 = 24
             this.mvar1 = 121
@@ -2021,10 +2184,6 @@
     class C extends B
         public static svar5: number
         def new()
-            svar1 = 31
-            svar2 = 32
-            svar3 = 33
-            svar4 = 34
             svar5 = 1001
             this.mvar1 = 131
             this.mvar2 = 132
@@ -2049,7 +2208,7 @@
     assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)])
     assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)])
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 def Test_call_interface_method()
@@ -2074,7 +2233,7 @@
     assert_equal('child', g:result)
     unlet g:result
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   lines =<< trim END
     vim9script
@@ -2099,7 +2258,7 @@
     assert_equal('child', g:result)
     unlet g:result
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # method of interface returns a value
   lines =<< trim END
@@ -2125,7 +2284,7 @@
     assert_equal('child/resource', g:result)
     unlet g:result
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   lines =<< trim END
     vim9script
@@ -2152,7 +2311,7 @@
     assert_equal('child/resource', g:result)
     unlet g:result
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
 
   # No class that implements the interface.
@@ -2170,7 +2329,7 @@
 
       defcompile
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 def Test_class_used_as_type()
@@ -2187,7 +2346,7 @@
       assert_equal(2, p.x)
       assert_equal(33, p.y)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   lines =<< trim END
       vim9script
@@ -2206,7 +2365,7 @@
       var hx = p
       assert_equal(2, hx.x)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   lines =<< trim END
       vim9script
@@ -2219,7 +2378,7 @@
       var p: Point
       p = 'text'
   END
-  v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string')
+  v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string')
 enddef
 
 def Test_class_extends()
@@ -2243,7 +2402,7 @@
       assert_equal(1, o.GetOne())
       assert_equal(3, o.GetTotal())
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   lines =<< trim END
       vim9script
@@ -2257,7 +2416,7 @@
       assert_equal(3, o.one)
       assert_equal(44, o.two)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   lines =<< trim END
       vim9script
@@ -2268,7 +2427,7 @@
         this.two = 2
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1352: Duplicate "extends"')
+  v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"')
 
   lines =<< trim END
       vim9script
@@ -2276,7 +2435,7 @@
         this.two = 2
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1353: Class name not found: BaseClass')
+  v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass')
 
   lines =<< trim END
       vim9script
@@ -2285,7 +2444,7 @@
         this.two = 2
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1354: Cannot extend SomeVar')
+  v9.CheckSourceFailure(lines, 'E1354: Cannot extend SomeVar')
 
   lines =<< trim END
       vim9script
@@ -2306,7 +2465,7 @@
       var o = Child.new('John', 42)
       assert_equal('John: 42', o.ToString())
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   lines =<< trim END
       vim9script
@@ -2320,7 +2479,7 @@
         enddef
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1355: Duplicate function: ToString')
+  v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString')
 
   lines =<< trim END
       vim9script
@@ -2333,7 +2492,7 @@
       var o = Child.new(42)
       echo o.ToString()
   END
-  v9.CheckScriptFailure(lines, 'E1356:')
+  v9.CheckSourceFailure(lines, 'E1356:')
 
   lines =<< trim END
       vim9script
@@ -2350,7 +2509,7 @@
       enddef
       echo ToString()
   END
-  v9.CheckScriptFailure(lines, 'E1357:')
+  v9.CheckSourceFailure(lines, 'E1357:')
 
   lines =<< trim END
       vim9script
@@ -2363,7 +2522,7 @@
       var o = Child.new(42)
       echo o.ToString()
   END
-  v9.CheckScriptFailure(lines, 'E1358:')
+  v9.CheckSourceFailure(lines, 'E1358:')
 
   lines =<< trim END
       vim9script
@@ -2384,7 +2543,7 @@
       var o = Child.new('John', 42)
       assert_equal('Base class: 42', o.ToString())
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   lines =<< trim END
       vim9script
@@ -2401,7 +2560,7 @@
       endclass
       var c = Child.new()
   END
-  v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Child": new(')
+  v9.CheckSourceFailure(lines, 'E1375: Class member "new" accessible only using class "Child"')
 
   # base class with more than one object member
   lines =<< trim END
@@ -2421,7 +2580,7 @@
       var v = Success.new('asdf')
       assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # class name after "extends" doesn't end in a space or NUL character
   lines =<< trim END
@@ -2431,7 +2590,7 @@
     class B extends A"
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1315:')
+  v9.CheckSourceFailure(lines, 'E1315:')
 enddef
 
 def Test_using_base_class()
@@ -2470,7 +2629,7 @@
     With(ChildEE.new())
     assert_equal('42/finally/exit', g:result)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
   unlet g:result
 
   # Using super, Child invokes Base method which has optional arg. #12471
@@ -2493,7 +2652,7 @@
     var obj = Child.new()
     assert_equal(true, obj.success)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 
@@ -2536,7 +2695,7 @@
       assert_equal('Peter', p.name)
       assert_equal(42, p.age)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   lines =<< trim END
       vim9script
@@ -2548,14 +2707,14 @@
       endclass
       var p = Base.new('Peter')
   END
-  v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Base": new(')
+  v9.CheckSourceFailure(lines, 'E1325: Method not found on class "Base": new')
 
   lines =<< trim END
       abstract class Base
         this.name: string
       endclass
   END
-  v9.CheckScriptFailure(lines, 'E1316:')
+  v9.CheckSourceFailure(lines, 'E1316:')
 
   # Abstract class cannot have a "new" function
   lines =<< trim END
@@ -2565,7 +2724,7 @@
       enddef
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1359:')
+  v9.CheckSourceFailure(lines, 'E1359:')
 enddef
 
 def Test_closure_in_class()
@@ -2583,7 +2742,7 @@
       Foo.new()
       assert_equal(['A'], g:result)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 def Test_call_constructor_from_legacy()
@@ -2606,7 +2765,7 @@
       legacy call p.new()
       assert_equal('true', newCalled)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 def Test_defer_with_object()
@@ -2635,7 +2794,7 @@
       })
       assert_equal('entered/called/exited', g:result)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
   unlet g:result
 
   lines =<< trim END
@@ -2672,7 +2831,7 @@
       })
       assert_equal('entered-child/called/exited-child', g:result)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
   unlet g:result
 enddef
 
@@ -2712,7 +2871,7 @@
 
     p.Set(true)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 " Test for calling a method in a class that is extended
@@ -2747,7 +2906,7 @@
     assert_true(prop_init_called)
     assert_true(prop_register_called)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 def Test_instanceof()
@@ -2794,7 +2953,7 @@
     enddef
     Foo()
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 " Test for calling a method in the parent class that is extended partially.
@@ -2832,7 +2991,7 @@
     var foo2 = Foo.new()
     var l = Stack(foo1, foo2)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 " Test for calling methods from three levels of classes
@@ -2906,7 +3065,7 @@
     assert_equal(0, B_func3)
     assert_equal(3, C_func3)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 " Test for using members from three levels of classes
@@ -2949,7 +3108,7 @@
     assert_equal(2, cobj.val2)
     assert_equal(1, cobj.val3)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 " Test expansion of <stack> with class methods.
@@ -2973,7 +3132,7 @@
 
     F()
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 " Test the return type of the new() constructor
@@ -3006,7 +3165,7 @@
     enddef
     F()
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # new() uses the default return type and an empty 'return' statement
   lines =<< trim END
@@ -3037,7 +3196,7 @@
     enddef
     F()
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # new() uses "any" return type and returns "this"
   lines =<< trim END
@@ -3054,7 +3213,7 @@
       enddef
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1365:')
+  v9.CheckSourceFailure(lines, 'E1365:')
 
   # new() uses 'Dict' return type and returns a Dict
   lines =<< trim END
@@ -3072,7 +3231,7 @@
     var c = C.new()
     assert_equal('object<C>', typename(c))
   END
-  v9.CheckScriptFailure(lines, 'E1365:')
+  v9.CheckSourceFailure(lines, 'E1365:')
 enddef
 
 " Test for checking a member initialization type at run time.
@@ -3098,7 +3257,7 @@
     var c1 = C.new()
     var c2 = C.new()
   END
-  v9.CheckScriptFailure(lines, 'E1012:')
+  v9.CheckSourceFailure(lines, 'E1012:')
 enddef
 
 " Test for locking a variable referring to an object and reassigning to another
@@ -3135,7 +3294,7 @@
     G()
     assert_equal(2, current.val)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 " Test for a private object method
@@ -3152,7 +3311,7 @@
     var a = A.new()
     a._Foo()
   END
-  v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
+  v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
 
   # Try calling a private method using an object (from a def function)
   lines =<< trim END
@@ -3169,7 +3328,7 @@
     enddef
     T()
   END
-  v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
+  v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
 
   # Use a private method from another object method (in script context)
   lines =<< trim END
@@ -3186,7 +3345,7 @@
     var a = A.new()
     assert_equal(1234, a.Bar())
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # Use a private method from another object method (def function context)
   lines =<< trim END
@@ -3206,7 +3365,7 @@
     enddef
     T()
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # Try calling a private method without the "this" prefix
   lines =<< trim END
@@ -3223,7 +3382,7 @@
     var a = A.new()
     a.Bar()
   END
-  v9.CheckScriptFailure(lines, 'E117: Unknown function: _Foo')
+  v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo')
 
   # Try calling a private method using the class name
   lines =<< trim END
@@ -3236,7 +3395,7 @@
     endclass
     A._Foo()
   END
-  v9.CheckScriptFailure(lines, 'E1325: Method not found on class "A": _Foo()')
+  v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo')
 
   # Try to use "public" keyword when defining a private method
   lines =<< trim END
@@ -3249,7 +3408,7 @@
     var a = A.new()
     a._Foo()
   END
-  v9.CheckScriptFailure(lines, 'E1331: Public must be followed by "this" or "static"')
+  v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "this" or "static"')
 
   # Define two private methods with the same name
   lines =<< trim END
@@ -3263,7 +3422,7 @@
     endclass
     var a = A.new()
   END
-  v9.CheckScriptFailure(lines, 'E1355: Duplicate function: _Foo')
+  v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo')
 
   # Define a private method and a object method with the same name
   lines =<< trim END
@@ -3277,7 +3436,7 @@
     endclass
     var a = A.new()
   END
-  v9.CheckScriptFailure(lines, 'E1355: Duplicate function: Foo')
+  v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo')
 
   # Define an object method and a private method with the same name
   lines =<< trim END
@@ -3291,7 +3450,7 @@
     endclass
     var a = A.new()
   END
-  v9.CheckScriptFailure(lines, 'E1355: Duplicate function: _Foo')
+  v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo')
 
   # Call a public method and a private method from a private method
   lines =<< trim END
@@ -3315,7 +3474,7 @@
     var a = A.new()
     a.T()
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # Try calling a private method from another class
   lines =<< trim END
@@ -3335,7 +3494,7 @@
     var b = B.new()
     b.Foo()
   END
-  v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
+  v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
 
   # Call a private object method from a child class object method
   lines =<< trim END
@@ -3357,7 +3516,7 @@
     var c = C.new()
     assert_equal(1234, c.Baz())
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # Call a private object method from a child class object
   lines =<< trim END
@@ -3378,7 +3537,7 @@
     var c = C.new()
     assert_equal(1234, c._Foo())
   END
-  v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
+  v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
 
   # Using "_" prefix in a method name should fail outside of a class
   lines =<< trim END
@@ -3388,7 +3547,7 @@
     enddef
     var a = _Foo()
   END
-  v9.CheckScriptFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number')
+  v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number')
 enddef
 
 " Test for an private class method
@@ -3404,7 +3563,7 @@
     endclass
     A._Foo()
   END
-  v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
+  v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
 
   # Try calling a class private method (from a def function)
   lines =<< trim END
@@ -3420,7 +3579,7 @@
     enddef
     T()
   END
-  v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
+  v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
 
   # Try calling a class private method using an object (at the script level)
   lines =<< trim END
@@ -3434,7 +3593,7 @@
     var a = A.new()
     a._Foo()
   END
-  v9.CheckScriptFailure(lines, 'E1325: Method not found on class "A": _Foo()')
+  v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo')
 
   # Try calling a class private method using an object (from a def function)
   lines =<< trim END
@@ -3451,7 +3610,7 @@
     enddef
     T()
   END
-  v9.CheckScriptFailure(lines, 'E1325: Method not found on class "A": _Foo()')
+  v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo')
 
   # Use a class private method from an object method
   lines =<< trim END
@@ -3468,7 +3627,7 @@
     var a = A.new()
     a.Bar()
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # Use a class private method from another class private method
   lines =<< trim END
@@ -3488,7 +3647,7 @@
     var a = A.new()
     a.Bar()
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # Declare a class method and a class private method with the same name
   lines =<< trim END
@@ -3502,7 +3661,7 @@
     endclass
     var a = A.new()
   END
-  v9.CheckScriptFailure(lines, 'E1355: Duplicate function: Foo')
+  v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo')
 
   # Try calling a class private method from another class
   lines =<< trim END
@@ -3521,7 +3680,7 @@
     var b = B.new()
     assert_equal(1234, b.Foo())
   END
-  v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
+  v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
 
   # Call a private class method from a child class object method
   lines =<< trim END
@@ -3543,7 +3702,7 @@
     var c = C.new()
     assert_equal(1234, c.Baz())
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
 
   # Call a private class method from a child class private class method
   lines =<< trim END
@@ -3564,7 +3723,7 @@
     endclass
     assert_equal(1234, C.Baz())
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
 
   # Call a private class method from a child class object
   lines =<< trim END
@@ -3585,7 +3744,7 @@
     var c = C.new()
     assert_equal(1234, C._Foo())
   END
-  v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
+  v9.CheckSourceFailure(lines, 'E1325: Method not found on class "C": _Foo')
 enddef
 
 " Test for an interface private object_method
@@ -3607,7 +3766,7 @@
     var a = A.new()
     assert_equal(1234, a.Bar())
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # Call an interface private class method (script context)
   lines =<< trim END
@@ -3623,7 +3782,7 @@
     var a = A.new()
     assert_equal(1234, a._Foo())
   END
-  v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
+  v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
 
   # Call an interface private class method (def context)
   lines =<< trim END
@@ -3642,7 +3801,7 @@
     enddef
     T()
   END
-  v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
+  v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
 
   # Implement an interface private object method as a private class method
   lines =<< trim END
@@ -3656,7 +3815,7 @@
       enddef
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1349: Function "_Foo" of interface "Intf" not implemented')
+  v9.CheckSourceFailure(lines, 'E1349: Function "_Foo" of interface "Intf" not implemented')
 enddef
 
 " Test for an interface private class method
@@ -3678,7 +3837,7 @@
     var a = A.new()
     assert_equal(1234, a.Bar())
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # Call an interface private class method (script context)
   lines =<< trim END
@@ -3693,7 +3852,7 @@
     endclass
     assert_equal(1234, A._Foo())
   END
-  v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo())')
+  v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo())')
 
   # Call an interface private class method (def context)
   lines =<< trim END
@@ -3711,7 +3870,7 @@
     enddef
     T()
   END
-  v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo())')
+  v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo())')
 
   # Implement an interface private class method as a private object method
   lines =<< trim END
@@ -3725,7 +3884,7 @@
       enddef
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1349: Function "_Foo" of interface "Intf" not implemented')
+  v9.CheckSourceFailure(lines, 'E1349: Function "_Foo" of interface "Intf" not implemented')
 enddef
 
 " Test for using the return value of a class/object method as a function
@@ -3751,7 +3910,7 @@
     var t = C.new()
     Baz(t)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   lines =<< trim END
     vim9script
@@ -3772,7 +3931,7 @@
 
     Baz()
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 def Test_static_inheritence()
@@ -3797,21 +3956,17 @@
 
     class B extends A
         def new()
-            _svar = 2
             this._mvar = 102
         enddef
     endclass
 
     class C extends B
         def new()
-            _svar = 3
             this._mvar = 103
         enddef
 
         def AccessPrivateStaticThroughClassName(): number
             assert_equal(1, A._svar)
-            assert_equal(2, B._svar)
-            assert_equal(3, C._svar)
             return 444
         enddef
     endclass
@@ -3823,14 +3978,14 @@
     assert_equal(102, ob.AccessObject())
     assert_equal(103, oc.AccessObject())
 
-    assert_equal(444, oc.AccessPrivateStaticThroughClassName())
+    assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access private member: _svar')
 
     # verify object properly resolves to correct static
     assert_equal(1, oa.AccessStaticThroughObject())
-    assert_equal(2, ob.AccessStaticThroughObject())
-    assert_equal(3, oc.AccessStaticThroughObject())
+    assert_equal(1, ob.AccessStaticThroughObject())
+    assert_equal(1, oc.AccessStaticThroughObject())
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 " Test for declaring duplicate object and class members
@@ -3843,7 +3998,7 @@
       this.val = 20
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1369: Duplicate member: val')
+  v9.CheckSourceFailure(lines, 'E1369: Duplicate member: val')
 
   # Duplicate private member variable
   lines =<< trim END
@@ -3853,7 +4008,7 @@
       this._val = 20
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _val')
+  v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _val')
 
   # Duplicate public member variable
   lines =<< trim END
@@ -3863,7 +4018,7 @@
       public this.val = 20
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1369: Duplicate member: val')
+  v9.CheckSourceFailure(lines, 'E1369: Duplicate member: val')
 
   # Duplicate private member variable
   lines =<< trim END
@@ -3873,7 +4028,7 @@
       this._val = 20
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _val')
+  v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _val')
 
   # Duplicate public and private member variable
   lines =<< trim END
@@ -3883,7 +4038,7 @@
       public this.val = 10
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1369: Duplicate member: val')
+  v9.CheckSourceFailure(lines, 'E1369: Duplicate member: val')
 
   # Duplicate class member variable
   lines =<< trim END
@@ -3893,7 +4048,7 @@
       static _s: string = "def"
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _s')
+  v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _s')
 
   # Duplicate public and private class member variable
   lines =<< trim END
@@ -3903,7 +4058,7 @@
       static _s: string = "def"
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _s')
+  v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _s')
 
   # Duplicate class and object member variable
   lines =<< trim END
@@ -3918,7 +4073,7 @@
     assert_equal(10, C.val)
     assert_equal(20, c.val)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # Duplicate object member variable in a derived class
   lines =<< trim END
@@ -3932,7 +4087,7 @@
       this.val = 20
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1369: Duplicate member: val')
+  v9.CheckSourceFailure(lines, 'E1369: Duplicate member: val')
 
   # Duplicate object private member variable in a derived class
   lines =<< trim END
@@ -3946,7 +4101,7 @@
       this._val = 20
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _val')
+  v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _val')
 
   # Duplicate object private member variable in a derived class
   lines =<< trim END
@@ -3960,7 +4115,7 @@
       this._val = 20
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _val')
+  v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _val')
 
   # Duplicate object member variable in a derived class
   lines =<< trim END
@@ -3974,63 +4129,7 @@
       this.val = 20
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1369: Duplicate member: val')
-
-  # Duplicate class member variable in a derived class
-  lines =<< trim END
-    vim9script
-    class A
-      static val = 10
-    endclass
-    class B extends A
-    endclass
-    class C extends B
-      static val = 20
-    endclass
-  END
-  v9.CheckScriptFailure(lines, 'E1369: Duplicate member: val')
-
-  # Duplicate private class member variable in a derived class
-  lines =<< trim END
-    vim9script
-    class A
-      static _val = 10
-    endclass
-    class B extends A
-    endclass
-    class C extends B
-      static _val = 20
-    endclass
-  END
-  v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _val')
-
-  # Duplicate private class member variable in a derived class
-  lines =<< trim END
-    vim9script
-    class A
-      static val = 10
-    endclass
-    class B extends A
-    endclass
-    class C extends B
-      static _val = 20
-    endclass
-  END
-  v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _val')
-
-  # Duplicate class member variable in a derived class
-  lines =<< trim END
-    vim9script
-    class A
-      static _val = 10
-    endclass
-    class B extends A
-    endclass
-    class C extends B
-      static val = 20
-    endclass
-  END
-  v9.CheckScriptFailure(lines, 'E1369: Duplicate member: val')
+  v9.CheckSourceFailure(lines, 'E1369: Duplicate member: val')
 
   # Two member variables with a common prefix
   lines =<< trim END
@@ -4040,7 +4139,7 @@
       public static svar: number
     endclass
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 def Test_interface_static_member_access()
@@ -4058,7 +4157,7 @@
     endclass
     C.new().F()
   END
-  v9.CheckScriptFailure(lines, 'E1409: Cannot directly access interface "I" static member "num"')
+  v9.CheckSourceFailure(lines, 'E1409: Cannot directly access interface "I" static member "num"')
 
   # In a class cannot write to interface static
   lines =<< trim END
@@ -4074,7 +4173,7 @@
     endclass
     C.new().F()
   END
-  v9.CheckScriptFailure(lines, 'E1409: Cannot directly access interface "I" static member "num"')
+  v9.CheckSourceFailure(lines, 'E1409: Cannot directly access interface "I" static member "num"')
 
   # In a def cannot read from interface static
   lines =<< trim END
@@ -4087,7 +4186,7 @@
     enddef
     F()
   END
-  v9.CheckScriptFailure(lines, 'E1409: Cannot directly access interface "I" static member "num"')
+  v9.CheckSourceFailure(lines, 'E1409: Cannot directly access interface "I" static member "num"')
 
   # In a def cannot write to interface static
   lines =<< trim END
@@ -4100,7 +4199,7 @@
     enddef
     F()
   END
-  v9.CheckScriptFailure(lines, 'E1409: Cannot directly access interface "I" static member "num"')
+  v9.CheckSourceFailure(lines, 'E1409: Cannot directly access interface "I" static member "num"')
 
   # script level cannot read interface static
   lines =<< trim END
@@ -4111,7 +4210,7 @@
 
     var x = I.s_var1
   END
-  v9.CheckScriptFailure(lines, 'E1409: Cannot directly access interface "I" static member "s_var1"')
+  v9.CheckSourceFailure(lines, 'E1409: Cannot directly access interface "I" static member "s_var1"')
 
   # script level cannot write interface static
   lines =<< trim END
@@ -4122,7 +4221,7 @@
 
     I.s_var1 = 3
   END
-  v9.CheckScriptFailure(lines, 'E1409: Cannot directly access interface "I" static member "I.s_var1 = 3"')
+  v9.CheckSourceFailure(lines, 'E1409: Cannot directly access interface "I" static member "I.s_var1 = 3"')
 
 enddef
 
@@ -4158,7 +4257,7 @@
 
     assert_equal(11, F1())
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 " Test for accessing a private member outside a class in a def function
@@ -4178,7 +4277,7 @@
     enddef
     T()
   END
-  v9.CheckScriptFailure(lines, 'E1333: Cannot access private member: _val')
+  v9.CheckSourceFailure(lines, 'E1333: Cannot access private member: _val')
 
   # access a non-existing private object member variable
   lines =<< trim END
@@ -4192,7 +4291,7 @@
     enddef
     T()
   END
-  v9.CheckScriptFailure(lines, 'E1089: Unknown variable: _a = 1')
+  v9.CheckSourceFailure(lines, 'E1089: Unknown variable: _a')
 
   # private static member variable
   lines =<< trim END
@@ -4206,7 +4305,7 @@
     enddef
     T()
   END
-  v9.CheckScriptFailure(lines, 'E1326: Member not found on object "A": _val')
+  v9.CheckSourceFailure(lines, 'E1375: Class member "_val" accessible only using class "A"')
 
   # private static member variable
   lines =<< trim END
@@ -4220,8 +4319,7 @@
     enddef
     T()
   END
-  # TODO: wrong error, should be about private member
-  v9.CheckScriptFailure(lines, 'E1089: Unknown variable')
+  v9.CheckSourceFailure(lines, 'E1374: Class member "_val" accessible only inside class "A"')
 
   # private static class variable
   lines =<< trim END
@@ -4234,7 +4332,7 @@
     enddef
     T()
   END
-  v9.CheckScriptFailure(lines, 'E1333: Cannot access private member: _val')
+  v9.CheckSourceFailure(lines, 'E1333: Cannot access private member: _val')
 
   # private static class variable
   lines =<< trim END
@@ -4247,7 +4345,7 @@
     enddef
     T()
   END
-  v9.CheckScriptFailure(lines, 'E1333: Cannot access private member: _val')
+  v9.CheckSourceFailure(lines, 'E1333: Cannot access private member: _val')
 enddef
 
 " Test for changing the member access of an interface in a implementation class
@@ -4261,7 +4359,7 @@
       this.val = 10
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1367: Access level of member "val" of interface "A" is different')
+  v9.CheckSourceFailure(lines, 'E1367: Access level of member "val" of interface "A" is different')
 
   lines =<< trim END
     vim9script
@@ -4272,7 +4370,7 @@
       public this.val = 10
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1367: Access level of member "val" of interface "A" is different')
+  v9.CheckSourceFailure(lines, 'E1367: Access level of member "val" of interface "A" is different')
 enddef
 
 " Test for trying to change a readonly member from a def function
@@ -4288,7 +4386,7 @@
     enddef
     T()
   END
-  v9.CheckScriptFailure(lines, 'E46: Cannot change read-only variable "val"')
+  v9.CheckSourceFailure(lines, 'E46: Cannot change read-only variable "val"')
 enddef
 
 " Test for reading and writing a class member from a def function
@@ -4312,7 +4410,7 @@
     enddef
     T()
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 " Test for accessing a class member variable using an object
@@ -4337,7 +4435,7 @@
     enddef
     Foo()
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # Cannot read from a class variable using an object in script context
   lines =<< trim END
@@ -4350,7 +4448,7 @@
     var a = A.new()
     echo a.svar2
   END
-  v9.CheckScriptFailure(lines, 'E1326: Member not found on object "A": svar2')
+  v9.CheckSourceFailure(lines, 'E1375: Class member "svar2" accessible only using class "A"')
 
   # Cannot write to a class variable using an object in script context
   lines =<< trim END
@@ -4363,7 +4461,7 @@
     var a = A.new()
     a.svar2 = [2]
   END
-  v9.CheckScriptFailure(lines, 'E1334: Object member not found: svar2 = [2]')
+  v9.CheckSourceFailure(lines, 'E1375: Class member "svar2" accessible only using class "A"')
 
   # Cannot read from a class variable using an object in def method context
   lines =<< trim END
@@ -4379,7 +4477,7 @@
     enddef
     T()
   END
-  v9.CheckScriptFailure(lines, 'E1326: Member not found on object "A": svar2')
+  v9.CheckSourceFailure(lines, 'E1375: Class member "svar2" accessible only using class "A"')
 
   # Cannot write to a class variable using an object in def method context
   lines =<< trim END
@@ -4395,7 +4493,7 @@
     enddef
     T()
   END
-  v9.CheckScriptFailure(lines, 'E1089: Unknown variable: svar2 = [2]')
+  v9.CheckSourceFailure(lines, 'E1374: Class member "svar2" accessible only inside class "A"')
 enddef
 
 " Test for using a interface method using a child object
@@ -4431,7 +4529,7 @@
     T1(c)
     T2(c)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 enddef
 
 " Test for using an interface method using a child object when it is overridden
@@ -4472,7 +4570,7 @@
 "     T1(c)
 "     T2(c)
 "   END
-"   v9.CheckScriptSuccess(lines)
+"   v9.CheckSourceSuccess(lines)
 " enddef
 
 " Test for abstract methods
@@ -4498,7 +4596,7 @@
     var b = B.new()
     assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # Don't define an abstract method
   lines =<< trim END
@@ -4509,7 +4607,7 @@
     class B extends A
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1373: Abstract method "Foo" is not implemented')
+  v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented')
 
   # Use abstract method in a concrete class
   lines =<< trim END
@@ -4520,7 +4618,7 @@
     class B extends A
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class')
+  v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class')
 
   # Use abstract method in an interface
   lines =<< trim END
@@ -4531,7 +4629,7 @@
     class B implements A
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class')
+  v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class')
 
   # Abbreviate the "abstract" keyword
   lines =<< trim END
@@ -4540,7 +4638,7 @@
       abs def Foo()
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()')
+  v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()')
 
   # Use "abstract" with a member variable
   lines =<< trim END
@@ -4549,7 +4647,7 @@
       abstract this.val = 10
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1371: Abstract must be followed by "def" or "static"')
+  v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def" or "static"')
 
   # Use a static abstract method
   lines =<< trim END
@@ -4564,7 +4662,7 @@
     endclass
     assert_equal(4, B.Foo())
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # Type mismatch between abstract method and concrete method
   lines =<< trim END
@@ -4578,7 +4676,7 @@
       enddef
     endclass
   END
-  v9.CheckScriptFailure(lines, 'E1407: Method "Foo": type mismatch, expected func(string, number): list<number> but got func(number, string): list<string>')
+  v9.CheckSourceFailure(lines, 'E1407: Method "Foo": type mismatch, expected func(string, number): list<number> but got func(number, string): list<string>')
 
   # Use an abstract class to invoke an abstract method
   # FIXME: This should fail
@@ -4589,7 +4687,7 @@
     endclass
     A.Foo()
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # Invoke an abstract method from a def function
   lines =<< trim END
@@ -4608,7 +4706,31 @@
     var b = B.new()
     Bar(b)
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for calling a class method from a subclass
+def Test_class_method_call_from_subclass()
+  # class method call from a subclass
+  var lines =<< trim END
+    vim9script
+
+    class A
+      static def Foo()
+        echo "foo"
+      enddef
+    endclass
+
+    class B extends A
+      def Bar()
+        Foo()
+      enddef
+    endclass
+
+    var b = B.new()
+    b.Bar()
+  END
+  v9.CheckSourceFailure(lines, 'E1374: Class member "Foo" accessible only inside class "A"')
 enddef
 
 " Test for calling a class method using an object in a def function context and
@@ -4638,7 +4760,7 @@
     a.Bar()
     T()
   END
-  v9.CheckScriptSuccess(lines)
+  v9.CheckSourceSuccess(lines)
 
   # script context
   lines =<< trim END
@@ -4652,7 +4774,7 @@
     var a = A.new()
     assert_equal('foo', a.Foo())
   END
-  v9.CheckScriptFailure(lines, 'E1325: Method not found on class "A": Foo()')
+  v9.CheckSourceFailure(lines, 'E1375: Class member "Foo" accessible only using class "A"')
 
   # def function context
   lines =<< trim END
@@ -4669,7 +4791,407 @@
     enddef
     T()
   END
-  v9.CheckScriptFailure(lines, 'E1325: Method not found on class "A": Foo()')
+  v9.CheckSourceFailure(lines, 'E1375: Class member "Foo" accessible only using class "A"')
+enddef
+
+def Test_class_variable()
+  var lines =<< trim END
+    vim9script
+
+    class A
+      public static val: number = 10
+      static def ClassFunc()
+        assert_equal(10, val)
+      enddef
+      def ObjFunc()
+        assert_equal(10, val)
+      enddef
+    endclass
+
+    class B extends A
+    endclass
+
+    assert_equal(10, A.val)
+    A.ClassFunc()
+    var a = A.new()
+    a.ObjFunc()
+    var b = B.new()
+    b.ObjFunc()
+
+    def T1(a1: A)
+      a1.ObjFunc()
+      A.ClassFunc()
+    enddef
+    T1(b)
+
+    A.val = 20
+    assert_equal(20, A.val)
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # Modifying a parent class variable from a child class method
+  lines =<< trim END
+    vim9script
+
+    class A
+      static val: number = 10
+    endclass
+
+    class B extends A
+      static def ClassFunc()
+        val = 20
+      enddef
+    endclass
+    B.ClassFunc()
+  END
+  v9.CheckSourceFailure(lines, 'E1374: Class member "val" accessible only inside class "A"')
+
+  # Reading a parent class variable from a child class method
+  lines =<< trim END
+    vim9script
+
+    class A
+      static val: number = 10
+    endclass
+
+    class B extends A
+      static def ClassFunc()
+        var i = val
+      enddef
+    endclass
+    B.ClassFunc()
+  END
+  v9.CheckSourceFailure(lines, 'E1374: Class member "val" accessible only inside class "A"')
+
+  # Modifying a parent class variable from a child object method
+  lines =<< trim END
+    vim9script
+
+    class A
+      static val: number = 10
+    endclass
+
+    class B extends A
+      def ObjFunc()
+        val = 20
+      enddef
+    endclass
+    var b = B.new()
+    b.ObjFunc()
+  END
+  v9.CheckSourceFailure(lines, 'E1374: Class member "val" accessible only inside class "A"')
+
+  # Reading a parent class variable from a child object method
+  lines =<< trim END
+    vim9script
+
+    class A
+      static val: number = 10
+    endclass
+
+    class B extends A
+      def ObjFunc()
+        var i = val
+      enddef
+    endclass
+    var b = B.new()
+    b.ObjFunc()
+  END
+  v9.CheckSourceFailure(lines, 'E1374: Class member "val" accessible only inside class "A"')
+
+  # Modifying a class variable using an object at script level
+  lines =<< trim END
+    vim9script
+
+    class A
+      static val: number = 10
+    endclass
+    var a = A.new()
+    a.val = 20
+  END
+  v9.CheckSourceFailure(lines, 'E1375: Class member "val" accessible only using class "A"')
+
+  # Reading a class variable using an object at script level
+  lines =<< trim END
+    vim9script
+
+    class A
+      static val: number = 10
+    endclass
+    var a = A.new()
+    var i = a.val
+  END
+  v9.CheckSourceFailure(lines, 'E1375: Class member "val" accessible only using class "A"')
+
+  # Modifying a class variable using an object at function level
+  lines =<< trim END
+    vim9script
+
+    class A
+      static val: number = 10
+    endclass
+
+    def T()
+      var a = A.new()
+      a.val = 20
+    enddef
+    T()
+  END
+  v9.CheckSourceFailure(lines, 'E1374: Class member "val" accessible only inside class "A"')
+
+  # Reading a class variable using an object at function level
+  lines =<< trim END
+    vim9script
+
+    class A
+      static val: number = 10
+    endclass
+    def T()
+      var a = A.new()
+      var i = a.val
+    enddef
+    T()
+  END
+  v9.CheckSourceFailure(lines, 'E1375: Class member "val" accessible only using class "A"')
+enddef
+
+" Test for using a duplicate class method and class variable in a child class
+def Test_dup_class_member()
+  # duplicate class variable, class method and overridden object method
+  var lines =<< trim END
+    vim9script
+    class A
+      static sval = 100
+      static def Check()
+        assert_equal(100, sval)
+      enddef
+      def GetVal(): number
+        return sval
+      enddef
+    endclass
+
+    class B extends A
+      static sval = 200
+      static def Check()
+        assert_equal(200, sval)
+      enddef
+      def GetVal(): number
+        return sval
+      enddef
+    endclass
+
+    def T1(aa: A): number
+      return aa.GetVal()
+    enddef
+
+    def T2(bb: B): number
+      return bb.GetVal()
+    enddef
+
+    assert_equal(100, A.sval)
+    assert_equal(200, B.sval)
+    var a = A.new()
+    assert_equal(100, a.GetVal())
+    var b = B.new()
+    assert_equal(200, b.GetVal())
+    assert_equal(200, T1(b))
+    assert_equal(200, T2(b))
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # duplicate class variable and class method
+  lines =<< trim END
+    vim9script
+    class A
+      static sval = 100
+      static def Check()
+        assert_equal(100, sval)
+      enddef
+      def GetVal(): number
+        return sval
+      enddef
+    endclass
+
+    class B extends A
+      static sval = 200
+      static def Check()
+        assert_equal(200, sval)
+      enddef
+    endclass
+
+    def T1(aa: A): number
+      return aa.GetVal()
+    enddef
+
+    def T2(bb: B): number
+      return bb.GetVal()
+    enddef
+
+    assert_equal(100, A.sval)
+    assert_equal(200, B.sval)
+    var a = A.new()
+    assert_equal(100, a.GetVal())
+    var b = B.new()
+    assert_equal(100, b.GetVal())
+    assert_equal(100, T1(b))
+    assert_equal(100, T2(b))
+  END
+  v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for calling an instance method using the class
+def Test_instance_method_call_using_class()
+  # Invoke an object method using a class in script context
+  var lines =<< trim END
+    vim9script
+    class A
+      def Foo()
+        echo "foo"
+      enddef
+    endclass
+    A.Foo()
+  END
+  v9.CheckSourceFailure(lines, 'E1376: Object member "Foo" accessible only using class "A" object')
+
+  # Invoke an object method using a class in def function context
+  lines =<< trim END
+    vim9script
+    class A
+      def Foo()
+        echo "foo"
+      enddef
+    endclass
+    def T()
+      A.Foo()
+    enddef
+    T()
+  END
+  v9.CheckSourceFailure(lines, 'E1376: Object member "Foo" accessible only using class "A" object')
+enddef
+
+" Test for duplicate class method and instance method
+def Test_dup_classmethod_objmethod()
+  # Duplicate instance method
+  var lines =<< trim END
+    vim9script
+    class A
+      static def Foo()
+      enddef
+      def Foo()
+      enddef
+    endclass
+  END
+  v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo')
+
+  # Duplicate private instance method
+  lines =<< trim END
+    vim9script
+    class A
+      static def Foo()
+      enddef
+      def _Foo()
+      enddef
+    endclass
+  END
+  v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo')
+
+  # Duplicate class method
+  lines =<< trim END
+    vim9script
+    class A
+      def Foo()
+      enddef
+      static def Foo()
+      enddef
+    endclass
+  END
+  v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo')
+
+  # Duplicate private class method
+  lines =<< trim END
+    vim9script
+    class A
+      def Foo()
+      enddef
+      static def _Foo()
+      enddef
+    endclass
+  END
+  v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo')
+
+  # Duplicate private class and object method
+  lines =<< trim END
+    vim9script
+    class A
+      def _Foo()
+      enddef
+      static def _Foo()
+      enddef
+    endclass
+  END
+  v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo')
+enddef
+
+" Test for an instance method access level comparison with parent instance
+" methods.
+def Test_instance_method_access_level()
+  # Private method in subclass
+  var lines =<< trim END
+    vim9script
+    class A
+      def Foo()
+      enddef
+    endclass
+    class B extends A
+    endclass
+    class C extends B
+      def _Foo()
+      enddef
+    endclass
+  END
+  v9.CheckSourceFailure(lines, 'E1378: Access level of method "_Foo" is different in class "A"')
+
+  # Public method in subclass
+  lines =<< trim END
+    vim9script
+    class A
+      def _Foo()
+      enddef
+    endclass
+    class B extends A
+    endclass
+    class C extends B
+      def Foo()
+      enddef
+    endclass
+  END
+  v9.CheckSourceFailure(lines, 'E1378: Access level of method "Foo" is different in class "A"')
+enddef
+
+def Test_extend_empty_class()
+  var lines =<< trim END
+    vim9script
+    class A
+    endclass
+    class B extends A
+    endclass
+    class C extends B
+      public static rw_class_var = 1
+      public this.rw_obj_var = 2
+      static def ClassMethod(): number
+        return 3
+      enddef
+      def ObjMethod(): number
+        return 4
+      enddef
+    endclass
+    assert_equal(1, C.rw_class_var)
+    assert_equal(3, C.ClassMethod())
+    var c = C.new()
+    assert_equal(2, c.rw_obj_var)
+    assert_equal(4, c.ObjMethod())
+  END
+  v9.CheckSourceSuccess(lines)
 enddef
 
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/testdir/vim9.vim b/src/testdir/vim9.vim
index 5877a79..782809b 100644
--- a/src/testdir/vim9.vim
+++ b/src/testdir/vim9.vim
@@ -110,6 +110,40 @@
   endtry
 enddef
 
+# :source a list of "lines" and check whether it fails with "error"
+export def CheckSourceFailure(lines: list<string>, error: string, lnum = -3)
+  new
+  setline(1, lines)
+  try
+    assert_fails('source', error, lines, lnum)
+  finally
+    bw!
+  endtry
+enddef
+
+# :source a list of "lines" and check whether it fails with the list of
+# "errors"
+export def CheckSourceFailureList(lines: list<string>, errors: list<string>, lnum = -3)
+  new
+  setline(1, lines)
+  try
+    assert_fails('source', errors, lines, lnum)
+  finally
+    bw!
+  endtry
+enddef
+
+# :source a list of "lines" and check whether it succeeds
+export def CheckSourceSuccess(lines: list<string>)
+  new
+  setline(1, lines)
+  try
+    :source
+  finally
+    bw!
+  endtry
+enddef
+
 export def CheckDefAndScriptSuccess(lines: list<string>)
   CheckDefSuccess(lines)
   CheckScriptSuccess(['vim9script'] + lines)