From 4cef8728d7f24be9044556e958d5feeb4930da4c Mon Sep 17 00:00:00 2001 From: Vyacheslav Gerasimov Date: Thu, 6 Jul 2017 18:25:19 +0300 Subject: [PATCH] Add layout file name in completion for Android Extension properties #KT-11051 Fixed --- .../completion/BasicLookupElementFactory.kt | 11 +++++ .../CompletionInformationProvider.kt | 29 +++++++++++++ idea/src/META-INF/android.xml | 1 + idea/src/META-INF/extensions/common.xml | 2 + .../android-extensions-idea.iml | 2 +- ...ExtensionsCompletionInformationProvider.kt | 43 +++++++++++++++++++ .../completion/fqNameInAttr/fqNameInAttr.kt | 2 +- .../fqNameInAttrFragment.kt | 2 +- .../completion/fqNameInTag/fqNameInTag.kt | 2 +- .../fqNameInTagFragment.kt | 2 +- .../android/completion/multiFile/multiFile.kt | 3 +- .../multiFileFragment/multiFileFragment.kt | 3 +- .../propertiesSimple/propertiesSimple.kt | 2 +- .../propertiesSimpleFragment.kt | 2 +- .../propertiesSimpleView.kt | 2 +- .../completion/withoutImport/withoutImport.kt | 2 +- 16 files changed, 99 insertions(+), 11 deletions(-) create mode 100644 idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionInformationProvider.kt create mode 100644 plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/AndroidExtensionsCompletionInformationProvider.kt diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicLookupElementFactory.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicLookupElementFactory.kt index 4c9351137c4..5117684c45a 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicLookupElementFactory.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicLookupElementFactory.kt @@ -36,6 +36,7 @@ import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor +import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult class BasicLookupElementFactory( private val project: Project, @@ -246,6 +247,16 @@ class BasicLookupElementFactory( } fun appendContainerAndReceiverInformation(descriptor: CallableDescriptor, appendTailText: (String) -> Unit) { + + val information = CompletionInformationProvider.EP_NAME.extensions.firstNotNullResult { + it.getContainerAndReceiverInformation(descriptor) + } + + if (information != null) { + appendTailText(information) + return + } + val extensionReceiver = descriptor.original.extensionReceiverParameter when { descriptor is SyntheticJavaPropertyDescriptor -> { diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionInformationProvider.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionInformationProvider.kt new file mode 100644 index 00000000000..765003ea095 --- /dev/null +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionInformationProvider.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.completion + +import com.intellij.openapi.extensions.ExtensionPointName +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor + +interface CompletionInformationProvider { + companion object { + val EP_NAME: ExtensionPointName = + ExtensionPointName.create("org.jetbrains.kotlin.completionInformationProvider") + } + + fun getContainerAndReceiverInformation(descriptor: DeclarationDescriptor): String? +} \ No newline at end of file diff --git a/idea/src/META-INF/android.xml b/idea/src/META-INF/android.xml index 701c939623b..2559c55d5bb 100644 --- a/idea/src/META-INF/android.xml +++ b/idea/src/META-INF/android.xml @@ -77,6 +77,7 @@ + diff --git a/idea/src/META-INF/extensions/common.xml b/idea/src/META-INF/extensions/common.xml index 9fd11a78718..2dde12330d3 100644 --- a/idea/src/META-INF/extensions/common.xml +++ b/idea/src/META-INF/extensions/common.xml @@ -45,5 +45,7 @@ interface="org.jetbrains.kotlin.idea.inspections.gradle.KotlinPlatformGradleDetector"/> + diff --git a/plugins/android-extensions/android-extensions-idea/android-extensions-idea.iml b/plugins/android-extensions/android-extensions-idea/android-extensions-idea.iml index cc60f9b6add..443993ce359 100644 --- a/plugins/android-extensions/android-extensions-idea/android-extensions-idea.iml +++ b/plugins/android-extensions/android-extensions-idea/android-extensions-idea.iml @@ -17,7 +17,7 @@ - + diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/AndroidExtensionsCompletionInformationProvider.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/AndroidExtensionsCompletionInformationProvider.kt new file mode 100644 index 00000000000..c3a61b01141 --- /dev/null +++ b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/AndroidExtensionsCompletionInformationProvider.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin + +import com.intellij.psi.xml.XmlAttributeValue +import org.jetbrains.kotlin.android.synthetic.res.AndroidSyntheticProperty +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.idea.completion.CompletionInformationProvider +import org.jetbrains.kotlin.renderer.DescriptorRenderer +import org.jetbrains.kotlin.resolve.source.PsiSourceElement + +class AndroidExtensionsCompletionInformationProvider : CompletionInformationProvider { + override fun getContainerAndReceiverInformation(descriptor: DeclarationDescriptor): String? { + if (descriptor !is AndroidSyntheticProperty) { + return null + } + + val propertyDescriptor = (descriptor as? PropertyDescriptor) ?: return null + val attributeValue = (propertyDescriptor.source as? PsiSourceElement)?.psi as? XmlAttributeValue ?: return null + val extensionReceiverType = propertyDescriptor.original.extensionReceiverParameter?.type + + return buildString { + append(" from ${attributeValue.containingFile.name}") + extensionReceiverType?.let { append(" for " + DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(it)) } + append(" (Android Extensions)") + } + } +} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInAttr/fqNameInAttr.kt b/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInAttr/fqNameInAttr.kt index e75072ebf26..3dcff3a1875 100644 --- a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInAttr/fqNameInAttr.kt +++ b/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInAttr/fqNameInAttr.kt @@ -7,4 +7,4 @@ class MyActivity: Activity() { val button = this.MyBu } -// EXIST: MyButton +// EXIST: { lookupString:"MyButton", tailText: " from layout.xml for Activity (Android Extensions)", typeText:"View!" } diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInAttrFragment/fqNameInAttrFragment.kt b/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInAttrFragment/fqNameInAttrFragment.kt index a98636e363d..b5b2448af2f 100644 --- a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInAttrFragment/fqNameInAttrFragment.kt +++ b/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInAttrFragment/fqNameInAttrFragment.kt @@ -7,4 +7,4 @@ class MyFragment: Fragment() { val button = this.MyBu } -// EXIST: MyButton +// EXIST: { lookupString:"MyButton", tailText: " from layout.xml for Fragment (Android Extensions)", typeText:"View!" } diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInTag/fqNameInTag.kt b/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInTag/fqNameInTag.kt index e75072ebf26..3dcff3a1875 100644 --- a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInTag/fqNameInTag.kt +++ b/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInTag/fqNameInTag.kt @@ -7,4 +7,4 @@ class MyActivity: Activity() { val button = this.MyBu } -// EXIST: MyButton +// EXIST: { lookupString:"MyButton", tailText: " from layout.xml for Activity (Android Extensions)", typeText:"View!" } diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInTagFragment/fqNameInTagFragment.kt b/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInTagFragment/fqNameInTagFragment.kt index a98636e363d..b5b2448af2f 100644 --- a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInTagFragment/fqNameInTagFragment.kt +++ b/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInTagFragment/fqNameInTagFragment.kt @@ -7,4 +7,4 @@ class MyFragment: Fragment() { val button = this.MyBu } -// EXIST: MyButton +// EXIST: { lookupString:"MyButton", tailText: " from layout.xml for Fragment (Android Extensions)", typeText:"View!" } diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/completion/multiFile/multiFile.kt b/plugins/android-extensions/android-extensions-idea/testData/android/completion/multiFile/multiFile.kt index 527a2657889..4a169c10800 100644 --- a/plugins/android-extensions/android-extensions-idea/testData/android/completion/multiFile/multiFile.kt +++ b/plugins/android-extensions/android-extensions-idea/testData/android/completion/multiFile/multiFile.kt @@ -8,4 +8,5 @@ class MyActivity: Activity() { val button = log } -// EXIST: login, loginButton +// EXIST: { lookupString:"login", tailText: " from layout.xml for Activity (Android Extensions)", typeText:"Button!" } +// EXIST: { lookupString:"loginButton", tailText: " from layout1.xml for Activity (Android Extensions)", typeText:"Button!" } diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/completion/multiFileFragment/multiFileFragment.kt b/plugins/android-extensions/android-extensions-idea/testData/android/completion/multiFileFragment/multiFileFragment.kt index 81762a895d4..687cef15adb 100644 --- a/plugins/android-extensions/android-extensions-idea/testData/android/completion/multiFileFragment/multiFileFragment.kt +++ b/plugins/android-extensions/android-extensions-idea/testData/android/completion/multiFileFragment/multiFileFragment.kt @@ -8,4 +8,5 @@ class MyFragment: Fragment() { val button = log } -// EXIST: login, loginButton +// EXIST: { lookupString:"login", tailText: " from layout.xml for Fragment (Android Extensions)", typeText:"Button!" } +// EXIST: { lookupString:"loginButton", tailText: " from layout1.xml for Fragment (Android Extensions)", typeText:"Button!" } \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/completion/propertiesSimple/propertiesSimple.kt b/plugins/android-extensions/android-extensions-idea/testData/android/completion/propertiesSimple/propertiesSimple.kt index 3bcf21476b3..3cb9debe0f5 100644 --- a/plugins/android-extensions/android-extensions-idea/testData/android/completion/propertiesSimple/propertiesSimple.kt +++ b/plugins/android-extensions/android-extensions-idea/testData/android/completion/propertiesSimple/propertiesSimple.kt @@ -7,4 +7,4 @@ class MyActivity: Activity() { val button = this.login } -// EXIST: login +// EXIST: { lookupString:"login", tailText: " from layout.xml for Activity (Android Extensions)", typeText:"Button!" } diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/completion/propertiesSimpleFragment/propertiesSimpleFragment.kt b/plugins/android-extensions/android-extensions-idea/testData/android/completion/propertiesSimpleFragment/propertiesSimpleFragment.kt index 6e8a8826b71..d4e94b43ef0 100644 --- a/plugins/android-extensions/android-extensions-idea/testData/android/completion/propertiesSimpleFragment/propertiesSimpleFragment.kt +++ b/plugins/android-extensions/android-extensions-idea/testData/android/completion/propertiesSimpleFragment/propertiesSimpleFragment.kt @@ -7,4 +7,4 @@ class MyFragment: Fragment() { val button = this.login } -// EXIST: login +// EXIST: { lookupString:"login", tailText: " from layout.xml for Fragment (Android Extensions)", typeText:"Button!" } diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/completion/propertiesSimpleView/propertiesSimpleView.kt b/plugins/android-extensions/android-extensions-idea/testData/android/completion/propertiesSimpleView/propertiesSimpleView.kt index a0e395b72db..169836747a2 100644 --- a/plugins/android-extensions/android-extensions-idea/testData/android/completion/propertiesSimpleView/propertiesSimpleView.kt +++ b/plugins/android-extensions/android-extensions-idea/testData/android/completion/propertiesSimpleView/propertiesSimpleView.kt @@ -7,4 +7,4 @@ fun View.a() { val button = this.login } -// EXIST: login +// EXIST: { lookupString:"login", tailText: " from layout.xml for View (Android Extensions)", typeText:"Button!" } diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/completion/withoutImport/withoutImport.kt b/plugins/android-extensions/android-extensions-idea/testData/android/completion/withoutImport/withoutImport.kt index 0905421dc6b..511096f89aa 100644 --- a/plugins/android-extensions/android-extensions-idea/testData/android/completion/withoutImport/withoutImport.kt +++ b/plugins/android-extensions/android-extensions-idea/testData/android/completion/withoutImport/withoutImport.kt @@ -6,4 +6,4 @@ class MyActivity: Activity() { val button = this.login } -// EXIST: login +// EXIST: { lookupString:"login", tailText: " from layout.xml for Activity (Android Extensions)", typeText:"Button!" }