From 0d80bf030fe2b6bc03a8fcbb2c6bf9a926da92e6 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Mon, 20 Jun 2016 15:52:41 +0300 Subject: [PATCH] Create from Usage: Fix exception in "Create class" quickfix applied to unresolved references in type arguments. Create class body when necessary #KT-12777 Fixed (cherry picked from commit dc90ec9) --- ChangeLog.md | 1 + .../callableBuilder/CallableBuilder.kt | 5 +++-- .../nestedClassByTypeArgumentRefNoBody.kt | 4 ++++ .../nestedClassByTypeArgumentRefNoBody.kt.after | 8 ++++++++ .../nestedClassByTypeArgumentRefWithBody.kt | 6 ++++++ .../nestedClassByTypeArgumentRefWithBody.kt.after | 9 +++++++++ .../kotlin/idea/quickfix/QuickFixTestGenerated.java | 12 ++++++++++++ 7 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 idea/testData/quickfix/createFromUsage/createClass/typeReference/nestedClassByTypeArgumentRefNoBody.kt create mode 100644 idea/testData/quickfix/createFromUsage/createClass/typeReference/nestedClassByTypeArgumentRefNoBody.kt.after create mode 100644 idea/testData/quickfix/createFromUsage/createClass/typeReference/nestedClassByTypeArgumentRefWithBody.kt create mode 100644 idea/testData/quickfix/createFromUsage/createClass/typeReference/nestedClassByTypeArgumentRefWithBody.kt.after diff --git a/ChangeLog.md b/ChangeLog.md index 4f6381e64bf..e967f37805c 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -208,6 +208,7 @@ - [`KT-11975`](https://youtrack.jetbrains.com/issue/KT-11975) "Invert if-condition" intention does not simplify `is` expression - [`KT-12437`](https://youtrack.jetbrains.com/issue/KT-12437) "Replace explicit parameter" intention is suggested for parameter of inner lambda in presence of `it` from outer lambda - [`KT-12376`](https://youtrack.jetbrains.com/issue/KT-12376) Don't show "Package directive doesn't match file location" in injected code +- [`KT-12777`](https://youtrack.jetbrains.com/issue/KT-12777) Fix exception in "Create class" quickfix applied to unresolved references in type arguments #### Language injection diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/callableBuilder/CallableBuilder.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/callableBuilder/CallableBuilder.kt index ef768735efa..00e8e46ec42 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/callableBuilder/CallableBuilder.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/callableBuilder/CallableBuilder.kt @@ -531,8 +531,9 @@ class CallableBuilder(val config: CallableBuilderConfiguration) { return Math.max(lineBreaksNeeded - lineBreaksPresent, 0) } + val actualContainer = (containingElement as? KtClassOrObject)?.getOrCreateBody() ?: containingElement + fun addNextToOriginalElementContainer(addBefore: Boolean): KtNamedDeclaration { - val actualContainer = (containingElement as? KtClassOrObject)?.getBody() ?: containingElement val sibling = config.originalElement.parentsWithSelf.first { it.parent == actualContainer } return if (addBefore) { actualContainer.addBefore(declaration, sibling) @@ -543,7 +544,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) { } val declarationInPlace = when { - containingElement.isAncestor(config.originalElement, true) -> { + actualContainer.isAncestor(config.originalElement, true) -> { val insertToBlock = containingElement is KtBlockExpression if (insertToBlock) { val parent = containingElement.parent diff --git a/idea/testData/quickfix/createFromUsage/createClass/typeReference/nestedClassByTypeArgumentRefNoBody.kt b/idea/testData/quickfix/createFromUsage/createClass/typeReference/nestedClassByTypeArgumentRefNoBody.kt new file mode 100644 index 00000000000..0818240c241 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createClass/typeReference/nestedClassByTypeArgumentRefNoBody.kt @@ -0,0 +1,4 @@ +// "Create class 'X'" "true" +open class A + +class B : AX>() \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createClass/typeReference/nestedClassByTypeArgumentRefNoBody.kt.after b/idea/testData/quickfix/createFromUsage/createClass/typeReference/nestedClassByTypeArgumentRefNoBody.kt.after new file mode 100644 index 00000000000..b3bc00cbf02 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createClass/typeReference/nestedClassByTypeArgumentRefNoBody.kt.after @@ -0,0 +1,8 @@ +// "Create class 'X'" "true" +open class A + +class B : A() { + class X { + + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createClass/typeReference/nestedClassByTypeArgumentRefWithBody.kt b/idea/testData/quickfix/createFromUsage/createClass/typeReference/nestedClassByTypeArgumentRefWithBody.kt new file mode 100644 index 00000000000..737d3a2e43f --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createClass/typeReference/nestedClassByTypeArgumentRefWithBody.kt @@ -0,0 +1,6 @@ +// "Create class 'X'" "true" +open class A + +class B : AX>() { + +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createClass/typeReference/nestedClassByTypeArgumentRefWithBody.kt.after b/idea/testData/quickfix/createFromUsage/createClass/typeReference/nestedClassByTypeArgumentRefWithBody.kt.after new file mode 100644 index 00000000000..a85d9156c50 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createClass/typeReference/nestedClassByTypeArgumentRefWithBody.kt.after @@ -0,0 +1,9 @@ +// "Create class 'X'" "true" +open class A + +class B : A() { + class X { + + } + +} \ 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 c35d6efc07e..423ca4a19b8 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -1788,6 +1788,18 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("nestedClassByTypeArgumentRefNoBody.kt") + public void testNestedClassByTypeArgumentRefNoBody() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createClass/typeReference/nestedClassByTypeArgumentRefNoBody.kt"); + doTest(fileName); + } + + @TestMetadata("nestedClassByTypeArgumentRefWithBody.kt") + public void testNestedClassByTypeArgumentRefWithBody() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createClass/typeReference/nestedClassByTypeArgumentRefWithBody.kt"); + doTest(fileName); + } + @TestMetadata("objectNotQualifierNoTypeArgs.kt") public void testObjectNotQualifierNoTypeArgs() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createClass/typeReference/objectNotQualifierNoTypeArgs.kt");