-
-
Notifications
You must be signed in to change notification settings - Fork 69
enhance(lang-service): performance improve for generate virtual code #301
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
✅ Deploy Preview for vue-vine ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
WalkthroughThis update introduces a new analysis function for Vine TypeScript files, restructures template compilation and code generation for language service support, and modularizes codegen logic into dedicated modules. Several type and variable prefixes are renamed for consistency, and internal helpers are refactored or replaced to streamline AST handling, diagnostics, and virtual code generation. Test cases and dependency declarations are also updated accordingly. Changes
Sequence Diagram(s)sequenceDiagram
participant LS as Language Service
participant Compiler as Vine Compiler
participant Codegen as Codegen Module
LS->>Compiler: analyzeVineTypeScriptFile(code, fileId, ctx)
Compiler->>Compiler: Create VineFileCtx, bind hooks
Compiler->>Compiler: Find Vine component functions
Compiler->>Compiler: Validate and analyze Vine restrictions
Compiler->>Compiler: For each VineCompFn, compile template AST
Compiler->>Compiler: Store template AST and diagnostics
Compiler->>Compiler: Call onEnd hook
Compiler-->>LS: Return VineFileCtx
LS->>Codegen: createVueVineVirtualCode(VineFileCtx)
Codegen->>Codegen: Generate TS code segments, embedded files
Codegen-->>LS: Virtual code & embedded files for IDE features
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
Note 🔌 MCP (Model Context Protocol) integration is now available in Early Access!Pro users can now connect to remote MCP servers under the Integrations page to get reviews and chat conversations that understand additional development context. ✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
@vue-vine/compiler
create-vue-vine
@vue-vine/eslint-config
@vue-vine/eslint-parser
@vue-vine/eslint-plugin
@vue-vine/language-server
@vue-vine/language-service
@vue-vine/nuxt
vue-vine-tsc
@vue-vine/vite-plugin
vue-vine
commit: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🔭 Outside diff range comments (1)
packages/language-service/src/injectTypes.ts (1)
42-47
: String-replace on magic line is fragile
generateGlobalTypes()
blindly replaces the exact string
type __VLS_Element = import('vue/jsx-runtime').JSX.Element;
If upstream@vue/language-core
ever tweaks whitespace or semicolons, the replacement silently fails.Guard with a regex or fallback:
globalTypes = globalTypes.replace( /type\s+__VLS_Element\s*=\s*import\('vue\/jsx-runtime'\)\.JSX\.Element\s*;/, 'type __VLS_Element = import(\'vue/jsx-runtime\').JSX.Element & { [VUE_VINE_COMPONENT]: true };', )This makes updates less brittle.
🧹 Nitpick comments (11)
packages/compiler/tests/validate.spec.ts (1)
276-283
: Underlying compiler emits duplicate errors – consider de-duping instead of asserting twiceUpdating the snapshot to expect two identical messages papers over a duplication bug in template validation. Prefer de-duplicating diagnostic emission so each unique issue is reported once, then keep the original single-error assertion.
packages/language-service/typescript-plugin/visitors.ts (3)
80-90
: Centralise magic string__VLS_VINE_ComponentsReferenceMap
.The same identifier is handcrafted here and in virtual-code generation. A future rename will break the linkage again – move it to a shared constant (e.g.
src/constants.ts
) and import from both places.
120-130
: Hard-coded__VLS_IntrinsicElements
deserves a shared constant.For the same maintainability reason as above, lift the string into a common constant to avoid accidental divergence.
160-170
: Ditto for__VLS_directives
.Re-use a constant rather than three separate literals introduced in this PR.
packages/compiler/src/index.ts (1)
175-219
: Heavy duplication betweencompileVineTypeScriptFile
&analyzeVineTypeScriptFile
.The new analyse-only path repeats ~80 % of the earlier function. Extract the shared steps (bind ctx, validate, analyse, optional template-compile loop) into an internal helper to keep the surface DRY and easier to evolve.
packages/language-service/src/virtual-code.ts (1)
7-10
: Rename import to avoid shadowing globaltoString
.
import { toString } from 'muggle-string'
shadows the intrinsicObject.prototype.toString
, which can trip up stack-traces and debuggers.-import { toString } from 'muggle-string' +import { toString as muggleToString } from 'muggle-string'and adjust later usages.
packages/compiler/src/template/compose.ts (1)
356-362
:hasTemplateCompileErr
is never writtenThe flag is declared but never set, so the subsequent check is dead code:
let hasTemplateCompileErr = false ... if (hasTemplateCompileErr) { ... }Drop the variable or wire it to the error callback to avoid misleading intent.
packages/language-service/src/codegen.ts (1)
368-376
: In-place sort mutates shared array
macrosInfoForVolar.sort(...)
re-orders the original array held by the compiler context.
If the same array is read elsewhere later the order change may cause subtle bugs.Use a cloned array to keep this function side-effect-free:
- vineCompFn.macrosInfoForVolar - // Sort by AST node start position - .sort(...) + [...vineCompFn.macrosInfoForVolar] + .sort(...)packages/language-service/src/injectTypes.ts (3)
54-60
: Avoid code-duplication: alias to the existing helpers instead of re-copying their bodies
__VLS_VINE_StrictIsAny
and__VLS_VINE_OmitAny
duplicate the full definition already present for__VLS_StrictIsAny
/__VLS_OmitAny
.
Keeping two divergent copies is maintenance-heavy and easy to let drift.-type __VLS_VINE_StrictIsAny<T> = [unknown] extends [T] - ? ([T] extends [unknown] ? true : false) - : false; - -type __VLS_VINE_OmitAny<T> = { - [K in keyof T as __VLS_VINE_StrictIsAny<T[K]> extends true ? never : K]: T[K] -} +type __VLS_VINE_StrictIsAny<T> = __VLS_StrictIsAny<T>; +type __VLS_VINE_OmitAny<T> = __VLS_OmitAny<T>;Same behaviour, one source of truth.
60-64
:__VLS_VINE_CreateVineVLSCtx
is type-only – make that explicitMark the helper with
declare const
(or put it in aninterface
) to avoid accidental value-side emission when the .d.ts is re-used outside the LS.-const __VLS_VINE_CreateVineVLSCtx: <T>(ctx: T) => __VLS_VINE_MakeVLSCtx<import('vue').ShallowUnwrapRef<T>>; +declare const __VLS_VINE_CreateVineVLSCtx: <T>( + ctx: T, +) => __VLS_VINE_MakeVLSCtx<import('vue').ShallowUnwrapRef<T>>;This keeps the helper purely ambient.
68-75
: Nit: helper-type names now exceed 30 chars
__VLS_VINE_RecordToUnion
/__VLS_VINE_UnionToIntersection
push IDE tooltips off-screen.
Consider shortening the prefix (e.g.__VV_
) – they are already unique.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
packages/language-service/tests/__snapshots__/global-types.spec.ts.snap
is excluded by!**/*.snap
packages/language-service/tests/__snapshots__/virtual-code.spec.ts.snap
is excluded by!**/*.snap
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (14)
packages/compiler/src/babel-helpers/ast.ts
(2 hunks)packages/compiler/src/index.ts
(3 hunks)packages/compiler/src/template/compose.ts
(8 hunks)packages/compiler/src/transform/steps.ts
(0 hunks)packages/compiler/tests/validate.spec.ts
(1 hunks)packages/e2e-test/src/fixtures/use-template-ref-virtual-code.vine.ts
(1 hunks)packages/language-service/src/codegen.ts
(1 hunks)packages/language-service/src/injectTypes.ts
(3 hunks)packages/language-service/src/shared.ts
(2 hunks)packages/language-service/src/vine-ctx.ts
(2 hunks)packages/language-service/src/virtual-code.ts
(10 hunks)packages/language-service/typescript-plugin/proxy-ts-lang-service.ts
(1 hunks)packages/language-service/typescript-plugin/visitors.ts
(3 hunks)packages/vite-plugin/package.json
(0 hunks)
💤 Files with no reviewable changes (2)
- packages/vite-plugin/package.json
- packages/compiler/src/transform/steps.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.vine.ts
📄 CodeRabbit Inference Engine (.cursor/rules/vue-vine-repo-rules.mdc)
**/*.vine.ts
: Vine 仅会处理文件名后缀为.vine.ts
的文件
在.vine.ts
文件中,所有函数只要满足条件:“返回值是一个 tagged template string 且标签名必须是vine
的字符串”,都将被视为一个组件函数
Files:
packages/e2e-test/src/fixtures/use-template-ref-virtual-code.vine.ts
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-20T18:38:22.094Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有函数只要满足条件:“返回值是一个 tagged template string 且标签名必须是 `vine` 的字符串”,都将被视为一个组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-20T18:38:22.094Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
📚 Learning: 2025-07-20T18:38:22.094Z
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-20T18:38:22.094Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有函数只要满足条件:“返回值是一个 tagged template string 且标签名必须是 `vine` 的字符串”,都将被视为一个组件函数
Applied to files:
packages/e2e-test/src/fixtures/use-template-ref-virtual-code.vine.ts
packages/language-service/typescript-plugin/proxy-ts-lang-service.ts
packages/language-service/src/vine-ctx.ts
packages/language-service/typescript-plugin/visitors.ts
packages/compiler/src/index.ts
packages/language-service/src/shared.ts
packages/compiler/tests/validate.spec.ts
packages/language-service/src/virtual-code.ts
packages/compiler/src/babel-helpers/ast.ts
packages/compiler/src/template/compose.ts
packages/language-service/src/injectTypes.ts
packages/language-service/src/codegen.ts
📚 Learning: 2025-07-20T18:38:22.094Z
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-20T18:38:22.094Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
Applied to files:
packages/language-service/typescript-plugin/proxy-ts-lang-service.ts
packages/language-service/src/vine-ctx.ts
packages/language-service/typescript-plugin/visitors.ts
packages/compiler/src/index.ts
packages/language-service/src/shared.ts
packages/compiler/tests/validate.spec.ts
packages/language-service/src/virtual-code.ts
packages/compiler/src/babel-helpers/ast.ts
packages/compiler/src/template/compose.ts
packages/language-service/src/injectTypes.ts
📚 Learning: 2025-06-17T14:54:18.385Z
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Applied to files:
packages/language-service/src/vine-ctx.ts
packages/language-service/typescript-plugin/visitors.ts
packages/compiler/src/index.ts
packages/language-service/src/shared.ts
packages/language-service/src/virtual-code.ts
packages/compiler/src/babel-helpers/ast.ts
packages/compiler/src/template/compose.ts
packages/language-service/src/injectTypes.ts
packages/language-service/src/codegen.ts
📚 Learning: 2025-05-26T13:09:15.829Z
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Applied to files:
packages/language-service/src/vine-ctx.ts
packages/language-service/typescript-plugin/visitors.ts
packages/compiler/src/index.ts
packages/language-service/src/shared.ts
packages/compiler/tests/validate.spec.ts
packages/language-service/src/virtual-code.ts
packages/compiler/src/babel-helpers/ast.ts
packages/compiler/src/template/compose.ts
packages/language-service/src/injectTypes.ts
packages/language-service/src/codegen.ts
🧬 Code Graph Analysis (4)
packages/language-service/src/vine-ctx.ts (1)
packages/compiler/src/index.ts (1)
analyzeVineTypeScriptFile
(183-219)
packages/compiler/src/index.ts (3)
packages/compiler/src/types.ts (2)
VineCompileCtx
(290-294)VineFileCtx
(152-187)packages/compiler/src/babel-helpers/ast.ts (1)
findVineCompFnDecls
(99-107)packages/compiler/src/template/compose.ts (2)
createTemplateCompileOptions
(237-273)compileVineTemplate
(275-339)
packages/language-service/src/shared.ts (1)
packages/language-service/src/vine-ctx.ts (1)
analyzeVineForVirtualCode
(7-56)
packages/language-service/src/codegen.ts (3)
packages/language-service/src/shared.ts (7)
BabelFunctionNodeTypes
(11-11)BabelToken
(13-19)VineCodeInformation
(8-8)VineCompFn
(10-10)parseCssClassNames
(101-118)wrapWith
(120-139)turnBackToCRLF
(37-39)packages/compiler/src/index.ts (5)
VineFileCtx
(44-44)VinePropsDefinitionBy
(35-35)VinePropMeta
(47-47)_breakableTraverse
(52-52)exitTraverse
(53-53)packages/language-service/src/injectTypes.ts (1)
createLinkedCodeTag
(90-95)
🪛 ast-grep (0.38.6)
packages/language-service/src/virtual-code.ts
[warning] 13-13: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(${escapeStrForRegExp(LINKED_CODE_TAG_PREFIX)}_LEFT__#(?<itemLength>\\d+)${escapeStrForRegExp(LINKED_CODE_TAG_SUFFIX)}
, 'g')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
🪛 Biome (2.1.2)
packages/language-service/src/virtual-code.ts
[error] 9-9: Do not shadow the global "toString" property.
Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.
(lint/suspicious/noShadowRestrictedNames)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: test (lts/*, macos-latest)
- GitHub Check: test (lts/*, windows-latest)
- GitHub Check: test (lts/*, ubuntu-latest)
🔇 Additional comments (7)
packages/e2e-test/src/fixtures/use-template-ref-virtual-code.vine.ts (1)
7-10
: ImportonMounted
or confirm global availability
onMounted
is referenced but not imported. Unless the Vine runtime auto-globals lifecycle APIs for.vine.ts
files, this will raise a TypeScript “cannot find name” error and break editor IntelliSense.-import { useTemplateRef } from 'vue' +import { useTemplateRef, onMounted } from 'vue'Please verify that automatic injection really covers this case; otherwise add the explicit import.
packages/language-service/src/vine-ctx.ts (1)
3-4
: Rename integration looks goodImport switched to
analyzeVineTypeScriptFile
; matches the new compiler API and compiles cleanly.packages/language-service/src/shared.ts (2)
28-30
: No references tocompileTime
remain
A repository‐wide search for.compileTime
returned no matches—there are no lingering accesses to the removed getter.
6-10
: Downstream usage verified
Search for the oldcompileVineForVirtualCode
alias returned no matches, confirming all consumers now useVineCompFn
(viaanalyzeVineForVirtualCode
). No further changes needed.packages/language-service/src/virtual-code.ts (1)
14-15
: Variable-driven RegExp – verify ReDoS safety.Although segments are escaped, confirm that
LINKED_CODE_TAG_PREFIX|SUFFIX
are constant and cannot originate from untrusted input to rule out ReDoS vectors.packages/language-service/src/codegen.ts (1)
28-65
:getIndexOfFnDeclLeftParen
misses some edge casesFor arrow functions without parentheses (e.g.
x => {}
) the helper returnsnode.start
, which is before the parameter list, causing later insertions to land in the wrong spot.Consider falling back to
node.params[0].start
when(
is absent.packages/language-service/src/injectTypes.ts (1)
144-167
: No stale helper references remainA search across the codebase for
__VLS_CreateVineVLSCtx
and__VLS_OmitAny
returned no matches, confirming that all old helper names have been removed and replaced with the new ones.
What's changed
Summary by CodeRabbit
New Features
Refactor
Bug Fixes
Chores
Style