@vue/language-core 1.9.0-alpha.3 → 2.0.1

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 (93) hide show
  1. package/index.d.ts +13 -0
  2. package/{out/index.js → index.js} +12 -14
  3. package/lib/generators/script.d.ts +13 -0
  4. package/lib/generators/script.js +1060 -0
  5. package/lib/generators/template.d.ts +9 -0
  6. package/lib/generators/template.js +1567 -0
  7. package/lib/generators/utils.d.ts +6 -0
  8. package/lib/generators/utils.js +58 -0
  9. package/lib/languageModule.d.ts +5 -0
  10. package/lib/languageModule.js +114 -0
  11. package/{out → lib}/parsers/scriptRanges.d.ts +2 -3
  12. package/{out → lib}/parsers/scriptRanges.js +11 -6
  13. package/{out → lib}/parsers/scriptSetupRanges.d.ts +17 -9
  14. package/{out → lib}/parsers/scriptSetupRanges.js +42 -35
  15. package/lib/plugins/file-html.d.ts +3 -0
  16. package/{out → lib}/plugins/file-html.js +1 -1
  17. package/lib/plugins/file-md.d.ts +3 -0
  18. package/{out → lib}/plugins/file-md.js +8 -8
  19. package/lib/plugins/file-vue.d.ts +3 -0
  20. package/{out → lib}/plugins/file-vue.js +9 -2
  21. package/lib/plugins/vue-sfc-customblocks.d.ts +3 -0
  22. package/lib/plugins/vue-sfc-customblocks.js +28 -0
  23. package/lib/plugins/vue-sfc-scripts.d.ts +3 -0
  24. package/lib/plugins/vue-sfc-scripts.js +36 -0
  25. package/lib/plugins/vue-sfc-styles.d.ts +3 -0
  26. package/lib/plugins/vue-sfc-styles.js +28 -0
  27. package/lib/plugins/vue-sfc-template.d.ts +3 -0
  28. package/lib/plugins/vue-sfc-template.js +29 -0
  29. package/lib/plugins/vue-template-html.d.ts +3 -0
  30. package/{out → lib}/plugins/vue-template-html.js +12 -12
  31. package/{out → lib}/plugins/vue-tsx.d.ts +25 -18
  32. package/lib/plugins/vue-tsx.js +212 -0
  33. package/{out → lib}/plugins.d.ts +19 -7
  34. package/{out → lib}/plugins.js +24 -18
  35. package/{out → lib}/types.d.ts +26 -9
  36. package/lib/types.js +5 -0
  37. package/{out → lib}/utils/parseCssClassNames.d.ts +0 -1
  38. package/{out → lib}/utils/parseCssVars.d.ts +0 -1
  39. package/{out → lib}/utils/parseSfc.d.ts +0 -1
  40. package/{out → lib}/utils/parseSfc.js +4 -18
  41. package/{out → lib}/utils/shared.d.ts +0 -1
  42. package/lib/utils/transform.d.ts +8 -0
  43. package/{out → lib}/utils/transform.js +62 -62
  44. package/{out → lib}/utils/ts.d.ts +3 -4
  45. package/{out → lib}/utils/ts.js +0 -12
  46. package/lib/utils/vue2TemplateCompiler.d.ts +2 -0
  47. package/{out → lib}/utils/vue2TemplateCompiler.js +5 -2
  48. package/{out → lib}/virtualFile/computedFiles.d.ts +2 -3
  49. package/{out → lib}/virtualFile/computedFiles.js +55 -42
  50. package/lib/virtualFile/computedMappings.d.ts +4 -0
  51. package/{out → lib}/virtualFile/computedMappings.js +9 -12
  52. package/lib/virtualFile/computedSfc.d.ts +4 -0
  53. package/{out → lib}/virtualFile/computedSfc.js +3 -3
  54. package/{out → lib}/virtualFile/computedVueSfc.d.ts +2 -3
  55. package/lib/virtualFile/embeddedFile.d.ts +12 -0
  56. package/lib/virtualFile/embeddedFile.js +15 -0
  57. package/lib/virtualFile/vueFile.d.ts +25 -0
  58. package/{out → lib}/virtualFile/vueFile.js +11 -21
  59. package/package.json +8 -11
  60. package/out/generators/script.d.ts +0 -15
  61. package/out/generators/script.js +0 -887
  62. package/out/generators/template.d.ts +0 -21
  63. package/out/generators/template.js +0 -1506
  64. package/out/index.d.ts +0 -16
  65. package/out/languageModule.d.ts +0 -10
  66. package/out/languageModule.js +0 -99
  67. package/out/plugins/file-html.d.ts +0 -4
  68. package/out/plugins/file-md.d.ts +0 -4
  69. package/out/plugins/file-vue.d.ts +0 -4
  70. package/out/plugins/vue-sfc-customblocks.d.ts +0 -4
  71. package/out/plugins/vue-sfc-customblocks.js +0 -33
  72. package/out/plugins/vue-sfc-scripts.d.ts +0 -4
  73. package/out/plugins/vue-sfc-scripts.js +0 -42
  74. package/out/plugins/vue-sfc-styles.d.ts +0 -4
  75. package/out/plugins/vue-sfc-styles.js +0 -33
  76. package/out/plugins/vue-sfc-template.d.ts +0 -4
  77. package/out/plugins/vue-sfc-template.js +0 -29
  78. package/out/plugins/vue-template-html.d.ts +0 -4
  79. package/out/plugins/vue-tsx.js +0 -159
  80. package/out/types.js +0 -3
  81. package/out/utils/globalTypes.d.ts +0 -4
  82. package/out/utils/globalTypes.js +0 -135
  83. package/out/utils/transform.d.ts +0 -9
  84. package/out/utils/vue2TemplateCompiler.d.ts +0 -3
  85. package/out/virtualFile/computedMappings.d.ts +0 -6
  86. package/out/virtualFile/computedSfc.d.ts +0 -5
  87. package/out/virtualFile/embeddedFile.d.ts +0 -13
  88. package/out/virtualFile/embeddedFile.js +0 -16
  89. package/out/virtualFile/vueFile.d.ts +0 -28
  90. /package/{out → lib}/utils/parseCssClassNames.js +0 -0
  91. /package/{out → lib}/utils/parseCssVars.js +0 -0
  92. /package/{out → lib}/utils/shared.js +0 -0
  93. /package/{out → lib}/virtualFile/computedVueSfc.js +0 -0
@@ -0,0 +1,6 @@
1
+ import type { Code, CodeAndStack, VueCodeInformation } from '../types';
2
+ export declare function withStack(code: Code): CodeAndStack;
3
+ export declare function getStack(): string;
4
+ export declare function disableAllFeatures(override: Partial<VueCodeInformation>): VueCodeInformation;
5
+ export declare function enableAllFeatures(override: Partial<VueCodeInformation>): VueCodeInformation;
6
+ export declare function mergeFeatureSettings(base: VueCodeInformation, ...others: Partial<VueCodeInformation>[]): VueCodeInformation;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mergeFeatureSettings = exports.enableAllFeatures = exports.disableAllFeatures = exports.getStack = exports.withStack = void 0;
4
+ function withStack(code) {
5
+ return [code, getStack()];
6
+ }
7
+ exports.withStack = withStack;
8
+ // TODO: import from muggle-string
9
+ function getStack() {
10
+ const stack = new Error().stack;
11
+ let source = stack.split('\n')[3].trim();
12
+ if (source.endsWith(')')) {
13
+ source = source.slice(source.lastIndexOf('(') + 1, -1);
14
+ }
15
+ else {
16
+ source = source.slice(source.lastIndexOf(' ') + 1);
17
+ }
18
+ return source;
19
+ }
20
+ exports.getStack = getStack;
21
+ function disableAllFeatures(override) {
22
+ return {
23
+ verification: false,
24
+ completion: false,
25
+ semantic: false,
26
+ navigation: false,
27
+ structure: false,
28
+ format: false,
29
+ ...override,
30
+ };
31
+ }
32
+ exports.disableAllFeatures = disableAllFeatures;
33
+ function enableAllFeatures(override) {
34
+ return {
35
+ verification: true,
36
+ completion: true,
37
+ semantic: true,
38
+ navigation: true,
39
+ structure: true,
40
+ format: true,
41
+ ...override,
42
+ };
43
+ }
44
+ exports.enableAllFeatures = enableAllFeatures;
45
+ function mergeFeatureSettings(base, ...others) {
46
+ const result = { ...base };
47
+ for (const info of others) {
48
+ for (const key in info) {
49
+ const value = info[key];
50
+ if (value) {
51
+ result[key] = value;
52
+ }
53
+ }
54
+ }
55
+ return result;
56
+ }
57
+ exports.mergeFeatureSettings = mergeFeatureSettings;
58
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1,5 @@
1
+ import { type LanguagePlugin } from '@volar/language-core';
2
+ import type * as ts from 'typescript';
3
+ import type { VueCompilerOptions } from './types';
4
+ import { VueGeneratedCode } from './virtualFile/vueFile';
5
+ export declare function createVueLanguagePlugin(ts: typeof import('typescript'), getFileName: (fileId: string) => string, compilerOptions?: ts.CompilerOptions, _vueCompilerOptions?: Partial<VueCompilerOptions>, codegenStack?: boolean, globalTypesHolder?: string): LanguagePlugin<VueGeneratedCode>;
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createVueLanguagePlugin = void 0;
4
+ const language_core_1 = require("@volar/language-core");
5
+ const plugins_1 = require("./plugins");
6
+ const ts_1 = require("./utils/ts");
7
+ const vueFile_1 = require("./virtualFile/vueFile");
8
+ const fileRegistries = [];
9
+ function getVueFileRegistry(key, plugins) {
10
+ let fileRegistry = fileRegistries.find(r => r.key === key
11
+ && r.plugins.length === plugins.length
12
+ && r.plugins.every(plugin => plugins.includes(plugin)))?.files;
13
+ if (!fileRegistry) {
14
+ fileRegistry = new Map();
15
+ fileRegistries.push({
16
+ key: key,
17
+ plugins: plugins,
18
+ files: fileRegistry,
19
+ });
20
+ }
21
+ return fileRegistry;
22
+ }
23
+ function getFileRegistryKey(compilerOptions, vueCompilerOptions, plugins, globalTypesHolder) {
24
+ const values = [
25
+ globalTypesHolder,
26
+ ...Object.keys(vueCompilerOptions)
27
+ .sort()
28
+ .filter(key => key !== 'plugins')
29
+ .map(key => [key, vueCompilerOptions[key]]),
30
+ [...new Set(plugins.map(plugin => plugin.requiredCompilerOptions ?? []).flat())]
31
+ .sort()
32
+ .map(key => [key, compilerOptions[key]]),
33
+ ];
34
+ return JSON.stringify(values);
35
+ }
36
+ function createVueLanguagePlugin(ts, getFileName, compilerOptions = {}, _vueCompilerOptions = {}, codegenStack = false, globalTypesHolder) {
37
+ const vueCompilerOptions = (0, ts_1.resolveVueCompilerOptions)(_vueCompilerOptions);
38
+ const allowLanguageIds = new Set(['vue']);
39
+ const pluginContext = (0, plugins_1.createPluginContext)(ts, compilerOptions, vueCompilerOptions, codegenStack, globalTypesHolder);
40
+ const plugins = (0, plugins_1.getDefaultVueLanguagePlugins)(pluginContext);
41
+ if (vueCompilerOptions.extensions.includes('.md')) {
42
+ allowLanguageIds.add('markdown');
43
+ }
44
+ if (vueCompilerOptions.extensions.includes('.html')) {
45
+ allowLanguageIds.add('html');
46
+ }
47
+ let generatedCodeRegistry;
48
+ return {
49
+ createVirtualCode(fileId, languageId, snapshot) {
50
+ if (allowLanguageIds.has(languageId)) {
51
+ const fileName = getFileName(fileId);
52
+ if (!generatedCodeRegistry) {
53
+ pluginContext.globalTypesHolder ??= fileName;
54
+ generatedCodeRegistry = getVueFileRegistry(getFileRegistryKey(compilerOptions, vueCompilerOptions, plugins, pluginContext.globalTypesHolder), vueCompilerOptions.plugins);
55
+ }
56
+ if (generatedCodeRegistry.has(fileId)) {
57
+ const reusedResult = generatedCodeRegistry.get(fileId);
58
+ reusedResult.update(snapshot);
59
+ return reusedResult;
60
+ }
61
+ const vueFile = new vueFile_1.VueGeneratedCode(fileName, languageId, snapshot, vueCompilerOptions, plugins, ts, codegenStack);
62
+ generatedCodeRegistry.set(fileId, vueFile);
63
+ return vueFile;
64
+ }
65
+ },
66
+ updateVirtualCode(_fileId, vueFile, snapshot) {
67
+ vueFile.update(snapshot);
68
+ return vueFile;
69
+ },
70
+ disposeVirtualCode(fileId, vueFile, files) {
71
+ generatedCodeRegistry?.delete(fileId);
72
+ if (vueFile.fileName === pluginContext.globalTypesHolder) {
73
+ if (generatedCodeRegistry?.size) {
74
+ for (const [fileName, file] of generatedCodeRegistry) {
75
+ pluginContext.globalTypesHolder = fileName;
76
+ generatedCodeRegistry = getVueFileRegistry(getFileRegistryKey(compilerOptions, vueCompilerOptions, plugins, pluginContext.globalTypesHolder), vueCompilerOptions.plugins);
77
+ files?.set(fileId, file.languageId,
78
+ // force dirty
79
+ { ...file.snapshot });
80
+ break;
81
+ }
82
+ }
83
+ else {
84
+ generatedCodeRegistry = undefined;
85
+ pluginContext.globalTypesHolder = undefined;
86
+ }
87
+ }
88
+ },
89
+ typescript: {
90
+ extraFileExtensions: vueCompilerOptions.extensions.map(ext => ({
91
+ extension: ext.slice(1),
92
+ isMixedContent: true,
93
+ scriptKind: 7,
94
+ })),
95
+ getScript(rootVirtualCode) {
96
+ for (const code of (0, language_core_1.forEachEmbeddedCode)(rootVirtualCode)) {
97
+ if (code.id.startsWith('script_')) {
98
+ const lang = code.id.substring('script_'.length);
99
+ return {
100
+ code,
101
+ extension: '.' + lang,
102
+ scriptKind: lang === 'js' ? ts.ScriptKind.JS
103
+ : lang === 'jsx' ? ts.ScriptKind.JSX
104
+ : lang === 'tsx' ? ts.ScriptKind.TSX
105
+ : ts.ScriptKind.TS,
106
+ };
107
+ }
108
+ }
109
+ },
110
+ },
111
+ };
112
+ }
113
+ exports.createVueLanguagePlugin = createVueLanguagePlugin;
114
+ //# sourceMappingURL=languageModule.js.map
@@ -1,8 +1,8 @@
1
1
  import type { TextRange } from '../types';
2
- import type * as ts from 'typescript/lib/tsserverlibrary';
2
+ import type * as ts from 'typescript';
3
3
  export interface ScriptRanges extends ReturnType<typeof parseScriptRanges> {
4
4
  }
5
- export declare function parseScriptRanges(ts: typeof import('typescript/lib/tsserverlibrary'), ast: ts.SourceFile, hasScriptSetup: boolean, withNode: boolean): {
5
+ export declare function parseScriptRanges(ts: typeof import('typescript'), ast: ts.SourceFile, hasScriptSetup: boolean, withNode: boolean): {
6
6
  exportDefault: (TextRange & {
7
7
  expression: TextRange;
8
8
  args: TextRange;
@@ -13,4 +13,3 @@ export declare function parseScriptRanges(ts: typeof import('typescript/lib/tsse
13
13
  }) | undefined;
14
14
  bindings: TextRange[];
15
15
  };
16
- //# sourceMappingURL=scriptRanges.d.ts.map
@@ -5,10 +5,10 @@ const scriptSetupRanges_1 = require("./scriptSetupRanges");
5
5
  function parseScriptRanges(ts, ast, hasScriptSetup, withNode) {
6
6
  let exportDefault;
7
7
  const bindings = hasScriptSetup ? (0, scriptSetupRanges_1.parseBindingRanges)(ts, ast) : [];
8
- ast.forEachChild(raw => {
8
+ ts.forEachChild(ast, raw => {
9
9
  if (ts.isExportAssignment(raw)) {
10
10
  let node = raw;
11
- while (ts.isAsExpression(node.expression) || ts.isParenthesizedExpression(node.expression)) { // fix https://github.com/vuejs/language-tools/issues/1882
11
+ while (isAsExpression(node.expression) || ts.isParenthesizedExpression(node.expression)) { // fix https://github.com/vuejs/language-tools/issues/1882
12
12
  node = node.expression;
13
13
  }
14
14
  let obj;
@@ -24,12 +24,13 @@ function parseScriptRanges(ts, ast, hasScriptSetup, withNode) {
24
24
  if (obj) {
25
25
  let componentsOptionNode;
26
26
  let nameOptionNode;
27
- obj.forEachChild(node => {
27
+ ts.forEachChild(obj, node => {
28
28
  if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name)) {
29
- if (node.name.escapedText === 'components' && ts.isObjectLiteralExpression(node.initializer)) {
29
+ const name = (0, scriptSetupRanges_1.getNodeText)(ts, node.name, ast);
30
+ if (name === 'components' && ts.isObjectLiteralExpression(node.initializer)) {
30
31
  componentsOptionNode = node.initializer;
31
32
  }
32
- if (node.name.escapedText === 'name') {
33
+ if (name === 'name') {
33
34
  nameOptionNode = node.initializer;
34
35
  }
35
36
  }
@@ -51,7 +52,11 @@ function parseScriptRanges(ts, ast, hasScriptSetup, withNode) {
51
52
  bindings,
52
53
  };
53
54
  function _getStartEnd(node) {
54
- return (0, scriptSetupRanges_1.getStartEnd)(node, ast);
55
+ return (0, scriptSetupRanges_1.getStartEnd)(ts, node, ast);
56
+ }
57
+ // isAsExpression is missing in tsc
58
+ function isAsExpression(node) {
59
+ return node.kind === ts.SyntaxKind.AsExpression;
55
60
  }
56
61
  }
57
62
  exports.parseScriptRanges = parseScriptRanges;
@@ -1,17 +1,18 @@
1
- import type * as ts from 'typescript/lib/tsserverlibrary';
1
+ import type * as ts from 'typescript';
2
2
  import type { VueCompilerOptions, TextRange } from '../types';
3
3
  export interface ScriptSetupRanges extends ReturnType<typeof parseScriptSetupRanges> {
4
4
  }
5
- export declare function parseScriptSetupRanges(ts: typeof import('typescript/lib/tsserverlibrary'), ast: ts.SourceFile, vueCompilerOptions: VueCompilerOptions): {
5
+ export declare function parseScriptSetupRanges(ts: typeof import('typescript'), ast: ts.SourceFile, vueCompilerOptions: VueCompilerOptions): {
6
6
  leadingCommentEndOffset: number;
7
7
  importSectionEndOffset: number;
8
8
  bindings: TextRange[];
9
9
  props: {
10
10
  name?: string | undefined;
11
11
  define?: (TextRange & {
12
- statement: TextRange;
13
12
  arg?: TextRange | undefined;
14
13
  typeArg?: TextRange | undefined;
14
+ } & {
15
+ statement: TextRange;
15
16
  }) | undefined;
16
17
  withDefaults?: (TextRange & {
17
18
  arg?: TextRange | undefined;
@@ -19,11 +20,17 @@ export declare function parseScriptSetupRanges(ts: typeof import('typescript/lib
19
20
  };
20
21
  slots: {
21
22
  name?: string | undefined;
22
- define?: TextRange | undefined;
23
+ define?: (TextRange & {
24
+ arg?: TextRange | undefined;
25
+ typeArg?: TextRange | undefined;
26
+ }) | undefined;
23
27
  };
24
28
  emits: {
25
29
  name?: string | undefined;
26
- define?: TextRange | undefined;
30
+ define?: (TextRange & {
31
+ arg?: TextRange | undefined;
32
+ typeArg?: TextRange | undefined;
33
+ }) | undefined;
27
34
  };
28
35
  expose: {
29
36
  name?: string | undefined;
@@ -38,12 +45,13 @@ export declare function parseScriptSetupRanges(ts: typeof import('typescript/lib
38
45
  type: TextRange | undefined;
39
46
  defaultValue: TextRange | undefined;
40
47
  required: boolean;
48
+ isModel?: boolean | undefined;
41
49
  }[];
42
50
  };
43
- export declare function parseBindingRanges(ts: typeof import('typescript/lib/tsserverlibrary'), sourceFile: ts.SourceFile): TextRange[];
44
- export declare function findBindingVars(ts: typeof import('typescript/lib/tsserverlibrary'), left: ts.BindingName, sourceFile: ts.SourceFile): TextRange[];
45
- export declare function getStartEnd(node: ts.Node, sourceFile: ts.SourceFile): {
51
+ export declare function parseBindingRanges(ts: typeof import('typescript'), sourceFile: ts.SourceFile): TextRange[];
52
+ export declare function findBindingVars(ts: typeof import('typescript'), left: ts.BindingName, sourceFile: ts.SourceFile): TextRange[];
53
+ export declare function getStartEnd(ts: typeof import('typescript'), node: ts.Node, sourceFile: ts.SourceFile): {
46
54
  start: number;
47
55
  end: number;
48
56
  };
49
- //# sourceMappingURL=scriptSetupRanges.d.ts.map
57
+ export declare function getNodeText(ts: typeof import('typescript'), node: ts.Node, sourceFile: ts.SourceFile): string;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getStartEnd = exports.findBindingVars = exports.parseBindingRanges = exports.parseScriptSetupRanges = void 0;
3
+ exports.getNodeText = exports.getStartEnd = exports.findBindingVars = exports.parseBindingRanges = exports.parseScriptSetupRanges = void 0;
4
4
  function parseScriptSetupRanges(ts, ast, vueCompilerOptions) {
5
5
  let foundNonImportExportNode = false;
6
6
  let importSectionEndOffset = 0;
@@ -8,13 +8,13 @@ function parseScriptSetupRanges(ts, ast, vueCompilerOptions) {
8
8
  const slots = {};
9
9
  const emits = {};
10
10
  const expose = {};
11
- const definePropProposalA = vueCompilerOptions.experimentalDefinePropProposal === 'kevinEdition' || ast.getFullText().trimStart().startsWith('// @experimentalDefinePropProposal=kevinEdition');
12
- const definePropProposalB = vueCompilerOptions.experimentalDefinePropProposal === 'johnsonEdition' || ast.getFullText().trimStart().startsWith('// @experimentalDefinePropProposal=johnsonEdition');
11
+ const definePropProposalA = vueCompilerOptions.experimentalDefinePropProposal === 'kevinEdition' || ast.text.trimStart().startsWith('// @experimentalDefinePropProposal=kevinEdition');
12
+ const definePropProposalB = vueCompilerOptions.experimentalDefinePropProposal === 'johnsonEdition' || ast.text.trimStart().startsWith('// @experimentalDefinePropProposal=johnsonEdition');
13
13
  const defineProp = [];
14
14
  const bindings = parseBindingRanges(ts, ast);
15
- const text = ast.getFullText();
15
+ const text = ast.text;
16
16
  const leadingCommentEndOffset = ts.getLeadingCommentRanges(text, 0)?.reverse()[0].end ?? 0;
17
- ast.forEachChild(node => {
17
+ ts.forEachChild(ast, node => {
18
18
  const isTypeExport = (ts.isTypeAliasDeclaration(node) || ts.isInterfaceDeclaration(node)) && node.modifiers?.some(mod => mod.kind === ts.SyntaxKind.ExportKeyword);
19
19
  if (!foundNonImportExportNode
20
20
  && !ts.isImportDeclaration(node)
@@ -22,18 +22,18 @@ function parseScriptSetupRanges(ts, ast, vueCompilerOptions) {
22
22
  && !ts.isEmptyStatement(node)
23
23
  // fix https://github.com/vuejs/language-tools/issues/1223
24
24
  && !ts.isImportEqualsDeclaration(node)) {
25
- const commentRanges = ts.getLeadingCommentRanges(text, node.getFullStart());
25
+ const commentRanges = ts.getLeadingCommentRanges(text, node.pos);
26
26
  if (commentRanges?.length) {
27
27
  const commentRange = commentRanges.sort((a, b) => a.pos - b.pos)[0];
28
28
  importSectionEndOffset = commentRange.pos;
29
29
  }
30
30
  else {
31
- importSectionEndOffset = node.getStart(ast);
31
+ importSectionEndOffset = getStartEnd(ts, node, ast).start;
32
32
  }
33
33
  foundNonImportExportNode = true;
34
34
  }
35
35
  });
36
- ast.forEachChild(child => visitNode(child, [ast]));
36
+ ts.forEachChild(ast, child => visitNode(child, [ast]));
37
37
  return {
38
38
  leadingCommentEndOffset,
39
39
  importSectionEndOffset,
@@ -45,13 +45,20 @@ function parseScriptSetupRanges(ts, ast, vueCompilerOptions) {
45
45
  defineProp,
46
46
  };
47
47
  function _getStartEnd(node) {
48
- return getStartEnd(node, ast);
48
+ return getStartEnd(ts, node, ast);
49
+ }
50
+ function parseDefineFunction(node) {
51
+ return {
52
+ ..._getStartEnd(node),
53
+ arg: node.arguments.length ? _getStartEnd(node.arguments[0]) : undefined,
54
+ typeArg: node.typeArguments?.length ? _getStartEnd(node.typeArguments[0]) : undefined,
55
+ };
49
56
  }
50
57
  function visitNode(node, parents) {
51
58
  const parent = parents[parents.length - 1];
52
59
  if (ts.isCallExpression(node)
53
60
  && ts.isIdentifier(node.expression)) {
54
- const callText = node.expression.getText(ast);
61
+ const callText = getNodeText(ts, node.expression, ast);
55
62
  if (vueCompilerOptions.macros.defineModel.includes(callText)) {
56
63
  let name;
57
64
  let options;
@@ -70,7 +77,7 @@ function parseScriptSetupRanges(ts, ast, vueCompilerOptions) {
70
77
  let required = false;
71
78
  if (options && ts.isObjectLiteralExpression(options)) {
72
79
  for (const property of options.properties) {
73
- if (ts.isPropertyAssignment(property) && ts.isIdentifier(property.name) && property.name.getText(ast) === 'required' && property.initializer.kind === ts.SyntaxKind.TrueKeyword) {
80
+ if (ts.isPropertyAssignment(property) && ts.isIdentifier(property.name) && getNodeText(ts, property.name, ast) === 'required' && property.initializer.kind === ts.SyntaxKind.TrueKeyword) {
74
81
  required = true;
75
82
  break;
76
83
  }
@@ -82,6 +89,7 @@ function parseScriptSetupRanges(ts, ast, vueCompilerOptions) {
82
89
  type: node.typeArguments?.length ? _getStartEnd(node.typeArguments[0]) : undefined,
83
90
  defaultValue: undefined,
84
91
  required,
92
+ isModel: true,
85
93
  });
86
94
  }
87
95
  else if (callText === 'defineProp') {
@@ -91,7 +99,7 @@ function parseScriptSetupRanges(ts, ast, vueCompilerOptions) {
91
99
  const secondArg = node.arguments[1];
92
100
  if (ts.isObjectLiteralExpression(secondArg)) {
93
101
  for (const property of secondArg.properties) {
94
- if (ts.isPropertyAssignment(property) && ts.isIdentifier(property.name) && property.name.getText(ast) === 'required' && property.initializer.kind === ts.SyntaxKind.TrueKeyword) {
102
+ if (ts.isPropertyAssignment(property) && ts.isIdentifier(property.name) && getNodeText(ts, property.name, ast) === 'required' && property.initializer.kind === ts.SyntaxKind.TrueKeyword) {
95
103
  required = true;
96
104
  break;
97
105
  }
@@ -128,32 +136,26 @@ function parseScriptSetupRanges(ts, ast, vueCompilerOptions) {
128
136
  }
129
137
  }
130
138
  else if (vueCompilerOptions.macros.defineSlots.includes(callText)) {
131
- slots.define = _getStartEnd(node);
139
+ slots.define = parseDefineFunction(node);
132
140
  if (ts.isVariableDeclaration(parent)) {
133
- slots.name = parent.name.getText(ast);
141
+ slots.name = getNodeText(ts, parent.name, ast);
134
142
  }
135
143
  }
136
144
  else if (vueCompilerOptions.macros.defineEmits.includes(callText)) {
137
- emits.define = _getStartEnd(node);
145
+ emits.define = parseDefineFunction(node);
138
146
  if (ts.isVariableDeclaration(parent)) {
139
- emits.name = parent.name.getText(ast);
147
+ emits.name = getNodeText(ts, parent.name, ast);
140
148
  }
141
149
  }
142
150
  else if (vueCompilerOptions.macros.defineExpose.includes(callText)) {
143
- expose.define = _getStartEnd(node);
144
- if (node.arguments.length) {
145
- expose.define.arg = _getStartEnd(node.arguments[0]);
146
- }
147
- if (node.typeArguments?.length) {
148
- expose.define.typeArg = _getStartEnd(node.typeArguments[0]);
149
- }
151
+ expose.define = parseDefineFunction(node);
150
152
  }
151
153
  else if (vueCompilerOptions.macros.defineProps.includes(callText)) {
152
154
  let statementRange;
153
155
  for (let i = parents.length - 1; i >= 0; i--) {
154
156
  if (ts.isStatement(parents[i])) {
155
157
  const statement = parents[i];
156
- statement.forEachChild(child => {
158
+ ts.forEachChild(statement, child => {
157
159
  const range = _getStartEnd(child);
158
160
  statementRange ??= range;
159
161
  statementRange.end = range.end;
@@ -165,11 +167,11 @@ function parseScriptSetupRanges(ts, ast, vueCompilerOptions) {
165
167
  statementRange = _getStartEnd(node);
166
168
  }
167
169
  props.define = {
168
- ..._getStartEnd(node),
170
+ ...parseDefineFunction(node),
169
171
  statement: statementRange,
170
172
  };
171
173
  if (ts.isVariableDeclaration(parent)) {
172
- props.name = parent.name.getText(ast);
174
+ props.name = getNodeText(ts, parent.name, ast);
173
175
  }
174
176
  if (node.arguments.length) {
175
177
  props.define.arg = _getStartEnd(node.arguments[0]);
@@ -185,11 +187,11 @@ function parseScriptSetupRanges(ts, ast, vueCompilerOptions) {
185
187
  props.withDefaults.arg = _getStartEnd(arg);
186
188
  }
187
189
  if (ts.isVariableDeclaration(parent)) {
188
- props.name = parent.name.getText(ast);
190
+ props.name = getNodeText(ts, parent.name, ast);
189
191
  }
190
192
  }
191
193
  }
192
- node.forEachChild(child => {
194
+ ts.forEachChild(node, child => {
193
195
  parents.push(node);
194
196
  visitNode(child, parents);
195
197
  parents.pop();
@@ -199,7 +201,7 @@ function parseScriptSetupRanges(ts, ast, vueCompilerOptions) {
199
201
  exports.parseScriptSetupRanges = parseScriptSetupRanges;
200
202
  function parseBindingRanges(ts, sourceFile) {
201
203
  const bindings = [];
202
- sourceFile.forEachChild(node => {
204
+ ts.forEachChild(sourceFile, node => {
203
205
  if (ts.isVariableStatement(node)) {
204
206
  for (const node_2 of node.declarationList.declarations) {
205
207
  const vars = _findBindingVars(node_2.name);
@@ -241,7 +243,7 @@ function parseBindingRanges(ts, sourceFile) {
241
243
  });
242
244
  return bindings;
243
245
  function _getStartEnd(node) {
244
- return getStartEnd(node, sourceFile);
246
+ return getStartEnd(ts, node, sourceFile);
245
247
  }
246
248
  function _findBindingVars(left) {
247
249
  return findBindingVars(ts, left, sourceFile);
@@ -254,7 +256,7 @@ function findBindingVars(ts, left, sourceFile) {
254
256
  return vars;
255
257
  function worker(_node) {
256
258
  if (ts.isIdentifier(_node)) {
257
- vars.push(getStartEnd(_node, sourceFile));
259
+ vars.push(getStartEnd(ts, _node, sourceFile));
258
260
  }
259
261
  // { ? } = ...
260
262
  // [ ? ] = ...
@@ -271,7 +273,7 @@ function findBindingVars(ts, left, sourceFile) {
271
273
  }
272
274
  // { foo } = ...
273
275
  else if (ts.isShorthandPropertyAssignment(_node)) {
274
- vars.push(getStartEnd(_node.name, sourceFile));
276
+ vars.push(getStartEnd(ts, _node.name, sourceFile));
275
277
  }
276
278
  // { ...? } = ...
277
279
  // [ ...? ] = ...
@@ -281,11 +283,16 @@ function findBindingVars(ts, left, sourceFile) {
281
283
  }
282
284
  }
283
285
  exports.findBindingVars = findBindingVars;
284
- function getStartEnd(node, sourceFile) {
286
+ function getStartEnd(ts, node, sourceFile) {
285
287
  return {
286
- start: node.getStart(sourceFile),
287
- end: node.getEnd(),
288
+ start: ts.getTokenPosOfNode(node, sourceFile),
289
+ end: node.end,
288
290
  };
289
291
  }
290
292
  exports.getStartEnd = getStartEnd;
293
+ function getNodeText(ts, node, sourceFile) {
294
+ const { start, end } = getStartEnd(ts, node, sourceFile);
295
+ return sourceFile.text.substring(start, end);
296
+ }
297
+ exports.getNodeText = getNodeText;
291
298
  //# sourceMappingURL=scriptSetupRanges.js.map
@@ -0,0 +1,3 @@
1
+ import type { VueLanguagePlugin } from '../types';
2
+ declare const plugin: VueLanguagePlugin;
3
+ export default plugin;
@@ -4,7 +4,7 @@ const sfcBlockReg = /\<(script|style)\b([\s\S]*?)\>([\s\S]*?)\<\/\1\>/g;
4
4
  const langReg = /\blang\s*=\s*(['\"]?)(\S*)\b\1/;
5
5
  const plugin = () => {
6
6
  return {
7
- version: 1,
7
+ version: 2,
8
8
  parseSFC(fileName, content) {
9
9
  if (fileName.endsWith('.html')) {
10
10
  let sfc = {
@@ -0,0 +1,3 @@
1
+ import type { VueLanguagePlugin } from '../types';
2
+ declare const plugin: VueLanguagePlugin;
3
+ export default plugin;
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const source_map_1 = require("@volar/source-map");
3
+ const language_core_1 = require("@volar/language-core");
4
4
  const parseSfc_1 = require("../utils/parseSfc");
5
- const codeblockReg = /```[\s\S]+?```/g;
5
+ const codeblockReg = /(`{3,})[\s\S]+?\1/g;
6
6
  const inlineCodeblockReg = /`[^\n`]+?`/g;
7
7
  const scriptSetupReg = /\\\<[\s\S]+?\>\n?/g;
8
8
  const sfcBlockReg = /\<(script|style)\b[\s\S]*?\>([\s\S]*?)\<\/\1\>/g;
@@ -11,12 +11,12 @@ const linkReg = /\[[\s\S]*?\]\([\s\S]*?\)/g;
11
11
  const codeSnippetImportReg = /^\s*<<<\s*.+/gm;
12
12
  const plugin = () => {
13
13
  return {
14
- version: 1,
14
+ version: 2,
15
15
  parseSFC(fileName, content) {
16
16
  if (fileName.endsWith('.md')) {
17
17
  content = content
18
18
  // code block
19
- .replace(codeblockReg, match => '```' + ' '.repeat(match.length - 6) + '```')
19
+ .replace(codeblockReg, (match, quotes) => quotes + ' '.repeat(match.length - quotes.length * 2) + quotes)
20
20
  // inline code block
21
21
  .replace(inlineCodeblockReg, match => `\`${' '.repeat(match.length - 2)}\``)
22
22
  // # \<script setup>
@@ -40,8 +40,8 @@ const plugin = () => {
40
40
  codes.push('<template>\n');
41
41
  codes.push([content, undefined, 0]);
42
42
  codes.push('\n</template>');
43
- const file2VueSourceMap = new source_map_1.SourceMap((0, source_map_1.buildMappings)(codes));
44
- const sfc = (0, parseSfc_1.parse)((0, source_map_1.toString)(codes));
43
+ const file2VueSourceMap = new language_core_1.SourceMap((0, language_core_1.buildMappings)(codes));
44
+ const sfc = (0, parseSfc_1.parse)((0, language_core_1.toString)(codes));
45
45
  if (sfc.descriptor.template) {
46
46
  transformRange(sfc.descriptor.template);
47
47
  }
@@ -59,8 +59,8 @@ const plugin = () => {
59
59
  }
60
60
  return sfc;
61
61
  function transformRange(block) {
62
- block.loc.start.offset = file2VueSourceMap.toSourceOffset(block.loc.start.offset)?.[0] ?? -1;
63
- block.loc.end.offset = file2VueSourceMap.toSourceOffset(block.loc.end.offset)?.[0] ?? -1;
62
+ block.loc.start.offset = file2VueSourceMap.getSourceOffset(block.loc.start.offset)?.[0] ?? -1;
63
+ block.loc.end.offset = file2VueSourceMap.getSourceOffset(block.loc.end.offset)?.[0] ?? -1;
64
64
  }
65
65
  }
66
66
  ;
@@ -0,0 +1,3 @@
1
+ import type { VueLanguagePlugin } from '../types';
2
+ declare const plugin: VueLanguagePlugin;
3
+ export default plugin;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const parseSfc_1 = require("../utils/parseSfc");
4
4
  const plugin = (_ctx) => {
5
5
  return {
6
- version: 1,
6
+ version: 2,
7
7
  parseSFC(_fileName, content) {
8
8
  return (0, parseSfc_1.parse)(content);
9
9
  },
@@ -19,10 +19,17 @@ const plugin = (_ctx) => {
19
19
  if (!hitBlock) {
20
20
  return;
21
21
  }
22
- hitBlock.content =
22
+ const oldContent = hitBlock.content;
23
+ const newContent = hitBlock.content =
23
24
  hitBlock.content.substring(0, change.start - hitBlock.loc.start.offset)
24
25
  + change.newText
25
26
  + hitBlock.content.substring(change.end - hitBlock.loc.start.offset);
27
+ // #3449
28
+ const endTagRegex = new RegExp(`</\\s*${hitBlock.type}\\s*>`);
29
+ const insertedEndTag = !!oldContent.match(endTagRegex) !== !!newContent.match(endTagRegex);
30
+ if (insertedEndTag) {
31
+ return;
32
+ }
26
33
  const lengthDiff = change.newText.length - (change.end - change.start);
27
34
  for (const block of blocks) {
28
35
  if (block.loc.start.offset > change.end) {
@@ -0,0 +1,3 @@
1
+ import type { VueLanguagePlugin } from '../types';
2
+ declare const plugin: VueLanguagePlugin;
3
+ export default plugin;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const utils_1 = require("../generators/utils");
4
+ const plugin = () => {
5
+ return {
6
+ version: 2,
7
+ getEmbeddedCodes(_fileName, sfc) {
8
+ return sfc.customBlocks.map((customBlock, i) => ({
9
+ id: 'customBlock_' + i,
10
+ lang: customBlock.lang,
11
+ }));
12
+ },
13
+ resolveEmbeddedCode(_fileName, sfc, embeddedFile) {
14
+ if (embeddedFile.id.startsWith('customBlock_')) {
15
+ const index = parseInt(embeddedFile.id.slice('customBlock_'.length));
16
+ const customBlock = sfc.customBlocks[index];
17
+ embeddedFile.content.push([
18
+ customBlock.content,
19
+ customBlock.name,
20
+ 0,
21
+ (0, utils_1.enableAllFeatures)({}),
22
+ ]);
23
+ }
24
+ },
25
+ };
26
+ };
27
+ exports.default = plugin;
28
+ //# sourceMappingURL=vue-sfc-customblocks.js.map