Skip to content

Commit

Permalink
fix(language-core): generate macros after script setup content (#5071)
Browse files Browse the repository at this point in the history
  • Loading branch information
KazariEX authored Dec 20, 2024
1 parent 3216627 commit 4fff892
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 34 deletions.
23 changes: 0 additions & 23 deletions packages/language-core/lib/codegen/script/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ export function* generateScript(options: ScriptCodegenOptions): Generator<Code,
&& options.sfc.script.content[exportDefault.expression.start] === '{';
if (options.sfc.scriptSetup && options.scriptSetupRanges) {
yield* generateScriptSetupImports(options.sfc.scriptSetup, options.scriptSetupRanges);
yield* generateDefineProp(options, options.sfc.scriptSetup);
if (exportDefault) {
yield generateSfcBlockSection(options.sfc.script, 0, exportDefault.expression.start, codeFeatures.all);
yield* generateScriptSetup(options, ctx, options.sfc.scriptSetup, options.scriptSetupRanges);
Expand Down Expand Up @@ -141,7 +140,6 @@ export function* generateScript(options: ScriptCodegenOptions): Generator<Code,
}
else if (options.sfc.scriptSetup && options.scriptSetupRanges) {
yield* generateScriptSetupImports(options.sfc.scriptSetup, options.scriptSetupRanges);
yield* generateDefineProp(options, options.sfc.scriptSetup);
yield* generateScriptSetup(options, ctx, options.sfc.scriptSetup, options.scriptSetupRanges);
}

Expand Down Expand Up @@ -182,24 +180,3 @@ export function* generateScriptSectionPartiallyEnding(source: string, end: numbe
yield ['', source, end, codeFeatures.verification];
yield `/* PartiallyEnd: ${mark} */${newLine}`;
}

function* generateDefineProp(
options: ScriptCodegenOptions,
scriptSetup: NonNullable<Sfc['scriptSetup']>
): Generator<Code> {
const definePropProposalA = scriptSetup.content.trimStart().startsWith('// @experimentalDefinePropProposal=kevinEdition') || options.vueCompilerOptions.experimentalDefinePropProposal === 'kevinEdition';
const definePropProposalB = scriptSetup.content.trimStart().startsWith('// @experimentalDefinePropProposal=johnsonEdition') || options.vueCompilerOptions.experimentalDefinePropProposal === 'johnsonEdition';

if (definePropProposalA || definePropProposalB) {
yield `type __VLS_PropOptions<T> = Exclude<import('${options.vueCompilerOptions.lib}').Prop<T>, import('${options.vueCompilerOptions.lib}').PropType<T>>${endOfLine}`;
if (definePropProposalA) {
yield `declare function defineProp<T>(name: string, options: ({ required: true } | { default: T }) & __VLS_PropOptions<T>): import('${options.vueCompilerOptions.lib}').ComputedRef<T>${endOfLine}`;
yield `declare function defineProp<T>(name?: string, options?: __VLS_PropOptions<T>): import('${options.vueCompilerOptions.lib}').ComputedRef<T | undefined>${endOfLine}`;
}
if (definePropProposalB) {
yield `declare function defineProp<T>(value: T | (() => T), required?: boolean, options?: __VLS_PropOptions<T>): import('${options.vueCompilerOptions.lib}').ComputedRef<T>${endOfLine}`;
yield `declare function defineProp<T>(value: T | (() => T) | undefined, required: true, options?: __VLS_PropOptions<T>): import('${options.vueCompilerOptions.lib}').ComputedRef<T>${endOfLine}`;
yield `declare function defineProp<T>(value?: T | (() => T), required?: boolean, options?: __VLS_PropOptions<T>): import('${options.vueCompilerOptions.lib}').ComputedRef<T | undefined>${endOfLine}`;
}
}
}
49 changes: 38 additions & 11 deletions packages/language-core/lib/codegen/script/scriptSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export function* generateScriptSetupImports(
0,
codeFeatures.all,
];
yield newLine;
}

export function* generateScriptSetup(
Expand Down Expand Up @@ -96,16 +95,6 @@ function* generateSetupFunction(
scriptSetupRanges: ScriptSetupRanges,
syntax: 'return' | 'export default' | undefined
): Generator<Code> {
if (options.vueCompilerOptions.target >= 3.3) {
yield `const { `;
for (const macro of Object.keys(options.vueCompilerOptions.macros)) {
if (!ctx.bindingNames.has(macro) && macro !== 'templateRef') {
yield macro + `, `;
}
}
yield `} = await import('${options.vueCompilerOptions.lib}')${endOfLine}`;
}

ctx.scriptSetupGeneratedOffset = options.getGeneratedLength() - scriptSetupRanges.importSectionEndOffset;

let setupCodeModifies: [Code[], number, number][] = [];
Expand Down Expand Up @@ -280,6 +269,8 @@ function* generateSetupFunction(
yield generateSfcBlockSection(scriptSetup, nextStart, scriptSetup.content.length, codeFeatures.all);

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

if (scriptSetupRanges.defineProps?.typeArg && scriptSetupRanges.withDefaults?.arg) {
// fix https://github.com/vuejs/language-tools/issues/1187
Expand Down Expand Up @@ -317,6 +308,42 @@ function* generateSetupFunction(
}
}

function* generateMacros(
options: ScriptCodegenOptions,
ctx: ScriptCodegenContext
): Generator<Code> {
if (options.vueCompilerOptions.target >= 3.3) {
yield `declare const { `;
for (const macro of Object.keys(options.vueCompilerOptions.macros)) {
if (!ctx.bindingNames.has(macro)) {
yield `${macro}, `;
}
}
yield `}: typeof import('${options.vueCompilerOptions.lib}')${endOfLine}`;
}
}

function* generateDefineProp(
options: ScriptCodegenOptions,
scriptSetup: NonNullable<Sfc['scriptSetup']>
): Generator<Code> {
const definePropProposalA = scriptSetup.content.trimStart().startsWith('// @experimentalDefinePropProposal=kevinEdition') || options.vueCompilerOptions.experimentalDefinePropProposal === 'kevinEdition';
const definePropProposalB = scriptSetup.content.trimStart().startsWith('// @experimentalDefinePropProposal=johnsonEdition') || options.vueCompilerOptions.experimentalDefinePropProposal === 'johnsonEdition';

if (definePropProposalA || definePropProposalB) {
yield `type __VLS_PropOptions<T> = Exclude<import('${options.vueCompilerOptions.lib}').Prop<T>, import('${options.vueCompilerOptions.lib}').PropType<T>>${endOfLine}`;
if (definePropProposalA) {
yield `declare function defineProp<T>(name: string, options: ({ required: true } | { default: T }) & __VLS_PropOptions<T>): import('${options.vueCompilerOptions.lib}').ComputedRef<T>${endOfLine}`;
yield `declare function defineProp<T>(name?: string, options?: __VLS_PropOptions<T>): import('${options.vueCompilerOptions.lib}').ComputedRef<T | undefined>${endOfLine}`;
}
if (definePropProposalB) {
yield `declare function defineProp<T>(value: T | (() => T), required?: boolean, options?: __VLS_PropOptions<T>): import('${options.vueCompilerOptions.lib}').ComputedRef<T>${endOfLine}`;
yield `declare function defineProp<T>(value: T | (() => T) | undefined, required: true, options?: __VLS_PropOptions<T>): import('${options.vueCompilerOptions.lib}').ComputedRef<T>${endOfLine}`;
yield `declare function defineProp<T>(value?: T | (() => T), required?: boolean, options?: __VLS_PropOptions<T>): import('${options.vueCompilerOptions.lib}').ComputedRef<T | undefined>${endOfLine}`;
}
}
}

function* generateDefineWithType(
scriptSetup: NonNullable<Sfc['scriptSetup']>,
statement: TextRange,
Expand Down
4 changes: 4 additions & 0 deletions packages/tsc/tests/typecheck.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ describe(`vue-tsc`, () => {
"test-workspace/tsc/failureFixtures/#3632/both.vue(7,1): error TS1109: Expression expected.",
"test-workspace/tsc/failureFixtures/#3632/script.vue(3,1): error TS1109: Expression expected.",
"test-workspace/tsc/failureFixtures/#3632/scriptSetup.vue(3,1): error TS1109: Expression expected.",
"test-workspace/tsc/failureFixtures/#5071/withoutScript.vue(2,26): error TS1005: ';' expected.",
"test-workspace/tsc/failureFixtures/#5071/withScript.vue(1,19): error TS1005: ';' expected.",
"test-workspace/tsc/failureFixtures/directives/main.vue(4,6): error TS2339: Property 'notExist' does not exist on type 'CreateComponentPublicInstanceWithMixins<ToResolvedProps<{}, {}>, { exist: typeof exist; }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 18 more ..., {}>'.",
"test-workspace/tsc/failureFixtures/directives/main.vue(9,6): error TS2339: Property 'notExist' does not exist on type 'CreateComponentPublicInstanceWithMixins<ToResolvedProps<{}, {}>, { exist: typeof exist; }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 18 more ..., {}>'.",
"test-workspace/tsc/failureFixtures/directives/main.vue(12,2): error TS2578: Unused '@ts-expect-error' directive.",
Expand All @@ -32,6 +34,8 @@ describe(`vue-tsc`, () => {
"test-workspace/tsc/failureFixtures/#3632/both.vue(7,1): error TS1109: Expression expected.",
"test-workspace/tsc/failureFixtures/#3632/script.vue(3,1): error TS1109: Expression expected.",
"test-workspace/tsc/failureFixtures/#3632/scriptSetup.vue(3,1): error TS1109: Expression expected.",
"test-workspace/tsc/failureFixtures/#5071/withoutScript.vue(2,26): error TS1005: ';' expected.",
"test-workspace/tsc/failureFixtures/#5071/withScript.vue(1,19): error TS1005: ';' expected.",
"test-workspace/tsc/failureFixtures/directives/main.vue(4,6): error TS2339: Property 'notExist' does not exist on type 'CreateComponentPublicInstanceWithMixins<ToResolvedProps<{}, {}>, { exist: typeof exist; }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 18 more ..., {}>'.",
"test-workspace/tsc/failureFixtures/directives/main.vue(9,6): error TS2339: Property 'notExist' does not exist on type 'CreateComponentPublicInstanceWithMixins<ToResolvedProps<{}, {}>, { exist: typeof exist; }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 18 more ..., {}>'.",
"test-workspace/tsc/failureFixtures/directives/main.vue(12,2): error TS2578: Unused '@ts-expect-error' directive.",
Expand Down
4 changes: 4 additions & 0 deletions test-workspace/tsc/failureFixtures/#5071/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "../../../tsconfig.base.json",
"include": [ "**/*" ]
}
6 changes: 6 additions & 0 deletions test-workspace/tsc/failureFixtures/#5071/withScript.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<script lang="ts">export default {};
</script>

<script setup lang="ts">
import { ref } from 'vue'ref('');
</script>
3 changes: 3 additions & 0 deletions test-workspace/tsc/failureFixtures/#5071/withoutScript.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<script setup lang="ts">
import { ref } from 'vue'ref('');
</script>
1 change: 1 addition & 0 deletions test-workspace/tsc/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"references": [
{ "path": "./failureFixtures/#3632" },
// { "path": "./failureFixtures/#4569" }, // TODO: not working with --build flag
{ "path": "./failureFixtures/#5071" },
{ "path": "./failureFixtures/directives" },

{ "path": "./passedFixtures/#1886" },
Expand Down

0 comments on commit 4fff892

Please sign in to comment.