Change properties to methods in light class hierarchy
There's a Kotlin-Java-Kotlin hierarchy with an abstract property in a superclass and its implementation (as a get-method) in the Java subclass, which caused problems because Kotlin subclass can't have both (different symbols, same JVM signatures)
This commit is contained in:
@@ -21,5 +21,5 @@ import org.jetbrains.kotlin.name.FqName;
|
|||||||
import org.jetbrains.kotlin.psi.JetClassOrObject
|
import org.jetbrains.kotlin.psi.JetClassOrObject
|
||||||
|
|
||||||
public trait KotlinLightClass : PsiClass, KotlinLightElement<JetClassOrObject, PsiClass> {
|
public trait KotlinLightClass : PsiClass, KotlinLightElement<JetClassOrObject, PsiClass> {
|
||||||
val fqName: FqName
|
public fun getFqName(): FqName
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.psi.JetDeclaration
|
|||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
|
||||||
public trait KotlinLightElement<T : JetDeclaration, D : PsiElement> {
|
public trait KotlinLightElement<T : JetDeclaration, D : PsiElement> {
|
||||||
public val origin: T?
|
public fun getOrigin(): T?
|
||||||
public val delegate: D
|
|
||||||
|
public fun getDelegate(): D
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-5
@@ -34,8 +34,8 @@ import com.intellij.psi.util.MethodSignatureBackedByPsiMethod
|
|||||||
|
|
||||||
open public class KotlinLightMethodForDeclaration(
|
open public class KotlinLightMethodForDeclaration(
|
||||||
manager: PsiManager,
|
manager: PsiManager,
|
||||||
override val delegate: PsiMethod,
|
private val delegate: PsiMethod,
|
||||||
override val origin: JetDeclaration,
|
private val origin: JetDeclaration,
|
||||||
containingClass: PsiClass
|
containingClass: PsiClass
|
||||||
): LightMethod(manager, delegate, containingClass), KotlinLightMethod {
|
): LightMethod(manager, delegate, containingClass), KotlinLightMethod {
|
||||||
|
|
||||||
@@ -65,8 +65,12 @@ open public class KotlinLightMethodForDeclaration(
|
|||||||
}, false)
|
}, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getNavigationElement() : PsiElement = origin
|
override fun getNavigationElement(): PsiElement = origin
|
||||||
override fun getOriginalElement() : PsiElement = origin
|
override fun getOriginalElement(): PsiElement = origin
|
||||||
|
|
||||||
|
override fun getDelegate(): PsiMethod = delegate
|
||||||
|
|
||||||
|
override fun getOrigin(): JetDeclaration = origin
|
||||||
|
|
||||||
override fun getParent(): PsiElement? = getContainingClass()
|
override fun getParent(): PsiElement? = getContainingClass()
|
||||||
|
|
||||||
@@ -82,7 +86,7 @@ open public class KotlinLightMethodForDeclaration(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun isEquivalentTo(another: PsiElement?): Boolean {
|
override fun isEquivalentTo(another: PsiElement?): Boolean {
|
||||||
if (another is KotlinLightMethod && origin == another.origin) {
|
if (another is KotlinLightMethod && origin == another.getOrigin()) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-3
@@ -24,11 +24,15 @@ import com.intellij.psi.PsiElement
|
|||||||
|
|
||||||
public class KotlinLightMethodForTraitFakeOverride(
|
public class KotlinLightMethodForTraitFakeOverride(
|
||||||
manager: PsiManager,
|
manager: PsiManager,
|
||||||
override val delegate: PsiMethod,
|
private val delegate: PsiMethod,
|
||||||
override val origin: JetDeclaration,
|
private val origin: JetDeclaration,
|
||||||
containingClass: PsiClass
|
containingClass: PsiClass
|
||||||
) : KotlinLightMethodForDeclaration(manager, delegate, origin, containingClass) {
|
) : KotlinLightMethodForDeclaration(manager, delegate, origin, containingClass) {
|
||||||
|
override fun getDelegate(): PsiMethod = delegate
|
||||||
|
|
||||||
|
override fun getOrigin(): JetDeclaration = origin
|
||||||
|
|
||||||
override fun copy(): PsiElement {
|
override fun copy(): PsiElement {
|
||||||
return KotlinLightMethodForTraitFakeOverride(getManager()!!, delegate, origin.copy() as JetDeclaration, getContainingClass()!!)
|
return KotlinLightMethodForTraitFakeOverride(getManager(), delegate, origin.copy() as JetDeclaration, getContainingClass())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ public fun JetTypeParameter.toPsiTypeParameters(): List<PsiTypeParameter> {
|
|||||||
|
|
||||||
// Returns original declaration if given PsiElement is a Kotlin light element, and element itself otherwise
|
// Returns original declaration if given PsiElement is a Kotlin light element, and element itself otherwise
|
||||||
public val PsiElement.unwrapped: PsiElement?
|
public val PsiElement.unwrapped: PsiElement?
|
||||||
get() = if (this is KotlinLightElement<*, *>) origin else this
|
get() = if (this is KotlinLightElement<*, *>) getOrigin() else this
|
||||||
|
|
||||||
public val PsiElement.namedUnwrappedElement: PsiNamedElement?
|
public val PsiElement.namedUnwrappedElement: PsiNamedElement?
|
||||||
get() = unwrapped?.getNonStrictParentOfType<PsiNamedElement>()
|
get() = unwrapped?.getNonStrictParentOfType<PsiNamedElement>()
|
||||||
|
|||||||
+1
-1
@@ -48,7 +48,7 @@ public object JavaResolveExtension : CacheExtension<(PsiElement) -> Pair<JavaDes
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun PsiMethod.getJavaMethodDescriptor(): FunctionDescriptor {
|
fun PsiMethod.getJavaMethodDescriptor(): FunctionDescriptor {
|
||||||
if (this is KotlinLightMethod) throw AssertionError("Light methods are not allowed here: ${origin?.getText()}")
|
if (this is KotlinLightMethod) throw AssertionError("Light methods are not allowed here: ${getOrigin()?.getText()}")
|
||||||
|
|
||||||
val resolver = JavaResolveExtension.getResolver(getProject(), this)
|
val resolver = JavaResolveExtension.getResolver(getProject(), this)
|
||||||
val methodDescriptor = when {
|
val methodDescriptor = when {
|
||||||
|
|||||||
+4
-2
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.name.FqName
|
|||||||
|
|
||||||
class KotlinLightClassForDecompiledDeclaration(
|
class KotlinLightClassForDecompiledDeclaration(
|
||||||
private val clsClass: ClsClassImpl,
|
private val clsClass: ClsClassImpl,
|
||||||
override val origin: JetClassOrObject?
|
private val origin: JetClassOrObject?
|
||||||
) : KotlinWrappingLightClass(clsClass.getManager()) {
|
) : KotlinWrappingLightClass(clsClass.getManager()) {
|
||||||
override fun copy() = this
|
override fun copy() = this
|
||||||
|
|
||||||
@@ -38,5 +38,7 @@ class KotlinLightClassForDecompiledDeclaration(
|
|||||||
|
|
||||||
override fun getDelegate() = clsClass
|
override fun getDelegate() = clsClass
|
||||||
|
|
||||||
override val fqName: FqName = origin?.getFqName() ?: FqName(clsClass.getQualifiedName())
|
override fun getOrigin() = origin
|
||||||
|
|
||||||
|
override fun getFqName() = origin?.getFqName() ?: FqName(clsClass.getQualifiedName())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ private fun KotlinLightElement<*, *>.getModuleInfoForLightElement(): IdeaModuleI
|
|||||||
if (this is KotlinLightClassForDecompiledDeclaration) {
|
if (this is KotlinLightClassForDecompiledDeclaration) {
|
||||||
return getModuleInfoByVirtualFile(getProject(), getContainingFile().getVirtualFile(), false)
|
return getModuleInfoByVirtualFile(getProject(), getContainingFile().getVirtualFile(), false)
|
||||||
}
|
}
|
||||||
val element = origin ?: when (this) {
|
val element = getOrigin() ?: when (this) {
|
||||||
is FakeLightClassForFileOfPackage -> this.getContainingFile()!!
|
is FakeLightClassForFileOfPackage -> this.getContainingFile()!!
|
||||||
is KotlinLightClassForPackage -> this.getFiles().first()
|
is KotlinLightClassForPackage -> this.getFiles().first()
|
||||||
else -> throw IllegalStateException("Unknown light class without origin is referenced by IDE lazy resolve: $javaClass")
|
else -> throw IllegalStateException("Unknown light class without origin is referenced by IDE lazy resolve: $javaClass")
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ fun PsiReference.isPropertyReadOnlyUsage(): Boolean {
|
|||||||
|
|
||||||
val refTarget = resolve()
|
val refTarget = resolve()
|
||||||
if (refTarget is KotlinLightMethod) {
|
if (refTarget is KotlinLightMethod) {
|
||||||
val origin = refTarget.origin
|
val origin = refTarget.getOrigin()
|
||||||
val declaration: JetNamedDeclaration? = when (origin) {
|
val declaration: JetNamedDeclaration? = when (origin) {
|
||||||
is JetPropertyAccessor -> origin.getNonStrictParentOfType<JetProperty>()
|
is JetPropertyAccessor -> origin.getNonStrictParentOfType<JetProperty>()
|
||||||
is JetProperty, is JetParameter -> origin as JetNamedDeclaration
|
is JetProperty, is JetParameter -> origin as JetNamedDeclaration
|
||||||
|
|||||||
@@ -286,7 +286,7 @@ class TypeInstantiationItems(
|
|||||||
val parameters = ClassInheritorsSearch.SearchParameters(psiClass, inheritorSearchScope, true, true, false, nameFilter)
|
val parameters = ClassInheritorsSearch.SearchParameters(psiClass, inheritorSearchScope, true, true, false, nameFilter)
|
||||||
for (inheritor in ClassInheritorsSearch.search(parameters)) {
|
for (inheritor in ClassInheritorsSearch.search(parameters)) {
|
||||||
val descriptor = if (inheritor is KotlinLightClass && inheritor !is KotlinLightClassForDecompiledDeclaration) {
|
val descriptor = if (inheritor is KotlinLightClass && inheritor !is KotlinLightClassForDecompiledDeclaration) {
|
||||||
val origin = inheritor.origin ?: continue
|
val origin = inheritor.getOrigin() ?: continue
|
||||||
val declaration = toFromOriginalFileMapper.toSyntheticFile(origin) ?: continue
|
val declaration = toFromOriginalFileMapper.toSyntheticFile(origin) ?: continue
|
||||||
resolutionFacade.resolveToDescriptor(declaration)
|
resolutionFacade.resolveToDescriptor(declaration)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (elementAt is KotlinLightClass) {
|
if (elementAt is KotlinLightClass) {
|
||||||
return getContextElement(elementAt.origin)
|
return getContextElement(elementAt.getOrigin())
|
||||||
}
|
}
|
||||||
|
|
||||||
val expressionAtOffset = PsiTreeUtil.findElementOfClassAtOffset(elementAt.getContainingFile()!!, elementAt.getTextOffset(), javaClass<JetExpression>(), false)
|
val expressionAtOffset = PsiTreeUtil.findElementOfClassAtOffset(elementAt.getContainingFile()!!, elementAt.getTextOffset(), javaClass<JetExpression>(), false)
|
||||||
|
|||||||
+1
-1
@@ -78,7 +78,7 @@ public class JetChangeSignatureData(
|
|||||||
val overrides = lightMethod?.let { OverridingMethodsSearch.search(it).findAll() } ?: Collections.emptyList()
|
val overrides = lightMethod?.let { OverridingMethodsSearch.search(it).findAll() } ?: Collections.emptyList()
|
||||||
overrides.map { method ->
|
overrides.map { method ->
|
||||||
if (method is KotlinLightMethod) {
|
if (method is KotlinLightMethod) {
|
||||||
val overridingDeclaration = method.origin
|
val overridingDeclaration = method.getOrigin()
|
||||||
val overridingDescriptor = overridingDeclaration?.resolveToDescriptor() as FunctionDescriptor
|
val overridingDescriptor = overridingDeclaration?.resolveToDescriptor() as FunctionDescriptor
|
||||||
JetFunctionDefinitionUsage<PsiElement>(overridingDeclaration, overridingDescriptor, primaryFunction, null)
|
JetFunctionDefinitionUsage<PsiElement>(overridingDeclaration, overridingDescriptor, primaryFunction, null)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -36,7 +36,7 @@ public class RenameKotlinFunctionProcessor : RenameKotlinPsiProcessor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun canProcessElement(element: PsiElement): Boolean {
|
override fun canProcessElement(element: PsiElement): Boolean {
|
||||||
return element is JetNamedFunction || (element is KotlinLightMethod && element.origin is JetNamedFunction)
|
return element is JetNamedFunction || (element is KotlinLightMethod && element.getOrigin() is JetNamedFunction)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun substituteElementToRename(element: PsiElement?, editor: Editor?): PsiElement? {
|
override fun substituteElementToRename(element: PsiElement?, editor: Editor?): PsiElement? {
|
||||||
@@ -50,7 +50,7 @@ public class RenameKotlinFunctionProcessor : RenameKotlinPsiProcessor() {
|
|||||||
val substitutedJavaElement = javaMethodProcessorInstance.substituteElementToRename(wrappedMethod, editor)
|
val substitutedJavaElement = javaMethodProcessorInstance.substituteElementToRename(wrappedMethod, editor)
|
||||||
|
|
||||||
return when (substitutedJavaElement) {
|
return when (substitutedJavaElement) {
|
||||||
is KotlinLightMethod -> substitutedJavaElement.origin as? JetNamedFunction
|
is KotlinLightMethod -> substitutedJavaElement.getOrigin() as? JetNamedFunction
|
||||||
else -> substitutedJavaElement
|
else -> substitutedJavaElement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
|||||||
val typeArguments = convertTypeArguments(expression)
|
val typeArguments = convertTypeArguments(expression)
|
||||||
|
|
||||||
if (target is KotlinLightMethod) {
|
if (target is KotlinLightMethod) {
|
||||||
val origin = target.origin
|
val origin = target.getOrigin()
|
||||||
val isTopLevel = origin?.getStrictParentOfType<JetClassOrObject>() == null
|
val isTopLevel = origin?.getStrictParentOfType<JetClassOrObject>() == null
|
||||||
if (origin is JetProperty || origin is JetPropertyAccessor || origin is JetParameter) {
|
if (origin is JetProperty || origin is JetPropertyAccessor || origin is JetParameter) {
|
||||||
val property = if (origin is JetPropertyAccessor)
|
val property = if (origin is JetPropertyAccessor)
|
||||||
|
|||||||
@@ -369,7 +369,7 @@ class TypeConverter(val converter: Converter) {
|
|||||||
|
|
||||||
override fun fromAnnotations(owner: PsiModifierListOwner): Mutability {
|
override fun fromAnnotations(owner: PsiModifierListOwner): Mutability {
|
||||||
if (owner is KotlinLightElement<*, *>) {
|
if (owner is KotlinLightElement<*, *>) {
|
||||||
val jetDeclaration = owner.origin as? JetCallableDeclaration ?: return Mutability.Default
|
val jetDeclaration = owner.getOrigin() as? JetCallableDeclaration ?: return Mutability.Default
|
||||||
val descriptor = converter.resolverForConverter.resolveToDescriptor(jetDeclaration) as? CallableDescriptor ?: return Mutability.Default
|
val descriptor = converter.resolverForConverter.resolveToDescriptor(jetDeclaration) as? CallableDescriptor ?: return Mutability.Default
|
||||||
val type = descriptor.getReturnType() ?: return Mutability.Default
|
val type = descriptor.getReturnType() ?: return Mutability.Default
|
||||||
val classDescriptor = TypeUtils.getClassDescriptor(type) ?: return Mutability.Default
|
val classDescriptor = TypeUtils.getClassDescriptor(type) ?: return Mutability.Default
|
||||||
|
|||||||
Reference in New Issue
Block a user