Skip to content

Commit

Permalink
feat(compiler-sfc): expose resolve type-based props and emits (#8874)
Browse files Browse the repository at this point in the history
  • Loading branch information
sxzz committed Oct 27, 2023
1 parent a645e7a commit 9e77580
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 13 deletions.
3 changes: 3 additions & 0 deletions packages/compiler-sfc/src/index.ts
Expand Up @@ -33,6 +33,8 @@ export {

// Internals for type resolution
export { invalidateTypeCache, registerTS } from './script/resolveType'
export { extractRuntimeProps } from './script/defineProps'
export { extractRuntimeEmits } from './script/defineEmits'

// Types
export type {
Expand All @@ -58,6 +60,7 @@ export type { SFCScriptCompileOptions } from './compileScript'
export type { ScriptCompileContext } from './script/context'
export type {
TypeResolveContext,
SimpleTypeResolveOptions,
SimpleTypeResolveContext
} from './script/resolveType'
export type {
Expand Down
10 changes: 7 additions & 3 deletions packages/compiler-sfc/src/script/defineEmits.ts
Expand Up @@ -8,7 +8,11 @@ import {
} from '@babel/types'
import { isCallOf } from './utils'
import { ScriptCompileContext } from './context'
import { resolveTypeElements, resolveUnionType } from './resolveType'
import {
TypeResolveContext,
resolveTypeElements,
resolveUnionType
} from './resolveType'

export const DEFINE_EMITS = 'defineEmits'

Expand Down Expand Up @@ -64,7 +68,7 @@ export function genRuntimeEmits(ctx: ScriptCompileContext): string | undefined {
return emitsDecl
}

function extractRuntimeEmits(ctx: ScriptCompileContext): Set<string> {
export function extractRuntimeEmits(ctx: TypeResolveContext): Set<string> {
const emits = new Set<string>()
const node = ctx.emitsTypeDecl!

Expand Down Expand Up @@ -97,7 +101,7 @@ function extractRuntimeEmits(ctx: ScriptCompileContext): Set<string> {
}

function extractEventNames(
ctx: ScriptCompileContext,
ctx: TypeResolveContext,
eventName: ArrayPattern | Identifier | ObjectPattern | RestElement,
emits: Set<string>
) {
Expand Down
22 changes: 14 additions & 8 deletions packages/compiler-sfc/src/script/defineProps.ts
Expand Up @@ -8,7 +8,11 @@ import {
} from '@babel/types'
import { BindingTypes, isFunctionType } from '@vue/compiler-dom'
import { ScriptCompileContext } from './context'
import { inferRuntimeType, resolveTypeElements } from './resolveType'
import {
TypeResolveContext,
inferRuntimeType,
resolveTypeElements
} from './resolveType'
import {
resolveObjectKey,
UNKNOWN_TYPE,
Expand Down Expand Up @@ -150,7 +154,7 @@ export function genRuntimeProps(ctx: ScriptCompileContext): string | undefined {
}
}
} else if (ctx.propsTypeDecl) {
propsDecls = genRuntimePropsFromTypes(ctx)
propsDecls = extractRuntimeProps(ctx)
}

const modelsDecls = genModelProps(ctx)
Expand All @@ -162,7 +166,9 @@ export function genRuntimeProps(ctx: ScriptCompileContext): string | undefined {
}
}

function genRuntimePropsFromTypes(ctx: ScriptCompileContext) {
export function extractRuntimeProps(
ctx: TypeResolveContext
): string | undefined {
// this is only called if propsTypeDecl exists
const props = resolveRuntimePropsFromType(ctx, ctx.propsTypeDecl!)
if (!props.length) {
Expand All @@ -175,7 +181,7 @@ function genRuntimePropsFromTypes(ctx: ScriptCompileContext) {
for (const prop of props) {
propStrings.push(genRuntimePropFromType(ctx, prop, hasStaticDefaults))
// register bindings
if (!(prop.key in ctx.bindingMetadata)) {
if ('bindingMetadata' in ctx && !(prop.key in ctx.bindingMetadata)) {
ctx.bindingMetadata[prop.key] = BindingTypes.PROPS
}
}
Expand All @@ -193,7 +199,7 @@ function genRuntimePropsFromTypes(ctx: ScriptCompileContext) {
}

function resolveRuntimePropsFromType(
ctx: ScriptCompileContext,
ctx: TypeResolveContext,
node: Node
): PropTypeData[] {
const props: PropTypeData[] = []
Expand Down Expand Up @@ -222,7 +228,7 @@ function resolveRuntimePropsFromType(
}

function genRuntimePropFromType(
ctx: ScriptCompileContext,
ctx: TypeResolveContext,
{ key, required, type, skipCheck }: PropTypeData,
hasStaticDefaults: boolean
): string {
Expand Down Expand Up @@ -284,7 +290,7 @@ function genRuntimePropFromType(
* static properties, we can directly generate more optimized default
* declarations. Otherwise we will have to fallback to runtime merging.
*/
function hasStaticWithDefaults(ctx: ScriptCompileContext) {
function hasStaticWithDefaults(ctx: TypeResolveContext) {
return !!(
ctx.propsRuntimeDefaults &&
ctx.propsRuntimeDefaults.type === 'ObjectExpression' &&
Expand All @@ -297,7 +303,7 @@ function hasStaticWithDefaults(ctx: ScriptCompileContext) {
}

function genDestructuredDefaultValue(
ctx: ScriptCompileContext,
ctx: TypeResolveContext,
key: string,
inferredType?: string[]
):
Expand Down
26 changes: 24 additions & 2 deletions packages/compiler-sfc/src/script/resolveType.ts
Expand Up @@ -42,6 +42,13 @@ import type TS from 'typescript'
import { extname, dirname } from 'path'
import { minimatch as isMatch } from 'minimatch'

export type SimpleTypeResolveOptions = Partial<
Pick<
SFCScriptCompileOptions,
'globalTypeFiles' | 'fs' | 'babelParserPlugins' | 'isProd'
>
>

/**
* TypeResolveContext is compatible with ScriptCompileContext
* but also allows a simpler version of it with minimal required properties
Expand All @@ -59,13 +66,28 @@ import { minimatch as isMatch } from 'minimatch'
*/
export type SimpleTypeResolveContext = Pick<
ScriptCompileContext,
// required
'source' | 'filename' | 'error' | 'options'
// file
| 'source'
| 'filename'

// utils
| 'error'
| 'helper'
| 'getString'

// props
| 'propsTypeDecl'
| 'propsRuntimeDefaults'
| 'propsDestructuredBindings'

// emits
| 'emitsTypeDecl'
> &
Partial<
Pick<ScriptCompileContext, 'scope' | 'globalScopes' | 'deps' | 'fs'>
> & {
ast: Statement[]
options: SimpleTypeResolveOptions
}

export type TypeResolveContext = ScriptCompileContext | SimpleTypeResolveContext
Expand Down

0 comments on commit 9e77580

Please sign in to comment.