Introduce subject to when: don't perform analysis in if transformation
Otherwise we get an exception about non-analysable file Related to KT-18772
This commit is contained in:
+13
-9
@@ -37,7 +37,7 @@ fun KtWhenCondition.toExpression(subject: KtExpression?): KtExpression {
|
||||
}
|
||||
}
|
||||
|
||||
fun KtWhenExpression.getSubjectToIntroduce(): KtExpression? {
|
||||
fun KtWhenExpression.getSubjectToIntroduce(checkConstants: Boolean = true): KtExpression? {
|
||||
if (subjectExpression != null) return null
|
||||
|
||||
var lastCandidate: KtExpression? = null
|
||||
@@ -48,7 +48,7 @@ fun KtWhenExpression.getSubjectToIntroduce(): KtExpression? {
|
||||
for (condition in conditions) {
|
||||
if (condition !is KtWhenConditionWithExpression) return null
|
||||
|
||||
val candidate = condition.expression?.getWhenConditionSubjectCandidate() ?: return null
|
||||
val candidate = condition.expression?.getWhenConditionSubjectCandidate(checkConstants) ?: return null
|
||||
if (candidate !is KtNameReferenceExpression
|
||||
&& (candidate as? KtQualifiedExpression)?.selectorExpression !is KtNameReferenceExpression
|
||||
&& candidate !is KtThisExpression
|
||||
@@ -65,7 +65,7 @@ fun KtWhenExpression.getSubjectToIntroduce(): KtExpression? {
|
||||
return lastCandidate
|
||||
}
|
||||
|
||||
private fun KtExpression?.getWhenConditionSubjectCandidate(): KtExpression? = when (this) {
|
||||
private fun KtExpression?.getWhenConditionSubjectCandidate(checkConstants: Boolean): KtExpression? = when (this) {
|
||||
is KtIsExpression -> leftHandSide
|
||||
|
||||
is KtBinaryExpression -> {
|
||||
@@ -74,10 +74,11 @@ private fun KtExpression?.getWhenConditionSubjectCandidate(): KtExpression? = wh
|
||||
when (operationToken) {
|
||||
KtTokens.IN_KEYWORD, KtTokens.NOT_IN -> lhs
|
||||
KtTokens.EQEQ ->
|
||||
lhs?.takeIf { it.hasCandidateNameReferenceExpression() } ?: rhs?.takeIf { it.hasCandidateNameReferenceExpression() }
|
||||
lhs?.takeIf { it.hasCandidateNameReferenceExpression(checkConstants) }
|
||||
?: rhs?.takeIf { it.hasCandidateNameReferenceExpression(checkConstants) }
|
||||
KtTokens.OROR -> {
|
||||
val leftCandidate = lhs.getWhenConditionSubjectCandidate()
|
||||
val rightCandidate = rhs.getWhenConditionSubjectCandidate()
|
||||
val leftCandidate = lhs.getWhenConditionSubjectCandidate(checkConstants)
|
||||
val rightCandidate = rhs.getWhenConditionSubjectCandidate(checkConstants)
|
||||
if (leftCandidate.matches(rightCandidate)) leftCandidate else null
|
||||
}
|
||||
else -> null
|
||||
@@ -88,17 +89,20 @@ private fun KtExpression?.getWhenConditionSubjectCandidate(): KtExpression? = wh
|
||||
else -> null
|
||||
}
|
||||
|
||||
private fun KtExpression.hasCandidateNameReferenceExpression(): Boolean {
|
||||
private fun KtExpression.hasCandidateNameReferenceExpression(checkConstants: Boolean): Boolean {
|
||||
val nameReferenceExpression = this as? KtNameReferenceExpression
|
||||
?: (this as? KtQualifiedExpression)?.selectorExpression as? KtNameReferenceExpression
|
||||
?: return false
|
||||
if (!checkConstants) {
|
||||
return true
|
||||
}
|
||||
val resolved = nameReferenceExpression.mainReference.resolve()
|
||||
if (resolved is KtObjectDeclaration || (resolved as? KtProperty)?.hasModifier(KtTokens.CONST_KEYWORD) == true) return false
|
||||
return true
|
||||
}
|
||||
|
||||
fun KtWhenExpression.introduceSubject(): KtWhenExpression? {
|
||||
val subject = getSubjectToIntroduce() ?: return null
|
||||
fun KtWhenExpression.introduceSubject(checkConstants: Boolean = true): KtWhenExpression? {
|
||||
val subject = getSubjectToIntroduce(checkConstants) ?: return null
|
||||
|
||||
val commentSaver = CommentSaver(this, saveLineBreaks = true)
|
||||
|
||||
|
||||
+2
-2
@@ -191,8 +191,8 @@ class IfToWhenIntention : SelfTargetingRangeIntention<KtIfExpression>(KtIfExpres
|
||||
} as KtWhenExpression
|
||||
|
||||
|
||||
if (whenExpression.getSubjectToIntroduce() != null) {
|
||||
whenExpression = whenExpression.introduceSubject() ?: return
|
||||
if (whenExpression.getSubjectToIntroduce(checkConstants = false) != null) {
|
||||
whenExpression = whenExpression.introduceSubject(checkConstants = false) ?: return
|
||||
}
|
||||
|
||||
val result = ifExpression.replaced(whenExpression)
|
||||
|
||||
Reference in New Issue
Block a user