Add quickfix for adding 'lateinit'
Fixes #KT-17650
This commit is contained in:
committed by
Mikhail Glukhikh
parent
5de55e80ce
commit
cd07aea5e3
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -136,6 +136,7 @@ private val MODIFIERS_TO_REPLACE = mapOf(
|
|||||||
private val MODIFIERS_ORDER = listOf(PUBLIC_KEYWORD, PROTECTED_KEYWORD, PRIVATE_KEYWORD, INTERNAL_KEYWORD,
|
private val MODIFIERS_ORDER = listOf(PUBLIC_KEYWORD, PROTECTED_KEYWORD, PRIVATE_KEYWORD, INTERNAL_KEYWORD,
|
||||||
FINAL_KEYWORD, OPEN_KEYWORD, ABSTRACT_KEYWORD,
|
FINAL_KEYWORD, OPEN_KEYWORD, ABSTRACT_KEYWORD,
|
||||||
OVERRIDE_KEYWORD,
|
OVERRIDE_KEYWORD,
|
||||||
|
LATEINIT_KEYWORD,
|
||||||
SUSPEND_KEYWORD,
|
SUSPEND_KEYWORD,
|
||||||
INNER_KEYWORD,
|
INNER_KEYWORD,
|
||||||
ENUM_KEYWORD, COMPANION_KEYWORD, INFIX_KEYWORD, OPERATOR_KEYWORD, DATA_KEYWORD)
|
ENUM_KEYWORD, COMPANION_KEYWORD, INFIX_KEYWORD, OPERATOR_KEYWORD, DATA_KEYWORD)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -21,8 +21,11 @@ import com.intellij.openapi.editor.Editor
|
|||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
import com.intellij.psi.PsiNameIdentifierOwner
|
import com.intellij.psi.PsiNameIdentifierOwner
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil
|
import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil
|
||||||
import org.jetbrains.kotlin.idea.refactoring.canRefactor
|
import org.jetbrains.kotlin.idea.refactoring.canRefactor
|
||||||
@@ -34,6 +37,7 @@ import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
|||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
|
|
||||||
open class AddModifierFix(
|
open class AddModifierFix(
|
||||||
element: KtModifierListOwner,
|
element: KtModifierListOwner,
|
||||||
@@ -116,4 +120,20 @@ open class AddModifierFix(
|
|||||||
return AddModifierFix(declaration, KtTokens.OPEN_KEYWORD)
|
return AddModifierFix(declaration, KtTokens.OPEN_KEYWORD)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object AddLateinitFactory : KotlinSingleIntentionActionFactory() {
|
||||||
|
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||||
|
val property = Errors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT.cast(diagnostic).psiElement
|
||||||
|
if (!property.isVar) return null
|
||||||
|
|
||||||
|
val context = property.analyze()
|
||||||
|
val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, property] ?: return null
|
||||||
|
val type = (descriptor as? PropertyDescriptor)?.type ?: return null
|
||||||
|
|
||||||
|
if (TypeUtils.isNullableType(type)) return null
|
||||||
|
if (KotlinBuiltIns.isPrimitiveType(type)) return null
|
||||||
|
|
||||||
|
return AddModifierFix(property, KtTokens.LATEINIT_KEYWORD)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -489,5 +489,7 @@ class QuickFixRegistrar : QuickFixContributor {
|
|||||||
INAPPLICABLE_JVM_FIELD.registerFactory(ReplaceJvmFieldWithConstFix)
|
INAPPLICABLE_JVM_FIELD.registerFactory(ReplaceJvmFieldWithConstFix)
|
||||||
|
|
||||||
CONFLICTING_OVERLOADS.registerFactory(ChangeSuspendInHierarchyFix)
|
CONFLICTING_OVERLOADS.registerFactory(ChangeSuspendInHierarchyFix)
|
||||||
|
|
||||||
|
MUST_BE_INITIALIZED_OR_BE_ABSTRACT.registerFactory(AddModifierFix.AddLateinitFactory)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// "Add 'lateinit' modifier" "true"
|
||||||
|
|
||||||
|
class A {
|
||||||
|
private var a: String<caret>
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// "Add 'lateinit' modifier" "true"
|
||||||
|
|
||||||
|
class A {
|
||||||
|
private lateinit var a: String<caret>
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// "Add 'lateinit' modifier" "false"
|
||||||
|
// ACTION: Add initializer
|
||||||
|
// ACTION: Make 'a' abstract
|
||||||
|
// ACTION: Move to constructor parameters
|
||||||
|
// ACTION: Move to constructor
|
||||||
|
// ERROR: Property must be initialized or be abstract
|
||||||
|
|
||||||
|
class A {
|
||||||
|
private var a: String?<caret>
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// "Add 'lateinit' modifier" "false"
|
||||||
|
// ACTION: Add initializer
|
||||||
|
// ACTION: Make 'a' abstract
|
||||||
|
// ACTION: Move to constructor parameters
|
||||||
|
// ACTION: Move to constructor
|
||||||
|
// ERROR: Property must be initialized or be abstract
|
||||||
|
|
||||||
|
class A {
|
||||||
|
private var a: Int<caret>
|
||||||
|
}
|
||||||
@@ -6613,6 +6613,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("addLateinit.kt")
|
||||||
|
public void testAddLateinit() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/addLateinit.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
public void testAllFilesPresentInModifiers() throws Exception {
|
public void testAllFilesPresentInModifiers() throws Exception {
|
||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/modifiers"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/modifiers"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
}
|
}
|
||||||
@@ -6671,6 +6677,18 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("noLateinitOnNullable.kt")
|
||||||
|
public void testNoLateinitOnNullable() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/noLateinitOnNullable.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("noLateinitOnPrimitive.kt")
|
||||||
|
public void testNoLateinitOnPrimitive() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/noLateinitOnPrimitive.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("notAnAnnotationClass.kt")
|
@TestMetadata("notAnAnnotationClass.kt")
|
||||||
public void testNotAnAnnotationClass() throws Exception {
|
public void testNotAnAnnotationClass() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/notAnAnnotationClass.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/notAnAnnotationClass.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user