diff --git a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts index bf3510a052d..fdda72e6448 100644 --- a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts +++ b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts @@ -121,6 +121,25 @@ describe('compiler: element transform', () => { expect(node.tag).toBe(`Example`) }) + test('resolve component from scoped slot bindings', () => { + const { root, node } = parseWithElementTransform( + ``, + { + inline: true, + bindingMetadata: { + Example: BindingTypes.SETUP_CONST, + }, + identifiers: { + Foo: 1, + }, + }, + ) + + expect(root.helpers).not.toContain(RESOLVE_COMPONENT) + expect(root.components).not.toContain('Foo') + expect(node.tag).toBe(`Example`) + }) + test('resolve namespaced component from setup bindings', () => { const { root, node } = parseWithElementTransform(``, { bindingMetadata: { @@ -175,6 +194,25 @@ describe('compiler: element transform', () => { expect(node.tag).toBe('_unref($props["Foo"]).Example') }) + test('resolve namespaced component from scoped slot bindings', () => { + const { root, node } = parseWithElementTransform( + ``, + { + inline: true, + bindingMetadata: { + Example: BindingTypes.SETUP_CONST, + }, + identifiers: { + SlotProps: 1, + }, + }, + ) + + expect(root.helpers).not.toContain(RESOLVE_COMPONENT) + expect(root.components).not.toContain('SlotProps') + expect(node.tag).toBe(`Example`) + }) + test('do not resolve component from non-script-setup bindings', () => { const bindingMetadata = { Example: BindingTypes.SETUP_MAYBE_REF, diff --git a/packages/compiler-core/src/codegen.ts b/packages/compiler-core/src/codegen.ts index 6b4559fabb2..be577d26d7c 100644 --- a/packages/compiler-core/src/codegen.ts +++ b/packages/compiler-core/src/codegen.ts @@ -120,7 +120,10 @@ enum NewlineType { } export interface CodegenContext - extends Omit, 'bindingMetadata' | 'inline'> { + extends Omit< + Required, + 'bindingMetadata' | 'inline' | 'identifiers' + > { source: string code: string line: number diff --git a/packages/compiler-core/src/options.ts b/packages/compiler-core/src/options.ts index 1de865f42eb..1cf7917076b 100644 --- a/packages/compiler-core/src/options.ts +++ b/packages/compiler-core/src/options.ts @@ -199,6 +199,8 @@ interface SharedTransformCodegenOptions { * binding access when `prefixIdentifiers` is enabled. */ bindingMetadata?: BindingMetadata + + identifiers?: { [name: string]: number | undefined } /** * Compile the function for inlining inside setup(). * This allows the function to directly access setup() local bindings. diff --git a/packages/compiler-core/src/transform.ts b/packages/compiler-core/src/transform.ts index 9d8fd842935..a677d9fd14d 100644 --- a/packages/compiler-core/src/transform.ts +++ b/packages/compiler-core/src/transform.ts @@ -143,6 +143,7 @@ export function createTransformContext( inSSR = false, ssrCssVars = ``, bindingMetadata = EMPTY_OBJ, + identifiers = Object.create(null), inline = false, isTS = false, onError = defaultOnError, @@ -187,7 +188,7 @@ export function createTransformContext( cached: [], constantCache: new WeakMap(), temps: 0, - identifiers: Object.create(null), + identifiers, scopes: { vFor: 0, vSlot: 0, diff --git a/packages/compiler-core/src/transforms/transformElement.ts b/packages/compiler-core/src/transforms/transformElement.ts index 1dca0c514c1..b49a60227db 100644 --- a/packages/compiler-core/src/transforms/transformElement.ts +++ b/packages/compiler-core/src/transforms/transformElement.ts @@ -282,7 +282,24 @@ export function resolveComponentType( return builtIn } - // 3. user component (from setup bindings) + // 3. component from slot props + // this is skipped in browser build since browser builds do not perform + // identifier tracking. + if (!__BROWSER__) { + if (context.identifiers[tag]) { + return tag + } + + const dotIndex = tag.indexOf('.') + if (dotIndex > 0) { + const ns = tag.slice(0, dotIndex) + if (context.identifiers[ns]) { + return ns + tag.slice(dotIndex) + } + } + } + + // 4. user component (from setup bindings) // this is skipped in browser build since browser builds do not perform // binding analysis. if (!__BROWSER__) { @@ -299,7 +316,7 @@ export function resolveComponentType( } } - // 4. Self referencing component (inferred from filename) + // 5. Self referencing component (inferred from filename) if ( !__BROWSER__ && context.selfName && @@ -313,7 +330,7 @@ export function resolveComponentType( return toValidAssetId(tag, `component`) } - // 5. user component (resolve) + // 6. user component (resolve) context.helper(RESOLVE_COMPONENT) context.components.add(tag) return toValidAssetId(tag, `component`) @@ -367,6 +384,11 @@ function resolveSetupReference(name: string, context: TransformContext) { context.inline ? '__props' : '$props' }[${JSON.stringify(fromProps)}])` } + + // const fromSlotScope = checkType(BindingTypes.SLOT_SCOPE) + // if (fromSlotScope) { + // return fromSlotScope + // } } export type PropsExpression = ObjectExpression | CallExpression | ExpressionNode