NI: Allow to resolve to functions with SAM conversion and passing array without spread as vararg (with warning)

^KT-35224 Fixed
This commit is contained in:
Victor Petukhov
2019-12-04 20:29:03 +03:00
parent fe875d628d
commit 07269661b4
33 changed files with 573 additions and 27 deletions
@@ -132,10 +132,12 @@ class RedundantSamConstructorInspection : AbstractKotlinInspection() {
if (!resolutionResults.isSuccess) return false
val generatingAdditionalSamCandidateIsDisabled =
parentCall.languageVersionSettings.supportsFeature(LanguageFeature.SamConversionPerArgument) ||
parentCall.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitVarargAsArrayAfterSamArgument)
val samAdapterOriginalDescriptor =
if (parentCall.languageVersionSettings.supportsFeature(LanguageFeature.SamConversionPerArgument) &&
resolutionResults.resultingCall is NewResolvedCallImpl<*>
) {
if (generatingAdditionalSamCandidateIsDisabled && resolutionResults.resultingCall is NewResolvedCallImpl<*>) {
resolutionResults.resultingDescriptor
} else {
SamCodegenUtil.getOriginalIfSamAdapter(resolutionResults.resultingDescriptor) ?: return false
@@ -0,0 +1,36 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.quickfix
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtPsiFactory
object AddSpreadOperatorForArrayAsVarargAfterSamFixFactory : KotlinSingleIntentionActionFactory() {
public override fun createAction(diagnostic: Diagnostic): IntentionAction? {
val diagnosticWithParameters = Errors.TYPE_INFERENCE_CANDIDATE_WITH_SAM_AND_VARARG.cast(diagnostic)
val argument = diagnosticWithParameters.psiElement
return AddSpreadOperatorForArrayAsVarargAfterSamFix(argument)
}
}
class AddSpreadOperatorForArrayAsVarargAfterSamFix(element: PsiElement) : KotlinQuickFixAction<PsiElement>(element) {
override fun getFamilyName() = "Add a spread operator before an array passing as vararg"
override fun getText() = familyName
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
val element = element ?: return
element.addBefore(KtPsiFactory(file).createStar(), element.firstChild)
}
}
@@ -160,6 +160,7 @@ class QuickFixRegistrar : QuickFixContributor {
UNRESOLVED_REFERENCE.registerFactory(ImportFix)
UNRESOLVED_REFERENCE.registerFactory(ImportConstructorReferenceFix)
DEPRECATED_ACCESS_BY_SHORT_NAME.registerFactory(AddExplicitImportForDeprecatedVisibilityFix.Factory)
TYPE_INFERENCE_CANDIDATE_WITH_SAM_AND_VARARG.registerFactory(AddSpreadOperatorForArrayAsVarargAfterSamFixFactory)
TOO_MANY_ARGUMENTS.registerFactory(ImportForMismatchingArgumentsFix)
NO_VALUE_FOR_PARAMETER.registerFactory(ImportForMismatchingArgumentsFix)
@@ -0,0 +1,21 @@
// FILE: test.before.kt
// "Add a spread operator before an array passing as vararg" "false"
// ACTION: Add 'toString()' call
// ACTION: Create member function 'Test.foo'
// ACTION: Introduce import alias
// ACTION: Introduce local variable
// ACTION: Put arguments on separate lines
// ERROR: Type mismatch: inferred type is Array<???> but String! was expected
// COMPILER_ARGUMENTS: -XXLanguage:+NewInference -XXLanguage:+SamConversionForKotlinFunctions -XXLanguage:+SamConversionPerArgument -XXLanguage:+ProhibitVarargAsArrayAfterSamArgument
// WITH_RUNTIME
fun main() {
Test.foo({}, <caret>arrayOf())
}
// FILE: Test.java
public class Test {
public static String foo(Runnable r, String... strs) {
return null;
}
}
@@ -0,0 +1,27 @@
// FILE: test.before.kt
// "Add a spread operator before an array passing as vararg" "true"
// WARNING: Please use spread operator to pass an array as vararg. It will be an error in 1.5.
// COMPILER_ARGUMENTS: -XXLanguage:+NewInference -XXLanguage:+SamConversionForKotlinFunctions -XXLanguage:+SamConversionPerArgument
// WITH_RUNTIME
fun main() {
Test.foo({}, <caret>arrayOf())
}
// FILE: Test.java
public class Test {
public static String foo(Runnable r, String... strs) {
return null;
}
}
// FILE: test.after.kt
// "Add a spread operator before an array passing as vararg" "true"
// WARNING: Please use spread operator to pass an array as vararg. It will be an error in 1.5.
// COMPILER_ARGUMENTS: -XXLanguage:+NewInference -XXLanguage:+SamConversionForKotlinFunctions -XXLanguage:+SamConversionPerArgument
// WITH_RUNTIME
fun main() {
Test.foo({}, <caret>*arrayOf())
}
@@ -0,0 +1,18 @@
// FILE: test.before.kt
// "Add a spread operator before an array passing as vararg" "false"
// ACTION: Add explicit type arguments
// ACTION: Introduce import alias
// ACTION: Introduce local variable
// ACTION: Put arguments on separate lines
// WITH_RUNTIME
fun main() {
Test.foo({}, <caret>arrayOf())
}
// FILE: Test.java
public class Test {
public static String foo(Runnable r, String... strs) {
return null;
}
}
@@ -324,6 +324,34 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes
}
}
@TestMetadata("idea/testData/quickfix/addSpreadOperatorForArrayAsVarargAfterSam")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class AddSpreadOperatorForArrayAsVarargAfterSam extends AbstractQuickFixMultiFileTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTestWithExtraFile, this, testDataFilePath);
}
public void testAllFilesPresentInAddSpreadOperatorForArrayAsVarargAfterSam() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/addSpreadOperatorForArrayAsVarargAfterSam"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), true);
}
@TestMetadata("withError.test")
public void testWithError() throws Exception {
runTest("idea/testData/quickfix/addSpreadOperatorForArrayAsVarargAfterSam/withError.test");
}
@TestMetadata("withWarning.test")
public void testWithWarning() throws Exception {
runTest("idea/testData/quickfix/addSpreadOperatorForArrayAsVarargAfterSam/withWarning.test");
}
@TestMetadata("withoutWarning.test")
public void testWithoutWarning() throws Exception {
runTest("idea/testData/quickfix/addSpreadOperatorForArrayAsVarargAfterSam/withoutWarning.test");
}
}
@TestMetadata("idea/testData/quickfix/addStarProjections")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -1174,6 +1174,19 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
}
}
@TestMetadata("idea/testData/quickfix/addSpreadOperatorForArrayAsVarargAfterSam")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class AddSpreadOperatorForArrayAsVarargAfterSam extends AbstractQuickFixTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInAddSpreadOperatorForArrayAsVarargAfterSam() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/addSpreadOperatorForArrayAsVarargAfterSam"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true);
}
}
@TestMetadata("idea/testData/quickfix/addStarProjections")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)