From badf8dbc535e47cd5890c9c43f9384c199bcdd85 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Wed, 3 Aug 2016 22:53:00 +0300 Subject: [PATCH] Kapt: Fixes in KotlinElements: 1. 'overrides()' when 'type' extends containing(overrider) and implements containing(overridden). According to documentation, In this case the function should return true. 2. Handle both kotlin.Deprecated and java.lang.Deprecated for Kotlin in 'isDeprecated'. 3. Fix 'isFunctionalInterface'. (cherry picked from commit a14d7ce) --- .../processing/impl/KotlinElements.kt | 49 +++++++++++++------ 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinElements.kt b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinElements.kt index 9414619e3ed..2bb37f851c1 100644 --- a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinElements.kt +++ b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinElements.kt @@ -16,11 +16,9 @@ package org.jetbrains.kotlin.annotation.processing.impl -import com.intellij.psi.JavaPsiFacade -import com.intellij.psi.PsiClass +import com.intellij.psi.* import com.intellij.psi.search.GlobalSearchScope -import com.intellij.psi.util.PsiSuperMethodUtil -import com.intellij.psi.util.PsiTypesUtil +import com.intellij.psi.util.* import org.jetbrains.kotlin.java.model.JeAnnotationOwner import org.jetbrains.kotlin.java.model.JeElement import org.jetbrains.kotlin.java.model.JeName @@ -37,26 +35,26 @@ class KotlinElements(val javaPsiFacade: JavaPsiFacade, val scope: GlobalSearchSc override fun hides(hider: Element, hidden: Element): Boolean { val hiderMethod = (hider as? JeMethodExecutableElement)?.psi ?: return false val hiddenMethod = (hidden as? JeMethodExecutableElement)?.psi ?: return false - - if (hiderMethod.name != hiddenMethod.name) return false - if (hiderMethod.parameterList.parametersCount != hiddenMethod.parameterList.parametersCount) return false - + val hiderMethodClass = hiderMethod.containingClass ?: return false val hiddenMethodClass = hiddenMethod.containingClass ?: return false - - if (PsiTypesUtil.getClassType(hiddenMethodClass) !in hiderMethodClass.superTypes) return false - if (hiderMethod.returnType != hiddenMethod.returnType) return false - for (i in 0..hiderMethod.parameterList.parametersCount - 1) { - if (hiderMethod.parameterList.parameters[i].type != hiddenMethod.parameterList.parameters[i].type) return false - } + if (PsiTypesUtil.getClassType(hiddenMethodClass) !in hiderMethodClass.superTypes) return false - return true + return isSubSignature(hiderMethod, hiddenMethod) } override fun overrides(overrider: ExecutableElement, overridden: ExecutableElement, type: TypeElement): Boolean { overrider as? JeMethodExecutableElement ?: return false overridden as? JeMethodExecutableElement ?: return false + type as? JeTypeElement ?: return false + + if (overrider.psi == overridden.psi) return false + + // if 'type' is a subtype of overrider's containing class + if (type.psi.isSubclassOf(overridden.psi.containingClass) && type.psi.isSubclassOf(overrider.psi.containingClass)) { + return isSubSignature(overrider.psi, overridden.psi) + } return PsiSuperMethodUtil.isSuperMethod(overrider.psi, overridden.psi) } @@ -74,6 +72,8 @@ class KotlinElements(val javaPsiFacade: JavaPsiFacade, val scope: GlobalSearchSc override fun getDocComment(e: Element?) = null override fun isDeprecated(e: Element?): Boolean { + val deprecated = ((e as? JeElement)?.psi as? PsiDocCommentOwner)?.isDeprecated ?: false + if (deprecated) return true return (e as? JeAnnotationOwner)?.annotationOwner?.findAnnotation("java.lang.Deprecated") != null } @@ -132,11 +132,28 @@ class KotlinElements(val javaPsiFacade: JavaPsiFacade, val scope: GlobalSearchSc override fun isFunctionalInterface(type: TypeElement): Boolean { val jeTypeElement = type as? JeTypeElement ?: return false if (!jeTypeElement.psi.isInterface) return false - if (jeTypeElement.psi.allMethods.size != 1) return false + if (jeTypeElement.psi.allMethods.count { it.hasModifierProperty(PsiModifier.ABSTRACT) } != 1) return false return true } } +private fun PsiClass.isSubclassOf(other: PsiClass?): Boolean { + if (other == null) return false + return TypeConversionUtil.isAssignable(PsiTypesUtil.getClassType(other), PsiTypesUtil.getClassType(this), false) +} + +private fun isSubSignature(childMethod: PsiMethod, superMethod: PsiMethod): Boolean { + if (childMethod.name != superMethod.name) return false + if (childMethod.parameterList.parametersCount != superMethod.parameterList.parametersCount) return false + + if (childMethod.returnType != superMethod.returnType) return false + for (i in 0..childMethod.parameterList.parametersCount - 1) { + if (childMethod.parameterList.parameters[i].type != superMethod.parameterList.parameters[i].type) return false + } + + return true +} + object Constants { fun format(value: Any?): String { return when (value) {