@vue/language-core 1.8.10 → 1.8.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -252,7 +252,7 @@ function generate(ts, fileName, _sfc, lang, scriptRanges, scriptSetupRanges, htm
252
252
  if (!scriptSetupRanges)
253
253
  return;
254
254
  codes.push([
255
- sfc.scriptSetup.content.substring(0, Math.max(scriptSetupRanges.importSectionEndOffset, scriptSetupRanges.leadingCommentEndOffset)),
255
+ sfc.scriptSetup.content.substring(0, Math.max(scriptSetupRanges.importSectionEndOffset, scriptSetupRanges.leadingCommentEndOffset)) + '\n',
256
256
  'scriptSetup',
257
257
  0,
258
258
  language_core_1.FileRangeCapabilities.full,
@@ -433,7 +433,20 @@ function generate(ts, fileName, _sfc, lang, scriptRanges, scriptSetupRanges, htm
433
433
  const definePropProposalA = sfc.scriptSetup.content.trimStart().startsWith('// @experimentalDefinePropProposal=kevinEdition') || vueCompilerOptions.experimentalDefinePropProposal === 'kevinEdition';
434
434
  const definePropProposalB = sfc.scriptSetup.content.trimStart().startsWith('// @experimentalDefinePropProposal=johnsonEdition') || vueCompilerOptions.experimentalDefinePropProposal === 'johnsonEdition';
435
435
  if (vueCompilerOptions.target >= 3.3) {
436
- codes.push(`const { defineProps, defineEmits, defineExpose, defineOptions, defineSlots, defineModel, withDefaults } = await import('${vueCompilerOptions.lib}');\n`);
436
+ const bindings = new Set(scriptSetupRanges.bindings.map(range => sfc.scriptSetup.content.substring(range.start, range.end)));
437
+ codes.push('const { ');
438
+ for (const [macro, aliases] of Object.entries(vueCompilerOptions.macros)) {
439
+ for (const alias of aliases) {
440
+ if (!bindings.has(alias)) {
441
+ codes.push(macro);
442
+ if (alias !== macro) {
443
+ codes.push(` : ${alias}`);
444
+ }
445
+ codes.push(`, `);
446
+ }
447
+ }
448
+ }
449
+ codes.push(`} = await import('${vueCompilerOptions.lib}');\n`);
437
450
  }
438
451
  if (definePropProposalA) {
439
452
  codes.push(`
@@ -60,6 +60,8 @@ const capabilitiesPresets = {
60
60
  };
61
61
  const formatBrackets = {
62
62
  normal: ['`${', '}`;'],
63
+ // fix https://github.com/vuejs/language-tools/issues/3572
64
+ params: ['(', ') => {}'],
63
65
  // fix https://github.com/vuejs/language-tools/issues/1210
64
66
  // fix https://github.com/vuejs/language-tools/issues/2305
65
67
  curly: ['0 +', '+ 0;'],
@@ -95,6 +97,7 @@ function generate(ts, compilerOptions, vueCompilerOptions, sourceTemplate, sourc
95
97
  const identifiers = new Set();
96
98
  const scopedClasses = [];
97
99
  const blockConditions = [];
100
+ const hasSlotElements = new Set();
98
101
  let hasSlot = false;
99
102
  let elementIndex = 0;
100
103
  let ignoreStart;
@@ -312,7 +315,7 @@ function generate(ts, compilerOptions, vueCompilerOptions, sourceTemplate, sourc
312
315
  }
313
316
  }
314
317
  codes.push([
315
- '// @ts-expect-error',
318
+ '// @ts-expect-error __VLS_TS_EXPECT_ERROR',
316
319
  'template',
317
320
  [expectedErrorNode.loc.start.offset, expectedErrorNode.loc.end.offset],
318
321
  {
@@ -529,14 +532,12 @@ function generate(ts, compilerOptions, vueCompilerOptions, sourceTemplate, sourc
529
532
  }
530
533
  codes.push(`typeof __VLS_resolvedLocalAndGlobalComponents['${toCanonicalComponentName(tag)}'];\n`);
531
534
  }
532
- codes.push(`const ${var_functionalComponent} = __VLS_asFunctionalComponent(`, `${var_originalComponent}, `);
533
535
  if (isIntrinsicElement) {
534
- codes.push('{}');
536
+ codes.push(`const ${var_functionalComponent} = __VLS_elementAsFunctionalComponent(${var_originalComponent});\n`);
535
537
  }
536
538
  else {
537
- codes.push(`new ${var_originalComponent}({`, ...createPropsCode(node, props, 'extraReferences'), '})');
539
+ codes.push(`const ${var_functionalComponent} = __VLS_asFunctionalComponent(`, `${var_originalComponent}, `, `new ${var_originalComponent}({`, ...createPropsCode(node, props, 'extraReferences'), '})', ');\n');
538
540
  }
539
- codes.push(');\n');
540
541
  for (const offset of tagOffsets) {
541
542
  if (isNamespacedTag || dynamicTagExp) {
542
543
  continue;
@@ -567,24 +568,32 @@ function generate(ts, compilerOptions, vueCompilerOptions, sourceTemplate, sourc
567
568
  ], ';\n');
568
569
  }
569
570
  }
570
- codes.push(`const ${var_componentInstance} = ${var_functionalComponent}(`,
571
- // diagnostic start
572
- tagOffsets.length ? ['', 'template', tagOffsets[0], capabilitiesPresets.diagnosticOnly]
573
- : dynamicTagExp ? ['', 'template', startTagOffset, capabilitiesPresets.diagnosticOnly]
574
- : '', '{ ');
575
- if (!vueCompilerOptions.strictTemplates) {
576
- // fix https://github.com/vuejs/language-tools/issues/3318
577
- codes.push('...{ ');
578
- }
579
- codes.push(...createPropsCode(node, props, 'normal', propsFailedExps));
580
- if (!vueCompilerOptions.strictTemplates) {
581
- codes.push('}, ');
582
- }
583
- codes.push('}',
584
- // diagnostic end
585
- tagOffsets.length ? ['', 'template', tagOffsets[0] + tag.length, capabilitiesPresets.diagnosticOnly]
586
- : dynamicTagExp ? ['', 'template', startTagOffset + tag.length, capabilitiesPresets.diagnosticOnly]
587
- : '', `, ...__VLS_functionalComponentArgsRest(${var_functionalComponent}));\n`);
571
+ if (vueCompilerOptions.strictTemplates) {
572
+ // with strictTemplates, generate once for props type-checking + instance type
573
+ codes.push(`const ${var_componentInstance} = ${var_functionalComponent}(`,
574
+ // diagnostic start
575
+ tagOffsets.length ? ['', 'template', tagOffsets[0], capabilitiesPresets.diagnosticOnly]
576
+ : dynamicTagExp ? ['', 'template', startTagOffset, capabilitiesPresets.diagnosticOnly]
577
+ : '', '{ ', ...createPropsCode(node, props, 'normal', propsFailedExps), '}',
578
+ // diagnostic end
579
+ tagOffsets.length ? ['', 'template', tagOffsets[0] + tag.length, capabilitiesPresets.diagnosticOnly]
580
+ : dynamicTagExp ? ['', 'template', startTagOffset + tag.length, capabilitiesPresets.diagnosticOnly]
581
+ : '', `, ...__VLS_functionalComponentArgsRest(${var_functionalComponent}));\n`);
582
+ }
583
+ else {
584
+ // without strictTemplates, this only for instacne type
585
+ codes.push(`const ${var_componentInstance} = ${var_functionalComponent}(`, '{ ', ...createPropsCode(node, props, 'extraReferences'), '}', `, ...__VLS_functionalComponentArgsRest(${var_functionalComponent}));\n`);
586
+ // and this for props type-checking
587
+ codes.push(`({} as (props: __VLS_FunctionalComponentProps<typeof ${var_originalComponent}, typeof ${var_componentInstance}> & Record<string, unknown>) => void)(`,
588
+ // diagnostic start
589
+ tagOffsets.length ? ['', 'template', tagOffsets[0], capabilitiesPresets.diagnosticOnly]
590
+ : dynamicTagExp ? ['', 'template', startTagOffset, capabilitiesPresets.diagnosticOnly]
591
+ : '', '{ ', ...createPropsCode(node, props, 'normal', propsFailedExps), '}',
592
+ // diagnostic end
593
+ tagOffsets.length ? ['', 'template', tagOffsets[0] + tag.length, capabilitiesPresets.diagnosticOnly]
594
+ : dynamicTagExp ? ['', 'template', startTagOffset + tag.length, capabilitiesPresets.diagnosticOnly]
595
+ : '', `);\n`);
596
+ }
588
597
  if (tag !== 'template' && tag !== 'slot') {
589
598
  componentCtxVar = `__VLS_${elementIndex++}`;
590
599
  codes.push(`const ${componentCtxVar} = __VLS_pickFunctionalComponentCtx(${var_originalComponent}, ${var_componentInstance})!;\n`);
@@ -636,13 +645,16 @@ function generate(ts, compilerOptions, vueCompilerOptions, sourceTemplate, sourc
636
645
  //#endregion
637
646
  const slotDir = node.props.find(p => p.type === 7 /* CompilerDOM.NodeTypes.DIRECTIVE */ && p.name === 'slot');
638
647
  if (slotDir && componentCtxVar) {
648
+ if (parentEl) {
649
+ hasSlotElements.add(parentEl);
650
+ }
639
651
  const slotBlockVars = [];
640
652
  codes.push(`{\n`);
641
653
  let hasProps = false;
642
654
  if (slotDir?.exp?.type === 4 /* CompilerDOM.NodeTypes.SIMPLE_EXPRESSION */) {
643
- formatCodes.push(...createFormatCode(slotDir.exp.content, slotDir.exp.loc.start.offset, formatBrackets.normal));
644
- const collectAst = createTsAst(slotDir, `(${slotDir.exp.content}) => {}`);
645
- (0, transform_1.colletVars)(ts, collectAst, slotBlockVars);
655
+ formatCodes.push(...createFormatCode(slotDir.exp.content, slotDir.exp.loc.start.offset, formatBrackets.params));
656
+ const slotAst = createTsAst(slotDir, `(${slotDir.exp.content}) => {}`);
657
+ (0, transform_1.colletVars)(ts, slotAst, slotBlockVars);
646
658
  hasProps = true;
647
659
  if (slotDir.exp.content.indexOf(':') === -1) {
648
660
  codes.push('const [', [
@@ -712,6 +724,18 @@ function generate(ts, compilerOptions, vueCompilerOptions, sourceTemplate, sourc
712
724
  prev = childNode;
713
725
  }
714
726
  resolveComment();
727
+ // fix https://github.com/vuejs/language-tools/issues/932
728
+ if (!hasSlotElements.has(node) && node.children.length) {
729
+ codes.push(`(${componentCtxVar}.slots!)`, ...createPropertyAccessCode([
730
+ 'default',
731
+ 'template',
732
+ [
733
+ node.children[0].loc.start.offset,
734
+ node.children[node.children.length - 1].loc.end.offset,
735
+ ],
736
+ { references: true },
737
+ ]), ';\n');
738
+ }
715
739
  }
716
740
  codes.push(`}\n`);
717
741
  }
@@ -721,7 +745,7 @@ function generate(ts, compilerOptions, vueCompilerOptions, sourceTemplate, sourc
721
745
  && prop.name === 'on'
722
746
  && prop.arg?.type === 4 /* CompilerDOM.NodeTypes.SIMPLE_EXPRESSION */) {
723
747
  const eventVar = `__VLS_${elementIndex++}`;
724
- codes.push(`let ${eventVar} = { '${prop.arg.loc.source}': `, `__VLS_pickEvent(${componentCtxVar}.emit!, '${prop.arg.loc.source}' as const, __VLS_componentProps(${componentVar}, ${componentInstanceVar})`, ...createPropertyAccessCode([
748
+ codes.push(`let ${eventVar} = { '${prop.arg.loc.source}': `, `__VLS_pickEvent(${componentCtxVar}.emit!, '${prop.arg.loc.source}' as const, {} as __VLS_FunctionalComponentProps<typeof ${componentVar}, typeof ${componentInstanceVar}>`, ...createPropertyAccessCode([
725
749
  (0, shared_1.camelize)('on-' + prop.arg.loc.source),
726
750
  'template',
727
751
  [prop.arg.loc.start.offset, prop.arg.loc.end.offset],
@@ -65,7 +65,7 @@ function parseScriptSetupRanges(ts, ast, vueCompilerOptions) {
65
65
  if (ts.isCallExpression(node)
66
66
  && ts.isIdentifier(node.expression)) {
67
67
  const callText = node.expression.getText(ast);
68
- if (callText === 'defineModel') {
68
+ if (vueCompilerOptions.macros.defineModel.includes(callText)) {
69
69
  let name;
70
70
  let options;
71
71
  if (node.arguments.length >= 2) {
@@ -8,6 +8,7 @@ const scriptSetupReg = /\\\<[\s\S]+?\>\n?/g;
8
8
  const sfcBlockReg = /\<(script|style)\b[\s\S]*?\>([\s\S]*?)\<\/\1\>/g;
9
9
  const angleBracketReg = /\<\S*\:\S*\>/g;
10
10
  const linkReg = /\[[\s\S]*?\]\([\s\S]*?\)/g;
11
+ const codeSnippetImportReg = /^\s*<<<\s*.+/gm;
11
12
  const plugin = () => {
12
13
  return {
13
14
  version: 1,
@@ -19,7 +20,9 @@ const plugin = () => {
19
20
  // inline code block
20
21
  .replace(inlineCodeblockReg, match => `\`${' '.repeat(match.length - 2)}\``)
21
22
  // # \<script setup>
22
- .replace(scriptSetupReg, match => ' '.repeat(match.length));
23
+ .replace(scriptSetupReg, match => ' '.repeat(match.length))
24
+ // <<< https://vitepress.dev/guide/markdown#import-code-snippets
25
+ .replace(codeSnippetImportReg, match => ' '.repeat(match.length));
23
26
  const codes = [];
24
27
  for (const match of content.matchAll(sfcBlockReg)) {
25
28
  if (match.index !== undefined) {
package/out/types.d.ts CHANGED
@@ -23,6 +23,8 @@ export interface VueCompilerOptions {
23
23
  defineSlots: string[];
24
24
  defineEmits: string[];
25
25
  defineExpose: string[];
26
+ defineModel: string[];
27
+ defineOptions: string[];
26
28
  withDefaults: string[];
27
29
  };
28
30
  plugins: VueLanguagePlugin[];
@@ -97,7 +97,8 @@ declare function __VLS_asFunctionalComponent<T, K = T extends new (...args: any)
97
97
  }) => JSX.Element & { __ctx?: typeof ctx & { props?: typeof props; expose?(exposed: K): void; } }
98
98
  : T extends () => any ? (props: {}, ctx?: any) => ReturnType<T>
99
99
  : T extends (...args: any) => any ? T
100
- : (_: T extends import('${vueCompilerOptions.lib}').VNode | import('${vueCompilerOptions.lib}').VNode[] | string ? {}: T${vueCompilerOptions.strictTemplates ? '' : ' & Record<string, unknown>'}, ctx?: any) => { __ctx?: { attrs?: any, expose?: any, slots?: any, emit?: any, props?: T${vueCompilerOptions.strictTemplates ? '' : ' & Record<string, unknown>'} } }; // IntrinsicElement
100
+ : (_: {}${vueCompilerOptions.strictTemplates ? '' : ' & Record<string, unknown>'}, ctx?: any) => { __ctx?: { attrs?: any, expose?: any, slots?: any, emit?: any, props?: {}${vueCompilerOptions.strictTemplates ? '' : ' & Record<string, unknown>'} } };
101
+ declare function __VLS_elementAsFunctionalComponent<T>(t: T): (_: T${vueCompilerOptions.strictTemplates ? '' : ' & Record<string, unknown>'}, ctx?: any) => { __ctx?: { attrs?: any, expose?: any, slots?: any, emit?: any, props?: T${vueCompilerOptions.strictTemplates ? '' : ' & Record<string, unknown>'} } };
101
102
  declare function __VLS_functionalComponentArgsRest<T extends (...args: any) => any>(t: T): Parameters<T>['length'] extends 2 ? [any] : [];
102
103
  declare function __VLS_pickEvent<Emit, K, E>(emit: Emit, emitKey: K, event: E): __VLS_FillingEventArg<
103
104
  __VLS_PickNotAny<
@@ -106,16 +107,16 @@ declare function __VLS_pickEvent<Emit, K, E>(emit: Emit, emitKey: K, event: E):
106
107
  >
107
108
  > | undefined;
108
109
  declare function __VLS_pickFunctionalComponentCtx<T, K>(comp: T, compInstance: K): __VLS_PickNotAny<
109
- K extends { __ctx?: infer Ctx } ? Ctx : any,
110
- T extends (props: any, ctx: infer Ctx) => any ? Ctx : any
110
+ '__ctx' extends keyof __VLS_PickNotAny<K, {}> ? K extends { __ctx?: infer Ctx } ? Ctx : never : any
111
+ , T extends (props: any, ctx: infer Ctx) => any ? Ctx : any
111
112
  >;
113
+ type __VLS_FunctionalComponentProps<T, K> =
114
+ '__ctx' extends keyof __VLS_PickNotAny<K, {}> ? K extends { __ctx?: { props?: infer P } } ? NonNullable<P> : never
115
+ : T extends (props: infer P, ...args: any) => any ? P :
116
+ {};
112
117
  type __VLS_AsFunctionOrAny<F> = unknown extends F ? any : ((...args: any) => any) extends F ? F : any;
113
118
 
114
119
  declare function __VLS_normalizeSlot<S>(s: S): S extends () => infer R ? (props: {}) => R : S;
115
- declare function __VLS_componentProps<T, K>(comp: T, fnReturn: K):
116
- __VLS_PickNotAny<K, {}> extends { __ctx: { props: infer P } } ? NonNullable<P>
117
- : T extends (props: infer P, ...args: any) => any ? NonNullable<P> :
118
- {};
119
120
  `.trim();
120
121
  }
121
122
  exports.getTypesCode = getTypesCode;
package/out/utils/ts.js CHANGED
@@ -225,12 +225,15 @@ function resolveVueCompilerOptions(vueOptions) {
225
225
  optionsWrapper: vueOptions.optionsWrapper ?? (target >= 2.7
226
226
  ? [`(await import('${lib}')).defineComponent(`, `)`]
227
227
  : [`(await import('vue')).default.extend(`, `)`]),
228
- macros: vueOptions.macros ?? {
228
+ macros: {
229
229
  defineProps: ['defineProps'],
230
230
  defineSlots: ['defineSlots'],
231
231
  defineEmits: ['defineEmits'],
232
232
  defineExpose: ['defineExpose'],
233
+ defineModel: ['defineModel'],
234
+ defineOptions: ['defineOptions'],
233
235
  withDefaults: ['withDefaults'],
236
+ ...vueOptions.macros,
234
237
  },
235
238
  plugins: vueOptions.plugins ?? [],
236
239
  hooks: vueOptions.hooks ?? [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue/language-core",
3
- "version": "1.8.10",
3
+ "version": "1.8.12",
4
4
  "main": "out/index.js",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -34,5 +34,5 @@
34
34
  "optional": true
35
35
  }
36
36
  },
37
- "gitHead": "97d60fa475b653fe435a7fae6e2a626821658351"
37
+ "gitHead": "a065fd7516de02f1804f3394d6e2e0511a1e67a5"
38
38
  }