From 20152264347e42bde73a43a79f6829e6ee1d9d39 Mon Sep 17 00:00:00 2001 From: KazariEX <1364035137@qq.com> Date: Thu, 5 Sep 2024 01:22:53 +0800 Subject: [PATCH 1/6] feat: typed directives in template --- .../lib/codegen/script/template.ts | 28 +++++++++++++++++++ .../lib/codegen/template/elementDirectives.ts | 2 +- .../language-core/lib/parsers/scriptRanges.ts | 10 +++++-- .../passedFixtures/vue3/directives/main.vue | 26 +++++++++++++---- 4 files changed, 58 insertions(+), 8 deletions(-) diff --git a/packages/language-core/lib/codegen/script/template.ts b/packages/language-core/lib/codegen/script/template.ts index 43b95da7c9..98757dcd2a 100644 --- a/packages/language-core/lib/codegen/script/template.ts +++ b/packages/language-core/lib/codegen/script/template.ts @@ -87,6 +87,33 @@ function* generateTemplateComponents(options: ScriptCodegenOptions): Generator { + const exps: Code[] = []; + + if (options.sfc.script && options.scriptRanges?.exportDefault?.directivesOption) { + const { directivesOption } = options.scriptRanges.exportDefault; + exps.push([ + options.sfc.script.content.substring(directivesOption.start, directivesOption.end), + 'script', + directivesOption.start, + codeFeatures.navigation, + ]); + } + + exps.push(`{} as NonNullable`); + exps.push(`__VLS_ctx`); + + yield `const __VLS_localDirectives = {${newLine}`; + for (const type of exps) { + yield `...`; + yield type; + yield `,${newLine}`; + } + yield `}${endOfLine}`; + + yield `let __VLS_directives: typeof __VLS_localDirectives & import('${options.vueCompilerOptions.lib}').GlobalDirectives${endOfLine}`; +} + export function* generateTemplate( options: ScriptCodegenOptions, ctx: ScriptCodegenContext, @@ -100,6 +127,7 @@ export function* generateTemplate( }); yield* generateTemplateCtx(options, isClassComponent); yield* generateTemplateComponents(options); + yield* generateTemplateDirectives(options); yield* generateTemplateBody(options, templateCodegenCtx); return templateCodegenCtx; } diff --git a/packages/language-core/lib/codegen/template/elementDirectives.ts b/packages/language-core/lib/codegen/template/elementDirectives.ts index edf88ab15b..06869d0392 100644 --- a/packages/language-core/lib/codegen/template/elementDirectives.ts +++ b/packages/language-core/lib/codegen/template/elementDirectives.ts @@ -43,7 +43,7 @@ export function* generateElementDirectives( prop.loc.start.offset, prop.loc.end.offset, ctx.codeFeatures.verification, - `__VLS_directiveAsFunction(__VLS_ctx.`, + `__VLS_directiveAsFunction(__VLS_directives.`, ...generateCamelized( 'v-' + prop.name, prop.loc.start.offset, diff --git a/packages/language-core/lib/parsers/scriptRanges.ts b/packages/language-core/lib/parsers/scriptRanges.ts index 01e5101e81..394eb16dce 100644 --- a/packages/language-core/lib/parsers/scriptRanges.ts +++ b/packages/language-core/lib/parsers/scriptRanges.ts @@ -12,6 +12,7 @@ export function parseScriptRanges(ts: typeof import('typescript'), ast: ts.Sourc argsNode: ts.ObjectLiteralExpression | undefined, componentsOption: TextRange | undefined, componentsOptionNode: ts.ObjectLiteralExpression | undefined, + directivesOption: TextRange | undefined, nameOption: TextRange | undefined, inheritAttrsOption: string | undefined, }) | undefined; @@ -40,6 +41,7 @@ export function parseScriptRanges(ts: typeof import('typescript'), ast: ts.Sourc } if (obj) { let componentsOptionNode: ts.ObjectLiteralExpression | undefined; + let directivesOptionNode: ts.ObjectLiteralExpression | undefined; let nameOptionNode: ts.Expression | undefined; let inheritAttrsOption: string | undefined; ts.forEachChild(obj, node => { @@ -48,10 +50,13 @@ export function parseScriptRanges(ts: typeof import('typescript'), ast: ts.Sourc if (name === 'components' && ts.isObjectLiteralExpression(node.initializer)) { componentsOptionNode = node.initializer; } - if (name === 'name') { + else if (name === 'directives' && ts.isObjectLiteralExpression(node.initializer)) { + directivesOptionNode = node.initializer; + } + else if (name === 'name') { nameOptionNode = node.initializer; } - if (name === 'inheritAttrs') { + else if (name === 'inheritAttrs') { inheritAttrsOption = getNodeText(ts, node.initializer, ast); } } @@ -63,6 +68,7 @@ export function parseScriptRanges(ts: typeof import('typescript'), ast: ts.Sourc argsNode: withNode ? obj : undefined, componentsOption: componentsOptionNode ? _getStartEnd(componentsOptionNode) : undefined, componentsOptionNode: withNode ? componentsOptionNode : undefined, + directivesOption: directivesOptionNode ? _getStartEnd(directivesOptionNode) : undefined, nameOption: nameOptionNode ? _getStartEnd(nameOptionNode) : undefined, inheritAttrsOption, }; diff --git a/test-workspace/tsc/passedFixtures/vue3/directives/main.vue b/test-workspace/tsc/passedFixtures/vue3/directives/main.vue index 006440002f..3d1d92c0a4 100644 --- a/test-workspace/tsc/passedFixtures/vue3/directives/main.vue +++ b/test-workspace/tsc/passedFixtures/vue3/directives/main.vue @@ -1,12 +1,28 @@ - + + + + + + \ No newline at end of file From 9eae3384c310ddda95fd5cb9148aaeeb5fd46b25 Mon Sep 17 00:00:00 2001 From: KazariEX <1364035137@qq.com> Date: Thu, 5 Sep 2024 01:33:56 +0800 Subject: [PATCH 2/6] fix: compatibility --- .../language-core/lib/codegen/globalTypes.ts | 29 +++++++++++-------- .../lib/codegen/script/template.ts | 2 +- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/packages/language-core/lib/codegen/globalTypes.ts b/packages/language-core/lib/codegen/globalTypes.ts index 28dab72d37..97b8e1eda8 100644 --- a/packages/language-core/lib/codegen/globalTypes.ts +++ b/packages/language-core/lib/codegen/globalTypes.ts @@ -17,20 +17,25 @@ declare global { }; type __VLS_IntrinsicElements = ${( - target >= 3.3 - ? `import('${lib}/jsx-runtime').JSX.IntrinsicElements;` - : `globalThis.JSX.IntrinsicElements;` - )} + target >= 3.3 + ? `import('${lib}/jsx-runtime').JSX.IntrinsicElements;` + : `globalThis.JSX.IntrinsicElements;` + )} type __VLS_Element = ${( - target >= 3.3 - ? `import('${lib}/jsx-runtime').JSX.Element;` - : `globalThis.JSX.Element;` - )} + target >= 3.3 + ? `import('${lib}/jsx-runtime').JSX.Element;` + : `globalThis.JSX.Element;` + )} type __VLS_GlobalComponents = ${( - target >= 3.5 - ? `import('${lib}').GlobalComponents` - : `import('${lib}').GlobalComponents & Pick;` - )} + target >= 3.5 + ? `import('${lib}').GlobalComponents;` + : `import('${lib}').GlobalComponents & Pick;` + )} + type __VLS_GlobalDirectives = ${( + target >= 3.5 + ? `import('${lib}').GlobalDirectives;` + : `{};` + )} type __VLS_IsAny = 0 extends 1 & T ? true : false; type __VLS_PickNotAny = __VLS_IsAny extends true ? B : A; type __VLS_unknownDirective = (arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown) => void; diff --git a/packages/language-core/lib/codegen/script/template.ts b/packages/language-core/lib/codegen/script/template.ts index 98757dcd2a..55692f6c07 100644 --- a/packages/language-core/lib/codegen/script/template.ts +++ b/packages/language-core/lib/codegen/script/template.ts @@ -111,7 +111,7 @@ export function* generateTemplateDirectives(options: ScriptCodegenOptions): Gene } yield `}${endOfLine}`; - yield `let __VLS_directives: typeof __VLS_localDirectives & import('${options.vueCompilerOptions.lib}').GlobalDirectives${endOfLine}`; + yield `let __VLS_directives: typeof __VLS_localDirectives & __VLS_GlobalDirectives${endOfLine}`; } export function* generateTemplate( From 026d0181e163081a1497d85e3de53d3e5c79f86c Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Thu, 5 Sep 2024 02:05:35 +0800 Subject: [PATCH 3/6] format --- .../language-core/lib/codegen/globalTypes.ts | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/language-core/lib/codegen/globalTypes.ts b/packages/language-core/lib/codegen/globalTypes.ts index 97b8e1eda8..9a50dedb43 100644 --- a/packages/language-core/lib/codegen/globalTypes.ts +++ b/packages/language-core/lib/codegen/globalTypes.ts @@ -17,25 +17,25 @@ declare global { }; type __VLS_IntrinsicElements = ${( - target >= 3.3 - ? `import('${lib}/jsx-runtime').JSX.IntrinsicElements;` - : `globalThis.JSX.IntrinsicElements;` - )} + target >= 3.3 + ? `import('${lib}/jsx-runtime').JSX.IntrinsicElements;` + : `globalThis.JSX.IntrinsicElements;` + )} type __VLS_Element = ${( - target >= 3.3 - ? `import('${lib}/jsx-runtime').JSX.Element;` - : `globalThis.JSX.Element;` - )} + target >= 3.3 + ? `import('${lib}/jsx-runtime').JSX.Element;` + : `globalThis.JSX.Element;` + )} type __VLS_GlobalComponents = ${( - target >= 3.5 - ? `import('${lib}').GlobalComponents;` - : `import('${lib}').GlobalComponents & Pick;` - )} + target >= 3.5 + ? `import('${lib}').GlobalComponents;` + : `import('${lib}').GlobalComponents & Pick;` + )} type __VLS_GlobalDirectives = ${( - target >= 3.5 - ? `import('${lib}').GlobalDirectives;` - : `{};` - )} + target >= 3.5 + ? `import('${lib}').GlobalDirectives;` + : `{};` + )} type __VLS_IsAny = 0 extends 1 & T ? true : false; type __VLS_PickNotAny = __VLS_IsAny extends true ? B : A; type __VLS_unknownDirective = (arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown) => void; From bd0b6e233c6480053fdb38cc5986db36e393d970 Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Thu, 5 Sep 2024 02:13:05 +0800 Subject: [PATCH 4/6] Update main.vue --- .../passedFixtures/vue3/directives/main.vue | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test-workspace/tsc/passedFixtures/vue3/directives/main.vue b/test-workspace/tsc/passedFixtures/vue3/directives/main.vue index 3d1d92c0a4..62a0808952 100644 --- a/test-workspace/tsc/passedFixtures/vue3/directives/main.vue +++ b/test-workspace/tsc/passedFixtures/vue3/directives/main.vue @@ -3,17 +3,17 @@ import { FunctionDirective } from 'vue'; import { exactType } from '../../shared'; declare module 'vue' { - interface GlobalDirectives { - vFoo: FunctionDirective void>; - } + interface GlobalDirectives { + vFoo: FunctionDirective void>; + } } let Comp!: (_: { foo?: string; }) => void; export default { - directives: { - vBar: {} as FunctionDirective void> - } + directives: { + vBar: {} as FunctionDirective void> + } }; @@ -23,6 +23,6 @@ let vBaz!: FunctionDirective void>; \ No newline at end of file + + + From 11bd13f9d51a8e31279863d48b83f1c3678ea682 Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Thu, 5 Sep 2024 02:19:28 +0800 Subject: [PATCH 5/6] Update globalTypes.ts --- .../language-core/lib/codegen/globalTypes.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/language-core/lib/codegen/globalTypes.ts b/packages/language-core/lib/codegen/globalTypes.ts index 9a50dedb43..0c704a71d3 100644 --- a/packages/language-core/lib/codegen/globalTypes.ts +++ b/packages/language-core/lib/codegen/globalTypes.ts @@ -2,11 +2,16 @@ import { getSlotsPropertyName } from '../utils/shared'; export function generateGlobalTypes(lib: string, target: number, strictTemplates: boolean) { const fnPropsType = `(K extends { $props: infer Props } ? Props : any)${strictTemplates ? '' : ' & Record'}`; - return ` + let text = ``; + if (target < 3.5) { + text += ` ; declare module '${lib}' { export interface GlobalComponents { } -} -declare global { + export interface GlobalDirectives { } +}`; + } + text += ` +; declare global { const __VLS_intrinsicElements: __VLS_IntrinsicElements; const __VLS_directiveBindingRestFields: { instance: null, oldValue: null, modifiers: any, dir: any }; const __VLS_unref: typeof import('${lib}').unref; @@ -31,11 +36,7 @@ declare global { ? `import('${lib}').GlobalComponents;` : `import('${lib}').GlobalComponents & Pick;` )} - type __VLS_GlobalDirectives = ${( - target >= 3.5 - ? `import('${lib}').GlobalDirectives;` - : `{};` - )} + type __VLS_GlobalDirectives = import('${lib}').GlobalDirectives; type __VLS_IsAny = 0 extends 1 & T ? true : false; type __VLS_PickNotAny = __VLS_IsAny extends true ? B : A; type __VLS_unknownDirective = (arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown) => void; @@ -136,4 +137,5 @@ declare global { function __VLS_tryAsConstant(t: T): T; } `; + return text; }; From 60064f0c9ffbe28eb294137b28143a1cddca5e11 Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Thu, 5 Sep 2024 02:42:46 +0800 Subject: [PATCH 6/6] fixes --- .../lib/codegen/script/template.ts | 4 ++-- .../tsc/passedFixtures/vue2/tsconfig.json | 1 + .../passedFixtures/vue3/directives/main.vue | 15 +++------------ .../passedFixtures/vue3/directives/option.vue | 19 +++++++++++++++++++ 4 files changed, 25 insertions(+), 14 deletions(-) create mode 100644 test-workspace/tsc/passedFixtures/vue3/directives/option.vue diff --git a/packages/language-core/lib/codegen/script/template.ts b/packages/language-core/lib/codegen/script/template.ts index 55692f6c07..44dbbc59ce 100644 --- a/packages/language-core/lib/codegen/script/template.ts +++ b/packages/language-core/lib/codegen/script/template.ts @@ -84,7 +84,7 @@ function* generateTemplateComponents(options: ScriptCodegenOptions): Generator { @@ -111,7 +111,7 @@ export function* generateTemplateDirectives(options: ScriptCodegenOptions): Gene } yield `}${endOfLine}`; - yield `let __VLS_directives: typeof __VLS_localDirectives & __VLS_GlobalDirectives${endOfLine}`; + yield `let __VLS_directives!: typeof __VLS_localDirectives & __VLS_GlobalDirectives${endOfLine}`; } export function* generateTemplate( diff --git a/test-workspace/tsc/passedFixtures/vue2/tsconfig.json b/test-workspace/tsc/passedFixtures/vue2/tsconfig.json index 13e6c0f8f6..1ff36d1175 100644 --- a/test-workspace/tsc/passedFixtures/vue2/tsconfig.json +++ b/test-workspace/tsc/passedFixtures/vue2/tsconfig.json @@ -29,6 +29,7 @@ "../vue3/defineEmits", "../vue3/defineModel", "../vue3/defineProp_B", + "../vue3/directives/option.vue", "../vue3/events", "../vue3/no-script-block", "../vue3/slots", diff --git a/test-workspace/tsc/passedFixtures/vue3/directives/main.vue b/test-workspace/tsc/passedFixtures/vue3/directives/main.vue index 62a0808952..05bf31f895 100644 --- a/test-workspace/tsc/passedFixtures/vue3/directives/main.vue +++ b/test-workspace/tsc/passedFixtures/vue3/directives/main.vue @@ -1,4 +1,4 @@ - - - diff --git a/test-workspace/tsc/passedFixtures/vue3/directives/option.vue b/test-workspace/tsc/passedFixtures/vue3/directives/option.vue new file mode 100644 index 0000000000..10878f25f9 --- /dev/null +++ b/test-workspace/tsc/passedFixtures/vue3/directives/option.vue @@ -0,0 +1,19 @@ + + + + +