net.mamoe.kjbb.compiler.diagnostic.BlockingBridgeDeclarationChecker.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlin-jvm-blocking-bridge-compiler Show documentation
Show all versions of kotlin-jvm-blocking-bridge-compiler Show documentation
Kotlin compiler plugin for generating blocking bridges for calling suspend functions from Java with minimal effort
The newest version!
package net.mamoe.kjbb.compiler.diagnostic
import net.mamoe.kjbb.compiler.backend.jvm.*
import net.mamoe.kjbb.compiler.backend.jvm.HasJvmBlockingBridgeAnnotation.*
import net.mamoe.kjbb.compiler.diagnostic.BlockingBridgeDeclarationChecker.CheckResult.BREAK
import net.mamoe.kjbb.compiler.diagnostic.BlockingBridgeDeclarationChecker.CheckResult.CONTINUE
import net.mamoe.kjbb.compiler.diagnostic.BlockingBridgeErrors.*
import net.mamoe.kjbb.compiler.extensions.IBridgeConfiguration
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmSyntheticAnnotation
open class BlockingBridgeDeclarationChecker(
private val isIr: Boolean,
private val ext: (KtDeclaration) -> IBridgeConfiguration,
) : DeclarationChecker {
override fun check(
declaration: KtDeclaration,
descriptor: DeclarationDescriptor,
context: DeclarationCheckerContext,
) {
when (declaration) {
is KtClass -> {
val annotation = descriptor.jvmBlockingBridgeAnnotationPsi() ?: return
if (!isPluginEnabled(descriptor)) {
context.report(BLOCKING_BRIDGE_PLUGIN_NOT_ENABLED.on(annotation))
return
}
if (declaration.isInterface()) {
if (descriptor.module.platform?.isJvm8OrHigher() != true) {
// below 8
context.report(INTERFACE_NOT_SUPPORTED.on(annotation))
return
}
}
}
is KtNamedFunction -> {
when (BREAK) {
checkApplicability(declaration, descriptor, context),
checkJvmSynthetic(declaration, descriptor, context),
-> return
else -> return
}
}
}
}
enum class CheckResult {
CONTINUE,
BREAK
}
protected open fun isPluginEnabled(
descriptor: DeclarationDescriptor,
): Boolean {
return true // in CLI compiler, always enabled
}
private fun checkApplicability(
declaration: KtDeclaration,
descriptor: DeclarationDescriptor,
context: DeclarationCheckerContext,
): CheckResult = with(ext(declaration)) {
val inspectionTarget =
when (descriptor.hasJvmBlockingBridgeAnnotation(context.trace.bindingContext, enableForModule)) {
NONE -> return CONTINUE
FROM_CONTAINING_DECLARATION,
ENABLE_FOR_MODULE,
-> {
// no need to check applicability for inherited from containing class or file or enabled for module.
return CONTINUE
}
FROM_FUNCTION -> descriptor.jvmBlockingBridgeAnnotationPsi() ?: declaration
}
if (!isPluginEnabled(descriptor)) {
context.report(BLOCKING_BRIDGE_PLUGIN_NOT_ENABLED.on(inspectionTarget))
return BREAK
}
if (descriptor !is FunctionDescriptor) {
context.report(INAPPLICABLE_JVM_BLOCKING_BRIDGE.on(inspectionTarget))
return BREAK
}
val result = descriptor.analyzeCapabilityForGeneratingBridges(isIr, context.trace.bindingContext, this)
result.createDiagnostic()?.let(context::report)
if (result is BlockingBridgeAnalyzeResult.BridgeAnnotationFromContainingDeclaration) return BREAK
return CONTINUE
}
companion object {
private val JVM_SYNTHETIC = FqName("kotlin.jvm.JvmSynthetic")
}
private fun checkJvmSynthetic(
declaration: KtDeclaration,
descriptor: DeclarationDescriptor,
context: DeclarationCheckerContext,
): CheckResult = with(ext(declaration)) {
val inspectionTarget =
when (descriptor.hasJvmBlockingBridgeAnnotation(context.trace.bindingContext, enableForModule)) {
NONE -> return CONTINUE
FROM_FUNCTION -> descriptor.jvmBlockingBridgeAnnotationPsi()
?: descriptor.annotations.findAnnotation(JVM_SYNTHETIC)?.findPsi()
?: declaration
FROM_CONTAINING_DECLARATION, ENABLE_FOR_MODULE -> return CONTINUE
}
if (descriptor.hasJvmSyntheticAnnotation()) {
context.report(REDUNDANT_JVM_BLOCKING_BRIDGE_WITH_JVM_SYNTHETIC.on(inspectionTarget))
return CONTINUE
}
return CONTINUE
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy