ReplaceGetIntention should not be available for non-operator functions

This commit is contained in:
Valentin Kipyatkov
2015-10-16 21:54:15 +03:00
parent 45389c61b4
commit 50f559a1c8
27 changed files with 54 additions and 26 deletions
@@ -19,20 +19,26 @@ package org.jetbrains.kotlin.idea.intentions.conventionNameCalls
import com.intellij.codeInsight.intention.HighPriorityAction import com.intellij.codeInsight.intention.HighPriorityAction
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
import org.jetbrains.kotlin.idea.intentions.JetSelfTargetingRangeIntention import org.jetbrains.kotlin.idea.intentions.JetSelfTargetingRangeIntention
import org.jetbrains.kotlin.idea.intentions.callExpression import org.jetbrains.kotlin.idea.intentions.callExpression
import org.jetbrains.kotlin.idea.intentions.calleeName
import org.jetbrains.kotlin.idea.intentions.isReceiverExpressionWithValue import org.jetbrains.kotlin.idea.intentions.isReceiverExpressionWithValue
import org.jetbrains.kotlin.idea.intentions.toResolvedCall
import org.jetbrains.kotlin.psi.JetDotQualifiedExpression import org.jetbrains.kotlin.psi.JetDotQualifiedExpression
import org.jetbrains.kotlin.psi.JetPsiFactory import org.jetbrains.kotlin.psi.JetPsiFactory
import org.jetbrains.kotlin.psi.buildExpression import org.jetbrains.kotlin.psi.buildExpression
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
public class ExplicitGetInspection : IntentionBasedInspection<JetDotQualifiedExpression>(ReplaceGetIntention()) public class ExplicitGetInspection : IntentionBasedInspection<JetDotQualifiedExpression>(ReplaceGetIntention())
public class ReplaceGetIntention : JetSelfTargetingRangeIntention<JetDotQualifiedExpression>(javaClass(), "Replace 'get' call with index operator"), HighPriorityAction { public class ReplaceGetIntention : JetSelfTargetingRangeIntention<JetDotQualifiedExpression>(javaClass(), "Replace 'get' call with index operator"), HighPriorityAction {
override fun applicabilityRange(element: JetDotQualifiedExpression): TextRange? { override fun applicabilityRange(element: JetDotQualifiedExpression): TextRange? {
if (element.calleeName != "get") return null val resolvedCall = element.toResolvedCall() ?: return null
if (!resolvedCall.isReallySuccess()) return null
val target = resolvedCall.resultingDescriptor as? FunctionDescriptor ?: return null
if (target.name.asString() != "get" || !target.isOperator) return null
val call = element.callExpression ?: return null val call = element.callExpression ?: return null
if (call.getTypeArgumentList() != null) return null if (call.getTypeArgumentList() != null) return null
@@ -46,6 +52,10 @@ public class ReplaceGetIntention : JetSelfTargetingRangeIntention<JetDotQualifie
} }
override fun applyTo(element: JetDotQualifiedExpression, editor: Editor) { override fun applyTo(element: JetDotQualifiedExpression, editor: Editor) {
applyTo(element)
}
fun applyTo(element: JetDotQualifiedExpression) {
val expression = JetPsiFactory(element).buildExpression { val expression = JetPsiFactory(element).buildExpression {
appendExpression(element.getReceiverExpression()) appendExpression(element.getReceiverExpression())
@@ -1,6 +1,6 @@
fun test() { fun test() {
class Test{ class Test{
fun get(a: Int, vararg b: Int, c: Int = 0) : Int = 0 operator fun get(a: Int, vararg b: Int, c: Int = 0) : Int = 0
} }
val test = Test() val test = Test()
test.g<caret>et(1, 3, 4, 5) test.g<caret>et(1, 3, 4, 5)
@@ -1,6 +1,6 @@
fun test() { fun test() {
class Test{ class Test{
fun get(a: Int, vararg b: Int, c: Int = 0) : Int = 0 operator fun get(a: Int, vararg b: Int, c: Int = 0) : Int = 0
} }
val test = Test() val test = Test()
test[1, 3, 4, 5] test[1, 3, 4, 5]
@@ -1,6 +1,6 @@
fun test() { fun test() {
class Test{ class Test{
fun get(a: Int, b: Int, fn: (i: Int) -> Int) : Int = 0 operator fun get(a: Int, b: Int, fn: (i: Int) -> Int) : Int = 0
} }
val test = Test() val test = Test()
test.g<caret>et(1, 2) { i -> test.g<caret>et(1, 2) { i ->
@@ -1,6 +1,6 @@
fun test() { fun test() {
class Test{ class Test{
fun get(a: Int, b: Int, fn: (i: Int) -> Int) : Int = 0 operator fun get(a: Int, b: Int, fn: (i: Int) -> Int) : Int = 0
} }
val test = Test() val test = Test()
test[1, 2, { i -> test[1, 2, { i ->
@@ -3,7 +3,7 @@
// ERROR: No value passed for parameter b // ERROR: No value passed for parameter b
fun test() { fun test() {
class Test{ class Test{
fun get(a: Int, b: Int) : Int = 0 operator fun get(a: Int, b: Int) : Int = 0
} }
val test = Test() val test = Test()
test.g<caret>et(a=0, a=1) test.g<caret>et(a=0, a=1)
@@ -1,7 +1,8 @@
fun test() { fun test() {
class Test() class Test()
fun Test.get(i: Int) : Int = 0 operator fun Test.get(i: Int) : Int = 0
val test = Test() val test = Test()
test.g<caret>et(0) test.g<caret>et(0)
} }
@@ -1,7 +1,8 @@
fun test() { fun test() {
class Test() class Test()
fun Test.get(i: Int) : Int = 0 operator fun Test.get(i: Int) : Int = 0
val test = Test() val test = Test()
test[0] test[0]
} }
@@ -1,6 +1,6 @@
fun test() { fun test() {
class Test{ class Test{
fun get(fn: (i: Int) -> Int) : Int = 0 operator fun get(fn: (i: Int) -> Int) : Int = 0
} }
val test = Test() val test = Test()
test.g<caret>et() { i -> test.g<caret>et() { i ->
@@ -1,6 +1,6 @@
fun test() { fun test() {
class Test{ class Test{
fun get(fn: (i: Int) -> Int) : Int = 0 operator fun get(fn: (i: Int) -> Int) : Int = 0
} }
val test = Test() val test = Test()
test[{ i -> test[{ i ->
@@ -28,7 +28,7 @@
<problem> <problem>
<file>extensionFunction.kt</file> <file>extensionFunction.kt</file>
<line>6</line> <line>7</line>
<module>light_idea_test_case</module> <module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/extensionFunction.kt" /> <entry_point TYPE="file" FQNAME="temp:///src/extensionFunction.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Explicit 'get'</problem_class> <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Explicit 'get'</problem_class>
@@ -2,7 +2,7 @@
// ERROR: Cannot find a parameter with this name: c // ERROR: Cannot find a parameter with this name: c
fun test() { fun test() {
class Test{ class Test{
fun get(a: Int=1, b: Int=2) : Int = 0 operator fun get(a: Int=1, b: Int=2) : Int = 0
} }
val test = Test() val test = Test()
test.g<caret>et(c=3) test.g<caret>et(c=3)
@@ -1,7 +1,7 @@
// IS_APPLICABLE: false // IS_APPLICABLE: false
fun test() { fun test() {
class Test{ class Test{
fun get(a: Int=1, b: Int=2) : Int = 0 operator fun get(a: Int=1, b: Int=2) : Int = 0
} }
val test = Test() val test = Test()
test.g<caret>et(b=3) test.g<caret>et(b=3)
@@ -1,6 +1,6 @@
fun test() { fun test() {
class Test{ class Test{
fun get(a: Int, b: Int) : Int = 0 operator fun get(a: Int, b: Int) : Int = 0
} }
val test = Test() val test = Test()
test.g<caret>et(1, 2) test.g<caret>et(1, 2)
@@ -1,6 +1,6 @@
fun test() { fun test() {
class Test{ class Test{
fun get(a: Int, b: Int) : Int = 0 operator fun get(a: Int, b: Int) : Int = 0
} }
val test = Test() val test = Test()
test[1, 2] test[1, 2]
@@ -1,7 +1,7 @@
// IS_APPLICABLE: false // IS_APPLICABLE: false
fun test() { fun test() {
class Test{ class Test{
fun get() : Int = 0 operator fun get() : Int = 0
} }
val test = Test() val test = Test()
test.g<caret>et() test.g<caret>et()
@@ -0,0 +1,10 @@
// IS_APPLICABLE: false
package p
class C
fun C.get(s: String) = s
fun foo(c: C) {
c.<caret>get("x")
}
@@ -1,6 +1,6 @@
class C { class C {
companion object { companion object {
fun get(s: String): C = C() operator fun get(s: String): C = C()
} }
} }
@@ -1,6 +1,6 @@
class C { class C {
companion object { companion object {
fun get(s: String): C = C() operator fun get(s: String): C = C()
} }
} }
@@ -2,7 +2,7 @@
// ERROR: Unresolved reference: got // ERROR: Unresolved reference: got
fun test() { fun test() {
class Test{ class Test{
fun get(i: Int) : Int = 0 operator fun get(i: Int) : Int = 0
} }
val test = Test() val test = Test()
test.g<caret>ot(0) test.g<caret>ot(0)
@@ -1,6 +1,6 @@
fun test() { fun test() {
class Test{ class Test{
fun get(i: Int) : Int = 0 operator fun get(i: Int) : Int = 0
} }
val test = Test() val test = Test()
test.g<caret>et(0) test.g<caret>et(0)
@@ -1,6 +1,6 @@
fun test() { fun test() {
class Test{ class Test{
fun get(i: Int) : Int = 0 operator fun get(i: Int) : Int = 0
} }
val test = Test() val test = Test()
test[0] test[0]
@@ -1,7 +1,7 @@
// IS_APPLICABLE: false // IS_APPLICABLE: false
open class Base { open class Base {
open fun get(s: String) = "" open operator fun get(s: String) = ""
} }
class C : Base() { class C : Base() {
@@ -1,7 +1,7 @@
// IS_APPLICABLE: false // IS_APPLICABLE: false
package p package p
fun get(s: String) = s operator fun get(s: String) = s
fun foo() { fun foo() {
p.<caret>get("x") p.<caret>get("x")
@@ -1,7 +1,7 @@
// IS_APPLICABLE: false // IS_APPLICABLE: false
fun test() { fun test() {
class Test{ class Test{
fun get(a: Int, vararg b: Int, c: Int = 0) : Int = 0 operator fun get(a: Int, vararg b: Int, c: Int = 0) : Int = 0
} }
val test = Test() val test = Test()
test.g<caret>et(1, 3, 4, c=5) test.g<caret>et(1, 3, 4, c=5)
@@ -1,7 +1,7 @@
// IS_APPLICABLE: false // IS_APPLICABLE: false
fun test() { fun test() {
class Test{ class Test{
fun get(a: Int = 0, b: Int = 1, c: Int = 2, d: Int = 3) : Int = 0 operator fun get(a: Int = 0, b: Int = 1, c: Int = 2, d: Int = 3) : Int = 0
} }
val test = Test() val test = Test()
test.g<caret>et(1, c=3, b=2) test.g<caret>et(1, c=3, b=2)
@@ -2783,6 +2783,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("notOperator.kt")
public void testNotOperator() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/conventionNameCalls/replaceGet/notOperator.kt");
doTest(fileName);
}
@TestMetadata("qualifier.kt") @TestMetadata("qualifier.kt")
public void testQualifier() throws Exception { public void testQualifier() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/conventionNameCalls/replaceGet/qualifier.kt"); String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/conventionNameCalls/replaceGet/qualifier.kt");