FqName is not required to create source light classes
This commit is contained in:
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.kotlin.asJava
|
||||
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import com.intellij.openapi.util.Comparing
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.java.stubs.PsiClassStub
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
@@ -30,26 +29,24 @@ import org.jetbrains.kotlin.asJava.elements.*
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
|
||||
object LightClassUtil {
|
||||
|
||||
fun findClass(fqn: FqName, stub: StubElement<*>): PsiClass? {
|
||||
if (stub is PsiClassStub<*> && Comparing.equal(fqn.asString(), stub.qualifiedName)) {
|
||||
fun findClass(stub: StubElement<*>, predicate: (PsiClassStub<*>) -> Boolean): PsiClass? {
|
||||
if (stub is PsiClassStub<*> && predicate(stub)) {
|
||||
return stub.getPsi()
|
||||
}
|
||||
|
||||
if (stub is PsiClassStub<*> || stub is PsiFileStub<*>) {
|
||||
for (child in stub.childrenStubs) {
|
||||
val answer = findClass(fqn, child)
|
||||
val answer = findClass(child, predicate)
|
||||
if (answer != null) return answer
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}/*package*/
|
||||
}
|
||||
|
||||
fun getLightClassAccessorMethod(accessor: KtPropertyAccessor): PsiMethod? =
|
||||
getLightClassAccessorMethods(accessor).firstOrNull()
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ public class ClsWrapperStubPsiFactory extends StubPsiFactory {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiElement getOriginalElement(@NotNull StubElement stub) {
|
||||
public static PsiElement getOriginalElement(@NotNull StubElement stub) {
|
||||
LightElementOrigin origin = ((StubBase) stub).getUserData(ORIGIN);
|
||||
return origin != null ? origin.getOriginalElement() : null;
|
||||
}
|
||||
|
||||
+3
-5
@@ -21,13 +21,11 @@ import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.InheritanceImplUtil
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.reference.SoftReference
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
|
||||
internal open class KtLightClassForAnonymousDeclaration(fqNameFunction: ((KtClassOrObject) -> FqName),
|
||||
classOrObject: KtClassOrObject) :
|
||||
KtLightClassForLocalDeclaration(fqNameFunction, classOrObject), PsiAnonymousClass {
|
||||
internal open class KtLightClassForAnonymousDeclaration(classOrObject: KtClassOrObject) :
|
||||
KtLightClassForLocalDeclaration(classOrObject), PsiAnonymousClass {
|
||||
|
||||
private var cachedBaseType: SoftReference<PsiClassType>? = null
|
||||
|
||||
@@ -119,7 +117,7 @@ internal open class KtLightClassForAnonymousDeclaration(fqNameFunction: ((KtClas
|
||||
override fun getTypeParameterList() = null
|
||||
override fun isEnum() = false
|
||||
|
||||
override fun copy(): PsiElement = KtLightClassForAnonymousDeclaration(classFqNameFunction, classOrObject)
|
||||
override fun copy(): PsiElement = KtLightClassForAnonymousDeclaration(classOrObject)
|
||||
|
||||
companion object {
|
||||
private val LOG = Logger.getInstance(KtLightClassForAnonymousDeclaration::class.java)
|
||||
|
||||
+2
-4
@@ -18,16 +18,14 @@ package org.jetbrains.kotlin.asJava.classes
|
||||
|
||||
import com.intellij.psi.PsiEnumConstant
|
||||
import com.intellij.psi.PsiEnumConstantInitializer
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtEnumEntry
|
||||
|
||||
internal class KtLightClassForEnumEntry(
|
||||
fqName: FqName,
|
||||
enumEntry: KtEnumEntry,
|
||||
private val enumConstant: PsiEnumConstant
|
||||
): KtLightClassForAnonymousDeclaration({ fqName }, enumEntry), PsiEnumConstantInitializer {
|
||||
): KtLightClassForAnonymousDeclaration(enumEntry), PsiEnumConstantInitializer {
|
||||
override fun getEnumConstant(): PsiEnumConstant = enumConstant
|
||||
override fun copy() = KtLightClassForEnumEntry(classFqName, classOrObject as KtEnumEntry, enumConstant)
|
||||
override fun copy() = KtLightClassForEnumEntry(classOrObject as KtEnumEntry, enumConstant)
|
||||
|
||||
override fun getParent() = enumConstant
|
||||
}
|
||||
|
||||
+3
-3
@@ -198,9 +198,9 @@ class KtLightClassForFacade private constructor(
|
||||
|
||||
override val clsDelegate: PsiClass
|
||||
get() {
|
||||
val psiClass = LightClassUtil.findClass(facadeClassFqName, lightClassDataCache.value.javaFileStub)
|
||||
?: throw IllegalStateException("Facade class $facadeClassFqName not found")
|
||||
return psiClass
|
||||
return LightClassUtil.findClass(lightClassDataCache.value.javaFileStub) {
|
||||
facadeClassFqName.asString() == it.qualifiedName
|
||||
} ?: throw IllegalStateException("Facade class $facadeClassFqName not found")
|
||||
}
|
||||
|
||||
override fun getNavigationElement() = files.iterator().next()
|
||||
|
||||
+15
-5
@@ -17,21 +17,31 @@
|
||||
package org.jetbrains.kotlin.asJava.classes
|
||||
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
|
||||
import com.intellij.psi.stubs.StubElement
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||
import org.jetbrains.kotlin.asJava.builder.ClsWrapperStubPsiFactory
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
|
||||
class KtLightClassForInterfaceDefaultImpls(
|
||||
classFqName: FqName,
|
||||
classOrObject: KtClassOrObject)
|
||||
: KtLightClassForSourceDeclaration({ classFqName }, classOrObject){
|
||||
override fun getQualifiedName(): String = classFqName.asString()
|
||||
: KtLightClassForSourceDeclaration(classOrObject){
|
||||
override fun getQualifiedName(): String? = containingClass?.qualifiedName?.let { it + ".${JvmAbi.DEFAULT_IMPLS_CLASS_NAME}" }
|
||||
|
||||
override fun getName() = JvmAbi.DEFAULT_IMPLS_CLASS_NAME
|
||||
override fun getParent() = containingClass
|
||||
|
||||
override fun copy(): PsiElement {
|
||||
return KtLightClassForInterfaceDefaultImpls(classFqName, classOrObject.copy() as KtClassOrObject)
|
||||
return KtLightClassForInterfaceDefaultImpls(classOrObject.copy() as KtClassOrObject)
|
||||
}
|
||||
|
||||
override fun findDelegateClass(javaFileStub: PsiJavaFileStub): PsiClass? {
|
||||
val interfaceClass = LightClassUtil.findClass(javaFileStub) {
|
||||
ClsWrapperStubPsiFactory.getOriginalElement(it as StubElement<*>) == classOrObject
|
||||
}
|
||||
return interfaceClass?.findInnerClassByName(JvmAbi.DEFAULT_IMPLS_CLASS_NAME, false)
|
||||
}
|
||||
|
||||
override fun getTypeParameterList(): PsiTypeParameterList? = null
|
||||
|
||||
+2
-4
@@ -24,16 +24,14 @@ import com.intellij.psi.impl.light.LightMethod
|
||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
|
||||
open class KtLightClassForLocalDeclaration(
|
||||
classFqNameFunction: (KtClassOrObject) -> FqName,
|
||||
classOrObject: KtClassOrObject
|
||||
) : KtLightClassForSourceDeclaration(classFqNameFunction, classOrObject) {
|
||||
) : KtLightClassForSourceDeclaration(classOrObject) {
|
||||
|
||||
override fun copy(): PsiElement = KtLightClassForLocalDeclaration(classFqNameFunction, classOrObject.copy() as KtClassOrObject)
|
||||
override fun copy(): PsiElement = KtLightClassForLocalDeclaration(classOrObject.copy() as KtClassOrObject)
|
||||
override fun getQualifiedName(): String? = null
|
||||
|
||||
override fun getParent() = _parent
|
||||
|
||||
+24
-26
@@ -32,12 +32,19 @@ import com.intellij.psi.util.CachedValuesManager
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import org.jetbrains.annotations.NonNls
|
||||
import org.jetbrains.kotlin.asJava.*
|
||||
import org.jetbrains.kotlin.asJava.builder.*
|
||||
import org.jetbrains.kotlin.asJava.KtJavaMirrorMarker
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||
import org.jetbrains.kotlin.asJava.builder.ClsWrapperStubPsiFactory.getOriginalElement
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassData
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForClassOrObject
|
||||
import org.jetbrains.kotlin.asJava.builder.OutermostKotlinClassLightClassData
|
||||
import org.jetbrains.kotlin.asJava.builder.WithFileStubAndExtraDiagnostics
|
||||
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightModifierListWithExplicitModifiers
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightPsiReferenceList
|
||||
import org.jetbrains.kotlin.asJava.hasInterfaceDefaultImpls
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||
@@ -45,6 +52,7 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.debugText.getDebugText
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
||||
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
@@ -52,16 +60,10 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import java.util.*
|
||||
import javax.swing.Icon
|
||||
|
||||
abstract class KtLightClassForSourceDeclaration(
|
||||
protected val classFqNameFunction: ((KtClassOrObject) -> FqName),
|
||||
protected val classOrObject: KtClassOrObject)
|
||||
abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtClassOrObject)
|
||||
: KtLightClassBase(classOrObject.manager), KtJavaMirrorMarker, StubBasedPsiElement<KotlinClassOrObjectStub<out KtClassOrObject>> {
|
||||
private val lightIdentifier = KtLightIdentifier(this, classOrObject)
|
||||
|
||||
protected val classFqName : FqName by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
classFqNameFunction(classOrObject)
|
||||
}
|
||||
|
||||
private val _extendsList by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
val listDelegate = super.getExtendsList() ?: return@lazy null
|
||||
KtLightPsiReferenceList(listDelegate, this)
|
||||
@@ -81,7 +83,7 @@ abstract class KtLightClassForSourceDeclaration(
|
||||
override val clsDelegate: PsiClass by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
val javaFileStub = getJavaFileStub()
|
||||
|
||||
LightClassUtil.findClass(classFqName, javaFileStub) ?: run {
|
||||
findDelegateClass(javaFileStub) ?: run {
|
||||
val outermostClassOrObject = getOutermostClassOrObject(classOrObject)
|
||||
val ktFileText: String? = try {
|
||||
outermostClassOrObject.containingFile.text
|
||||
@@ -91,7 +93,13 @@ abstract class KtLightClassForSourceDeclaration(
|
||||
}
|
||||
|
||||
val stubFileText = DebugUtil.stubTreeToString(javaFileStub)
|
||||
throw IllegalStateException("Class was not found $classFqName\nin $ktFileText\nstub: \n$stubFileText")
|
||||
throw IllegalStateException("Couldn't get delegate for $this\nin $ktFileText\nstub: \n$stubFileText")
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun findDelegateClass(javaFileStub: PsiJavaFileStub): PsiClass? {
|
||||
return LightClassUtil.findClass(javaFileStub) {
|
||||
getOriginalElement(it as StubElement<*>) == classOrObject
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,14 +313,14 @@ abstract class KtLightClassForSourceDeclaration(
|
||||
return this
|
||||
}
|
||||
|
||||
override fun toString() = "${KtLightClass::class.java.simpleName}:$classFqName"
|
||||
override fun toString() = "${this.javaClass.simpleName}:${classOrObject.getDebugText()}"
|
||||
|
||||
override fun getOwnInnerClasses(): List<PsiClass> {
|
||||
val result = ArrayList<PsiClass>()
|
||||
classOrObject.declarations.filterIsInstance<KtClassOrObject>().mapNotNullTo(result) { create(it) }
|
||||
|
||||
if (classOrObject.hasInterfaceDefaultImpls) {
|
||||
result.add(KtLightClassForInterfaceDefaultImpls(classFqName.defaultImplsChild(), classOrObject))
|
||||
result.add(KtLightClassForInterfaceDefaultImpls(classOrObject))
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -342,25 +350,20 @@ abstract class KtLightClassForSourceDeclaration(
|
||||
if (classOrObject is KtObjectDeclaration && classOrObject.isObjectLiteral()) {
|
||||
if (classOrObject.containingFile.virtualFile == null) return null
|
||||
|
||||
val data = getLightClassDataExactly(classOrObject) ?: return null
|
||||
return KtLightClassForAnonymousDeclaration(
|
||||
{ data.jvmQualifiedName },
|
||||
classOrObject)
|
||||
return KtLightClassForAnonymousDeclaration(classOrObject)
|
||||
}
|
||||
|
||||
if (classOrObject.isLocal()) {
|
||||
if (classOrObject.containingFile.virtualFile == null) return null
|
||||
|
||||
val data = getLightClassDataExactly(classOrObject) ?: return null
|
||||
return KtLightClassForLocalDeclaration({ data.jvmQualifiedName }, classOrObject)
|
||||
return KtLightClassForLocalDeclaration(classOrObject)
|
||||
}
|
||||
|
||||
if (isEnumEntryWithoutBody(classOrObject)) {
|
||||
return null
|
||||
}
|
||||
|
||||
val fqName = classOrObject.fqName ?: return null
|
||||
return KtLightClassImpl({ fqName }, classOrObject)
|
||||
return KtLightClassImpl(classOrObject)
|
||||
}
|
||||
|
||||
private fun isEnumEntryWithoutBody(classOrObject: KtClassOrObject): Boolean {
|
||||
@@ -385,11 +388,6 @@ abstract class KtLightClassForSourceDeclaration(
|
||||
return value
|
||||
}
|
||||
|
||||
private fun getLightClassDataExactly(classOrObject: KtClassOrObject): LightClassDataForKotlinClass? {
|
||||
val data = getLightClassData(classOrObject) as? OutermostKotlinClassLightClassData ?: return null
|
||||
return data.dataForClass(classOrObject)
|
||||
}
|
||||
|
||||
private fun getOutermostClassOrObject(classOrObject: KtClassOrObject): KtClassOrObject {
|
||||
val outermostClass = KtPsiUtil.getOutermostClassOrObject(classOrObject) ?:
|
||||
throw IllegalStateException("Attempt to build a light class for a local class: " + classOrObject.text)
|
||||
|
||||
@@ -16,17 +16,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.asJava.classes
|
||||
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
|
||||
// light class for top level or (inner/nested of top level) source declarations
|
||||
class KtLightClassImpl(
|
||||
classFqNameFunction: (KtClassOrObject) -> FqName,
|
||||
classOrObject: KtClassOrObject
|
||||
) : KtLightClassForSourceDeclaration(classFqNameFunction, classOrObject) {
|
||||
val fqName: FqName
|
||||
get() = fqName
|
||||
|
||||
class KtLightClassImpl(classOrObject: KtClassOrObject) : KtLightClassForSourceDeclaration(classOrObject) {
|
||||
override fun getQualifiedName() = classOrObject.fqName?.asString()
|
||||
|
||||
override fun getParent() = if (classOrObject.isTopLevel())
|
||||
@@ -34,5 +27,5 @@ class KtLightClassImpl(
|
||||
else
|
||||
containingClass
|
||||
|
||||
override fun copy() = KtLightClassImpl(classFqNameFunction, classOrObject.copy() as KtClassOrObject)
|
||||
override fun copy() = KtLightClassImpl(classOrObject.copy() as KtClassOrObject)
|
||||
}
|
||||
@@ -26,9 +26,7 @@ import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
|
||||
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForEnumEntry
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassImpl
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtEnumEntry
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
@@ -141,8 +139,7 @@ sealed class KtLightFieldImpl(
|
||||
is PsiEnumConstant -> {
|
||||
val kotlinEnumEntry = (origin as? LightMemberOriginForDeclaration)?.originalElement as? KtEnumEntry
|
||||
val initializingClass = if (kotlinEnumEntry != null && kotlinEnumEntry.declarations.isNotEmpty()) {
|
||||
val enumConstantFqName = FqName((containingClass as KtLightClassImpl).fqName.asString() + "." + kotlinEnumEntry.name)
|
||||
KtLightClassForEnumEntry(enumConstantFqName, kotlinEnumEntry, delegate)
|
||||
KtLightClassForEnumEntry(kotlinEnumEntry, delegate)
|
||||
}
|
||||
else null
|
||||
return KtLightEnumConstant(origin, delegate, containingClass, initializingClass)
|
||||
|
||||
Reference in New Issue
Block a user