From f6096d3e50fbaea42d091bebbe79c4d2e4b07802 Mon Sep 17 00:00:00 2001 From: SunsetFi Date: Tue, 7 Apr 2026 10:41:21 -0700 Subject: [PATCH 1/7] fix(mock): Do not hoist imports that match class properties close #10093 --- packages/mocker/src/node/esmWalker.ts | 5 +++++ test/core/test/injector-mock.test.ts | 10 +++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/mocker/src/node/esmWalker.ts b/packages/mocker/src/node/esmWalker.ts index 9efebe893736..324d261d8ee4 100644 --- a/packages/mocker/src/node/esmWalker.ts +++ b/packages/mocker/src/node/esmWalker.ts @@ -311,6 +311,11 @@ function isRefIdentifier(id: Identifier, parent: _Node, parentStack: _Node[]) { return false } + // class property + if (parent.type === 'PropertyDefinition' && !parent.computed) { + return false + } + // property key if (isStaticPropertyKey(id, parent)) { return false diff --git a/test/core/test/injector-mock.test.ts b/test/core/test/injector-mock.test.ts index 56c66b36a330..6b5ac9226504 100644 --- a/test/core/test/injector-mock.test.ts +++ b/test/core/test/injector-mock.test.ts @@ -752,6 +752,9 @@ class A { remove = 1 add = null } + +remove(2); +add(4); `, ), ).toMatchInlineSnapshot(` @@ -761,12 +764,13 @@ class A { - const add = __vi_import_0__.add; - const remove = __vi_import_0__.remove; class A { remove = 1 add = null - }" + } + + __vi_import_0__.remove(2); + __vi_import_0__.add(4);" `) }) From b97abc96bdec4beb8f2b86faf13612e88a8559bf Mon Sep 17 00:00:00 2001 From: SunsetFi Date: Tue, 7 Apr 2026 11:15:55 -0700 Subject: [PATCH 2/7] Hoist class property assignment references. --- packages/mocker/src/node/esmWalker.ts | 3 ++- test/core/test/injector-mock.test.ts | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/mocker/src/node/esmWalker.ts b/packages/mocker/src/node/esmWalker.ts index 324d261d8ee4..53f2d915bf7a 100644 --- a/packages/mocker/src/node/esmWalker.ts +++ b/packages/mocker/src/node/esmWalker.ts @@ -313,7 +313,8 @@ function isRefIdentifier(id: Identifier, parent: _Node, parentStack: _Node[]) { // class property if (parent.type === 'PropertyDefinition' && !parent.computed) { - return false + // Default values can still reference identifiers + return id === parent.value } // property key diff --git a/test/core/test/injector-mock.test.ts b/test/core/test/injector-mock.test.ts index 6b5ac9226504..dc09915441a9 100644 --- a/test/core/test/injector-mock.test.ts +++ b/test/core/test/injector-mock.test.ts @@ -746,11 +746,12 @@ const obj = { expect( hoistSimpleCodeWithoutMocks( ` -import { remove, add } from 'vue' +import { remove, add, update } from 'vue' class A { remove = 1 add = null + update = update } remove(2); @@ -763,10 +764,12 @@ add(4); import {vi} from "vitest"; - + + const update = __vi_import_0__.update; class A { remove = 1 add = null + update = update } __vi_import_0__.remove(2); From b08d4b8b82e06516185b51717692c14d95c0cc03 Mon Sep 17 00:00:00 2001 From: SunsetFi Date: Tue, 7 Apr 2026 11:22:11 -0700 Subject: [PATCH 3/7] More class prop reference tests --- test/core/test/injector-mock.test.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/core/test/injector-mock.test.ts b/test/core/test/injector-mock.test.ts index dc09915441a9..7a09deaf4a18 100644 --- a/test/core/test/injector-mock.test.ts +++ b/test/core/test/injector-mock.test.ts @@ -746,12 +746,14 @@ const obj = { expect( hoistSimpleCodeWithoutMocks( ` -import { remove, add, update } from 'vue' +import { remove, add, update, del, call } from 'vue' class A { remove = 1 add = null update = update + del = () => del() + call = call(4) } remove(2); @@ -764,12 +766,14 @@ add(4); import {vi} from "vitest"; - + const update = __vi_import_0__.update; class A { remove = 1 add = null update = update + del = () => __vi_import_0__.del() + call = __vi_import_0__.call(4) } __vi_import_0__.remove(2); From 79fd472e9acae636719ab0821a14ccc67a78f268 Mon Sep 17 00:00:00 2001 From: SunsetFi Date: Tue, 7 Apr 2026 12:07:09 -0700 Subject: [PATCH 4/7] Ensure timeout is not transformed --- test/core/test/injector-mock.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/core/test/injector-mock.test.ts b/test/core/test/injector-mock.test.ts index 7a09deaf4a18..983622eb2c2d 100644 --- a/test/core/test/injector-mock.test.ts +++ b/test/core/test/injector-mock.test.ts @@ -754,6 +754,7 @@ class A { update = update del = () => del() call = call(4) + timeout = null } remove(2); @@ -774,6 +775,7 @@ add(4); update = update del = () => __vi_import_0__.del() call = __vi_import_0__.call(4) + timeout = null } __vi_import_0__.remove(2); From 46136f897f4fc13324cddddb01f58ba3c778f863 Mon Sep 17 00:00:00 2001 From: SunsetFi Date: Tue, 7 Apr 2026 12:07:54 -0700 Subject: [PATCH 5/7] Remove timeout; case covered by add --- test/core/test/injector-mock.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/test/core/test/injector-mock.test.ts b/test/core/test/injector-mock.test.ts index 983622eb2c2d..433c05680362 100644 --- a/test/core/test/injector-mock.test.ts +++ b/test/core/test/injector-mock.test.ts @@ -775,7 +775,6 @@ add(4); update = update del = () => __vi_import_0__.del() call = __vi_import_0__.call(4) - timeout = null } __vi_import_0__.remove(2); From b93742830e8daca6864bfbc52d3af4c448698854 Mon Sep 17 00:00:00 2001 From: SunsetFi Date: Tue, 7 Apr 2026 12:18:00 -0700 Subject: [PATCH 6/7] Really remove timeout for real --- test/core/test/injector-mock.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/test/core/test/injector-mock.test.ts b/test/core/test/injector-mock.test.ts index 433c05680362..7a09deaf4a18 100644 --- a/test/core/test/injector-mock.test.ts +++ b/test/core/test/injector-mock.test.ts @@ -754,7 +754,6 @@ class A { update = update del = () => del() call = call(4) - timeout = null } remove(2); From e2025207dfd556f2024d7c6b51a51c2afd62fcee Mon Sep 17 00:00:00 2001 From: SunsetFi Date: Tue, 7 Apr 2026 12:26:04 -0700 Subject: [PATCH 7/7] Do not host / interpret identifiers used in class properties as class declarations --- packages/mocker/src/node/esmWalker.ts | 6 +----- test/core/test/injector-mock.test.ts | 3 +-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/mocker/src/node/esmWalker.ts b/packages/mocker/src/node/esmWalker.ts index 53f2d915bf7a..ab130b19049b 100644 --- a/packages/mocker/src/node/esmWalker.ts +++ b/packages/mocker/src/node/esmWalker.ts @@ -255,17 +255,13 @@ export function esmWalker( identifiers.forEach(([node, stack]) => { if (!isInScope(node.name, stack)) { const parent = stack[0] - const grandparent = stack[1] const hasBindingShortcut = isStaticProperty(parent) && parent.shorthand && (!isNodeInPattern(parent) || isInDestructuringAssignment(parent, parentStack)) - const classDeclaration - = (parent.type === 'PropertyDefinition' - && grandparent?.type === 'ClassBody') - || (parent.type === 'ClassDeclaration' && node === parent.superClass) + const classDeclaration = (parent.type === 'ClassDeclaration' && node === parent.superClass) const classExpression = parent.type === 'ClassExpression' && node === parent.id diff --git a/test/core/test/injector-mock.test.ts b/test/core/test/injector-mock.test.ts index 7a09deaf4a18..00140e705140 100644 --- a/test/core/test/injector-mock.test.ts +++ b/test/core/test/injector-mock.test.ts @@ -767,11 +767,10 @@ add(4); - const update = __vi_import_0__.update; class A { remove = 1 add = null - update = update + update = __vi_import_0__.update del = () => __vi_import_0__.del() call = __vi_import_0__.call(4) }