KT-5099 "Remove explicit type arguments" should highlight only type arguments
#KT-5099 Fixed
This commit is contained in:
@@ -17,6 +17,6 @@
|
|||||||
package org.jetbrains.jet.plugin.inspections
|
package org.jetbrains.jet.plugin.inspections
|
||||||
|
|
||||||
import org.jetbrains.jet.plugin.intentions.RemoveExplicitTypeArguments
|
import org.jetbrains.jet.plugin.intentions.RemoveExplicitTypeArguments
|
||||||
import org.jetbrains.jet.lang.psi.JetCallExpression
|
import org.jetbrains.jet.lang.psi.JetTypeArgumentList
|
||||||
|
|
||||||
public class RemoveExplicitTypeArgsInspection : IntentionBasedInspection<JetCallExpression>(RemoveExplicitTypeArguments())
|
public class RemoveExplicitTypeArgsInspection : IntentionBasedInspection<JetTypeArgumentList>(RemoveExplicitTypeArguments())
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import com.intellij.openapi.editor.Editor
|
|||||||
import org.jetbrains.jet.lang.psi.JetCallExpression
|
import org.jetbrains.jet.lang.psi.JetCallExpression
|
||||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
|
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||||
import org.jetbrains.jet.lang.psi.JetPsiFactory
|
|
||||||
import org.jetbrains.jet.lang.resolve.calls.util.DelegatingCall
|
import org.jetbrains.jet.lang.resolve.calls.util.DelegatingCall
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo
|
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo
|
||||||
import org.jetbrains.jet.lang.types.TypeUtils
|
import org.jetbrains.jet.lang.types.TypeUtils
|
||||||
@@ -37,20 +36,23 @@ import com.intellij.psi.util.PsiTreeUtil
|
|||||||
import org.jetbrains.jet.lang.psi.JetReturnExpression
|
import org.jetbrains.jet.lang.psi.JetReturnExpression
|
||||||
import org.jetbrains.jet.lang.psi.JetDeclaration
|
import org.jetbrains.jet.lang.psi.JetDeclaration
|
||||||
import org.jetbrains.jet.lang.psi.JetDeclarationWithBody
|
import org.jetbrains.jet.lang.psi.JetDeclarationWithBody
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
|
|
||||||
public class RemoveExplicitTypeArguments : JetSelfTargetingIntention<JetCallExpression>(
|
public class RemoveExplicitTypeArguments : JetSelfTargetingIntention<JetTypeArgumentList>(
|
||||||
"remove.explicit.type.arguments", javaClass()) {
|
"remove.explicit.type.arguments", javaClass()) {
|
||||||
|
|
||||||
override fun isApplicableTo(element: JetCallExpression): Boolean {
|
override fun isApplicableTo(element: JetTypeArgumentList): Boolean {
|
||||||
|
val callExpression = element.getParent()
|
||||||
|
if (callExpression !is JetCallExpression) return false
|
||||||
|
|
||||||
val context = AnalyzerFacadeWithCache.getContextForElement(element)
|
val context = AnalyzerFacadeWithCache.getContextForElement(callExpression)
|
||||||
if (element.getTypeArguments().isEmpty()) return false
|
if (callExpression.getTypeArguments().isEmpty()) return false
|
||||||
|
|
||||||
val resolveSession = element.getLazyResolveSession()
|
val resolveSession = callExpression.getLazyResolveSession()
|
||||||
val injector = InjectorForMacros(element.getProject(), resolveSession.getModuleDescriptor())
|
val injector = InjectorForMacros(callExpression.getProject(), resolveSession.getModuleDescriptor())
|
||||||
|
|
||||||
val scope = context[BindingContext.RESOLUTION_SCOPE, element]
|
val scope = context[BindingContext.RESOLUTION_SCOPE, callExpression]
|
||||||
val originalCall = context[BindingContext.RESOLVED_CALL, element.getCalleeExpression()]?.getCall()
|
val originalCall = context[BindingContext.RESOLVED_CALL, callExpression.getCalleeExpression()]?.getCall()
|
||||||
if (originalCall == null || scope !is JetScope) return false
|
if (originalCall == null || scope !is JetScope) return false
|
||||||
val untypedCall = CallWithoutTypeArgs(originalCall)
|
val untypedCall = CallWithoutTypeArgs(originalCall)
|
||||||
|
|
||||||
@@ -58,8 +60,8 @@ public class RemoveExplicitTypeArguments : JetSelfTargetingIntention<JetCallExpr
|
|||||||
// If always use expected type from trace there is a problem with nested calls:
|
// If always use expected type from trace there is a problem with nested calls:
|
||||||
// the expression type for them can depend on their explicit type arguments (via outer call),
|
// the expression type for them can depend on their explicit type arguments (via outer call),
|
||||||
// therefore we should resolve outer call with erased type arguments for inner call
|
// therefore we should resolve outer call with erased type arguments for inner call
|
||||||
val parent = element.getParent()
|
val parent = callExpression.getParent()
|
||||||
val expectedTypeIsExplicitInCode = when(parent) {
|
val expectedTypeIsExplicitInCode = when (parent) {
|
||||||
is JetProperty -> parent.getInitializer() == callExpression && parent.getTypeRef() != null
|
is JetProperty -> parent.getInitializer() == callExpression && parent.getTypeRef() != null
|
||||||
is JetDeclarationWithBody -> parent.getBodyExpression() == callExpression
|
is JetDeclarationWithBody -> parent.getBodyExpression() == callExpression
|
||||||
is JetReturnExpression -> true
|
is JetReturnExpression -> true
|
||||||
@@ -71,11 +73,11 @@ public class RemoveExplicitTypeArguments : JetSelfTargetingIntention<JetCallExpr
|
|||||||
else {
|
else {
|
||||||
TypeUtils.NO_EXPECTED_TYPE
|
TypeUtils.NO_EXPECTED_TYPE
|
||||||
}
|
}
|
||||||
val dataFlow = context[BindingContext.EXPRESSION_DATA_FLOW_INFO, element] ?: DataFlowInfo.EMPTY
|
val dataFlow = context[BindingContext.EXPRESSION_DATA_FLOW_INFO, callExpression] ?: DataFlowInfo.EMPTY
|
||||||
val resolvedCall = injector.getExpressionTypingServices()?.getCallResolver()?.resolveFunctionCall(
|
val resolvedCall = injector.getExpressionTypingServices()?.getCallResolver()?.resolveFunctionCall(
|
||||||
BindingTraceContext(), scope, untypedCall, jType, dataFlow, false)
|
BindingTraceContext(), scope, untypedCall, jType, dataFlow, false)
|
||||||
|
|
||||||
val args = context[BindingContext.RESOLVED_CALL, element.getCalleeExpression()]?.getTypeArguments()
|
val args = context[BindingContext.RESOLVED_CALL, callExpression.getCalleeExpression()]?.getTypeArguments()
|
||||||
val newArgs = resolvedCall?.getResultingCall()?.getTypeArguments()
|
val newArgs = resolvedCall?.getResultingCall()?.getTypeArguments()
|
||||||
|
|
||||||
return args == newArgs
|
return args == newArgs
|
||||||
@@ -91,15 +93,7 @@ public class RemoveExplicitTypeArguments : JetSelfTargetingIntention<JetCallExpr
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun applyTo(element: JetCallExpression, editor: Editor) {
|
override fun applyTo(element: JetTypeArgumentList, editor: Editor) {
|
||||||
val text = element.getText()
|
element.delete()
|
||||||
val typeArgs = element.getTypeArgumentList()
|
|
||||||
if (text == null || typeArgs == null) return
|
|
||||||
val base = typeArgs.getTextOffset() - element.getTextOffset()
|
|
||||||
val untypedText = "${text.substring(0, base)}${text.substring(base + typeArgs.getTextLength())}"
|
|
||||||
element.replace(JetPsiFactory.createExpression(element.getProject(), untypedText))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
// IS_APPLICABLE: true
|
// IS_APPLICABLE: true
|
||||||
fun foo() {
|
fun foo() {
|
||||||
val z = <caret>bar<String, Int, Int, String>("1", 1, 2, "x")
|
val z = bar<caret><String, Int, Int, String>("1", 1, 2, "x")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bar<T, V, R, K>(t: T, v: V, r: R, k: K): Int = 2
|
fun bar<T, V, R, K>(t: T, v: V, r: R, k: K): Int = 2
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
// IS_APPLICABLE: false
|
// IS_APPLICABLE: false
|
||||||
fun foo() {
|
fun foo() {
|
||||||
<caret>bar<(Int) -> Int>({ baz(it) })
|
bar<caret><(Int) -> Int>({ baz(it) })
|
||||||
}
|
}
|
||||||
|
|
||||||
fun baz(x: Int): Int = x
|
fun baz(x: Int): Int = x
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// IS_APPLICABLE: true
|
// IS_APPLICABLE: true
|
||||||
fun foo() {
|
fun foo() {
|
||||||
<caret>bar<(Int) -> Int> { (it:Int) -> it }
|
bar<caret><(Int) -> Int> { (it: Int) -> it }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bar<T>(t: T): Int = 1
|
fun bar<T>(t: T): Int = 1
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
// IS_APPLICABLE: true
|
// IS_APPLICABLE: true
|
||||||
fun foo() {
|
fun foo() {
|
||||||
bar {(it: Int) -> it }
|
bar { (it: Int) -> it }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bar<T>(t: T): Int = 1
|
fun bar<T>(t: T): Int = 1
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
// IS_APPLICABLE: true
|
// IS_APPLICABLE: true
|
||||||
fun foo() {
|
fun foo() {
|
||||||
val x = <caret>Box<Any>(Any())
|
val x = Box<caret><Any>(Any())
|
||||||
}
|
}
|
||||||
|
|
||||||
class Box<T>(t : T) {
|
class Box<T>(t : T) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// IS_APPLICABLE: true
|
// IS_APPLICABLE: true
|
||||||
fun foo() {
|
fun foo() {
|
||||||
<caret>bar<String>("x")
|
bar<caret><String>("x")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bar<T>(t: T): Int = 1
|
fun bar<T>(t: T): Int = 1
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
// IS_APPLICABLE: true
|
// IS_APPLICABLE: true
|
||||||
fun foo() {
|
fun foo() {
|
||||||
val x = <caret>Box<String>("x")
|
val x = Box<caret><String>("x")
|
||||||
}
|
}
|
||||||
|
|
||||||
class Box<T>(t : T) {
|
class Box<T>(t : T) {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
// IS_APPLICABLE: true
|
// IS_APPLICABLE: true
|
||||||
fun foo() {
|
fun foo() {
|
||||||
val x = <caret>Box("x")
|
val x = Box<caret>("x")
|
||||||
}
|
}
|
||||||
|
|
||||||
class Box<T>(t : T) {
|
class Box<T>(t : T) {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
// IS_APPLICABLE: true
|
// IS_APPLICABLE: true
|
||||||
fun foo() {
|
fun foo() {
|
||||||
val x = <caret>Box<Box<String>>(Box("x"))
|
val x = Box<caret><Box<String>>(Box("x"))
|
||||||
}
|
}
|
||||||
|
|
||||||
class Box<T>(t : T) {
|
class Box<T>(t : T) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// IS_APPLICABLE: false
|
// IS_APPLICABLE: false
|
||||||
// ERROR: Unresolved reference: LinkedList
|
// ERROR: Unresolved reference: LinkedList
|
||||||
fun foo() {
|
fun foo() {
|
||||||
val x = <caret>bar<String>()
|
val x = bar<caret><String>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> bar() : List<T> = LinkedList<T>();
|
fun <T> bar() : List<T> = LinkedList<T>();
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
// IS_APPLICABLE: false
|
// IS_APPLICABLE: false
|
||||||
fun foo() {
|
fun foo() {
|
||||||
val x = <caret>bar<Any>("x")
|
val x = bar<caret><Any>("x")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bar<T>(t: T): Int = 1
|
fun bar<T>(t: T): Int = 1
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
// IS_APPLICABLE: false
|
// IS_APPLICABLE: false
|
||||||
fun foo() {
|
fun foo() {
|
||||||
val x = <caret>Box<Any>("x")
|
val x = Box<caret><Any>("x")
|
||||||
}
|
}
|
||||||
|
|
||||||
class Box<T>(t : T) {
|
class Box<T>(t : T) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// IS_APPLICABLE: true
|
// IS_APPLICABLE: true
|
||||||
fun foo() {
|
fun foo() {
|
||||||
val x = <caret>bar<String, Int>("x", 0)
|
val x = bar<caret><String, Int>("x", 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bar<T, V>(t: T, v: V): Int = 1
|
fun bar<T, V>(t: T, v: V): Int = 1
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
// IS_APPLICABLE: true
|
// IS_APPLICABLE: true
|
||||||
fun foo() {
|
fun foo() {
|
||||||
val x = "x"
|
val x = "x"
|
||||||
<caret>bar<String>(x)
|
bar<caret><String>(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bar<T>(t: T): Int = 1
|
fun bar<T>(t: T): Int = 1
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
// IS_APPLICABLE: true
|
// IS_APPLICABLE: true
|
||||||
fun foo(x: String) {
|
fun foo(x: String) {
|
||||||
<caret>bar<String>(x)
|
bar<caret><String>(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bar<T>(t: T): Int = 1
|
fun bar<T>(t: T): Int = 1
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
val x = "x"
|
val x = "x"
|
||||||
|
|
||||||
fun foo() {
|
fun foo() {
|
||||||
<caret>bar<String>(x)
|
bar<caret><String>(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bar<T>(t: T): Int = 1
|
fun bar<T>(t: T): Int = 1
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
fun foo() {
|
fun foo() {
|
||||||
val x = "1"
|
val x = "1"
|
||||||
val y = 2
|
val y = 2
|
||||||
val z = <caret>bar<String, Int, Int, String>(x, 1, y, "x")
|
val z = bar<caret><String, Int, Int, String>(x, 1, y, "x")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bar<T, V, R, K>(t: T, v: V, r: R, k: K): Int = 2
|
fun bar<T, V, R, K>(t: T, v: V, r: R, k: K): Int = 2
|
||||||
Reference in New Issue
Block a user