├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ └── feature_request.yml └── workflows │ ├── auto-fix.yml │ ├── close-cannot-repoduce-issues.yml │ ├── extension-build.yml │ ├── extension-release.yml │ ├── pkg.pr.new.yml │ ├── test.yml │ └── update-html-data.yml ├── .gitignore ├── .npmrc ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── extensions └── vscode │ ├── .vscodeignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── images │ ├── icon.png │ └── split-editors.png │ ├── languages │ ├── markdown-language-configuration.json │ ├── sfc-template-language-configuration.json │ └── vue-language-configuration.json │ ├── package.json │ ├── package.nls.ja.json │ ├── package.nls.json │ ├── package.nls.ru.json │ ├── package.nls.zh-CN.json │ ├── package.nls.zh-TW.json │ ├── rolldown.config.ts │ ├── src │ ├── config.ts │ ├── features │ │ ├── nameCasing.ts │ │ └── splitEditors.ts │ ├── hybridMode.ts │ ├── insiders.ts │ ├── languageClient.ts │ ├── middleware.ts │ └── nodeClientMain.ts │ ├── syntaxes │ ├── markdown-vue.json │ ├── mdx-vue.json │ ├── vue-directives.json │ ├── vue-interpolations.json │ ├── vue-sfc-style-variable-injection.json │ └── vue.tmLanguage.json │ ├── tests │ ├── __snapshots__ │ │ └── grammar.spec.ts.snap │ ├── grammar.spec.ts │ ├── grammarFixtures │ │ ├── basic.vue │ │ ├── directives.vue │ │ ├── generic.vue │ │ ├── inline-style.vue │ │ ├── jsx.vue │ │ ├── namespaced.vue │ │ ├── script-tag-in-script.vue │ │ ├── snippet-import.md │ │ ├── template-expression.vue │ │ └── template-in-template.vue │ └── index.spec.ts │ ├── tsconfig.json │ └── web.js ├── insiders.json ├── lerna.json ├── package.json ├── packages ├── component-meta │ ├── LICENSE │ ├── README.md │ ├── index.ts │ ├── lib │ │ ├── base.ts │ │ └── types.ts │ ├── package.json │ ├── tests │ │ └── index.spec.ts │ └── tsconfig.json ├── component-type-helpers │ ├── LICENSE │ ├── README.md │ ├── index.ts │ ├── package.json │ └── tsconfig.json ├── language-core │ ├── LICENSE │ ├── index.ts │ ├── lib │ │ ├── codegen │ │ │ ├── codeFeatures.ts │ │ │ ├── globalTypes.ts │ │ │ ├── inlayHints.ts │ │ │ ├── localTypes.ts │ │ │ ├── script │ │ │ │ ├── component.ts │ │ │ │ ├── componentSelf.ts │ │ │ │ ├── context.ts │ │ │ │ ├── index.ts │ │ │ │ ├── scriptSetup.ts │ │ │ │ ├── src.ts │ │ │ │ └── template.ts │ │ │ ├── style │ │ │ │ ├── classProperty.ts │ │ │ │ ├── modules.ts │ │ │ │ └── scopedClasses.ts │ │ │ ├── template │ │ │ │ ├── context.ts │ │ │ │ ├── element.ts │ │ │ │ ├── elementChildren.ts │ │ │ │ ├── elementDirectives.ts │ │ │ │ ├── elementEvents.ts │ │ │ │ ├── elementProps.ts │ │ │ │ ├── index.ts │ │ │ │ ├── interpolation.ts │ │ │ │ ├── objectProperty.ts │ │ │ │ ├── propertyAccess.ts │ │ │ │ ├── slotOutlet.ts │ │ │ │ ├── styleScopedClasses.ts │ │ │ │ ├── templateChild.ts │ │ │ │ ├── vFor.ts │ │ │ │ ├── vIf.ts │ │ │ │ └── vSlot.ts │ │ │ └── utils │ │ │ │ ├── camelized.ts │ │ │ │ ├── escaped.ts │ │ │ │ ├── index.ts │ │ │ │ ├── stringLiteralKey.ts │ │ │ │ ├── unicode.ts │ │ │ │ └── wrapWith.ts │ │ ├── languagePlugin.ts │ │ ├── parsers │ │ │ ├── scriptRanges.ts │ │ │ ├── scriptSetupRanges.ts │ │ │ └── vueCompilerOptions.ts │ │ ├── plugins.ts │ │ ├── plugins │ │ │ ├── file-html.ts │ │ │ ├── file-md.ts │ │ │ ├── file-vue.ts │ │ │ ├── shared.ts │ │ │ ├── vue-root-tags.ts │ │ │ ├── vue-script-js.ts │ │ │ ├── vue-sfc-customblocks.ts │ │ │ ├── vue-sfc-scripts.ts │ │ │ ├── vue-sfc-styles.ts │ │ │ ├── vue-sfc-template.ts │ │ │ ├── vue-template-html.ts │ │ │ ├── vue-template-inline-css.ts │ │ │ ├── vue-template-inline-ts.ts │ │ │ └── vue-tsx.ts │ │ ├── types.ts │ │ ├── utils │ │ │ ├── buildMappings.ts │ │ │ ├── parseCssClassNames.ts │ │ │ ├── parseCssVars.ts │ │ │ ├── parseSfc.ts │ │ │ ├── shared.ts │ │ │ ├── signals.ts │ │ │ └── ts.ts │ │ └── virtualFile │ │ │ ├── computedEmbeddedCodes.ts │ │ │ ├── computedSfc.ts │ │ │ ├── computedVueSfc.ts │ │ │ ├── embeddedFile.ts │ │ │ └── vueFile.ts │ ├── package.json │ ├── schemas │ │ └── vue-tsconfig.schema.json │ └── tsconfig.json ├── language-plugin-pug │ ├── LICENSE │ ├── README.md │ ├── index.ts │ ├── package.json │ └── tsconfig.json ├── language-server │ ├── LICENSE │ ├── bin │ │ └── vue-language-server.js │ ├── index.ts │ ├── lib │ │ └── types.ts │ ├── node.ts │ ├── package.json │ ├── protocol.ts │ ├── tests │ │ ├── completions.spec.ts │ │ ├── definitions.spec.ts │ │ ├── inlayHints.spec.ts │ │ ├── references.spec.ts │ │ ├── renaming.spec.ts │ │ └── server.ts │ └── tsconfig.json ├── language-service │ ├── LICENSE │ ├── data │ │ ├── language-blocks │ │ │ ├── cs.json │ │ │ ├── en.json │ │ │ ├── fr.json │ │ │ ├── it.json │ │ │ ├── ja.json │ │ │ ├── ko.json │ │ │ ├── pt.json │ │ │ ├── ru.json │ │ │ ├── zh-cn.json │ │ │ └── zh-hk.json │ │ ├── locale.json │ │ ├── model-modifiers │ │ │ ├── cs.json │ │ │ ├── en.json │ │ │ ├── fr.json │ │ │ ├── it.json │ │ │ ├── ja.json │ │ │ ├── ko.json │ │ │ ├── pt.json │ │ │ ├── ru.json │ │ │ ├── zh-cn.json │ │ │ └── zh-hk.json │ │ └── template │ │ │ ├── cs.json │ │ │ ├── en.json │ │ │ ├── fr.json │ │ │ ├── it.json │ │ │ ├── ja.json │ │ │ ├── ko.json │ │ │ ├── pt.json │ │ │ ├── ru.json │ │ │ ├── zh-cn.json │ │ │ └── zh-hk.json │ ├── index.ts │ ├── lib │ │ ├── nameCasing.ts │ │ ├── plugins │ │ │ ├── css.ts │ │ │ ├── data.ts │ │ │ ├── utils.ts │ │ │ ├── vue-autoinsert-dotvalue.ts │ │ │ ├── vue-autoinsert-space.ts │ │ │ ├── vue-compiler-dom-errors.ts │ │ │ ├── vue-complete-define-assignment.ts │ │ │ ├── vue-directive-comments.ts │ │ │ ├── vue-document-drop.ts │ │ │ ├── vue-document-highlights.ts │ │ │ ├── vue-document-links.ts │ │ │ ├── vue-extract-file.ts │ │ │ ├── vue-inlayhints.ts │ │ │ ├── vue-missing-props-hints.ts │ │ │ ├── vue-sfc.ts │ │ │ ├── vue-template.ts │ │ │ └── vue-twoslash-queries.ts │ │ └── types.ts │ ├── package.json │ ├── scripts │ │ └── update-html-data.js │ ├── tests │ │ ├── format │ │ │ ├── 1210.spec.ts │ │ │ ├── 1398.spec.ts │ │ │ ├── 1806.spec.ts │ │ │ ├── 1823.spec.ts │ │ │ ├── 2026.spec.ts │ │ │ ├── 2105.spec.ts │ │ │ ├── 2305.spec.ts │ │ │ ├── 2350.spec.ts │ │ │ ├── 2385.spec.ts │ │ │ ├── 2390.spec.ts │ │ │ ├── 2393.spec.ts │ │ │ ├── 2480.spec.ts │ │ │ ├── 2505.spec.ts │ │ │ ├── 2507.spec.ts │ │ │ ├── 2519.spec.ts │ │ │ ├── 2520.spec.ts │ │ │ ├── 2571.spec.ts │ │ │ ├── 2750.spec.ts │ │ │ ├── 3101.spec.ts │ │ │ ├── 3572.spec.ts │ │ │ ├── 3943.spec.ts │ │ │ ├── 3949.spec.ts │ │ │ ├── 3987.spec.ts │ │ │ ├── 4333.spec.ts │ │ │ ├── deep-interpolation-indent.spec.ts │ │ │ ├── js-template-strings.spec.ts │ │ │ ├── multiple-interpolations-indent.spec.ts │ │ │ ├── mutilple-lines-html-comment.spec.ts │ │ │ └── mutilple-lines-interpolation.spec.ts │ │ └── utils │ │ │ └── format.ts │ └── tsconfig.json ├── tsc │ ├── LICENSE │ ├── README.md │ ├── bin │ │ └── vue-tsc.js │ ├── index.ts │ ├── package.json │ ├── tests │ │ ├── __snapshots__ │ │ │ └── dts.spec.ts.snap │ │ ├── dts.spec.ts │ │ └── typecheck.spec.ts │ └── tsconfig.json └── typescript-plugin │ ├── LICENSE │ ├── README.md │ ├── index.ts │ ├── lib │ ├── common.ts │ └── requests │ │ ├── collectExtractProps.ts │ │ ├── getComponentDirectives.ts │ │ ├── getComponentEvents.ts │ │ ├── getComponentNames.ts │ │ ├── getComponentProps.ts │ │ ├── getElementAttrs.ts │ │ ├── getElementNames.ts │ │ ├── getImportPathForFile.ts │ │ ├── getPropertiesAtLocation.ts │ │ ├── index.ts │ │ ├── types.ts │ │ └── utils.ts │ ├── package.json │ └── tsconfig.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── test-workspace ├── component-meta │ ├── #4577 │ │ └── main.vue │ ├── class-slots │ │ └── component.vue │ ├── empty-component │ │ ├── component.vue │ │ └── custom-extension-component.cext │ ├── events │ │ ├── component-class.vue │ │ └── component-generic.vue │ ├── generic │ │ ├── component.vue │ │ ├── custom-extension-component.cext │ │ └── main.vue │ ├── non-component │ │ └── component.ts │ ├── options-api │ │ └── component.ts │ ├── reference-type-events │ │ ├── component.vue │ │ └── my-events.ts │ ├── reference-type-exposed │ │ └── component.vue │ ├── reference-type-model │ │ └── component.vue │ ├── reference-type-props │ │ ├── component-destructure.vue │ │ ├── component-js-setup.vue │ │ ├── component-js.vue │ │ ├── component.vue │ │ └── my-props.ts │ ├── template-slots │ │ ├── component-define-slots.vue │ │ ├── component-destructuring.vue │ │ ├── component-no-script.vue │ │ └── component.vue │ ├── ts-component │ │ ├── PropDefinitions.ts │ │ ├── component.ts │ │ └── component.tsx │ ├── ts-named-export │ │ └── component.ts │ └── tsconfig.json ├── package.json ├── tsc │ ├── failureFixtures │ │ ├── #3632 │ │ │ ├── both.vue │ │ │ ├── script.vue │ │ │ ├── scriptSetup.vue │ │ │ └── tsconfig.json │ │ ├── #4569 │ │ │ ├── main.vue │ │ │ └── tsconfig.json │ │ ├── #5071 │ │ │ ├── tsconfig.json │ │ │ ├── withScript.vue │ │ │ └── withoutScript.vue │ │ └── directives │ │ │ ├── main.vue │ │ │ └── tsconfig.json │ ├── passedFixtures │ │ ├── #1886 │ │ │ ├── main.vue │ │ │ └── tsconfig.json │ │ ├── #2157 │ │ │ ├── main.vue │ │ │ └── tsconfig.json │ │ ├── #2472 │ │ │ ├── child.vue │ │ │ ├── env.d.ts │ │ │ ├── generic.vue │ │ │ ├── main.vue │ │ │ └── tsconfig.json │ │ ├── #3373 │ │ │ ├── NavBar.vue │ │ │ ├── main.vue │ │ │ └── tsconfig.json │ │ ├── #3574 │ │ │ ├── child.vue │ │ │ ├── main.vue │ │ │ └── tsconfig.json │ │ ├── #3592 │ │ │ ├── main.vue │ │ │ └── tsconfig.json │ │ ├── #3819 │ │ │ ├── component.vue │ │ │ ├── main.vue │ │ │ └── tsconfig.json │ │ ├── #4503 │ │ │ ├── globalcomp.vue │ │ │ ├── globals.d.ts │ │ │ ├── main.vue │ │ │ └── tsconfig.json │ │ ├── #5106 │ │ │ ├── main.vue │ │ │ └── tsconfig.json │ │ ├── #5111 │ │ │ ├── main.vue │ │ │ └── tsconfig.json │ │ ├── #5338 │ │ │ ├── main.vue │ │ │ └── tsconfig.json │ │ ├── core#9923 │ │ │ ├── comp.vue │ │ │ ├── main.vue │ │ │ └── tsconfig.json │ │ ├── fallthroughAttributes │ │ │ ├── tsconfig.json │ │ │ └── unknownTag │ │ │ │ ├── basic.vue │ │ │ │ └── main.vue │ │ ├── fallthroughAttributes_strictTemplate │ │ │ ├── #4699 │ │ │ │ ├── HelloWorld.vue │ │ │ │ └── main.vue │ │ │ ├── base │ │ │ │ ├── basic.vue │ │ │ │ ├── child.vue │ │ │ │ ├── define-options-inherit-attrs-false.vue │ │ │ │ ├── inherit-attrs-false-v-bind.vue │ │ │ │ ├── inherit-attrs-false.vue │ │ │ │ └── main.vue │ │ │ ├── duplicateNameEvent │ │ │ │ ├── basic.vue │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── duplicateNameProp │ │ │ │ ├── basic.vue │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── generic │ │ │ │ ├── basic.vue │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── requiredProp │ │ │ │ ├── basic.vue │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── tsconfig.json │ │ │ └── unknownTag │ │ │ │ ├── basic.vue │ │ │ │ └── main.vue │ │ ├── noPropertyAccessFromIndexSignature │ │ │ ├── #2236 │ │ │ │ └── main.vue │ │ │ ├── #3106 │ │ │ │ └── main.vue │ │ │ └── tsconfig.json │ │ ├── petite-vue │ │ │ └── main.html │ │ ├── pug │ │ │ ├── #4774.vue │ │ │ ├── #5099.vue │ │ │ ├── main.vue │ │ │ └── tsconfig.json │ │ ├── shared.d.ts │ │ ├── vue3.4 │ │ │ ├── components │ │ │ │ ├── main.vue │ │ │ │ ├── script-setup-default-props.vue │ │ │ │ ├── script-setup-expose.vue │ │ │ │ ├── script-setup-generic.vue │ │ │ │ ├── script-setup-type-only.vue │ │ │ │ └── script-setup.vue │ │ │ ├── defineModel │ │ │ │ ├── main.vue │ │ │ │ └── script-setup.vue │ │ │ ├── defineProp_B │ │ │ │ ├── main.vue │ │ │ │ ├── script-setup-generic.vue │ │ │ │ └── script-setup.vue │ │ │ ├── env.d.ts │ │ │ └── tsconfig.json │ │ ├── vue3.4_strictTemplate │ │ │ ├── #3718 │ │ │ │ └── main.vue │ │ │ └── tsconfig.json │ │ ├── vue3 │ │ │ ├── #1855 │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── #2048 │ │ │ │ ├── components.ts │ │ │ │ └── main.vue │ │ │ ├── #2166 │ │ │ │ └── main.vue │ │ │ ├── #2206 │ │ │ │ └── main.vue │ │ │ ├── #2225 │ │ │ │ └── main.vue │ │ │ ├── #2250 │ │ │ │ └── main.vue │ │ │ ├── #2308 │ │ │ │ └── main.vue │ │ │ ├── #2370 │ │ │ │ └── main.vue │ │ │ ├── #2399 │ │ │ │ └── main.vue │ │ │ ├── #2431 │ │ │ │ └── main.vue │ │ │ ├── #2468 │ │ │ │ └── main.vue │ │ │ ├── #2514 │ │ │ │ └── main.vue │ │ │ ├── #2554 │ │ │ │ └── main.vue │ │ │ ├── #2586 │ │ │ │ └── main.vue │ │ │ ├── #2588 │ │ │ │ └── main.vue │ │ │ ├── #2590 │ │ │ │ └── foo.vue │ │ │ ├── #2617 │ │ │ │ └── main.vue │ │ │ ├── #2629 │ │ │ │ └── main.vue │ │ │ ├── #2638 │ │ │ │ └── main.vue │ │ │ ├── #2639 │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── #2640 │ │ │ │ └── main.vue │ │ │ ├── #2646 │ │ │ │ └── main.vue │ │ │ ├── #2647 │ │ │ │ └── main.vue │ │ │ ├── #2678 │ │ │ │ └── main.vue │ │ │ ├── #2683 │ │ │ │ └── main.vue │ │ │ ├── #2691 │ │ │ │ └── main.vue │ │ │ ├── #2700 │ │ │ │ └── main.vue │ │ │ ├── #2709 │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── #2712 │ │ │ │ └── main.vue │ │ │ ├── #2720 │ │ │ │ └── main.vue │ │ │ ├── #2725 │ │ │ │ └── main.vue │ │ │ ├── #2730 │ │ │ │ └── main.vue │ │ │ ├── #2744 │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── #2754 │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── #2758 │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── #3100 │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── #3102 │ │ │ │ └── main.vue │ │ │ ├── #3109 │ │ │ │ └── main.vue │ │ │ ├── #3117 │ │ │ │ └── main.vue │ │ │ ├── #3121 │ │ │ │ └── main.vue │ │ │ ├── #3122 │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── #3123 │ │ │ │ └── main.vue │ │ │ ├── #3129 │ │ │ │ └── main.vue │ │ │ ├── #3138 │ │ │ │ └── main.vue │ │ │ ├── #3164 │ │ │ │ └── main.vue │ │ │ ├── #3171 │ │ │ │ └── main.vue │ │ │ ├── #3204 │ │ │ │ └── main.vue │ │ │ ├── #3255 │ │ │ │ └── main.vue │ │ │ ├── #3257 │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── #3258 │ │ │ │ ├── main.vue │ │ │ │ └── main2.vue │ │ │ ├── #3289 │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── #329 │ │ │ │ └── main.vue │ │ │ ├── #3295 │ │ │ │ └── main.vue │ │ │ ├── #3311 │ │ │ │ ├── component.vue │ │ │ │ └── main.vue │ │ │ ├── #3318 │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── #3327 │ │ │ │ ├── main.vue │ │ │ │ └── main2.vue │ │ │ ├── #3340 │ │ │ │ ├── FooBar.ts │ │ │ │ └── main.vue │ │ │ ├── #3353 │ │ │ │ └── main.vue │ │ │ ├── #3371 │ │ │ │ └── main.vue │ │ │ ├── #3374 │ │ │ │ ├── component.vue │ │ │ │ └── main.vue │ │ │ ├── #3379 │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── #3405 │ │ │ │ └── main.vue │ │ │ ├── #3414 │ │ │ │ └── main.vue │ │ │ ├── #3433 │ │ │ │ └── main.vue │ │ │ ├── #3440 │ │ │ │ └── main.vue │ │ │ ├── #3476 │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── #3488 │ │ │ │ └── main.vue │ │ │ ├── #3518 │ │ │ │ └── main.vue │ │ │ ├── #3548 │ │ │ │ └── main.vue │ │ │ ├── #3561 │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── #3612 │ │ │ │ └── main.vue │ │ │ ├── #3615 │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── #3629 │ │ │ │ └── main.vue │ │ │ ├── #3637 │ │ │ │ └── main.vue │ │ │ ├── #3643 │ │ │ │ └── main.vue │ │ │ ├── #3656 │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── #3671 │ │ │ │ └── main.vue │ │ │ ├── #3672 │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── #3688 │ │ │ │ └── main.vue │ │ │ ├── #3718 │ │ │ │ └── main.vue │ │ │ ├── #3732 │ │ │ │ ├── child.vue │ │ │ │ ├── child2.vue │ │ │ │ └── main.ts │ │ │ ├── #3756 │ │ │ │ └── main.vue │ │ │ ├── #3779 │ │ │ │ ├── main.vue │ │ │ │ └── named.vue │ │ │ ├── #3782 │ │ │ │ └── main.vue │ │ │ ├── #3820 │ │ │ │ └── main.vue │ │ │ ├── #3845 │ │ │ │ └── main.vue │ │ │ ├── #3997 │ │ │ │ └── main.vue │ │ │ ├── #4050 │ │ │ │ └── main.vue │ │ │ ├── #4209 │ │ │ │ └── main.vue │ │ │ ├── #4263 │ │ │ │ └── main.vue │ │ │ ├── #4326 │ │ │ │ └── main.vue │ │ │ ├── #4327 │ │ │ │ └── main.vue │ │ │ ├── #4333 │ │ │ │ └── main.vue │ │ │ ├── #4353 │ │ │ │ └── main.vue │ │ │ ├── #4361 │ │ │ │ └── main.vue │ │ │ ├── #4369 │ │ │ │ └── main.vue │ │ │ ├── #4386 │ │ │ │ ├── component.vue │ │ │ │ └── main.vue │ │ │ ├── #4387 │ │ │ │ ├── comment-2113645943.vue │ │ │ │ ├── component.vue │ │ │ │ └── main.vue │ │ │ ├── #4391 │ │ │ │ ├── comp.vue │ │ │ │ └── main.vue │ │ │ ├── #4413 │ │ │ │ └── main.vue │ │ │ ├── #4433 │ │ │ │ └── main.vue │ │ │ ├── #4512 │ │ │ │ ├── main.vue │ │ │ │ ├── test1.vue │ │ │ │ ├── test2.vue │ │ │ │ └── test3.vue │ │ │ ├── #4537 │ │ │ │ └── main.vue │ │ │ ├── #4540 │ │ │ │ ├── component.vue │ │ │ │ └── main.vue │ │ │ ├── #4600 │ │ │ │ └── main.vue │ │ │ ├── #4604 │ │ │ │ └── main.vue │ │ │ ├── #4646 │ │ │ │ ├── child.vue │ │ │ │ ├── child2.vue │ │ │ │ └── parent.vue │ │ │ ├── #4649 │ │ │ │ ├── main.vue │ │ │ │ ├── model-comp.vue │ │ │ │ └── prop-comp.vue │ │ │ ├── #4668 │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── #4682 │ │ │ │ └── main.vue │ │ │ ├── #4785 │ │ │ │ ├── generic.vue │ │ │ │ └── main.vue │ │ │ ├── #4799 │ │ │ │ └── main.vue │ │ │ ├── #4820 │ │ │ │ └── main.vue │ │ │ ├── #4822 │ │ │ │ ├── comp.vue │ │ │ │ └── main.vue │ │ │ ├── #4826 │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── #4827 │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── #4828 │ │ │ │ └── main.vue │ │ │ ├── #4862 │ │ │ │ └── main.vue │ │ │ ├── #4878 │ │ │ │ └── main.vue │ │ │ ├── #4890 │ │ │ │ └── main.vue │ │ │ ├── #4899 │ │ │ │ └── main.vue │ │ │ ├── #4978 │ │ │ │ ├── comp.vue │ │ │ │ └── main.vue │ │ │ ├── #4979 │ │ │ │ └── main.vue │ │ │ ├── #5027 │ │ │ │ └── main.vue │ │ │ ├── #5097 │ │ │ │ ├── child.ts │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── #5157 │ │ │ │ └── main.vue │ │ │ ├── #5207 │ │ │ │ └── main.vue │ │ │ ├── #5228 │ │ │ │ └── main.vue │ │ │ ├── #5262 │ │ │ │ ├── comp.vue │ │ │ │ └── main.vue │ │ │ ├── #5267 │ │ │ │ └── main.vue │ │ │ ├── #625 │ │ │ │ └── main.vue │ │ │ ├── attrs │ │ │ │ └── main.vue │ │ │ ├── components │ │ │ │ ├── main.vue │ │ │ │ ├── script-setup-default-props.vue │ │ │ │ ├── script-setup-expose.vue │ │ │ │ ├── script-setup-generic.vue │ │ │ │ ├── script-setup-type-only.vue │ │ │ │ └── script-setup.vue │ │ │ ├── cssModule │ │ │ │ ├── empty.vue │ │ │ │ └── main.vue │ │ │ ├── defineEmits │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── defineExpose │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── defineModel │ │ │ │ ├── main.vue │ │ │ │ └── script-setup.vue │ │ │ ├── defineModelModifiers │ │ │ │ ├── comp.vue │ │ │ │ └── main.vue │ │ │ ├── defineOptions │ │ │ │ └── child.vue │ │ │ ├── defineProp_A │ │ │ │ └── script-setup.vue │ │ │ ├── defineProp_B │ │ │ │ ├── main.vue │ │ │ │ ├── script-setup-generic.vue │ │ │ │ └── script-setup.vue │ │ │ ├── directiveComments │ │ │ │ └── main.vue │ │ │ ├── directives │ │ │ │ ├── arg-modifiers.vue │ │ │ │ ├── main.vue │ │ │ │ └── option.vue │ │ │ ├── dynamic-component │ │ │ │ └── main.vue │ │ │ ├── events │ │ │ │ ├── main.vue │ │ │ │ └── union_type.vue │ │ │ ├── input-radio │ │ │ │ └── main.vue │ │ │ ├── namespace-component │ │ │ │ └── main.vue │ │ │ ├── no-script-block │ │ │ │ └── main.vue │ │ │ ├── reference-type-in-template │ │ │ │ └── main.vue │ │ │ ├── rootEl │ │ │ │ ├── base.vue │ │ │ │ ├── child.vue │ │ │ │ └── main.vue │ │ │ ├── script-setup-scope │ │ │ │ ├── export-order.vue │ │ │ │ └── main.vue │ │ │ ├── slots │ │ │ │ └── main.vue │ │ │ ├── templateRef │ │ │ │ ├── generic.vue │ │ │ │ ├── main.vue │ │ │ │ ├── missing-import.vue │ │ │ │ └── template-refs.vue │ │ │ ├── tsconfig.json │ │ │ ├── type-helpers │ │ │ │ └── main.vue │ │ │ ├── unknownProp │ │ │ │ └── main.vue │ │ │ ├── v-bind-require-object │ │ │ │ └── main.vue │ │ │ ├── v-bind-shorthand │ │ │ │ ├── child.vue │ │ │ │ └── entry.vue │ │ │ ├── v-for │ │ │ │ ├── generic.vue │ │ │ │ └── main.vue │ │ │ ├── v-generic │ │ │ │ ├── comp.vue │ │ │ │ └── main.vue │ │ │ ├── v-if │ │ │ │ └── main.vue │ │ │ └── withDefaults │ │ │ │ └── main.vue │ │ └── vue3_strictTemplate │ │ │ ├── #2726 │ │ │ └── main.vue │ │ │ ├── #3140 │ │ │ ├── Focus.ts │ │ │ └── main.vue │ │ │ ├── #3152 │ │ │ ├── MyInput.vue │ │ │ └── main.vue │ │ │ ├── #3539 │ │ │ └── main.vue │ │ │ ├── #5067 │ │ │ ├── comp.vue │ │ │ └── main.vue │ │ │ ├── dataAttributes │ │ │ └── main.vue │ │ │ ├── defineModel │ │ │ ├── comp.vue │ │ │ └── main.vue │ │ │ ├── intrinsicProps │ │ │ └── main.vue │ │ │ ├── slot-children │ │ │ ├── child.vue │ │ │ ├── main.vue │ │ │ └── parent.vue │ │ │ ├── tsconfig.json │ │ │ └── unknownProp │ │ │ └── main.vue │ └── tsconfig.json ├── tsconfig.base.json └── tsconfigProject │ ├── empty.vue │ ├── fixture.vue │ └── tsconfig.json ├── tsconfig.base.json ├── tsconfig.json ├── tsslint.config.ts └── vitest.config.ts /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: johnsoncodehk 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Questions & Discussions 4 | url: https://github.com/vuejs/language-tools/discussions 5 | about: Use GitHub discussions for message-board style questions and discussions. 6 | -------------------------------------------------------------------------------- /.github/workflows/auto-fix.yml: -------------------------------------------------------------------------------- 1 | name: auto-fix 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | 11 | permissions: 12 | contents: write 13 | 14 | jobs: 15 | auto-fix: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v4 19 | 20 | - uses: pnpm/action-setup@v4 21 | 22 | - uses: actions/setup-node@v4 23 | with: 24 | node-version: 20 25 | cache: pnpm 26 | 27 | - run: pnpm install 28 | 29 | # lint 30 | - name: Auto-fix 31 | run: pnpm run lint:fix 32 | 33 | # commit 34 | - name: Commit 35 | uses: EndBug/add-and-commit@v9 36 | with: 37 | message: "ci(lint): auto-fix" 38 | default_author: github_actions 39 | env: 40 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 41 | -------------------------------------------------------------------------------- /.github/workflows/close-cannot-repoduce-issues.yml: -------------------------------------------------------------------------------- 1 | name: Auto close issues with "can't reproduce" label 2 | 3 | on: 4 | schedule: 5 | - cron: '0 0 * * *' 6 | 7 | permissions: 8 | issues: write 9 | 10 | jobs: 11 | close-issues: 12 | if: github.repository == 'vuejs/language-tools' 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: can't reproduce 16 | uses: actions-cool/issues-helper@v3 17 | with: 18 | actions: close-issues 19 | token: ${{ secrets.GITHUB_TOKEN }} 20 | labels: "can't reproduce" 21 | inactive-day: 3 22 | -------------------------------------------------------------------------------- /.github/workflows/extension-build.yml: -------------------------------------------------------------------------------- 1 | name: extension 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'master' 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | 14 | - uses: pnpm/action-setup@v4 15 | 16 | - uses: actions/setup-node@v4 17 | with: 18 | node-version: 20 19 | cache: pnpm 20 | 21 | - name: Install dependencies 22 | run: pnpm install 23 | 24 | - name: Build 25 | run: pnpm run build && pnpm --filter volar run pack 26 | 27 | - name: Upload Artifact 28 | uses: actions/upload-artifact@v4 29 | with: 30 | name: extensions 31 | path: ./extensions/vscode/volar-*.vsix 32 | -------------------------------------------------------------------------------- /.github/workflows/pkg.pr.new.yml: -------------------------------------------------------------------------------- 1 | name: publish-any-commit 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v4 11 | 12 | - uses: pnpm/action-setup@v4 13 | 14 | - uses: actions/setup-node@v4 15 | with: 16 | node-version: 20 17 | cache: pnpm 18 | 19 | - name: Install dependencies 20 | run: pnpm install 21 | 22 | - name: Build 23 | run: pnpm build 24 | 25 | - run: pnpx pkg-pr-new publish './packages/*' 26 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ${{ matrix.os }} 8 | 9 | strategy: 10 | matrix: 11 | node-version: [18] 12 | os: [macos-latest, windows-latest, ubuntu-latest] 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | 17 | - uses: pnpm/action-setup@v4 18 | 19 | - name: Use Node.js ${{ matrix.node-version }} 20 | uses: actions/setup-node@v4 21 | with: 22 | node-version: ${{ matrix.node-version }} 23 | cache: pnpm 24 | 25 | - run: pnpm install --frozen-lockfile 26 | - run: pnpm run build 27 | - run: pnpm run test 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | dist 3 | node_modules 4 | *.tsbuildinfo 5 | *.vsix 6 | .vscode-test-web 7 | extensions/*/meta.json 8 | extensions/*/stats.html 9 | extensions/vscode/src/generated-meta.ts 10 | 11 | packages/*/*.d.ts 12 | packages/*/*.js 13 | packages/*/*.map 14 | packages/*/lib/**/*.d.ts 15 | packages/*/lib/**/*.js 16 | packages/*/lib/**/*.map 17 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | link-workspace-packages=true 2 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.format.semicolons": "insert", 3 | "editor.insertSpaces": false, 4 | "editor.detectIndentation": false, 5 | "editor.codeActionsOnSave": { 6 | "source.organizeImports": "always" 7 | }, 8 | "json.format.keepLines": true, 9 | "typescript.tsdk": "node_modules/typescript/lib", 10 | "[typescript]": { 11 | "editor.defaultFormatter": "vscode.typescript-language-features" 12 | }, 13 | "[javascript]": { 14 | "editor.defaultFormatter": "vscode.typescript-language-features" 15 | }, 16 | "[json]": { 17 | "editor.defaultFormatter": "vscode.json-language-features" 18 | }, 19 | "[jsonc]": { 20 | "editor.defaultFormatter": "vscode.json-language-features" 21 | }, 22 | "files.exclude": { 23 | "packages/*/*.d.ts": true, 24 | "packages/*/*.js": true, 25 | "packages/*/*.map": true, 26 | "packages/*/lib/**/*.d.ts": true, 27 | "packages/*/lib/**/*.js": true, 28 | "packages/*/lib/**/*.map": true 29 | } 30 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "type": "npm", 6 | "script": "compile", 7 | "group": "build", 8 | "presentation": { 9 | "panel": "dedicated", 10 | "reveal": "never" 11 | }, 12 | "problemMatcher": [ 13 | "$tsc" 14 | ] 15 | }, 16 | { 17 | "type": "npm", 18 | "script": "watch", 19 | "isBackground": true, 20 | "group": { 21 | "kind": "build", 22 | "isDefault": true 23 | }, 24 | "presentation": { 25 | "panel": "dedicated", 26 | "reveal": "never" 27 | }, 28 | "problemMatcher": { 29 | "pattern": { 30 | "regexp": "__________" 31 | }, 32 | "background": { 33 | "activeOnStart": true, 34 | "beginsPattern": " ", 35 | "endsPattern": "Waiting for changes..." 36 | } 37 | } 38 | } 39 | ] 40 | } -------------------------------------------------------------------------------- /extensions/vscode/.vscodeignore: -------------------------------------------------------------------------------- 1 | out 2 | scripts 3 | src 4 | tests 5 | tsconfig.* 6 | meta.json 7 | stats.html 8 | -------------------------------------------------------------------------------- /extensions/vscode/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | For a full change history, refer to the [CHANGELOG](https://github.com/vuejs/language-tools/blob/master/CHANGELOG.md) on the GitHub site. 2 | -------------------------------------------------------------------------------- /extensions/vscode/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/language-tools/d94c100f416f5dbe9adfbdb24305537ee9cc326e/extensions/vscode/images/icon.png -------------------------------------------------------------------------------- /extensions/vscode/images/split-editors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/language-tools/d94c100f416f5dbe9adfbdb24305537ee9cc326e/extensions/vscode/images/split-editors.png -------------------------------------------------------------------------------- /extensions/vscode/languages/sfc-template-language-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "colorizedBracketPairs": [ 3 | [ 4 | "{{", 5 | "}}" 6 | ], 7 | ] 8 | } -------------------------------------------------------------------------------- /extensions/vscode/src/config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfigObject } from 'reactive-vscode'; 2 | import { type NestedScopedConfigs, scopedConfigs } from './generated-meta'; 3 | 4 | export const config = defineConfigObject( 5 | scopedConfigs.scope, 6 | scopedConfigs.defaults 7 | ); 8 | -------------------------------------------------------------------------------- /extensions/vscode/syntaxes/vue-directives.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", 3 | "fileTypes": [], 4 | "injectionSelector": "L:meta.tag -meta.attribute -meta.ng-binding -entity.name.tag.pug -attribute_value -source.tsx -source.js.jsx, L:meta.element -meta.attribute", 5 | "patterns": [ 6 | { 7 | "include": "source.vue#vue-directives" 8 | } 9 | ], 10 | "scopeName": "vue.directives" 11 | } 12 | -------------------------------------------------------------------------------- /extensions/vscode/syntaxes/vue-interpolations.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", 3 | "fileTypes": [], 4 | "injectionSelector": "L:text.pug -comment -string.comment, L:text.html.derivative -comment.block, L:text.html.markdown -comment.block", 5 | "patterns": [ 6 | { 7 | "include": "source.vue#vue-interpolations" 8 | } 9 | ], 10 | "scopeName": "vue.interpolations" 11 | } -------------------------------------------------------------------------------- /extensions/vscode/tests/grammar.spec.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'node:fs'; 2 | import * as path from 'node:path'; 3 | import { describe, expect, it } from 'vitest'; 4 | import { createGrammarSnapshot } from 'vscode-tmlanguage-snapshot'; 5 | 6 | const fixturesDir = path.resolve(__dirname, './grammarFixtures'); 7 | const packageJsonPath = path.resolve(__dirname, '../package.json'); 8 | 9 | describe('grammar', async () => { 10 | const snapshot = await createGrammarSnapshot(packageJsonPath); 11 | const fixtures = fs.readdirSync(fixturesDir); 12 | 13 | for (const fixture of fixtures) { 14 | it.skipIf(fixture === 'snippet-import.md')(fixture, async () => { 15 | const result = await snapshot(`tests/grammarFixtures/${fixture}`); 16 | 17 | expect(result).toMatchSnapshot(); 18 | }); 19 | } 20 | }); 21 | -------------------------------------------------------------------------------- /extensions/vscode/tests/grammarFixtures/basic.vue: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /extensions/vscode/tests/grammarFixtures/generic.vue: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /extensions/vscode/tests/grammarFixtures/inline-style.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /extensions/vscode/tests/grammarFixtures/jsx.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /extensions/vscode/tests/grammarFixtures/namespaced.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 26 | -------------------------------------------------------------------------------- /extensions/vscode/tests/grammarFixtures/script-tag-in-script.vue: -------------------------------------------------------------------------------- 1 | ' 2 | -------------------------------------------------------------------------------- /extensions/vscode/tests/grammarFixtures/snippet-import.md: -------------------------------------------------------------------------------- 1 | <<< 2 | -------------------------------------------------------------------------------- /extensions/vscode/tests/grammarFixtures/template-expression.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /extensions/vscode/tests/grammarFixtures/template-in-template.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | -------------------------------------------------------------------------------- /extensions/vscode/tests/index.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, test } from 'vitest'; 2 | 3 | describe('vscode', () => { 4 | test.skip('vscode versions should be consistent ', () => { 5 | 6 | const languageClientVersion = require('vscode-languageclient/package.json').engines.vscode; 7 | const typesVersion = require('../package.json').devDependencies['@types/vscode']; 8 | const enginesVersion = require('../package.json').engines.vscode; 9 | 10 | expect(typesVersion).toBe(languageClientVersion); 11 | expect(enginesVersion).toBe(languageClientVersion); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /extensions/vscode/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "noEmit": true, 5 | "module": "CommonJS", 6 | "moduleResolution": "Node" 7 | }, 8 | "include": [ "src", "rolldown.config.ts" ] 9 | } -------------------------------------------------------------------------------- /extensions/vscode/web.js: -------------------------------------------------------------------------------- 1 | const vscode = require("vscode"); 2 | 3 | exports.activate = async function () { 4 | const tsWeb = vscode.extensions.getExtension('johnsoncodehk.vscode-typescript-web'); 5 | if (!tsWeb) { 6 | const select = await vscode.window.showInformationMessage( 7 | 'Install "TypeScript IntelliSense for Web" to enable Vue IntelliSense.', 8 | 'Install', 9 | 'Cancel', 10 | ); 11 | if (select === 'Install') { 12 | vscode.commands.executeCommand('workbench.extensions.search', 'johnsoncodehk.vscode-typescript-web'); 13 | } 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/lerna-lite/lerna-lite/main/packages/cli/schemas/lerna-schema.json", 3 | "npmClient": "pnpm", 4 | "packages": [ 5 | "extensions/**", 6 | "packages/**", 7 | "test-workspace" 8 | ], 9 | "version": "3.0.0-alpha.8" 10 | } 11 | -------------------------------------------------------------------------------- /packages/component-meta/index.ts: -------------------------------------------------------------------------------- 1 | import * as ts from 'typescript'; 2 | import { createCheckerBase, createCheckerByJsonConfigBase } from './lib/base'; 3 | import type { MetaCheckerOptions } from './lib/types'; 4 | 5 | export * from './lib/types'; 6 | 7 | export function createCheckerByJson( 8 | rootPath: string, 9 | json: any, 10 | checkerOptions: MetaCheckerOptions = {} 11 | ) { 12 | return createCheckerByJsonConfigBase( 13 | ts, 14 | rootPath, 15 | json, 16 | checkerOptions 17 | ); 18 | } 19 | 20 | export function createChecker( 21 | tsconfig: string, 22 | checkerOptions: MetaCheckerOptions = {} 23 | ) { 24 | return createCheckerBase( 25 | ts, 26 | tsconfig, 27 | checkerOptions 28 | ); 29 | } 30 | -------------------------------------------------------------------------------- /packages/component-meta/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-component-meta", 3 | "version": "3.0.0-alpha.8", 4 | "license": "MIT", 5 | "files": [ 6 | "**/*.js", 7 | "**/*.d.ts" 8 | ], 9 | "sideEffects": false, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/vuejs/language-tools.git", 13 | "directory": "packages/component-meta" 14 | }, 15 | "dependencies": { 16 | "@volar/typescript": "~2.4.13", 17 | "@vue/language-core": "3.0.0-alpha.8", 18 | "path-browserify": "^1.0.1", 19 | "vue-component-type-helpers": "3.0.0-alpha.8" 20 | }, 21 | "peerDependencies": { 22 | "typescript": "*" 23 | }, 24 | "peerDependenciesMeta": { 25 | "typescript": { 26 | "optional": true 27 | } 28 | }, 29 | "devDependencies": { 30 | "@types/node": "^22.10.4", 31 | "@types/path-browserify": "^1.0.1" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/component-meta/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": [ "*", "lib/**/*" ], 4 | "exclude": [ "tests" ], 5 | "references": [ 6 | { "path": "../component-type-helpers/tsconfig.json" }, 7 | { "path": "../language-core/tsconfig.json" }, 8 | ], 9 | } -------------------------------------------------------------------------------- /packages/component-type-helpers/README.md: -------------------------------------------------------------------------------- 1 | # vue-component-type-helpers 2 | 3 | Some very simple type helpers used behind `vue-component-meta` for extract component props, slots, emit, exposed types. 4 | 5 | ## Usage 6 | 7 | ```vue 8 | 12 | 13 | 18 | ``` 19 | 20 | ```ts 21 | import HelloWorld from './HelloWorld.vue' 22 | import type { ComponentProps, ComponentSlots } from 'vue-component-type-helpers' 23 | 24 | type Props = ComponentProps // { msg: string } 25 | type Slots = ComponentSlots // { header?: (props: { num: number; }) => any; footer?: (props: { str: string; }) => any; } 26 | ``` 27 | -------------------------------------------------------------------------------- /packages/component-type-helpers/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-component-type-helpers", 3 | "version": "3.0.0-alpha.8", 4 | "license": "MIT", 5 | "files": [ 6 | "**/*.js", 7 | "**/*.d.ts" 8 | ], 9 | "sideEffects": false, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/vuejs/language-tools.git", 13 | "directory": "packages/component-type-helpers" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/component-type-helpers/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": [ "*", "lib/**/*" ], 4 | "exclude": [ "tests" ], 5 | } -------------------------------------------------------------------------------- /packages/language-core/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/codegen/globalTypes'; 2 | export * from './lib/codegen/template'; 3 | export * from './lib/languagePlugin'; 4 | export * from './lib/parsers/scriptSetupRanges'; 5 | export * from './lib/plugins'; 6 | export * from './lib/types'; 7 | export * from './lib/utils/parseSfc'; 8 | export * from './lib/utils/shared'; 9 | export * from './lib/utils/ts'; 10 | export * from './lib/virtualFile/vueFile'; 11 | 12 | export { tsCodegen } from './lib/plugins/vue-tsx'; 13 | 14 | export * from '@volar/language-core'; 15 | -------------------------------------------------------------------------------- /packages/language-core/lib/codegen/inlayHints.ts: -------------------------------------------------------------------------------- 1 | import type * as CompilerDOM from '@vue/compiler-dom'; 2 | 3 | export interface InlayHintInfo { 4 | blockName: string; 5 | offset: number; 6 | setting: string; 7 | label: string; 8 | tooltip?: string; 9 | paddingRight?: boolean; 10 | paddingLeft?: boolean; 11 | } 12 | 13 | export function createVBindShorthandInlayHintInfo(loc: CompilerDOM.SourceLocation, variableName: string): InlayHintInfo { 14 | return { 15 | blockName: 'template', 16 | offset: loc.end.offset, 17 | setting: 'vue.inlayHints.vBindShorthand', 18 | label: `="${variableName}"`, 19 | tooltip: [ 20 | `This is a shorthand for \`${loc.source}="${variableName}"\`.`, 21 | 'To hide this hint, set `vue.inlayHints.vBindShorthand` to `false` in IDE settings.', 22 | '[More info](https://github.com/vuejs/core/pull/9451)', 23 | ].join('\n\n'), 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /packages/language-core/lib/codegen/style/classProperty.ts: -------------------------------------------------------------------------------- 1 | import type { Code } from '../../types'; 2 | import { codeFeatures } from '../codeFeatures'; 3 | import { combineLastMapping, newLine } from '../utils'; 4 | import { wrapWith } from '../utils/wrapWith'; 5 | 6 | export function* generateClassProperty( 7 | styleIndex: number, 8 | classNameWithDot: string, 9 | offset: number, 10 | propertyType: string 11 | ): Generator { 12 | yield `${newLine} & { `; 13 | yield* wrapWith( 14 | offset, 15 | offset + classNameWithDot.length, 16 | 'style_' + styleIndex, 17 | codeFeatures.navigation, 18 | `'`, 19 | [ 20 | classNameWithDot.slice(1), 21 | 'style_' + styleIndex, 22 | offset + 1, 23 | combineLastMapping 24 | ], 25 | `'` 26 | ); 27 | yield `: ${propertyType}`; 28 | yield ` }`; 29 | } 30 | -------------------------------------------------------------------------------- /packages/language-core/lib/codegen/template/elementChildren.ts: -------------------------------------------------------------------------------- 1 | import type * as CompilerDOM from '@vue/compiler-dom'; 2 | import type { Code } from '../../types'; 3 | import type { TemplateCodegenContext } from './context'; 4 | import type { TemplateCodegenOptions } from './index'; 5 | import { generateTemplateChild } from './templateChild'; 6 | 7 | export function* generateElementChildren( 8 | options: TemplateCodegenOptions, 9 | ctx: TemplateCodegenContext, 10 | children: (CompilerDOM.TemplateChildNode | CompilerDOM.SimpleExpressionNode)[], 11 | enterNode = true 12 | ): Generator { 13 | yield* ctx.generateAutoImportCompletion(); 14 | for (const childNode of children) { 15 | yield* generateTemplateChild(options, ctx, childNode, enterNode); 16 | } 17 | yield* ctx.generateAutoImportCompletion(); 18 | } 19 | -------------------------------------------------------------------------------- /packages/language-core/lib/codegen/utils/camelized.ts: -------------------------------------------------------------------------------- 1 | import { capitalize } from '@vue/shared'; 2 | import type { Code, VueCodeInformation } from '../../types'; 3 | 4 | export function* generateCamelized( 5 | code: string, 6 | source: string, 7 | offset: number, 8 | features: VueCodeInformation 9 | ): Generator { 10 | const parts = code.split('-'); 11 | const startCombineOffset = features.__combineOffset ?? 0; 12 | 13 | for (let i = 0; i < parts.length; i++) { 14 | const part = parts[i]; 15 | if (part !== '') { 16 | if (i === 0) { 17 | yield [ 18 | part, 19 | source, 20 | offset, 21 | features, 22 | ]; 23 | } 24 | else { 25 | yield [ 26 | capitalize(part), 27 | source, 28 | offset, 29 | { __combineOffset: startCombineOffset + i }, 30 | ]; 31 | } 32 | } 33 | offset += part.length + 1; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/language-core/lib/codegen/utils/escaped.ts: -------------------------------------------------------------------------------- 1 | import type { Code, VueCodeInformation } from "../../types"; 2 | 3 | export function* generateEscaped( 4 | text: string, 5 | source: string, 6 | offset: number, 7 | features: VueCodeInformation, 8 | escapeTarget: RegExp 9 | ): Generator { 10 | const parts = text.split(escapeTarget); 11 | const startCombineOffset = features.__combineOffset ?? 0; 12 | let isEscapeTarget = false; 13 | 14 | for (let i = 0; i < parts.length; i++) { 15 | const part = parts[i]; 16 | if (isEscapeTarget) { 17 | yield `\\`; 18 | } 19 | yield [ 20 | part, 21 | source, 22 | offset, 23 | i === 0 ? features : { __combineOffset: startCombineOffset + i }, 24 | ]; 25 | offset += part.length; 26 | isEscapeTarget = !isEscapeTarget; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/language-core/lib/codegen/utils/stringLiteralKey.ts: -------------------------------------------------------------------------------- 1 | import type { Code, VueCodeInformation } from '../../types'; 2 | import { combineLastMapping } from './index'; 3 | import { wrapWith } from './wrapWith'; 4 | 5 | export function* generateStringLiteralKey(code: string, offset?: number, info?: VueCodeInformation): Generator { 6 | if (offset === undefined || !info) { 7 | yield `'${code}'`; 8 | } 9 | else { 10 | yield* wrapWith( 11 | offset, 12 | offset + code.length, 13 | info, 14 | `'`, 15 | [code, 'template', offset, combineLastMapping], 16 | `'` 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/language-core/lib/codegen/utils/unicode.ts: -------------------------------------------------------------------------------- 1 | import type { Code, VueCodeInformation } from '../../types'; 2 | import { wrapWith } from './wrapWith'; 3 | 4 | export function* generateUnicode(code: string, offset: number, info: VueCodeInformation): Generator { 5 | if (needToUnicode(code)) { 6 | yield* wrapWith( 7 | offset, 8 | offset + code.length, 9 | info, 10 | toUnicode(code) 11 | ); 12 | } 13 | else { 14 | yield [code, 'template', offset, info]; 15 | } 16 | } 17 | 18 | function needToUnicode(str: string) { 19 | return str.includes('\\') || str.includes('\n'); 20 | } 21 | 22 | function toUnicode(str: string) { 23 | return str.split('').map(value => { 24 | const temp = value.charCodeAt(0).toString(16).padStart(4, '0'); 25 | if (temp.length > 2) { 26 | return '\\u' + temp; 27 | } 28 | return value; 29 | }).join(''); 30 | } 31 | -------------------------------------------------------------------------------- /packages/language-core/lib/parsers/vueCompilerOptions.ts: -------------------------------------------------------------------------------- 1 | import type { RawVueCompilerOptions } from '../types'; 2 | 3 | const syntaxReg = /^\s*@(?.+?)\s+(?.+?)\s*$/m; 4 | 5 | export function parseVueCompilerOptions(comments: string[]): RawVueCompilerOptions | undefined { 6 | const entries = comments 7 | .map(text => { 8 | try { 9 | const match = text.match(syntaxReg); 10 | if (match) { 11 | const { key, value } = match.groups ?? {}; 12 | return [key, JSON.parse(value)] as const; 13 | } 14 | } 15 | catch { }; 16 | }) 17 | .filter(item => !!item); 18 | 19 | if (entries.length) { 20 | return Object.fromEntries(entries); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/language-core/lib/plugins/shared.ts: -------------------------------------------------------------------------------- 1 | import type { CodeInformation } from '@volar/language-core'; 2 | 3 | export const allCodeFeatures: CodeInformation = { 4 | verification: true, 5 | completion: true, 6 | semantic: true, 7 | navigation: true, 8 | structure: true, 9 | format: true, 10 | }; 11 | -------------------------------------------------------------------------------- /packages/language-core/lib/plugins/vue-script-js.ts: -------------------------------------------------------------------------------- 1 | import type * as ts from 'typescript'; 2 | import type { VueLanguagePlugin } from '../types'; 3 | 4 | const plugin: VueLanguagePlugin = ({ modules }) => { 5 | 6 | return { 7 | 8 | version: 2.1, 9 | 10 | compileSFCScript(lang, script) { 11 | if (lang === 'js' || lang === 'ts' || lang === 'jsx' || lang === 'tsx') { 12 | const ts = modules.typescript; 13 | return ts.createSourceFile('test.' + lang, script, 99 satisfies ts.ScriptTarget.Latest); 14 | } 15 | }, 16 | }; 17 | }; 18 | 19 | export default plugin; 20 | -------------------------------------------------------------------------------- /packages/language-core/lib/plugins/vue-sfc-customblocks.ts: -------------------------------------------------------------------------------- 1 | import type { VueLanguagePlugin } from '../types'; 2 | import { allCodeFeatures } from './shared'; 3 | 4 | const plugin: VueLanguagePlugin = () => { 5 | 6 | return { 7 | 8 | version: 2.1, 9 | 10 | getEmbeddedCodes(_fileName, sfc) { 11 | return sfc.customBlocks.map((customBlock, i) => ({ 12 | id: 'custom_block_' + i, 13 | lang: customBlock.lang, 14 | })); 15 | }, 16 | 17 | resolveEmbeddedCode(_fileName, sfc, embeddedFile) { 18 | if (embeddedFile.id.startsWith('custom_block_')) { 19 | const index = parseInt(embeddedFile.id.slice('custom_block_'.length)); 20 | const customBlock = sfc.customBlocks[index]; 21 | 22 | embeddedFile.content.push([ 23 | customBlock.content, 24 | customBlock.name, 25 | 0, 26 | allCodeFeatures, 27 | ]); 28 | } 29 | }, 30 | }; 31 | }; 32 | 33 | export default plugin; 34 | -------------------------------------------------------------------------------- /packages/language-core/lib/plugins/vue-sfc-template.ts: -------------------------------------------------------------------------------- 1 | import type { VueLanguagePlugin } from '../types'; 2 | import { allCodeFeatures } from './shared'; 3 | 4 | const plugin: VueLanguagePlugin = () => { 5 | 6 | return { 7 | 8 | version: 2.1, 9 | 10 | getEmbeddedCodes(_fileName, sfc) { 11 | if (sfc.template?.lang === 'html') { 12 | return [{ 13 | id: 'template', 14 | lang: sfc.template.lang, 15 | }]; 16 | } 17 | return []; 18 | }, 19 | 20 | resolveEmbeddedCode(_fileName, sfc, embeddedFile) { 21 | if (embeddedFile.id === 'template' && sfc.template?.lang === 'html') { 22 | embeddedFile.content.push([ 23 | sfc.template.content, 24 | sfc.template.name, 25 | 0, 26 | allCodeFeatures, 27 | ]); 28 | } 29 | }, 30 | }; 31 | }; 32 | 33 | export default plugin; 34 | -------------------------------------------------------------------------------- /packages/language-core/lib/utils/buildMappings.ts: -------------------------------------------------------------------------------- 1 | import type { Mapping } from '@volar/language-core'; 2 | import type { Segment } from 'muggle-string'; 3 | 4 | export function buildMappings(chunks: Segment[]) { 5 | let length = 0; 6 | const mappings: Mapping[] = []; 7 | for (const segment of chunks) { 8 | if (typeof segment === 'string') { 9 | length += segment.length; 10 | } 11 | else { 12 | mappings.push({ 13 | sourceOffsets: [segment[2]], 14 | generatedOffsets: [length], 15 | lengths: [segment[0].length], 16 | data: segment[3]!, 17 | }); 18 | length += segment[0].length; 19 | } 20 | } 21 | return mappings; 22 | } 23 | -------------------------------------------------------------------------------- /packages/language-core/lib/utils/parseCssClassNames.ts: -------------------------------------------------------------------------------- 1 | import { commentReg, fillBlank } from './parseCssVars'; 2 | 3 | const cssClassNameReg = /(?=(\.[a-z_][-\w]*)[\s.,+~>:#)[{])/gi; 4 | const fragmentReg = /(?<={)[^{]*(?=(? t); 11 | if (matchText) { 12 | const offset = match.index + css.slice(match.index).indexOf(matchText); 13 | yield { offset, text: matchText }; 14 | } 15 | } 16 | } 17 | 18 | export function fillBlank(css: string, ...regs: RegExp[]) { 19 | for (const reg of regs) { 20 | css = css.replace(reg, match => ' '.repeat(match.length)); 21 | } 22 | return css; 23 | } -------------------------------------------------------------------------------- /packages/language-core/lib/virtualFile/embeddedFile.ts: -------------------------------------------------------------------------------- 1 | import type { Mapping } from '@volar/language-core'; 2 | import type { Code } from '../types'; 3 | 4 | export class VueEmbeddedCode { 5 | 6 | public parentCodeId?: string; 7 | public linkedCodeMappings: Mapping[] = []; 8 | public embeddedCodes: VueEmbeddedCode[] = []; 9 | 10 | constructor( 11 | public id: string, 12 | public lang: string, 13 | public content: Code[], 14 | ) { } 15 | } 16 | -------------------------------------------------------------------------------- /packages/language-core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": [ "*", "lib/**/*" ], 4 | "exclude": [ "tests" ], 5 | } -------------------------------------------------------------------------------- /packages/language-plugin-pug/README.md: -------------------------------------------------------------------------------- 1 | A `VueLanguagePlugin` to support `