diff --git a/ChangeLog.md b/ChangeLog.md index 8759f2a9409..e9eff3a84b2 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -210,6 +210,7 @@ These artifacts include extensions for the types available in the latter JDKs, s - [`KT-13151`](https://youtrack.jetbrains.com/issue/KT-13151) Incorrect warning "Make variable immutable" - [`KT-13170`](https://youtrack.jetbrains.com/issue/KT-13170) "Declaration has platform type" inspection: by default should not be reported for platform type arguments - [`KT-13262`](https://youtrack.jetbrains.com/issue/KT-13262) "Wrap with safe let call" quickfix produces wrong result for qualified function +- [`KT-13364`](https://youtrack.jetbrains.com/issue/KT-13364) Do not suggest creating annotations/enum classes for unresolved type parameter bounds ##### New features diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromTypeReferenceActionFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromTypeReferenceActionFactory.kt index 9a2dd98f469..5a4587746f7 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromTypeReferenceActionFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromTypeReferenceActionFactory.kt @@ -20,10 +20,8 @@ import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.idea.caches.resolve.analyzeAndGetResult import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.TypeInfo -import org.jetbrains.kotlin.psi.KtConstructorCalleeExpression -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi.KtSuperTypeEntry -import org.jetbrains.kotlin.psi.KtUserType +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.types.Variance import java.util.* @@ -41,15 +39,19 @@ object CreateClassFromTypeReferenceActionFactory : CreateClassFromUsageFactory { extendsBound } != null + || typeReference?.getParentOfTypeAndBranch { boundTypeReference } != null + return when { interfaceExpected -> Collections.singletonList(ClassKind.INTERFACE) else -> ClassKind.values().filter { val noTypeArguments = element.typeArgumentsAsTypes.isEmpty() when (it) { ClassKind.OBJECT -> noTypeArguments && isQualifier - ClassKind.ANNOTATION_CLASS -> noTypeArguments && !isQualifier + ClassKind.ANNOTATION_CLASS -> noTypeArguments && !isQualifier && !isUpperBound ClassKind.ENUM_ENTRY -> false - ClassKind.ENUM_CLASS -> noTypeArguments + ClassKind.ENUM_CLASS -> noTypeArguments && !isUpperBound else -> true } } diff --git a/idea/testData/quickfix/createFromUsage/createClass/typeReference/noAnnotationForTypeBound.kt b/idea/testData/quickfix/createFromUsage/createClass/typeReference/noAnnotationForTypeBound.kt new file mode 100644 index 00000000000..f4eea7e0807 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createClass/typeReference/noAnnotationForTypeBound.kt @@ -0,0 +1,6 @@ +// "Create annotation 'NotExistent'" "false" +// ACTION: Create class 'NotExistent' +// ACTION: Create interface 'NotExistent' +// ACTION: Create test +// ERROR: Unresolved reference: NotExistent +class TPBNotExistent> \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createClass/typeReference/noAnnotationForTypeConstraint.kt b/idea/testData/quickfix/createFromUsage/createClass/typeReference/noAnnotationForTypeConstraint.kt new file mode 100644 index 00000000000..3c473c1ee00 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createClass/typeReference/noAnnotationForTypeConstraint.kt @@ -0,0 +1,6 @@ +// "Create annotation 'NotExistent'" "false" +// ACTION: Create class 'NotExistent' +// ACTION: Create interface 'NotExistent' +// ACTION: Create test +// ERROR: Unresolved reference: NotExistent +class TPB where X : NotExistent \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createClass/typeReference/noEnumForTypeBound.kt b/idea/testData/quickfix/createFromUsage/createClass/typeReference/noEnumForTypeBound.kt new file mode 100644 index 00000000000..0b461c355fa --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createClass/typeReference/noEnumForTypeBound.kt @@ -0,0 +1,6 @@ +// "Create enum 'NotExistent'" "false" +// ACTION: Create class 'NotExistent' +// ACTION: Create interface 'NotExistent' +// ACTION: Create test +// ERROR: Unresolved reference: NotExistent +class TPBNotExistent> \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createClass/typeReference/noEnumForTypeConstraint.kt b/idea/testData/quickfix/createFromUsage/createClass/typeReference/noEnumForTypeConstraint.kt new file mode 100644 index 00000000000..af4367437cd --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createClass/typeReference/noEnumForTypeConstraint.kt @@ -0,0 +1,6 @@ +// "Create enum 'NotExistent'" "false" +// ACTION: Create class 'NotExistent' +// ACTION: Create interface 'NotExistent' +// ACTION: Create test +// ERROR: Unresolved reference: NotExistent +class TPB where X : NotExistent \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createClass/typeReference/noObjectForTypeBound.kt b/idea/testData/quickfix/createFromUsage/createClass/typeReference/noObjectForTypeBound.kt new file mode 100644 index 00000000000..1aa841a73b7 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createClass/typeReference/noObjectForTypeBound.kt @@ -0,0 +1,6 @@ +// "Create object 'NotExistent'" "false" +// ACTION: Create class 'NotExistent' +// ACTION: Create interface 'NotExistent' +// ACTION: Create test +// ERROR: Unresolved reference: NotExistent +class TPBNotExistent> \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createClass/typeReference/noObjectForTypeConstraint.kt b/idea/testData/quickfix/createFromUsage/createClass/typeReference/noObjectForTypeConstraint.kt new file mode 100644 index 00000000000..e275b4524a9 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createClass/typeReference/noObjectForTypeConstraint.kt @@ -0,0 +1,6 @@ +// "Create object 'NotExistent'" "false" +// ACTION: Create class 'NotExistent' +// ACTION: Create interface 'NotExistent' +// ACTION: Create test +// ERROR: Unresolved reference: NotExistent +class TPB where X : NotExistent \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 172975b6d5a..65102a1da3a 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -1815,6 +1815,42 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("noAnnotationForTypeBound.kt") + public void testNoAnnotationForTypeBound() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createClass/typeReference/noAnnotationForTypeBound.kt"); + doTest(fileName); + } + + @TestMetadata("noAnnotationForTypeConstraint.kt") + public void testNoAnnotationForTypeConstraint() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createClass/typeReference/noAnnotationForTypeConstraint.kt"); + doTest(fileName); + } + + @TestMetadata("noEnumForTypeBound.kt") + public void testNoEnumForTypeBound() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createClass/typeReference/noEnumForTypeBound.kt"); + doTest(fileName); + } + + @TestMetadata("noEnumForTypeConstraint.kt") + public void testNoEnumForTypeConstraint() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createClass/typeReference/noEnumForTypeConstraint.kt"); + doTest(fileName); + } + + @TestMetadata("noObjectForTypeBound.kt") + public void testNoObjectForTypeBound() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createClass/typeReference/noObjectForTypeBound.kt"); + doTest(fileName); + } + + @TestMetadata("noObjectForTypeConstraint.kt") + public void testNoObjectForTypeConstraint() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createClass/typeReference/noObjectForTypeConstraint.kt"); + doTest(fileName); + } + @TestMetadata("objectNotQualifierNoTypeArgs.kt") public void testObjectNotQualifierNoTypeArgs() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createClass/typeReference/objectNotQualifierNoTypeArgs.kt");