[FIR-PLUGIN] Add dummy implementation for nested class generator extension

This commit is contained in:
Dmitriy Novozhilov
2020-05-28 18:01:11 +03:00
parent 8acdb39bdd
commit 9cc13c8324
7 changed files with 176 additions and 3 deletions
@@ -54,6 +54,4 @@ class AllOpenMemberGenerator(session: FirSession) : FirExistingClassModification
override val key: FirPluginKey
get() = AllOpenPluginKey
}
private fun String.fqn(): FqName = FqName("org.jetbrains.kotlin.fir.plugin.$this")
}
@@ -0,0 +1,102 @@
/*
* Copyright 2010-2020 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.fir.plugin
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.FirEffectiveVisibilityImpl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.buildConstructor
import org.jetbrains.kotlin.fir.declarations.builder.buildRegularClass
import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunction
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
import org.jetbrains.kotlin.fir.extensions.FirExistingClassModificationExtension
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
import org.jetbrains.kotlin.fir.extensions.predicate.has
import org.jetbrains.kotlin.fir.resolve.transformers.plugin.GeneratedNestedClass
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.name.Name
class AllOpenNestedClassGenerator(session: FirSession) : FirExistingClassModificationExtension(session) {
override fun generateNestedClasses(
annotatedDeclaration: FirDeclaration,
owners: List<FirAnnotatedDeclaration>
): List<GeneratedDeclaration<FirRegularClass>> {
val owner = annotatedDeclaration as? FirRegularClass ?: return emptyList()
val newClass = buildRegularClass {
session = this@AllOpenNestedClassGenerator.session
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
origin = FirDeclarationOrigin.Plugin(key)
status = FirResolvedDeclarationStatusImpl(
Visibilities.PRIVATE,
FirEffectiveVisibilityImpl.Private,
Modality.FINAL
).apply {
isInner = true
}
classKind = ClassKind.CLASS
name = Name.identifier("Foo")
symbol = FirRegularClassSymbol(owner.symbol.classId.createNestedClassId(name))
scopeProvider = owner.scopeProvider
}
return listOf(GeneratedDeclaration(newClass, owner))
}
override fun generateMembersForNestedClasses(generatedNestedClass: GeneratedNestedClass): List<FirDeclaration> {
val klass = generatedNestedClass.nestedClass
val classId = klass.symbol.classId
val constructor = buildConstructor {
session = klass.session
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
origin = FirDeclarationOrigin.Plugin(key)
returnTypeRef = buildResolvedTypeRef {
type = ConeClassLikeTypeImpl(ConeClassLikeLookupTagImpl(classId), emptyArray(), isNullable = false)
}
status = FirResolvedDeclarationStatusImpl(
Visibilities.PUBLIC,
FirEffectiveVisibilityImpl.Public,
Modality.FINAL
)
symbol = FirConstructorSymbol(CallableId(classId, classId.shortClassName))
}
val function = buildSimpleFunction {
session = klass.session
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
origin = FirDeclarationOrigin.Plugin(key)
returnTypeRef = session.builtinTypes.intType
status = FirResolvedDeclarationStatusImpl(
Visibilities.PUBLIC,
FirEffectiveVisibilityImpl.Public,
Modality.FINAL
)
name = Name.identifier("hello")
symbol = FirNamedFunctionSymbol(CallableId(classId, name), isFakeOverride = false)
}
return listOf(constructor, function)
}
override fun generateMembers(
annotatedDeclaration: FirDeclaration,
owners: List<FirAnnotatedDeclaration>
): List<GeneratedDeclaration<*>> {
return emptyList()
}
override val predicate: DeclarationPredicate = has("WithNestedFoo".fqn())
override val key: FirPluginKey
get() = AllOpenPluginKey
}
@@ -11,6 +11,7 @@ class FirAllOpenComponentRegistrar : FirExtensionRegistrar() {
override fun ExtensionRegistrarContext.configurePlugin() {
+::AllOpenStatusTransformer
+::AllOpenMemberGenerator
+::AllOpenNestedClassGenerator
+::AllOpenAdditionalCheckers
}
}
@@ -0,0 +1,10 @@
/*
* Copyright 2010-2020 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.fir.plugin
import org.jetbrains.kotlin.name.FqName
fun String.fqn(): FqName = FqName("org.jetbrains.kotlin.fir.plugin.$this")
@@ -0,0 +1,20 @@
import org.jetbrains.kotlin.fir.plugin.WithNestedFoo
fun <T> T.also(block: (T) -> Unit): T = this
@WithNestedFoo
class A {
private fun test(): Foo {
return Foo().also {
it.hello() // should be OK
}
}
}
class B {
private fun test(): Foo {
return <!UNRESOLVED_REFERENCE!>Foo<!>().<!INAPPLICABLE_CANDIDATE!>also<!> {
<!UNRESOLVED_REFERENCE!>it<!>.<!UNRESOLVED_REFERENCE!>hello<!>() // should be an error
}
}
}
@@ -0,0 +1,37 @@
FILE: nestedClass.kt
public final fun <T> R|T|.also(block: R|(T) -> kotlin/Unit|): R|T| {
^also this@R|/also|
}
@R|org/jetbrains/kotlin/fir/plugin/WithNestedFoo|() public final class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
private final fun test(): R|A.Foo| {
^test R|/A.Foo.Foo|().R|/also|<R|A.Foo|>(<L> = also@fun <anonymous>(it: R|A.Foo|): R|kotlin/Unit| {
^ R|<local>/it|.R|/A.Foo.hello|()
}
)
}
private final inner class Foo {
public constructor(): R|A.Foo|
public final fun hello(): R|kotlin/Int|
}
}
public final class B : R|kotlin/Any| {
public constructor(): R|B| {
super<R|kotlin/Any|>()
}
private final fun test(): R|ERROR CLASS: Symbol not found, for `Foo`| {
^test <Unresolved name: Foo>#().<Inapplicable(WRONG_RECEIVER): [/also]>#(<L> = also@fun <anonymous>(): R|ERROR CLASS: Unresolved name: hello| {
^ <Unresolved name: it>#.<Unresolved name: hello>#()
}
)
}
}
@@ -62,6 +62,11 @@ public class FirAllOpenDiagnosticTestGenerated extends AbstractFirAllOpenDiagnos
public void testFunctionForProperty() throws Exception {
runTest("plugins/fir/fir-plugin-prototype/testData/memberGen/functionForProperty.kt");
}
@TestMetadata("nestedClass.kt")
public void testNestedClass() throws Exception {
runTest("plugins/fir/fir-plugin-prototype/testData/memberGen/nestedClass.kt");
}
}
@TestMetadata("plugins/fir/fir-plugin-prototype/testData/status")