From 09d6e2e0c0852c2e6fac76c478e93d295c29f215 Mon Sep 17 00:00:00 2001 From: Kirill Rakhman Date: Thu, 13 Oct 2016 19:29:27 +0200 Subject: [PATCH] Add quick-fixes for lateinit-related errors #KT-14342 Fixed --- .../quickfix/ChangeVariableMutabilityFix.kt | 10 +++++++++ .../kotlin/idea/quickfix/QuickFixRegistrar.kt | 5 ++++- .../kotlin/idea/quickfix/RemoveNullableFix.kt | 17 ++++++++++++++- idea/testData/quickfix/lateinit/nullable.kt | 5 +++++ .../quickfix/lateinit/nullable.kt.after | 5 +++++ idea/testData/quickfix/lateinit/val.kt | 5 +++++ idea/testData/quickfix/lateinit/val.kt.after | 5 +++++ .../idea/quickfix/QuickFixTestGenerated.java | 21 +++++++++++++++++++ 8 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 idea/testData/quickfix/lateinit/nullable.kt create mode 100644 idea/testData/quickfix/lateinit/nullable.kt.after create mode 100644 idea/testData/quickfix/lateinit/val.kt create mode 100644 idea/testData/quickfix/lateinit/val.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt index 79f27879f1c..a98978ef6c2 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1 import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils class ChangeVariableMutabilityFix(element: KtValVarKeywordOwner, private val makeVar: Boolean) : KotlinQuickFixAction(element) { @@ -81,5 +82,14 @@ class ChangeVariableMutabilityFix(element: KtValVarKeywordOwner, private val mak return ChangeVariableMutabilityFix(element, false) } } + + val LATEINIT_VAL_FACTORY = object: KotlinSingleIntentionActionFactory() { + override fun createAction(diagnostic: Diagnostic): IntentionAction? { + val lateinitElement = Errors.INAPPLICABLE_LATEINIT_MODIFIER.cast(diagnostic).psiElement + val property = lateinitElement.getStrictParentOfType() ?: return null + if (property.valOrVarKeyword.text != "val") return null + return ChangeVariableMutabilityFix(property, makeVar = true) + } + } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt index 2b783019807..9ceb8cfa08d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. + * Copyright 2010-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -434,5 +434,8 @@ class QuickFixRegistrar : QuickFixContributor { UNUSED_VALUE.registerFactory(RemoveUnusedValueFix) ANNOTATIONS_ON_BLOCK_LEVEL_EXPRESSION_ON_THE_SAME_LINE.registerFactory(AddNewLineAfterAnnotationsFix) + + INAPPLICABLE_LATEINIT_MODIFIER.registerFactory(ChangeVariableMutabilityFix.LATEINIT_VAL_FACTORY) + INAPPLICABLE_LATEINIT_MODIFIER.registerFactory(RemoveNullableFix.LATEINIT_FACTORY) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveNullableFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveNullableFix.kt index 7dabc48141b..81360979d1f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveNullableFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveNullableFix.kt @@ -19,16 +19,20 @@ package org.jetbrains.kotlin.idea.quickfix import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project import org.jetbrains.kotlin.diagnostics.Diagnostic +import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtNullableType +import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType +import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType class RemoveNullableFix(element: KtNullableType, private val typeOfError: RemoveNullableFix.NullableKind) : KotlinQuickFixAction(element) { enum class NullableKind(val message: String) { REDUNDANT("Remove redundant '?'"), SUPERTYPE("Remove '?'"), - USELESS("Remove useless '?'") + USELESS("Remove useless '?'"), + PROPERTY("Make not-nullable") } override fun getFamilyName() = "Remove '?'" @@ -47,4 +51,15 @@ class RemoveNullableFix(element: KtNullableType, return RemoveNullableFix(nullType, typeOfError) } } + + object LATEINIT_FACTORY : KotlinSingleIntentionActionFactory() { + override fun createAction(diagnostic: Diagnostic): KotlinQuickFixAction? { + val lateinitElement = Errors.INAPPLICABLE_LATEINIT_MODIFIER.cast(diagnostic).psiElement + val property = lateinitElement.getStrictParentOfType() ?: return null + val typeReference = property.typeReference ?: return null + val typeElement = (typeReference.typeElement ?: return null) as? KtNullableType ?: return null + if (typeElement.innerType == null) return null + return RemoveNullableFix(typeElement, NullableKind.PROPERTY) + } + } } diff --git a/idea/testData/quickfix/lateinit/nullable.kt b/idea/testData/quickfix/lateinit/nullable.kt new file mode 100644 index 00000000000..845cc34778a --- /dev/null +++ b/idea/testData/quickfix/lateinit/nullable.kt @@ -0,0 +1,5 @@ +// "Make not-nullable" "true" + +class A() { + lateinit var foo: String? +} \ No newline at end of file diff --git a/idea/testData/quickfix/lateinit/nullable.kt.after b/idea/testData/quickfix/lateinit/nullable.kt.after new file mode 100644 index 00000000000..ad81581c0c2 --- /dev/null +++ b/idea/testData/quickfix/lateinit/nullable.kt.after @@ -0,0 +1,5 @@ +// "Make not-nullable" "true" + +class A() { + lateinit var foo: String +} \ No newline at end of file diff --git a/idea/testData/quickfix/lateinit/val.kt b/idea/testData/quickfix/lateinit/val.kt new file mode 100644 index 00000000000..307674870fc --- /dev/null +++ b/idea/testData/quickfix/lateinit/val.kt @@ -0,0 +1,5 @@ +// "Make variable mutable" "true" + +class A() { + lateinit val foo: String +} \ No newline at end of file diff --git a/idea/testData/quickfix/lateinit/val.kt.after b/idea/testData/quickfix/lateinit/val.kt.after new file mode 100644 index 00000000000..3853b8ebf97 --- /dev/null +++ b/idea/testData/quickfix/lateinit/val.kt.after @@ -0,0 +1,5 @@ +// "Make variable mutable" "true" + +class A() { + lateinit var foo: String +} \ 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 3a8134d4019..bfbeab0503c 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -5675,6 +5675,27 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } } + @TestMetadata("idea/testData/quickfix/lateinit") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Lateinit extends AbstractQuickFixTest { + public void testAllFilesPresentInLateinit() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/lateinit"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true); + } + + @TestMetadata("nullable.kt") + public void testNullable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/lateinit/nullable.kt"); + doTest(fileName); + } + + @TestMetadata("val.kt") + public void testVal() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/lateinit/val.kt"); + doTest(fileName); + } + } + @TestMetadata("idea/testData/quickfix/leakingThis") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)