New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@vue/language-core

Package Overview
Dependencies
Maintainers
0
Versions
86
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@vue/language-core - npm Package Compare versions

Comparing version 2.2.2 to 2.2.4

lib/codegen/style/classProperty.d.ts

48

lib/codegen/globalTypes.js

@@ -37,7 +37,3 @@ "use strict";

const __VLS_nativeElements = {
...{} as SVGElementTagNameMap,
...{} as HTMLElementTagNameMap,
};
type __VLS_NativeElements = __VLS_SpreadMerge<SVGElementTagNameMap, HTMLElementTagNameMap>;
type __VLS_IntrinsicElements = ${(target >= 3.3

@@ -55,3 +51,3 @@ ? `import('${lib}/jsx-runtime').JSX.IntrinsicElements;`

type __VLS_PickNotAny<A, B> = __VLS_IsAny<A> extends true ? B : A;
type __VLS_unknownDirective = (arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown) => void;
type __VLS_SpreadMerge<A, B> = Omit<A, keyof B> & B;
type __VLS_WithComponent<N0 extends string, LocalComponents, Self, N1 extends string, N2 extends string, N3 extends string> =

@@ -119,17 +115,10 @@ N1 extends keyof LocalComponents ? N1 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : { [K in N0]: LocalComponents[N1] } :

function __VLS_getVForSourceType(source: number): [number, number][];
function __VLS_getVForSourceType(source: string): [string, number][];
function __VLS_getVForSourceType<T extends any[]>(source: T): [
item: T[number],
function __VLS_getVForSourceType<T extends number | string | any[] | Iterable<any>>(source: T): [
item: T extends number ? number
: T extends string ? string
: T extends any[] ? T[number]
: T extends Iterable<infer T1> ? T1
: any,
index: number,
][];
function __VLS_getVForSourceType<T extends { [Symbol.iterator](): Iterator<any> }>(source: T): [
item: T extends { [Symbol.iterator](): Iterator<infer T1> } ? T1 : never,
index: number,
][];
// #3845
function __VLS_getVForSourceType<T extends number | { [Symbol.iterator](): Iterator<any> }>(source: T): [
item: number | (Exclude<T, number> extends { [Symbol.iterator](): Iterator<infer T1> } ? T1 : never),
index: number,
][];
function __VLS_getVForSourceType<T>(source: T): [

@@ -148,18 +137,21 @@ item: T[keyof T],

? T
: __VLS_unknownDirective;
function __VLS_withScope<T, K>(ctx: T, scope: K): ctx is T & K;
: (arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown) => void;
function __VLS_makeOptional<T>(t: T): { [K in keyof T]?: T[K] };
function __VLS_asFunctionalComponent<T, K = T extends new (...args: any) => any ? InstanceType<T> : unknown>(t: T, instance?: K):
T extends new (...args: any) => any
? (props: ${fnPropsType}, ctx?: any) => __VLS_Element & { __ctx?: {
attrs?: any,
slots?: K extends { ${(0, shared_1.getSlotsPropertyName)(target)}: infer Slots } ? Slots : any,
emit?: K extends { $emit: infer Emit } ? Emit : any
} & { props?: ${fnPropsType}; expose?(exposed: K): void; } }
? (props: ${fnPropsType}, ctx?: any) => __VLS_Element & {
__ctx?: {
attrs?: any;
slots?: K extends { ${(0, shared_1.getSlotsPropertyName)(target)}: infer Slots } ? Slots : any;
emit?: K extends { $emit: infer Emit } ? Emit : any;
expose?(exposed: K): void;
props?: ${fnPropsType};
}
}
: T extends () => any ? (props: {}, ctx?: any) => ReturnType<T>
: T extends (...args: any) => any ? T
: (_: {}${checkUnknownProps ? '' : ' & Record<string, unknown>'}, ctx?: any) => { __ctx?: { attrs?: any, expose?: any, slots?: any, emit?: any, props?: {}${checkUnknownProps ? '' : ' & Record<string, unknown>'} } };
function __VLS_asFunctionalElement<T>(tag: T, endTag?: T): (_: T${checkUnknownComponents ? '' : ' & Record<string, unknown>'}) => void;
function __VLS_functionalComponentArgsRest<T extends (...args: any) => any>(t: T): 2 extends Parameters<T>['length'] ? [any] : [];
function __VLS_normalizeSlot<S>(s: S): S extends () => infer R ? (props: {}) => R : S;
function __VLS_asFunctionalElement<T>(tag: T, endTag?: T): (attrs: T${checkUnknownComponents ? '' : ' & Record<string, unknown>'}) => void;
function __VLS_asFunctionalSlot<S>(slot: S): (props: NonNullable<S> extends (props: infer P) => any ? P : {}) => void;
function __VLS_tryAsConstant<const T>(t: T): T;

@@ -166,0 +158,0 @@ }

@@ -35,2 +35,12 @@ "use strict";

}
if (options.vueCompilerOptions.target >= 3.5
&& options.vueCompilerOptions.inferComponentDollarRefs
&& options.templateCodegen?.templateRefs.size) {
yield `__typeRefs: {} as __VLS_TemplateRefs,${utils_1.newLine}`;
}
if (options.vueCompilerOptions.target >= 3.5
&& options.vueCompilerOptions.inferComponentDollarEl
&& options.templateCodegen?.singleRootElTypes.length) {
yield `__typeEl: {} as __VLS_RootEl,${utils_1.newLine}`;
}
if (options.sfc.script && options.scriptRanges?.exportDefault?.args) {

@@ -40,8 +50,2 @@ const { args } = options.scriptRanges.exportDefault;

}
if (options.vueCompilerOptions.target >= 3.5 && options.templateCodegen?.templateRefs.size) {
yield `__typeRefs: {} as __VLS_TemplateRefs,${utils_1.newLine}`;
}
if (options.vueCompilerOptions.target >= 3.5 && options.templateCodegen?.singleRootElType) {
yield `__typeEl: {} as __VLS_RootEl,${utils_1.newLine}`;
}
yield `})`;

@@ -48,0 +52,0 @@ }

@@ -13,3 +13,2 @@ "use strict";

const src_1 = require("./src");
const styleModulesType_1 = require("./styleModulesType");
const template_1 = require("./template");

@@ -35,4 +34,7 @@ function* generateScript(options) {

if (options.sfc.script?.src) {
yield* (0, src_1.generateSrc)(options.sfc.script, options.sfc.script.src);
yield* (0, src_1.generateSrc)(options.sfc.script.src);
}
if (options.sfc.scriptSetup && options.scriptSetupRanges) {
yield* (0, scriptSetup_1.generateScriptSetupImports)(options.sfc.scriptSetup, options.scriptSetupRanges);
}
if (options.sfc.script && options.scriptRanges) {

@@ -43,3 +45,2 @@ const { exportDefault, classBlockEnd } = options.scriptRanges;

if (options.sfc.scriptSetup && options.scriptSetupRanges) {
yield* (0, scriptSetup_1.generateScriptSetupImports)(options.sfc.scriptSetup, options.scriptSetupRanges);
if (exportDefault) {

@@ -100,3 +101,2 @@ yield (0, utils_1.generateSfcBlockSection)(options.sfc.script, 0, exportDefault.expression.start, codeFeatures_1.codeFeatures.all);

else if (options.sfc.scriptSetup && options.scriptSetupRanges) {
yield* (0, scriptSetup_1.generateScriptSetupImports)(options.sfc.scriptSetup, options.scriptSetupRanges);
yield* (0, scriptSetup_1.generateScriptSetup)(options, ctx, options.sfc.scriptSetup, options.scriptSetupRanges);

@@ -114,4 +114,2 @@ }

}
// #4788
yield* (0, styleModulesType_1.generateStyleModulesType)(options, ctx);
if (options.edited) {

@@ -118,0 +116,0 @@ yield `type __VLS_IntrinsicElementsCompletion = __VLS_IntrinsicElements${utils_1.endOfLine}`;

@@ -33,13 +33,17 @@ "use strict";

}
yield `(<`;
yield [
scriptSetup.generic,
scriptSetup.name,
scriptSetup.genericOffset,
codeFeatures_1.codeFeatures.all,
];
if (!scriptSetup.generic.endsWith(`,`)) {
yield `,`;
yield `(`;
if (typeof scriptSetup.generic === 'object') {
yield `<`;
yield [
scriptSetup.generic.text,
'main',
scriptSetup.generic.offset,
codeFeatures_1.codeFeatures.all,
];
if (!scriptSetup.generic.text.endsWith(`,`)) {
yield `,`;
}
yield `>`;
}
yield `>(${utils_1.newLine}`
yield `(${utils_1.newLine}`
+ ` __VLS_props: NonNullable<Awaited<typeof __VLS_setup>>['props'],${utils_1.newLine}`

@@ -127,12 +131,14 @@ + ` __VLS_ctx?: ${ctx.localTypes.PrettifyLocal}<Pick<NonNullable<Awaited<typeof __VLS_setup>>, 'attrs' | 'emit' | 'slots'>>,${utils_1.newLine}` // use __VLS_Prettify for less dts code

}
for (const { callExp } of scriptSetupRanges.useAttrs) {
setupCodeModifies.push([
[`(`],
callExp.start,
callExp.start
], [
[` as typeof __VLS_special.$attrs)`],
callExp.end,
callExp.end
]);
if (options.vueCompilerOptions.inferTemplateDollarAttrs) {
for (const { callExp } of scriptSetupRanges.useAttrs) {
setupCodeModifies.push([
[`(`],
callExp.start,
callExp.start
], [
[` as typeof __VLS_dollars.$attrs)`],
callExp.end,
callExp.end
]);
}
}

@@ -161,3 +167,3 @@ for (const { callExp, exp, arg } of scriptSetupRanges.useCssModule) {

setupCodeModifies.push([
[`(__VLS_placeholder)`],
[`__VLS_placeholder`],
arg.start,

@@ -168,12 +174,14 @@ arg.end

}
for (const { callExp } of scriptSetupRanges.useSlots) {
setupCodeModifies.push([
[`(`],
callExp.start,
callExp.start
], [
[` as typeof __VLS_special.$slots)`],
callExp.end,
callExp.end
]);
if (options.vueCompilerOptions.inferTemplateDollarSlots) {
for (const { callExp } of scriptSetupRanges.useSlots) {
setupCodeModifies.push([
[`(`],
callExp.start,
callExp.start
], [
[` as typeof __VLS_dollars.$slots)`],
callExp.end,
callExp.end
]);
}
}

@@ -217,3 +225,3 @@ const isTs = options.lang !== 'js' && options.lang !== 'jsx';

setupCodeModifies.push([
[`(__VLS_placeholder)`],
[`__VLS_placeholder`],
arg.start,

@@ -248,3 +256,6 @@ arg.end

if (syntax) {
if (!options.vueCompilerOptions.skipTemplateCodegen && (options.templateCodegen?.hasSlot || scriptSetupRanges.defineSlots)) {
if (!options.vueCompilerOptions.skipTemplateCodegen
&& (scriptSetupRanges.defineSlots
|| options.templateCodegen?.slots.length
|| options.templateCodegen?.dynamicSlots.length)) {
yield `const __VLS_component = `;

@@ -432,3 +443,3 @@ yield* (0, component_1.generateComponent)(options, ctx, scriptSetup, scriptSetupRanges);

yield* generateDefinePropType(scriptSetup, propName, localName, defineModel);
if (!defineModel.required) {
if (!defineModel.required && defineModel.defaultValue === undefined) {
yield ` | undefined`;

@@ -435,0 +446,0 @@ }

@@ -1,2 +0,2 @@

import type { Code, Sfc } from '../../types';
export declare function generateSrc(script: NonNullable<Sfc['script']>, src: string): Generator<Code>;
import type { Code, SfcBlockAttr } from '../../types';
export declare function generateSrc(src: SfcBlockAttr): Generator<Code>;

@@ -6,47 +6,46 @@ "use strict";

const utils_1 = require("../utils");
function* generateSrc(script, src) {
if (src.endsWith('.d.ts')) {
src = src.slice(0, -'.d.ts'.length);
function* generateSrc(src) {
if (src === true) {
return;
}
else if (src.endsWith('.ts')) {
src = src.slice(0, -'.ts'.length);
let { text } = src;
if (text.endsWith('.d.ts')) {
text = text.slice(0, -'.d.ts'.length);
}
else if (src.endsWith('.tsx')) {
src = src.slice(0, -'.tsx'.length) + '.jsx';
else if (text.endsWith('.ts')) {
text = text.slice(0, -'.ts'.length);
}
if (!src.endsWith('.js') && !src.endsWith('.jsx')) {
src = src + '.js';
else if (text.endsWith('.tsx')) {
text = text.slice(0, -'.tsx'.length) + '.jsx';
}
if (!text.endsWith('.js') && !text.endsWith('.jsx')) {
text = text + '.js';
}
yield `export * from `;
yield [
`'${src}'`,
'script',
script.srcOffset - 1,
{
...codeFeatures_1.codeFeatures.all,
navigation: src === script.src
? true
: {
shouldRename: () => false,
resolveRenameEditText(newName) {
if (newName.endsWith('.jsx') || newName.endsWith('.js')) {
newName = newName.split('.').slice(0, -1).join('.');
}
if (script?.src?.endsWith('.d.ts')) {
newName = newName + '.d.ts';
}
else if (script?.src?.endsWith('.ts')) {
newName = newName + '.ts';
}
else if (script?.src?.endsWith('.tsx')) {
newName = newName + '.tsx';
}
return newName;
},
yield* (0, utils_1.generateSfcBlockAttrValue)(src, text, {
...codeFeatures_1.codeFeatures.all,
navigation: text === src.text
? true
: {
shouldRename: () => false,
resolveRenameEditText(newName) {
if (newName.endsWith('.jsx') || newName.endsWith('.js')) {
newName = newName.split('.').slice(0, -1).join('.');
}
if (src?.text.endsWith('.d.ts')) {
newName = newName + '.d.ts';
}
else if (src?.text.endsWith('.ts')) {
newName = newName + '.ts';
}
else if (src?.text.endsWith('.tsx')) {
newName = newName + '.tsx';
}
return newName;
},
},
];
},
});
yield utils_1.endOfLine;
yield `export { default } from '${src}'${utils_1.endOfLine}`;
yield `export { default } from '${text}'${utils_1.endOfLine}`;
}
//# sourceMappingURL=src.js.map
import type { Code } from '../../types';
import { TemplateCodegenContext } from '../template/context';
import { type TemplateCodegenContext } from '../template/context';
import type { ScriptCodegenContext } from './context';

@@ -7,3 +7,2 @@ import type { ScriptCodegenOptions } from './index';

export declare function generateTemplateDirectives(options: ScriptCodegenOptions): Generator<Code>;
export declare function generateCssClassProperty(styleIndex: number, classNameWithDot: string, offset: number, propertyType: string, optional: boolean): Generator<Code>;
export declare function getTemplateUsageVars(options: ScriptCodegenOptions, ctx: ScriptCodegenContext): Set<string>;

@@ -5,6 +5,7 @@ "use strict";

exports.generateTemplateDirectives = generateTemplateDirectives;
exports.generateCssClassProperty = generateCssClassProperty;
exports.getTemplateUsageVars = getTemplateUsageVars;
const shared_1 = require("../../utils/shared");
const codeFeatures_1 = require("../codeFeatures");
const modules_1 = require("../style/modules");
const scopedClasses_1 = require("../style/scopedClasses");
const context_1 = require("../template/context");

@@ -97,4 +98,5 @@ const interpolation_1 = require("../template/interpolation");

function* generateTemplateBody(options, templateCodegenCtx) {
yield* generateStyleScopedClasses(options, templateCodegenCtx);
yield* (0, scopedClasses_1.generateStyleScopedClasses)(options, templateCodegenCtx);
yield* (0, styleScopedClasses_1.generateStyleScopedClassReferences)(templateCodegenCtx, true);
yield* (0, modules_1.generateStyleModules)(options);
yield* generateCssVars(options, templateCodegenCtx);

@@ -116,50 +118,2 @@ if (options.templateCodegen) {

}
function* generateStyleScopedClasses(options, ctx) {
const firstClasses = new Set();
yield `type __VLS_StyleScopedClasses = {}`;
for (let i = 0; i < options.sfc.styles.length; i++) {
const style = options.sfc.styles[i];
const option = options.vueCompilerOptions.experimentalResolveStyleCssClasses;
if (option === 'always' || (option === 'scoped' && style.scoped)) {
for (const className of style.classNames) {
if (firstClasses.has(className.text)) {
ctx.scopedClasses.push({
source: 'style_' + i,
className: className.text.slice(1),
offset: className.offset + 1
});
continue;
}
firstClasses.add(className.text);
yield* generateCssClassProperty(i, className.text, className.offset, 'boolean', true);
}
}
}
yield utils_1.endOfLine;
}
function* generateCssClassProperty(styleIndex, classNameWithDot, offset, propertyType, optional) {
yield `${utils_1.newLine} & { `;
yield [
'',
'style_' + styleIndex,
offset,
codeFeatures_1.codeFeatures.navigation,
];
yield `'`;
yield [
classNameWithDot.slice(1),
'style_' + styleIndex,
offset + 1,
codeFeatures_1.codeFeatures.navigation,
];
yield `'`;
yield [
'',
'style_' + styleIndex,
offset + classNameWithDot.length,
codeFeatures_1.codeFeatures.navigationWithoutRename,
];
yield `${optional ? '?' : ''}: ${propertyType}`;
yield ` }`;
}
function* generateCssVars(options, ctx) {

@@ -166,0 +120,0 @@ if (!options.sfc.styles.length) {

@@ -6,2 +6,99 @@ import type * as CompilerDOM from '@vue/compiler-dom';

export type TemplateCodegenContext = ReturnType<typeof createTemplateCodegenContext>;
/**
* Creates and returns a Context object used for generating type-checkable TS code
* from the template section of a .vue file.
*
* ## Implementation Notes for supporting `@vue-ignore`, `@vue-expect-error`, and `@vue-skip` directives.
*
* Vue language tooling supports a number of directives for suppressing diagnostics within
* Vue templates (https://github.com/vuejs/language-tools/pull/3215)
*
* Here is an overview for how support for how @vue-expect-error is implemented within this file
* (@vue-expect-error is the most complicated directive to support due to its behavior of raising
* a diagnostic when it is annotating a piece of code that doesn't actually have any errors/warning/diagnostics).
*
* Given .vue code:
*
* ```vue
* <script setup lang="ts">
* defineProps<{
* knownProp1: string;
* knownProp2: string;
* knownProp3: string;
* knownProp4_will_trigger_unused_expect_error: string;
* }>();
* </script>
*
* <template>
* {{ knownProp1 }}
* {{ error_unknownProp }} <!-- ERROR: Property 'error_unknownProp' does not exist on type [...] -->
* {{ knownProp2 }}
* <!-- @vue-expect-error This suppresses an Unknown Property Error -->
* {{ suppressed_error_unknownProp }}
* {{ knownProp3 }}
* <!-- @vue-expect-error This will trigger Unused '@ts-expect-error' directive.ts(2578) -->
* {{ knownProp4_will_trigger_unused_expect_error }}
* </template>
* ```
*
* The above code should raise two diagnostics:
*
* 1. Property 'error_unknownProp' does not exist on type [...]
* 2. Unused '@ts-expect-error' directive.ts(2578) -- this is the bottom `@vue-expect-error` directive
* that covers code that doesn't actually raise an error -- note that all `@vue-...` directives
* will ultimately translate into `@ts-...` diagnostics.
*
* The above code will produce the following type-checkable TS code (note: omitting asterisks
* to prevent VSCode syntax double-greying out double-commented code).
*
* ```ts
* ( __VLS_ctx.knownProp1 );
* ( __VLS_ctx.error_unknownProp ); // ERROR: Property 'error_unknownProp' does not exist on type [...]
* ( __VLS_ctx.knownProp2 );
* // @vue-expect-error start
* ( __VLS_ctx.suppressed_error_unknownProp );
* // @ts-expect-error __VLS_TS_EXPECT_ERROR
* ;
* // @vue-expect-error end of INTERPOLATION
* ( __VLS_ctx.knownProp3 );
* // @vue-expect-error start
* ( __VLS_ctx.knownProp4_will_trigger_unused_expect_error );
* // @ts-expect-error __VLS_TS_EXPECT_ERROR
* ;
* // @vue-expect-error end of INTERPOLATION
* ```
*
* In the generated code, there are actually 3 diagnostic errors that'll be raised in the first
* pass on this generated code (but through cleverness described below, not all of them will be
* propagated back to the original .vue file):
*
* 1. Property 'error_unknownProp' does not exist on type [...]
* 2. Unused '@ts-expect-error' directive.ts(2578) from the 1st `@ts-expect-error __VLS_TS_EXPECT_ERROR`
* 3. Unused '@ts-expect-error' directive.ts(2578) from the 2nd `@ts-expect-error __VLS_TS_EXPECT_ERROR`
*
* Be sure to pay careful attention to the mixture of `@vue-expect-error` and `@ts-expect-error`;
* Within the TS file, the only "real" directives recognized by TS are going to be prefixed with `@ts-`;
* any `@vue-` prefixed directives in the comments are only for debugging purposes.
*
* As mentioned above, there are 3 diagnostics errors that'll be generated for the above code, but
* only 2 should be propagated back to the original .vue file.
*
* (The reason we structure things this way is somewhat complicated, but in short it allows us
* to lean on TS as much as possible to generate actual `unused @ts-expect-error directive` errors
* while covering a number of edge cases.)
*
* So, we need a way to dynamically decide whether each of the `@ts-expect-error __VLS_TS_EXPECT_ERROR`
* directives should be reported as an unused directive or not.
*
* To do this, we'll make use of the `shouldReport` callback that'll optionally be provided to the
* `verification` property of the `CodeInformation` object attached to the mapping between source .vue
* and generated .ts code. The `verification` property determines whether "verification" (which includes
* semantic diagnostics) should be performed on the generated .ts code, and `shouldReport`, if provided,
* can be used to determine whether a given diagnostic should be reported back "upwards" to the original
* .vue file or not.
*
* See the comments in the code below for how and where we use this hook to keep track of whether
* an error/diagnostic was encountered for a region of code covered by a `@vue-expect-error` directive,
* and additionally how we use that to determine whether to propagate diagnostics back upward.
*/
export declare function createTemplateCodegenContext(options: Pick<TemplateCodegenOptions, 'scriptSetupBindingNames' | 'edited'>): {

@@ -38,3 +135,3 @@ codeFeatures: {

}[];
specialVars: Set<string>;
dollarVars: Set<string>;
accessExternalVariables: Map<string, Set<number>>;

@@ -53,6 +150,8 @@ lastGenericComment: {

inlayHints: InlayHintInfo[];
hasSlot: boolean;
bindingAttrLocs: CompilerDOM.SourceLocation[];
inheritedAttrVars: Set<string>;
templateRefs: Map<string, [varName: string, offset: number]>;
templateRefs: Map<string, {
typeExp: string;
offset: number;
}>;
currentComponent: {

@@ -62,4 +161,4 @@ ctxVar: string;

} | undefined;
singleRootElType: string | undefined;
singleRootNode: CompilerDOM.ElementNode | undefined;
singleRootElTypes: string[];
singleRootNodes: Set<CompilerDOM.ElementNode | null>;
accessExternalVariable(name: string, offset?: number): void;

@@ -70,2 +169,4 @@ hasLocalVariable: (name: string) => boolean;

getInternalVariable: () => string;
getHoistVariable: (originalVar: string) => string;
generateHoistVariables: () => Generator<string, void, unknown>;
ignoreError: () => Generator<Code>;

@@ -72,0 +173,0 @@ expectError: (prevNode: CompilerDOM.CommentNode) => Generator<Code>;

@@ -6,2 +6,99 @@ "use strict";

const utils_1 = require("../utils");
/**
* Creates and returns a Context object used for generating type-checkable TS code
* from the template section of a .vue file.
*
* ## Implementation Notes for supporting `@vue-ignore`, `@vue-expect-error`, and `@vue-skip` directives.
*
* Vue language tooling supports a number of directives for suppressing diagnostics within
* Vue templates (https://github.com/vuejs/language-tools/pull/3215)
*
* Here is an overview for how support for how @vue-expect-error is implemented within this file
* (@vue-expect-error is the most complicated directive to support due to its behavior of raising
* a diagnostic when it is annotating a piece of code that doesn't actually have any errors/warning/diagnostics).
*
* Given .vue code:
*
* ```vue
* <script setup lang="ts">
* defineProps<{
* knownProp1: string;
* knownProp2: string;
* knownProp3: string;
* knownProp4_will_trigger_unused_expect_error: string;
* }>();
* </script>
*
* <template>
* {{ knownProp1 }}
* {{ error_unknownProp }} <!-- ERROR: Property 'error_unknownProp' does not exist on type [...] -->
* {{ knownProp2 }}
* <!-- @vue-expect-error This suppresses an Unknown Property Error -->
* {{ suppressed_error_unknownProp }}
* {{ knownProp3 }}
* <!-- @vue-expect-error This will trigger Unused '@ts-expect-error' directive.ts(2578) -->
* {{ knownProp4_will_trigger_unused_expect_error }}
* </template>
* ```
*
* The above code should raise two diagnostics:
*
* 1. Property 'error_unknownProp' does not exist on type [...]
* 2. Unused '@ts-expect-error' directive.ts(2578) -- this is the bottom `@vue-expect-error` directive
* that covers code that doesn't actually raise an error -- note that all `@vue-...` directives
* will ultimately translate into `@ts-...` diagnostics.
*
* The above code will produce the following type-checkable TS code (note: omitting asterisks
* to prevent VSCode syntax double-greying out double-commented code).
*
* ```ts
* ( __VLS_ctx.knownProp1 );
* ( __VLS_ctx.error_unknownProp ); // ERROR: Property 'error_unknownProp' does not exist on type [...]
* ( __VLS_ctx.knownProp2 );
* // @vue-expect-error start
* ( __VLS_ctx.suppressed_error_unknownProp );
* // @ts-expect-error __VLS_TS_EXPECT_ERROR
* ;
* // @vue-expect-error end of INTERPOLATION
* ( __VLS_ctx.knownProp3 );
* // @vue-expect-error start
* ( __VLS_ctx.knownProp4_will_trigger_unused_expect_error );
* // @ts-expect-error __VLS_TS_EXPECT_ERROR
* ;
* // @vue-expect-error end of INTERPOLATION
* ```
*
* In the generated code, there are actually 3 diagnostic errors that'll be raised in the first
* pass on this generated code (but through cleverness described below, not all of them will be
* propagated back to the original .vue file):
*
* 1. Property 'error_unknownProp' does not exist on type [...]
* 2. Unused '@ts-expect-error' directive.ts(2578) from the 1st `@ts-expect-error __VLS_TS_EXPECT_ERROR`
* 3. Unused '@ts-expect-error' directive.ts(2578) from the 2nd `@ts-expect-error __VLS_TS_EXPECT_ERROR`
*
* Be sure to pay careful attention to the mixture of `@vue-expect-error` and `@ts-expect-error`;
* Within the TS file, the only "real" directives recognized by TS are going to be prefixed with `@ts-`;
* any `@vue-` prefixed directives in the comments are only for debugging purposes.
*
* As mentioned above, there are 3 diagnostics errors that'll be generated for the above code, but
* only 2 should be propagated back to the original .vue file.
*
* (The reason we structure things this way is somewhat complicated, but in short it allows us
* to lean on TS as much as possible to generate actual `unused @ts-expect-error directive` errors
* while covering a number of edge cases.)
*
* So, we need a way to dynamically decide whether each of the `@ts-expect-error __VLS_TS_EXPECT_ERROR`
* directives should be reported as an unused directive or not.
*
* To do this, we'll make use of the `shouldReport` callback that'll optionally be provided to the
* `verification` property of the `CodeInformation` object attached to the mapping between source .vue
* and generated .ts code. The `verification` property determines whether "verification" (which includes
* semantic diagnostics) should be performed on the generated .ts code, and `shouldReport`, if provided,
* can be used to determine whether a given diagnostic should be reported back "upwards" to the original
* .vue file or not.
*
* See the comments in the code below for how and where we use this hook to keep track of whether
* an error/diagnostic was encountered for a region of code covered by a `@vue-expect-error` directive,
* and additionally how we use that to determine whether to propagate diagnostics back upward.
*/
function createTemplateCodegenContext(options) {

@@ -15,2 +112,4 @@ let ignoredError = false;

if (ignoredError) {
// We are currently in a region of code covered by a @vue-ignore directive, so don't
// even bother performing any type-checking: set verification to false.
return {

@@ -22,2 +121,6 @@ ...features,

if (expectErrorToken) {
// We are currently in a region of code covered by a @vue-expect-error directive. We need to
// keep track of the number of errors encountered within this region so that we can know whether
// we will need to propagate an "unused ts-expect-error" diagnostic back to the original
// .vue file or not.
const token = expectErrorToken;

@@ -37,4 +140,5 @@ return {

}
const hoistVars = new Map();
const localVars = new Map();
const specialVars = new Set();
const dollarVars = new Set();
const accessExternalVariables = new Map();

@@ -60,3 +164,3 @@ const slots = [];

dynamicSlots,
specialVars,
dollarVars,
accessExternalVariables,

@@ -68,3 +172,2 @@ lastGenericComment,

inlayHints,
hasSlot: false,
bindingAttrLocs,

@@ -74,4 +177,4 @@ inheritedAttrVars,

currentComponent: undefined,
singleRootElType: undefined,
singleRootNode: undefined,
singleRootElTypes: [],
singleRootNodes: new Set(),
accessExternalVariable(name, offset) {

@@ -98,2 +201,20 @@ let arr = accessExternalVariables.get(name);

},
getHoistVariable: (originalVar) => {
let name = hoistVars.get(originalVar);
if (name === undefined) {
hoistVars.set(originalVar, name = `__VLS_${variableId++}`);
}
return name;
},
generateHoistVariables: function* () {
// trick to avoid TS 4081 (#5186)
if (hoistVars.size) {
yield `// @ts-ignore${utils_1.newLine}`;
yield `var `;
for (const [originalVar, hoistVar] of hoistVars) {
yield `${hoistVar} = ${originalVar}, `;
}
yield utils_1.endOfLine;
}
},
ignoreError: function* () {

@@ -119,2 +240,5 @@ if (!ignoredError) {

verification: {
// If no errors/warnings/diagnostics were reported within the region of code covered
// by the @vue-expect-error directive, then we should allow any `unused @ts-expect-error`
// diagnostics to be reported upward.
shouldReport: () => token.errors === 0,

@@ -121,0 +245,0 @@ },

@@ -5,3 +5,3 @@ import * as CompilerDOM from '@vue/compiler-dom';

import type { TemplateCodegenOptions } from './index';
export declare function generateComponent(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.ElementNode): Generator<Code>;
export declare function generateComponent(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.ElementNode, isVForChild: boolean): Generator<Code>;
export declare function generateElement(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.ElementNode, isVForChild: boolean): Generator<Code>;

@@ -20,3 +20,3 @@ "use strict";

const colonReg = /:/g;
function* generateComponent(options, ctx, node) {
function* generateComponent(options, ctx, node, isVForChild) {
const tagOffsets = [node.loc.start.offset + options.template.content.slice(node.loc.start.offset).indexOf(node.tag)];

@@ -32,11 +32,9 @@ if (!node.isSelfClosing && options.template.lang === 'html') {

const matchImportName = possibleOriginalNames.find(name => options.scriptSetupImportComponentNames.has(name));
const var_originalComponent = matchImportName ?? ctx.getInternalVariable();
const var_functionalComponent = ctx.getInternalVariable();
const var_componentInstance = ctx.getInternalVariable();
const var_componentEmit = ctx.getInternalVariable();
const var_componentEvents = ctx.getInternalVariable();
const var_defineComponentCtx = ctx.getInternalVariable();
const componentOriginalVar = matchImportName ?? ctx.getInternalVariable();
const componentFunctionalVar = ctx.getInternalVariable();
const componentVNodeVar = ctx.getInternalVariable();
const componentCtxVar = ctx.getInternalVariable();
const isComponentTag = node.tag.toLowerCase() === 'component';
ctx.currentComponent = {
ctxVar: var_defineComponentCtx,
ctxVar: componentCtxVar,
used: false

@@ -74,10 +72,9 @@ };

if (matchImportName) {
// hover, renaming / find references support
yield `// @ts-ignore${utils_1.newLine}`; // #2304
yield `/** @type { [`;
// navigation support
yield `/** @type {[`;
for (const tagOffset of tagOffsets) {
yield `typeof `;
if (var_originalComponent === node.tag) {
if (componentOriginalVar === node.tag) {
yield [
var_originalComponent,
componentOriginalVar,
'template',

@@ -100,10 +97,10 @@ tagOffset,

}
yield `] } */${utils_1.endOfLine}`;
yield `]} */${utils_1.endOfLine}`;
}
else if (dynamicTagInfo) {
yield `const ${var_originalComponent} = (`;
yield* (0, interpolation_1.generateInterpolation)(options, ctx, 'template', ctx.codeFeatures.all, dynamicTagInfo.tag, dynamicTagInfo.offsets[0], dynamicTagInfo.astHolder, '(', ')');
yield `const ${componentOriginalVar} = (`;
yield* (0, interpolation_1.generateInterpolation)(options, ctx, 'template', ctx.codeFeatures.all, dynamicTagInfo.tag, dynamicTagInfo.offsets[0], dynamicTagInfo.astHolder, `(`, `)`);
if (dynamicTagInfo.offsets[1] !== undefined) {
yield `,`;
yield* (0, interpolation_1.generateInterpolation)(options, ctx, 'template', ctx.codeFeatures.withoutCompletion, dynamicTagInfo.tag, dynamicTagInfo.offsets[1], dynamicTagInfo.astHolder, '(', ')');
yield* (0, interpolation_1.generateInterpolation)(options, ctx, 'template', ctx.codeFeatures.withoutCompletion, dynamicTagInfo.tag, dynamicTagInfo.offsets[1], dynamicTagInfo.astHolder, `(`, `)`);
}

@@ -113,3 +110,3 @@ yield `)${utils_1.endOfLine}`;

else if (!isComponentTag) {
yield `const ${var_originalComponent} = ({} as __VLS_WithComponent<'${getCanonicalComponentName(node.tag)}', __VLS_LocalComponents, `;
yield `const ${componentOriginalVar} = ({} as __VLS_WithComponent<'${getCanonicalComponentName(node.tag)}', __VLS_LocalComponents, `;
if (options.selfComponentName && possibleOriginalNames.includes(options.selfComponentName)) {

@@ -131,4 +128,4 @@ yield `typeof __VLS_self & (new () => { `

if (utils_1.variableNameRegex.test(camelizedTag)) {
// renaming / find references support
yield `/** @type { [`;
// navigation support
yield `/** @type {[`;
for (const tagOffset of tagOffsets) {

@@ -147,3 +144,3 @@ for (const shouldCapitalize of (node.tag[0] === node.tag[0].toUpperCase() ? [false] : [true, false])) {

}
yield `] } */${utils_1.endOfLine}`;
yield `]} */${utils_1.endOfLine}`;
// auto import support

@@ -163,6 +160,6 @@ if (options.edited) {

else {
yield `const ${var_originalComponent} = {} as any${utils_1.endOfLine}`;
yield `const ${componentOriginalVar} = {} as any${utils_1.endOfLine}`;
}
yield `// @ts-ignore${utils_1.newLine}`;
yield `const ${var_functionalComponent} = __VLS_asFunctionalComponent(${var_originalComponent}, new ${var_originalComponent}({${utils_1.newLine}`;
yield `const ${componentFunctionalVar} = __VLS_asFunctionalComponent(${componentOriginalVar}, new ${componentOriginalVar}({${utils_1.newLine}`;
yield* (0, elementProps_1.generateElementProps)(options, ctx, node, props, options.vueCompilerOptions.checkUnknownProps, false);

@@ -174,42 +171,42 @@ yield `}))${utils_1.endOfLine}`;

shouldReport(_source, code) {
// https://typescript.tv/errors/#ts6133
return String(code) !== '6133';
},
}
}), var_componentInstance);
yield ` = ${var_functionalComponent}`;
}), componentVNodeVar);
yield ` = ${componentFunctionalVar}`;
yield* generateComponentGeneric(ctx);
yield `(`;
yield* (0, utils_1.wrapWith)(tagOffsets[0], tagOffsets[0] + node.tag.length, ctx.codeFeatures.verification, `{${utils_1.newLine}`, ...(0, elementProps_1.generateElementProps)(options, ctx, node, props, options.vueCompilerOptions.checkUnknownProps, true, failedPropExps), `}`);
yield `, ...__VLS_functionalComponentArgsRest(${var_functionalComponent}))${utils_1.endOfLine}`;
yield `, ...__VLS_functionalComponentArgsRest(${componentFunctionalVar}))${utils_1.endOfLine}`;
yield* generateFailedPropExps(options, ctx, failedPropExps);
const [refName, offset] = yield* generateVScope(options, ctx, node, props);
const isRootNode = node === ctx.singleRootNode;
yield* (0, elementEvents_1.generateElementEvents)(options, ctx, node, componentFunctionalVar, componentVNodeVar, componentCtxVar);
yield* (0, elementDirectives_1.generateElementDirectives)(options, ctx, node);
const [refName, offset] = yield* generateElementReference(options, ctx, node);
const tag = (0, shared_2.hyphenateTag)(node.tag);
const isRootNode = ctx.singleRootNodes.has(node) && !options.vueCompilerOptions.fallthroughComponentNames.includes(tag);
if (refName || isRootNode) {
const varName = ctx.getInternalVariable();
const componentInstanceVar = ctx.getInternalVariable();
ctx.currentComponent.used = true;
yield `var ${varName} = {} as (Parameters<NonNullable<typeof ${var_defineComponentCtx}['expose']>>[0] | null)`;
if (node.codegenNode?.type === CompilerDOM.NodeTypes.VNODE_CALL
&& node.codegenNode.props?.type === CompilerDOM.NodeTypes.JS_OBJECT_EXPRESSION
&& node.codegenNode.props.properties.some(({ key }) => key.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION && key.content === 'ref_for')) {
yield `var ${componentInstanceVar} = {} as (Parameters<NonNullable<typeof ${componentCtxVar}['expose']>>[0] | null)`;
if (isVForChild) {
yield `[]`;
}
yield `${utils_1.endOfLine}`;
if (refName) {
ctx.templateRefs.set(refName, [varName, offset]);
if (refName && offset) {
ctx.templateRefs.set(refName, {
typeExp: `typeof ${ctx.getHoistVariable(componentInstanceVar)}`,
offset
});
}
if (isRootNode) {
ctx.singleRootElType = `NonNullable<typeof ${varName}>['$el']`;
ctx.singleRootElTypes.push(`NonNullable<typeof ${componentInstanceVar}>['$el']`);
}
}
const usedComponentEventsVar = yield* (0, elementEvents_1.generateElementEvents)(options, ctx, node, var_functionalComponent, var_componentInstance, var_componentEvents);
if (usedComponentEventsVar) {
ctx.currentComponent.used = true;
yield `let ${var_componentEmit}!: typeof ${var_defineComponentCtx}.emit${utils_1.endOfLine}`;
yield `let ${var_componentEvents}!: __VLS_NormalizeEmits<typeof ${var_componentEmit}>${utils_1.endOfLine}`;
}
if (hasVBindAttrs(options, ctx, node)) {
const attrsVar = ctx.getInternalVariable();
yield `let ${attrsVar}!: Parameters<typeof ${componentFunctionalVar}>[0]${utils_1.endOfLine}`;
ctx.inheritedAttrVars.add(attrsVar);
yield `let ${attrsVar}!: Parameters<typeof ${var_functionalComponent}>[0];\n`;
}
(0, styleScopedClasses_1.collectStyleScopedClassReferences)(options, ctx, node);
const slotDir = node.props.find(p => p.type === CompilerDOM.NodeTypes.DIRECTIVE && p.name === 'slot');

@@ -220,6 +217,8 @@ if (slotDir) {

else {
yield* (0, elementChildren_1.generateElementChildren)(options, ctx, node, true);
// #932: reference for default slot
yield* (0, vSlot_1.generateImplicitDefaultSlot)(ctx, node);
yield* (0, elementChildren_1.generateElementChildren)(options, ctx, node);
}
if (ctx.currentComponent.used) {
yield `var ${var_defineComponentCtx}!: __VLS_PickFunctionalComponentCtx<typeof ${var_originalComponent}, typeof ${var_componentInstance}>${utils_1.endOfLine}`;
yield `var ${componentCtxVar}!: __VLS_PickFunctionalComponentCtx<typeof ${componentOriginalVar}, typeof ${componentVNodeVar}>${utils_1.endOfLine}`;
}

@@ -243,12 +242,16 @@ }

yield* generateFailedPropExps(options, ctx, failedPropExps);
const [refName, offset] = yield* generateVScope(options, ctx, node, node.props);
if (refName) {
let refValue = `__VLS_nativeElements['${node.tag}']`;
yield* (0, elementDirectives_1.generateElementDirectives)(options, ctx, node);
const [refName, offset] = yield* generateElementReference(options, ctx, node);
if (refName && offset) {
let typeExp = `__VLS_NativeElements['${node.tag}']`;
if (isVForChild) {
refValue = `[${refValue}]`;
typeExp += `[]`;
}
ctx.templateRefs.set(refName, [refValue, offset]);
ctx.templateRefs.set(refName, {
typeExp,
offset
});
}
if (ctx.singleRootNode === node) {
ctx.singleRootElType = `typeof __VLS_nativeElements['${node.tag}']`;
if (ctx.singleRootNodes.has(node)) {
ctx.singleRootElTypes.push(`__VLS_NativeElements['${node.tag}']`);
}

@@ -258,2 +261,3 @@ if (hasVBindAttrs(options, ctx, node)) {

}
(0, styleScopedClasses_1.collectStyleScopedClassReferences)(options, ctx, node);
yield* (0, elementChildren_1.generateElementChildren)(options, ctx, node);

@@ -267,30 +271,2 @@ }

}
function* generateVScope(options, ctx, node, props) {
const vScope = props.find(prop => prop.type === CompilerDOM.NodeTypes.DIRECTIVE && (prop.name === 'scope' || prop.name === 'data'));
let inScope = false;
let originalConditionsNum = ctx.blockConditions.length;
if (vScope?.type === CompilerDOM.NodeTypes.DIRECTIVE && vScope.exp) {
const scopeVar = ctx.getInternalVariable();
const condition = `__VLS_withScope(__VLS_ctx, ${scopeVar})`;
yield `const ${scopeVar} = `;
yield [
vScope.exp.loc.source,
'template',
vScope.exp.loc.start.offset,
ctx.codeFeatures.all,
];
yield utils_1.endOfLine;
yield `if (${condition}) {${utils_1.newLine}`;
ctx.blockConditions.push(condition);
inScope = true;
}
yield* (0, elementDirectives_1.generateElementDirectives)(options, ctx, node);
const [refName, offset] = yield* generateReferencesForElements(options, ctx, node); // <el ref="foo" />
(0, styleScopedClasses_1.collectStyleScopedClassReferences)(options, ctx, node);
if (inScope) {
yield `}${utils_1.newLine}`;
ctx.blockConditions.length = originalConditionsNum;
}
return [refName, offset];
}
function getCanonicalComponentName(tagText) {

@@ -334,3 +310,3 @@ return utils_1.variableNameRegex.test(tagText)

}
function* generateReferencesForElements(options, ctx, node) {
function* generateElementReference(options, ctx, node) {
for (const prop of node.props) {

@@ -341,6 +317,6 @@ if (prop.type === CompilerDOM.NodeTypes.ATTRIBUTE

const [content, startOffset] = (0, utils_1.normalizeAttributeValue)(prop.value);
yield `// @ts-ignore navigation for \`const ${content} = ref()\`${utils_1.newLine}`;
yield `/** @type { typeof __VLS_ctx`;
// navigation support for `const foo = ref()`
yield `/** @type {typeof __VLS_ctx`;
yield* (0, propertyAccess_1.generatePropertyAccess)(options, ctx, content, startOffset, ctx.codeFeatures.navigation, prop.value.loc);
yield ` } */${utils_1.endOfLine}`;
yield `} */${utils_1.endOfLine}`;
if (utils_1.variableNameRegex.test(content) && !options.templateRefNames.has(content)) {

@@ -355,3 +331,3 @@ ctx.accessExternalVariable(content, startOffset);

function hasVBindAttrs(options, ctx, node) {
return options.vueCompilerOptions.fallthroughAttributes && (node === ctx.singleRootNode ||
return options.vueCompilerOptions.fallthroughAttributes && ((options.inheritAttrs && ctx.singleRootNodes.has(node)) ||
node.props.some(prop => prop.type === CompilerDOM.NodeTypes.DIRECTIVE

@@ -358,0 +334,0 @@ && prop.name === 'bind'

@@ -5,2 +5,2 @@ import * as CompilerDOM from '@vue/compiler-dom';

import type { TemplateCodegenOptions } from './index';
export declare function generateElementChildren(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.ElementNode, isDefaultSlot?: boolean): Generator<Code>;
export declare function generateElementChildren(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.ElementNode): Generator<Code>;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateElementChildren = generateElementChildren;
const CompilerDOM = require("@vue/compiler-dom");
const utils_1 = require("../utils");
const templateChild_1 = require("./templateChild");
function* generateElementChildren(options, ctx, node, isDefaultSlot = false) {
function* generateElementChildren(options, ctx, node) {
yield* ctx.resetDirectiveComments('end of element children start');

@@ -15,13 +13,3 @@ let prev;

yield* ctx.generateAutoImportCompletion();
// fix https://github.com/vuejs/language-tools/issues/932
if (ctx.currentComponent
&& isDefaultSlot
&& node.children.length
&& node.tagType === CompilerDOM.ElementTypes.COMPONENT) {
ctx.currentComponent.used = true;
yield `${ctx.currentComponent.ctxVar}.slots!.`;
yield* (0, utils_1.wrapWith)(node.children[0].loc.start.offset, node.children[node.children.length - 1].loc.end.offset, ctx.codeFeatures.navigation, `default`);
yield utils_1.endOfLine;
}
}
//# sourceMappingURL=elementChildren.js.map

@@ -12,2 +12,3 @@ "use strict";

const stringLiteralKey_1 = require("../utils/stringLiteralKey");
const elementProps_1 = require("./elementProps");
const interpolation_1 = require("./interpolation");

@@ -90,3 +91,3 @@ const objectProperty_1 = require("./objectProperty");

yield `: `;
yield* (0, utils_1.wrapWith)(exp.loc.start.offset, exp.loc.end.offset, ctx.codeFeatures.verification, ...(0, interpolation_1.generateInterpolation)(options, ctx, 'template', ctx.codeFeatures.all, exp.content, exp.loc.start.offset, exp.loc, `(`, `)`));
yield* (0, elementProps_1.generatePropExp)(options, ctx, prop, exp, ctx.codeFeatures.all);
}

@@ -93,0 +94,0 @@ function getPropRenameApply(oldName) {

@@ -6,5 +6,5 @@ import * as CompilerDOM from '@vue/compiler-dom';

import type { TemplateCodegenOptions } from './index';
export declare function generateElementEvents(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.ElementNode, componentVar: string, componentInstanceVar: string, eventsVar: string): Generator<Code, boolean>;
export declare function generateElementEvents(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.ElementNode, componentFunctionalVar: string, componentVNodeVar: string, componentCtxVar: string): Generator<Code>;
export declare function generateEventArg(ctx: TemplateCodegenContext, name: string, start: number, directive?: string): Generator<Code>;
export declare function generateEventExpression(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, prop: CompilerDOM.DirectiveNode): Generator<Code>;
export declare function isCompoundExpression(ts: typeof import('typescript'), ast: ts.SourceFile): boolean;

@@ -12,4 +12,5 @@ "use strict";

const interpolation_1 = require("./interpolation");
function* generateElementEvents(options, ctx, node, componentVar, componentInstanceVar, eventsVar) {
let usedComponentEventsVar = false;
function* generateElementEvents(options, ctx, node, componentFunctionalVar, componentVNodeVar, componentCtxVar) {
let emitVar;
let eventsVar;
let propsVar;

@@ -22,6 +23,10 @@ for (const prop of node.props) {

&& !prop.arg.loc.source.endsWith(']')) {
usedComponentEventsVar = true;
if (!propsVar) {
ctx.currentComponent.used = true;
if (!emitVar) {
emitVar = ctx.getInternalVariable();
eventsVar = ctx.getInternalVariable();
propsVar = ctx.getInternalVariable();
yield `let ${propsVar}!: __VLS_FunctionalComponentProps<typeof ${componentVar}, typeof ${componentInstanceVar}>${utils_1.endOfLine}`;
yield `let ${emitVar}!: typeof ${componentCtxVar}.emit${utils_1.endOfLine}`;
yield `let ${eventsVar}!: __VLS_NormalizeEmits<typeof ${emitVar}>${utils_1.endOfLine}`;
yield `let ${propsVar}!: __VLS_FunctionalComponentProps<typeof ${componentFunctionalVar}, typeof ${componentVNodeVar}>${utils_1.endOfLine}`;
}

@@ -45,3 +50,2 @@ let source = prop.arg.loc.source;

}
return usedComponentEventsVar;
}

@@ -64,4 +68,4 @@ function* generateEventArg(ctx, name, start, directive = 'on') {

if (prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
let prefix = '(';
let suffix = ')';
let prefix = `(`;
let suffix = `)`;
let isFirstMapping = true;

@@ -73,6 +77,6 @@ const ast = (0, utils_1.createTsAst)(options.ts, prop.exp, prop.exp.content);

ctx.addLocalVariable('$event');
prefix = '';
suffix = '';
prefix = ``;
suffix = ``;
for (const blockCondition of ctx.blockConditions) {
prefix += `if (!(${blockCondition})) return${utils_1.endOfLine}`;
prefix += `if (!${blockCondition}) return${utils_1.endOfLine}`;
}

@@ -79,0 +83,0 @@ }

@@ -11,2 +11,2 @@ import * as CompilerDOM from '@vue/compiler-dom';

export declare function generateElementProps(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.ElementNode, props: CompilerDOM.ElementNode['props'], strictPropsCheck: boolean, enableCodeFeatures: boolean, failedPropExps?: FailedPropExpression[]): Generator<Code>;
export declare function generatePropExp(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, prop: CompilerDOM.DirectiveNode, exp: CompilerDOM.SimpleExpressionNode | undefined, features: VueCodeInformation, enableCodeFeatures: boolean): Generator<Code>;
export declare function generatePropExp(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, prop: CompilerDOM.DirectiveNode, exp: CompilerDOM.SimpleExpressionNode | undefined, features: VueCodeInformation, enableCodeFeatures?: boolean): Generator<Code>;

@@ -43,8 +43,8 @@ "use strict";

&& prop.arg.loc.source.endsWith(']')) {
failedPropExps?.push({ node: prop.arg, prefix: '(', suffix: ')' });
failedPropExps?.push({ node: prop.exp, prefix: '() => {', suffix: '}' });
failedPropExps?.push({ node: prop.arg, prefix: `(`, suffix: `)` });
failedPropExps?.push({ node: prop.exp, prefix: `() => {`, suffix: `}` });
}
else if (!prop.arg
&& prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
failedPropExps?.push({ node: prop.exp, prefix: '(', suffix: ')' });
failedPropExps?.push({ node: prop.exp, prefix: `(`, suffix: `)` });
}

@@ -70,3 +70,3 @@ }

if (prop.exp && prop.exp.constType !== CompilerDOM.ConstantTypes.CAN_STRINGIFY) {
failedPropExps?.push({ node: prop.exp, prefix: '(', suffix: ')' });
failedPropExps?.push({ node: prop.exp, prefix: `(`, suffix: `)` });
}

@@ -87,3 +87,3 @@ continue;

? (0, objectProperty_1.generateObjectProperty)(options, ctx, propName, prop.arg.loc.start.offset, codeInfo, prop.loc.name_2 ??= {}, shouldCamelize)
: (0, utils_1.wrapWith)(prop.loc.start.offset, prop.loc.start.offset + 'v-model'.length, ctx.codeFeatures.verification, propName)), `: (`, ...generatePropExp(options, ctx, prop, prop.exp, ctx.codeFeatures.all, enableCodeFeatures), `)`);
: (0, utils_1.wrapWith)(prop.loc.start.offset, prop.loc.start.offset + 'v-model'.length, ctx.codeFeatures.verification, propName)), `: `, ...generatePropExp(options, ctx, prop, prop.exp, ctx.codeFeatures.all, enableCodeFeatures));
if (enableCodeFeatures) {

@@ -129,5 +129,5 @@ yield* codes;

}
const codes = (0, utils_1.wrapWith)(prop.loc.start.offset, prop.loc.end.offset, ctx.codeFeatures.verification, ...(0, objectProperty_1.generateObjectProperty)(options, ctx, prop.name, prop.loc.start.offset, codeInfo, prop.loc.name_1 ??= {}, shouldCamelize), `: (`, ...(prop.value
const codes = (0, utils_1.wrapWith)(prop.loc.start.offset, prop.loc.end.offset, ctx.codeFeatures.verification, ...(0, objectProperty_1.generateObjectProperty)(options, ctx, prop.name, prop.loc.start.offset, codeInfo, prop.loc.name_1 ??= {}, shouldCamelize), `: `, ...(prop.value
? generateAttrValue(prop.value, ctx.codeFeatures.withoutNavigation)
: [`true`]), `)`);
: [`true`]));
if (enableCodeFeatures) {

@@ -166,3 +166,3 @@ yield* codes;

}
function* generatePropExp(options, ctx, prop, exp, features, enableCodeFeatures) {
function* generatePropExp(options, ctx, prop, exp, features, enableCodeFeatures = true) {
const isShorthand = prop.arg?.loc.start.offset === prop.exp?.loc.start.offset;

@@ -177,3 +177,3 @@ if (isShorthand && features.completion) {

if (!isShorthand) { // vue 3.4+
yield* (0, interpolation_1.generateInterpolation)(options, ctx, 'template', features, exp.loc.source, exp.loc.start.offset, exp.loc, '(', ')');
yield* (0, interpolation_1.generateInterpolation)(options, ctx, 'template', features, exp.loc.source, exp.loc.start.offset, exp.loc, `(`, `)`);
}

@@ -240,2 +240,4 @@ else {

shouldReport(_source, code) {
// https://typescript.tv/errors/#ts2353
// https://typescript.tv/errors/#ts2561
if (String(code) === '2353' || String(code) === '2561') {

@@ -242,0 +244,0 @@ return false;

@@ -21,6 +21,14 @@ "use strict";

const slotsPropertyName = (0, shared_1.getSlotsPropertyName)(options.vueCompilerOptions.target);
ctx.specialVars.add(slotsPropertyName);
ctx.specialVars.add('$attrs');
ctx.specialVars.add('$refs');
ctx.specialVars.add('$el');
if (options.vueCompilerOptions.inferTemplateDollarSlots) {
ctx.dollarVars.add(slotsPropertyName);
}
if (options.vueCompilerOptions.inferTemplateDollarAttrs) {
ctx.dollarVars.add('$attrs');
}
if (options.vueCompilerOptions.inferTemplateDollarRefs) {
ctx.dollarVars.add('$refs');
}
if (options.vueCompilerOptions.inferTemplateDollarEl) {
ctx.dollarVars.add('$el');
}
if (options.template.ast) {

@@ -30,2 +38,4 @@ yield* (0, templateChild_1.generateTemplateChild)(options, ctx, options.template.ast, undefined);

yield* (0, styleScopedClasses_1.generateStyleScopedClassReferences)(ctx);
yield* ctx.generateAutoImportCompletion();
yield* ctx.generateHoistVariables();
const speicalTypes = [

@@ -37,8 +47,7 @@ [slotsPropertyName, yield* generateSlots(options, ctx)],

];
yield `var __VLS_special!: {${utils_1.newLine}`;
yield `var __VLS_dollars!: {${utils_1.newLine}`;
for (const [name, type] of speicalTypes) {
yield `${name}: ${type}${utils_1.endOfLine}`;
}
yield `} & { [K in keyof typeof __VLS_ctx]: unknown }${utils_1.endOfLine}`;
yield* ctx.generateAutoImportCompletion();
yield `} & { [K in keyof import('${options.vueCompilerOptions.lib}').ComponentPublicInstance]: unknown }${utils_1.endOfLine}`;
return ctx;

@@ -51,3 +60,2 @@ }

for (const { expVar, propsVar } of ctx.dynamicSlots) {
ctx.hasSlot = true;
yield `${utils_1.newLine}& { [K in NonNullable<typeof ${expVar}>]?: (props: typeof ${propsVar}) => any }`;

@@ -57,3 +65,2 @@ }

yield `${utils_1.newLine}& { `;
ctx.hasSlot = true;
if (slot.name && slot.offset !== undefined) {

@@ -80,3 +87,3 @@ yield* (0, objectProperty_1.generateObjectProperty)(options, ctx, slot.name, slot.offset, ctx.codeFeatures.withoutHighlightAndCompletion, slot.nodeLoc);

for (const loc of ctx.bindingAttrLocs) {
yield `__VLS_special.`;
yield `__VLS_dollars.`;
yield [

@@ -96,5 +103,5 @@ loc.source,

yield `type __VLS_TemplateRefs = {${utils_1.newLine}`;
for (const [name, [varName, offset]] of ctx.templateRefs) {
for (const [name, { typeExp, offset }] of ctx.templateRefs) {
yield* (0, objectProperty_1.generateObjectProperty)(options, ctx, name, offset, ctx.codeFeatures.navigationAndCompletion);
yield `: typeof ${varName},${utils_1.newLine}`;
yield `: ${typeExp},${utils_1.newLine}`;
}

@@ -106,3 +113,10 @@ yield `}${utils_1.endOfLine}`;

yield `type __VLS_RootEl = `;
yield ctx.singleRootElType ?? `any`;
if (ctx.singleRootElTypes.length && !ctx.singleRootNodes.has(null)) {
for (const type of ctx.singleRootElTypes) {
yield `${utils_1.newLine}| ${type}`;
}
}
else {
yield `any`;
}
yield utils_1.endOfLine;

@@ -109,0 +123,0 @@ return `__VLS_RootEl`;

@@ -90,3 +90,3 @@ "use strict";

const nextVar = ctxVars[i + 1];
yield* generateVar(code, ctx.specialVars, destructuredPropNames, templateRefNames, curVar);
yield* generateVar(code, ctx.dollarVars, destructuredPropNames, templateRefNames, curVar);
if (nextVar.isShorthand) {

@@ -101,3 +101,3 @@ yield [code.slice(curVar.offset + curVar.text.length, nextVar.offset + nextVar.text.length), curVar.offset + curVar.text.length];

const lastVar = ctxVars.at(-1);
yield* generateVar(code, ctx.specialVars, destructuredPropNames, templateRefNames, lastVar);
yield* generateVar(code, ctx.dollarVars, destructuredPropNames, templateRefNames, lastVar);
if (lastVar.offset + lastVar.text.length < code.length) {

@@ -111,3 +111,3 @@ yield [code.slice(lastVar.offset + lastVar.text.length), lastVar.offset + lastVar.text.length, 'endText'];

}
function* generateVar(code, specialVars, destructuredPropNames, templateRefNames, curVar) {
function* generateVar(code, dollarVars, destructuredPropNames, templateRefNames, curVar) {
// fix https://github.com/vuejs/language-tools/issues/1205

@@ -124,4 +124,4 @@ // fix https://github.com/vuejs/language-tools/issues/1264

else {
if (specialVars.has(curVar.text)) {
yield [`__VLS_special.`, undefined];
if (dollarVars.has(curVar.text)) {
yield [`__VLS_dollars.`, undefined];
}

@@ -128,0 +128,0 @@ else if (!isDestructuredProp) {

@@ -13,2 +13,3 @@ "use strict";

const startTagOffset = node.loc.start.offset + options.template.content.slice(node.loc.start.offset).indexOf(node.tag);
const startTagEndOffset = startTagOffset + node.tag.length;
const propsVar = ctx.getInternalVariable();

@@ -26,3 +27,3 @@ const nameProp = node.props.find(prop => {

if (options.hasDefineSlots) {
yield `__VLS_normalizeSlot(`;
yield `__VLS_asFunctionalSlot(`;
if (nameProp) {

@@ -42,3 +43,3 @@ let codes;

`[`,
...(0, elementProps_1.generatePropExp)(options, ctx, nameProp, nameProp.exp, ctx.codeFeatures.all, true),
...(0, elementProps_1.generatePropExp)(options, ctx, nameProp, nameProp.exp, ctx.codeFeatures.all),
`]`

@@ -53,6 +54,6 @@ ];

else {
yield* (0, utils_1.wrapWith)(node.loc.start.offset, node.loc.end.offset, ctx.codeFeatures.verification, `${options.slotsAssignName ?? '__VLS_slots'}['default']`);
yield* (0, utils_1.wrapWith)(startTagOffset, startTagEndOffset, ctx.codeFeatures.verification, `${options.slotsAssignName ?? '__VLS_slots'}[`, ...(0, utils_1.wrapWith)(startTagOffset, startTagEndOffset, ctx.codeFeatures.verification, `'default'`), `]`);
}
yield `)?.(`;
yield* (0, utils_1.wrapWith)(startTagOffset, startTagOffset + node.tag.length, ctx.codeFeatures.verification, `{${utils_1.newLine}`, ...(0, elementProps_1.generateElementProps)(options, ctx, node, node.props.filter(prop => prop !== nameProp), true, true), `}`);
yield `)(`;
yield* (0, utils_1.wrapWith)(startTagOffset, startTagEndOffset, ctx.codeFeatures.verification, `{${utils_1.newLine}`, ...(0, elementProps_1.generateElementProps)(options, ctx, node, node.props.filter(prop => prop !== nameProp), true, true), `}`);
yield `)${utils_1.endOfLine}`;

@@ -71,3 +72,3 @@ }

nodeLoc: node.loc,
propsVar,
propsVar: ctx.getHoistVariable(propsVar),
});

@@ -86,4 +87,4 @@ }

ctx.dynamicSlots.push({
expVar,
propsVar,
expVar: ctx.getHoistVariable(expVar),
propsVar: ctx.getHoistVariable(propsVar),
});

@@ -94,5 +95,5 @@ }

name: 'default',
tagRange: [startTagOffset, startTagOffset + node.tag.length],
tagRange: [startTagOffset, startTagEndOffset],
nodeLoc: node.loc,
propsVar,
propsVar: ctx.getHoistVariable(propsVar),
});

@@ -99,0 +100,0 @@ }

@@ -9,8 +9,4 @@ "use strict";

function* generateStyleScopedClassReferences(ctx, withDot = false) {
if (!ctx.emptyClassOffsets.length && !ctx.scopedClasses.length) {
return;
}
yield `[`;
for (const offset of ctx.emptyClassOffsets) {
yield `'`;
yield `/** @type {__VLS_StyleScopedClasses['`;
yield [

@@ -22,5 +18,6 @@ '',

];
yield `', `;
yield `']} */${utils_1.endOfLine}`;
}
for (const { source, className, offset } of ctx.scopedClasses) {
yield `/** @type {__VLS_StyleScopedClasses[`;
yield [

@@ -40,7 +37,6 @@ '',

offset + className.length,
ctx.codeFeatures.navigationWithoutRename,
ctx.codeFeatures.navigation,
];
yield `, `;
yield `]} */${utils_1.endOfLine}`;
}
yield `] as (keyof __VLS_StyleScopedClasses)[]${utils_1.endOfLine}`;
function* escapeString(source, className, offset, escapeTargets) {

@@ -47,0 +43,0 @@ let count = 0;

@@ -7,2 +7,3 @@ "use strict";

const CompilerDOM = require("@vue/compiler-dom");
const shared_1 = require("../../utils/shared");
const utils_1 = require("../utils");

@@ -15,2 +16,3 @@ const element_1 = require("./element");

const vSlot_1 = require("./vSlot");
const commentDirectiveRegex = /^<!--\s*@vue-(?<name>[-\w]+)\b(?<content>[\s\S]*)-->$/;
// @ts-ignore

@@ -33,25 +35,31 @@ const transformContext = {

if (prevNode?.type === CompilerDOM.NodeTypes.COMMENT) {
const commentText = prevNode.content.trim().split(' ')[0];
if (/^@vue-skip\b[\s\S]*/.test(commentText)) {
yield `// @vue-skip${utils_1.newLine}`;
return;
}
else if (/^@vue-ignore\b[\s\S]*/.test(commentText)) {
yield* ctx.ignoreError();
}
else if (/^@vue-expect-error\b[\s\S]*/.test(commentText)) {
yield* ctx.expectError(prevNode);
}
else {
const match = prevNode.loc.source.match(/^<!--\s*@vue-generic\b\s*\{(?<content>[^}]*)\}/);
if (match) {
const { content } = match.groups ?? {};
ctx.lastGenericComment = {
content,
offset: prevNode.loc.start.offset + match[0].indexOf(content)
};
const match = prevNode.loc.source.match(commentDirectiveRegex);
if (match) {
const { name, content } = match.groups;
switch (name) {
case 'skip': {
yield `// @vue-skip${utils_1.newLine}`;
return;
}
case 'ignore': {
yield* ctx.ignoreError();
break;
}
case 'expect-error': {
yield* ctx.expectError(prevNode);
break;
}
case 'generic': {
const text = content.trim();
if (text.startsWith('{') && text.endsWith('}')) {
ctx.lastGenericComment = {
content: text.slice(1, -1),
offset: prevNode.loc.start.offset + prevNode.loc.source.indexOf('{') + 1,
};
}
break;
}
}
}
}
const shouldInheritRootNodeAttrs = options.inheritAttrs;
const cur = node;

@@ -62,6 +70,6 @@ if (cur.codegenNode?.type === CompilerDOM.NodeTypes.JS_CACHE_EXPRESSION) {

if (node.type === CompilerDOM.NodeTypes.ROOT) {
for (const item of collectSingleRootNodes(options, node.children)) {
ctx.singleRootNodes.add(item);
}
let prev;
if (shouldInheritRootNodeAttrs && node.children.length === 1 && node.children[0].type === CompilerDOM.NodeTypes.ELEMENT) {
ctx.singleRootNode = node.children[0];
}
for (const childNode of node.children) {

@@ -98,3 +106,3 @@ yield* generateTemplateChild(options, ctx, childNode, prev);

const { currentComponent } = ctx;
yield* (0, element_1.generateComponent)(options, ctx, node);
yield* (0, element_1.generateComponent)(options, ctx, node, isVForChild);
ctx.currentComponent = currentComponent;

@@ -134,2 +142,26 @@ }

}
function* collectSingleRootNodes(options, children) {
if (children.length !== 1) {
// "null" is used to determine whether the component is not always has a single root
if (children.length > 1) {
yield null;
}
return;
}
const child = children[0];
if (child.type === CompilerDOM.NodeTypes.IF) {
for (const branch of child.branches) {
yield* collectSingleRootNodes(options, branch.children);
}
return;
}
else if (child.type !== CompilerDOM.NodeTypes.ELEMENT) {
return;
}
yield child;
const tag = (0, shared_1.hyphenateTag)(child.tag);
if (options.vueCompilerOptions.fallthroughComponentNames.includes(tag)) {
yield* collectSingleRootNodes(options, child.children);
}
}
// TODO: track https://github.com/vuejs/vue-next/issues/3498

@@ -155,7 +187,7 @@ function getVForNode(node) {

function getVIfNode(node) {
const forDirective = node.props.find((prop) => prop.type === CompilerDOM.NodeTypes.DIRECTIVE
const ifDirective = node.props.find((prop) => prop.type === CompilerDOM.NodeTypes.DIRECTIVE
&& prop.name === 'if');
if (forDirective) {
if (ifDirective) {
let ifNode;
CompilerDOM.processIf(node, forDirective, transformContext, _ifNode => {
CompilerDOM.processIf(node, ifDirective, transformContext, _ifNode => {
ifNode = { ..._ifNode };

@@ -168,3 +200,3 @@ return undefined;

...node,
props: node.props.filter(prop => prop !== forDirective),
props: node.props.filter(prop => prop !== ifDirective),
}];

@@ -171,0 +203,0 @@ }

@@ -27,3 +27,3 @@ "use strict";

yield `__VLS_getVForSourceType(`;
yield* (0, interpolation_1.generateInterpolation)(options, ctx, 'template', ctx.codeFeatures.all, source.content, source.loc.start.offset, source.loc, '(', ')');
yield* (0, interpolation_1.generateInterpolation)(options, ctx, 'template', ctx.codeFeatures.all, source.content, source.loc.start.offset, source.loc, `(`, `)`);
yield `!)`; // #3102

@@ -50,3 +50,3 @@ }

&& !prop.value.isStatic) {
yield* (0, interpolation_1.generateInterpolation)(options, ctx, 'template', ctx.codeFeatures.all, prop.value.content, prop.value.loc.start.offset, prop.value.loc, '(', ')');
yield* (0, interpolation_1.generateInterpolation)(options, ctx, 'template', ctx.codeFeatures.all, prop.value.content, prop.value.loc.start.offset, prop.value.loc, `(`, `)`);
yield utils_1.endOfLine;

@@ -53,0 +53,0 @@ }

@@ -10,3 +10,3 @@ "use strict";

function* generateVIf(options, ctx, node) {
let originalBlockConditionsLength = ctx.blockConditions.length;
const originalBlockConditionsLength = ctx.blockConditions.length;
for (let i = 0; i < node.branches.length; i++) {

@@ -26,3 +26,3 @@ const branch = node.branches[i];

const codes = [
...(0, interpolation_1.generateInterpolation)(options, ctx, 'template', ctx.codeFeatures.all, branch.condition.content, branch.condition.loc.start.offset, branch.condition.loc, '(', ')'),
...(0, interpolation_1.generateInterpolation)(options, ctx, 'template', ctx.codeFeatures.all, branch.condition.content, branch.condition.loc.start.offset, branch.condition.loc, `(`, `)`),
];

@@ -48,3 +48,3 @@ for (const code of codes) {

if (addedBlockCondition) {
ctx.blockConditions[ctx.blockConditions.length - 1] = `!(${ctx.blockConditions[ctx.blockConditions.length - 1]})`;
ctx.blockConditions[ctx.blockConditions.length - 1] = `!${ctx.blockConditions[ctx.blockConditions.length - 1]}`;
}

@@ -51,0 +51,0 @@ }

@@ -6,1 +6,2 @@ import * as CompilerDOM from '@vue/compiler-dom';

export declare function generateVSlot(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.ElementNode, slotDir: CompilerDOM.DirectiveNode): Generator<Code>;
export declare function generateImplicitDefaultSlot(ctx: TemplateCodegenContext, node: CompilerDOM.ElementNode): Generator<Code, void, any>;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateVSlot = generateVSlot;
exports.generateImplicitDefaultSlot = generateImplicitDefaultSlot;
const CompilerDOM = require("@vue/compiler-dom");

@@ -80,2 +81,13 @@ const utils_1 = require("../utils");

}
function* generateImplicitDefaultSlot(ctx, node) {
if (!ctx.currentComponent) {
return;
}
if (node.children.length) {
ctx.currentComponent.used = true;
yield `${ctx.currentComponent.ctxVar}.slots!.`;
yield* (0, utils_1.wrapWith)(node.children[0].loc.start.offset, node.children[node.children.length - 1].loc.end.offset, ctx.codeFeatures.navigation, `default`);
yield utils_1.endOfLine;
}
}
//# sourceMappingURL=vSlot.js.map
import * as CompilerDOM from '@vue/compiler-dom';
import type * as ts from 'typescript';
import type { Code, SfcBlock, VueCodeInformation } from '../../types';
import type { Code, SfcBlock, SfcBlockAttr, VueCodeInformation } from '../../types';
export declare const newLine = "\n";

@@ -22,1 +22,2 @@ export declare const endOfLine = ";\n";

export declare function generateSfcBlockSection(block: SfcBlock, start: number, end: number, features: VueCodeInformation): Code;
export declare function generateSfcBlockAttrValue(src: SfcBlockAttr & object, text: string, features: VueCodeInformation): Generator<Code>;

@@ -10,6 +10,7 @@ "use strict";

exports.generateSfcBlockSection = generateSfcBlockSection;
exports.generateSfcBlockAttrValue = generateSfcBlockAttrValue;
const scriptSetupRanges_1 = require("../../parsers/scriptSetupRanges");
exports.newLine = `\n`;
exports.endOfLine = `;${exports.newLine}`;
exports.combineLastMapping = { __combineLastMapping: true };
exports.combineLastMapping = { __combineOffset: 1 };
exports.variableNameRegex = /^[a-zA-Z_$][0-9a-zA-Z_$]*$/;

@@ -25,3 +26,3 @@ function* wrapWith(startOffset, endOffset, features, ...wrapCodes) {

}
yield ['', 'template', endOffset, { __combineOffsetMapping: offset }];
yield ['', 'template', endOffset, { __combineOffset: offset }];
}

@@ -81,2 +82,17 @@ function collectVars(ts, node, ast, results = []) {

}
function* generateSfcBlockAttrValue(src, text, features) {
const { offset, quotes } = src;
if (!quotes) {
yield [``, 'main', offset, { verification: true }];
}
yield [
`'${text}'`,
'main',
quotes ? offset - 1 : offset,
features
];
if (!quotes) {
yield [``, 'main', offset + text.length, { __combineOffset: 2 }];
}
}
//# sourceMappingURL=index.js.map

@@ -199,23 +199,18 @@ "use strict";

defineProps = {
...parseCallExpression(node),
...parseCallExpressionAssignment(node, parent),
statement: getStatementRange(ts, parents, node, ast),
argNode: node.arguments[0]
};
if (ts.isVariableDeclaration(parent)) {
if (ts.isObjectBindingPattern(parent.name)) {
defineProps.destructured = new Map();
const identifiers = (0, utils_1.collectIdentifiers)(ts, parent.name, []);
for (const { id, isRest, initializer } of identifiers) {
const name = _getNodeText(id);
if (isRest) {
defineProps.destructuredRest = name;
}
else {
defineProps.destructured.set(name, initializer);
}
if (ts.isVariableDeclaration(parent) && ts.isObjectBindingPattern(parent.name)) {
defineProps.destructured = new Map();
const identifiers = (0, utils_1.collectIdentifiers)(ts, parent.name, []);
for (const { id, isRest, initializer } of identifiers) {
const name = _getNodeText(id);
if (isRest) {
defineProps.destructuredRest = name;
}
else {
defineProps.destructured.set(name, initializer);
}
}
else {
defineProps.name = _getNodeText(parent.name);
}
}

@@ -241,8 +236,5 @@ else if (ts.isCallExpression(parent)

defineEmits = {
...parseCallExpression(node),
...parseCallExpressionAssignment(node, parent),
statement: getStatementRange(ts, parents, node, ast)
};
if (ts.isVariableDeclaration(parent)) {
defineEmits.name = _getNodeText(parent.name);
}
if (node.typeArguments?.length && ts.isTypeLiteralNode(node.typeArguments[0])) {

@@ -262,8 +254,5 @@ for (const member of node.typeArguments[0].members) {

defineSlots = {
...parseCallExpression(node),
...parseCallExpressionAssignment(node, parent),
statement: getStatementRange(ts, parents, node, ast)
};
if (ts.isVariableDeclaration(parent)) {
defineSlots.name = _getNodeText(parent.name);
}
}

@@ -301,6 +290,3 @@ else if (vueCompilerOptions.macros.defineExpose.includes(callText)) {

&& !node.typeArguments?.length) {
useTemplateRef.push({
name: ts.isVariableDeclaration(parent) ? _getNodeText(parent.name) : undefined,
...parseCallExpression(node)
});
useTemplateRef.push(parseCallExpressionAssignment(node, parent));
}

@@ -325,2 +311,8 @@ }

}
function parseCallExpressionAssignment(node, parent) {
return {
name: ts.isVariableDeclaration(parent) ? _getNodeText(parent.name) : undefined,
...parseCallExpression(node),
};
}
function _getStartEnd(node) {

@@ -327,0 +319,0 @@ return getStartEnd(ts, node, ast);

@@ -9,2 +9,3 @@ "use strict";

const inlineCodeblockReg = /`[^\n`]+?`/g;
const latexBlockReg = /(\${2,})[\s\S]+?\1/g;
const scriptSetupReg = /\\\<[\s\S]+?\>\n?/g;

@@ -35,2 +36,4 @@ const sfcBlockReg = /\<(script|style)\b[\s\S]*?\>([\s\S]*?)\<\/\1\>/g;

.replace(inlineCodeblockReg, match => `\`${' '.repeat(match.length - 2)}\``)
// latex block
.replace(latexBlockReg, (match, quotes) => quotes + ' '.repeat(match.length - quotes.length * 2) + quotes)
// # \<script setup>

@@ -37,0 +40,0 @@ .replace(scriptSetupReg, match => ' '.repeat(match.length))

@@ -63,6 +63,6 @@ "use strict";

if (node.type === CompilerDOM.NodeTypes.COMMENT) {
const match = node.loc.source.match(/^<!--\s*@vue-generic\b\s*\{(?<content>[^}]*)\}/);
const match = node.loc.source.match(/^<!--\s*@vue-generic\s*\{(?<content>[\s\S]*)\}\s*-->$/);
if (match) {
const { content } = match.groups ?? {};
addFormatCodes(content, node.loc.start.offset + match[0].indexOf(content), formatBrackets.generic);
const { content } = match.groups;
addFormatCodes(content, node.loc.start.offset + node.loc.source.indexOf('{') + 1, formatBrackets.generic);
}

@@ -69,0 +69,0 @@ }

@@ -172,3 +172,3 @@ import type { Mapping } from '@volar/language-core';

}[];
specialVars: Set<string>;
dollarVars: Set<string>;
accessExternalVariables: Map<string, Set<number>>;

@@ -187,6 +187,8 @@ lastGenericComment: {

inlayHints: import("../codegen/inlayHints").InlayHintInfo[];
hasSlot: boolean;
bindingAttrLocs: import("@vue/compiler-dom").SourceLocation[];
inheritedAttrVars: Set<string>;
templateRefs: Map<string, [varName: string, offset: number]>;
templateRefs: Map<string, {
typeExp: string;
offset: number;
}>;
currentComponent: {

@@ -196,4 +198,4 @@ ctxVar: string;

} | undefined;
singleRootElType: string | undefined;
singleRootNode: import("@vue/compiler-dom").ElementNode | undefined;
singleRootElTypes: string[];
singleRootNodes: Set<import("@vue/compiler-dom").ElementNode | null>;
accessExternalVariable(name: string, offset?: number): void;

@@ -204,2 +206,4 @@ hasLocalVariable: (name: string) => boolean;

getInternalVariable: () => string;
getHoistVariable: (originalVar: string) => string;
generateHoistVariables: () => Generator<string, void, unknown>;
ignoreError: () => Generator<Code>;

@@ -206,0 +210,0 @@ expectError: (prevNode: import("@vue/compiler-dom").CommentNode) => Generator<Code>;

@@ -56,12 +56,12 @@ "use strict";

exports.default = plugin;
function createTsx(fileName, _sfc, ctx, appendGlobalTypes) {
function createTsx(fileName, sfc, ctx, appendGlobalTypes) {
const ts = ctx.modules.typescript;
const getLang = (0, alien_signals_1.computed)(() => {
return !_sfc.script && !_sfc.scriptSetup ? 'ts'
: _sfc.scriptSetup && _sfc.scriptSetup.lang !== 'js' ? _sfc.scriptSetup.lang
: _sfc.script && _sfc.script.lang !== 'js' ? _sfc.script.lang
return !sfc.script && !sfc.scriptSetup ? 'ts'
: sfc.scriptSetup && sfc.scriptSetup.lang !== 'js' ? sfc.scriptSetup.lang
: sfc.script && sfc.script.lang !== 'js' ? sfc.script.lang
: 'js';
});
const getResolvedOptions = (0, alien_signals_1.computed)(() => {
const options = (0, vueCompilerOptions_1.parseVueCompilerOptions)(_sfc.comments);
const options = (0, vueCompilerOptions_1.parseVueCompilerOptions)(sfc.comments);
if (options) {

@@ -74,7 +74,7 @@ const resolver = new ts_1.CompilerOptionsResolver();

});
const getScriptRanges = (0, alien_signals_1.computed)(() => _sfc.script
? (0, scriptRanges_1.parseScriptRanges)(ts, _sfc.script.ast, !!_sfc.scriptSetup, false)
const getScriptRanges = (0, alien_signals_1.computed)(() => sfc.script
? (0, scriptRanges_1.parseScriptRanges)(ts, sfc.script.ast, !!sfc.scriptSetup, false)
: undefined);
const getScriptSetupRanges = (0, alien_signals_1.computed)(() => _sfc.scriptSetup
? (0, scriptSetupRanges_1.parseScriptSetupRanges)(ts, _sfc.scriptSetup.ast, getResolvedOptions())
const getScriptSetupRanges = (0, alien_signals_1.computed)(() => sfc.scriptSetup
? (0, scriptSetupRanges_1.parseScriptSetupRanges)(ts, sfc.scriptSetup.ast, getResolvedOptions())
: undefined);

@@ -84,5 +84,5 @@ const getSetupBindingNames = (0, signals_1.computedSet)((0, alien_signals_1.computed)(() => {

const bindings = getScriptSetupRanges()?.bindings;
if (_sfc.scriptSetup && bindings) {
if (sfc.scriptSetup && bindings) {
for (const { range } of bindings) {
newNames.add(_sfc.scriptSetup.content.slice(range.start, range.end));
newNames.add(sfc.scriptSetup.content.slice(range.start, range.end));
}

@@ -95,3 +95,3 @@ }

const bindings = getScriptSetupRanges()?.bindings;
if (_sfc.scriptSetup && bindings) {
if (sfc.scriptSetup && bindings) {
for (const { range, moduleName, isDefaultImport, isNamespace } of bindings) {

@@ -102,3 +102,3 @@ if (moduleName

&& ctx.vueCompilerOptions.extensions.some(ext => moduleName.endsWith(ext))) {
newNames.add(_sfc.scriptSetup.content.slice(range.start, range.end));
newNames.add(sfc.scriptSetup.content.slice(range.start, range.end));
}

@@ -132,8 +132,8 @@ }

const { exportDefault } = getScriptRanges() ?? {};
if (_sfc.script && exportDefault?.nameOption) {
if (sfc.script && exportDefault?.nameOption) {
const { nameOption } = exportDefault;
return _sfc.script.content.slice(nameOption.start + 1, nameOption.end - 1);
return sfc.script.content.slice(nameOption.start + 1, nameOption.end - 1);
}
const { defineOptions } = getScriptSetupRanges() ?? {};
if (_sfc.scriptSetup && defineOptions?.name) {
if (sfc.scriptSetup && defineOptions?.name) {
return defineOptions.name;

@@ -145,3 +145,3 @@ }

const getGeneratedTemplate = (0, alien_signals_1.computed)(() => {
if (getResolvedOptions().skipTemplateCodegen || !_sfc.template) {
if (getResolvedOptions().skipTemplateCodegen || !sfc.template) {
return;

@@ -154,3 +154,3 @@ }

vueCompilerOptions: getResolvedOptions(),
template: _sfc.template,
template: sfc.template,
edited: getResolvedOptions().__test || (fileEditTimes.get(fileName) ?? 0) >= 2,

@@ -179,5 +179,5 @@ scriptSetupBindingNames: getSetupBindingNames(),

const getGeneratedScript = (0, alien_signals_1.computed)(() => {
const codes = [];
const linkedCodeMappings = [];
let generatedLength = 0;
const codes = [];
const codegen = (0, script_1.generateScript)({

@@ -187,3 +187,3 @@ ts,

vueCompilerOptions: getResolvedOptions(),
sfc: _sfc,
sfc: sfc,
edited: getResolvedOptions().__test || (fileEditTimes.get(fileName) ?? 0) >= 2,

@@ -190,0 +190,0 @@ fileName,

@@ -15,4 +15,3 @@ import type { CodeInformation } from '@volar/language-core';

export interface VueCodeInformation extends CodeInformation {
__combineLastMapping?: boolean;
__combineOffsetMapping?: number;
__combineOffset?: number;
}

@@ -31,4 +30,11 @@ export type Code = Segment<VueCodeInformation>;

checkUnknownComponents: boolean;
inferComponentDollarEl: boolean;
inferComponentDollarRefs: boolean;
inferTemplateDollarAttrs: boolean;
inferTemplateDollarEl: boolean;
inferTemplateDollarRefs: boolean;
inferTemplateDollarSlots: boolean;
skipTemplateCodegen: boolean;
fallthroughAttributes: boolean;
fallthroughComponentNames: string[];
dataAttributes: string[];

@@ -108,2 +114,7 @@ htmlAttributes: string[];

}
export type SfcBlockAttr = true | {
text: string;
offset: number;
quotes: boolean;
};
export interface Sfc {

@@ -118,9 +129,7 @@ content: string;

script: (SfcBlock & {
src: string | undefined;
srcOffset: number;
src: SfcBlockAttr | undefined;
ast: ts.SourceFile;
}) | undefined;
scriptSetup: SfcBlock & {
generic: string | undefined;
genericOffset: number;
generic: SfcBlockAttr | undefined;
ast: ts.SourceFile;

@@ -130,6 +139,3 @@ } | undefined;

scoped: boolean;
module?: {
name: string;
offset?: number;
};
module?: SfcBlockAttr | undefined;
cssVars: {

@@ -149,7 +155,10 @@ text: string;

declare module '@vue/compiler-sfc' {
interface SFCBlock {
__src?: SfcBlockAttr;
}
interface SFCScriptBlock {
__generic?: SfcBlockAttr;
}
interface SFCStyleBlock {
__module?: {
name: string;
offset?: number;
};
__module?: SfcBlockAttr;
}

@@ -156,0 +165,0 @@ }

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parse = parse;
const compiler = require("@vue/compiler-dom");
const CompilerDOM = require("@vue/compiler-dom");
function parse(source) {
const errors = [];
const ast = compiler.parse(source, {
const ast = CompilerDOM.parse(source, {
// there are no components at SFC parsing level

@@ -32,7 +32,7 @@ isNativeTag: () => true,

ast.children.forEach(node => {
if (node.type === compiler.NodeTypes.COMMENT) {
if (node.type === CompilerDOM.NodeTypes.COMMENT) {
descriptor.comments.push(node.content);
return;
}
else if (node.type !== compiler.NodeTypes.ELEMENT) {
else if (node.type !== CompilerDOM.NodeTypes.ELEMENT) {
return;

@@ -103,11 +103,19 @@ }

node.props.forEach(p => {
if (p.type === compiler.NodeTypes.ATTRIBUTE) {
if (p.type === CompilerDOM.NodeTypes.ATTRIBUTE) {
attrs[p.name] = p.value ? p.value.content || true : true;
if (p.name === 'lang') {
block.lang = p.value && p.value.content;
block.lang = p.value?.content;
}
else if (p.name === 'src') {
block.src = p.value && p.value.content;
block.__src = parseAttr(p, node);
}
else if (type === 'style') {
else if (isScriptBlock(block)) {
if (p.name === 'setup' || p.name === 'vapor') {
block.setup = attrs[p.name];
}
else if (p.name === 'generic') {
block.__generic = parseAttr(p, node);
}
}
else if (isStyleBlock(block)) {
if (p.name === 'scoped') {

@@ -117,12 +125,5 @@ block.scoped = true;

else if (p.name === 'module') {
block.__module = {
name: p.value?.content ?? '$style',
offset: p.value?.content ? p.value?.loc.start.offset - node.loc.start.offset : undefined
};
block.__module = parseAttr(p, node);
}
}
else if (type === 'script'
&& (p.name === 'setup' || p.name === 'vapor')) {
block.setup = attrs[p.name];
}
}

@@ -132,2 +133,25 @@ });

}
function isScriptBlock(block) {
return block.type === 'script';
}
function isStyleBlock(block) {
return block.type === 'style';
}
function parseAttr(p, node) {
if (!p.value) {
return true;
}
const text = p.value.content;
const source = p.value.loc.source;
let offset = p.value.loc.start.offset - node.loc.start.offset;
const quotes = source.startsWith('"') || source.startsWith("'");
if (quotes) {
offset++;
}
return {
text,
offset,
quotes,
};
}
//# sourceMappingURL=parseSfc.js.map

@@ -13,2 +13,3 @@ "use strict";

const languagePlugin_1 = require("../languagePlugin");
const shared_2 = require("./shared");
function createParsedCommandLineByJson(ts, parseConfigHost, rootDir, json, configFileName = rootDir + '/jsconfig.json', skipGlobalTypesSetup = false) {

@@ -178,2 +179,6 @@ const proxyHost = proxyParseConfigHostForExtendConfigPaths(parseConfigHost);

},
fallthroughComponentNames: [
...defaults.fallthroughComponentNames,
...this.options.fallthroughComponentNames ?? []
].map(shared_2.hyphenateTag),
// https://github.com/vuejs/vue-next/blob/master/packages/compiler-dom/src/transforms/vModel.ts#L49-L51

@@ -222,4 +227,16 @@ // https://vuejs.org/guide/essentials/forms.html#form-input-bindings

checkUnknownComponents: strictTemplates,
inferComponentDollarEl: false,
inferComponentDollarRefs: false,
inferTemplateDollarAttrs: false,
inferTemplateDollarEl: false,
inferTemplateDollarRefs: false,
inferTemplateDollarSlots: false,
skipTemplateCodegen: false,
fallthroughAttributes: false,
fallthroughComponentNames: [
'Transition',
'KeepAlive',
'Teleport',
'Suspense',
],
dataAttributes: [],

@@ -226,0 +243,0 @@ htmlAttributes: ['aria-*'],

@@ -174,9 +174,8 @@ "use strict";

const newMappings = [];
let lastValidMapping;
for (let i = 0; i < mappings.length; i++) {
const mapping = mappings[i];
if (mapping.data.__combineOffsetMapping !== undefined) {
const offsetMapping = mappings[i - mapping.data.__combineOffsetMapping];
if (mapping.data.__combineOffset !== undefined) {
const offsetMapping = mappings[i - mapping.data.__combineOffset];
if (typeof offsetMapping === 'string' || !offsetMapping) {
throw new Error('Invalid offset mapping, mappings: ' + mappings.length + ', i: ' + i + ', offset: ' + mapping.data.__combineOffsetMapping);
throw new Error('Invalid offset mapping, mappings: ' + mappings.length + ', i: ' + i + ', offset: ' + mapping.data.__combineOffset);
}

@@ -188,11 +187,2 @@ offsetMapping.sourceOffsets.push(...mapping.sourceOffsets);

}
else if (mapping.data.__combineLastMapping) {
lastValidMapping.sourceOffsets.push(...mapping.sourceOffsets);
lastValidMapping.generatedOffsets.push(...mapping.generatedOffsets);
lastValidMapping.lengths.push(...mapping.lengths);
continue;
}
else {
lastValidMapping = mapping;
}
newMappings.push(mapping);

@@ -199,0 +189,0 @@ }

@@ -35,8 +35,4 @@ "use strict";

const getScript = computedNullableSfcBlock('script', 'js', (0, alien_signals_1.computed)(() => getParseResult()?.descriptor.script ?? undefined), (block, base) => {
const src = (0, alien_signals_1.computed)(() => block().src);
const srcOffset = (0, alien_signals_1.computed)(() => {
const _src = src();
return _src ? getUntrackedSnapshot().getText(0, base.startTagEnd).lastIndexOf(_src) - base.startTagEnd : -1;
});
const ast = (0, alien_signals_1.computed)(() => {
const getSrc = computedAttrValue('__src', base, block);
const getAst = (0, alien_signals_1.computed)(() => {
for (const plugin of plugins) {

@@ -51,17 +47,9 @@ const ast = plugin.compileSFCScript?.(base.lang, base.content);

return mergeObject(base, {
get src() { return src(); },
get srcOffset() { return srcOffset(); },
get ast() { return ast(); },
get src() { return getSrc(); },
get ast() { return getAst(); },
});
});
const getOriginalScriptSetup = computedNullableSfcBlock('scriptSetup', 'js', (0, alien_signals_1.computed)(() => getParseResult()?.descriptor.scriptSetup ?? undefined), (block, base) => {
const generic = (0, alien_signals_1.computed)(() => {
const _block = block();
return typeof _block.attrs.generic === 'string' ? _block.attrs.generic : undefined;
});
const genericOffset = (0, alien_signals_1.computed)(() => {
const _generic = generic();
return _generic !== undefined ? getUntrackedSnapshot().getText(0, base.startTagEnd).lastIndexOf(_generic) - base.startTagEnd : -1;
});
const ast = (0, alien_signals_1.computed)(() => {
const getGeneric = computedAttrValue('__generic', base, block);
const getAst = (0, alien_signals_1.computed)(() => {
for (const plugin of plugins) {

@@ -76,5 +64,4 @@ const ast = plugin.compileSFCScript?.(base.lang, base.content);

return mergeObject(base, {
get generic() { return generic(); },
get genericOffset() { return genericOffset(); },
get ast() { return ast(); },
get generic() { return getGeneric(); },
get ast() { return getAst(); },
});

@@ -105,9 +92,3 @@ });

const base = computedSfcBlock('style_' + i, 'css', getBlock);
const getModule = (0, alien_signals_1.computed)(() => {
const { __module } = getBlock();
return __module ? {
name: __module.name,
offset: __module.offset ? base.start + __module.offset : undefined
} : undefined;
});
const getModule = computedAttrValue('__module', base, getBlock);
const getScoped = (0, alien_signals_1.computed)(() => !!getBlock().scoped);

@@ -250,2 +231,14 @@ const getCssVars = (0, alien_signals_1.computed)(() => [...(0, parseCssVars_1.parseCssVars)(base.content)]);

}
function computedAttrValue(key, base, getBlock) {
return (0, alien_signals_1.computed)(() => {
const val = getBlock()[key];
if (typeof val === 'object') {
return {
...val,
offset: base.start + val.offset,
};
}
return val;
});
}
}

@@ -252,0 +245,0 @@ function mergeObject(a, b) {

@@ -13,13 +13,10 @@ import type { VirtualCode } from '@volar/language-core';

private _snapshot;
_vueSfc: () => import("@vue/compiler-sfc").SFCParseResult | undefined;
_sfc: import("../types").Sfc;
_mappings: () => {
sourceOffsets: number[];
generatedOffsets: number[];
lengths: number[];
data: import("@volar/language-core").CodeInformation;
}[];
_embeddedCodes: () => VirtualCode[];
private _vueSfc;
private _sfc;
private _embeddedCodes;
private _mappings;
get snapshot(): ts.IScriptSnapshot;
get vueSfc(): import("@vue/compiler-sfc").SFCParseResult | undefined;
get sfc(): import("../types").Sfc;
get embeddedCodes(): VirtualCode[];
get snapshot(): ts.IScriptSnapshot;
get mappings(): {

@@ -26,0 +23,0 @@ sourceOffsets: number[];

@@ -11,8 +11,14 @@ "use strict";

// others
get snapshot() {
return this._snapshot();
}
get vueSfc() {
return this._vueSfc();
}
get sfc() {
return this._sfc;
}
get embeddedCodes() {
return this._embeddedCodes();
}
get snapshot() {
return this._snapshot();
}
get mappings() {

@@ -34,2 +40,3 @@ return this._mappings();

this._sfc = (0, computedSfc_1.computedSfc)(this.ts, this.plugins, this.fileName, this._snapshot, this._vueSfc);
this._embeddedCodes = (0, computedEmbeddedCodes_1.computedEmbeddedCodes)(this.plugins, this.fileName, this._sfc);
this._mappings = (0, alien_signals_1.computed)(() => {

@@ -44,3 +51,2 @@ const snapshot = this._snapshot();

});
this._embeddedCodes = (0, computedEmbeddedCodes_1.computedEmbeddedCodes)(this.plugins, this.fileName, this._sfc);
this._snapshot(initSnapshot);

@@ -47,0 +53,0 @@ }

{
"name": "@vue/language-core",
"version": "2.2.2",
"version": "2.2.4",
"license": "MIT",

@@ -40,3 +40,3 @@ "files": [

},
"gitHead": "30757908b67f40f779c36795665163634fb81868"
"gitHead": "c28986596935cb43979c9d437c25f292bdb36cef"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc