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
|
if (subjectExpression != null) return null
|
||||||
|
|
||||||
var lastCandidate: KtExpression? = null
|
var lastCandidate: KtExpression? = null
|
||||||
@@ -48,7 +48,7 @@ fun KtWhenExpression.getSubjectToIntroduce(): KtExpression? {
|
|||||||
for (condition in conditions) {
|
for (condition in conditions) {
|
||||||
if (condition !is KtWhenConditionWithExpression) return null
|
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
|
if (candidate !is KtNameReferenceExpression
|
||||||
&& (candidate as? KtQualifiedExpression)?.selectorExpression !is KtNameReferenceExpression
|
&& (candidate as? KtQualifiedExpression)?.selectorExpression !is KtNameReferenceExpression
|
||||||
&& candidate !is KtThisExpression
|
&& candidate !is KtThisExpression
|
||||||
@@ -65,7 +65,7 @@ fun KtWhenExpression.getSubjectToIntroduce(): KtExpression? {
|
|||||||
return lastCandidate
|
return lastCandidate
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtExpression?.getWhenConditionSubjectCandidate(): KtExpression? = when (this) {
|
private fun KtExpression?.getWhenConditionSubjectCandidate(checkConstants: Boolean): KtExpression? = when (this) {
|
||||||
is KtIsExpression -> leftHandSide
|
is KtIsExpression -> leftHandSide
|
||||||
|
|
||||||
is KtBinaryExpression -> {
|
is KtBinaryExpression -> {
|
||||||
@@ -74,10 +74,11 @@ private fun KtExpression?.getWhenConditionSubjectCandidate(): KtExpression? = wh
|
|||||||
when (operationToken) {
|
when (operationToken) {
|
||||||
KtTokens.IN_KEYWORD, KtTokens.NOT_IN -> lhs
|
KtTokens.IN_KEYWORD, KtTokens.NOT_IN -> lhs
|
||||||
KtTokens.EQEQ ->
|
KtTokens.EQEQ ->
|
||||||
lhs?.takeIf { it.hasCandidateNameReferenceExpression() } ?: rhs?.takeIf { it.hasCandidateNameReferenceExpression() }
|
lhs?.takeIf { it.hasCandidateNameReferenceExpression(checkConstants) }
|
||||||
|
?: rhs?.takeIf { it.hasCandidateNameReferenceExpression(checkConstants) }
|
||||||
KtTokens.OROR -> {
|
KtTokens.OROR -> {
|
||||||
val leftCandidate = lhs.getWhenConditionSubjectCandidate()
|
val leftCandidate = lhs.getWhenConditionSubjectCandidate(checkConstants)
|
||||||
val rightCandidate = rhs.getWhenConditionSubjectCandidate()
|
val rightCandidate = rhs.getWhenConditionSubjectCandidate(checkConstants)
|
||||||
if (leftCandidate.matches(rightCandidate)) leftCandidate else null
|
if (leftCandidate.matches(rightCandidate)) leftCandidate else null
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
@@ -88,17 +89,20 @@ private fun KtExpression?.getWhenConditionSubjectCandidate(): KtExpression? = wh
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtExpression.hasCandidateNameReferenceExpression(): Boolean {
|
private fun KtExpression.hasCandidateNameReferenceExpression(checkConstants: Boolean): Boolean {
|
||||||
val nameReferenceExpression = this as? KtNameReferenceExpression
|
val nameReferenceExpression = this as? KtNameReferenceExpression
|
||||||
?: (this as? KtQualifiedExpression)?.selectorExpression as? KtNameReferenceExpression
|
?: (this as? KtQualifiedExpression)?.selectorExpression as? KtNameReferenceExpression
|
||||||
?: return false
|
?: return false
|
||||||
|
if (!checkConstants) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
val resolved = nameReferenceExpression.mainReference.resolve()
|
val resolved = nameReferenceExpression.mainReference.resolve()
|
||||||
if (resolved is KtObjectDeclaration || (resolved as? KtProperty)?.hasModifier(KtTokens.CONST_KEYWORD) == true) return false
|
if (resolved is KtObjectDeclaration || (resolved as? KtProperty)?.hasModifier(KtTokens.CONST_KEYWORD) == true) return false
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun KtWhenExpression.introduceSubject(): KtWhenExpression? {
|
fun KtWhenExpression.introduceSubject(checkConstants: Boolean = true): KtWhenExpression? {
|
||||||
val subject = getSubjectToIntroduce() ?: return null
|
val subject = getSubjectToIntroduce(checkConstants) ?: return null
|
||||||
|
|
||||||
val commentSaver = CommentSaver(this, saveLineBreaks = true)
|
val commentSaver = CommentSaver(this, saveLineBreaks = true)
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -191,8 +191,8 @@ class IfToWhenIntention : SelfTargetingRangeIntention<KtIfExpression>(KtIfExpres
|
|||||||
} as KtWhenExpression
|
} as KtWhenExpression
|
||||||
|
|
||||||
|
|
||||||
if (whenExpression.getSubjectToIntroduce() != null) {
|
if (whenExpression.getSubjectToIntroduce(checkConstants = false) != null) {
|
||||||
whenExpression = whenExpression.introduceSubject() ?: return
|
whenExpression = whenExpression.introduceSubject(checkConstants = false) ?: return
|
||||||
}
|
}
|
||||||
|
|
||||||
val result = ifExpression.replaced(whenExpression)
|
val result = ifExpression.replaced(whenExpression)
|
||||||
|
|||||||
Reference in New Issue
Block a user