Do not highlight replacement of equals involving floating-point types
Two tests with smart casts do not work yet Part of KT-25933
This commit is contained in:
committed by
Mikhail Glukhikh
parent
8c6337f3f6
commit
1aa9d5673b
+40
-8
@@ -21,20 +21,25 @@ import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import org.jetbrains.kotlin.codegen.kotlinType
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
|
||||
import org.jetbrains.kotlin.idea.inspections.AbstractApplicabilityBasedInspection
|
||||
import org.jetbrains.kotlin.idea.intentions.callExpression
|
||||
import org.jetbrains.kotlin.idea.intentions.*
|
||||
import org.jetbrains.kotlin.idea.intentions.conventionNameCalls.isAnyEquals
|
||||
import org.jetbrains.kotlin.idea.intentions.isReceiverExpressionWithValue
|
||||
import org.jetbrains.kotlin.idea.intentions.toResolvedCall
|
||||
import org.jetbrains.kotlin.lexer.KtSingleValueToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getLastParentOfTypeInRow
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getFirstArgumentExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getReceiverExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
|
||||
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
import org.jetbrains.kotlin.types.typeUtil.*
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
class ReplaceCallWithBinaryOperatorInspection : AbstractApplicabilityBasedInspection<KtDotQualifiedExpression>(
|
||||
@@ -69,10 +74,13 @@ class ReplaceCallWithBinaryOperatorInspection : AbstractApplicabilityBasedInspec
|
||||
override fun inspectionHighlightType(element: KtDotQualifiedExpression): ProblemHighlightType {
|
||||
val calleeExpression = element.callExpression?.calleeExpression as? KtSimpleNameExpression
|
||||
val identifier = calleeExpression?.getReferencedNameAsName()
|
||||
return if (identifier == OperatorNameConventions.EQUALS || identifier == OperatorNameConventions.COMPARE_TO) {
|
||||
val isFloatingPointNumberEquals = calleeExpression?.isFloatingPointNumberEquals() ?: false
|
||||
|
||||
return if (isFloatingPointNumberEquals) {
|
||||
ProblemHighlightType.INFORMATION
|
||||
} else if (identifier == OperatorNameConventions.EQUALS || identifier == OperatorNameConventions.COMPARE_TO) {
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
ProblemHighlightType.INFORMATION
|
||||
}
|
||||
}
|
||||
@@ -84,6 +92,10 @@ class ReplaceCallWithBinaryOperatorInspection : AbstractApplicabilityBasedInspec
|
||||
|
||||
override fun fixText(element: KtDotQualifiedExpression): String {
|
||||
val calleeExpression = element.callExpression?.calleeExpression as? KtSimpleNameExpression ?: return defaultFixText
|
||||
if (calleeExpression.isFloatingPointNumberEquals()) {
|
||||
return "Replace total order equality with IEEE 754 equality"
|
||||
}
|
||||
|
||||
val operation = operation(calleeExpression) ?: return defaultFixText
|
||||
return "Replace with '${operation.value}'"
|
||||
}
|
||||
@@ -123,7 +135,6 @@ class ReplaceCallWithBinaryOperatorInspection : AbstractApplicabilityBasedInspec
|
||||
return when (identifier) {
|
||||
OperatorNameConventions.EQUALS -> {
|
||||
if (!dotQualified.isAnyEquals()) return null
|
||||
|
||||
val prefixExpression = dotQualified.getWrappingPrefixExpressionIfAny()
|
||||
if (prefixExpression != null && prefixExpression.operationToken == KtTokens.EXCL) KtTokens.EXCLEQ
|
||||
else KtTokens.EQEQ
|
||||
@@ -148,4 +159,25 @@ class ReplaceCallWithBinaryOperatorInspection : AbstractApplicabilityBasedInspec
|
||||
else -> OperatorConventions.BINARY_OPERATION_NAMES.inverse()[identifier]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun KtDotQualifiedExpression.isFloatingPointNumberEquals(): Boolean {
|
||||
val resolvedCall = resolveToCall() ?: return false
|
||||
val context = analyze(BodyResolveMode.PARTIAL)
|
||||
val receiverType = resolvedCall.getReceiverExpression().kotlinType(context) ?: return false
|
||||
val argumentType = resolvedCall.getFirstArgumentExpression().kotlinType(context) ?: return false
|
||||
return (receiverType.isFpType() && argumentType.isNumericType()) || (argumentType.isFpType() && receiverType.isNumericType())
|
||||
}
|
||||
|
||||
private fun KtSimpleNameExpression.isFloatingPointNumberEquals(): Boolean {
|
||||
val dotQualified = parent.parent as? KtDotQualifiedExpression ?: return false
|
||||
return dotQualified.isFloatingPointNumberEquals()
|
||||
}
|
||||
|
||||
private fun KotlinType.isFpType(): Boolean {
|
||||
return isFloat() || isDouble()
|
||||
}
|
||||
|
||||
private fun KotlinType.isNumericType(): Boolean {
|
||||
return isFpType() || isByte() || isShort() || isInt() || isLong()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user