diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractionData.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractionData.kt index f3f1edbef97..bc553b43233 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractionData.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractionData.kt @@ -28,7 +28,6 @@ import org.jetbrains.kotlin.idea.codeInsight.JetFileReferencesResolver import org.jetbrains.kotlin.idea.core.compareDescriptors import org.jetbrains.kotlin.idea.core.refactoring.getContextForContainingDeclarationBody import org.jetbrains.kotlin.idea.util.psi.patternMatching.JetPsiRange -import org.jetbrains.kotlin.idea.util.psi.patternMatching.JetPsiUnifier import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType @@ -44,6 +43,8 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory import org.jetbrains.kotlin.resolve.calls.tasks.isSynthesizedInvoke import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver +import org.jetbrains.kotlin.resolve.source.getPsi +import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor import org.jetbrains.kotlin.types.JetType import java.util.* @@ -125,6 +126,20 @@ data class ExtractionData( return function == null || !function.isInsideOf(originalElements) } + fun getSyntheticPropertyAccessorDeclarationIfAny(descriptor: DeclarationDescriptor): PsiNameIdentifierOwner? { + return (descriptor as? SyntheticJavaPropertyDescriptor ?: return null).getMethod.source.getPsi() as? PsiNameIdentifierOwner + } + + fun getDeclaration(descriptor: DeclarationDescriptor, context: BindingContext): PsiNameIdentifierOwner? { + (DescriptorToSourceUtilsIde.getAnyDeclaration(project, descriptor) as? PsiNameIdentifierOwner)?.let { return it } + + return when { + isExtractableIt(descriptor, context) -> itFakeDeclaration + isSynthesizedInvoke(descriptor) -> synthesizedInvokeDeclaration + else -> getSyntheticPropertyAccessorDeclarationIfAny(descriptor) + } + } + val originalStartOffset = originalStartOffset val context = bindingContext @@ -147,9 +162,7 @@ data class ExtractionData( val resolvedCall = ref.getResolvedCall(context) val descriptor = context[BindingContext.REFERENCE_TARGET, ref] ?: return - val declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, descriptor) as? PsiNameIdentifierOwner - ?: if (isExtractableIt(descriptor, context)) itFakeDeclaration - else if (isSynthesizedInvoke(descriptor)) synthesizedInvokeDeclaration else return + val declaration = getDeclaration(descriptor, context) ?: return val offset = ref.getTextRange()!!.getStartOffset() - originalStartOffset resultMap[offset] = ResolveResult(ref, declaration, descriptor, resolvedCall) diff --git a/idea/testData/refactoring/extractFunction/parameters/extractThis/javaSyntheticProperty.java b/idea/testData/refactoring/extractFunction/parameters/extractThis/javaSyntheticProperty.java new file mode 100644 index 00000000000..b37222cd4d2 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/parameters/extractThis/javaSyntheticProperty.java @@ -0,0 +1,6 @@ +import org.jetbrains.annotations.NotNull; + +interface Named { + @NotNull + String getName(); +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/parameters/extractThis/javaSyntheticProperty.kt b/idea/testData/refactoring/extractFunction/parameters/extractThis/javaSyntheticProperty.kt new file mode 100644 index 00000000000..708269882a2 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/parameters/extractThis/javaSyntheticProperty.kt @@ -0,0 +1,6 @@ +// WITH_RUNTIME +// PARAM_DESCRIPTOR: private final fun Named.foo(): [org.jetbrains.annotations.NotNull] String defined in Test +// PARAM_TYPES: Named +public class Test { + private fun Named.foo() = name +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/parameters/extractThis/javaSyntheticProperty.kt.after b/idea/testData/refactoring/extractFunction/parameters/extractThis/javaSyntheticProperty.kt.after new file mode 100644 index 00000000000..596664c23f5 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/parameters/extractThis/javaSyntheticProperty.kt.after @@ -0,0 +1,8 @@ +// WITH_RUNTIME +// PARAM_DESCRIPTOR: private final fun Named.foo(): [org.jetbrains.annotations.NotNull] String defined in Test +// PARAM_TYPES: Named +public class Test { + private fun Named.foo() = s() + + private fun Named.s() = name +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java index 338107f45e4..1a4a7dcd10b 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java @@ -1991,6 +1991,12 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest { doExtractFunctionTest(fileName); } + @TestMetadata("javaSyntheticProperty.kt") + public void testJavaSyntheticProperty() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/extractThis/javaSyntheticProperty.kt"); + doExtractFunctionTest(fileName); + } + @TestMetadata("missingReceiver.kt") public void testMissingReceiver() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/extractThis/missingReceiver.kt");