Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.util.getSimpleFunction
import org.jetbrains.kotlin.ir.util.hasAnnotation
import org.jetbrains.kotlin.ir.util.isObject
import org.jetbrains.kotlin.ir.util.kotlinFqName
import org.jetbrains.kotlin.ir.util.parentClassOrNull
import org.jetbrains.kotlin.ir.util.properties
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.konan.isNative

internal sealed class ProviderFactory : IrMetroFactory, IrBindingContainerCallable {
/**
Expand Down Expand Up @@ -142,6 +144,25 @@ internal sealed class ProviderFactory : IrMetroFactory, IrBindingContainerCallab
val rawTypeKey = contextKey.typeKey.copy(qualifier = callableMetadata.annotations.qualifier)
val typeKey = rawTypeKey.transformIfIntoMultibinding(callableMetadata.annotations)

if (mirrorFunction.isExternalParent && context.platform.isNative()) {
// Validate qualifiers due to https://github.com/ZacSweers/metro/issues/1556
val createFunctionParams =
clazz.requireSimpleFunction(Symbols.StringNames.CREATE).owner.parameters().allParameters
for ((i, mirrorP) in
callableMetadata.mirrorFunction.parameters().allParameters.withIndex()) {
val createP = createFunctionParams[i]
if (createP.typeKey != mirrorP.typeKey) {
reportCompilerBug(
"""
Mirror/create function parameter type mismatch: ${mirrorP.typeKey} != ${createP.typeKey}
Source: ${callableMetadata.function.kotlinFqName.asString()}
"""
.trimIndent()
)
}
}
}

return Metro(
factoryClass = clazz,
typeKey = typeKey,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.ir.util.primaryConstructor
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.platform.konan.isNative

internal class InjectConstructorTransformer(
context: IrMetroContext,
Expand Down Expand Up @@ -124,10 +125,35 @@ internal class InjectConstructorTransformer(
?: reportCompilerBug(
"Expected nested class '$factoryClassName' not found in '${declaration.kotlinFqName}'."
)
val parameters =
factoryCls.requireSimpleFunction(Symbols.StringNames.MIRROR_FUNCTION).owner.parameters()
val mirrorFunction =
factoryCls.requireSimpleFunction(Symbols.StringNames.MIRROR_FUNCTION).owner
val parameters = mirrorFunction.parameters()

// Look up the injectable constructor for direct invocation optimization
val externalTargetConstructor = targetConstructor()

if (platform.isNative()) {
// Validate qualifiers due to https://github.com/ZacSweers/metro/issues/1556
val createFunctionParams =
factoryCls
.requireSimpleFunction(Symbols.StringNames.CREATE)
.owner
.parameters()
.allParameters
for ((i, mirrorP) in parameters.allParameters.withIndex()) {
val createP = createFunctionParams[i]
if (createP.typeKey != mirrorP.typeKey) {
reportCompilerBug(
"""
Mirror/create function parameter type mismatch: ${mirrorP.typeKey} != ${createP.typeKey}
Source: ${externalTargetConstructor?.kotlinFqName ?: declaration.kotlinFqName}
"""
.trimIndent()
)
}
}
}

val wrapper = ClassFactory.MetroFactory(factoryCls, parameters, externalTargetConstructor)
// If it's from another module, we're done!
// TODO this doesn't work as expected in KMP, where things compiled in common are seen
Expand Down