@vue/language-core 3.2.9 → 3.3.0

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.
Files changed (42) hide show
  1. package/README.md +1 -0
  2. package/lib/codegen/names.d.ts +1 -0
  3. package/lib/codegen/names.js +1 -0
  4. package/lib/codegen/script/component.d.ts +2 -2
  5. package/lib/codegen/script/component.js +64 -58
  6. package/lib/codegen/script/index.d.ts +3 -3
  7. package/lib/codegen/script/scriptSetup.d.ts +4 -4
  8. package/lib/codegen/script/template.js +9 -9
  9. package/lib/codegen/style/common.d.ts +2 -2
  10. package/lib/codegen/style/index.d.ts +2 -2
  11. package/lib/codegen/template/element.js +29 -24
  12. package/lib/codegen/template/elementProps.d.ts +2 -2
  13. package/lib/codegen/template/elementProps.js +11 -10
  14. package/lib/codegen/template/index.d.ts +2 -2
  15. package/lib/codegen/template/index.js +6 -3
  16. package/lib/codegen/template/interpolation.d.ts +2 -2
  17. package/lib/codegen/template/styleScopedClasses.d.ts +3 -3
  18. package/lib/codegen/template/templateChild.d.ts +1 -1
  19. package/lib/codegen/template/templateChild.js +8 -4
  20. package/lib/codegen/utils/index.d.ts +3 -3
  21. package/lib/codegen/utils/merge.d.ts +2 -2
  22. package/lib/codegen/utils/merge.js +9 -9
  23. package/lib/compilerOptions.js +1 -0
  24. package/lib/plugins/vue-root-tags.js +9 -9
  25. package/lib/plugins/vue-sfc-customblocks.js +4 -4
  26. package/lib/plugins/vue-sfc-scripts.js +8 -8
  27. package/lib/plugins/vue-sfc-styles.js +5 -5
  28. package/lib/plugins/vue-sfc-template.js +7 -7
  29. package/lib/plugins/vue-template-inline-css.js +6 -6
  30. package/lib/plugins/vue-template-inline-ts.js +12 -12
  31. package/lib/plugins/vue-tsx.d.ts +2 -2
  32. package/lib/plugins/vue-tsx.js +35 -35
  33. package/lib/types.d.ts +54 -48
  34. package/lib/utils/parseSfc.js +0 -1
  35. package/lib/utils/shared.d.ts +2 -2
  36. package/lib/virtualCode/embeddedCodes.d.ts +2 -2
  37. package/lib/virtualCode/embeddedCodes.js +11 -11
  38. package/lib/virtualCode/index.d.ts +4 -2
  39. package/lib/virtualCode/index.js +4 -0
  40. package/lib/virtualCode/ir.d.ts +2 -2
  41. package/package.json +2 -2
  42. package/types/template-helpers.d.ts +1 -0
@@ -3,22 +3,22 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateIntersectMerge = generateIntersectMerge;
4
4
  exports.generateSpreadMerge = generateSpreadMerge;
5
5
  const index_1 = require("./index");
6
- function* generateIntersectMerge(generates) {
7
- yield* generates[0];
8
- for (let i = 1; i < generates.length; i++) {
6
+ function* generateIntersectMerge(...codes) {
7
+ yield codes[0];
8
+ for (let i = 1; i < codes.length; i++) {
9
9
  yield ` & `;
10
- yield* generates[i];
10
+ yield codes[i];
11
11
  }
12
12
  }
13
- function* generateSpreadMerge(generates) {
14
- if (generates.length === 1) {
15
- yield* generates[0];
13
+ function* generateSpreadMerge(...codes) {
14
+ if (codes.length <= 1) {
15
+ yield* codes;
16
16
  }
17
17
  else {
18
18
  yield `{${index_1.newLine}`;
19
- for (const generate of generates) {
19
+ for (const code of codes) {
20
20
  yield `...`;
21
- yield* generate;
21
+ yield code;
22
22
  yield `,${index_1.newLine}`;
23
23
  }
24
24
  yield `}`;
@@ -211,6 +211,7 @@ function getDefaultCompilerOptions(target = 99, lib = 'vue', strictTemplates = f
211
211
  inferTemplateDollarSlots: false,
212
212
  skipTemplateCodegen: false,
213
213
  fallthroughAttributes: false,
214
+ checkRequiredFallthroughAttributes: false,
214
215
  resolveStyleImports: false,
215
216
  resolveStyleClassNames: 'scoped',
216
217
  fallthroughComponentNames: [
@@ -11,27 +11,27 @@ const plugin = () => {
11
11
  lang: 'vue-root-tags',
12
12
  }];
13
13
  },
14
- resolveEmbeddedCode(_fileName, sfc, embeddedFile) {
14
+ resolveEmbeddedCode(_fileName, ir, embeddedFile) {
15
15
  if (embeddedFile.id === 'root_tags') {
16
- embeddedFile.content.push([sfc.content, undefined, 0, shared_1.allCodeFeatures]);
16
+ embeddedFile.content.push([ir.content, undefined, 0, shared_1.allCodeFeatures]);
17
17
  for (const block of [
18
- sfc.template,
19
- sfc.script,
20
- sfc.scriptSetup,
21
- ...sfc.styles,
22
- ...sfc.customBlocks,
18
+ ir.template,
19
+ ir.script,
20
+ ir.scriptSetup,
21
+ ...ir.styles,
22
+ ...ir.customBlocks,
23
23
  ]) {
24
24
  if (!block) {
25
25
  continue;
26
26
  }
27
27
  const offset = block.content.lastIndexOf('\n', block.content.lastIndexOf('\n') - 1) + 1;
28
28
  // fix folding range end position failed to mapping
29
- (0, muggle_string_1.replaceSourceRange)(embeddedFile.content, undefined, block.startTagEnd, block.endTagStart, sfc.content.slice(block.startTagEnd, block.startTagEnd + offset), [
29
+ (0, muggle_string_1.replaceSourceRange)(embeddedFile.content, undefined, block.startTagEnd, block.endTagStart, ir.content.slice(block.startTagEnd, block.startTagEnd + offset), [
30
30
  '',
31
31
  undefined,
32
32
  block.startTagEnd + offset,
33
33
  { structure: true },
34
- ], sfc.content.slice(block.startTagEnd + offset, block.endTagStart));
34
+ ], ir.content.slice(block.startTagEnd + offset, block.endTagStart));
35
35
  }
36
36
  }
37
37
  else {
@@ -4,16 +4,16 @@ const shared_1 = require("./shared");
4
4
  const plugin = () => {
5
5
  return {
6
6
  version: 2.2,
7
- getEmbeddedCodes(_fileName, sfc) {
8
- return sfc.customBlocks.map((customBlock, i) => ({
7
+ getEmbeddedCodes(_fileName, ir) {
8
+ return ir.customBlocks.map((customBlock, i) => ({
9
9
  id: 'custom_block_' + i,
10
10
  lang: customBlock.lang,
11
11
  }));
12
12
  },
13
- resolveEmbeddedCode(_fileName, sfc, embeddedFile) {
13
+ resolveEmbeddedCode(_fileName, ir, embeddedFile) {
14
14
  if (embeddedFile.id.startsWith('custom_block_')) {
15
15
  const index = parseInt(embeddedFile.id.slice('custom_block_'.length));
16
- const customBlock = sfc.customBlocks[index];
16
+ const customBlock = ir.customBlocks[index];
17
17
  embeddedFile.content.push([
18
18
  customBlock.content,
19
19
  customBlock.name,
@@ -3,21 +3,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const plugin = () => {
4
4
  return {
5
5
  version: 2.2,
6
- getEmbeddedCodes(_fileName, sfc) {
6
+ getEmbeddedCodes(_fileName, ir) {
7
7
  const names = [];
8
- if (sfc.script) {
9
- names.push({ id: 'script_raw', lang: sfc.script.lang });
8
+ if (ir.script) {
9
+ names.push({ id: 'script_raw', lang: ir.script.lang });
10
10
  }
11
- if (sfc.scriptSetup) {
12
- names.push({ id: 'scriptsetup_raw', lang: sfc.scriptSetup.lang });
11
+ if (ir.scriptSetup) {
12
+ names.push({ id: 'scriptsetup_raw', lang: ir.scriptSetup.lang });
13
13
  }
14
14
  return names;
15
15
  },
16
- resolveEmbeddedCode(_fileName, sfc, embeddedFile) {
16
+ resolveEmbeddedCode(_fileName, ir, embeddedFile) {
17
17
  const script = embeddedFile.id === 'script_raw'
18
- ? sfc.script
18
+ ? ir.script
19
19
  : embeddedFile.id === 'scriptsetup_raw'
20
- ? sfc.scriptSetup
20
+ ? ir.scriptSetup
21
21
  : undefined;
22
22
  if (script) {
23
23
  embeddedFile.content.push([
@@ -4,10 +4,10 @@ const shared_1 = require("./shared");
4
4
  const plugin = () => {
5
5
  return {
6
6
  version: 2.2,
7
- getEmbeddedCodes(_fileName, sfc) {
7
+ getEmbeddedCodes(_fileName, ir) {
8
8
  const result = [];
9
- for (let i = 0; i < sfc.styles.length; i++) {
10
- const style = sfc.styles[i];
9
+ for (let i = 0; i < ir.styles.length; i++) {
10
+ const style = ir.styles[i];
11
11
  if (style) {
12
12
  result.push({
13
13
  id: 'style_' + i,
@@ -23,10 +23,10 @@ const plugin = () => {
23
23
  }
24
24
  return result;
25
25
  },
26
- resolveEmbeddedCode(_fileName, sfc, embeddedFile) {
26
+ resolveEmbeddedCode(_fileName, ir, embeddedFile) {
27
27
  if (embeddedFile.id.startsWith('style_')) {
28
28
  const index = parseInt(embeddedFile.id.split('_')[1]);
29
- const style = sfc.styles[index];
29
+ const style = ir.styles[index];
30
30
  if (embeddedFile.id.endsWith('_inline_ts')) {
31
31
  embeddedFile.parentCodeId = 'style_' + index;
32
32
  for (const binding of style.bindings) {
@@ -4,20 +4,20 @@ const shared_1 = require("./shared");
4
4
  const plugin = () => {
5
5
  return {
6
6
  version: 2.2,
7
- getEmbeddedCodes(_fileName, sfc) {
8
- if (sfc.template?.lang === 'html') {
7
+ getEmbeddedCodes(_fileName, ir) {
8
+ if (ir.template?.lang === 'html') {
9
9
  return [{
10
10
  id: 'template',
11
- lang: sfc.template.lang,
11
+ lang: ir.template.lang,
12
12
  }];
13
13
  }
14
14
  return [];
15
15
  },
16
- resolveEmbeddedCode(_fileName, sfc, embeddedFile) {
17
- if (embeddedFile.id === 'template' && sfc.template?.lang === 'html') {
16
+ resolveEmbeddedCode(_fileName, ir, embeddedFile) {
17
+ if (embeddedFile.id === 'template' && ir.template?.lang === 'html') {
18
18
  embeddedFile.content.push([
19
- sfc.template.content,
20
- sfc.template.name,
19
+ ir.template.content,
20
+ ir.template.name,
21
21
  0,
22
22
  shared_1.allCodeFeatures,
23
23
  ]);
@@ -45,18 +45,18 @@ const codeFeatures = {
45
45
  const plugin = () => {
46
46
  return {
47
47
  version: 2.2,
48
- getEmbeddedCodes(_fileName, sfc) {
49
- if (!sfc.template?.ast) {
48
+ getEmbeddedCodes(_fileName, ir) {
49
+ if (!ir.template?.ast) {
50
50
  return [];
51
51
  }
52
52
  return [{ id: 'template_inline_css', lang: 'css' }];
53
53
  },
54
- resolveEmbeddedCode(_fileName, sfc, embeddedFile) {
55
- if (embeddedFile.id !== 'template_inline_css' || !sfc.template?.ast) {
54
+ resolveEmbeddedCode(_fileName, ir, embeddedFile) {
55
+ if (embeddedFile.id !== 'template_inline_css' || !ir.template?.ast) {
56
56
  return;
57
57
  }
58
- embeddedFile.parentCodeId = sfc.template.lang === 'md' ? 'root_tags' : 'template';
59
- embeddedFile.content.push(...generate(sfc.template.ast));
58
+ embeddedFile.parentCodeId = ir.template.lang === 'md' ? 'root_tags' : 'template';
59
+ embeddedFile.content.push(...generate(ir.template.ast));
60
60
  },
61
61
  };
62
62
  };
@@ -57,42 +57,42 @@ const plugin = ({ modules: { typescript: ts } }) => {
57
57
  const parseds = new WeakMap();
58
58
  return {
59
59
  version: 2.2,
60
- getEmbeddedCodes(_fileName, sfc) {
61
- if (!sfc.template?.ast) {
60
+ getEmbeddedCodes(_fileName, ir) {
61
+ if (!ir.template?.ast) {
62
62
  return [];
63
63
  }
64
- const parsed = parse(sfc);
65
- parseds.set(sfc, parsed);
64
+ const parsed = parse(ir);
65
+ parseds.set(ir, parsed);
66
66
  const result = [];
67
67
  for (const [id] of parsed) {
68
68
  result.push({ id, lang: 'ts' });
69
69
  }
70
70
  return result;
71
71
  },
72
- resolveEmbeddedCode(_fileName, sfc, embeddedFile) {
72
+ resolveEmbeddedCode(_fileName, ir, embeddedFile) {
73
73
  if (!embeddedFile.id.startsWith('template_inline_ts_')) {
74
74
  return;
75
75
  }
76
76
  // access template content to watch change
77
- void sfc.template?.content;
78
- const parsed = parseds.get(sfc);
77
+ void ir.template?.content;
78
+ const parsed = parseds.get(ir);
79
79
  if (parsed) {
80
80
  const codes = parsed.get(embeddedFile.id);
81
81
  if (codes) {
82
82
  embeddedFile.content.push(...codes);
83
- embeddedFile.parentCodeId = sfc.template?.lang === 'md' ? 'root_tags' : 'template';
83
+ embeddedFile.parentCodeId = ir.template?.lang === 'md' ? 'root_tags' : 'template';
84
84
  }
85
85
  }
86
86
  },
87
87
  };
88
- function parse(sfc) {
88
+ function parse(ir) {
89
89
  const result = new Map();
90
- if (!sfc.template?.ast) {
90
+ if (!ir.template?.ast) {
91
91
  return result;
92
92
  }
93
- const template = sfc.template;
93
+ const template = ir.template;
94
94
  let i = 0;
95
- sfc.template.ast.children.forEach(visit);
95
+ ir.template.ast.children.forEach(visit);
96
96
  return result;
97
97
  function visit(node) {
98
98
  if (node.type === CompilerDOM.NodeTypes.COMMENT) {
@@ -1,5 +1,5 @@
1
- import type { Sfc, VueLanguagePlugin } from '../types';
2
- export declare const tsCodegen: WeakMap<Sfc, {
1
+ import type { IR, VueLanguagePlugin } from '../types';
2
+ export declare const tsCodegen: WeakMap<IR, {
3
3
  getScriptRanges: () => {
4
4
  exportDefault: (import("../types").TextRange<import("typescript").Node> & {
5
5
  expression: import("../types").TextRange<import("typescript").Expression>;
@@ -50,29 +50,29 @@ const validLangs = new Set(['js', 'jsx', 'ts', 'tsx']);
50
50
  const plugin = ({ modules: { typescript: ts }, vueCompilerOptions, }) => {
51
51
  return {
52
52
  version: 2.2,
53
- getEmbeddedCodes(_fileName, sfc) {
54
- const lang = computeLang(sfc);
53
+ getEmbeddedCodes(_fileName, ir) {
54
+ const lang = computeLang(ir);
55
55
  return [{ lang, id: 'script_' + lang }];
56
56
  },
57
- resolveEmbeddedCode(fileName, sfc, embeddedFile) {
57
+ resolveEmbeddedCode(fileName, ir, embeddedFile) {
58
58
  if (/script_(js|jsx|ts|tsx)/.test(embeddedFile.id)) {
59
- let codegen = exports.tsCodegen.get(sfc);
59
+ let codegen = exports.tsCodegen.get(ir);
60
60
  if (!codegen) {
61
- exports.tsCodegen.set(sfc, codegen = useCodegen(ts, vueCompilerOptions, fileName, sfc));
61
+ exports.tsCodegen.set(ir, codegen = useCodegen(ts, vueCompilerOptions, fileName, ir));
62
62
  }
63
63
  const generatedScript = codegen.getGeneratedScript();
64
64
  embeddedFile.content = [...generatedScript.codes];
65
65
  }
66
66
  },
67
67
  };
68
- function computeLang(sfc) {
69
- let lang = sfc.scriptSetup?.lang ?? sfc.script?.lang;
70
- if (sfc.script && sfc.scriptSetup) {
71
- if (sfc.scriptSetup.lang !== 'js') {
72
- lang = sfc.scriptSetup.lang;
68
+ function computeLang(ir) {
69
+ let lang = ir.scriptSetup?.lang ?? ir.script?.lang;
70
+ if (ir.script && ir.scriptSetup) {
71
+ if (ir.scriptSetup.lang !== 'js') {
72
+ lang = ir.scriptSetup.lang;
73
73
  }
74
74
  else {
75
- lang = sfc.script.lang;
75
+ lang = ir.script.lang;
76
76
  }
77
77
  }
78
78
  if (lang && validLangs.has(lang)) {
@@ -82,9 +82,9 @@ const plugin = ({ modules: { typescript: ts }, vueCompilerOptions, }) => {
82
82
  }
83
83
  };
84
84
  exports.default = plugin;
85
- function useCodegen(ts, vueCompilerOptions, fileName, sfc) {
85
+ function useCodegen(ts, vueCompilerOptions, fileName, ir) {
86
86
  const getResolvedOptions = (0, alien_signals_1.computed)(() => {
87
- const options = (0, vueCompilerOptions_1.parseVueCompilerOptions)(sfc.comments);
87
+ const options = (0, vueCompilerOptions_1.parseVueCompilerOptions)(ir.comments);
88
88
  if (options) {
89
89
  const resolver = new compilerOptions_1.CompilerOptionsResolver(ts, () => undefined /* does not support resolving target="auto" */);
90
90
  resolver.addConfig(options, path.dirname(fileName));
@@ -92,23 +92,23 @@ function useCodegen(ts, vueCompilerOptions, fileName, sfc) {
92
92
  }
93
93
  return vueCompilerOptions;
94
94
  });
95
- const getScriptRanges = (0, alien_signals_1.computed)(() => sfc.script && validLangs.has(sfc.script.lang)
96
- ? (0, scriptRanges_1.parseScriptRanges)(ts, sfc.script.ast, getResolvedOptions())
95
+ const getScriptRanges = (0, alien_signals_1.computed)(() => ir.script && validLangs.has(ir.script.lang)
96
+ ? (0, scriptRanges_1.parseScriptRanges)(ts, ir.script.ast, getResolvedOptions())
97
97
  : undefined);
98
- const getScriptSetupRanges = (0, alien_signals_1.computed)(() => sfc.scriptSetup && validLangs.has(sfc.scriptSetup.lang)
99
- ? (0, scriptSetupRanges_1.parseScriptSetupRanges)(ts, sfc.scriptSetup.ast, getResolvedOptions())
98
+ const getScriptSetupRanges = (0, alien_signals_1.computed)(() => ir.scriptSetup && validLangs.has(ir.scriptSetup.lang)
99
+ ? (0, scriptSetupRanges_1.parseScriptSetupRanges)(ts, ir.scriptSetup.ast, getResolvedOptions())
100
100
  : undefined);
101
101
  const getImportedComponents = (0, signals_1.computedSet)(() => {
102
102
  const names = new Set();
103
103
  const scriptSetupRanges = getScriptSetupRanges();
104
- if (sfc.scriptSetup && scriptSetupRanges) {
104
+ if (ir.scriptSetup && scriptSetupRanges) {
105
105
  for (const range of scriptSetupRanges.components) {
106
- names.add(sfc.scriptSetup.content.slice(range.start, range.end));
106
+ names.add(ir.scriptSetup.content.slice(range.start, range.end));
107
107
  }
108
108
  const scriptRange = getScriptRanges();
109
- if (sfc.script && scriptRange) {
109
+ if (ir.script && scriptRange) {
110
110
  for (const range of scriptRange.components) {
111
- names.add(sfc.script.content.slice(range.start, range.end));
111
+ names.add(ir.script.content.slice(range.start, range.end));
112
112
  }
113
113
  }
114
114
  }
@@ -142,12 +142,12 @@ function useCodegen(ts, vueCompilerOptions, fileName, sfc) {
142
142
  const getComponentName = (0, alien_signals_1.computed)(() => {
143
143
  let name;
144
144
  const componentOptions = getScriptRanges()?.exportDefault?.options;
145
- if (sfc.script && componentOptions?.name) {
146
- name = sfc.script.content.slice(componentOptions.name.start + 1, componentOptions.name.end - 1);
145
+ if (ir.script && componentOptions?.name) {
146
+ name = ir.script.content.slice(componentOptions.name.start + 1, componentOptions.name.end - 1);
147
147
  }
148
148
  else {
149
149
  const { defineOptions } = getScriptSetupRanges() ?? {};
150
- if (sfc.scriptSetup && defineOptions?.name) {
150
+ if (ir.scriptSetup && defineOptions?.name) {
151
151
  name = defineOptions.name;
152
152
  }
153
153
  else {
@@ -158,13 +158,13 @@ function useCodegen(ts, vueCompilerOptions, fileName, sfc) {
158
158
  return (0, shared_1.capitalize)((0, shared_1.camelize)(name));
159
159
  });
160
160
  const getGeneratedTemplate = (0, alien_signals_1.computed)(() => {
161
- if (getResolvedOptions().skipTemplateCodegen || !sfc.template) {
161
+ if (getResolvedOptions().skipTemplateCodegen || !ir.template) {
162
162
  return;
163
163
  }
164
164
  return (0, template_1.generateTemplate)({
165
165
  typescript: ts,
166
166
  vueCompilerOptions: getResolvedOptions(),
167
- template: sfc.template,
167
+ template: ir.template,
168
168
  componentName: getComponentName(),
169
169
  setupConsts: getSetupConsts(),
170
170
  setupRefs: getSetupRefs(),
@@ -175,13 +175,13 @@ function useCodegen(ts, vueCompilerOptions, fileName, sfc) {
175
175
  });
176
176
  });
177
177
  const getGeneratedStyle = (0, alien_signals_1.computed)(() => {
178
- if (!sfc.styles.length) {
178
+ if (!ir.styles.length) {
179
179
  return;
180
180
  }
181
181
  return (0, style_1.generateStyle)({
182
182
  typescript: ts,
183
183
  vueCompilerOptions: getResolvedOptions(),
184
- styles: sfc.styles,
184
+ styles: ir.styles,
185
185
  setupConsts: getSetupConsts(),
186
186
  setupRefs: getSetupRefs(),
187
187
  });
@@ -189,17 +189,17 @@ function useCodegen(ts, vueCompilerOptions, fileName, sfc) {
189
189
  const getSetupExposed = (0, signals_1.computedSet)(() => {
190
190
  const allVars = new Set();
191
191
  const scriptSetupRanges = getScriptSetupRanges();
192
- if (!sfc.scriptSetup || !scriptSetupRanges) {
192
+ if (!ir.scriptSetup || !scriptSetupRanges) {
193
193
  return allVars;
194
194
  }
195
195
  for (const range of scriptSetupRanges.bindings) {
196
- const name = sfc.scriptSetup.content.slice(range.start, range.end);
196
+ const name = ir.scriptSetup.content.slice(range.start, range.end);
197
197
  allVars.add(name);
198
198
  }
199
199
  const scriptRanges = getScriptRanges();
200
- if (sfc.script && scriptRanges) {
200
+ if (ir.script && scriptRanges) {
201
201
  for (const range of scriptRanges.bindings) {
202
- const name = sfc.script.content.slice(range.start, range.end);
202
+ const name = ir.script.content.slice(range.start, range.end);
203
203
  allVars.add(name);
204
204
  }
205
205
  }
@@ -209,15 +209,15 @@ function useCodegen(ts, vueCompilerOptions, fileName, sfc) {
209
209
  return new Set([
210
210
  ...getGeneratedTemplate()?.componentAccessMap.keys() ?? [],
211
211
  ...getGeneratedStyle()?.componentAccessMap.keys() ?? [],
212
- ...sfc.template?.ast?.components.flatMap(name => [(0, shared_1.camelize)(name), (0, shared_1.capitalize)((0, shared_1.camelize)(name))]) ?? [],
212
+ ...ir.template?.ast?.components.flatMap(name => [(0, shared_1.camelize)(name), (0, shared_1.capitalize)((0, shared_1.camelize)(name))]) ?? [],
213
213
  ].filter(name => allVars.has(name)));
214
214
  });
215
215
  const getGeneratedScript = (0, alien_signals_1.computed)(() => {
216
216
  return (0, script_1.generateScript)({
217
217
  vueCompilerOptions: getResolvedOptions(),
218
218
  fileName,
219
- script: sfc.script,
220
- scriptSetup: sfc.scriptSetup,
219
+ script: ir.script,
220
+ scriptSetup: ir.scriptSetup,
221
221
  exposed: getSetupExposed(),
222
222
  scriptRanges: getScriptRanges(),
223
223
  scriptSetupRanges: getScriptSetupRanges(),
package/lib/types.d.ts CHANGED
@@ -16,6 +16,7 @@ export type RawPlugin = string | (Record<string, any> & {
16
16
  });
17
17
  export interface VueCodeInformation extends CodeInformation {
18
18
  __importCompletion?: boolean;
19
+ __propsCompletion?: boolean;
19
20
  __shorthandExpression?: 'html' | 'js';
20
21
  __combineToken?: symbol;
21
22
  __linkedToken?: symbol;
@@ -43,6 +44,7 @@ export interface VueCompilerOptions {
43
44
  inferTemplateDollarSlots: boolean;
44
45
  skipTemplateCodegen: boolean;
45
46
  fallthroughAttributes: boolean;
47
+ checkRequiredFallthroughAttributes: boolean;
46
48
  resolveStyleImports: boolean;
47
49
  resolveStyleClassNames: boolean | 'scoped';
48
50
  fallthroughComponentNames: string[];
@@ -85,17 +87,17 @@ export interface VueLanguagePluginReturn {
85
87
  resolveTemplateCompilerOptions?(options: CompilerDOM.CompilerOptions): CompilerDOM.CompilerOptions;
86
88
  compileSFCScript?(lang: string, script: string): ts.SourceFile | undefined;
87
89
  compileSFCTemplate?(lang: string, template: string, options: CompilerDOM.CompilerOptions): CompilerDOM.CodegenResult | undefined;
88
- compileSFCStyle?(lang: string, style: string): Pick<Sfc['styles'][number], 'imports' | 'bindings' | 'classNames'> | undefined;
90
+ compileSFCStyle?(lang: string, style: string): Pick<IRStyle, 'imports' | 'bindings' | 'classNames'> | undefined;
89
91
  updateSFCTemplate?(oldResult: CompilerDOM.CodegenResult, textChange: {
90
92
  start: number;
91
93
  end: number;
92
94
  newText: string;
93
95
  }): CompilerDOM.CodegenResult | undefined;
94
- getEmbeddedCodes?(fileName: string, sfc: Sfc): {
96
+ getEmbeddedCodes?(fileName: string, ir: IR): {
95
97
  id: string;
96
98
  lang: string;
97
99
  }[];
98
- resolveEmbeddedCode?(fileName: string, sfc: Sfc, embeddedFile: VueEmbeddedCode): void;
100
+ resolveEmbeddedCode?(fileName: string, ir: IR, embeddedFile: VueEmbeddedCode): void;
99
101
  }
100
102
  export type VueLanguagePlugin<T extends Record<string, any> = {}> = (ctx: {
101
103
  modules: {
@@ -107,7 +109,20 @@ export type VueLanguagePlugin<T extends Record<string, any> = {}> = (ctx: {
107
109
  vueCompilerOptions: VueCompilerOptions;
108
110
  config: T;
109
111
  }) => VueLanguagePluginReturn | VueLanguagePluginReturn[];
110
- export interface SfcBlock {
112
+ export interface IR {
113
+ content: string;
114
+ comments: string[];
115
+ template: IRTemplate | undefined;
116
+ script: IRScript | undefined;
117
+ scriptSetup: IRScriptSetup | undefined;
118
+ styles: readonly IRStyle[];
119
+ customBlocks: readonly IRCustomBlock[];
120
+ }
121
+ export type IRAttr = true | {
122
+ text: string;
123
+ offset: number;
124
+ };
125
+ export interface IRBlock {
111
126
  name: string;
112
127
  start: number;
113
128
  end: number;
@@ -117,57 +132,48 @@ export interface SfcBlock {
117
132
  content: string;
118
133
  attrs: Record<string, string | true>;
119
134
  }
120
- export type SfcBlockAttr = true | {
121
- text: string;
122
- offset: number;
123
- quotes: boolean;
124
- };
125
- export interface Sfc {
126
- content: string;
127
- comments: string[];
128
- template: (SfcBlock & {
129
- ast: CompilerDOM.RootNode | undefined;
130
- errors: CompilerDOM.CompilerError[];
131
- warnings: CompilerDOM.CompilerError[];
132
- }) | undefined;
133
- script: (SfcBlock & {
134
- src: SfcBlockAttr | undefined;
135
- ast: ts.SourceFile;
136
- }) | undefined;
137
- scriptSetup: (SfcBlock & {
138
- generic: SfcBlockAttr | undefined;
139
- ast: ts.SourceFile;
140
- }) | undefined;
141
- styles: readonly (SfcBlock & {
142
- src: SfcBlockAttr | undefined;
143
- module: SfcBlockAttr | undefined;
144
- scoped: boolean;
145
- imports: {
146
- text: string;
147
- offset: number;
148
- }[];
149
- bindings: {
150
- text: string;
151
- offset: number;
152
- }[];
153
- classNames: {
154
- text: string;
155
- offset: number;
156
- }[];
157
- })[];
158
- customBlocks: readonly (SfcBlock & {
159
- type: string;
160
- })[];
135
+ export interface IRTemplate extends IRBlock {
136
+ ast: CompilerDOM.RootNode | undefined;
137
+ errors: CompilerDOM.CompilerError[];
138
+ warnings: CompilerDOM.CompilerError[];
139
+ }
140
+ export interface IRScript extends IRBlock {
141
+ src: IRAttr | undefined;
142
+ ast: ts.SourceFile;
143
+ }
144
+ export interface IRScriptSetup extends IRBlock {
145
+ generic: IRAttr | undefined;
146
+ ast: ts.SourceFile;
147
+ }
148
+ export interface IRStyle extends IRBlock {
149
+ src: IRAttr | undefined;
150
+ module: IRAttr | undefined;
151
+ scoped: boolean;
152
+ imports: {
153
+ text: string;
154
+ offset: number;
155
+ }[];
156
+ bindings: {
157
+ text: string;
158
+ offset: number;
159
+ }[];
160
+ classNames: {
161
+ text: string;
162
+ offset: number;
163
+ }[];
164
+ }
165
+ export interface IRCustomBlock extends IRBlock {
166
+ type: string;
161
167
  }
162
168
  declare module '@vue/compiler-sfc' {
163
169
  interface SFCBlock {
164
- __src?: SfcBlockAttr;
170
+ __src?: IRAttr;
165
171
  }
166
172
  interface SFCScriptBlock {
167
- __generic?: SfcBlockAttr;
173
+ __generic?: IRAttr;
168
174
  }
169
175
  interface SFCStyleBlock {
170
- __module?: SfcBlockAttr;
176
+ __module?: IRAttr;
171
177
  }
172
178
  }
173
179
  export interface TextRange<Node extends ts.Node = ts.Node> {
@@ -179,7 +179,6 @@ function parseAttr(p, node) {
179
179
  return {
180
180
  text: content,
181
181
  offset: offset - node.loc.start.offset,
182
- quotes: offset > p.value.loc.start.offset,
183
182
  };
184
183
  }
185
184
  //# sourceMappingURL=parseSfc.js.map
@@ -1,9 +1,9 @@
1
1
  import type * as CompilerDOM from '@vue/compiler-dom';
2
2
  import type * as ts from 'typescript';
3
- import type { Sfc, TextRange } from '../types';
3
+ import type { IRTemplate, TextRange } from '../types';
4
4
  export { hyphenate as hyphenateTag } from '@vue/shared';
5
5
  export declare function hyphenateAttr(str: string): string;
6
6
  export declare function normalizeAttributeValue(node: CompilerDOM.TextNode): readonly [string, number];
7
- export declare function getElementTagOffsets(node: CompilerDOM.ElementNode, template: NonNullable<Sfc['template']>): [number] | [number, number];
7
+ export declare function getElementTagOffsets(node: CompilerDOM.ElementNode, template: IRTemplate): [number] | [number, number];
8
8
  export declare function getStartEnd<T extends ts.Node>(ts: typeof import('typescript'), node: T, ast: ts.SourceFile): TextRange<T>;
9
9
  export declare function getNodeText(ts: typeof import('typescript'), node: ts.Node, ast: ts.SourceFile): string;
@@ -1,5 +1,5 @@
1
1
  import type { Mapping, VirtualCode } from '@volar/language-core';
2
- import type { Code, Sfc, VueLanguagePluginReturn } from '../types';
2
+ import type { Code, IR, VueLanguagePluginReturn } from '../types';
3
3
  export declare class VueEmbeddedCode {
4
4
  id: string;
5
5
  lang: string;
@@ -9,4 +9,4 @@ export declare class VueEmbeddedCode {
9
9
  embeddedCodes: VueEmbeddedCode[];
10
10
  constructor(id: string, lang: string, content: Code[]);
11
11
  }
12
- export declare function useEmbeddedCodes(plugins: VueLanguagePluginReturn[], fileName: string, sfc: Sfc): () => VirtualCode[];
12
+ export declare function useEmbeddedCodes(plugins: VueLanguagePluginReturn[], fileName: string, ir: IR): () => VirtualCode[];