Allow to convert nullable local / top to late-init since version 1.2
Enhancement for KT-12743
This commit is contained in:
+8
-3
@@ -7,10 +7,13 @@ package org.jetbrains.kotlin.idea.intentions
|
|||||||
|
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.core.setType
|
import org.jetbrains.kotlin.idea.core.setType
|
||||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isNullExpression
|
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isNullExpression
|
||||||
|
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.KtNullableType
|
import org.jetbrains.kotlin.psi.KtNullableType
|
||||||
import org.jetbrains.kotlin.psi.KtProperty
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
@@ -27,7 +30,9 @@ class ConvertNullablePropertyToLateinitIntention : SelfTargetingIntention<KtProp
|
|||||||
override fun isApplicableTo(element: KtProperty, caretOffset: Int): Boolean {
|
override fun isApplicableTo(element: KtProperty, caretOffset: Int): Boolean {
|
||||||
if (element.hasModifier(KtTokens.LATEINIT_KEYWORD) || element.hasModifier(KtTokens.ABSTRACT_KEYWORD)) return false
|
if (element.hasModifier(KtTokens.LATEINIT_KEYWORD) || element.hasModifier(KtTokens.ABSTRACT_KEYWORD)) return false
|
||||||
if (!element.isVar) return false
|
if (!element.isVar) return false
|
||||||
if (element.isLocal || element.isTopLevel) return false
|
val languageVersionSettings = element.languageVersionSettings
|
||||||
|
if (!languageVersionSettings.supportsFeature(LanguageFeature.LateinitLocalVariables) && element.isLocal) return false
|
||||||
|
if (!languageVersionSettings.supportsFeature(LanguageFeature.LateinitTopLevelProperties) && element.isTopLevel) return false
|
||||||
if (element.getter?.hasBody() != null || element.setter?.hasBody() != null) return false
|
if (element.getter?.hasBody() != null || element.setter?.hasBody() != null) return false
|
||||||
if (!element.initializer.isNullExpression()) return false
|
if (!element.initializer.isNullExpression()) return false
|
||||||
|
|
||||||
@@ -37,8 +42,8 @@ class ConvertNullablePropertyToLateinitIntention : SelfTargetingIntention<KtProp
|
|||||||
val type = context[BindingContext.TYPE, typeReference]?.makeNotNullable() ?: return false
|
val type = context[BindingContext.TYPE, typeReference]?.makeNotNullable() ?: return false
|
||||||
if (KotlinBuiltIns.isPrimitiveType(type) || type.isInlineClassType() || TypeUtils.isNullableType(type)) return false
|
if (KotlinBuiltIns.isPrimitiveType(type) || type.isInlineClassType() || TypeUtils.isNullableType(type)) return false
|
||||||
|
|
||||||
val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, element] as? PropertyDescriptor ?: return false
|
val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, element] as? VariableDescriptor ?: return false
|
||||||
if (context[BindingContext.BACKING_FIELD_REQUIRED, descriptor] == false) return false
|
if (descriptor is PropertyDescriptor && context[BindingContext.BACKING_FIELD_REQUIRED, descriptor] == false) return false
|
||||||
if (descriptor.extensionReceiverParameter != null) return false
|
if (descriptor.extensionReceiverParameter != null) return false
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IS_APPLICABLE: false
|
|
||||||
fun test() {
|
fun test() {
|
||||||
<caret>var foo: String? = null
|
<caret>var foo: String? = null
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun test() {
|
||||||
|
lateinit var foo: String
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// IS_APPLICABLE: false
|
||||||
|
// LANGUAGE_VERSION: 1.1
|
||||||
|
fun test() {
|
||||||
|
<caret>var foo: String? = null
|
||||||
|
}
|
||||||
@@ -1,2 +1 @@
|
|||||||
// IS_APPLICABLE: false
|
|
||||||
<caret>var foo: String? = null
|
<caret>var foo: String? = null
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
lateinit var foo: String
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
// IS_APPLICABLE: false
|
||||||
|
// LANGUAGE_VERSION: 1.1
|
||||||
|
<caret>var foo: String? = null
|
||||||
@@ -33,9 +33,7 @@ import com.intellij.refactoring.util.CommonRefactoringUtil
|
|||||||
import com.intellij.testFramework.PlatformTestUtil
|
import com.intellij.testFramework.PlatformTestUtil
|
||||||
import junit.framework.ComparisonFailure
|
import junit.framework.ComparisonFailure
|
||||||
import junit.framework.TestCase
|
import junit.framework.TestCase
|
||||||
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
|
import org.jetbrains.kotlin.idea.test.*
|
||||||
import org.jetbrains.kotlin.idea.test.DirectiveBasedActionUtils
|
|
||||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
|
||||||
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||||
@@ -106,6 +104,7 @@ abstract class AbstractIntentionTest : KotlinLightCodeInsightFixtureTestCase() {
|
|||||||
val pathToFiles = mapOf(*(sourceFilePaths zip psiFiles).toTypedArray())
|
val pathToFiles = mapOf(*(sourceFilePaths zip psiFiles).toTypedArray())
|
||||||
|
|
||||||
val fileText = FileUtil.loadFile(mainFile, true)
|
val fileText = FileUtil.loadFile(mainFile, true)
|
||||||
|
val configured = configureCompilerOptions(fileText, project, module)
|
||||||
|
|
||||||
ConfigLibraryUtil.configureLibrariesByDirective(myModule, PlatformTestUtil.getCommunityPath(), fileText)
|
ConfigLibraryUtil.configureLibrariesByDirective(myModule, PlatformTestUtil.getCommunityPath(), fileText)
|
||||||
|
|
||||||
@@ -124,9 +123,11 @@ abstract class AbstractIntentionTest : KotlinLightCodeInsightFixtureTestCase() {
|
|||||||
if (file is KtFile && !InTextDirectivesUtils.isDirectiveDefined(fileText, "// SKIP_ERRORS_AFTER")) {
|
if (file is KtFile && !InTextDirectivesUtils.isDirectiveDefined(fileText, "// SKIP_ERRORS_AFTER")) {
|
||||||
DirectiveBasedActionUtils.checkForUnexpectedErrors(file as KtFile)
|
DirectiveBasedActionUtils.checkForUnexpectedErrors(file as KtFile)
|
||||||
}
|
}
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
ConfigLibraryUtil.unconfigureLibrariesByDirective(myModule, fileText)
|
ConfigLibraryUtil.unconfigureLibrariesByDirective(myModule, fileText)
|
||||||
|
if (configured) {
|
||||||
|
rollbackCompilerOptions(project, module)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5910,6 +5910,11 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
runTest("idea/testData/intentions/convertNullablePropertyToLateinit/local.kt");
|
runTest("idea/testData/intentions/convertNullablePropertyToLateinit/local.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localLegacy.kt")
|
||||||
|
public void testLocalLegacy() throws Exception {
|
||||||
|
runTest("idea/testData/intentions/convertNullablePropertyToLateinit/localLegacy.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("nonNullInitializer.kt")
|
@TestMetadata("nonNullInitializer.kt")
|
||||||
public void testNonNullInitializer() throws Exception {
|
public void testNonNullInitializer() throws Exception {
|
||||||
runTest("idea/testData/intentions/convertNullablePropertyToLateinit/nonNullInitializer.kt");
|
runTest("idea/testData/intentions/convertNullablePropertyToLateinit/nonNullInitializer.kt");
|
||||||
@@ -5940,6 +5945,11 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
runTest("idea/testData/intentions/convertNullablePropertyToLateinit/topLevel.kt");
|
runTest("idea/testData/intentions/convertNullablePropertyToLateinit/topLevel.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelLegacy.kt")
|
||||||
|
public void testTopLevelLegacy() throws Exception {
|
||||||
|
runTest("idea/testData/intentions/convertNullablePropertyToLateinit/topLevelLegacy.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("unsignedInt.kt")
|
@TestMetadata("unsignedInt.kt")
|
||||||
public void testUnsignedInt() throws Exception {
|
public void testUnsignedInt() throws Exception {
|
||||||
runTest("idea/testData/intentions/convertNullablePropertyToLateinit/unsignedInt.kt");
|
runTest("idea/testData/intentions/convertNullablePropertyToLateinit/unsignedInt.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user