changeset 31694:2f61e308b997 v9.0.1179

patch 9.0.1179: not all errors around inheritance are tested Commit: https://github.com/vim/vim/commit/6aa0937fb88001a5ea18e732aad4c625e9b2baeb Author: Bram Moolenaar <Bram@vim.org> Date: Wed Jan 11 17:59:38 2023 +0000 patch 9.0.1179: not all errors around inheritance are tested Problem: Not all errors around inheritance are tested. Solution: Add more tests. Fix uncovered problems.
author Bram Moolenaar <Bram@vim.org>
date Wed, 11 Jan 2023 19:00:06 +0100
parents 2698d61dcc97
children 67deb9ef03b7
files src/errors.h src/testdir/test_vim9_class.vim src/version.c src/vim9compile.c src/vim9expr.c
diffstat 5 files changed, 83 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/errors.h
+++ b/src/errors.h
@@ -3438,4 +3438,6 @@ EXTERN char e_super_must_be_followed_by_
 	INIT(= N_("E1356: \"super\" must be followed by a dot"));
 EXTERN char e_using_super_not_in_class_function[]
 	INIT(= N_("E1357: Using \"super\" not in a class function"));
-#endif
+EXTERN char e_using_super_not_in_child_class[]
+	INIT(= N_("E1358: Using \"super\" not in a child class"));
+#endif
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -838,6 +838,63 @@ def Test_class_extends()
       assert_equal('John: 42', o.ToString())
   END
   v9.CheckScriptSuccess(lines)
+
+  lines =<< trim END
+      vim9script
+      class Child
+        this.age: number
+        def ToString(): number
+          return this.age
+        enddef
+        def ToString(): string
+          return this.age
+        enddef
+      endclass
+  END
+  v9.CheckScriptFailure(lines, 'E1355: Duplicate function: ToString')
+
+  lines =<< trim END
+      vim9script
+      class Child
+        this.age: number
+        def ToString(): string
+          return super .ToString() .. ': ' .. this.age
+        enddef
+      endclass
+      var o = Child.new(42)
+      echo o.ToString()
+  END
+  v9.CheckScriptFailure(lines, 'E1356:')
+
+  lines =<< trim END
+      vim9script
+      class Base
+        this.name: string
+        def ToString(): string
+          return this.name
+        enddef
+      endclass
+
+      var age = 42
+      def ToString(): string
+        return super.ToString() .. ': ' .. age
+      enddef
+      echo ToString()
+  END
+  v9.CheckScriptFailure(lines, 'E1357:')
+
+  lines =<< trim END
+      vim9script
+      class Child
+        this.age: number
+        def ToString(): string
+          return super.ToString() .. ': ' .. this.age
+        enddef
+      endclass
+      var o = Child.new(42)
+      echo o.ToString()
+  END
+  v9.CheckScriptFailure(lines, 'E1358:')
 enddef
 
 
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1179,
+/**/
     1178,
 /**/
     1177,
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -49,6 +49,20 @@ lookup_local(char_u *name, size_t len, l
 	    && (cctx->ctx_ufunc->uf_flags & (FC_OBJECT|FC_NEW)))
     {
 	int is_super = *name == 's';
+	if (is_super)
+	{
+	    if (name[5] != '.')
+	    {
+		emsg(_(e_super_must_be_followed_by_dot));
+		return FAIL;
+	    }
+	    if (cctx->ctx_ufunc->uf_class != NULL
+		    && cctx->ctx_ufunc->uf_class->class_extends == NULL)
+	    {
+		emsg(_(e_using_super_not_in_child_class));
+		return FAIL;
+	    }
+	}
 	if (lvar != NULL)
 	{
 	    CLEAR_POINTER(lvar);
--- a/src/vim9expr.c
+++ b/src/vim9expr.c
@@ -268,14 +268,14 @@ compile_class_object_index(cctx_T *cctx,
     if (type == &t_super)
     {
 	if (cctx->ctx_ufunc == NULL || cctx->ctx_ufunc->uf_class == NULL)
+	{
 	    emsg(_(e_using_super_not_in_class_function));
-	else
-	{
-	    is_super = TRUE;
-	    cl = cctx->ctx_ufunc->uf_class;
-	    // Remove &t_super from the stack.
-	    --cctx->ctx_type_stack.ga_len;
+	    return FAIL;
 	}
+	is_super = TRUE;
+	cl = cctx->ctx_ufunc->uf_class;
+	// Remove &t_super from the stack.
+	--cctx->ctx_type_stack.ga_len;
     }
     else if (type->tt_type == VAR_CLASS)
     {
@@ -2261,6 +2261,7 @@ compile_subscript(
 	    // class constructor: SomeClass.new()
 	    // object member: someObject.varname, this.varname
 	    // object method: someObject.SomeMethod(), this.SomeMethod()
+	    *arg = p;
 	    if (compile_class_object_index(cctx, arg, type) == FAIL)
 		return FAIL;
 	}