Prohibit type parameters for local variables in LV >= 1.4 & -progressive
#KT-8341 Fixed
This commit is contained in:
@@ -954,6 +954,8 @@ public interface Errors {
|
||||
DiagnosticFactory0<KtTypeReference> LOCAL_EXTENSION_PROPERTY = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtPropertyAccessor> LOCAL_VARIABLE_WITH_GETTER = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtPropertyAccessor> LOCAL_VARIABLE_WITH_SETTER = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtTypeParameterList> LOCAL_VARIABLE_WITH_TYPE_PARAMETERS_WARNING = DiagnosticFactory0.create(WARNING);
|
||||
DiagnosticFactory0<KtTypeParameterList> LOCAL_VARIABLE_WITH_TYPE_PARAMETERS = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory3<KtExpression, DeclarationDescriptor, Visibility, DeclarationDescriptor> INVISIBLE_SETTER = DiagnosticFactory3.create(ERROR);
|
||||
|
||||
|
||||
+2
@@ -399,6 +399,8 @@ public class DefaultErrorMessages {
|
||||
MAP.put(LOCAL_EXTENSION_PROPERTY, "Local extension properties are not allowed");
|
||||
MAP.put(LOCAL_VARIABLE_WITH_GETTER, "Local variables are not allowed to have getters");
|
||||
MAP.put(LOCAL_VARIABLE_WITH_SETTER, "Local variables are not allowed to have setters");
|
||||
MAP.put(LOCAL_VARIABLE_WITH_TYPE_PARAMETERS_WARNING, "Type parameters for local variables are deprecated");
|
||||
MAP.put(LOCAL_VARIABLE_WITH_TYPE_PARAMETERS, "Local variables are not allowed to have type parameters");
|
||||
MAP.put(VAL_WITH_SETTER, "A 'val'-property cannot have a setter");
|
||||
|
||||
MAP.put(DEPRECATED_IDENTITY_EQUALS, "Identity equality for arguments of types {0} and {1} is deprecated", RENDER_TYPE, RENDER_TYPE);
|
||||
|
||||
@@ -33,7 +33,8 @@ private val DEFAULT_DECLARATION_CHECKERS = listOf(
|
||||
PropertiesWithBackingFieldsInsideInlineClass(),
|
||||
AnnotationClassTargetAndRetentionChecker(),
|
||||
ReservedMembersAndConstructsForInlineClass(),
|
||||
ResultClassInReturnTypeChecker()
|
||||
ResultClassInReturnTypeChecker(),
|
||||
LocalVariableTypeParametersChecker()
|
||||
)
|
||||
|
||||
private val DEFAULT_CALL_CHECKERS = listOf(
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.resolve.checkers
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
|
||||
class LocalVariableTypeParametersChecker : DeclarationChecker {
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
if (declaration !is KtProperty || descriptor !is LocalVariableDescriptor) return
|
||||
|
||||
val typeParameters = declaration.typeParameters
|
||||
val typeParametersList = declaration.typeParameterList
|
||||
if (typeParameters.isEmpty() || typeParametersList == null) return
|
||||
|
||||
val diagnostic =
|
||||
if (context.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitTypeParametersForLocalVariables))
|
||||
Errors.LOCAL_VARIABLE_WITH_TYPE_PARAMETERS
|
||||
else
|
||||
Errors.LOCAL_VARIABLE_WITH_TYPE_PARAMETERS_WARNING
|
||||
|
||||
context.trace.report(diagnostic.on(typeParametersList))
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -7,6 +7,6 @@ class SomeClass {
|
||||
val <<!WRONG_ANNOTATION_TARGET!>@A1<!> <!WRONG_ANNOTATION_TARGET!>@A2(3)<!> <!WRONG_ANNOTATION_TARGET, REPEATED_ANNOTATION!>@A2<!> <!WRONG_ANNOTATION_TARGET, REPEATED_ANNOTATION!>@A1(<!TOO_MANY_ARGUMENTS!>12<!>)<!> <!WRONG_ANNOTATION_TARGET, REPEATED_ANNOTATION!>@A2(<!TYPE_MISMATCH!>"Test"<!>)<!> T> T.field: Int get() = 12
|
||||
|
||||
fun foo() {
|
||||
val <<!WRONG_ANNOTATION_TARGET!>@<!DEBUG_INFO_MISSING_UNRESOLVED!>A1<!><!> <!WRONG_ANNOTATION_TARGET!>@<!DEBUG_INFO_MISSING_UNRESOLVED!>A2<!>(3)<!> <!WRONG_ANNOTATION_TARGET!>@<!DEBUG_INFO_MISSING_UNRESOLVED!>A2<!><!> <!WRONG_ANNOTATION_TARGET!>@<!DEBUG_INFO_MISSING_UNRESOLVED!>A1<!>(12)<!> <!WRONG_ANNOTATION_TARGET!>@<!DEBUG_INFO_MISSING_UNRESOLVED!>A2<!>("Test")<!> T> <!UNUSED_VARIABLE!>localVal<!> = 12
|
||||
val <!LOCAL_VARIABLE_WITH_TYPE_PARAMETERS_WARNING!><<!WRONG_ANNOTATION_TARGET!>@<!DEBUG_INFO_MISSING_UNRESOLVED!>A1<!><!> <!WRONG_ANNOTATION_TARGET!>@<!DEBUG_INFO_MISSING_UNRESOLVED!>A2<!>(3)<!> <!WRONG_ANNOTATION_TARGET!>@<!DEBUG_INFO_MISSING_UNRESOLVED!>A2<!><!> <!WRONG_ANNOTATION_TARGET!>@<!DEBUG_INFO_MISSING_UNRESOLVED!>A1<!>(12)<!> <!WRONG_ANNOTATION_TARGET!>@<!DEBUG_INFO_MISSING_UNRESOLVED!>A2<!>("Test")<!> T><!> <!UNUSED_VARIABLE!>localVal<!> = 12
|
||||
}
|
||||
}
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
// !LANGUAGE: -ProhibitTypeParametersForLocalVariables
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
fun test() {
|
||||
val <!LOCAL_VARIABLE_WITH_TYPE_PARAMETERS_WARNING!><T><!> a0 = 0
|
||||
val <!LOCAL_VARIABLE_WITH_TYPE_PARAMETERS_WARNING!><T : <!DEBUG_INFO_MISSING_UNRESOLVED!>__UNRESOLVED__<!>><!> a1 = ""
|
||||
val <!LOCAL_VARIABLE_WITH_TYPE_PARAMETERS_WARNING!><T : <!DEBUG_INFO_MISSING_UNRESOLVED!>String<!>><!> a2 = 0
|
||||
<!WRONG_MODIFIER_TARGET!>const<!> val <!LOCAL_VARIABLE_WITH_TYPE_PARAMETERS_WARNING!><T><!> a3 = 0
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER, INAPPLICABLE_LATEINIT_MODIFIER, INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> val <!LOCAL_VARIABLE_WITH_TYPE_PARAMETERS_WARNING!><T><!> a4 = 0
|
||||
val <!LOCAL_VARIABLE_WITH_TYPE_PARAMETERS_WARNING!><T><!> a5 by Delegate<Int>()
|
||||
val <!LOCAL_VARIABLE_WITH_TYPE_PARAMETERS_WARNING!><T><!> a6 by Delegate<<!UNRESOLVED_REFERENCE!>T<!>>()
|
||||
}
|
||||
|
||||
class Delegate<F> {
|
||||
operator fun getValue(thisRef: Any?, property: KProperty<*>): String = ""
|
||||
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {}
|
||||
}
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
package
|
||||
|
||||
public fun test(): kotlin.Unit
|
||||
|
||||
public final class Delegate</*0*/ F> {
|
||||
public constructor Delegate</*0*/ F>()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun getValue(/*0*/ thisRef: kotlin.Any?, /*1*/ property: kotlin.reflect.KProperty<*>): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final operator fun setValue(/*0*/ thisRef: kotlin.Any?, /*1*/ property: kotlin.reflect.KProperty<*>, /*2*/ value: kotlin.String): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
// !LANGUAGE: +ProhibitTypeParametersForLocalVariables
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
fun test() {
|
||||
val <!LOCAL_VARIABLE_WITH_TYPE_PARAMETERS!><T><!> a0 = 0
|
||||
val <!LOCAL_VARIABLE_WITH_TYPE_PARAMETERS!><T : <!DEBUG_INFO_MISSING_UNRESOLVED!>__UNRESOLVED__<!>><!> a1 = ""
|
||||
val <!LOCAL_VARIABLE_WITH_TYPE_PARAMETERS!><T : <!DEBUG_INFO_MISSING_UNRESOLVED!>String<!>><!> a2 = 0
|
||||
<!WRONG_MODIFIER_TARGET!>const<!> val <!LOCAL_VARIABLE_WITH_TYPE_PARAMETERS!><T><!> a3 = 0
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER, INAPPLICABLE_LATEINIT_MODIFIER, INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> val <!LOCAL_VARIABLE_WITH_TYPE_PARAMETERS!><T><!> a4 = 0
|
||||
val <!LOCAL_VARIABLE_WITH_TYPE_PARAMETERS!><T><!> a5 by Delegate<Int>()
|
||||
val <!LOCAL_VARIABLE_WITH_TYPE_PARAMETERS!><T><!> a6 by Delegate<<!UNRESOLVED_REFERENCE!>T<!>>()
|
||||
}
|
||||
|
||||
class Delegate<F> {
|
||||
operator fun getValue(thisRef: Any?, property: KProperty<*>): String = ""
|
||||
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {}
|
||||
}
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
package
|
||||
|
||||
public fun test(): kotlin.Unit
|
||||
|
||||
public final class Delegate</*0*/ F> {
|
||||
public constructor Delegate</*0*/ F>()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun getValue(/*0*/ thisRef: kotlin.Any?, /*1*/ property: kotlin.reflect.KProperty<*>): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final operator fun setValue(/*0*/ thisRef: kotlin.Any?, /*1*/ property: kotlin.reflect.KProperty<*>, /*2*/ value: kotlin.String): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -5133,6 +5133,16 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
runTest("compiler/testData/diagnostics/tests/declarationChecks/LocalVariableWithNoTypeInformation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localVariablesWithTypeParameters_1_3.kt")
|
||||
public void testLocalVariablesWithTypeParameters_1_3() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_3.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localVariablesWithTypeParameters_1_4.kt")
|
||||
public void testLocalVariablesWithTypeParameters_1_4() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_4.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("mulitpleVarargParameters.kt")
|
||||
public void testMulitpleVarargParameters() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/declarationChecks/mulitpleVarargParameters.kt");
|
||||
|
||||
Generated
+10
@@ -5133,6 +5133,16 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
||||
runTest("compiler/testData/diagnostics/tests/declarationChecks/LocalVariableWithNoTypeInformation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localVariablesWithTypeParameters_1_3.kt")
|
||||
public void testLocalVariablesWithTypeParameters_1_3() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_3.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localVariablesWithTypeParameters_1_4.kt")
|
||||
public void testLocalVariablesWithTypeParameters_1_4() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_4.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("mulitpleVarargParameters.kt")
|
||||
public void testMulitpleVarargParameters() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/declarationChecks/mulitpleVarargParameters.kt");
|
||||
|
||||
@@ -94,6 +94,7 @@ enum class LanguageFeature(
|
||||
WarningOnMainUnusedParameter(KOTLIN_1_4),
|
||||
PolymorphicSignature(KOTLIN_1_4),
|
||||
ProhibitConcurrentHashMapContains(KOTLIN_1_4, kind = BUG_FIX),
|
||||
ProhibitTypeParametersForLocalVariables(KOTLIN_1_4, kind = BUG_FIX),
|
||||
|
||||
ProperVisibilityForCompanionObjectInstanceField(sinceVersion = null, kind = BUG_FIX),
|
||||
// Temporarily disabled, see KT-27084/KT-22379
|
||||
|
||||
@@ -271,6 +271,9 @@ class QuickFixRegistrar : QuickFixContributor {
|
||||
|
||||
TYPE_ARGUMENTS_REDUNDANT_IN_SUPER_QUALIFIER.registerFactory(RemovePsiElementSimpleFix.RemoveTypeArgumentsFactory)
|
||||
|
||||
LOCAL_VARIABLE_WITH_TYPE_PARAMETERS.registerFactory(RemovePsiElementSimpleFix.RemoveTypeParametersFactory)
|
||||
LOCAL_VARIABLE_WITH_TYPE_PARAMETERS_WARNING.registerFactory(RemovePsiElementSimpleFix.RemoveTypeParametersFactory)
|
||||
|
||||
UNCHECKED_CAST.registerFactory(ChangeToStarProjectionFix)
|
||||
CANNOT_CHECK_FOR_ERASED.registerFactory(ChangeToStarProjectionFix)
|
||||
|
||||
|
||||
@@ -58,6 +58,13 @@ open class RemovePsiElementSimpleFix(element: PsiElement, private val text: Stri
|
||||
}
|
||||
}
|
||||
|
||||
object RemoveTypeParametersFactory : KotlinSingleIntentionActionFactory() {
|
||||
public override fun createAction(diagnostic: Diagnostic): KotlinQuickFixAction<PsiElement>? {
|
||||
val element = diagnostic.psiElement.getNonStrictParentOfType<KtTypeParameterList>() ?: return null
|
||||
return RemovePsiElementSimpleFix(element, "Remove type parameters")
|
||||
}
|
||||
}
|
||||
|
||||
object RemoveVariableFactory : KotlinSingleIntentionActionFactory() {
|
||||
public override fun createAction(diagnostic: Diagnostic): KotlinQuickFixAction<PsiElement>? {
|
||||
val expression = diagnostic.psiElement.getNonStrictParentOfType<KtProperty>() ?: return null
|
||||
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
// "Remove type parameters" "true"
|
||||
|
||||
fun test() {
|
||||
val <caret><T : unresovled_reference, K> x = 0
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
// "Remove type parameters" "true"
|
||||
|
||||
fun test() {
|
||||
val x = 0
|
||||
}
|
||||
+13
@@ -2840,6 +2840,19 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/localVariableWithTypeParameters")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class LocalVariableWithTypeParameters extends AbstractQuickFixMultiFileTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTestWithExtraFile, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInLocalVariableWithTypeParameters() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/localVariableWithTypeParameters"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), TargetBackend.ANY, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/makeConstructorParameterProperty")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -7415,6 +7415,24 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/localVariableWithTypeParameters")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class LocalVariableWithTypeParameters extends AbstractQuickFixTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInLocalVariableWithTypeParameters() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/localVariableWithTypeParameters"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("removeTypeParametersFromLocalVariable.kt")
|
||||
public void testRemoveTypeParametersFromLocalVariable() throws Exception {
|
||||
runTest("idea/testData/quickfix/localVariableWithTypeParameters/removeTypeParametersFromLocalVariable.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/makeConstructorParameterProperty")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user