changeset 31744:1b2bde0c64f2 v9.0.1204

patch 9.0.1204: expression compiled the wrong way after using an object Commit: https://github.com/vim/vim/commit/912bfee71041fce0902bbcb649faf247519ec400 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jan 15 20:18:55 2023 +0000 patch 9.0.1204: expression compiled the wrong way after using an object Problem: Expression compiled the wrong way after using an object. Solution: Generate constants before getting the type.
author Bram Moolenaar <Bram@vim.org>
date Sun, 15 Jan 2023 21:30:03 +0100
parents 3ebf441d9f88
children ded74e298639
files src/testdir/test_vim9_class.vim src/version.c src/vim9expr.c
diffstat 3 files changed, 54 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -240,6 +240,25 @@ def Test_list_of_objects()
   v9.CheckScriptSuccess(lines)
 enddef
 
+def Test_expr_after_using_object()
+  var lines =<< trim END
+      vim9script
+
+      class Something
+        this.label: string = ''
+      endclass
+
+      def Foo(): Something
+        var v = Something.new()
+        echo 'in Foo(): ' .. typename(v)
+        return v
+      enddef
+
+      Foo()
+  END
+  v9.CheckScriptSuccess(lines)
+enddef
+
 def Test_class_default_new()
   var 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 */
 /**/
+    1204,
+/**/
     1203,
 /**/
     1202,
--- a/src/vim9expr.c
+++ b/src/vim9expr.c
@@ -2252,19 +2252,6 @@ compile_subscript(
 	    if (compile_member(is_slice, &keeping_dict, cctx) == FAIL)
 		return FAIL;
 	}
-	else if (*p == '.'
-		&& (type = get_type_on_stack(cctx, 0)) != &t_unknown
-		&& (type->tt_type == VAR_CLASS || type->tt_type == VAR_OBJECT))
-	{
-	    // class member: SomeClass.varname
-	    // class method: SomeClass.SomeMethod()
-	    // 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;
-	}
 	else if (*p == '.' && p[1] != '.')
 	{
 	    // dictionary member: dict.name
@@ -2272,27 +2259,43 @@ compile_subscript(
 		return FAIL;
 	    ppconst->pp_is_const = FALSE;
 
-	    *arg = p + 1;
-	    if (IS_WHITE_OR_NUL(**arg))
+	    if ((type = get_type_on_stack(cctx, 0)) != &t_unknown
+		    && (type->tt_type == VAR_CLASS
+					       || type->tt_type == VAR_OBJECT))
 	    {
-		emsg(_(e_missing_name_after_dot));
-		return FAIL;
+		// class member: SomeClass.varname
+		// class method: SomeClass.SomeMethod()
+		// 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;
 	    }
-	    p = *arg;
-	    if (eval_isdictc(*p))
-		while (eval_isnamec(*p))
-		    MB_PTR_ADV(p);
-	    if (p == *arg)
+	    else
 	    {
-		semsg(_(e_syntax_error_at_str), *arg);
-		return FAIL;
+		*arg = p + 1;
+		if (IS_WHITE_OR_NUL(**arg))
+		{
+		    emsg(_(e_missing_name_after_dot));
+		    return FAIL;
+		}
+		p = *arg;
+		if (eval_isdictc(*p))
+		    while (eval_isnamec(*p))
+			MB_PTR_ADV(p);
+		if (p == *arg)
+		{
+		    semsg(_(e_syntax_error_at_str), *arg);
+		    return FAIL;
+		}
+		if (keeping_dict && generate_instr(cctx, ISN_CLEARDICT) == NULL)
+		    return FAIL;
+		if (generate_STRINGMEMBER(cctx, *arg, p - *arg) == FAIL)
+		    return FAIL;
+		keeping_dict = TRUE;
+		*arg = p;
 	    }
-	    if (keeping_dict && generate_instr(cctx, ISN_CLEARDICT) == NULL)
-		return FAIL;
-	    if (generate_STRINGMEMBER(cctx, *arg, p - *arg) == FAIL)
-		return FAIL;
-	    keeping_dict = TRUE;
-	    *arg = p;
 	}
 	else
 	    break;