Skip to content

Commit cd07aea

Browse files
cypressiousmglukhikh
authored andcommitted
Add quickfix for adding 'lateinit'
Fixes #KT-17650
1 parent 5de55e8 commit cd07aea

File tree

8 files changed

+73
-2
lines changed

8 files changed

+73
-2
lines changed

compiler/frontend/src/org/jetbrains/kotlin/psi/addRemoveModifier.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2010-2016 JetBrains s.r.o.
2+
* Copyright 2010-2017 JetBrains s.r.o.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -136,6 +136,7 @@ private val MODIFIERS_TO_REPLACE = mapOf(
136136
private val MODIFIERS_ORDER = listOf(PUBLIC_KEYWORD, PROTECTED_KEYWORD, PRIVATE_KEYWORD, INTERNAL_KEYWORD,
137137
FINAL_KEYWORD, OPEN_KEYWORD, ABSTRACT_KEYWORD,
138138
OVERRIDE_KEYWORD,
139+
LATEINIT_KEYWORD,
139140
SUSPEND_KEYWORD,
140141
INNER_KEYWORD,
141142
ENUM_KEYWORD, COMPANION_KEYWORD, INFIX_KEYWORD, OPERATOR_KEYWORD, DATA_KEYWORD)

idea/src/org/jetbrains/kotlin/idea/quickfix/AddModifierFix.kt

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2010-2015 JetBrains s.r.o.
2+
* Copyright 2010-2017 JetBrains s.r.o.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -21,8 +21,11 @@ import com.intellij.openapi.editor.Editor
2121
import com.intellij.openapi.project.Project
2222
import com.intellij.psi.PsiFile
2323
import com.intellij.psi.PsiNameIdentifierOwner
24+
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
2425
import org.jetbrains.kotlin.descriptors.ClassDescriptor
26+
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
2527
import org.jetbrains.kotlin.diagnostics.Diagnostic
28+
import org.jetbrains.kotlin.diagnostics.Errors
2629
import org.jetbrains.kotlin.idea.caches.resolve.analyze
2730
import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil
2831
import org.jetbrains.kotlin.idea.refactoring.canRefactor
@@ -34,6 +37,7 @@ import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
3437
import org.jetbrains.kotlin.resolve.BindingContext
3538
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
3639
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
40+
import org.jetbrains.kotlin.types.TypeUtils
3741

3842
open class AddModifierFix(
3943
element: KtModifierListOwner,
@@ -116,4 +120,20 @@ open class AddModifierFix(
116120
return AddModifierFix(declaration, KtTokens.OPEN_KEYWORD)
117121
}
118122
}
123+
124+
object AddLateinitFactory : KotlinSingleIntentionActionFactory() {
125+
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
126+
val property = Errors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT.cast(diagnostic).psiElement
127+
if (!property.isVar) return null
128+
129+
val context = property.analyze()
130+
val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, property] ?: return null
131+
val type = (descriptor as? PropertyDescriptor)?.type ?: return null
132+
133+
if (TypeUtils.isNullableType(type)) return null
134+
if (KotlinBuiltIns.isPrimitiveType(type)) return null
135+
136+
return AddModifierFix(property, KtTokens.LATEINIT_KEYWORD)
137+
}
138+
}
119139
}

idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,5 +489,7 @@ class QuickFixRegistrar : QuickFixContributor {
489489
INAPPLICABLE_JVM_FIELD.registerFactory(ReplaceJvmFieldWithConstFix)
490490

491491
CONFLICTING_OVERLOADS.registerFactory(ChangeSuspendInHierarchyFix)
492+
493+
MUST_BE_INITIALIZED_OR_BE_ABSTRACT.registerFactory(AddModifierFix.AddLateinitFactory)
492494
}
493495
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// "Add 'lateinit' modifier" "true"
2+
3+
class A {
4+
private var a: String<caret>
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// "Add 'lateinit' modifier" "true"
2+
3+
class A {
4+
private lateinit var a: String<caret>
5+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// "Add 'lateinit' modifier" "false"
2+
// ACTION: Add initializer
3+
// ACTION: Make 'a' abstract
4+
// ACTION: Move to constructor parameters
5+
// ACTION: Move to constructor
6+
// ERROR: Property must be initialized or be abstract
7+
8+
class A {
9+
private var a: String?<caret>
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// "Add 'lateinit' modifier" "false"
2+
// ACTION: Add initializer
3+
// ACTION: Make 'a' abstract
4+
// ACTION: Move to constructor parameters
5+
// ACTION: Move to constructor
6+
// ERROR: Property must be initialized or be abstract
7+
8+
class A {
9+
private var a: Int<caret>
10+
}

idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6613,6 +6613,12 @@ public void testAbstractModifierInEnum() throws Exception {
66136613
doTest(fileName);
66146614
}
66156615

6616+
@TestMetadata("addLateinit.kt")
6617+
public void testAddLateinit() throws Exception {
6618+
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/addLateinit.kt");
6619+
doTest(fileName);
6620+
}
6621+
66166622
public void testAllFilesPresentInModifiers() throws Exception {
66176623
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/modifiers"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
66186624
}
@@ -6671,6 +6677,18 @@ public void testNoAbstractForObject() throws Exception {
66716677
doTest(fileName);
66726678
}
66736679

6680+
@TestMetadata("noLateinitOnNullable.kt")
6681+
public void testNoLateinitOnNullable() throws Exception {
6682+
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/noLateinitOnNullable.kt");
6683+
doTest(fileName);
6684+
}
6685+
6686+
@TestMetadata("noLateinitOnPrimitive.kt")
6687+
public void testNoLateinitOnPrimitive() throws Exception {
6688+
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/noLateinitOnPrimitive.kt");
6689+
doTest(fileName);
6690+
}
6691+
66746692
@TestMetadata("notAnAnnotationClass.kt")
66756693
public void testNotAnAnnotationClass() throws Exception {
66766694
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/notAnAnnotationClass.kt");

0 commit comments

Comments
 (0)