From 6aa0937fb88001a5ea18e732aad4c625e9b2baeb Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Wed, 11 Jan 2023 17:59:38 +0000 Subject: [PATCH] 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. --- src/errors.h | 2 ++ src/testdir/test_vim9_class.vim | 57 +++++++++++++++++++++++++++++++++ src/version.c | 2 ++ src/vim9compile.c | 14 ++++++++ src/vim9expr.c | 13 ++++---- 5 files changed, 82 insertions(+), 6 deletions(-) diff --git a/src/errors.h b/src/errors.h index 6fa1abb78..de1ae4bd0 100644 --- a/src/errors.h +++ b/src/errors.h @@ -3438,4 +3438,6 @@ EXTERN char e_super_must_be_followed_by_dot[] 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")); +EXTERN char e_using_super_not_in_child_class[] + INIT(= N_("E1358: Using \"super\" not in a child class")); #endif diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim index 220cb7578..c6da4f49c 100644 --- 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 diff --git a/src/version.c b/src/version.c index 1c8bf6086..b16a3f757 100644 --- a/src/version.c +++ b/src/version.c @@ -695,6 +695,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1179, /**/ 1178, /**/ diff --git a/src/vim9compile.c b/src/vim9compile.c index 9fe850775..cc7a3bdc4 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -49,6 +49,20 @@ lookup_local(char_u *name, size_t len, lvar_T *lvar, cctx_T *cctx) && (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); diff --git a/src/vim9expr.c b/src/vim9expr.c index 27f3bc465..bbf3059e2 100644 --- a/src/vim9expr.c +++ b/src/vim9expr.c @@ -268,14 +268,14 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type) 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; + emsg(_(e_using_super_not_in_class_function)); + 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; } -- 2.40.0