Do not generate DefaultImpls for light classes if not needed
#KT-41130 In Progress
This commit is contained in:
committed by
TeamCityServer
parent
ac6232b4ba
commit
111e54c8c1
@@ -13,6 +13,7 @@ import com.intellij.psi.search.PsiSearchScopeUtil
|
||||
import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.asJava.classes.*
|
||||
import org.jetbrains.kotlin.config.JvmAnalysisFlags
|
||||
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
|
||||
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
|
||||
import org.jetbrains.kotlin.load.java.components.FilesByFacadeFqNameIndexer
|
||||
@@ -109,7 +110,7 @@ class CliKotlinAsJavaSupport(
|
||||
}
|
||||
|
||||
override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? =
|
||||
KtLightClassForSourceDeclaration.create(classOrObject)
|
||||
KtLightClassForSourceDeclaration.create(classOrObject, traceHolder.languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode))
|
||||
|
||||
override fun getLightClassForScript(script: KtScript): KtLightClassForScript? =
|
||||
KtLightClassForScript.create(script)
|
||||
|
||||
+3
-2
@@ -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>()
|
||||
}
|
||||
|
||||
+2
-1
@@ -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)
|
||||
|
||||
|
||||
+2
-1
@@ -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
|
||||
|
||||
+15
-9
@@ -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
|
||||
|
||||
-1
@@ -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
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
public abstract interface KtInterface /* KtInterface*/ {
|
||||
public abstract void defaultFun();// defaultFun()
|
||||
|
||||
public abstract void withoutBody();// withoutBody()
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// CHECK_BY_JAVA_FILE
|
||||
// COMPILER_ARGUMENTS: -Xjvm-default=all
|
||||
|
||||
interface KtInterface {
|
||||
fun defaultFun() {
|
||||
println("default")
|
||||
}
|
||||
|
||||
fun withoutBody()
|
||||
}
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
public abstract interface KtInterface /* KtInterface*/ {
|
||||
public abstract void defaultFun();// defaultFun()
|
||||
|
||||
public abstract void withoutBody();// withoutBody()
|
||||
|
||||
|
||||
class DefaultImpls ...
|
||||
|
||||
}
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
// CHECK_BY_JAVA_FILE
|
||||
// COMPILER_ARGUMENTS: -Xjvm-default=all-compatibility
|
||||
|
||||
interface KtInterface {
|
||||
fun defaultFun() {
|
||||
println("default")
|
||||
}
|
||||
|
||||
fun withoutBody()
|
||||
}
|
||||
+4
-1
@@ -16,6 +16,7 @@ import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.asJava.builder.ClsWrapperStubPsiFactory
|
||||
import org.jetbrains.kotlin.asJava.classes.*
|
||||
import org.jetbrains.kotlin.config.JvmAnalysisFlags
|
||||
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
|
||||
import org.jetbrains.kotlin.idea.caches.lightClasses.ClsJavaStubByVirtualFileCache
|
||||
import org.jetbrains.kotlin.idea.caches.lightClasses.KtLightClassForDecompiledDeclaration
|
||||
@@ -24,6 +25,7 @@ import org.jetbrains.kotlin.idea.caches.project.*
|
||||
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
||||
import org.jetbrains.kotlin.idea.decompiler.classFile.KtClsFile
|
||||
import org.jetbrains.kotlin.idea.decompiler.navigation.SourceNavigationHelper
|
||||
import org.jetbrains.kotlin.idea.project.getLanguageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.project.platform
|
||||
import org.jetbrains.kotlin.idea.stubindex.*
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
@@ -38,9 +40,10 @@ import org.jetbrains.kotlin.utils.sure
|
||||
|
||||
open class IDEKotlinAsJavaSupport(private val project: Project) : KotlinAsJavaSupport() {
|
||||
private val psiManager: PsiManager = PsiManager.getInstance(project)
|
||||
private val languageVersionSettings = project.getLanguageVersionSettings()
|
||||
|
||||
protected open fun createLightClassForSourceDeclaration(classOrObject: KtClassOrObject): KtLightClass? =
|
||||
KtLightClassForSourceDeclaration.create(classOrObject)
|
||||
KtLightClassForSourceDeclaration.create(classOrObject, languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode))
|
||||
|
||||
protected open fun createLightClassForScript(script: KtScript): KtLightClass? =
|
||||
KtLightClassForScript.create(script)
|
||||
|
||||
+10
@@ -64,6 +64,16 @@ public class FirClassLoadingTestGenerated extends AbstractFirClassLoadingTest {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/dataClasses.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("defaultMethodInKotlinWithSettingAll.kt")
|
||||
public void testDefaultMethodInKotlinWithSettingAll() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/defaultMethodInKotlinWithSettingAll.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("defaultMethodInKotlinWithSettingAllCompatibility.kt")
|
||||
public void testDefaultMethodInKotlinWithSettingAllCompatibility() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/defaultMethodInKotlinWithSettingAllCompatibility.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("delegatesWithAnnotations.kt")
|
||||
public void testDelegatesWithAnnotations() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/delegatesWithAnnotations.kt");
|
||||
|
||||
+10
@@ -64,6 +64,16 @@ public class UltraLightClassLoadingTestGenerated extends AbstractUltraLightClass
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/dataClasses.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("defaultMethodInKotlinWithSettingAll.kt")
|
||||
public void testDefaultMethodInKotlinWithSettingAll() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/defaultMethodInKotlinWithSettingAll.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("defaultMethodInKotlinWithSettingAllCompatibility.kt")
|
||||
public void testDefaultMethodInKotlinWithSettingAllCompatibility() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/defaultMethodInKotlinWithSettingAllCompatibility.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("delegatesWithAnnotations.kt")
|
||||
public void testDelegatesWithAnnotations() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/delegatesWithAnnotations.kt");
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass;
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration;
|
||||
import org.jetbrains.kotlin.config.JvmDefaultMode;
|
||||
import org.jetbrains.kotlin.idea.caches.lightClasses.KtLightClassForDecompiledDeclaration;
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor;
|
||||
@@ -49,8 +50,8 @@ public class LightClassEqualsTest extends KotlinLightCodeInsightFixtureTestCase
|
||||
static void doTestEquals(@Nullable KtClassOrObject origin) {
|
||||
assertNotNull(origin);
|
||||
|
||||
PsiClass lightClass1 = KtLightClassForSourceDeclaration.Companion.createNoCache(origin, true);
|
||||
PsiClass lightClass2 = KtLightClassForSourceDeclaration.Companion.createNoCache(origin, true);
|
||||
PsiClass lightClass1 = KtLightClassForSourceDeclaration.Companion.createNoCache(origin, JvmDefaultMode.DEFAULT, true);
|
||||
PsiClass lightClass2 = KtLightClassForSourceDeclaration.Companion.createNoCache(origin, JvmDefaultMode.DEFAULT, true);
|
||||
assertNotNull(lightClass1);
|
||||
assertNotNull(lightClass2);
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.PsiClassRenderer
|
||||
import org.jetbrains.kotlin.asJava.PsiClassRenderer.renderClass
|
||||
import org.jetbrains.kotlin.asJava.classes.*
|
||||
import org.jetbrains.kotlin.config.JvmAnalysisFlags
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||
@@ -104,7 +105,9 @@ object UltraLightChecker {
|
||||
}
|
||||
|
||||
fun checkClassEquivalence(ktClass: KtClassOrObject): KtUltraLightClass? {
|
||||
val gold = KtLightClassForSourceDeclaration.createNoCache(ktClass, forceUsingOldLightClasses = true)
|
||||
val gold = KtLightClassForSourceDeclaration.createNoCache(
|
||||
ktClass, ktClass.languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode), forceUsingOldLightClasses = true
|
||||
)
|
||||
val ultraLightClass = LightClassGenerationSupport.getInstance(ktClass.project).createUltraLightClass(ktClass) ?: return null
|
||||
|
||||
val secondULInstance = LightClassGenerationSupport.getInstance(ktClass.project).createUltraLightClass(ktClass)
|
||||
|
||||
Reference in New Issue
Block a user