]> granicus.if.org Git - vim/commitdiff
patch 9.0.1204: expression compiled the wrong way after using an object v9.0.1204
authorBram Moolenaar <Bram@vim.org>
Sun, 15 Jan 2023 20:18:55 +0000 (20:18 +0000)
committerBram Moolenaar <Bram@vim.org>
Sun, 15 Jan 2023 20:18:55 +0000 (20:18 +0000)
Problem:    Expression compiled the wrong way after using an object.
Solution:   Generate constants before getting the type.

src/testdir/test_vim9_class.vim
src/version.c
src/vim9expr.c

index 28af68b386ee02d481756cb6a2376d161df5b44a..83717eb5d35d14f6c41213354df3a034e4de3c6c 100644 (file)
@@ -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
index f36b66651a32dcfa484124c04635f462dab0c272..95b92e4a8dd4cae561632750fd9625beb54be361 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1204,
 /**/
     1203,
 /**/
index bbf3059e2b00a1f56fac347bac035d0530f66882..6131f9fe600d0a8d1f566b85b2c0a3e714104e03 100644 (file)
@@ -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))
-           {
-               emsg(_(e_missing_name_after_dot));
-               return FAIL;
+           if ((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;
            }
-           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;