@vue/language-core 3.2.1 → 3.2.3

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.
@@ -387,7 +387,8 @@ function* generateModels(scriptSetup, scriptSetupRanges) {
387
387
  yield* codes;
388
388
  }
389
389
  yield `}${utils_1.endOfLine}`;
390
- yield `const ${names.modelEmit} = defineEmits<${names.ModelEmit}>()${utils_1.endOfLine}`;
390
+ // avoid `defineModel<...>()` to prevent JS AST issues
391
+ yield `let ${names.modelEmit}!: __VLS_ShortEmits<${names.ModelEmit}>${utils_1.endOfLine}`;
391
392
  }
392
393
  function* generateModelProp(scriptSetup, defineModel, propName, modelType) {
393
394
  if (defineModel.comments) {
@@ -58,6 +58,7 @@ function* generateComponent(options, ctx, node) {
58
58
  let { tag, props } = node;
59
59
  let [startTagOffset, endTagOffset] = (0, shared_2.getElementTagOffsets)(node, options.template);
60
60
  let isExpression = false;
61
+ let isIsShorthand = false;
61
62
  if (tag.includes('.')) {
62
63
  isExpression = true;
63
64
  }
@@ -67,7 +68,8 @@ function* generateComponent(options, ctx, node) {
67
68
  && prop.name === 'bind'
68
69
  && prop.arg?.loc.source === 'is'
69
70
  && prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
70
- if (prop.arg.loc.end.offset === prop.exp.loc.end.offset) {
71
+ isIsShorthand = prop.arg.loc.end.offset === prop.exp.loc.end.offset;
72
+ if (isIsShorthand) {
71
73
  ctx.inlayHints.push((0, inlayHints_1.createVBindShorthandInlayHintInfo)(prop.exp.loc, 'is'));
72
74
  }
73
75
  isExpression = true;
@@ -82,7 +84,9 @@ function* generateComponent(options, ctx, node) {
82
84
  const componentVar = ctx.getInternalVariable();
83
85
  if (isExpression) {
84
86
  yield `const ${componentVar} = `;
85
- yield* (0, interpolation_1.generateInterpolation)(options, ctx, options.template, codeFeatures_1.codeFeatures.all, tag, startTagOffset, `(`, `)`);
87
+ yield* (0, interpolation_1.generateInterpolation)(options, ctx, options.template, isIsShorthand
88
+ ? codeFeatures_1.codeFeatures.withoutHighlightAndCompletion
89
+ : codeFeatures_1.codeFeatures.all, tag, startTagOffset, `(`, `)`);
86
90
  if (endTagOffset !== undefined) {
87
91
  yield ` || `;
88
92
  yield* (0, interpolation_1.generateInterpolation)(options, ctx, options.template, codeFeatures_1.codeFeatures.withoutCompletion, tag, endTagOffset, `(`, `)`);
@@ -164,7 +168,7 @@ function* generateComponentBody(options, ctx, node, tag, tagOffset, props, compo
164
168
  const propsVar = ctx.getInternalVariable();
165
169
  yield `// @ts-ignore${utils_1.newLine}`;
166
170
  yield `const ${functionalVar} = ${options.vueCompilerOptions.checkUnknownProps ? '__VLS_asFunctionalComponent0' : '__VLS_asFunctionalComponent1'}(${componentVar}, new ${componentVar}({${utils_1.newLine}`;
167
- yield* (0, muggle_string_1.toString)(propCodes);
171
+ yield (0, muggle_string_1.toString)(propCodes);
168
172
  yield `}))${utils_1.endOfLine}`;
169
173
  yield `const `;
170
174
  const token = yield* (0, boundary_1.startBoundary)('template', node.loc.start.offset, codeFeatures_1.codeFeatures.doNotReportTs6133);
@@ -266,18 +270,9 @@ function* generateStyleScopedClassReferences({ template, typescript: ts }, node)
266
270
  if (prop.type === CompilerDOM.NodeTypes.ATTRIBUTE
267
271
  && prop.name === 'class'
268
272
  && prop.value) {
269
- if (template.lang === 'pug') {
270
- const getClassOffset = Reflect.get(prop.value.loc.start, 'getClassOffset');
271
- const content = prop.value.loc.source.slice(1, -1);
272
- for (const [className, pos] of forEachClassName(content)) {
273
- yield* (0, styleScopedClasses_1.generateStyleScopedClassReference)(template, className, getClassOffset(pos + 1));
274
- }
275
- }
276
- else {
277
- const [text, start] = (0, shared_2.normalizeAttributeValue)(prop.value);
278
- for (const [className, offset] of forEachClassName(text)) {
279
- yield* (0, styleScopedClasses_1.generateStyleScopedClassReference)(template, className, start + offset);
280
- }
273
+ const [text, start] = (0, shared_2.normalizeAttributeValue)(prop.value);
274
+ for (const [className, offset] of forEachClassName(text)) {
275
+ yield* (0, styleScopedClasses_1.generateStyleScopedClassReference)(template, className, start + offset);
281
276
  }
282
277
  }
283
278
  else if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
@@ -46,14 +46,6 @@ const stringLiteralKey_1 = require("../utils/stringLiteralKey");
46
46
  const elementProps_1 = require("./elementProps");
47
47
  const interpolation_1 = require("./interpolation");
48
48
  const objectProperty_1 = require("./objectProperty");
49
- const builtInDirectives = new Set([
50
- 'cloak',
51
- 'html',
52
- 'memo',
53
- 'once',
54
- 'show',
55
- 'text',
56
- ]);
57
49
  function* generateElementDirectives(options, ctx, node) {
58
50
  for (const prop of node.props) {
59
51
  if (prop.type !== CompilerDOM.NodeTypes.DIRECTIVE
@@ -83,9 +75,9 @@ function* generateIdentifier(options, ctx, prop) {
83
75
  yield `.`;
84
76
  yield* (0, camelized_1.generateCamelized)(rawName, 'template', prop.loc.start.offset, {
85
77
  ...codeFeatures_1.codeFeatures.withoutHighlightAndCompletion,
86
- verification: options.vueCompilerOptions.checkUnknownDirectives && !builtInDirectives.has(prop.name),
78
+ verification: options.vueCompilerOptions.checkUnknownDirectives && !(0, shared_1.isBuiltInDirective)(prop.name),
87
79
  });
88
- if (!builtInDirectives.has(prop.name)) {
80
+ if (!(0, shared_1.isBuiltInDirective)(prop.name)) {
89
81
  ctx.recordComponentAccess('template', (0, shared_1.camelize)(rawName), prop.loc.start.offset);
90
82
  }
91
83
  yield (0, boundary_1.endBoundary)(token, startOffset + rawName.length);
@@ -154,7 +154,16 @@ function* generateElementProps(options, ctx, node, props, strictPropsCheck, fail
154
154
  yield `...{ `;
155
155
  }
156
156
  const token = yield* (0, boundary_1.startBoundary)('template', prop.loc.start.offset, codeFeatures_1.codeFeatures.verification);
157
- yield* (0, objectProperty_1.generateObjectProperty)(options, ctx, prop.name, prop.loc.start.offset, features, shouldCamelize);
157
+ const prefix = options.template.content.slice(prop.loc.start.offset, prop.loc.start.offset + 1);
158
+ if (prefix === '.' || prefix === '#') {
159
+ // Pug shorthand syntax
160
+ for (const char of prop.name) {
161
+ yield [char, 'template', prop.loc.start.offset, features];
162
+ }
163
+ }
164
+ else {
165
+ yield* (0, objectProperty_1.generateObjectProperty)(options, ctx, prop.name, prop.loc.start.offset, features, shouldCamelize);
166
+ }
158
167
  yield `: `;
159
168
  if (prop.name === 'style') {
160
169
  yield `{}`;
@@ -197,7 +206,10 @@ function* generatePropExp(options, ctx, prop, exp) {
197
206
  else {
198
207
  const propVariableName = (0, shared_1.camelize)(exp.loc.source);
199
208
  if (utils_1.identifierRegex.test(propVariableName)) {
200
- const codes = (0, camelized_1.generateCamelized)(exp.loc.source, 'template', exp.loc.start.offset, codeFeatures_1.codeFeatures.withoutHighlightAndCompletion);
209
+ const codes = (0, camelized_1.generateCamelized)(exp.loc.source, 'template', exp.loc.start.offset, {
210
+ ...codeFeatures_1.codeFeatures.withoutHighlightAndCompletion,
211
+ __shorthandExpression: 'html',
212
+ });
201
213
  if (ctx.scopes.some(scope => scope.has(propVariableName))) {
202
214
  yield* codes;
203
215
  }
@@ -69,7 +69,9 @@ function* generateInterpolation({ typescript, setupRefs }, ctx, block, data, cod
69
69
  start + offset,
70
70
  type === 'errorMappingOnly'
71
71
  ? codeFeatures_1.codeFeatures.verification
72
- : data,
72
+ : type === 'shorthand'
73
+ ? { ...data, __shorthandExpression: 'js' }
74
+ : data,
73
75
  ];
74
76
  }
75
77
  yield addSuffix;
@@ -100,7 +102,7 @@ function* forEachInterpolationSegment(ts, setupRefs, ctx, block, originalCode, s
100
102
  yield names.ctx;
101
103
  }
102
104
  yield `.`;
103
- yield [name, offset];
105
+ yield [name, offset, isShorthand ? 'shorthand' : undefined];
104
106
  }
105
107
  prevEnd = offset + name.length;
106
108
  }
@@ -121,7 +121,9 @@ function* generateSlotOutlet(options, ctx, node) {
121
121
  }
122
122
  const expVar = ctx.getInternalVariable();
123
123
  yield `var ${expVar} = __VLS_tryAsConstant(`;
124
- yield* (0, interpolation_1.generateInterpolation)(options, ctx, options.template, codeFeatures_1.codeFeatures.all, nameProp.exp.content, nameProp.exp.loc.start.offset);
124
+ yield* (0, interpolation_1.generateInterpolation)(options, ctx, options.template, isShortHand
125
+ ? codeFeatures_1.codeFeatures.withoutHighlightAndCompletion
126
+ : codeFeatures_1.codeFeatures.all, nameProp.exp.content, nameProp.exp.loc.start.offset);
125
127
  yield `)${utils_1.endOfLine}`;
126
128
  ctx.dynamicSlots.push({
127
129
  expVar: ctx.getHoistVariable(expVar),
@@ -119,25 +119,27 @@ class CompilerOptionsResolver {
119
119
  }
120
120
  break;
121
121
  case 'plugins':
122
- this.plugins = (options.plugins ?? [])
123
- .flatMap((pluginPath) => {
122
+ for (let raw of options.plugins ?? []) {
123
+ raw = typeof raw === 'string' ? { name: raw } : raw;
124
124
  try {
125
125
  const resolve = require?.resolve;
126
- const resolvedPath = resolve?.(pluginPath, { paths: [rootDir] });
126
+ const resolvedPath = resolve?.(raw.name, { paths: [rootDir] });
127
127
  if (resolvedPath) {
128
128
  const plugin = require(resolvedPath);
129
- plugin.__moduleName = pluginPath;
130
- return plugin;
129
+ const plugins = Array.isArray(plugin) ? plugin : [plugin];
130
+ for (const plugin of plugins) {
131
+ plugin.__moduleConfig = raw;
132
+ this.plugins.push(plugin);
133
+ }
131
134
  }
132
135
  else {
133
- console.warn('[Vue] Load plugin failed:', pluginPath);
136
+ console.warn('[Vue] Load plugin failed:', raw.name);
134
137
  }
135
138
  }
136
139
  catch (error) {
137
- console.warn('[Vue] Resolve plugin path failed:', pluginPath, error);
140
+ console.warn('[Vue] Resolve plugin path failed:', raw.name, error);
138
141
  }
139
- return [];
140
- });
142
+ }
141
143
  break;
142
144
  default:
143
145
  // @ts-expect-error
package/lib/plugins.js CHANGED
@@ -55,15 +55,15 @@ function createPlugins(pluginContext) {
55
55
  const pluginInstances = plugins
56
56
  .flatMap(plugin => {
57
57
  try {
58
- const instance = plugin(pluginContext);
59
- const moduleName = plugin.__moduleName;
58
+ const moduleConfig = plugin.__moduleConfig ?? {};
59
+ const instance = plugin({ ...pluginContext, ...moduleConfig });
60
60
  if (Array.isArray(instance)) {
61
61
  for (let i = 0; i < instance.length; i++) {
62
- instance[i].name ??= `${moduleName} (${i})`;
62
+ instance[i].name ??= `${moduleConfig.name} (${i})`;
63
63
  }
64
64
  }
65
65
  else {
66
- instance.name ??= moduleName;
66
+ instance.name ??= moduleConfig.name;
67
67
  }
68
68
  return instance;
69
69
  }
package/lib/types.d.ts CHANGED
@@ -9,10 +9,14 @@ export { VueEmbeddedCode };
9
9
  export type RawVueCompilerOptions = Partial<Omit<VueCompilerOptions, 'target' | 'plugins'>> & {
10
10
  strictTemplates?: boolean;
11
11
  target?: 'auto' | 3 | 3.3 | 3.5 | 3.6 | 99 | number;
12
- plugins?: string[];
12
+ plugins?: RawPlugin[];
13
13
  };
14
+ export type RawPlugin = string | (Record<string, any> & {
15
+ name: string;
16
+ });
14
17
  export interface VueCodeInformation extends CodeInformation {
15
18
  __importCompletion?: boolean;
19
+ __shorthandExpression?: 'html' | 'js';
16
20
  __combineToken?: symbol;
17
21
  __linkedToken?: symbol;
18
22
  }
@@ -93,7 +97,7 @@ export interface VueLanguagePluginReturn {
93
97
  }[];
94
98
  resolveEmbeddedCode?(fileName: string, sfc: Sfc, embeddedFile: VueEmbeddedCode): void;
95
99
  }
96
- export type VueLanguagePlugin = (ctx: {
100
+ export type VueLanguagePlugin = (ctx: Record<string, any> & {
97
101
  modules: {
98
102
  typescript: typeof ts;
99
103
  '@vue/compiler-dom': typeof CompilerDOM;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue/language-core",
3
- "version": "3.2.1",
3
+ "version": "3.2.3",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "**/*.js",
@@ -28,5 +28,5 @@
28
28
  "@volar/typescript": "2.4.27",
29
29
  "@vue/compiler-sfc": "^3.5.0"
30
30
  },
31
- "gitHead": "fad5a89205579e6a0902d7ee5bae3db7b510e2f4"
31
+ "gitHead": "efc6882ab62a518b41ab5c8dc1d762c41c862ebc"
32
32
  }
@@ -93,6 +93,9 @@ declare global {
93
93
  ) => any;
94
94
  }
95
95
  >;
96
+ type __VLS_ShortEmits<E extends Record<string, any[]>> = __VLS_UnionToIntersection<
97
+ { [K in keyof E]: (event: K, ...args: E[K]) => void }[keyof E]
98
+ >;
96
99
  type __VLS_ShortEmitsToObject<E> = E extends Record<string, any[]> ? { [K in keyof E]: (...args: E[K]) => any }
97
100
  : E;
98
101
  type __VLS_ResolveEmits<
@@ -110,7 +113,7 @@ declare global {
110
113
  : T extends string ? [string, number][]
111
114
  : T extends (infer U)[] ? [U, number][]
112
115
  : T extends Iterable<infer V> ? [V, number][]
113
- : [T[keyof T], `${keyof T & (string | number)}`, number][];
116
+ : [T[keyof T], keyof T extends string ? keyof T : `${keyof T & (string | number)}`, number][];
114
117
  function __VLS_vSlot<S, D extends S>(slot: S, decl?: D): D extends (...args: infer P) => any ? P : any[];
115
118
  function __VLS_asFunctionalDirective<T, ObjectDirective>(
116
119
  dir: T,