From e2aa3518df204ee34eb6554195f95a8621973c7c Mon Sep 17 00:00:00 2001 From: Dmitry Neverov Date: Sun, 4 Jun 2017 12:25:34 +0300 Subject: [PATCH] Property accessor isn't recursive when called on another object So #KT-18120 Fixed --- .../inspections/RecursivePropertyAccessorInspection.kt | 10 ++++++++++ .../inspectionData/expected.xml | 9 +++++++++ .../recursivePropertyAccessors.kt | 10 ++++++++++ 3 files changed, 29 insertions(+) diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/RecursivePropertyAccessorInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/RecursivePropertyAccessorInspection.kt index eaa2d628d2f..34eb740972d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/RecursivePropertyAccessorInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/RecursivePropertyAccessorInspection.kt @@ -20,6 +20,8 @@ import com.intellij.codeInspection.* import com.intellij.openapi.project.Project import com.intellij.psi.PsiElementVisitor import com.intellij.psi.util.PsiTreeUtil +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* @@ -96,6 +98,9 @@ class RecursivePropertyAccessorInspection : AbstractKotlinInspection() { val bindingContext = element.analyze() val target = bindingContext[REFERENCE_TARGET, element] if (target != bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, propertyAccessor.property]) return false + (element.parent as? KtQualifiedExpression)?.let { + if (it.receiverExpression.text != KtTokens.THIS_KEYWORD.value && !it.hasObjectReceiver(bindingContext)) return false + } return isSameAccessor(element, propertyAccessor.isGetter) } @@ -114,5 +119,10 @@ class RecursivePropertyAccessorInspection : AbstractKotlinInspection() { namedFunctionDescriptor != syntheticDescriptor.setMethod) return false return isSameAccessor(element, isGetter) } + + private fun KtQualifiedExpression.hasObjectReceiver(context: BindingContext) : Boolean { + val receiver = receiverExpression as? KtReferenceExpression ?: return false + return (context[REFERENCE_TARGET, receiver] as? ClassDescriptor)?.kind == ClassKind.OBJECT + } } } \ No newline at end of file diff --git a/idea/testData/inspections/recursivePropertyAccessor/inspectionData/expected.xml b/idea/testData/inspections/recursivePropertyAccessor/inspectionData/expected.xml index 0dbf3ec6ef5..bec992521b7 100644 --- a/idea/testData/inspections/recursivePropertyAccessor/inspectionData/expected.xml +++ b/idea/testData/inspections/recursivePropertyAccessor/inspectionData/expected.xml @@ -116,4 +116,13 @@ Recursive property accessor + + recursivePropertyAccessors.kt + 45 + light_idea_test_case + + Recursive property accessor + Recursive property accessor + + diff --git a/idea/testData/inspections/recursivePropertyAccessor/recursivePropertyAccessors.kt b/idea/testData/inspections/recursivePropertyAccessor/recursivePropertyAccessors.kt index ba6820401e3..e53faccd6bc 100644 --- a/idea/testData/inspections/recursivePropertyAccessor/recursivePropertyAccessors.kt +++ b/idea/testData/inspections/recursivePropertyAccessor/recursivePropertyAccessors.kt @@ -38,4 +38,14 @@ class A { A.g = 99 } } +} + +object Obj { + val s: String + get() = Obj.s +} + +class Node(val next: Node?) { + val last: Node + get() = if (next != null) next.last else this } \ No newline at end of file