From 8e9f32db9e3e83c2b56ff6722bf3fc8794e2718b Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Mon, 3 Oct 2016 20:25:10 +0300 Subject: [PATCH] Search Everywhere: Render function parameter types. Render extension type in prefix position #KT-13976 Fixed #KT-13977 Fixed --- ChangeLog.md | 2 + idea/src/META-INF/plugin.xml | 1 + .../goto/KotlinSearchEverywhereClassifier.kt | 37 +++++++++ .../idea/goto/SearchEverywherePsiRenderer.kt | 80 +++++++++++++++++++ .../idea/refactoring/kotlinRefactoringUtil.kt | 2 + 5 files changed, 122 insertions(+) create mode 100644 idea/src/org/jetbrains/kotlin/idea/goto/KotlinSearchEverywhereClassifier.kt create mode 100644 idea/src/org/jetbrains/kotlin/idea/goto/SearchEverywherePsiRenderer.kt diff --git a/ChangeLog.md b/ChangeLog.md index d7ff2d59219..41a5e3a329b 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -199,6 +199,8 @@ These artifacts include extensions for the types available in the latter JDKs, s - [`KT-12556`](https://youtrack.jetbrains.com/issue/KT-12556) Allow using whitespaces and other symbols in "Generate -> Test Function" dialog - [`KT-14122`](https://youtrack.jetbrains.com/issue/KT-14122) Generate 'toString()': Permit for data classes - [`KT-12398`](https://youtrack.jetbrains.com/issue/KT-12398) Call Hierarchy: Show Kotlin usages of Java methods +- [`KT-13976`](https://youtrack.jetbrains.com/issue/KT-13976) Search Everywhere: Render function parameter types +- [`KT-13977`](https://youtrack.jetbrains.com/issue/KT-13977) Search Everywhere: Render extension type in prefix position #### Intention actions, inspections and quickfixes diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 56a953c364b..9ad15aa8f07 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -301,6 +301,7 @@ + diff --git a/idea/src/org/jetbrains/kotlin/idea/goto/KotlinSearchEverywhereClassifier.kt b/idea/src/org/jetbrains/kotlin/idea/goto/KotlinSearchEverywhereClassifier.kt new file mode 100644 index 00000000000..2c4f91dd747 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/goto/KotlinSearchEverywhereClassifier.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2010-2016 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.goto + +import com.intellij.ide.actions.SearchEverywhereClassifier +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.psi.KtNamedDeclaration +import java.awt.Component +import javax.swing.JList + +class KotlinSearchEverywhereClassifier : SearchEverywhereClassifier { + override fun isClass(o: Any?) = o is KtClassOrObject + + override fun isSymbol(o: Any?) = o is KtNamedDeclaration + + override fun getVirtualFile(o: Any) = (o as? PsiElement)?.containingFile?.virtualFile + + override fun getListCellRendererComponent(list: JList<*>, value: Any?, index: Int, isSelected: Boolean, cellHasFocus: Boolean): Component? { + if (value !is PsiElement) return null + return KotlinSearchEverywherePsiRenderer(list).getListCellRendererComponent(list, value, index, isSelected, isSelected) + } +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/goto/SearchEverywherePsiRenderer.kt b/idea/src/org/jetbrains/kotlin/idea/goto/SearchEverywherePsiRenderer.kt new file mode 100644 index 00000000000..22f7902615f --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/goto/SearchEverywherePsiRenderer.kt @@ -0,0 +1,80 @@ +/* + * Copyright 2010-2016 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.goto + +import com.intellij.ide.util.DefaultPsiElementCellRenderer +import com.intellij.openapi.util.text.StringUtil +import com.intellij.psi.PsiElement +import com.intellij.psi.presentation.java.SymbolPresentationUtil +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor +import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers +import org.jetbrains.kotlin.psi.KtNamedFunction +import org.jetbrains.kotlin.renderer.ParameterNameRenderingPolicy +import java.util.* +import javax.swing.JList + +class KotlinSearchEverywherePsiRenderer(private val list: JList<*>) : DefaultPsiElementCellRenderer() { + private val RENDERER = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.withOptions { + parameterNameRenderingPolicy = ParameterNameRenderingPolicy.NONE + modifiers = emptySet() + startFromName = false + } + + override fun getElementText(element: PsiElement?): String { + if (element is KtNamedFunction) { + val descriptor = element.resolveToDescriptor() as FunctionDescriptor + return buildString { + descriptor.extensionReceiverParameter?.let { append(RENDERER.renderType(it.type)).append('.') } + append(element.name) + descriptor.valueParameters.joinTo(this, prefix = "(", postfix = ")") { RENDERER.renderType(it.type) } + } + } + return super.getElementText(element) + } + + // Mostly copied from SearchEverywherePsiRenderer + override fun getContainerText(element: PsiElement?, name: String?): String? { + var text = SymbolPresentationUtil.getSymbolContainerText(element) ?: return null + if (list.width == 0) return text + + if (text.startsWith("(") && text.endsWith(")")) { + text = text.substring(1, text.length - 1) + } + + val inIndex = text.indexOf("in ") + if (inIndex >= 0) text = text.substring(inIndex + 3) + val fm = list.getFontMetrics(list.font) + val maxWidth = list.width - fm.stringWidth(name) - 16 - myRightComponentWidth - 20 + val left = if (inIndex >= 0) "(in " else "(" + val right = ")" + + if (fm.stringWidth(left + text + right) < maxWidth) return left + text + right + val parts = LinkedList(StringUtil.split(text, ".")) + var index: Int + while (parts.size > 1) { + index = parts.size / 2 - 1 + parts.removeAt(index) + if (fm.stringWidth(StringUtil.join(parts, ".") + "...") < maxWidth) { + parts.add(index, if (index == 0) "..." else ".") + return left + StringUtil.join(parts, ".") + right + } + } + + return left + "..." + right + } +} diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt index 6c5e7cc5d7d..537d3d04f03 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt @@ -137,6 +137,8 @@ fun VirtualFile.toPsiFile(project: Project): PsiFile? = PsiManager.getInstance(p fun VirtualFile.toPsiDirectory(project: Project): PsiDirectory? = PsiManager.getInstance(project).findDirectory(this) +fun VirtualFile.toPsiFileOrDirectory(project: Project): PsiFileSystemItem? = if (isDirectory) toPsiDirectory(project) else toPsiFile(project) + fun PsiElement.getUsageContext(): PsiElement { return when (this) { is KtElement -> PsiTreeUtil.getParentOfType(this, KtPropertyAccessor::class.java, KtNamedDeclaration::class.java, KtFile::class.java)!!