CanBePrimaryConstructorPropertyInspection: do not report for 'open' property used in class initializer in 'open' class
This commit is contained in:
committed by
Dmitry Gridin
parent
963258189a
commit
0b9106b0f8
+21
-6
@@ -12,13 +12,14 @@ import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.intentions.MovePropertyToConstructorIntention
|
import org.jetbrains.kotlin.idea.intentions.MovePropertyToConstructorIntention
|
||||||
|
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.hasUsages
|
||||||
import org.jetbrains.kotlin.idea.refactoring.isInterfaceClass
|
import org.jetbrains.kotlin.idea.refactoring.isInterfaceClass
|
||||||
import org.jetbrains.kotlin.psi.KtParameter
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.KtReferenceExpression
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.propertyVisitor
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
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.utils.addToStdlib.firstIsInstanceOrNull
|
||||||
|
|
||||||
class CanBePrimaryConstructorPropertyInspection : AbstractKotlinInspection() {
|
class CanBePrimaryConstructorPropertyInspection : AbstractKotlinInspection() {
|
||||||
|
|
||||||
@@ -42,9 +43,14 @@ class CanBePrimaryConstructorPropertyInspection : AbstractKotlinInspection() {
|
|||||||
if (nameIdentifier.text != assignedDescriptor.name.asString()) return
|
if (nameIdentifier.text != assignedDescriptor.name.asString()) return
|
||||||
|
|
||||||
val assignedParameter = DescriptorToSourceUtils.descriptorToDeclaration(assignedDescriptor) as? KtParameter ?: return
|
val assignedParameter = DescriptorToSourceUtils.descriptorToDeclaration(assignedDescriptor) as? KtParameter ?: return
|
||||||
if (property.containingClassOrObject !== assignedParameter.containingClassOrObject) return
|
val containingClassOrObject = property.containingClassOrObject ?: return
|
||||||
|
if (containingClassOrObject !== assignedParameter.containingClassOrObject) return
|
||||||
if (property.containingClassOrObject?.isInterfaceClass() == true) return
|
if (containingClassOrObject.isInterfaceClass()) return
|
||||||
|
if (property.hasModifier(KtTokens.OPEN_KEYWORD)
|
||||||
|
&& containingClassOrObject is KtClass
|
||||||
|
&& containingClassOrObject.isOpen()
|
||||||
|
&& assignedParameter.isUsedInClassInitializer(containingClassOrObject)
|
||||||
|
) return
|
||||||
|
|
||||||
holder.registerProblem(
|
holder.registerProblem(
|
||||||
holder.manager.createProblemDescriptor(
|
holder.manager.createProblemDescriptor(
|
||||||
@@ -58,4 +64,13 @@ class CanBePrimaryConstructorPropertyInspection : AbstractKotlinInspection() {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun KtClass.isOpen(): Boolean {
|
||||||
|
return hasModifier(KtTokens.OPEN_KEYWORD) || hasModifier(KtTokens.ABSTRACT_KEYWORD) || hasModifier(KtTokens.SEALED_KEYWORD)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun KtParameter.isUsedInClassInitializer(containingClass: KtClass): Boolean {
|
||||||
|
val classInitializer = containingClass.body?.declarations?.firstIsInstanceOrNull<KtClassInitializer>() ?: return false
|
||||||
|
return hasUsages(classInitializer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+24
@@ -15,4 +15,28 @@
|
|||||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Property is explicitly assigned to constructor parameter</problem_class>
|
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Property is explicitly assigned to constructor parameter</problem_class>
|
||||||
<description>Property is explicitly assigned to parameter withType, can be declared directly in constructor</description>
|
<description>Property is explicitly assigned to parameter withType, can be declared directly in constructor</description>
|
||||||
</problem>
|
</problem>
|
||||||
|
<problem>
|
||||||
|
<file>properties.kt</file>
|
||||||
|
<line>79</line>
|
||||||
|
<module>light_idea_test_case</module>
|
||||||
|
<entry_point TYPE="file" FQNAME="temp:///src/properties.kt" />
|
||||||
|
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Property is explicitly assigned to constructor parameter</problem_class>
|
||||||
|
<description>Property is explicitly assigned to parameter property, can be declared directly in constructor</description>
|
||||||
|
</problem>
|
||||||
|
<problem>
|
||||||
|
<file>properties.kt</file>
|
||||||
|
<line>87</line>
|
||||||
|
<module>light_idea_test_case</module>
|
||||||
|
<entry_point TYPE="file" FQNAME="temp:///src/properties.kt" />
|
||||||
|
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Property is explicitly assigned to constructor parameter</problem_class>
|
||||||
|
<description>Property is explicitly assigned to parameter property, can be declared directly in constructor</description>
|
||||||
|
</problem>
|
||||||
|
<problem>
|
||||||
|
<file>properties.kt</file>
|
||||||
|
<line>91</line>
|
||||||
|
<module>light_idea_test_case</module>
|
||||||
|
<entry_point TYPE="file" FQNAME="temp:///src/properties.kt" />
|
||||||
|
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Property is explicitly assigned to constructor parameter</problem_class>
|
||||||
|
<description>Property is explicitly assigned to parameter property, can be declared directly in constructor</description>
|
||||||
|
</problem>
|
||||||
</problems>
|
</problems>
|
||||||
@@ -45,3 +45,48 @@ class Bar(x : String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KT-32561
|
||||||
|
open class X(property: String) {
|
||||||
|
init {
|
||||||
|
print(property)
|
||||||
|
}
|
||||||
|
|
||||||
|
open val property: String = property
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class X2(property: String) {
|
||||||
|
init {
|
||||||
|
print(property)
|
||||||
|
}
|
||||||
|
|
||||||
|
open val property: String = property
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class X3(property: String) {
|
||||||
|
init {
|
||||||
|
print(property)
|
||||||
|
}
|
||||||
|
|
||||||
|
open val property: String = property
|
||||||
|
}
|
||||||
|
|
||||||
|
open class X4(property: String) {
|
||||||
|
init {
|
||||||
|
print(property)
|
||||||
|
}
|
||||||
|
|
||||||
|
val property: String = property
|
||||||
|
}
|
||||||
|
|
||||||
|
class X5(property: String) {
|
||||||
|
init {
|
||||||
|
print(property)
|
||||||
|
}
|
||||||
|
|
||||||
|
open val property: String = property
|
||||||
|
}
|
||||||
|
|
||||||
|
open class X6(property: String) {
|
||||||
|
open val property: String = property
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user