changeset 31720:1949c2613b3e v9.0.1192

patch 9.0.1192: no error when class function argument shadows a member Commit: https://github.com/vim/vim/commit/d40f00cb43019fb4d39b89f407f8b52e92f9e16f Author: Bram Moolenaar <Bram@vim.org> 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.
author Bram Moolenaar <Bram@vim.org>
date Fri, 13 Jan 2023 18:45:03 +0100
parents de70d5c5ef88
children a651dcb2c127
files src/testdir/test_vim9_class.vim src/version.c src/vim9class.c
diffstat 3 files changed, 53 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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,
--- 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)
     {