Support DefaultImpls in light-classes and indices
#KT-4647 Fixed
This commit is contained in:
@@ -31,6 +31,7 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.SLRUCache;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.NamePackage;
|
||||
@@ -127,7 +128,10 @@ public class JavaElementFinder extends PsiElementFinder implements KotlinFinderM
|
||||
}
|
||||
|
||||
// Finds explicitly declared classes and objects, not package classes
|
||||
// Also DefaultImpls classes of interfaces
|
||||
private void findClassesAndObjects(FqName qualifiedName, GlobalSearchScope scope, List<PsiClass> answer) {
|
||||
findInterfaceDefaultImpls(qualifiedName, scope, answer);
|
||||
|
||||
Collection<JetClassOrObject> classOrObjectDeclarations =
|
||||
lightClassGenerationSupport.findClassOrObjectDeclarations(qualifiedName, scope);
|
||||
|
||||
@@ -141,6 +145,22 @@ public class JavaElementFinder extends PsiElementFinder implements KotlinFinderM
|
||||
}
|
||||
}
|
||||
|
||||
private void findInterfaceDefaultImpls(FqName qualifiedName, GlobalSearchScope scope, List<PsiClass> answer) {
|
||||
if (!qualifiedName.shortName().asString().equals(JvmAbi.DEFAULT_IMPLS_CLASS_NAME)) return;
|
||||
|
||||
for (JetClassOrObject classOrObject : lightClassGenerationSupport.findClassOrObjectDeclarations(qualifiedName.parent(), scope)) {
|
||||
if (LightClassUtilsKt.getHasInterfaceDefaultImpls(classOrObject)) {
|
||||
PsiClass interfaceClass = LightClassUtil.INSTANCE$.getPsiClass(classOrObject);
|
||||
if (interfaceClass != null) {
|
||||
PsiClass implsClass = interfaceClass.findInnerClassByName(JvmAbi.DEFAULT_IMPLS_CLASS_NAME, false);
|
||||
if (implsClass != null) {
|
||||
answer.add(implsClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<String> getClassNames(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
|
||||
|
||||
+17
-4
@@ -50,7 +50,7 @@ import javax.swing.Icon
|
||||
|
||||
public open class KotlinLightClassForExplicitDeclaration(
|
||||
manager: PsiManager,
|
||||
private val classFqName: FqName, // FqName of (possibly inner) class
|
||||
protected val classFqName: FqName, // FqName of (possibly inner) class
|
||||
protected val classOrObject: JetClassOrObject)
|
||||
: KotlinWrappingLightClass(manager), JetJavaMirrorMarker, StubBasedPsiElement<KotlinClassOrObjectStub<out JetClassOrObject>> {
|
||||
private var delegate: PsiClass? = null
|
||||
@@ -268,7 +268,7 @@ public open class KotlinLightClassForExplicitDeclaration(
|
||||
|
||||
override fun getModifierList(): PsiModifierList = _modifierList
|
||||
|
||||
private fun computeModifiers(): Array<String> {
|
||||
protected open fun computeModifiers(): Array<String> {
|
||||
val psiModifiers = hashSetOf<String>()
|
||||
|
||||
// PUBLIC, PROTECTED, PRIVATE, ABSTRACT, FINAL
|
||||
@@ -377,7 +377,7 @@ public open class KotlinLightClassForExplicitDeclaration(
|
||||
return getDelegate().innerClasses
|
||||
.map {
|
||||
val declaration = ClsWrapperStubPsiFactory.getOriginalDeclaration(it) as JetClassOrObject?
|
||||
if (declaration != null) create(myManager, declaration) else null
|
||||
if (declaration != null) create(myManager, declaration, it) else null
|
||||
}
|
||||
.filterNotNull()
|
||||
}
|
||||
@@ -397,7 +397,12 @@ public open class KotlinLightClassForExplicitDeclaration(
|
||||
FINAL_KEYWORD to PsiModifier.FINAL)
|
||||
|
||||
|
||||
public fun create(manager: PsiManager, classOrObject: JetClassOrObject): KotlinLightClassForExplicitDeclaration? {
|
||||
@JvmOverloads
|
||||
public fun create(
|
||||
manager: PsiManager,
|
||||
classOrObject: JetClassOrObject,
|
||||
psiClass: PsiClass? = null
|
||||
): KotlinLightClassForExplicitDeclaration? {
|
||||
if (LightClassUtil.belongsToKotlinBuiltIns(classOrObject.getContainingJetFile())) {
|
||||
return null
|
||||
}
|
||||
@@ -407,6 +412,14 @@ public open class KotlinLightClassForExplicitDeclaration(
|
||||
if (classOrObject is JetObjectDeclaration && classOrObject.isObjectLiteral()) {
|
||||
return KotlinLightClassForAnonymousDeclaration(manager, fqName, classOrObject)
|
||||
}
|
||||
|
||||
if (classOrObject.hasInterfaceDefaultImpls) {
|
||||
val implsFqName = fqName.defaultImplsChild()
|
||||
if (implsFqName.asString() == psiClass?.qualifiedName) {
|
||||
return KotlinLightClassForInterfaceDefaultImpls(manager, implsFqName, classOrObject)
|
||||
}
|
||||
}
|
||||
|
||||
return KotlinLightClassForExplicitDeclaration(manager, fqName, classOrObject)
|
||||
}
|
||||
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.asJava
|
||||
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.JetClassOrObject
|
||||
|
||||
public open class KotlinLightClassForInterfaceDefaultImpls(
|
||||
manager: PsiManager,
|
||||
classFqName: FqName,
|
||||
classOrObject: JetClassOrObject)
|
||||
: KotlinLightClassForExplicitDeclaration(manager, classFqName, classOrObject){
|
||||
|
||||
override fun copy(): PsiElement {
|
||||
return KotlinLightClassForInterfaceDefaultImpls(manager, classFqName, classOrObject.copy() as JetClassOrObject)
|
||||
}
|
||||
|
||||
override fun getTypeParameterList(): PsiTypeParameterList? = null
|
||||
override fun getTypeParameters(): Array<PsiTypeParameter> = emptyArray()
|
||||
|
||||
override fun computeModifiers(): Array<String> = arrayOf(PsiModifier.PUBLIC, PsiModifier.STATIC, PsiModifier.FINAL)
|
||||
|
||||
override fun isInterface(): Boolean = false
|
||||
override fun isDeprecated(): Boolean = false
|
||||
override fun isAnnotationType(): Boolean = false
|
||||
override fun isEnum(): Boolean = false
|
||||
override fun hasTypeParameters(): Boolean = false
|
||||
override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean = false
|
||||
|
||||
@Throws(IncorrectOperationException::class)
|
||||
override fun setName(name: String): PsiElement {
|
||||
throw IncorrectOperationException("Impossible to rename DefaultImpls")
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,9 @@
|
||||
package org.jetbrains.kotlin.asJava
|
||||
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration
|
||||
@@ -98,3 +101,10 @@ public val PsiElement.unwrapped: PsiElement?
|
||||
|
||||
public val PsiElement.namedUnwrappedElement: PsiNamedElement?
|
||||
get() = unwrapped?.getNonStrictParentOfType<PsiNamedElement>()
|
||||
|
||||
|
||||
val JetClassOrObject.hasInterfaceDefaultImpls: Boolean
|
||||
get() = this is JetClass && isInterface()
|
||||
|
||||
private val DEFAULT_IMPLS_CLASS_NAME = Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME)
|
||||
fun FqName.defaultImplsChild() = child(DEFAULT_IMPLS_CLASS_NAME)
|
||||
|
||||
Reference in New Issue
Block a user