# HG changeset patch # User Bram Moolenaar # Date 1673631903 -3600 # Node ID 1949c2613b3e53f6a8b072c80d89e164264df9a8 # Parent de70d5c5ef88428f9d22dbd95da21edd72e6d89c patch 9.0.1192: no error when class function argument shadows a member Commit: https://github.com/vim/vim/commit/d40f00cb43019fb4d39b89f407f8b52e92f9e16f Author: Bram Moolenaar Date: Fri Jan 13 17:36:49 2023 +0000 patch 9.0.1192: no error when class function argument shadows a member Problem: No error when class function argument shadows a member. Solution: Check for shadowing. diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim --- a/src/testdir/test_vim9_class.vim +++ b/src/testdir/test_vim9_class.vim @@ -639,8 +639,17 @@ def Test_interface_basics() def Method(count: number) endinterface END - # TODO: this should give an error for "count" shadowing - v9.CheckScriptSuccess(lines) + v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count') + + lines =<< trim END + vim9script + + interface Some + this.value: number + def Method(value: number) + endinterface + END + v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: value') lines =<< trim END vim9script diff --git a/src/version.c b/src/version.c --- 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 */ /**/ + 1192, +/**/ 1191, /**/ 1190, diff --git a/src/vim9class.c b/src/vim9class.c --- a/src/vim9class.c +++ b/src/vim9class.c @@ -699,6 +699,46 @@ early_ret: } } + if (success) + { + // Check no function argument name is used as an object/class member. + for (int loop = 1; loop <= 2 && success; ++loop) + { + garray_T *gap = loop == 1 ? &classfunctions : &objmethods; + + for (int fi = 0; fi < gap->ga_len && success; ++fi) + { + ufunc_T *uf = ((ufunc_T **)gap->ga_data)[fi]; + + for (int i = 0; i < uf->uf_args.ga_len && success; ++i) + { + char_u *aname = ((char_u **)uf->uf_args.ga_data)[i]; + for (int il = 1; il <= 2 && success; ++il) + { + // For a "new()" function "this.member" arguments are + // OK. TODO: check for the "this." prefix. + if (STRNCMP(uf->uf_name, "new", 3) == NULL && il == 2) + continue; + garray_T *mgap = il == 1 ? &classmembers : &objmembers; + for (int mi = 0; mi < mgap->ga_len; ++mi) + { + char_u *mname = ((ocmember_T *)mgap->ga_data + + mi)->ocm_name; + if (STRCMP(aname, mname) == 0) + { + success = FALSE; + semsg(_(e_argument_already_declared_in_class_str), + aname); + break; + } + } + } + } + } + } + } + + class_T *cl = NULL; if (success) {