From 5fb79259f71af20ba5b007c9a466aa051d0f53f5 Mon Sep 17 00:00:00 2001 From: shiraji Date: Tue, 26 Jul 2016 01:12:50 +0300 Subject: [PATCH] Intention / inspection for unnecessary lateinit #KT-13011 Fixed (cherry picked from commit 45d82f1) --- .../RemoveUnnecessaryLateinit.html | 5 ++ .../after.kt.template | 7 ++ .../before.kt.template | 7 ++ .../description.html | 5 ++ idea/src/META-INF/plugin.xml | 13 +++ .../RemoveUnnecessaryLateinitIntention.kt | 87 +++++++++++++++++++ .../removeUnnecessaryLateinit/.intention | 1 + .../lateinitWithConstructor.kt | 9 ++ .../lateinitWithConstructor.kt.after | 9 ++ .../lateinitWithErroneousDelegation.kt | 12 +++ .../lateinitWithInit.kt | 9 ++ .../lateinitWithInit.kt.after | 9 ++ .../lateinitWithMultipleConstructors.kt | 13 +++ .../lateinitWithMultipleConstructors.kt.after | 13 +++ ...itWithMultipleConstructorsAndDelegation.kt | 15 ++++ ...MultipleConstructorsAndDelegation.kt.after | 15 ++++ .../lateinitWithMultipleInit.kt | 14 +++ .../lateinitWithMultipleInit.kt.after | 14 +++ .../lateinitWithPlusAssign.kt | 9 ++ ...nitWithPrimaryConstructorAndConstructor.kt | 9 ++ .../normalLateinit.kt | 9 ++ .../secondaryConstructorDelegateItself.kt | 14 +++ ...econdaryConstructorDelegateItself.kt.after | 14 +++ .../secondaryConstructorDelegateLoop.kt | 21 +++++ .../secondaryConstructorDelegateSuper.kt | 14 +++ .../intentions/IntentionTestGenerated.java | 81 +++++++++++++++++ 26 files changed, 428 insertions(+) create mode 100644 idea/resources/inspectionDescriptions/RemoveUnnecessaryLateinit.html create mode 100644 idea/resources/intentionDescriptions/RemoveUnnecessaryLateinitIntention/after.kt.template create mode 100644 idea/resources/intentionDescriptions/RemoveUnnecessaryLateinitIntention/before.kt.template create mode 100644 idea/resources/intentionDescriptions/RemoveUnnecessaryLateinitIntention/description.html create mode 100644 idea/src/org/jetbrains/kotlin/idea/intentions/RemoveUnnecessaryLateinitIntention.kt create mode 100644 idea/testData/intentions/removeUnnecessaryLateinit/.intention create mode 100644 idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithConstructor.kt create mode 100644 idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithConstructor.kt.after create mode 100644 idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithErroneousDelegation.kt create mode 100644 idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithInit.kt create mode 100644 idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithInit.kt.after create mode 100644 idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleConstructors.kt create mode 100644 idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleConstructors.kt.after create mode 100644 idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleConstructorsAndDelegation.kt create mode 100644 idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleConstructorsAndDelegation.kt.after create mode 100644 idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleInit.kt create mode 100644 idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleInit.kt.after create mode 100644 idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithPlusAssign.kt create mode 100644 idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithPrimaryConstructorAndConstructor.kt create mode 100644 idea/testData/intentions/removeUnnecessaryLateinit/normalLateinit.kt create mode 100644 idea/testData/intentions/removeUnnecessaryLateinit/secondaryConstructorDelegateItself.kt create mode 100644 idea/testData/intentions/removeUnnecessaryLateinit/secondaryConstructorDelegateItself.kt.after create mode 100644 idea/testData/intentions/removeUnnecessaryLateinit/secondaryConstructorDelegateLoop.kt create mode 100644 idea/testData/intentions/removeUnnecessaryLateinit/secondaryConstructorDelegateSuper.kt diff --git a/idea/resources/inspectionDescriptions/RemoveUnnecessaryLateinit.html b/idea/resources/inspectionDescriptions/RemoveUnnecessaryLateinit.html new file mode 100644 index 00000000000..2d6647dd968 --- /dev/null +++ b/idea/resources/inspectionDescriptions/RemoveUnnecessaryLateinit.html @@ -0,0 +1,5 @@ + + +This inspection detects lateinit that can be safely removed + + \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/RemoveUnnecessaryLateinitIntention/after.kt.template b/idea/resources/intentionDescriptions/RemoveUnnecessaryLateinitIntention/after.kt.template new file mode 100644 index 00000000000..5b7cd1e2379 --- /dev/null +++ b/idea/resources/intentionDescriptions/RemoveUnnecessaryLateinitIntention/after.kt.template @@ -0,0 +1,7 @@ +class My { + var x: String + + init { + x = "My" + } +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/RemoveUnnecessaryLateinitIntention/before.kt.template b/idea/resources/intentionDescriptions/RemoveUnnecessaryLateinitIntention/before.kt.template new file mode 100644 index 00000000000..7924d662dbf --- /dev/null +++ b/idea/resources/intentionDescriptions/RemoveUnnecessaryLateinitIntention/before.kt.template @@ -0,0 +1,7 @@ +class My { + lateinit var x: String + + init { + x = "My" + } +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/RemoveUnnecessaryLateinitIntention/description.html b/idea/resources/intentionDescriptions/RemoveUnnecessaryLateinitIntention/description.html new file mode 100644 index 00000000000..b01afecd641 --- /dev/null +++ b/idea/resources/intentionDescriptions/RemoveUnnecessaryLateinitIntention/description.html @@ -0,0 +1,5 @@ + + +This intention removes unnecessary lateinit modifiers. + + \ No newline at end of file diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 5b3cb0709ce..4d59a799235 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -1273,6 +1273,11 @@ Kotlin + + org.jetbrains.kotlin.idea.intentions.RemoveUnnecessaryLateinitIntention + Kotlin + + org.jetbrains.kotlin.idea.intentions.RemoveSingleExpressionStringTemplateIntention Kotlin @@ -1641,6 +1646,14 @@ language="kotlin" /> + + (RemoveUnnecessaryLateinitIntention()) { + override val problemHighlightType = ProblemHighlightType.LIKE_UNUSED_SYMBOL + + override val problemText = "Unnecessary lateinit" +} + +class RemoveUnnecessaryLateinitIntention : SelfTargetingRangeIntention(KtProperty::class.java, "Remove unnecessary lateinit") { + override fun applicabilityRange(element: KtProperty): TextRange? { + if (!element.hasModifier(KtTokens.LATEINIT_KEYWORD)) return null + val ktClass = element.getStrictParentOfType() ?: return null + if (ktClass.getAnonymousInitializers().any { hasAssignmentStatements(it.body, element) }) { + return element.lateinitTextRange() + } + if (ktClass.hasPrimaryConstructor()) return null + val secondaryConstructors = ktClass.getSecondaryConstructors() + + val secondaryConstructorsInfo = secondaryConstructors.map { secondaryConstructor -> + val delegationCall = secondaryConstructor.getDelegationCall() + val hasAssignmentStatements = hasAssignmentStatements(secondaryConstructor.bodyExpression, element) + if (!hasAssignmentStatements && !delegationCall.isCallToThis) return null + val resolvedCall = delegationCall.getResolvedCall(delegationCall.analyzeFully()) ?: return null + val delegationCallIndex = secondaryConstructors.indexOfFirst { + DescriptorToSourceUtils.descriptorToDeclaration(resolvedCall.resultingDescriptor) == it + } + SecondaryConstructorInfo(hasAssignmentStatements, delegationCallIndex) + } + return if (assignmentReachableFromAnySecondaryConstructor(secondaryConstructorsInfo)) element.lateinitTextRange() + else null + } + + private fun assignmentReachableFromAnySecondaryConstructor(constructorsInfo: List): Boolean { + constructorsInfo.forEach { + val visitedInfo = hashSetOf() + var currentConstructor = it + while (!currentConstructor.hasAssignmentStatement) { + if (!visitedInfo.add(currentConstructor)) return false + currentConstructor = constructorsInfo.getOrNull(currentConstructor.delegationCallIndex) ?: return false + } + } + return true + } + + private fun KtProperty.lateinitTextRange() = modifierList?.getModifier(KtTokens.LATEINIT_KEYWORD)?.range + + private fun hasAssignmentStatements(body: KtExpression?, property: KtProperty) = + body?.children?.any { + it is KtBinaryExpression && + it.operationToken === KtTokens.EQ && + it.left?.text == property.name + } ?: false + + override fun applyTo(element: KtProperty, editor: Editor?) { + element.removeModifier(KtTokens.LATEINIT_KEYWORD) + } +} + +private data class SecondaryConstructorInfo(val hasAssignmentStatement: Boolean, val delegationCallIndex: Int) \ No newline at end of file diff --git a/idea/testData/intentions/removeUnnecessaryLateinit/.intention b/idea/testData/intentions/removeUnnecessaryLateinit/.intention new file mode 100644 index 00000000000..f6e91edcea8 --- /dev/null +++ b/idea/testData/intentions/removeUnnecessaryLateinit/.intention @@ -0,0 +1 @@ +org.jetbrains.kotlin.idea.intentions.RemoveUnnecessaryLateinitIntention \ No newline at end of file diff --git a/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithConstructor.kt b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithConstructor.kt new file mode 100644 index 00000000000..8721d280e41 --- /dev/null +++ b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithConstructor.kt @@ -0,0 +1,9 @@ +// INTENTION_TEXT: Remove unnecessary lateinit + +class Foo { + lateinit var bar: String + + constructor(baz: Int) { + bar = "" + } +} diff --git a/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithConstructor.kt.after b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithConstructor.kt.after new file mode 100644 index 00000000000..b731a7b979c --- /dev/null +++ b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithConstructor.kt.after @@ -0,0 +1,9 @@ +// INTENTION_TEXT: Remove unnecessary lateinit + +class Foo { + var bar: String + + constructor(baz: Int) { + bar = "" + } +} \ No newline at end of file diff --git a/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithErroneousDelegation.kt b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithErroneousDelegation.kt new file mode 100644 index 00000000000..3d660fe7e1e --- /dev/null +++ b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithErroneousDelegation.kt @@ -0,0 +1,12 @@ +// IS_APPLICABLE: false +// ERROR: None of the following functions can be called with the arguments supplied:
public constructor Foo() defined in Foo
public constructor Foo(x: String, y: String) defined in Foo + +class Foo { + lateinit var x: String + + constructor() { + x = "Foo" + } + + constructor(x: String, y: String): this(y.hashCode()) +} \ No newline at end of file diff --git a/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithInit.kt b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithInit.kt new file mode 100644 index 00000000000..3edcc6dea88 --- /dev/null +++ b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithInit.kt @@ -0,0 +1,9 @@ +// INTENTION_TEXT: Remove unnecessary lateinit + +class Foo { + lateinit var bar: String + + init { + bar = "" + } +} \ No newline at end of file diff --git a/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithInit.kt.after b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithInit.kt.after new file mode 100644 index 00000000000..8e75eb92fce --- /dev/null +++ b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithInit.kt.after @@ -0,0 +1,9 @@ +// INTENTION_TEXT: Remove unnecessary lateinit + +class Foo { + var bar: String + + init { + bar = "" + } +} \ No newline at end of file diff --git a/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleConstructors.kt b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleConstructors.kt new file mode 100644 index 00000000000..f8bc360ff75 --- /dev/null +++ b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleConstructors.kt @@ -0,0 +1,13 @@ +// INTENTION_TEXT: Remove unnecessary lateinit + +class Foo { + lateinit var bar: String + + constructor() { + bar = "" + } + + constructor(baz: Int) { + bar = "" + } +} \ No newline at end of file diff --git a/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleConstructors.kt.after b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleConstructors.kt.after new file mode 100644 index 00000000000..a697dc99bc3 --- /dev/null +++ b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleConstructors.kt.after @@ -0,0 +1,13 @@ +// INTENTION_TEXT: Remove unnecessary lateinit + +class Foo { + var bar: String + + constructor() { + bar = "" + } + + constructor(baz: Int) { + bar = "" + } +} \ No newline at end of file diff --git a/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleConstructorsAndDelegation.kt b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleConstructorsAndDelegation.kt new file mode 100644 index 00000000000..62551652dbb --- /dev/null +++ b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleConstructorsAndDelegation.kt @@ -0,0 +1,15 @@ +// INTENTION_TEXT: Remove unnecessary lateinit + +class Foo { + lateinit var bar: String + + constructor() { + bar = "" + } + + constructor(a: Int) : this() { + } + + constructor(a: Int, b: Int) : this(a) { + } +} \ No newline at end of file diff --git a/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleConstructorsAndDelegation.kt.after b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleConstructorsAndDelegation.kt.after new file mode 100644 index 00000000000..98f2d958c46 --- /dev/null +++ b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleConstructorsAndDelegation.kt.after @@ -0,0 +1,15 @@ +// INTENTION_TEXT: Remove unnecessary lateinit + +class Foo { + var bar: String + + constructor() { + bar = "" + } + + constructor(a: Int) : this() { + } + + constructor(a: Int, b: Int) : this(a) { + } +} \ No newline at end of file diff --git a/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleInit.kt b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleInit.kt new file mode 100644 index 00000000000..15de7563f5c --- /dev/null +++ b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleInit.kt @@ -0,0 +1,14 @@ +// INTENTION_TEXT: Remove unnecessary lateinit + +class Foo { + lateinit var bar: String + var baz: Int + + init { + baz = 1 + } + + init { + bar = "" + } +} \ No newline at end of file diff --git a/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleInit.kt.after b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleInit.kt.after new file mode 100644 index 00000000000..b97dd3391e8 --- /dev/null +++ b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleInit.kt.after @@ -0,0 +1,14 @@ +// INTENTION_TEXT: Remove unnecessary lateinit + +class Foo { + var bar: String + var baz: Int + + init { + baz = 1 + } + + init { + bar = "" + } +} \ No newline at end of file diff --git a/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithPlusAssign.kt b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithPlusAssign.kt new file mode 100644 index 00000000000..9f79369317c --- /dev/null +++ b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithPlusAssign.kt @@ -0,0 +1,9 @@ +// IS_APPLICABLE: false + +class Foo { + lateinit var bar: String + + constructor(baz: Int) { + bar += baz + } +} diff --git a/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithPrimaryConstructorAndConstructor.kt b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithPrimaryConstructorAndConstructor.kt new file mode 100644 index 00000000000..7fb92d4e2e9 --- /dev/null +++ b/idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithPrimaryConstructorAndConstructor.kt @@ -0,0 +1,9 @@ +// IS_APPLICABLE: false + +class Foo() { + lateinit var bar: String + + constructor(baz: Int) : this() { + bar = "" + } +} \ No newline at end of file diff --git a/idea/testData/intentions/removeUnnecessaryLateinit/normalLateinit.kt b/idea/testData/intentions/removeUnnecessaryLateinit/normalLateinit.kt new file mode 100644 index 00000000000..b832a36b4b0 --- /dev/null +++ b/idea/testData/intentions/removeUnnecessaryLateinit/normalLateinit.kt @@ -0,0 +1,9 @@ +// IS_APPLICABLE: false + +class Foo { + lateinit var bar: String + + fun init() { + bar = "" + } +} \ No newline at end of file diff --git a/idea/testData/intentions/removeUnnecessaryLateinit/secondaryConstructorDelegateItself.kt b/idea/testData/intentions/removeUnnecessaryLateinit/secondaryConstructorDelegateItself.kt new file mode 100644 index 00000000000..fd8139b4dd3 --- /dev/null +++ b/idea/testData/intentions/removeUnnecessaryLateinit/secondaryConstructorDelegateItself.kt @@ -0,0 +1,14 @@ +// IS_APPLICABLE: true +// ERROR: There's a cycle in the delegation calls chain + +class Foo { + lateinit var bar: String + + constructor() { + bar = "" + } + + constructor(a: Int) : this(a) { + bar = "a" + } +} diff --git a/idea/testData/intentions/removeUnnecessaryLateinit/secondaryConstructorDelegateItself.kt.after b/idea/testData/intentions/removeUnnecessaryLateinit/secondaryConstructorDelegateItself.kt.after new file mode 100644 index 00000000000..bfc1aa5e888 --- /dev/null +++ b/idea/testData/intentions/removeUnnecessaryLateinit/secondaryConstructorDelegateItself.kt.after @@ -0,0 +1,14 @@ +// IS_APPLICABLE: true +// ERROR: There's a cycle in the delegation calls chain + +class Foo { + var bar: String + + constructor() { + bar = "" + } + + constructor(a: Int) : this(a) { + bar = "a" + } +} diff --git a/idea/testData/intentions/removeUnnecessaryLateinit/secondaryConstructorDelegateLoop.kt b/idea/testData/intentions/removeUnnecessaryLateinit/secondaryConstructorDelegateLoop.kt new file mode 100644 index 00000000000..b2dc4b78cbc --- /dev/null +++ b/idea/testData/intentions/removeUnnecessaryLateinit/secondaryConstructorDelegateLoop.kt @@ -0,0 +1,21 @@ +// IS_APPLICABLE: false +// ERROR: There's a cycle in the delegation calls chain +// ERROR: There's a cycle in the delegation calls chain +// ERROR: There's a cycle in the delegation calls chain + +class Foo { + lateinit var bar: String + + constructor() { + bar = "" + } + + constructor(a: Int) : this(a, 0, 0) { + } + + constructor(a: Int, b: Int) : this(a) { + } + + constructor(a: Int, b: Int, c: Int) : this(a, b) { + } +} diff --git a/idea/testData/intentions/removeUnnecessaryLateinit/secondaryConstructorDelegateSuper.kt b/idea/testData/intentions/removeUnnecessaryLateinit/secondaryConstructorDelegateSuper.kt new file mode 100644 index 00000000000..bae359bf99d --- /dev/null +++ b/idea/testData/intentions/removeUnnecessaryLateinit/secondaryConstructorDelegateSuper.kt @@ -0,0 +1,14 @@ +// IS_APPLICABLE: false + +open class Bar(val a: Int = 0) + +class Foo : Bar { + lateinit var bar: String + + constructor() : super() { + bar = "" + } + + constructor(a: Int) : super(a) { + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index df90a370410..2594b39009e 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -8531,6 +8531,87 @@ public class IntentionTestGenerated extends AbstractIntentionTest { } } + @TestMetadata("idea/testData/intentions/removeUnnecessaryLateinit") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class RemoveUnnecessaryLateinit extends AbstractIntentionTest { + public void testAllFilesPresentInRemoveUnnecessaryLateinit() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/removeUnnecessaryLateinit"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true); + } + + @TestMetadata("lateinitWithConstructor.kt") + public void testLateinitWithConstructor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithConstructor.kt"); + doTest(fileName); + } + + @TestMetadata("lateinitWithErroneousDelegation.kt") + public void testLateinitWithErroneousDelegation() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithErroneousDelegation.kt"); + doTest(fileName); + } + + @TestMetadata("lateinitWithInit.kt") + public void testLateinitWithInit() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithInit.kt"); + doTest(fileName); + } + + @TestMetadata("lateinitWithMultipleConstructors.kt") + public void testLateinitWithMultipleConstructors() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleConstructors.kt"); + doTest(fileName); + } + + @TestMetadata("lateinitWithMultipleConstructorsAndDelegation.kt") + public void testLateinitWithMultipleConstructorsAndDelegation() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleConstructorsAndDelegation.kt"); + doTest(fileName); + } + + @TestMetadata("lateinitWithMultipleInit.kt") + public void testLateinitWithMultipleInit() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithMultipleInit.kt"); + doTest(fileName); + } + + @TestMetadata("lateinitWithPlusAssign.kt") + public void testLateinitWithPlusAssign() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithPlusAssign.kt"); + doTest(fileName); + } + + @TestMetadata("lateinitWithPrimaryConstructorAndConstructor.kt") + public void testLateinitWithPrimaryConstructorAndConstructor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeUnnecessaryLateinit/lateinitWithPrimaryConstructorAndConstructor.kt"); + doTest(fileName); + } + + @TestMetadata("normalLateinit.kt") + public void testNormalLateinit() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeUnnecessaryLateinit/normalLateinit.kt"); + doTest(fileName); + } + + @TestMetadata("secondaryConstructorDelegateItself.kt") + public void testSecondaryConstructorDelegateItself() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeUnnecessaryLateinit/secondaryConstructorDelegateItself.kt"); + doTest(fileName); + } + + @TestMetadata("secondaryConstructorDelegateLoop.kt") + public void testSecondaryConstructorDelegateLoop() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeUnnecessaryLateinit/secondaryConstructorDelegateLoop.kt"); + doTest(fileName); + } + + @TestMetadata("secondaryConstructorDelegateSuper.kt") + public void testSecondaryConstructorDelegateSuper() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeUnnecessaryLateinit/secondaryConstructorDelegateSuper.kt"); + doTest(fileName); + } + } + @TestMetadata("idea/testData/intentions/removeUnnecessaryParentheses") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)