More correct algorithm for redundant type arguments detection
This commit is contained in:
+4
-2
@@ -193,7 +193,9 @@ public abstract class ResolutionContext<Context extends ResolutionContext<Contex
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public <T extends PsiElement> T getContextParentOfType(@NotNull KtExpression expression, @NotNull Class<? extends T>... classes) {
|
public <T extends PsiElement> T getContextParentOfType(@NotNull KtExpression expression, @NotNull Class<? extends T>... classes) {
|
||||||
PsiElement current = expression.getParent();
|
KtExpression context = expressionContextProvider.invoke(expression);
|
||||||
|
PsiElement current = context != null ? context : expression.getParent();
|
||||||
|
|
||||||
while (current != null) {
|
while (current != null) {
|
||||||
for (Class<? extends T> klass : classes) {
|
for (Class<? extends T> klass : classes) {
|
||||||
if (klass.isInstance(current)) {
|
if (klass.isInstance(current)) {
|
||||||
@@ -205,7 +207,7 @@ public abstract class ResolutionContext<Context extends ResolutionContext<Contex
|
|||||||
if (current instanceof PsiFile) return null;
|
if (current instanceof PsiFile) return null;
|
||||||
|
|
||||||
if (current instanceof KtExpression) {
|
if (current instanceof KtExpression) {
|
||||||
KtExpression context = expressionContextProvider.invoke((KtExpression) current);
|
context = expressionContextProvider.invoke((KtExpression) current);
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
current = context;
|
current = context;
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
+84
-29
@@ -18,17 +18,24 @@ package org.jetbrains.kotlin.idea.intentions
|
|||||||
|
|
||||||
import com.intellij.codeInspection.ProblemHighlightType
|
import com.intellij.codeInspection.ProblemHighlightType
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
|
import com.intellij.openapi.util.Key
|
||||||
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ValueDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.analysis.analyzeInContext
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||||
|
import org.jetbrains.kotlin.idea.core.copied
|
||||||
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
|
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
|
||||||
import org.jetbrains.kotlin.idea.resolve.frontendService
|
import org.jetbrains.kotlin.idea.project.builtIns
|
||||||
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.BindingTraceContext
|
import org.jetbrains.kotlin.resolve.DelegatingBindingTrace
|
||||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfoBefore
|
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfoBefore
|
||||||
import org.jetbrains.kotlin.resolve.calls.CallResolver
|
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.DelegatingCall
|
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
@@ -73,29 +80,33 @@ class RemoveExplicitTypeArgumentsIntention : SelfTargetingOffsetIndependentInten
|
|||||||
if (callExpression.typeArguments.isEmpty()) return false
|
if (callExpression.typeArguments.isEmpty()) return false
|
||||||
|
|
||||||
val resolutionFacade = callExpression.getResolutionFacade()
|
val resolutionFacade = callExpression.getResolutionFacade()
|
||||||
val context = resolutionFacade.analyze(callExpression, BodyResolveMode.PARTIAL)
|
val bindingContext = resolutionFacade.analyze(callExpression, BodyResolveMode.PARTIAL)
|
||||||
val calleeExpression = callExpression.calleeExpression ?: return false
|
val originalCall = callExpression.getResolvedCall(bindingContext) ?: return false
|
||||||
val scope = calleeExpression.getResolutionScope(context, resolutionFacade)
|
|
||||||
val originalCall = callExpression.getResolvedCall(context) ?: return false
|
|
||||||
val untypedCall = CallWithoutTypeArgs(originalCall.call)
|
|
||||||
|
|
||||||
val expectedTypeIsExplicitInCode = callExpression.hasExplicitExpectedType(context)
|
val (contextExpression, expectedType) = findContextToAnalyze(callExpression, bindingContext)
|
||||||
val expectedType = if (expectedTypeIsExplicitInCode) {
|
val resolutionScope = contextExpression.getResolutionScope(bindingContext, resolutionFacade)
|
||||||
context[BindingContext.EXPECTED_EXPRESSION_TYPE, callExpression] ?: TypeUtils.NO_EXPECTED_TYPE
|
|
||||||
}
|
val key = Key<Unit>("RemoveExplicitTypeArgumentsIntention")
|
||||||
else {
|
callExpression.putCopyableUserData(key, Unit)
|
||||||
TypeUtils.NO_EXPECTED_TYPE
|
val expressionToAnalyze = contextExpression.copied()
|
||||||
}
|
callExpression.putCopyableUserData(key, null)
|
||||||
val dataFlow = context.getDataFlowInfoBefore(callExpression)
|
|
||||||
val callResolver = resolutionFacade.frontendService<CallResolver>()
|
val newCallExpression = expressionToAnalyze.findDescendantOfType<KtCallExpression> { it.getCopyableUserData(key) != null }!!
|
||||||
val resolutionResults = callResolver.resolveFunctionCall(
|
newCallExpression.typeArgumentList!!.delete()
|
||||||
BindingTraceContext(), scope, untypedCall, expectedType, dataFlow, false)
|
|
||||||
if (!resolutionResults.isSingleResult) {
|
val newBindingContext = expressionToAnalyze.analyzeInContext(
|
||||||
return false
|
resolutionScope,
|
||||||
}
|
contextExpression,
|
||||||
|
trace = DelegatingBindingTrace(bindingContext, "Temporary trace"),
|
||||||
|
dataFlowInfo = bindingContext.getDataFlowInfoBefore(contextExpression),
|
||||||
|
expectedType = expectedType ?: TypeUtils.NO_EXPECTED_TYPE,
|
||||||
|
isStatement = expectedType == null
|
||||||
|
)
|
||||||
|
|
||||||
|
val newCall = newCallExpression.getResolvedCall(newBindingContext) ?: return false
|
||||||
|
|
||||||
val args = originalCall.typeArguments
|
val args = originalCall.typeArguments
|
||||||
val newArgs = resolutionResults.resultingCall.typeArguments
|
val newArgs = newCall.typeArguments
|
||||||
|
|
||||||
fun equalTypes(type1: KotlinType, type2: KotlinType): Boolean {
|
fun equalTypes(type1: KotlinType, type2: KotlinType): Boolean {
|
||||||
return if (approximateFlexible) {
|
return if (approximateFlexible) {
|
||||||
@@ -110,17 +121,61 @@ class RemoveExplicitTypeArgumentsIntention : SelfTargetingOffsetIndependentInten
|
|||||||
equalTypes(argType, newArgType)
|
equalTypes(argType, newArgType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun findContextToAnalyze(expression: KtExpression, bindingContext: BindingContext): Pair<KtExpression, KotlinType?> {
|
||||||
|
for (element in expression.parentsWithSelf) {
|
||||||
|
if (element !is KtExpression) continue
|
||||||
|
|
||||||
|
if (element.getQualifiedExpressionForSelector() != null) continue
|
||||||
|
if (!element.isUsedAsExpression(bindingContext)) return element to null
|
||||||
|
|
||||||
|
val parent = element.parent
|
||||||
|
when (parent) {
|
||||||
|
is KtNamedFunction -> {
|
||||||
|
val expectedType = if (element == parent.bodyExpression && !parent.hasBlockBody() && parent.hasDeclaredReturnType())
|
||||||
|
(bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, parent] as? FunctionDescriptor)?.returnType
|
||||||
|
else
|
||||||
|
null
|
||||||
|
return element to expectedType
|
||||||
|
}
|
||||||
|
|
||||||
|
is KtVariableDeclaration -> {
|
||||||
|
val expectedType = if (element == parent.initializer && parent.typeReference != null)
|
||||||
|
(bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, parent] as? ValueDescriptor)?.type
|
||||||
|
else
|
||||||
|
null
|
||||||
|
return element to expectedType
|
||||||
|
}
|
||||||
|
|
||||||
|
is KtParameter -> {
|
||||||
|
val expectedType = if (element == parent.defaultValue)
|
||||||
|
(bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, parent] as? ValueDescriptor)?.type
|
||||||
|
else
|
||||||
|
null
|
||||||
|
return element to expectedType
|
||||||
|
}
|
||||||
|
|
||||||
|
is KtPropertyAccessor -> {
|
||||||
|
val property = parent.parent as KtProperty
|
||||||
|
val expectedType = when {
|
||||||
|
element != parent.bodyExpression || parent.hasBlockBody() -> null
|
||||||
|
parent.isSetter -> parent.builtIns.unitType
|
||||||
|
property.typeReference == null -> null
|
||||||
|
else -> (bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, parent] as? FunctionDescriptor)?.returnType
|
||||||
|
}
|
||||||
|
return element to expectedType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return expression to null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isApplicableTo(element: KtTypeArgumentList): Boolean {
|
override fun isApplicableTo(element: KtTypeArgumentList): Boolean {
|
||||||
return isApplicableTo(element, approximateFlexible = false)
|
return isApplicableTo(element, approximateFlexible = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CallWithoutTypeArgs(call: Call) : DelegatingCall(call) {
|
|
||||||
override fun getTypeArguments() = emptyList<KtTypeProjection>()
|
|
||||||
override fun getTypeArgumentList() = null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun applyTo(element: KtTypeArgumentList, editor: Editor?) {
|
override fun applyTo(element: KtTypeArgumentList, editor: Editor?) {
|
||||||
element.delete()
|
element.delete()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// IS_APPLICABLE: true
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
fun f(p: Int): List<String>? {
|
||||||
|
return if (p > 0) {
|
||||||
|
print("a")
|
||||||
|
listOf<caret><String>()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// IS_APPLICABLE: true
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
fun f(p: Int): List<String>? {
|
||||||
|
return if (p > 0) {
|
||||||
|
print("a")
|
||||||
|
listOf()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// IS_APPLICABLE: true
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
fun foo(p: List<String> = listOf<caret><String>()) {
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
// IS_APPLICABLE: true
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
fun foo(p: List<String> = listOf()) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// IS_APPLICABLE: true
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
val x: List<String>
|
||||||
|
get() = listOf<caret><String>()
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// IS_APPLICABLE: true
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
val x: List<String>
|
||||||
|
get() = listOf()
|
||||||
+56
-3
@@ -138,7 +138,7 @@
|
|||||||
<file>insideOtherCall.kt</file>
|
<file>insideOtherCall.kt</file>
|
||||||
<line>5</line>
|
<line>5</line>
|
||||||
<module>light_idea_test_case</module>
|
<module>light_idea_test_case</module>
|
||||||
<entry_point TYPE="file" FQNAME="temp:///src/insideOtherCall.kt" />
|
<entry_point TYPE="file" FQNAME="insideOtherCall.kt" />
|
||||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary type argument</problem_class>
|
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary type argument</problem_class>
|
||||||
<description>Remove explicit type arguments</description>
|
<description>Remove explicit type arguments</description>
|
||||||
</problem>
|
</problem>
|
||||||
@@ -147,7 +147,7 @@
|
|||||||
<file>insideDeepOtherCall.kt</file>
|
<file>insideDeepOtherCall.kt</file>
|
||||||
<line>8</line>
|
<line>8</line>
|
||||||
<module>light_idea_test_case</module>
|
<module>light_idea_test_case</module>
|
||||||
<entry_point TYPE="file" FQNAME="temp:///src/insideDeepOtherCall.kt" />
|
<entry_point TYPE="file" FQNAME="insideDeepOtherCall.kt" />
|
||||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary type argument</problem_class>
|
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary type argument</problem_class>
|
||||||
<description>Remove explicit type arguments</description>
|
<description>Remove explicit type arguments</description>
|
||||||
</problem>
|
</problem>
|
||||||
@@ -156,9 +156,62 @@
|
|||||||
<file>insideDeepOtherCall.kt</file>
|
<file>insideDeepOtherCall.kt</file>
|
||||||
<line>8</line>
|
<line>8</line>
|
||||||
<module>light_idea_test_case</module>
|
<module>light_idea_test_case</module>
|
||||||
<entry_point TYPE="file" FQNAME="temp:///src/insideDeepOtherCall.kt" />
|
<entry_point TYPE="file" FQNAME="insideDeepOtherCall.kt" />
|
||||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary type argument</problem_class>
|
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary type argument</problem_class>
|
||||||
<description>Remove explicit type arguments</description>
|
<description>Remove explicit type arguments</description>
|
||||||
</problem>
|
</problem>
|
||||||
|
|
||||||
|
<problem>
|
||||||
|
<file>twoArguments.kt</file>
|
||||||
|
<line>8</line>
|
||||||
|
<module>light_idea_test_case</module>
|
||||||
|
<entry_point TYPE="file" FQNAME="twoArguments.kt" />
|
||||||
|
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unnecessary type argument</problem_class>
|
||||||
|
<description>Remove explicit type arguments</description>
|
||||||
|
</problem>
|
||||||
|
|
||||||
|
<problem>
|
||||||
|
<file>twoArguments.kt</file>
|
||||||
|
<line>8</line>
|
||||||
|
<module>light_idea_test_case</module>
|
||||||
|
<entry_point TYPE="file" FQNAME="twoArguments.kt" />
|
||||||
|
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unnecessary type argument</problem_class>
|
||||||
|
<description>Remove explicit type arguments</description>
|
||||||
|
</problem>
|
||||||
|
|
||||||
|
<problem>
|
||||||
|
<file>qualified.kt</file>
|
||||||
|
<line>6</line>
|
||||||
|
<module>light_idea_test_case</module>
|
||||||
|
<entry_point TYPE="file" FQNAME="qualified.kt" />
|
||||||
|
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unnecessary type argument</problem_class>
|
||||||
|
<description>Remove explicit type arguments</description>
|
||||||
|
</problem>
|
||||||
|
|
||||||
|
<problem>
|
||||||
|
<file>getterBody.kt</file>
|
||||||
|
<line>5</line>
|
||||||
|
<module>light_idea_test_case</module>
|
||||||
|
<entry_point TYPE="file" FQNAME="getterBody.kt" />
|
||||||
|
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unnecessary type argument</problem_class>
|
||||||
|
<description>Remove explicit type arguments</description>
|
||||||
|
</problem>
|
||||||
|
|
||||||
|
<problem>
|
||||||
|
<file>defaultParamValue.kt</file>
|
||||||
|
<line>4</line>
|
||||||
|
<module>light_idea_test_case</module>
|
||||||
|
<entry_point TYPE="file" FQNAME="defaultParamValue.kt" />
|
||||||
|
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unnecessary type argument</problem_class>
|
||||||
|
<description>Remove explicit type arguments</description>
|
||||||
|
</problem>
|
||||||
|
|
||||||
|
<problem>
|
||||||
|
<file>blockValue.kt</file>
|
||||||
|
<line>7</line>
|
||||||
|
<module>light_idea_test_case</module>
|
||||||
|
<entry_point TYPE="file" FQNAME="blockValue.kt" />
|
||||||
|
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unnecessary type argument</problem_class>
|
||||||
|
<description>Remove explicit type arguments</description>
|
||||||
|
</problem>
|
||||||
</problems>
|
</problems>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
interface I<T>
|
||||||
|
|
||||||
|
fun <T> Int.foo(p: I<T>){}
|
||||||
|
|
||||||
|
fun bar(p: I<String>) {
|
||||||
|
1.foo<caret><String>(p)
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
interface I<T>
|
||||||
|
|
||||||
|
fun <T> Int.foo(p: I<T>){}
|
||||||
|
|
||||||
|
fun bar(p: I<String>) {
|
||||||
|
1.foo(p)
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// IS_APPLICABLE: true
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
fun <T> foo(p1: List<T>, p2: List<T>) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
foo(listOf<caret><String>(), listOf<String>())
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// IS_APPLICABLE: true
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
fun <T> foo(p1: List<T>, p2: List<T>) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
foo(listOf(), listOf<String>())
|
||||||
|
}
|
||||||
@@ -12896,6 +12896,18 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/removeExplicitTypeArguments"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/removeExplicitTypeArguments"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("blockValue.kt")
|
||||||
|
public void testBlockValue() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeExplicitTypeArguments/blockValue.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("defaultParamValue.kt")
|
||||||
|
public void testDefaultParamValue() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeExplicitTypeArguments/defaultParamValue.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("fourLiterals.kt")
|
@TestMetadata("fourLiterals.kt")
|
||||||
public void testFourLiterals() throws Exception {
|
public void testFourLiterals() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeExplicitTypeArguments/fourLiterals.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeExplicitTypeArguments/fourLiterals.kt");
|
||||||
@@ -12908,6 +12920,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("getterBody.kt")
|
||||||
|
public void testGetterBody() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeExplicitTypeArguments/getterBody.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("inapplicableTypeThatIsAFunItCannotBeInferred.kt")
|
@TestMetadata("inapplicableTypeThatIsAFunItCannotBeInferred.kt")
|
||||||
public void testInapplicableTypeThatIsAFunItCannotBeInferred() throws Exception {
|
public void testInapplicableTypeThatIsAFunItCannotBeInferred() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeExplicitTypeArguments/inapplicableTypeThatIsAFunItCannotBeInferred.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeExplicitTypeArguments/inapplicableTypeThatIsAFunItCannotBeInferred.kt");
|
||||||
@@ -13010,12 +13028,24 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("qualified.kt")
|
||||||
|
public void testQualified() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeExplicitTypeArguments/qualified.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("returnCallWithUnnecessaryTypeArgs.kt")
|
@TestMetadata("returnCallWithUnnecessaryTypeArgs.kt")
|
||||||
public void testReturnCallWithUnnecessaryTypeArgs() throws Exception {
|
public void testReturnCallWithUnnecessaryTypeArgs() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeExplicitTypeArguments/returnCallWithUnnecessaryTypeArgs.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeExplicitTypeArguments/returnCallWithUnnecessaryTypeArgs.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("twoArguments.kt")
|
||||||
|
public void testTwoArguments() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeExplicitTypeArguments/twoArguments.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("twoLiteralValues.kt")
|
@TestMetadata("twoLiteralValues.kt")
|
||||||
public void testTwoLiteralValues() throws Exception {
|
public void testTwoLiteralValues() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeExplicitTypeArguments/twoLiteralValues.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeExplicitTypeArguments/twoLiteralValues.kt");
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ internal class A {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun bar() {
|
fun bar() {
|
||||||
field5 = ArrayList<String>()
|
field5 = ArrayList()
|
||||||
field7++
|
field7++
|
||||||
field8++
|
field8++
|
||||||
field9 = null
|
field9 = null
|
||||||
|
|||||||
Reference in New Issue
Block a user