[AllOpen] Reorganize module structure of AllOpen plugin

This scheme will be common for all compiler plugins with K1 and K2 support:
- `plugin-common` contains classes shared with K1 and K2 implementations (if any)
- `plugin-k1` contains implementation for K1 compiler
- `plugin-k2` contains implementation for K2 compiler
- `plugin-backend` contains implementation for backend extensions (if any)
- `plugin-cli` is module for registration of plugin in CLI compiler
- `plugin` is a root module with tests and all submodules embedded

This structure is needed to distinguish parts related to different frontends,
  which is needed for proper dependencies settings for Kotlin IDE plugins
This commit is contained in:
Dmitriy Novozhilov
2022-05-17 13:09:56 +03:00
committed by teamcity
parent 22ebea8174
commit 2a7dc1cc0c
52 changed files with 199 additions and 114 deletions
@@ -0,0 +1,27 @@
description = "Kotlin AllOpen Compiler Plugin (K2)"
plugins {
kotlin("jvm")
id("jps-compatible")
}
dependencies {
compileOnly(project(":compiler:fir:cones"))
compileOnly(project(":compiler:fir:tree"))
compileOnly(project(":compiler:fir:resolve"))
compileOnly(project(":compiler:fir:checkers"))
compileOnly(project(":compiler:ir.backend.common"))
compileOnly(project(":compiler:fir:entrypoint"))
compileOnly(intellijCore())
runtimeOnly(kotlinStdlib())
}
sourceSets {
"main" { projectDefault() }
"test" { none() }
}
runtimeJar()
sourcesJar()
javadocJar()
@@ -0,0 +1,14 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.allopen.fir
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
class FirAllOpenExtensionRegistrar(val allOpenAnnotationFqNames: List<String>) : FirExtensionRegistrar() {
override fun ExtensionRegistrarContext.configurePlugin() {
+FirAllOpenStatusTransformer.getFactory(allOpenAnnotationFqNames)
}
}
@@ -0,0 +1,78 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.allopen.fir
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.caches.FirCache
import org.jetbrains.kotlin.fir.caches.firCachesFactory
import org.jetbrains.kotlin.fir.caches.getValue
import org.jetbrains.kotlin.fir.copy
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
import org.jetbrains.kotlin.fir.extensions.FirStatusTransformerExtension
import org.jetbrains.kotlin.fir.extensions.FirStatusTransformerExtension.Factory
import org.jetbrains.kotlin.fir.extensions.predicate.has
import org.jetbrains.kotlin.fir.extensions.predicate.metaHas
import org.jetbrains.kotlin.fir.extensions.predicate.or
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
import org.jetbrains.kotlin.name.FqName
class FirAllOpenStatusTransformer(allOpenAnnotationFqNames: List<String>, session: FirSession) : FirStatusTransformerExtension(session) {
companion object {
fun getFactory(allOpenAnnotationFqNames: List<String>): Factory {
return Factory { session -> FirAllOpenStatusTransformer(allOpenAnnotationFqNames, session) }
}
}
private val annotationFqNames = allOpenAnnotationFqNames.map { FqName(it) }
private val hasPredicate = has(annotationFqNames) or metaHas(annotationFqNames)
private val cache: FirCache<FirRegularClassSymbol, Boolean, Nothing?> = session.firCachesFactory.createCache { symbol, _ ->
symbol.annotated()
}
override fun FirDeclarationPredicateRegistrar.registerPredicates() {
register(hasPredicate)
}
override fun needTransformStatus(declaration: FirDeclaration): Boolean {
return when (declaration) {
is FirRegularClass -> declaration.classKind == ClassKind.CLASS && cache.getValue(declaration.symbol)
is FirCallableDeclaration -> {
val parentClassId = declaration.symbol.callableId.classId ?: return false
if (parentClassId.isLocal) return false
val parentClassSymbol = session.symbolProvider.getClassLikeSymbolByClassId(parentClassId) as? FirRegularClassSymbol
?: return false
cache.getValue(parentClassSymbol)
}
else -> false
}
}
private fun FirRegularClassSymbol.annotated(): Boolean {
if (session.predicateBasedProvider.matches(hasPredicate, this)) return true
return resolvedSuperTypes.any {
val superSymbol = it.toRegularClassSymbol(session) ?: return@any false
cache.getValue(superSymbol)
}
}
override fun transformStatus(status: FirDeclarationStatus, declaration: FirDeclaration): FirDeclarationStatus {
return if (status.modality == null) {
status.copy(modality = Modality.OPEN)
} else {
status
}
}
}