Presentation: Render function signature in RefactoringDescriptionLocation

#KT-12943 Fixed
This commit is contained in:
Alexey Sedunov
2016-07-22 13:59:14 +03:00
parent 892c8436f3
commit 59a714ca5c
22 changed files with 51 additions and 41 deletions
+1
View File
@@ -242,6 +242,7 @@ Using 'this' as function argument in constructor of non-final class
- [`KT-13207`](https://youtrack.jetbrains.com/issue/KT-13207) Safe delete: Fix exception when removing any function in 2016.2
- [`KT-12945`](https://youtrack.jetbrains.com/issue/KT-12945) Rename: Fix function description in super method warning dialog
- [`KT-12922`](https://youtrack.jetbrains.com/issue/KT-12922) Introduce Variable: Do not suggest expressions without type
- [`KT-12943`](https://youtrack.jetbrains.com/issue/KT-12943) Rename: Show function signatures in "Rename Overloads" dialog
##### New features
@@ -190,6 +190,7 @@ interface DescriptorRendererOptions {
var renderAccessors: Boolean
var renderDefaultAnnotationArguments: Boolean
var alwaysRenderModifiers: Boolean
var renderConstructorKeyword: Boolean
}
object ExcludedTypeAnnotations {
@@ -626,10 +626,14 @@ internal class DescriptorRendererImpl(
renderVisibility(constructor.visibility, builder)
renderMemberKind(constructor, builder)
builder.append(renderKeyword("constructor"))
if (renderConstructorKeyword) {
builder.append(renderKeyword("constructor"))
}
if (secondaryConstructorsAsPrimary) {
val classDescriptor = constructor.containingDeclaration
builder.append(" ")
if (renderConstructorKeyword) {
builder.append(" ")
}
renderName(classDescriptor, builder)
renderTypeParameters(constructor.typeParameters, builder, false)
}
@@ -97,4 +97,6 @@ internal class DescriptorRendererOptionsImpl : DescriptorRendererOptions {
+ ExcludedTypeAnnotations.internalAnnotationsForResolve)
override var alwaysRenderModifiers by property(false)
override var renderConstructorKeyword by property(true)
}
@@ -28,16 +28,24 @@ import com.intellij.usageView.UsageViewShortNameLocation
import com.intellij.usageView.UsageViewTypeLocation
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.unwrapped
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.refactoring.rename.RenameJavaSyntheticPropertyHandler
import org.jetbrains.kotlin.idea.refactoring.rename.RenameKotlinPropertyProcessor
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
class KotlinElementDescriptionProvider : ElementDescriptionProvider {
companion object {
val REFACTORING_RENDERER = DescriptorRenderer.ONLY_NAMES_WITH_SHORT_TYPES.withOptions {
withoutReturnType = true
renderConstructorKeyword = false
}
}
override fun getElementDescription(element: PsiElement, location: ElementDescriptionLocation): String? {
val shouldUnwrap = location !is UsageViewShortNameLocation && location !is UsageViewLongNameLocation
val targetElement = if (shouldUnwrap) element.unwrapped ?: element else element
@@ -57,34 +65,31 @@ class KotlinElementDescriptionProvider : ElementDescriptionProvider {
else -> null
}
fun targetDescriptor(): DeclarationDescriptor? {
val descriptor = (targetElement as KtDeclaration).descriptor ?: return null
if (descriptor is ConstructorDescriptor) {
return descriptor.containingDeclaration
}
return descriptor
}
if (targetElement !is PsiNamedElement || targetElement.language != KotlinLanguage.INSTANCE) return null
return when(location) {
is UsageViewTypeLocation -> elementKind()
is UsageViewShortNameLocation, is UsageViewLongNameLocation -> targetElement.name
is RefactoringDescriptionLocation -> {
val kind = elementKind() ?: return null
val descriptor = targetDescriptor() ?: return null
val desc =
if (location.includeParent() && targetElement !is KtTypeParameter && targetElement !is KtParameter) {
DescriptorUtils.getFqName(descriptor).asString()
}
else {
descriptor.name.asString()
}
val descriptor = (targetElement as KtDeclaration).descriptor ?: return null
val renderFqName = location.includeParent() &&
targetElement !is KtTypeParameter &&
targetElement !is KtParameter &&
targetElement !is KtConstructor<*>
val desc = when (descriptor) {
is FunctionDescriptor -> {
val baseText = REFACTORING_RENDERER.render(descriptor)
val parentFqName = if (renderFqName) descriptor.containingDeclaration.fqNameSafe else null
if (parentFqName?.isRoot ?: true) baseText else "${parentFqName!!.asString()}.$baseText"
}
else -> if (renderFqName) DescriptorUtils.getFqName(descriptor).asString() else descriptor.name.asString()
}
"$kind ${CommonRefactoringUtil.htmlEmphasize(desc)}"
}
is HighlightUsagesDescriptionLocation -> {
val kind = elementKind() ?: return null
val descriptor = targetDescriptor() ?: return null
val descriptor = (targetElement as KtDeclaration).descriptor ?: return null
"$kind ${descriptor.name.asString()}"
}
else -> null
@@ -251,10 +251,7 @@ class MoveKotlinDeclarationsProcessor(
}
}
fun render(declaration: PsiElement): String {
val text = RefactoringUIUtil.getDescription(declaration, false)
return if (declaration is KtFunction) "$text()" else text
}
fun render(declaration: PsiElement) = RefactoringUIUtil.getDescription(declaration, false)
fun checkVisibilityInUsages(usages: List<UsageInfo>) {
val declarationToContainers = HashMap<KtNamedDeclaration, MutableSet<PsiElement>>()
@@ -1,4 +1,4 @@
// SHOULD_FAIL_WITH: Function foo already exists
// SHOULD_FAIL_WITH: Function foo() on A already exists
class A(val n: Int) {
val <caret>foo: Boolean = n > 1
}
@@ -1,4 +1,4 @@
// SHOULD_FAIL_WITH: Function <b><code>foo</code></b> is overridden by declaration(s) in a subclass
// SHOULD_FAIL_WITH: Function <b><code>foo()</code></b> is overridden by declaration(s) in a subclass
open class A {
open fun <caret>foo() {
@@ -1 +1 @@
Function length will no longer be accessible after signature change
Function length() will no longer be accessible after signature change
@@ -1 +1 @@
Function foo.bar will no longer be accessible after extraction
Function foo.bar() will no longer be accessible after extraction
@@ -1 +1 @@
Function foo.bar will no longer be accessible after extraction
Function foo.bar() will no longer be accessible after extraction
@@ -1 +1 @@
Function A.unresolved will no longer be accessible after extraction
Function A.unresolved() on B will no longer be accessible after extraction
@@ -1,4 +1,4 @@
Class Test uses class Foo which will be inaccessible after move
Class Test uses function foo() which will be inaccessible after move
Class Test uses function foo(Foo) which will be inaccessible after move
Method bar() uses class Test which will be inaccessible after move
Variable t uses class Test which will be inaccessible after move
@@ -1,4 +1,4 @@
Function bar() uses function test() which will be inaccessible after move
Function test() uses class Foo which will be inaccessible after move
Function test() uses function foo() which will be inaccessible after move
Function test() uses function foo(Foo) which will be inaccessible after move
Method bar() uses function test() which will be inaccessible after move
@@ -1,4 +1,4 @@
Method bar() uses object Test which will be inaccessible after move
Object Test uses class Foo which will be inaccessible after move
Object Test uses function foo() which will be inaccessible after move
Object Test uses function foo(Foo) which will be inaccessible after move
Variable t uses object Test which will be inaccessible after move
@@ -1,4 +1,4 @@
Function bar() uses property test which will be inaccessible after move
Method bar() uses property test which will be inaccessible after move
Property test uses class Foo which will be inaccessible after move
Property test uses function foo() which will be inaccessible after move
Property test uses function foo(Foo) which will be inaccessible after move
@@ -1 +1 @@
function test.foo has 1 usage that is not safe to delete.
function test.foo() has 1 usage that is not safe to delete.
@@ -1 +1 @@
function test.foo has 1 usage that is not safe to delete.
function test.foo() on B has 1 usage that is not safe to delete.
@@ -1 +1 @@
function foo.bar has 1 usage that is not safe to delete.
function foo.bar() has 1 usage that is not safe to delete.
@@ -1 +1 @@
function foo.bar has 1 usage that is not safe to delete.
function foo.bar() on String has 1 usage that is not safe to delete.
@@ -1 +1 @@
function test.foo has 1 usage that is not safe to delete.
function test.foo() on String has 1 usage that is not safe to delete.
@@ -1 +1 @@
constructor B has 5 usages that are not safe to delete.
constructor B(Int) has 5 usages that are not safe to delete.