diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SyntheticExtensionsScope.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SyntheticExtensionsScope.kt index ab7b91d3933..ec392b71faf 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SyntheticExtensionsScope.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SyntheticExtensionsScope.kt @@ -39,6 +39,17 @@ import java.util.* interface SyntheticExtensionPropertyDescriptor : PropertyDescriptor { val getMethod: FunctionDescriptor val setMethod: FunctionDescriptor? + + companion object { + fun findByGetterOrSetter(getterOrSetter: FunctionDescriptor, resolutionScope: JetScope): SyntheticExtensionPropertyDescriptor? { + val owner = getterOrSetter.getContainingDeclaration() + if (owner !is JavaClassDescriptor) return null + + return resolutionScope.getSyntheticExtensionProperties(owner.getDefaultType()) + .filterIsInstance() + .firstOrNull { getterOrSetter == it.getMethod || getterOrSetter == it.setMethod } + } + } } class AdditionalScopesWithSyntheticExtensions(storageManager: StorageManager) : FileScopeProvider.AdditionalScopes() { diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/JavaResolveExtension.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/JavaResolveExtension.kt index ba0e9518b98..1baf2103b85 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/JavaResolveExtension.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/JavaResolveExtension.kt @@ -45,32 +45,21 @@ public object JavaResolveExtension : CacheExtension<(PsiElement) -> Pair resolver.resolveConstructor(JavaConstructorImpl(method)) else -> resolver.resolveMethod(JavaMethodImpl(method)) } - assert(methodDescriptor != null) { "No descriptor found for " + method.getText() } - - return methodDescriptor!! } -fun PsiClass.getJavaClassDescriptor(): ClassDescriptor { - val resolver = JavaResolveExtension.getResolver(getProject(), this) - val classDescriptor = resolver.resolveClass(JavaClassImpl(this)) - assert(classDescriptor != null) { "No descriptor found for " + getText() } - - return classDescriptor!! +fun PsiClass.getJavaClassDescriptor(): ClassDescriptor? { + return JavaResolveExtension.getResolver(getProject(), this).resolveClass(JavaClassImpl(this)) } -fun PsiField.getJavaFieldDescriptor(): PropertyDescriptor { - val resolver = JavaResolveExtension.getResolver(getProject(), this) - val fieldDescriptor = resolver.resolveField(JavaFieldImpl(this)) - assert(fieldDescriptor != null) { "No descriptor found for " + getText() } - - return fieldDescriptor!! +fun PsiField.getJavaFieldDescriptor(): PropertyDescriptor? { + return JavaResolveExtension.getResolver(getProject(), this).resolveField(JavaFieldImpl(this)) } fun PsiMember.getJavaMemberDescriptor(): DeclarationDescriptor? { diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 8894006e50b..d3edb629a19 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -502,7 +502,7 @@ - + diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/UsePropertyAccessSyntaxIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/UsePropertyAccessSyntaxIntention.kt index 964c9d2412a..6a035528e54 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/UsePropertyAccessSyntaxIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/UsePropertyAccessSyntaxIntention.kt @@ -88,7 +88,7 @@ class UsePropertyAccessSyntaxIntention : JetSelfTargetingOffsetIndependentIntent } private fun findSyntheticProperty(function: FunctionDescriptor, resolutionScope: JetScope): SyntheticExtensionPropertyDescriptor? { - findSyntheticPropertyNoOverriddenCheck(function, resolutionScope)?.let { return it } + SyntheticExtensionPropertyDescriptor.findByGetterOrSetter(function, resolutionScope)?.let { return it } for (overridden in function.getOverriddenDescriptors()) { findSyntheticProperty(overridden, resolutionScope)?.let { return it } @@ -97,15 +97,6 @@ class UsePropertyAccessSyntaxIntention : JetSelfTargetingOffsetIndependentIntent return null } - private fun findSyntheticPropertyNoOverriddenCheck(function: FunctionDescriptor, resolutionScope: JetScope): SyntheticExtensionPropertyDescriptor? { - val owner = function.getContainingDeclaration() - if (owner !is JavaClassDescriptor) return null - - return resolutionScope.getSyntheticExtensionProperties(owner.getDefaultType()) - .filterIsInstance() - .firstOrNull { function == it.getMethod || function == it.setMethod } - } - private fun replaceWithPropertyGet(callExpression: JetCallExpression, propertyName: Name) { val newExpression = JetPsiFactory(callExpression).createExpression(propertyName.render()) callExpression.replace(newExpression) diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeInfo.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeInfo.kt index 0f049551a01..9a15bb58bd2 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeInfo.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeInfo.kt @@ -388,7 +388,7 @@ public fun JetChangeInfo.getAffectedCallables(): Collection = methodD public fun ChangeInfo.toJetChangeInfo(originalChangeSignatureDescriptor: JetMethodDescriptor): JetChangeInfo { val method = getMethod() as PsiMethod - val functionDescriptor = method.getJavaMethodDescriptor() + val functionDescriptor = method.getJavaMethodDescriptor()!! val parameterDescriptors = functionDescriptor.getValueParameters() //noinspection ConstantConditions diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java index fd3bd9db57b..2b5c86bc055 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java @@ -394,6 +394,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro if (!RefactoringPackage.isTrueJavaMethod(method)) return; FunctionDescriptor methodDescriptor = ResolvePackage.getJavaMethodDescriptor((PsiMethod) method); + assert methodDescriptor != null; DeclarationDescriptor containingDescriptor = methodDescriptor.getContainingDeclaration(); if (!(containingDescriptor instanceof JavaClassDescriptor)) return; @@ -958,6 +959,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro boolean startedFromJava = method instanceof PsiMethod; if (startedFromJava && originalJavaMethodDescriptor == null) { FunctionDescriptor methodDescriptor = ResolvePackage.getJavaMethodDescriptor((PsiMethod) method); + assert methodDescriptor != null; originalJavaMethodDescriptor = new JetChangeSignatureData(methodDescriptor, method, Collections.singletonList(methodDescriptor));; diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/ui/KotlinCallerChooser.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/ui/KotlinCallerChooser.kt index 7c71b4f010a..9ee84b4ed31 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/ui/KotlinCallerChooser.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/ui/KotlinCallerChooser.kt @@ -83,7 +83,7 @@ public class KotlinMethodNode( val descriptor = when (myMethod) { is JetFunction -> myMethod.resolveToDescriptor() as FunctionDescriptor is JetClass -> (myMethod.resolveToDescriptor() as ClassDescriptor).getUnsubstitutedPrimaryConstructor() ?: return - is PsiMethod -> myMethod.getJavaMethodDescriptor() + is PsiMethod -> myMethod.getJavaMethodDescriptor() ?: return else -> throw AssertionError("Invalid declaration: ${myMethod.getElementTextWithContext()}") } val containerName = sequence(descriptor) { it.getContainingDeclaration() } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceParameter/KotlinIntroduceParameterMethodUsageProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceParameter/KotlinIntroduceParameterMethodUsageProcessor.kt index ae465fde734..206873cb47f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceParameter/KotlinIntroduceParameterMethodUsageProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceParameter/KotlinIntroduceParameterMethodUsageProcessor.kt @@ -89,7 +89,7 @@ public class KotlinIntroduceParameterMethodUsageProcessor : IntroduceParameterMe val changeInfo = createChangeInfo(data, element) ?: return true // Java method is already updated at this point - val addedParameterType = data.getMethodToReplaceIn().getJavaMethodDescriptor().getValueParameters().last().getType() + val addedParameterType = data.getMethodToReplaceIn().getJavaMethodDescriptor()!!.getValueParameters().last().getType() changeInfo.getNewParameters().last().currentTypeText = IdeDescriptorRenderers.SOURCE_CODE.renderType(addedParameterType) val scope = element.getUseScope().let { diff --git a/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinLightPropertyAccessorsReferenceSearcher.kt b/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinPropertyAccessorsReferenceSearcher.kt similarity index 58% rename from idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinLightPropertyAccessorsReferenceSearcher.kt rename to idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinPropertyAccessorsReferenceSearcher.kt index 91bc4c5a187..c65191aa4b9 100644 --- a/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinLightPropertyAccessorsReferenceSearcher.kt +++ b/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinPropertyAccessorsReferenceSearcher.kt @@ -17,27 +17,27 @@ package org.jetbrains.kotlin.idea.search.ideaExtensions import com.intellij.openapi.application.QueryExecutorBase +import com.intellij.psi.PsiMethod import com.intellij.psi.PsiReference import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.SearchScope import com.intellij.psi.search.UsageSearchContext import com.intellij.psi.search.searches.MethodReferencesSearch import com.intellij.util.Processor -import org.jetbrains.kotlin.idea.JetFileType import org.jetbrains.kotlin.asJava.namedUnwrappedElement +import org.jetbrains.kotlin.idea.JetFileType +import org.jetbrains.kotlin.idea.caches.resolve.getJavaMethodDescriptor import org.jetbrains.kotlin.psi.JetProperty +import org.jetbrains.kotlin.storage.LockBasedStorageManager +import org.jetbrains.kotlin.synthetic.SyntheticExtensionPropertyDescriptor +import org.jetbrains.kotlin.synthetic.SyntheticExtensionsScope -public class KotlinLightPropertyAccessorsReferenceSearcher() : QueryExecutorBase(true) { +public class KotlinPropertyAccessorsReferenceSearcher() : QueryExecutorBase(true) { override fun processQuery(queryParameters: MethodReferencesSearch.SearchParameters, consumer: Processor) { val method = queryParameters.getMethod() - val unwrapped = method.namedUnwrappedElement + val propertyName = propertyName(method) ?: return - if (unwrapped !is JetProperty) return - - val propertyName = unwrapped.getName() - if (propertyName == null) return - - val onlyKotlinFiles = restrictToKotlinSources(queryParameters.getScope()) + val onlyKotlinFiles = restrictToKotlinSources(queryParameters.getEffectiveSearchScope()) queryParameters.getOptimizer()!!.searchWord( propertyName, @@ -47,10 +47,22 @@ public class KotlinLightPropertyAccessorsReferenceSearcher() : QueryExecutorBase method) } - private fun restrictToKotlinSources(originalScope: SearchScope): SearchScope { - if (originalScope is GlobalSearchScope) { - return GlobalSearchScope.getScopeRestrictedByFileTypes(originalScope as GlobalSearchScope, JetFileType.INSTANCE) + private fun propertyName(method: PsiMethod): String? { + val unwrapped = method.namedUnwrappedElement + if (unwrapped is JetProperty) { + return unwrapped.getName() + } + + val functionDescriptor = method.getJavaMethodDescriptor() ?: return null + val syntheticExtensionsScope = SyntheticExtensionsScope(LockBasedStorageManager()) + val property = SyntheticExtensionPropertyDescriptor.findByGetterOrSetter(functionDescriptor, syntheticExtensionsScope) ?: return null + return property.getName().asString() + } + + private fun restrictToKotlinSources(originalScope: SearchScope): SearchScope { + return when (originalScope) { + is GlobalSearchScope -> GlobalSearchScope.getScopeRestrictedByFileTypes(originalScope, JetFileType.INSTANCE) + else -> originalScope } - return originalScope } } diff --git a/idea/testData/findUsages/java/findJavaMethodUsages/SyntheticProperties.0.java b/idea/testData/findUsages/java/findJavaMethodUsages/SyntheticProperties.0.java new file mode 100644 index 00000000000..763832cbb04 --- /dev/null +++ b/idea/testData/findUsages/java/findJavaMethodUsages/SyntheticProperties.0.java @@ -0,0 +1,6 @@ +// PSI_ELEMENT: com.intellij.psi.PsiMethod +// OPTIONS: usages +class JavaClass { + public int getSomething() { return 1; } + public void setSomething(int value) {} +} \ No newline at end of file diff --git a/idea/testData/findUsages/java/findJavaMethodUsages/SyntheticProperties.1.kt b/idea/testData/findUsages/java/findJavaMethodUsages/SyntheticProperties.1.kt new file mode 100644 index 00000000000..f305e8e07e3 --- /dev/null +++ b/idea/testData/findUsages/java/findJavaMethodUsages/SyntheticProperties.1.kt @@ -0,0 +1,5 @@ +fun foo(javaClass: JavaClass) { + print(javaClass.something) + javaClass.something = 1 + javaClass.something++ +} diff --git a/idea/testData/findUsages/java/findJavaMethodUsages/SyntheticProperties.results.txt b/idea/testData/findUsages/java/findJavaMethodUsages/SyntheticProperties.results.txt new file mode 100644 index 00000000000..2be354cdc95 --- /dev/null +++ b/idea/testData/findUsages/java/findJavaMethodUsages/SyntheticProperties.results.txt @@ -0,0 +1,2 @@ +Value read (2: 21) print(javaClass.something) +Value read (4: 15) javaClass.something++ diff --git a/idea/tests/org/jetbrains/kotlin/findUsages/JetFindUsagesTestGenerated.java b/idea/tests/org/jetbrains/kotlin/findUsages/JetFindUsagesTestGenerated.java index cdf5da168d4..dcbe2cdde33 100644 --- a/idea/tests/org/jetbrains/kotlin/findUsages/JetFindUsagesTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/findUsages/JetFindUsagesTestGenerated.java @@ -1250,6 +1250,12 @@ public class JetFindUsagesTestGenerated extends AbstractJetFindUsagesTest { String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/java/findJavaMethodUsages/JKMethodUsages.0.java"); doTest(fileName); } + + @TestMetadata("SyntheticProperties.0.java") + public void testSyntheticProperties() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/java/findJavaMethodUsages/SyntheticProperties.0.java"); + doTest(fileName); + } } } }