-
-
Notifications
You must be signed in to change notification settings - Fork 416
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: write real files to FS for shared global types (#4736)
- Loading branch information
1 parent
a162f04
commit 38c1e48
Showing
29 changed files
with
608 additions
and
648 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,16 @@ | ||
export * from './lib/codegen/globalTypes'; | ||
export * from './lib/codegen/template'; | ||
export * from './lib/languagePlugin'; | ||
export * from './lib/parsers/scriptSetupRanges'; | ||
export * from './lib/plugins'; | ||
export * from './lib/virtualFile/vueFile'; | ||
export * from './lib/types'; | ||
export * from './lib/utils/ts'; | ||
export * from './lib/utils/parseSfc'; | ||
export * from './lib/utils/ts'; | ||
export * from './lib/virtualFile/vueFile'; | ||
|
||
export * as scriptRanges from './lib/parsers/scriptRanges'; | ||
export * from './lib/utils/shared'; | ||
export { tsCodegen } from './lib/plugins/vue-tsx'; | ||
export * from './lib/utils/shared'; | ||
|
||
export * from '@volar/language-core'; | ||
export type * as CompilerDOM from '@vue/compiler-dom'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
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<string, unknown>'}`; | ||
return ` | ||
const __VLS_globalComponents = { ...{} as import('${lib}').GlobalComponents }; | ||
declare const __VLS_intrinsicElements: __VLS_IntrinsicElements; | ||
declare const __VLS_directiveBindingRestFields = { instance: null, oldValue: null, modifiers: null as any, dir: null as any }; | ||
type __VLS_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;` | ||
)} | ||
type __VLS_GlobalComponents = ${( | ||
target >= 3.5 | ||
? `void extends typeof __VLS_globalComponents ? {} : typeof __VLS_globalComponents;` | ||
: `(void extends typeof __VLS_globalComponents ? {} : typeof __VLS_globalComponents) & Pick<typeof import('${lib}'), 'Transition' | 'TransitionGroup' | 'KeepAlive' | 'Suspense' | 'Teleport'>;` | ||
)} | ||
type __VLS_IsAny<T> = 0 extends 1 & T ? true : false; | ||
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_WithComponent<N0 extends string, LocalComponents, N1 extends string, N2 extends string, N3 extends string> = | ||
N1 extends keyof LocalComponents ? N1 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : { [K in N0]: LocalComponents[N1] } : | ||
N2 extends keyof LocalComponents ? N2 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : { [K in N0]: LocalComponents[N2] } : | ||
N3 extends keyof LocalComponents ? N3 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : { [K in N0]: LocalComponents[N3] } : | ||
N1 extends keyof __VLS_GlobalComponents ? N1 extends N0 ? Pick<__VLS_GlobalComponents, N0 extends keyof __VLS_GlobalComponents ? N0 : never> : { [K in N0]: __VLS_GlobalComponents[N1] } : | ||
N2 extends keyof __VLS_GlobalComponents ? N2 extends N0 ? Pick<__VLS_GlobalComponents, N0 extends keyof __VLS_GlobalComponents ? N0 : never> : { [K in N0]: __VLS_GlobalComponents[N2] } : | ||
N3 extends keyof __VLS_GlobalComponents ? N3 extends N0 ? Pick<__VLS_GlobalComponents, N0 extends keyof __VLS_GlobalComponents ? N0 : never> : { [K in N0]: __VLS_GlobalComponents[N3] } : | ||
${strictTemplates ? '{}' : '{ [K in N0]: unknown }'} | ||
type __VLS_FunctionalComponentProps<T, K> = | ||
'__ctx' extends keyof __VLS_PickNotAny<K, {}> ? K extends { __ctx?: { props?: infer P } } ? NonNullable<P> : never | ||
: T extends (props: infer P, ...args: any) => any ? P : | ||
{}; | ||
type __VLS_IsFunction<T, K> = K extends keyof T | ||
? __VLS_IsAny<T[K]> extends false | ||
? unknown extends T[K] | ||
? false | ||
: true | ||
: false | ||
: false; | ||
// fix https://github.com/vuejs/language-tools/issues/926 | ||
type __VLS_UnionToIntersection<U> = (U extends unknown ? (arg: U) => unknown : never) extends ((arg: infer P) => unknown) ? P : never; | ||
type __VLS_OverloadUnionInner<T, U = unknown> = U & T extends (...args: infer A) => infer R | ||
? U extends T | ||
? never | ||
: __VLS_OverloadUnionInner<T, Pick<T, keyof T> & U & ((...args: A) => R)> | ((...args: A) => R) | ||
: never; | ||
type __VLS_OverloadUnion<T> = Exclude< | ||
__VLS_OverloadUnionInner<(() => never) & T>, | ||
T extends () => never ? never : () => never | ||
>; | ||
type __VLS_ConstructorOverloads<T> = __VLS_OverloadUnion<T> extends infer F | ||
? F extends (event: infer E, ...args: infer A) => any | ||
? { [K in E & string]: (...args: A) => void; } | ||
: never | ||
: never; | ||
type __VLS_NormalizeEmits<T> = __VLS_PrettifyGlobal< | ||
__VLS_UnionToIntersection< | ||
__VLS_ConstructorOverloads<T> & { | ||
[K in keyof T]: T[K] extends any[] ? { (...args: T[K]): void } : never | ||
} | ||
> | ||
>; | ||
type __VLS_PrettifyGlobal<T> = { [K in keyof T]: T[K]; } & {}; | ||
declare function __VLS_getVForSourceType(source: number): [number, number, number][]; | ||
declare function __VLS_getVForSourceType(source: string): [string, number, number][]; | ||
declare function __VLS_getVForSourceType<T extends any[]>(source: T): [ | ||
item: T[number], | ||
key: number, | ||
index: number, | ||
][]; | ||
declare function __VLS_getVForSourceType<T extends { [Symbol.iterator](): Iterator<any> }>(source: T): [ | ||
item: T extends { [Symbol.iterator](): Iterator<infer T1> } ? T1 : never, | ||
key: number, | ||
index: undefined, | ||
][]; | ||
// #3845 | ||
declare 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), | ||
key: number, | ||
index: undefined, | ||
][]; | ||
declare function __VLS_getVForSourceType<T>(source: T): [ | ||
item: T[keyof T], | ||
key: keyof T, | ||
index: number, | ||
][]; | ||
// @ts-ignore | ||
declare function __VLS_getSlotParams<T>(slot: T): Parameters<__VLS_PickNotAny<NonNullable<T>, (...args: any[]) => any>>; | ||
// @ts-ignore | ||
declare function __VLS_getSlotParam<T>(slot: T): Parameters<__VLS_PickNotAny<NonNullable<T>, (...args: any[]) => any>>[0]; | ||
declare 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']>; | ||
declare function __VLS_withScope<T, K>(ctx: T, scope: K): ctx is T & K; | ||
declare function __VLS_makeOptional<T>(t: T): { [K in keyof T]?: T[K] }; | ||
declare function __VLS_nonNullable<T>(t: T): T extends null | undefined ? never : T; | ||
declare 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 { ${getSlotsPropertyName(target)}: infer Slots } ? Slots : any, | ||
emit?: K extends { $emit: infer Emit } ? Emit : any | ||
} & { props?: ${fnPropsType}; expose?(exposed: K): void; } } | ||
: T extends () => any ? (props: {}, ctx?: any) => ReturnType<T> | ||
: T extends (...args: any) => any ? T | ||
: (_: {}${strictTemplates ? '' : ' & Record<string, unknown>'}, ctx?: any) => { __ctx?: { attrs?: any, expose?: any, slots?: any, emit?: any, props?: {}${strictTemplates ? '' : ' & Record<string, unknown>'} } }; | ||
declare function __VLS_elementAsFunction<T>(tag: T, endTag?: T): (_: T${strictTemplates ? '' : ' & Record<string, unknown>'}) => void; | ||
declare function __VLS_functionalComponentArgsRest<T extends (...args: any) => any>(t: T): Parameters<T>['length'] extends 2 ? [any] : []; | ||
declare function __VLS_pickFunctionalComponentCtx<T, K>(comp: T, compInstance: K): NonNullable<__VLS_PickNotAny< | ||
'__ctx' extends keyof __VLS_PickNotAny<K, {}> ? K extends { __ctx?: infer Ctx } ? Ctx : never : any | ||
, T extends (props: any, ctx: infer Ctx) => any ? Ctx : any | ||
>>; | ||
declare function __VLS_normalizeSlot<S>(s: S): S extends () => infer R ? (props: {}) => R : S; | ||
declare function __VLS_tryAsConstant<const T>(t: T): T; | ||
`; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
import type * as ts from 'typescript'; | ||
import { VueCompilerOptions } from '../types'; | ||
import { getSlotsPropertyName } from '../utils/shared'; | ||
import { endOfLine } from './common'; | ||
|
||
export function getLocalTypesGenerator(compilerOptions: ts.CompilerOptions, vueCompilerOptions: VueCompilerOptions) { | ||
const used = new Set<string>(); | ||
|
||
const OmitKeepDiscriminatedUnion = defineHelper( | ||
`__VLS_OmitKeepDiscriminatedUnion`, | ||
() => ` | ||
type __VLS_OmitKeepDiscriminatedUnion<T, K extends keyof any> = T extends any | ||
? Pick<T, Exclude<keyof T, K>> | ||
: never; | ||
`.trimStart() | ||
); | ||
const WithDefaults = defineHelper( | ||
`__VLS_WithDefaults`, | ||
() => ` | ||
type __VLS_WithDefaults<P, D> = { | ||
[K in keyof Pick<P, keyof P>]: K extends keyof D | ||
? ${PrettifyLocal.name}<P[K] & { default: D[K]}> | ||
: P[K] | ||
}; | ||
`.trimStart() | ||
); | ||
const PrettifyLocal = defineHelper( | ||
`__VLS_PrettifyLocal`, | ||
() => `type __VLS_PrettifyLocal<T> = { [K in keyof T]: T[K]; } & {}${endOfLine}` | ||
); | ||
const WithTemplateSlots = defineHelper( | ||
`__VLS_WithTemplateSlots`, | ||
() => ` | ||
type __VLS_WithTemplateSlots<T, S> = T & { | ||
new(): { | ||
${getSlotsPropertyName(vueCompilerOptions.target)}: S; | ||
${vueCompilerOptions.jsxSlots ? `$props: ${PropsChildren.name}<S>;` : ''} | ||
} | ||
}; | ||
`.trimStart() | ||
); | ||
const PropsChildren = defineHelper( | ||
`__VLS_PropsChildren`, | ||
() => ` | ||
type __VLS_PropsChildren<S> = { | ||
[K in keyof ( | ||
boolean extends ( | ||
// @ts-ignore | ||
JSX.ElementChildrenAttribute extends never | ||
? true | ||
: false | ||
) | ||
? never | ||
// @ts-ignore | ||
: JSX.ElementChildrenAttribute | ||
)]?: S; | ||
}; | ||
`.trimStart() | ||
); | ||
const TypePropsToOption = defineHelper( | ||
`__VLS_TypePropsToOption`, | ||
() => compilerOptions.exactOptionalPropertyTypes ? | ||
` | ||
type __VLS_TypePropsToOption<T> = { | ||
[K in keyof T]-?: {} extends Pick<T, K> | ||
? { type: import('${vueCompilerOptions.lib}').PropType<T[K]> } | ||
: { type: import('${vueCompilerOptions.lib}').PropType<T[K]>, required: true } | ||
}; | ||
`.trimStart() : | ||
` | ||
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T; | ||
type __VLS_TypePropsToOption<T> = { | ||
[K in keyof T]-?: {} extends Pick<T, K> | ||
? { type: import('${vueCompilerOptions.lib}').PropType<__VLS_NonUndefinedable<T[K]>> } | ||
: { type: import('${vueCompilerOptions.lib}').PropType<T[K]>, required: true } | ||
}; | ||
`.trimStart() | ||
); | ||
const OmitIndexSignature = defineHelper( | ||
`__VLS_OmitIndexSignature`, | ||
() => `type __VLS_OmitIndexSignature<T> = { [K in keyof T as {} extends Record<K, unknown> ? never : K]: T[K]; }${endOfLine}` | ||
); | ||
const PickRefsExpose = defineHelper( | ||
`__VLS_PickRefsExpose`, | ||
() => ` | ||
type __VLS_PickRefsExpose<T> = T extends object | ||
? { [K in keyof T]: (T[K] extends any[] | ||
? Parameters<T[K][0]['expose']>[0][] | ||
: T[K] extends { expose?: (exposed: infer E) => void } | ||
? E | ||
: T[K]) | null } | ||
: never; | ||
`.trimStart() | ||
); | ||
|
||
const helpers = { | ||
[PrettifyLocal.name]: PrettifyLocal, | ||
[OmitKeepDiscriminatedUnion.name]: OmitKeepDiscriminatedUnion, | ||
[WithDefaults.name]: WithDefaults, | ||
[WithTemplateSlots.name]: WithTemplateSlots, | ||
[PropsChildren.name]: PropsChildren, | ||
[TypePropsToOption.name]: TypePropsToOption, | ||
[OmitIndexSignature.name]: OmitIndexSignature, | ||
[PickRefsExpose.name]: PickRefsExpose, | ||
}; | ||
used.clear(); | ||
|
||
return { | ||
generate, | ||
getUsedNames() { | ||
return used; | ||
}, | ||
get PrettifyLocal() { return PrettifyLocal.name; }, | ||
get OmitKeepDiscriminatedUnion() { return OmitKeepDiscriminatedUnion.name; }, | ||
get WithDefaults() { return WithDefaults.name; }, | ||
get WithTemplateSlots() { return WithTemplateSlots.name; }, | ||
get PropsChildren() { return PropsChildren.name; }, | ||
get TypePropsToOption() { return TypePropsToOption.name; }, | ||
get OmitIndexSignature() { return OmitIndexSignature.name; }, | ||
get PickRefsExpose() { return PickRefsExpose.name; }, | ||
}; | ||
|
||
function* generate(names: string[]) { | ||
const generated = new Set<string>(); | ||
while (names.length) { | ||
used.clear(); | ||
for (const name of names) { | ||
if (generated.has(name)) { | ||
continue; | ||
} | ||
const helper = helpers[name as keyof typeof helpers]; | ||
yield helper.generate(); | ||
generated.add(name); | ||
} | ||
names = [...used].filter(name => !generated.has(name)); | ||
} | ||
} | ||
|
||
function defineHelper(name: string, generate: () => string) { | ||
return { | ||
get name() { | ||
used.add(name); | ||
return name; | ||
}, | ||
generate, | ||
}; | ||
} | ||
} |
Oops, something went wrong.