[FIR-PLUGIN] Add dummy implementation for nested class generator extension
This commit is contained in:
+1
-3
@@ -54,6 +54,4 @@ class AllOpenMemberGenerator(session: FirSession) : FirExistingClassModification
|
|||||||
|
|
||||||
override val key: FirPluginKey
|
override val key: FirPluginKey
|
||||||
get() = AllOpenPluginKey
|
get() = AllOpenPluginKey
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun String.fqn(): FqName = FqName("org.jetbrains.kotlin.fir.plugin.$this")
|
|
||||||
+102
@@ -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
|
||||||
|
}
|
||||||
+1
@@ -11,6 +11,7 @@ class FirAllOpenComponentRegistrar : FirExtensionRegistrar() {
|
|||||||
override fun ExtensionRegistrarContext.configurePlugin() {
|
override fun ExtensionRegistrarContext.configurePlugin() {
|
||||||
+::AllOpenStatusTransformer
|
+::AllOpenStatusTransformer
|
||||||
+::AllOpenMemberGenerator
|
+::AllOpenMemberGenerator
|
||||||
|
+::AllOpenNestedClassGenerator
|
||||||
+::AllOpenAdditionalCheckers
|
+::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>#()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+5
@@ -62,6 +62,11 @@ public class FirAllOpenDiagnosticTestGenerated extends AbstractFirAllOpenDiagnos
|
|||||||
public void testFunctionForProperty() throws Exception {
|
public void testFunctionForProperty() throws Exception {
|
||||||
runTest("plugins/fir/fir-plugin-prototype/testData/memberGen/functionForProperty.kt");
|
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")
|
@TestMetadata("plugins/fir/fir-plugin-prototype/testData/status")
|
||||||
|
|||||||
Reference in New Issue
Block a user