Do not generate DefaultImpls for light classes if not needed

#KT-41130 In Progress
This commit is contained in:
Mikhail Zarechenskiy
2021-03-09 14:45:31 +03:00
committed by TeamCityServer
parent ac6232b4ba
commit 111e54c8c1
17 changed files with 98 additions and 23 deletions
@@ -19,11 +19,12 @@ package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.*
import com.intellij.util.IncorrectOperationException
import org.jetbrains.kotlin.asJava.builder.LightClassData
import org.jetbrains.kotlin.config.JvmDefaultMode
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.psi.KtClassOrObject
class KtLightClassForInterfaceDefaultImpls(classOrObject: KtClassOrObject)
: KtLightClassForSourceDeclaration(classOrObject) {
: KtLightClassForSourceDeclaration(classOrObject, JvmDefaultMode.DEFAULT) {
override fun getQualifiedName(): String? = containingClass?.qualifiedName?.let { it + ".${JvmAbi.DEFAULT_IMPLS_CLASS_NAME}" }
override fun getName() = JvmAbi.DEFAULT_IMPLS_CLASS_NAME
@@ -54,7 +55,7 @@ class KtLightClassForInterfaceDefaultImpls(classOrObject: KtClassOrObject)
throw IncorrectOperationException("Impossible to rename DefaultImpls")
}
override fun getContainingClass() = KtLightClassForSourceDeclaration.create(classOrObject)
override fun getContainingClass() = KtLightClassForSourceDeclaration.create(classOrObject, JvmDefaultMode.DEFAULT)
override fun getOwnInnerClasses() = emptyList<PsiClass>()
}
@@ -12,13 +12,14 @@ import com.intellij.psi.impl.light.LightClass
import com.intellij.psi.impl.light.LightMethod
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.config.JvmDefaultMode
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
open class KtLightClassForLocalDeclaration(
classOrObject: KtClassOrObject
) : KtLightClassForSourceDeclaration(classOrObject) {
) : KtLightClassForSourceDeclaration(classOrObject, JvmDefaultMode.DEFAULT) {
override fun copy(): PsiElement = KtLightClassForLocalDeclaration(classOrObject.copy() as KtClassOrObject)
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.asJava.builder.LightClassData
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForScript
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
import org.jetbrains.kotlin.config.JvmDefaultMode
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
import org.jetbrains.kotlin.name.FqName
@@ -107,7 +108,7 @@ open class KtLightClassForScript(val script: KtScript) : KtLazyLightClass(script
// inner classes with null names can't be searched for and can't be used from java anyway
// we can't prohibit creating light classes with null names either since they can contain members
.filter { it.name != null }
.mapNotNull { KtLightClassForSourceDeclaration.create(it) }
.mapNotNull { KtLightClassForSourceDeclaration.create(it, JvmDefaultMode.DEFAULT) }
}
override fun getInitializers(): Array<PsiClassInitializer> = PsiClassInitializer.EMPTY_ARRAY
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.asJava.elements.KtLightModifierList
import org.jetbrains.kotlin.asJava.elements.KtLightPsiReferenceList
import org.jetbrains.kotlin.asJava.hasInterfaceDefaultImpls
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.config.JvmDefaultMode
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.lexer.KtTokens.*
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
@@ -67,6 +68,7 @@ private class KtLightClassModifierList(containingClass: KtLightClassForSourceDec
abstract class KtLightClassForSourceDeclaration(
protected val classOrObject: KtClassOrObject,
protected val jvmDefaultMode: JvmDefaultMode,
private val forceUsingOldLightClasses: Boolean = false
) : KtLazyLightClass(classOrObject.manager),
StubBasedPsiElement<KotlinClassOrObjectStub<out KtClassOrObject>> {
@@ -123,7 +125,7 @@ abstract class KtLightClassForSourceDeclaration(
private val _containingFile: PsiFile by lazyPub {
object : FakeFileForLightClass(
classOrObject.containingKtFile,
{ if (classOrObject.isTopLevel()) this else create(getOutermostClassOrObject(classOrObject))!! },
{ if (classOrObject.isTopLevel()) this else create(getOutermostClassOrObject(classOrObject), jvmDefaultMode)!! },
{ getJavaFileStub() }
) {
override fun findReferenceAt(offset: Int) = ktFile.findReferenceAt(offset)
@@ -179,7 +181,7 @@ abstract class KtLightClassForSourceDeclaration(
val containingClassOrObject = (classOrObject.parent as? KtClassBody)?.parent as? KtClassOrObject
if (containingClassOrObject != null) {
return create(containingClassOrObject)
return create(containingClassOrObject, jvmDefaultMode)
}
// TODO: should return null
@@ -300,12 +302,12 @@ abstract class KtLightClassForSourceDeclaration(
.filter { it.name != null }
.mapNotNullTo(result) {
if (!forceUsingOldLightClasses)
create(it)
create(it, jvmDefaultMode)
else
createNoCache(it, forceUsingOldLightClasses = true)
createNoCache(it, jvmDefaultMode, forceUsingOldLightClasses = true)
}
if (classOrObject.hasInterfaceDefaultImpls) {
if (classOrObject.hasInterfaceDefaultImpls && jvmDefaultMode != JvmDefaultMode.ALL_INCOMPATIBLE) {
result.add(KtLightClassForInterfaceDefaultImpls(classOrObject))
}
return result
@@ -335,16 +337,20 @@ abstract class KtLightClassForSourceDeclaration(
FINAL_KEYWORD to PsiModifier.FINAL
)
fun create(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? =
fun create(classOrObject: KtClassOrObject, jvmDefaultMode: JvmDefaultMode): KtLightClassForSourceDeclaration? =
CachedValuesManager.getCachedValue(classOrObject) {
CachedValueProvider.Result
.create(
createNoCache(classOrObject, KtUltraLightSupport.forceUsingOldLightClasses),
createNoCache(classOrObject, jvmDefaultMode, KtUltraLightSupport.forceUsingOldLightClasses),
KotlinModificationTrackerService.getInstance(classOrObject.project).outOfBlockModificationTracker
)
}
fun createNoCache(classOrObject: KtClassOrObject, forceUsingOldLightClasses: Boolean): KtLightClassForSourceDeclaration? {
fun createNoCache(
classOrObject: KtClassOrObject,
jvmDefaultMode: JvmDefaultMode,
forceUsingOldLightClasses: Boolean
): KtLightClassForSourceDeclaration? {
val containingFile = classOrObject.containingFile
if (containingFile is KtCodeFragment) {
// Avoid building light classes for code fragments
@@ -372,7 +378,7 @@ abstract class KtLightClassForSourceDeclaration(
KtLightClassForLocalDeclaration(classOrObject)
else ->
KtLightClassImpl(classOrObject, forceUsingOldLightClasses)
KtLightClassImpl(classOrObject, jvmDefaultMode, forceUsingOldLightClasses)
}
}
@@ -16,13 +16,15 @@
package org.jetbrains.kotlin.asJava.classes
import org.jetbrains.kotlin.config.JvmDefaultMode
import org.jetbrains.kotlin.psi.KtClassOrObject
// light class for top level or (inner/nested of top level) source declarations
open class KtLightClassImpl @JvmOverloads constructor(
classOrObject: KtClassOrObject,
jvmDefaultMode: JvmDefaultMode,
forceUsingOldLightClasses: Boolean = false
) : KtLightClassForSourceDeclaration(classOrObject, forceUsingOldLightClasses) {
) : KtLightClassForSourceDeclaration(classOrObject, jvmDefaultMode, forceUsingOldLightClasses) {
override fun getQualifiedName() = classOrObject.fqName?.asString()
override fun getParent() = if (classOrObject.isTopLevel())
@@ -30,5 +32,5 @@ open class KtLightClassImpl @JvmOverloads constructor(
else
containingClass
override fun copy() = KtLightClassImpl(classOrObject.copy() as KtClassOrObject)
override fun copy() = KtLightClassImpl(classOrObject.copy() as KtClassOrObject, jvmDefaultMode)
}
@@ -24,6 +24,8 @@ import org.jetbrains.kotlin.backend.common.DataClassMethodGenerator
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
import org.jetbrains.kotlin.codegen.kotlinType
import org.jetbrains.kotlin.config.AnalysisFlags
import org.jetbrains.kotlin.config.JvmAnalysisFlags
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
@@ -46,7 +48,7 @@ import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny
open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val support: KtUltraLightSupport) :
KtLightClassImpl(classOrObject) {
KtLightClassImpl(classOrObject, support.languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode)) {
private class KtUltraLightClassModifierList(
private val containingClass: KtLightClassForSourceDeclaration,
@@ -484,7 +486,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
val containingBody = classOrObject.parent as? KtClassBody
val containingClass = containingBody?.parent as? KtClassOrObject
containingClass?.let { return create(it) }
containingClass?.let { return create(it, jvmDefaultMode) }
val containingBlock = classOrObject.parent as? KtBlockExpression
val containingScript = containingBlock?.parent as? KtScript
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
import org.jetbrains.kotlin.psi.psiUtil.hasSuspendModifier
import org.jetbrains.kotlin.psi.psiUtil.isPrivate
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.isPublishedApi