Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
… feat/component-fallthrough
  • Loading branch information
KazariEX committed Oct 23, 2024
2 parents f1f5c2f + 1e04fc9 commit 7b3637d
Show file tree
Hide file tree
Showing 60 changed files with 676 additions and 449 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @johnsoncodehk @so1ve @KazariEX @zhiyuanzmj @KermanX @davidmatter
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,15 @@ lspconfig.tsserver.setup {
},
},
},
}

lspconfig.volar.setup {
init_options = {
vue = {
hybridMode = false,
},
},
},
}
```

### nvim-cmp integration
Expand Down
4 changes: 2 additions & 2 deletions packages/component-meta/lib/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,7 @@ function readVueComponentDefaultProps(

function scriptSetupWorker() {

const descriptor = vueSourceFile.sfc;
const descriptor = vueSourceFile._sfc;
const scriptSetupRanges = descriptor.scriptSetup ? vue.parseScriptSetupRanges(ts, descriptor.scriptSetup.ast, vueCompilerOptions) : undefined;

if (descriptor.scriptSetup && scriptSetupRanges?.props.withDefaults?.arg) {
Expand Down Expand Up @@ -772,7 +772,7 @@ function readVueComponentDefaultProps(

function scriptWorker() {

const descriptor = vueSourceFile.sfc;
const descriptor = vueSourceFile._sfc;

if (descriptor.script) {
const scriptResult = readTsComponentDefaultProps(descriptor.script.lang, descriptor.script.content, 'default', printer, ts);
Expand Down
1 change: 1 addition & 0 deletions packages/component-meta/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"**/*.js",
"**/*.d.ts"
],
"sideEffects": false,
"repository": {
"type": "git",
"url": "https://github.com/vuejs/language-tools.git",
Expand Down
1 change: 1 addition & 0 deletions packages/component-type-helpers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"**/*.js",
"**/*.d.ts"
],
"sideEffects": false,
"repository": {
"type": "git",
"url": "https://github.com/vuejs/language-tools.git",
Expand Down
8 changes: 5 additions & 3 deletions packages/language-core/lib/codegen/globalTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,11 @@ export function generateGlobalTypes(lib: string, target: number, strictTemplates
function __VLS_getSlotParams<T>(slot: T): Parameters<__VLS_PickNotAny<NonNullable<T>, (...args: any[]) => any>>;
// @ts-ignore
function __VLS_getSlotParam<T>(slot: T): Parameters<__VLS_PickNotAny<NonNullable<T>, (...args: any[]) => any>>[0];
function __VLS_directiveAsFunction<T extends import('${lib}').Directive>(dir: T): T extends (...args: any) => any
? T | __VLS_unknownDirective
: NonNullable<(T & Record<string, __VLS_unknownDirective>)['created' | 'beforeMount' | 'mounted' | 'beforeUpdate' | 'updated' | 'beforeUnmount' | 'unmounted']>;
function __VLS_asFunctionalDirective<T>(dir: T): T extends import('${lib}').ObjectDirective
? NonNullable<T['created' | 'beforeMount' | 'mounted' | 'beforeUpdate' | 'updated' | 'beforeUnmount' | 'unmounted']>
: T extends (...args: any) => any
? T
: __VLS_unknownDirective;
function __VLS_withScope<T, K>(ctx: T, scope: K): ctx is T & K;
function __VLS_makeOptional<T>(t: T): { [K in keyof T]?: T[K] };
function __VLS_nonNullable<T>(t: T): T extends null | undefined ? never : T;
Expand Down
25 changes: 25 additions & 0 deletions packages/language-core/lib/codegen/inlayHints.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type * as CompilerDOM from '@vue/compiler-dom';

export interface InlayHintInfo {
blockName: string;
offset: number;
setting: string;
label: string;
tooltip?: string;
paddingRight?: boolean;
paddingLeft?: boolean;
}

export function createVBindShorthandInlayHintInfo(loc: CompilerDOM.SourceLocation, variableName: string): InlayHintInfo {
return {
blockName: 'template',
offset: loc.end.offset,
setting: 'vue.inlayHints.vBindShorthand',
label: `="${variableName}"`,
tooltip: [
`This is a shorthand for \`${loc.source}="${variableName}"\`.`,
'To hide this hint, set `vue.inlayHints.vBindShorthand` to `false` in IDE settings.',
'[More info](https://github.com/vuejs/core/pull/9451)',
].join('\n\n'),
};
}
2 changes: 1 addition & 1 deletion packages/language-core/lib/codegen/script/context.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { InlayHintInfo } from '../types';
import { InlayHintInfo } from '../inlayHints';
import { getLocalTypesGenerator } from '../localTypes';
import type { ScriptCodegenOptions } from './index';

Expand Down
23 changes: 15 additions & 8 deletions packages/language-core/lib/codegen/script/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import type { Code, Sfc, VueCodeInformation, VueCompilerOptions } from '../../ty
import { endOfLine, generateSfcBlockSection, newLine } from '../common';
import { generateGlobalTypes } from '../globalTypes';
import type { TemplateCodegenContext } from '../template/context';
import { createScriptCodegenContext, ScriptCodegenContext } from './context';
import { generateComponentSelf } from './componentSelf';
import { createScriptCodegenContext, ScriptCodegenContext } from './context';
import { generateScriptSetup, generateScriptSetupImports } from './scriptSetup';
import { generateSrc } from './src';
import { generateStyleModulesType } from './styleModulesType';
Expand Down Expand Up @@ -79,6 +79,7 @@ export function* generateScript(options: ScriptCodegenOptions): Generator<Code,
}
else {
yield generateSfcBlockSection(options.sfc.script, 0, options.sfc.script.content.length, codeFeatures.all);
yield* generateScriptSectionPartiallyEnding(options.sfc.script.name, options.sfc.script.content.length, '#3632/both.vue');
yield* generateScriptSetup(options, ctx, options.sfc.scriptSetup, options.scriptSetupRanges);
}
}
Expand Down Expand Up @@ -114,8 +115,8 @@ export function* generateScript(options: ScriptCodegenOptions): Generator<Code,
}
else {
yield generateSfcBlockSection(options.sfc.script, 0, classBlockEnd, codeFeatures.all);
yield `__VLS_template = () => {`;
const templateCodegenCtx = yield* generateTemplate(options, ctx, true);
yield `__VLS_template = () => {${newLine}`;
const templateCodegenCtx = yield* generateTemplate(options, ctx);
yield* generateComponentSelf(options, ctx, templateCodegenCtx);
yield `},${newLine}`;
yield generateSfcBlockSection(options.sfc.script, classBlockEnd, options.sfc.script.content.length, codeFeatures.all);
Expand All @@ -131,16 +132,16 @@ export function* generateScript(options: ScriptCodegenOptions): Generator<Code,
yield* generateScriptSetup(options, ctx, options.sfc.scriptSetup, options.scriptSetupRanges);
}

yield `;`;
if (options.sfc.script) {
yield* generateScriptSectionPartiallyEnding(options.sfc.script.name, options.sfc.script.content.length, '#3632/script.vue');
}
if (options.sfc.scriptSetup) {
// #4569
yield ['', 'scriptSetup', options.sfc.scriptSetup.content.length, codeFeatures.verification];
yield* generateScriptSectionPartiallyEnding(options.sfc.scriptSetup.name, options.sfc.scriptSetup.content.length, '#4569/main.vue');
}
yield newLine;

if (!ctx.generatedTemplate) {
yield `function __VLS_template() {${newLine}`;
const templateCodegenCtx = yield* generateTemplate(options, ctx, false);
const templateCodegenCtx = yield* generateTemplate(options, ctx);
yield `}${endOfLine}`;
yield* generateComponentSelf(options, ctx, templateCodegenCtx);
}
Expand All @@ -163,6 +164,12 @@ export function* generateScript(options: ScriptCodegenOptions): Generator<Code,
return ctx;
}

export function* generateScriptSectionPartiallyEnding(source: string, end: number, mark: string): Generator<Code> {
yield `;`;
yield ['', source, end, codeFeatures.verification];
yield `/* PartiallyEnd: ${mark} */${newLine}`;
}

function* generateDefineProp(
options: ScriptCodegenOptions,
scriptSetup: NonNullable<Sfc['scriptSetup']>
Expand Down
8 changes: 5 additions & 3 deletions packages/language-core/lib/codegen/script/scriptSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import type { ScriptSetupRanges } from '../../parsers/scriptSetupRanges';
import type { Code, Sfc, TextRange } from '../../types';
import { endOfLine, generateSfcBlockSection, newLine } from '../common';
import { generateComponent, generateEmitsOption } from './component';
import type { ScriptCodegenContext } from './context';
import { ScriptCodegenOptions, codeFeatures } from './index';
import { generateComponentSelf } from './componentSelf';
import type { ScriptCodegenContext } from './context';
import { ScriptCodegenOptions, codeFeatures, generateScriptSectionPartiallyEnding } from './index';
import { generateTemplate } from './template';

export function* generateScriptSetupImports(
Expand Down Expand Up @@ -278,6 +278,8 @@ function* generateSetupFunction(
yield generateSfcBlockSection(scriptSetup, scriptSetupRanges.importSectionEndOffset, scriptSetup.content.length, codeFeatures.all);
}

yield* generateScriptSectionPartiallyEnding(scriptSetup.name, scriptSetup.content.length, '#3632/scriptSetup.vue');

if (scriptSetupRanges.props.define?.typeArg && scriptSetupRanges.props.withDefaults?.arg) {
// fix https://github.com/vuejs/language-tools/issues/1187
yield `const __VLS_withDefaultsArg = (function <T>(t: T) { return t })(`;
Expand All @@ -288,7 +290,7 @@ function* generateSetupFunction(
yield* generateComponentProps(options, ctx, scriptSetup, scriptSetupRanges, definePropMirrors);
yield* generateModelEmits(options, scriptSetup, scriptSetupRanges);
yield `function __VLS_template() {${newLine}`;
const templateCodegenCtx = yield* generateTemplate(options, ctx, false);
const templateCodegenCtx = yield* generateTemplate(options, ctx);
yield `}${endOfLine}`;
yield* generateComponentSelf(options, ctx, templateCodegenCtx);
yield `type __VLS_TemplateResult = ReturnType<typeof __VLS_template>${endOfLine}`;
Expand Down
18 changes: 5 additions & 13 deletions packages/language-core/lib/codegen/script/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,11 @@ import { generateStyleScopedClasses } from '../template/styleScopedClasses';
import type { ScriptCodegenContext } from './context';
import { codeFeatures, type ScriptCodegenOptions } from './index';

function* generateTemplateCtx(
options: ScriptCodegenOptions,
isClassComponent: boolean
): Generator<Code> {
function* generateTemplateCtx(options: ScriptCodegenOptions): Generator<Code> {
const exps = [];

if (isClassComponent) {
exps.push(`this`);
}
else {
exps.push(`{} as InstanceType<__VLS_PickNotAny<typeof __VLS_self, new () => {}>>`);
}
exps.push(`{} as InstanceType<__VLS_PickNotAny<typeof __VLS_self, new () => {}>>`);

if (options.vueCompilerOptions.petiteVueExtensions.some(ext => options.fileBaseName.endsWith(ext))) {
exps.push(`globalThis`);
}
Expand Down Expand Up @@ -116,16 +109,15 @@ export function* generateTemplateDirectives(options: ScriptCodegenOptions): Gene

export function* generateTemplate(
options: ScriptCodegenOptions,
ctx: ScriptCodegenContext,
isClassComponent: boolean
ctx: ScriptCodegenContext
): Generator<Code, TemplateCodegenContext> {
ctx.generatedTemplate = true;

const templateCodegenCtx = createTemplateCodegenContext({
scriptSetupBindingNames: new Set(),
edited: options.edited,
});
yield* generateTemplateCtx(options, isClassComponent);
yield* generateTemplateCtx(options);
yield* generateTemplateComponents(options);
yield* generateTemplateDirectives(options);
yield* generateTemplateBody(options, templateCodegenCtx);
Expand Down
2 changes: 1 addition & 1 deletion packages/language-core/lib/codegen/template/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type * as CompilerDOM from '@vue/compiler-dom';
import type { Code, VueCodeInformation } from '../../types';
import { endOfLine, newLine, wrapWith } from '../common';
import type { TemplateCodegenOptions } from './index';
import { InlayHintInfo } from '../types';
import { InlayHintInfo } from '../inlayHints';

const _codeFeatures = {
all: {
Expand Down
25 changes: 17 additions & 8 deletions packages/language-core/lib/codegen/template/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { generateInterpolation } from './interpolation';
import { generatePropertyAccess } from './propertyAccess';
import { generateTemplateChild } from './templateChild';
import { generateObjectProperty } from './objectProperty';
import { createVBindShorthandInlayHintInfo } from '../inlayHints';
import { getNodeText } from '../../parsers/scriptSetupRanges';

const colonReg = /:/g;
Expand Down Expand Up @@ -48,16 +49,24 @@ export function* generateComponent(

let props = node.props;
let dynamicTagInfo: {
exp: string;
tag: string;
offsets: [number, number | undefined];
astHolder: any;
astHolder: CompilerDOM.SourceLocation;
} | undefined;

if (isComponentTag) {
for (const prop of node.props) {
if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE && prop.name === 'bind' && prop.arg?.loc.source === 'is' && prop.exp) {
if (
prop.type === CompilerDOM.NodeTypes.DIRECTIVE
&& prop.name === 'bind'
&& prop.arg?.loc.source === 'is'
&& prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
) {
if (prop.arg.loc.end.offset === prop.exp.loc.end.offset) {
ctx.inlayHints.push(createVBindShorthandInlayHintInfo(prop.exp.loc, 'is'));
}
dynamicTagInfo = {
exp: prop.exp.loc.source,
tag: prop.exp.content,
offsets: [prop.exp.loc.start.offset, undefined],
astHolder: prop.exp.loc,
};
Expand All @@ -69,9 +78,9 @@ export function* generateComponent(
else if (node.tag.includes('.')) {
// namespace tag
dynamicTagInfo = {
exp: node.tag,
astHolder: node.loc,
tag: node.tag,
offsets: [startTagOffset, endTagOffset],
astHolder: node.loc,
};
}

Expand Down Expand Up @@ -110,7 +119,7 @@ export function* generateComponent(
yield* generateInterpolation(
options,
ctx,
dynamicTagInfo.exp,
dynamicTagInfo.tag,
dynamicTagInfo.astHolder,
dynamicTagInfo.offsets[0],
ctx.codeFeatures.all,
Expand All @@ -122,7 +131,7 @@ export function* generateComponent(
yield* generateInterpolation(
options,
ctx,
dynamicTagInfo.exp,
dynamicTagInfo.tag,
dynamicTagInfo.astHolder,
dynamicTagInfo.offsets[1],
{
Expand Down
Loading

0 comments on commit 7b3637d

Please sign in to comment.