@vue/language-core 2.0.16 → 2.0.17

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.
@@ -76,9 +76,9 @@ function createVueLanguagePlugin(ts, getFileName, useCaseSensitiveFileNames, get
76
76
  return 'html';
77
77
  }
78
78
  },
79
- createVirtualCode(fileId, languageId, snapshot) {
79
+ createVirtualCode(scriptId, languageId, snapshot) {
80
80
  if (languageId === 'vue' || languageId === 'markdown' || languageId === 'html') {
81
- const fileName = getFileName(fileId);
81
+ const fileName = getFileName(scriptId);
82
82
  const projectVersion = getProjectVersion();
83
83
  if (projectVersion !== canonicalRootFileNamesVersion) {
84
84
  canonicalRootFileNames = new Set([...getScriptFileNames()].map(getCanonicalFileName));
@@ -88,7 +88,7 @@ function createVueLanguagePlugin(ts, getFileName, useCaseSensitiveFileNames, get
88
88
  pluginContext.globalTypesHolder = fileName;
89
89
  }
90
90
  const fileRegistry = getFileRegistry(pluginContext.globalTypesHolder === fileName);
91
- const code = fileRegistry.get(fileId);
91
+ const code = fileRegistry.get(scriptId);
92
92
  if (code) {
93
93
  code.update(snapshot);
94
94
  return code;
@@ -99,7 +99,7 @@ function createVueLanguagePlugin(ts, getFileName, useCaseSensitiveFileNames, get
99
99
  : languageId === 'markdown'
100
100
  ? [vitePressSfcPlugin, ...basePlugins]
101
101
  : [vueSfcPlugin, ...basePlugins], ts);
102
- fileRegistry.set(fileId, code);
102
+ fileRegistry.set(scriptId, code);
103
103
  return code;
104
104
  }
105
105
  }
@@ -11,5 +11,6 @@ export declare function parseScriptRanges(ts: typeof import('typescript'), ast:
11
11
  componentsOptionNode: ts.ObjectLiteralExpression | undefined;
12
12
  nameOption: TextRange | undefined;
13
13
  }) | undefined;
14
+ classBlockEnd: number | undefined;
14
15
  bindings: TextRange[];
15
16
  };
@@ -4,6 +4,7 @@ exports.parseScriptRanges = void 0;
4
4
  const scriptSetupRanges_1 = require("./scriptSetupRanges");
5
5
  function parseScriptRanges(ts, ast, hasScriptSetup, withNode) {
6
6
  let exportDefault;
7
+ let classBlockEnd;
7
8
  const bindings = hasScriptSetup ? (0, scriptSetupRanges_1.parseBindingRanges)(ts, ast) : [];
8
9
  ts.forEachChild(ast, raw => {
9
10
  if (ts.isExportAssignment(raw)) {
@@ -46,9 +47,15 @@ function parseScriptRanges(ts, ast, hasScriptSetup, withNode) {
46
47
  };
47
48
  }
48
49
  }
50
+ if (ts.isClassDeclaration(raw)
51
+ && raw.modifiers?.some(mod => mod.kind === ts.SyntaxKind.ExportKeyword)
52
+ && raw.modifiers?.some(mod => mod.kind === ts.SyntaxKind.DefaultKeyword)) {
53
+ classBlockEnd = raw.end - 1;
54
+ }
49
55
  });
50
56
  return {
51
57
  exportDefault,
58
+ classBlockEnd,
52
59
  bindings,
53
60
  };
54
61
  function _getStartEnd(node) {
@@ -6,6 +6,7 @@ export declare function parseScriptSetupRanges(ts: typeof import('typescript'),
6
6
  leadingCommentEndOffset: number;
7
7
  importSectionEndOffset: number;
8
8
  bindings: TextRange[];
9
+ importComponentNames: Set<string>;
9
10
  props: {
10
11
  name?: string | undefined;
11
12
  define?: (TextRange & {
@@ -49,6 +50,9 @@ export declare function parseScriptSetupRanges(ts: typeof import('typescript'),
49
50
  required: boolean;
50
51
  isModel?: boolean | undefined;
51
52
  }[];
53
+ options: {
54
+ name?: string | undefined;
55
+ };
52
56
  };
53
57
  export declare function parseBindingRanges(ts: typeof import('typescript'), sourceFile: ts.SourceFile): TextRange[];
54
58
  export declare function findBindingVars(ts: typeof import('typescript'), left: ts.BindingName, sourceFile: ts.SourceFile): TextRange[];
@@ -8,12 +8,14 @@ function parseScriptSetupRanges(ts, ast, vueCompilerOptions) {
8
8
  const slots = {};
9
9
  const emits = {};
10
10
  const expose = {};
11
+ const options = {};
11
12
  const definePropProposalA = vueCompilerOptions.experimentalDefinePropProposal === 'kevinEdition' || ast.text.trimStart().startsWith('// @experimentalDefinePropProposal=kevinEdition');
12
13
  const definePropProposalB = vueCompilerOptions.experimentalDefinePropProposal === 'johnsonEdition' || ast.text.trimStart().startsWith('// @experimentalDefinePropProposal=johnsonEdition');
13
14
  const defineProp = [];
14
15
  const bindings = parseBindingRanges(ts, ast);
15
16
  const text = ast.text;
16
17
  const leadingCommentEndOffset = ts.getLeadingCommentRanges(text, 0)?.reverse()[0].end ?? 0;
18
+ const importComponentNames = new Set();
17
19
  ts.forEachChild(ast, node => {
18
20
  const isTypeExport = (ts.isTypeAliasDeclaration(node) || ts.isInterfaceDeclaration(node)) && node.modifiers?.some(mod => mod.kind === ts.SyntaxKind.ExportKeyword);
19
21
  if (!foundNonImportExportNode
@@ -32,17 +34,27 @@ function parseScriptSetupRanges(ts, ast, vueCompilerOptions) {
32
34
  }
33
35
  foundNonImportExportNode = true;
34
36
  }
37
+ if (ts.isImportDeclaration(node)
38
+ && node.importClause?.name
39
+ && !node.importClause.isTypeOnly) {
40
+ const moduleName = getNodeText(ts, node.moduleSpecifier, ast).slice(1, -1);
41
+ if (vueCompilerOptions.extensions.some(ext => moduleName.endsWith(ext))) {
42
+ importComponentNames.add(getNodeText(ts, node.importClause.name, ast));
43
+ }
44
+ }
35
45
  });
36
46
  ts.forEachChild(ast, child => visitNode(child, [ast]));
37
47
  return {
38
48
  leadingCommentEndOffset,
39
49
  importSectionEndOffset,
40
50
  bindings,
51
+ importComponentNames,
41
52
  props,
42
53
  slots,
43
54
  emits,
44
55
  expose,
45
56
  defineProp,
57
+ options,
46
58
  };
47
59
  function _getStartEnd(node) {
48
60
  return getStartEnd(ts, node, ast);
@@ -196,6 +208,15 @@ function parseScriptSetupRanges(ts, ast, vueCompilerOptions) {
196
208
  props.name = getNodeText(ts, parent.name, ast);
197
209
  }
198
210
  }
211
+ else if (vueCompilerOptions.macros.defineOptions.includes(callText)) {
212
+ if (node.arguments.length && ts.isObjectLiteralExpression(node.arguments[0])) {
213
+ for (const prop of node.arguments[0].properties) {
214
+ if ((ts.isPropertyAssignment(prop)) && getNodeText(ts, prop.name, ast) === 'name' && ts.isStringLiteral(prop.initializer)) {
215
+ options.name = prop.initializer.text;
216
+ }
217
+ }
218
+ }
219
+ }
199
220
  }
200
221
  ts.forEachChild(node, child => {
201
222
  parents.push(node);
@@ -237,6 +258,9 @@ function parseBindingRanges(ts, sourceFile) {
237
258
  if (node.importClause.namedBindings) {
238
259
  if (ts.isNamedImports(node.importClause.namedBindings)) {
239
260
  for (const element of node.importClause.namedBindings.elements) {
261
+ if (element.isTypeOnly) {
262
+ continue;
263
+ }
240
264
  bindings.push(_getStartEnd(element.name));
241
265
  }
242
266
  }
@@ -74,7 +74,7 @@ const plugin = ctx => {
74
74
  if (prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
75
75
  && prop.exp.constType !== CompilerDOM.ConstantTypes.CAN_STRINGIFY // style='z-index: 2' will compile to {'z-index':'2'}
76
76
  ) {
77
- if (prop.name === 'on') {
77
+ if (prop.name === 'on' && prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
78
78
  const ast = (0, common_1.createTsAst)(ctx.modules.typescript, prop.exp, prop.exp.content);
79
79
  addFormatCodes(prop.exp.content, prop.exp.loc.start.offset, (0, elementEvents_1.isCompoundExpression)(ctx.modules.typescript, ast)
80
80
  ? formatBrackets.event
@@ -10,12 +10,14 @@ export declare const tsCodegen: WeakMap<Sfc, {
10
10
  componentsOptionNode: import("typescript").ObjectLiteralExpression | undefined;
11
11
  nameOption: import("../types").TextRange | undefined;
12
12
  }) | undefined;
13
+ classBlockEnd: number | undefined;
13
14
  bindings: import("../types").TextRange[];
14
15
  } | undefined;
15
16
  scriptSetupRanges: () => {
16
17
  leadingCommentEndOffset: number;
17
18
  importSectionEndOffset: number;
18
19
  bindings: import("../types").TextRange[];
20
+ importComponentNames: Set<string>;
19
21
  props: {
20
22
  name?: string | undefined;
21
23
  define?: (import("../types").TextRange & {
@@ -59,6 +61,9 @@ export declare const tsCodegen: WeakMap<Sfc, {
59
61
  required: boolean;
60
62
  isModel?: boolean | undefined;
61
63
  }[];
64
+ options: {
65
+ name?: string | undefined;
66
+ };
62
67
  } | undefined;
63
68
  lang: () => string;
64
69
  generatedScript: () => {
@@ -67,48 +72,49 @@ export declare const tsCodegen: WeakMap<Sfc, {
67
72
  };
68
73
  generatedTemplate: () => {
69
74
  codes: Code[];
70
- ctx: {
71
- slots: {
72
- name: string;
73
- loc?: number | undefined;
74
- tagRange: [number, number];
75
- varName: string;
76
- nodeLoc: any;
77
- }[];
78
- dynamicSlots: {
79
- expVar: string;
80
- varName: string;
81
- }[];
82
- codeFeatures: {
83
- all: import("../types").VueCodeInformation;
84
- verification: import("../types").VueCodeInformation;
85
- completion: import("../types").VueCodeInformation;
86
- additionalCompletion: import("../types").VueCodeInformation;
87
- navigation: import("../types").VueCodeInformation;
88
- navigationAndCompletion: import("../types").VueCodeInformation;
89
- withoutHighlight: import("../types").VueCodeInformation;
90
- withoutHighlightAndCompletion: import("../types").VueCodeInformation;
91
- withoutHighlightAndCompletionAndNavigation: import("../types").VueCodeInformation;
92
- };
93
- accessGlobalVariables: Map<string, Set<number>>;
94
- hasSlotElements: Set<import("@vue/compiler-dom").ElementNode>;
95
- blockConditions: string[];
96
- usedComponentCtxVars: Set<string>;
97
- scopedClasses: {
98
- className: string;
99
- offset: number;
100
- }[];
101
- accessGlobalVariable(name: string, offset?: number | undefined): void;
102
- hasLocalVariable: (name: string) => boolean;
103
- addLocalVariable: (name: string) => void;
104
- removeLocalVariable: (name: string) => void;
105
- getInternalVariable: () => string;
106
- ignoreError: () => Generator<Code, any, unknown>;
107
- expectError: (prevNode: import("@vue/compiler-dom").CommentNode) => Generator<Code, any, unknown>;
108
- resetDirectiveComments: (endStr: string) => Generator<Code, any, unknown>;
109
- generateAutoImportCompletion: () => Generator<Code, any, unknown>;
75
+ slots: {
76
+ name: string;
77
+ loc?: number | undefined;
78
+ tagRange: [number, number];
79
+ varName: string;
80
+ nodeLoc: any;
81
+ }[];
82
+ dynamicSlots: {
83
+ expVar: string;
84
+ varName: string;
85
+ }[];
86
+ codeFeatures: {
87
+ all: import("../types").VueCodeInformation;
88
+ verification: import("../types").VueCodeInformation;
89
+ completion: import("../types").VueCodeInformation;
90
+ additionalCompletion: import("../types").VueCodeInformation;
91
+ navigation: import("../types").VueCodeInformation;
92
+ navigationWithoutRename: import("../types").VueCodeInformation;
93
+ navigationAndCompletion: import("../types").VueCodeInformation;
94
+ navigationAndAdditionalCompletion: import("../types").VueCodeInformation;
95
+ withoutHighlight: import("../types").VueCodeInformation;
96
+ withoutHighlightAndCompletion: import("../types").VueCodeInformation;
97
+ withoutHighlightAndCompletionAndNavigation: import("../types").VueCodeInformation;
110
98
  };
99
+ accessExternalVariables: Map<string, Set<number>>;
100
+ hasSlotElements: Set<import("@vue/compiler-dom").ElementNode>;
101
+ blockConditions: string[];
102
+ usedComponentCtxVars: Set<string>;
103
+ scopedClasses: {
104
+ className: string;
105
+ offset: number;
106
+ }[];
107
+ emptyClassOffsets: number[];
111
108
  hasSlot: boolean;
109
+ accessExternalVariable(name: string, offset?: number | undefined): void;
110
+ hasLocalVariable: (name: string) => boolean;
111
+ addLocalVariable: (name: string) => void;
112
+ removeLocalVariable: (name: string) => void;
113
+ getInternalVariable: () => string;
114
+ ignoreError: () => Generator<Code, any, unknown>;
115
+ expectError: (prevNode: import("@vue/compiler-dom").CommentNode) => Generator<Code, any, unknown>;
116
+ resetDirectiveComments: (endStr: string) => Generator<Code, any, unknown>;
117
+ generateAutoImportCompletion: () => Generator<Code, any, unknown>;
112
118
  } | undefined;
113
119
  }>;
114
120
  declare const plugin: VueLanguagePlugin;
@@ -57,27 +57,6 @@ function createTsx(fileName, _sfc, ctx) {
57
57
  const scriptSetupRanges = (0, computeds_1.computed)(() => _sfc.scriptSetup
58
58
  ? (0, scriptSetupRanges_1.parseScriptSetupRanges)(ts, _sfc.scriptSetup.ast, ctx.vueCompilerOptions)
59
59
  : undefined);
60
- const shouldGenerateScopedClasses = (0, computeds_1.computed)(() => {
61
- const option = ctx.vueCompilerOptions.experimentalResolveStyleCssClasses;
62
- return _sfc.styles.some(s => {
63
- return option === 'always' || (option === 'scoped' && s.scoped);
64
- });
65
- });
66
- const stylesScopedClasses = (0, computeds_1.computedSet)(() => {
67
- const classes = new Set();
68
- if (!shouldGenerateScopedClasses()) {
69
- return classes;
70
- }
71
- for (const style of _sfc.styles) {
72
- const option = ctx.vueCompilerOptions.experimentalResolveStyleCssClasses;
73
- if (option === 'always' || (option === 'scoped' && style.scoped)) {
74
- for (const className of style.classNames) {
75
- classes.add(className.text.substring(1));
76
- }
77
- }
78
- }
79
- return classes;
80
- });
81
60
  const generatedTemplate = (0, computeds_1.computed)(() => {
82
61
  if (!_sfc.template) {
83
62
  return;
@@ -88,8 +67,8 @@ function createTsx(fileName, _sfc, ctx) {
88
67
  compilerOptions: ctx.compilerOptions,
89
68
  vueCompilerOptions: ctx.vueCompilerOptions,
90
69
  template: _sfc.template,
91
- shouldGenerateScopedClasses: shouldGenerateScopedClasses(),
92
- stylesScopedClasses: stylesScopedClasses(),
70
+ scriptSetupBindingNames: scriptSetupBindingNames(),
71
+ scriptSetupImportComponentNames: scriptSetupImportComponentNames(),
93
72
  hasDefineSlots: hasDefineSlots(),
94
73
  slotsAssignName: slotsAssignName(),
95
74
  propsAssignName: propsAssignName(),
@@ -106,6 +85,26 @@ function createTsx(fileName, _sfc, ctx) {
106
85
  };
107
86
  });
108
87
  const hasDefineSlots = (0, computeds_1.computed)(() => !!scriptSetupRanges()?.slots.define);
88
+ const scriptSetupBindingNames = (0, computeds_1.computed)(oldNames => {
89
+ const newNames = new Set();
90
+ const bindings = scriptSetupRanges()?.bindings;
91
+ if (_sfc.scriptSetup && bindings) {
92
+ for (const binding of bindings) {
93
+ newNames.add(_sfc.scriptSetup?.content.substring(binding.start, binding.end));
94
+ }
95
+ }
96
+ if (newNames && oldNames && twoSetsEqual(newNames, oldNames)) {
97
+ return oldNames;
98
+ }
99
+ return newNames;
100
+ });
101
+ const scriptSetupImportComponentNames = (0, computeds_1.computed)(oldNames => {
102
+ const newNames = scriptSetupRanges()?.importComponentNames ?? new Set();
103
+ if (newNames && oldNames && twoSetsEqual(newNames, oldNames)) {
104
+ return oldNames;
105
+ }
106
+ return newNames;
107
+ });
109
108
  const slotsAssignName = (0, computeds_1.computed)(() => scriptSetupRanges()?.slots.name);
110
109
  const propsAssignName = (0, computeds_1.computed)(() => scriptSetupRanges()?.props.name);
111
110
  const generatedScript = (0, computeds_1.computed)(() => {
@@ -121,11 +120,7 @@ function createTsx(fileName, _sfc, ctx) {
121
120
  lang: lang(),
122
121
  scriptRanges: scriptRanges(),
123
122
  scriptSetupRanges: scriptSetupRanges(),
124
- templateCodegen: _template ? {
125
- tsCodes: _template.codes,
126
- ctx: _template.ctx,
127
- hasSlot: _template.hasSlot,
128
- } : undefined,
123
+ templateCodegen: _template,
129
124
  compilerOptions: ctx.compilerOptions,
130
125
  vueCompilerOptions: ctx.vueCompilerOptions,
131
126
  getGeneratedLength: () => generatedLength,
@@ -150,4 +145,15 @@ function createTsx(fileName, _sfc, ctx) {
150
145
  generatedTemplate,
151
146
  };
152
147
  }
148
+ function twoSetsEqual(a, b) {
149
+ if (a.size !== b.size) {
150
+ return false;
151
+ }
152
+ for (const file of a) {
153
+ if (!b.has(file)) {
154
+ return false;
155
+ }
156
+ }
157
+ return true;
158
+ }
153
159
  //# sourceMappingURL=vue-tsx.js.map
package/lib/types.d.ts CHANGED
@@ -10,8 +10,6 @@ export type RawVueCompilerOptions = Partial<Omit<VueCompilerOptions, 'target' |
10
10
  plugins?: string[];
11
11
  };
12
12
  export interface VueCodeInformation extends CodeInformation {
13
- __referencesCodeLens?: boolean;
14
- __displayWithLink?: boolean;
15
13
  __hint?: {
16
14
  setting: string;
17
15
  label: string;
@@ -48,7 +46,6 @@ export interface VueCompilerOptions {
48
46
  experimentalDefinePropProposal: 'kevinEdition' | 'johnsonEdition' | false;
49
47
  experimentalResolveStyleCssClasses: 'scoped' | 'always' | 'never';
50
48
  experimentalModelPropName: Record<string, Record<string, boolean | Record<string, string> | Record<string, string>[]>>;
51
- experimentalUseElementAccessInTemplate: boolean;
52
49
  }
53
50
  export declare const pluginVersion = 2;
54
51
  export type VueLanguagePlugin = (ctx: {
@@ -124,18 +121,6 @@ export interface Sfc {
124
121
  customBlocks: readonly (SfcBlock & {
125
122
  type: string;
126
123
  })[];
127
- /**
128
- * @deprecated use `template.ast` instead
129
- */
130
- templateAst: CompilerDOM.RootNode | undefined;
131
- /**
132
- * @deprecated use `script.ast` instead
133
- */
134
- scriptAst: ts.SourceFile | undefined;
135
- /**
136
- * @deprecated use `scriptSetup.ast` instead
137
- */
138
- scriptSetupAst: ts.SourceFile | undefined;
139
124
  }
140
125
  export interface TextRange {
141
126
  start: number;
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseCssClassNames = void 0;
4
4
  const parseCssVars_1 = require("./parseCssVars");
5
- const cssClassNameReg = /(?=([\.]{1}[a-zA-Z_]+[\w\_\-]*)[\s\.\+\{\>#\:]{1})/g;
5
+ const cssClassNameReg = /(?=([\.]{1}[a-zA-Z_]+[\w\_\-]*)[\s\.\,\+\{\>#\:]{1})/g;
6
6
  function* parseCssClassNames(styleContent) {
7
7
  styleContent = (0, parseCssVars_1.clearComments)(styleContent);
8
8
  const matches = styleContent.matchAll(cssClassNameReg);
package/lib/utils/ts.js CHANGED
@@ -210,7 +210,6 @@ function resolveVueCompilerOptions(vueOptions) {
210
210
  select: true
211
211
  }
212
212
  },
213
- experimentalUseElementAccessInTemplate: vueOptions.experimentalUseElementAccessInTemplate ?? false,
214
213
  };
215
214
  }
216
215
  exports.resolveVueCompilerOptions = resolveVueCompilerOptions;
@@ -95,9 +95,6 @@ function computedSfc(ts, plugins, fileName, snapshot, parsed) {
95
95
  get scriptSetup() { return scriptSetup(); },
96
96
  get styles() { return styles; },
97
97
  get customBlocks() { return customBlocks; },
98
- get templateAst() { return template()?.ast; },
99
- get scriptAst() { return script()?.ast; },
100
- get scriptSetupAst() { return scriptSetup()?.ast; },
101
98
  };
102
99
  function computedTemplateAst(base) {
103
100
  let cache;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue/language-core",
3
- "version": "2.0.16",
3
+ "version": "2.0.17",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "**/*.js",
@@ -12,7 +12,7 @@
12
12
  "directory": "packages/language-core"
13
13
  },
14
14
  "dependencies": {
15
- "@volar/language-core": "~2.2.0",
15
+ "@volar/language-core": "~2.2.2",
16
16
  "@vue/compiler-dom": "^3.4.0",
17
17
  "@vue/shared": "^3.4.0",
18
18
  "computeds": "^0.0.1",
@@ -34,5 +34,5 @@
34
34
  "optional": true
35
35
  }
36
36
  },
37
- "gitHead": "95b78c38cbf75481ebb59e11956b592346f01d92"
37
+ "gitHead": "968039cbb07961f318b4bf122bfa8e3e4a824277"
38
38
  }