From fb3efd2d789dadb9580c78f47737f31f963540d5 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Tue, 19 Mar 2019 20:31:11 +0300 Subject: [PATCH] Debugger: Fix completion for synthetic '_field' extension properties (KT-23586) --- .../codeFragments/syntheticFieldProperties.kt | 12 +++++++ .../syntheticFieldProperties.kt.fragment | 1 + .../kotlin/idea/core/KotlinIndicesHelper.kt | 4 ++- .../extension/KotlinIndicesHelperExtension.kt | 14 +++++--- ...buggerFieldKotlinIndicesHelperExtension.kt | 34 +++++++++++++++++++ .../DebuggerFieldSyntheticScopeProvider.kt | 2 +- idea/resources/META-INF/jvm.xml | 1 + idea/resources/META-INF/jvm.xml.181 | 1 + idea/resources/META-INF/jvm.xml.182 | 1 + idea/resources/META-INF/jvm.xml.191 | 1 + .../CodeFragmentCompletionTestGenerated.java | 5 +++ .../idea/AndroidIndicesHelperExtension.kt | 10 +++--- 12 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 idea/idea-completion/testData/basic/codeFragments/syntheticFieldProperties.kt create mode 100644 idea/idea-completion/testData/basic/codeFragments/syntheticFieldProperties.kt.fragment create mode 100644 idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/evaluate/DebuggerFieldKotlinIndicesHelperExtension.kt diff --git a/idea/idea-completion/testData/basic/codeFragments/syntheticFieldProperties.kt b/idea/idea-completion/testData/basic/codeFragments/syntheticFieldProperties.kt new file mode 100644 index 00000000000..aee4cce8cd4 --- /dev/null +++ b/idea/idea-completion/testData/basic/codeFragments/syntheticFieldProperties.kt @@ -0,0 +1,12 @@ +class Foo { + val foo: Int = 3 + get() = field + 1 + + fun foo() { + + } +} + +// INVOCATION_COUNT: 1 +// EXIST: foo +// EXIST: foo_field \ No newline at end of file diff --git a/idea/idea-completion/testData/basic/codeFragments/syntheticFieldProperties.kt.fragment b/idea/idea-completion/testData/basic/codeFragments/syntheticFieldProperties.kt.fragment new file mode 100644 index 00000000000..86ce433a762 --- /dev/null +++ b/idea/idea-completion/testData/basic/codeFragments/syntheticFieldProperties.kt.fragment @@ -0,0 +1 @@ +this.f \ No newline at end of file diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt index 48e3698ca86..a704d9a789c 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt @@ -40,6 +40,7 @@ import org.jetbrains.kotlin.idea.util.CallType import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver import org.jetbrains.kotlin.idea.util.receiverTypes import org.jetbrains.kotlin.idea.util.substituteExtensionIfCallable +import org.jetbrains.kotlin.incremental.KotlinLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.load.java.sam.SamAdapterDescriptor @@ -169,8 +170,9 @@ class KotlinIndicesHelper( val additionalDescriptors = ArrayList(0) + val lookupLocation = this.file?.let { KotlinLookupLocation(it) } ?: NoLookupLocation.FROM_IDE for (extension in KotlinIndicesHelperExtension.getInstances(project)) { - extension.appendExtensionCallables(additionalDescriptors, moduleDescriptor, receiverTypes, nameFilter) + extension.appendExtensionCallables(additionalDescriptors, moduleDescriptor, receiverTypes, nameFilter, lookupLocation) } return if (additionalDescriptors.isNotEmpty()) diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/extension/KotlinIndicesHelperExtension.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/extension/KotlinIndicesHelperExtension.kt index 68c0b601a6f..fe755a0d0e1 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/extension/KotlinIndicesHelperExtension.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/extension/KotlinIndicesHelperExtension.kt @@ -19,15 +19,19 @@ package org.jetbrains.kotlin.idea.core.extension import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor +import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.types.KotlinType interface KotlinIndicesHelperExtension { companion object : ProjectExtensionDescriptor( - "org.jetbrains.kotlin.kotlinIndicesHelperExtension", KotlinIndicesHelperExtension::class.java) + "org.jetbrains.kotlin.kotlinIndicesHelperExtension", KotlinIndicesHelperExtension::class.java + ) fun appendExtensionCallables( - consumer: MutableList, - moduleDescriptor: ModuleDescriptor, - receiverTypes: Collection, - nameFilter: (String) -> Boolean) + consumer: MutableList, + moduleDescriptor: ModuleDescriptor, + receiverTypes: Collection, + nameFilter: (String) -> Boolean, + lookupLocation: LookupLocation + ) } \ No newline at end of file diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/evaluate/DebuggerFieldKotlinIndicesHelperExtension.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/evaluate/DebuggerFieldKotlinIndicesHelperExtension.kt new file mode 100644 index 00000000000..d94e27ebe96 --- /dev/null +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/evaluate/DebuggerFieldKotlinIndicesHelperExtension.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.debugger.evaluate + +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.idea.core.extension.KotlinIndicesHelperExtension +import org.jetbrains.kotlin.incremental.components.LookupLocation +import org.jetbrains.kotlin.incremental.components.LookupTracker +import org.jetbrains.kotlin.storage.LockBasedStorageManager +import org.jetbrains.kotlin.synthetic.JavaSyntheticPropertiesScope +import org.jetbrains.kotlin.types.KotlinType + +class DebuggerFieldKotlinIndicesHelperExtension : KotlinIndicesHelperExtension { + override fun appendExtensionCallables( + consumer: MutableList, + moduleDescriptor: ModuleDescriptor, + receiverTypes: Collection, + nameFilter: (String) -> Boolean, + lookupLocation: LookupLocation + ) { + val javaPropertiesScope = JavaSyntheticPropertiesScope(LockBasedStorageManager.NO_LOCKS, LookupTracker.DO_NOTHING) + val fieldScope = DebuggerFieldSyntheticScope(javaPropertiesScope) + + for (property in fieldScope.getSyntheticExtensionProperties(receiverTypes, lookupLocation)) { + if (nameFilter(property.name.asString())) { + consumer += property + } + } + } +} \ No newline at end of file diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/evaluate/DebuggerFieldSyntheticScopeProvider.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/evaluate/DebuggerFieldSyntheticScopeProvider.kt index d60dd7eae32..a8646ad1a84 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/evaluate/DebuggerFieldSyntheticScopeProvider.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/evaluate/DebuggerFieldSyntheticScopeProvider.kt @@ -46,7 +46,7 @@ class DebuggerFieldSyntheticScopeProvider : SyntheticScopeProviderExtension { } } -private class DebuggerFieldSyntheticScope(val javaSyntheticPropertiesScope: JavaSyntheticPropertiesScope) : SyntheticScope.Default() { +class DebuggerFieldSyntheticScope(val javaSyntheticPropertiesScope: JavaSyntheticPropertiesScope) : SyntheticScope.Default() { private val javaSourceElementFactory = JavaSourceElementFactoryImpl() override fun getSyntheticExtensionProperties( diff --git a/idea/resources/META-INF/jvm.xml b/idea/resources/META-INF/jvm.xml index b11b2297593..d5c501d1cd4 100644 --- a/idea/resources/META-INF/jvm.xml +++ b/idea/resources/META-INF/jvm.xml @@ -202,5 +202,6 @@ + diff --git a/idea/resources/META-INF/jvm.xml.181 b/idea/resources/META-INF/jvm.xml.181 index f8c8d5b573e..f3944ae13db 100644 --- a/idea/resources/META-INF/jvm.xml.181 +++ b/idea/resources/META-INF/jvm.xml.181 @@ -187,5 +187,6 @@ + diff --git a/idea/resources/META-INF/jvm.xml.182 b/idea/resources/META-INF/jvm.xml.182 index fe3e090b5dd..e0ed23dbff8 100644 --- a/idea/resources/META-INF/jvm.xml.182 +++ b/idea/resources/META-INF/jvm.xml.182 @@ -201,5 +201,6 @@ + diff --git a/idea/resources/META-INF/jvm.xml.191 b/idea/resources/META-INF/jvm.xml.191 index 528b485ded4..b21476dcad2 100644 --- a/idea/resources/META-INF/jvm.xml.191 +++ b/idea/resources/META-INF/jvm.xml.191 @@ -207,5 +207,6 @@ + diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/CodeFragmentCompletionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/CodeFragmentCompletionTestGenerated.java index 63060a9b4d3..442ef3a632a 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/CodeFragmentCompletionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/CodeFragmentCompletionTestGenerated.java @@ -74,6 +74,11 @@ public class CodeFragmentCompletionTestGenerated extends AbstractCodeFragmentCom runTest("idea/idea-completion/testData/basic/codeFragments/privatesInSecondPressCompletion.kt"); } + @TestMetadata("syntheticFieldProperties.kt") + public void testSyntheticFieldProperties() throws Exception { + runTest("idea/idea-completion/testData/basic/codeFragments/syntheticFieldProperties.kt"); + } + @TestMetadata("topLevel.kt") public void testTopLevel() throws Exception { runTest("idea/idea-completion/testData/basic/codeFragments/topLevel.kt"); diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidIndicesHelperExtension.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidIndicesHelperExtension.kt index 2c76f9845a0..9486425579a 100644 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidIndicesHelperExtension.kt +++ b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidIndicesHelperExtension.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.android.synthetic.descriptors.PredefinedPackageFragm import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.idea.core.extension.KotlinIndicesHelperExtension +import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope @@ -29,10 +30,11 @@ import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf class AndroidIndicesHelperExtension : KotlinIndicesHelperExtension { override fun appendExtensionCallables( - consumer: MutableList, - moduleDescriptor: ModuleDescriptor, - receiverTypes: Collection, - nameFilter: (String) -> Boolean + consumer: MutableList, + moduleDescriptor: ModuleDescriptor, + receiverTypes: Collection, + nameFilter: (String) -> Boolean, + lookupLocation: LookupLocation ) { for (packageFragment in moduleDescriptor.getPackage(FqName(AndroidConst.SYNTHETIC_PACKAGE)).fragments) { if (packageFragment !is PredefinedPackageFragmentDescriptor) continue