changeset 33379:7c9124711f99 v9.0.1948

patch 9.0.1948: Vim9: object variable "this." should only be used in constructor Commit: https://github.com/vim/vim/commit/db38552dcdc7460459df8bf5cf02666256045308 Author: h-east <h.east.727@gmail.com> Date: Thu Sep 28 22:18:19 2023 +0200 patch 9.0.1948: Vim9: object variable "this." should only be used in constructor Problem: Vim9: object variable "this." should only be used in constructor Solution: Disallow to this in normal object methods (other than constructors) closes: #13152 closes: #13212 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: h-east <h.east.727@gmail.com>
author Christian Brabandt <cb@256bit.org>
date Thu, 28 Sep 2023 22:30:03 +0200
parents dd9da4eb6780
children 7ba7c38a9914
files runtime/doc/tags runtime/doc/vim9class.txt src/errors.h src/testdir/test_vim9_class.vim src/userfunc.c src/version.c
diffstat 6 files changed, 29 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -4483,6 +4483,7 @@ E1387	vim9class.txt	/*E1387*
 E1388	vim9class.txt	/*E1388*
 E1389	vim9class.txt	/*E1389*
 E139	message.txt	/*E139*
+E1390	vim9class.txt	/*E1390*
 E140	message.txt	/*E140*
 E1400	builtin.txt	/*E1400*
 E1401	builtin.txt	/*E1401*
--- a/runtime/doc/vim9class.txt
+++ b/runtime/doc/vim9class.txt
@@ -216,7 +216,8 @@ see this pattern: >
 	      this.col = col
 	   enddef
 	 endclass
-
+<
+							*E1390*
 Not only is this text you need to write, it also has the type of each
 variables twice.  Since this is so common a shorter way to write new() is
 provided: >
--- a/src/errors.h
+++ b/src/errors.h
@@ -3529,6 +3529,8 @@ EXTERN char e_public_keyword_not_support
 	INIT(= N_("E1388: Public keyword not supported for a method"));
 EXTERN char e_missing_name_after_implements[]
 	INIT(= N_("E1389: Missing name after implements"));
+EXTERN char e_cannot_use_an_object_variable_except_with_the_new_method_str[]
+	INIT(= N_("E1390: Cannot use an object variable \"this.%s\" except with the \"new\" method"));
 #endif
 EXTERN char e_cannot_mix_positional_and_non_positional_str[]
 	INIT(= N_("E1400: Cannot mix positional and non-positional arguments: %s"));
@@ -3544,4 +3546,4 @@ EXTERN char e_invalid_format_specifier_s
 	INIT(= N_("E1405: Invalid format specifier: %s"));
 EXTERN char e_aptypes_is_null_nr_str[]
 	INIT(= "E1408: Internal error: ap_types or ap_types[idx] is NULL: %d: %s");
-// E1390 - E1399 unused
+// E1391 - E1399 unused
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -956,6 +956,17 @@ def Test_class_new_with_object_member()
   v9.CheckSourceFailure(lines, 'E1013:')
 
   lines =<< trim END
+    vim9script
+
+    class C
+      this.str: string
+      def MethodA(this.str)
+      enddef
+    endclass
+  END
+  v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.str" except with the "new" method')
+
+  lines =<< trim END
       vim9script
 
       class C
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -320,6 +320,16 @@ get_function_args(
 		++p;
 	    char_u *argend = p;
 
+	    // object variable this. can be used only in a constructor
+	    if (STRNCMP(eap->arg, "new", 3) != 0)
+	    {
+		c = *argend;
+		*argend = NUL;
+		semsg(_(e_cannot_use_an_object_variable_except_with_the_new_method_str), arg);
+		*argend = c;
+		break;
+	    }
+
 	    if (*skipwhite(p) == '=')
 	    {
 		char_u *defval = skipwhite(skipwhite(p) + 1);
--- a/src/version.c
+++ b/src/version.c
@@ -700,6 +700,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1948,
+/**/
     1947,
 /**/
     1946,