From b1b5af8e1e4a13a0c12459cf13ebb57530a98629 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Wed, 23 Sep 2015 13:25:47 +0300 Subject: [PATCH] More correct detection of super property --- .../idea/j2k/IdeaJavaToKotlinServices.kt | 12 +++++++++++- .../kotlin/idea/j2k/IdeaReferenceSearcher.kt | 2 +- .../j2k/JavaToKotlinConverterServices.kt | 19 ++++++++++++++++++- .../jetbrains/kotlin/j2k/propertyDetection.kt | 12 +++++------- j2k/testData/JavaApi.java | 11 +++++++++++ .../OverridesOfExternalCode.java | 10 ++++++++++ .../dropAccessors/OverridesOfExternalCode.kt | 15 +++++++++++++++ 7 files changed, 71 insertions(+), 10 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/j2k/IdeaJavaToKotlinServices.kt b/idea/src/org/jetbrains/kotlin/idea/j2k/IdeaJavaToKotlinServices.kt index 7023490061d..62de71e10ac 100644 --- a/idea/src/org/jetbrains/kotlin/idea/j2k/IdeaJavaToKotlinServices.kt +++ b/idea/src/org/jetbrains/kotlin/idea/j2k/IdeaJavaToKotlinServices.kt @@ -16,13 +16,23 @@ package org.jetbrains.kotlin.idea.j2k +import com.intellij.psi.PsiMethod import org.jetbrains.kotlin.j2k.* -object IdeaJavaToKotlinServices: JavaToKotlinConverterServices { +object IdeaJavaToKotlinServices : JavaToKotlinConverterServices { override val referenceSearcher: ReferenceSearcher get() = IdeaReferenceSearcher + + override val superMethodsSearcher: SuperMethodsSearcher + get() = IdeaSuperMethodSearcher + override val resolverForConverter: ResolverForConverter get() = IdeaResolverForConverter + override val docCommentConverter: DocCommentConverter get() = IdeaDocCommentConverter +} + +object IdeaSuperMethodSearcher : SuperMethodsSearcher { + override fun findDeepestSuperMethods(method: PsiMethod) = method.findDeepestSuperMethods().asList() } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/j2k/IdeaReferenceSearcher.kt b/idea/src/org/jetbrains/kotlin/idea/j2k/IdeaReferenceSearcher.kt index c5948cf3e65..91a40187da5 100644 --- a/idea/src/org/jetbrains/kotlin/idea/j2k/IdeaReferenceSearcher.kt +++ b/idea/src/org/jetbrains/kotlin/idea/j2k/IdeaReferenceSearcher.kt @@ -49,4 +49,4 @@ public object IdeaReferenceSearcher: ReferenceSearcher { val searchScope = GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.projectScope(element.getProject()), *fileTypes.toTypedArray()) return ReferencesSearch.search(element, searchScope).findAll() } -} \ No newline at end of file +} diff --git a/j2k/src/org/jetbrains/kotlin/j2k/JavaToKotlinConverterServices.kt b/j2k/src/org/jetbrains/kotlin/j2k/JavaToKotlinConverterServices.kt index 3721cf37b9d..3f6480150eb 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/JavaToKotlinConverterServices.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/JavaToKotlinConverterServices.kt @@ -16,8 +16,11 @@ package org.jetbrains.kotlin.j2k +import com.intellij.psi.PsiMethod + interface JavaToKotlinConverterServices { val referenceSearcher: ReferenceSearcher + val superMethodsSearcher: SuperMethodsSearcher val resolverForConverter: ResolverForConverter val docCommentConverter: DocCommentConverter } @@ -25,8 +28,22 @@ interface JavaToKotlinConverterServices { object EmptyJavaToKotlinServices: JavaToKotlinConverterServices { override val referenceSearcher: ReferenceSearcher get() = EmptyReferenceSearcher + + override val superMethodsSearcher: SuperMethodsSearcher + get() = SuperMethodsSearcher.Default + override val resolverForConverter: ResolverForConverter get() = EmptyResolverForConverter + override val docCommentConverter: DocCommentConverter get() = EmptyDocCommentConverter -} \ No newline at end of file +} + +interface SuperMethodsSearcher { + fun findDeepestSuperMethods(method: PsiMethod): Collection + + object Default : SuperMethodsSearcher { + // use simple findSuperMethods by default because findDeepestSuperMethods requires some service from IDEA + override fun findDeepestSuperMethods(method: PsiMethod) = method.findSuperMethods().asList() + } +} diff --git a/j2k/src/org/jetbrains/kotlin/j2k/propertyDetection.kt b/j2k/src/org/jetbrains/kotlin/j2k/propertyDetection.kt index 3db9d1486df..2136db7da76 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/propertyDetection.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/propertyDetection.kt @@ -255,17 +255,15 @@ private class PropertyDetector( } private fun createAccessorInfo(getOrSetMethod: PsiMethod, field: PsiField?, kind: AccessorKind, propertyName: String): AccessorInfo? { - //TODO: deepest method //TODO: multiple - for (superSignature in getOrSetMethod.hierarchicalMethodSignature.superSignatures) { - val method = superSignature.method - val containingClass = method.containingClass!! + for (superMethod in converter.services.superMethodsSearcher.findDeepestSuperMethods(getOrSetMethod)) { + val containingClass = superMethod.containingClass!! val superPropertyInfo: SuperPropertyInfo? = if (converter.inConversionScope(containingClass)) { - val propertyInfo = converter.propertyDetectionCache[containingClass][method] + val propertyInfo = converter.propertyDetectionCache[containingClass][superMethod] if (propertyInfo != null) SuperPropertyInfo(propertyInfo.isVar) else null } - else if (method is KotlinLightMethod) { - val origin = method.getOrigin() + else if (superMethod is KotlinLightMethod) { + val origin = superMethod.getOrigin() if (origin is JetProperty) SuperPropertyInfo(origin.isVar) else null } else { diff --git a/j2k/testData/JavaApi.java b/j2k/testData/JavaApi.java index f971e229b8e..e1c1db0d86e 100644 --- a/j2k/testData/JavaApi.java +++ b/j2k/testData/JavaApi.java @@ -1,7 +1,10 @@ package javaApi; import org.jetbrains.annotations.Nullable; + +import java.lang.String; import java.util.Set; +import kotlinApi.KotlinClassWithProperties; public @interface Anon1 { String[] value(); @@ -103,4 +106,12 @@ public class JavaClassWithProperties { public int getValue4() { return 1; } public void setValue4(int value) { } +} + +public class JavaClassDerivedFromKotlinClassWithProperties extends KotlinClassWithProperties { + @Override + public String getSomeVar1() { return ""; } + + @Override + public void setSomeVar2(String value) { } } \ No newline at end of file diff --git a/j2k/testData/fileOrElement/dropAccessors/OverridesOfExternalCode.java b/j2k/testData/fileOrElement/dropAccessors/OverridesOfExternalCode.java index 9b58ee9a702..5757ab6afa5 100644 --- a/j2k/testData/fileOrElement/dropAccessors/OverridesOfExternalCode.java +++ b/j2k/testData/fileOrElement/dropAccessors/OverridesOfExternalCode.java @@ -1,5 +1,6 @@ import kotlinApi.KotlinClassWithProperties; import javaApi.JavaClassWithProperties; +import javaApi.JavaClassDerivedFromKotlinClassWithProperties; import org.jetbrains.annotations.NotNull; @@ -100,4 +101,13 @@ class C extends A { public String getSomeVar1() { return super.getSomeVar1(); } +} + +class D extends JavaClassDerivedFromKotlinClassWithProperties { + @Override + public String getSomeVar1() { return "a"; } + + @Override + public void setSomeVar2(String value) { } + } \ No newline at end of file diff --git a/j2k/testData/fileOrElement/dropAccessors/OverridesOfExternalCode.kt b/j2k/testData/fileOrElement/dropAccessors/OverridesOfExternalCode.kt index 5fc60c63faf..5917179870c 100644 --- a/j2k/testData/fileOrElement/dropAccessors/OverridesOfExternalCode.kt +++ b/j2k/testData/fileOrElement/dropAccessors/OverridesOfExternalCode.kt @@ -2,8 +2,11 @@ // ERROR: Property must be initialized // ERROR: Property must be initialized // ERROR: Property must be initialized +// ERROR: Property must be initialized +// ERROR: Property must be initialized import kotlinApi.KotlinClassWithProperties import javaApi.JavaClassWithProperties +import javaApi.JavaClassDerivedFromKotlinClassWithProperties internal open class A : KotlinClassWithProperties() { override var someVar1: String @@ -82,4 +85,16 @@ internal class C : A() { get() { return super.someVar1 } +} + +internal class D : JavaClassDerivedFromKotlinClassWithProperties() { + override var someVar1: String + get() { + return "a" + } + + override var someVar2: String + set(value: String) { + } + } \ No newline at end of file