From 7215414bfdda031be1d90cfaa885bad77bbeb81d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E6=99=BA=E5=AD=90=20Kevin=20Deng?=
 <sxzz@sxzz.moe>
Date: Sun, 30 Jul 2023 23:11:22 +0800
Subject: [PATCH 1/3] feat(compiler-sfc): expose resolve TS type

for babel plugin usage
---
 packages/compiler-sfc/src/index.ts              | 2 ++
 packages/compiler-sfc/src/script/defineEmits.ts | 2 +-
 packages/compiler-sfc/src/script/defineProps.ts | 6 ++++--
 3 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/packages/compiler-sfc/src/index.ts b/packages/compiler-sfc/src/index.ts
index 76b4900d46d..7c886a280e2 100644
--- a/packages/compiler-sfc/src/index.ts
+++ b/packages/compiler-sfc/src/index.ts
@@ -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 {
diff --git a/packages/compiler-sfc/src/script/defineEmits.ts b/packages/compiler-sfc/src/script/defineEmits.ts
index 02014d1b276..a308093e1f9 100644
--- a/packages/compiler-sfc/src/script/defineEmits.ts
+++ b/packages/compiler-sfc/src/script/defineEmits.ts
@@ -57,7 +57,7 @@ export function genRuntimeEmits(ctx: ScriptCompileContext): string | undefined {
   return emitsDecl
 }
 
-function extractRuntimeEmits(ctx: ScriptCompileContext): Set<string> {
+export function extractRuntimeEmits(ctx: ScriptCompileContext): Set<string> {
   const emits = new Set<string>()
   const node = ctx.emitsTypeDecl!
 
diff --git a/packages/compiler-sfc/src/script/defineProps.ts b/packages/compiler-sfc/src/script/defineProps.ts
index 5004e314da1..2fd35a3eabb 100644
--- a/packages/compiler-sfc/src/script/defineProps.ts
+++ b/packages/compiler-sfc/src/script/defineProps.ts
@@ -150,7 +150,7 @@ export function genRuntimeProps(ctx: ScriptCompileContext): string | undefined {
       }
     }
   } else if (ctx.propsTypeDecl) {
-    propsDecls = genRuntimePropsFromTypes(ctx)
+    propsDecls = extractRuntimeProps(ctx)
   }
 
   const modelsDecls = genModelProps(ctx)
@@ -162,7 +162,9 @@ export function genRuntimeProps(ctx: ScriptCompileContext): string | undefined {
   }
 }
 
-function genRuntimePropsFromTypes(ctx: ScriptCompileContext) {
+export function extractRuntimeProps(
+  ctx: ScriptCompileContext
+): string | undefined {
   // this is only called if propsTypeDecl exists
   const props = resolveRuntimePropsFromType(ctx, ctx.propsTypeDecl!)
   if (!props.length) {

From abdfbcf74b2be1ea1c4ffe8852872294ee07deec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E6=99=BA=E5=AD=90=20Kevin=20Deng?=
 <sxzz@sxzz.moe>
Date: Sun, 27 Aug 2023 23:31:49 +0800
Subject: [PATCH 2/3] types: add more fields to simple type ctx

---
 .../compiler-sfc/src/script/defineEmits.ts    | 10 +++++++---
 .../compiler-sfc/src/script/defineProps.ts    | 16 +++++++++------
 .../compiler-sfc/src/script/resolveType.ts    | 20 +++++++++++++++++--
 3 files changed, 35 insertions(+), 11 deletions(-)

diff --git a/packages/compiler-sfc/src/script/defineEmits.ts b/packages/compiler-sfc/src/script/defineEmits.ts
index a308093e1f9..9f0184af836 100644
--- a/packages/compiler-sfc/src/script/defineEmits.ts
+++ b/packages/compiler-sfc/src/script/defineEmits.ts
@@ -1,7 +1,11 @@
 import { Identifier, LVal, Node, RestElement } 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'
 
@@ -57,7 +61,7 @@ export function genRuntimeEmits(ctx: ScriptCompileContext): string | undefined {
   return emitsDecl
 }
 
-export function extractRuntimeEmits(ctx: ScriptCompileContext): Set<string> {
+export function extractRuntimeEmits(ctx: TypeResolveContext): Set<string> {
   const emits = new Set<string>()
   const node = ctx.emitsTypeDecl!
 
@@ -90,7 +94,7 @@ export function extractRuntimeEmits(ctx: ScriptCompileContext): Set<string> {
 }
 
 function extractEventNames(
-  ctx: ScriptCompileContext,
+  ctx: TypeResolveContext,
   eventName: Identifier | RestElement,
   emits: Set<string>
 ) {
diff --git a/packages/compiler-sfc/src/script/defineProps.ts b/packages/compiler-sfc/src/script/defineProps.ts
index 2fd35a3eabb..653bbbb46c6 100644
--- a/packages/compiler-sfc/src/script/defineProps.ts
+++ b/packages/compiler-sfc/src/script/defineProps.ts
@@ -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,
@@ -163,7 +167,7 @@ export function genRuntimeProps(ctx: ScriptCompileContext): string | undefined {
 }
 
 export function extractRuntimeProps(
-  ctx: ScriptCompileContext
+  ctx: TypeResolveContext
 ): string | undefined {
   // this is only called if propsTypeDecl exists
   const props = resolveRuntimePropsFromType(ctx, ctx.propsTypeDecl!)
@@ -195,7 +199,7 @@ export function extractRuntimeProps(
 }
 
 function resolveRuntimePropsFromType(
-  ctx: ScriptCompileContext,
+  ctx: TypeResolveContext,
   node: Node
 ): PropTypeData[] {
   const props: PropTypeData[] = []
@@ -224,7 +228,7 @@ function resolveRuntimePropsFromType(
 }
 
 function genRuntimePropFromType(
-  ctx: ScriptCompileContext,
+  ctx: TypeResolveContext,
   { key, required, type, skipCheck }: PropTypeData,
   hasStaticDefaults: boolean
 ): string {
@@ -286,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' &&
@@ -299,7 +303,7 @@ function hasStaticWithDefaults(ctx: ScriptCompileContext) {
 }
 
 function genDestructuredDefaultValue(
-  ctx: ScriptCompileContext,
+  ctx: TypeResolveContext,
   key: string,
   inferredType?: string[]
 ):
diff --git a/packages/compiler-sfc/src/script/resolveType.ts b/packages/compiler-sfc/src/script/resolveType.ts
index 146c454729c..712cfeef95c 100644
--- a/packages/compiler-sfc/src/script/resolveType.ts
+++ b/packages/compiler-sfc/src/script/resolveType.ts
@@ -59,8 +59,24 @@ import { minimatch as isMatch } from 'minimatch'
  */
 export type SimpleTypeResolveContext = Pick<
   ScriptCompileContext,
-  // required
-  'source' | 'filename' | 'error' | 'options'
+  // file
+  | 'source'
+  | 'filename'
+  | 'options'
+  | 'bindingMetadata'
+
+  // utils
+  | 'error'
+  | 'helper'
+  | 'getString'
+
+  // props
+  | 'propsTypeDecl'
+  | 'propsRuntimeDefaults'
+  | 'propsDestructuredBindings'
+
+  // emits
+  | 'emitsTypeDecl'
 > &
   Partial<
     Pick<ScriptCompileContext, 'scope' | 'globalScopes' | 'deps' | 'fs'>

From f2881c0f7dc3e4b3d676ba80111087d9a4fc7a91 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E6=99=BA=E5=AD=90=20Kevin=20Deng?=
 <sxzz@sxzz.moe>
Date: Mon, 28 Aug 2023 01:24:05 +0800
Subject: [PATCH 3/3] types: improve

---
 packages/compiler-sfc/src/index.ts              |  1 +
 packages/compiler-sfc/src/script/defineProps.ts |  2 +-
 packages/compiler-sfc/src/script/resolveType.ts | 10 ++++++++--
 3 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/packages/compiler-sfc/src/index.ts b/packages/compiler-sfc/src/index.ts
index 7c886a280e2..c6ee604146e 100644
--- a/packages/compiler-sfc/src/index.ts
+++ b/packages/compiler-sfc/src/index.ts
@@ -60,6 +60,7 @@ export type { SFCScriptCompileOptions } from './compileScript'
 export type { ScriptCompileContext } from './script/context'
 export type {
   TypeResolveContext,
+  SimpleTypeResolveOptions,
   SimpleTypeResolveContext
 } from './script/resolveType'
 export type {
diff --git a/packages/compiler-sfc/src/script/defineProps.ts b/packages/compiler-sfc/src/script/defineProps.ts
index 653bbbb46c6..449ed250d1d 100644
--- a/packages/compiler-sfc/src/script/defineProps.ts
+++ b/packages/compiler-sfc/src/script/defineProps.ts
@@ -181,7 +181,7 @@ export function extractRuntimeProps(
   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
     }
   }
diff --git a/packages/compiler-sfc/src/script/resolveType.ts b/packages/compiler-sfc/src/script/resolveType.ts
index 712cfeef95c..315c3d98405 100644
--- a/packages/compiler-sfc/src/script/resolveType.ts
+++ b/packages/compiler-sfc/src/script/resolveType.ts
@@ -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
@@ -62,8 +69,6 @@ export type SimpleTypeResolveContext = Pick<
   // file
   | 'source'
   | 'filename'
-  | 'options'
-  | 'bindingMetadata'
 
   // utils
   | 'error'
@@ -82,6 +87,7 @@ export type SimpleTypeResolveContext = Pick<
     Pick<ScriptCompileContext, 'scope' | 'globalScopes' | 'deps' | 'fs'>
   > & {
     ast: Statement[]
+    options: SimpleTypeResolveOptions
   }
 
 export type TypeResolveContext = ScriptCompileContext | SimpleTypeResolveContext