Add Inspection for lateinit var overrides another lateinit var
#KT-30775 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
fbd992f8c7
commit
4b4be07942
@@ -3408,6 +3408,15 @@
|
|||||||
language="kotlin"
|
language="kotlin"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.LateinitVarOverridesLateinitVarInspection"
|
||||||
|
displayName="lateinit var property overrides lateinit var property"
|
||||||
|
groupPath="Kotlin"
|
||||||
|
groupName="Probable bugs"
|
||||||
|
enabledByDefault="true"
|
||||||
|
level="WARNING"
|
||||||
|
language="kotlin"
|
||||||
|
/>
|
||||||
|
|
||||||
<referenceImporter implementation="org.jetbrains.kotlin.idea.quickfix.KotlinReferenceImporter"/>
|
<referenceImporter implementation="org.jetbrains.kotlin.idea.quickfix.KotlinReferenceImporter"/>
|
||||||
|
|
||||||
<fileType.fileViewProviderFactory filetype="KJSM" implementationClass="com.intellij.psi.ClassFileViewProviderFactory"/>
|
<fileType.fileViewProviderFactory filetype="KJSM" implementationClass="com.intellij.psi.ClassFileViewProviderFactory"/>
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
This inspection reports when one lateinit var property overrides another lateinit var property.
|
||||||
|
An instance of a subclass will have two fields for the single property and the one from a superclass remains effectively unused.
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.inspections
|
||||||
|
|
||||||
|
import com.intellij.codeInspection.ProblemsHolder
|
||||||
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||||
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
|
import org.jetbrains.kotlin.psi.classOrObjectRecursiveVisitor
|
||||||
|
|
||||||
|
class LateinitVarOverridesLateinitVarInspection : AbstractKotlinInspection() {
|
||||||
|
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean) = classOrObjectRecursiveVisitor(fun(klass) {
|
||||||
|
for (declaration in klass.declarations) {
|
||||||
|
val property = declaration as? KtProperty ?: continue
|
||||||
|
if (!property.hasModifier(KtTokens.OVERRIDE_KEYWORD) || !property.hasModifier(KtTokens.LATEINIT_KEYWORD) || !property.isVar) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
val identifier = property.nameIdentifier ?: continue
|
||||||
|
val descriptor = property.resolveToDescriptorIfAny() ?: continue
|
||||||
|
if (descriptor.overriddenDescriptors.any { (it as? PropertyDescriptor)?.let { d -> d.isLateInit && d.isVar } == true }) {
|
||||||
|
holder.registerProblem(
|
||||||
|
identifier,
|
||||||
|
"lateinit var overrides lateinit var"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
org.jetbrains.kotlin.idea.inspections.LateinitVarOverridesLateinitVarInspection
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// FIX: none
|
||||||
|
open class A1 {
|
||||||
|
open lateinit var a: String
|
||||||
|
}
|
||||||
|
|
||||||
|
class A2 : A1() {
|
||||||
|
override lateinit var <caret>a: String
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// PROBLEM: none
|
||||||
|
open class A1 {
|
||||||
|
open var a: String = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
class A2 : A1() {
|
||||||
|
override lateinit var <caret>a: String
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
// PROBLEM: none
|
||||||
|
open class A1 {
|
||||||
|
open lateinit var a: String
|
||||||
|
}
|
||||||
|
|
||||||
|
class A2 : A1() {
|
||||||
|
override var <caret>a: String = ""
|
||||||
|
}
|
||||||
+28
@@ -4475,6 +4475,34 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/inspectionsLocal/lateinitVarOverridesLateinitVar")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class LateinitVarOverridesLateinitVar extends AbstractLocalInspectionTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInLateinitVarOverridesLateinitVar() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/lateinitVarOverridesLateinitVar"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("basic.kt")
|
||||||
|
public void testBasic() throws Exception {
|
||||||
|
runTest("idea/testData/inspectionsLocal/lateinitVarOverridesLateinitVar/basic.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("notLateinit.kt")
|
||||||
|
public void testNotLateinit() throws Exception {
|
||||||
|
runTest("idea/testData/inspectionsLocal/lateinitVarOverridesLateinitVar/notLateinit.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("notLateinit2.kt")
|
||||||
|
public void testNotLateinit2() throws Exception {
|
||||||
|
runTest("idea/testData/inspectionsLocal/lateinitVarOverridesLateinitVar/notLateinit2.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/inspectionsLocal/leakingThis")
|
@TestMetadata("idea/testData/inspectionsLocal/leakingThis")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user