RemoveRedundantQualifierInspection: fix false positive for enum/object

#KT-34113 Fixed
#KT-32965 Fixed
#KT-33991 Fixed
#KT-33597 Fixed
This commit is contained in:
Dmitry Gridin
2019-10-15 17:32:17 +07:00
parent a4f805ccd0
commit 696b832a9c
2 changed files with 26 additions and 17 deletions
@@ -6,12 +6,9 @@
package org.jetbrains.kotlin.idea.inspections
import com.intellij.codeInspection.*
import com.intellij.lang.jvm.JvmModifier
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiMember
import com.intellij.psi.PsiMethod
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.analysis.analyzeAsReplacement
import org.jetbrains.kotlin.idea.caches.resolve.analyze
@@ -20,11 +17,16 @@ import org.jetbrains.kotlin.idea.core.compareDescriptors
import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.idea.util.getResolutionScope
import org.jetbrains.kotlin.idea.util.hasNotReceiver
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.getLastParentOfTypeInRowWithSelf
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.ImportedFromObjectCallableDescriptor
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.isCompanionObject
import org.jetbrains.kotlin.resolve.scopes.utils.findFirstClassifierWithDeprecationStatus
@@ -70,14 +72,10 @@ class RemoveRedundantQualifierNameInspection : AbstractKotlinInspection(), Clean
}
}
private tailrec fun KtDotQualifiedExpression.firstExpressionWithoutReceiver(): KtDotQualifiedExpression? {
val element = getQualifiedElementSelector()?.mainReference?.resolve() ?: return null
return if (element is KtClassOrObject ||
element is KtCallableDeclaration && element.receiverTypeReference == null ||
element is PsiMember && element.hasModifier(JvmModifier.STATIC) ||
element is PsiMethod && element.isConstructor
) this else (receiverExpression as? KtDotQualifiedExpression)?.firstExpressionWithoutReceiver()
}
private tailrec fun KtDotQualifiedExpression.firstExpressionWithoutReceiver(): KtDotQualifiedExpression? = if (hasNotReceiver())
this
else
(receiverExpression as? KtDotQualifiedExpression)?.firstExpressionWithoutReceiver()
private tailrec fun <T : KtElement> T.firstApplicableExpression(validator: T.() -> T?, generator: T.() -> T?): T? =
validator() ?: generator()?.firstApplicableExpression(validator, generator)
@@ -100,7 +98,7 @@ private fun KtDotQualifiedExpression.applicableExpression(
?.firstOrNull() ?: return null
return takeIf {
originalDescriptor.importableFqName == newDescriptor.importableFqName &&
originalDescriptor.fqNameSafe == newDescriptor.fqNameSafe &&
if (newDescriptor is ImportedFromObjectCallableDescriptor<*>)
compareDescriptors(project, newDescriptor.callableFromObject, originalDescriptor)
else
@@ -5,16 +5,18 @@
package org.jetbrains.kotlin.idea.util
import com.intellij.lang.jvm.JvmModifier
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiComment
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMember
import com.intellij.psi.PsiMethod
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.intentions.callExpression
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
import org.jetbrains.kotlin.psi.psiUtil.containingClass
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
@@ -48,4 +50,13 @@ fun KtDotQualifiedExpression.calleeTextRangeInThis(): TextRange? = callExpressio
fun KtNamedDeclaration.nameIdentifierTextRangeInThis(): TextRange? = nameIdentifier?.textRangeIn(this)
fun PsiElement.hasComments(): Boolean = anyDescendantOfType<PsiComment>()
fun PsiElement.hasComments(): Boolean = anyDescendantOfType<PsiComment>()
fun KtDotQualifiedExpression.hasNotReceiver(): Boolean {
val element = getQualifiedElementSelector()?.mainReference?.resolve() ?: return false
return element is KtClassOrObject ||
element is KtConstructor<*> ||
element is KtCallableDeclaration && element.receiverTypeReference == null && (element.containingClassOrObject is KtObjectDeclaration?) ||
element is PsiMember && element.hasModifier(JvmModifier.STATIC) ||
element is PsiMethod && element.isConstructor
}