Lot of code corrections in RemoveForLoopIndicesIntention

This commit is contained in:
Valentin Kipyatkov
2015-07-21 13:45:49 +03:00
parent e4cdcadbc7
commit 6b0fc8391f
@@ -17,45 +17,46 @@
package org.jetbrains.kotlin.idea.intentions package org.jetbrains.kotlin.idea.intentions
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.openapi.util.TextRange
import com.intellij.psi.search.searches.ReferencesSearch import com.intellij.psi.search.searches.ReferencesSearch
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.psi.JetCallExpression
import org.jetbrains.kotlin.psi.JetDotQualifiedExpression import org.jetbrains.kotlin.psi.JetDotQualifiedExpression
import org.jetbrains.kotlin.psi.JetForExpression import org.jetbrains.kotlin.psi.JetForExpression
import org.jetbrains.kotlin.psi.JetPsiFactory import org.jetbrains.kotlin.psi.JetPsiFactory
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.psi.createExpressionByPattern
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
public class RemoveForLoopIndicesIntention : JetSelfTargetingIntention<JetForExpression>(javaClass(), "Remove indices in for-loop") { public class RemoveForLoopIndicesIntention : JetSelfTargetingRangeIntention<JetForExpression>(javaClass(), "Remove indices in for-loop") {
override fun isApplicableTo(element: JetForExpression, caretOffset: Int): Boolean { private val WITH_INDEX_FQ_NAME = "kotlin.withIndex"
val multiParameter = element.getMultiParameter() ?: return false
if (multiParameter.getEntries().size() != 2) return false
val range = element.getLoopRange() as? JetDotQualifiedExpression ?: return false
val selector = range.getSelectorExpression() as? JetCallExpression ?: return false
if (!selector.textMatches("withIndex()")) return false override fun applicabilityRange(element: JetForExpression): TextRange? {
val loopRange = element.loopRange as? JetDotQualifiedExpression ?: return null
val multiParameter = element.multiParameter ?: return null
if (multiParameter.entries.size() != 2) return null
val body = element.getBody() val bindingContext = element.analyze(BodyResolveMode.PARTIAL)
if (body != null && caretOffset >= body.getTextRange().getStartOffset()) return false
val bindingContext = element.analyze() val resolvedCall = loopRange.getResolvedCall(bindingContext)
val call = bindingContext[BindingContext.CALL, selector.getCalleeExpression()] ?: return false if (resolvedCall?.resultingDescriptor?.fqNameUnsafe?.asString() != WITH_INDEX_FQ_NAME) return null
val callResolution = bindingContext[BindingContext.RESOLVED_CALL, call] ?: return false
val fqName = DescriptorUtils.getFqNameSafe(callResolution.getCandidateDescriptor())
if (fqName.toString() != "kotlin.withIndex") return false
val indexVar = multiParameter.getEntries()[0] val indexVar = multiParameter.entries[0]
return ReferencesSearch.search(indexVar).findFirst() == null if (ReferencesSearch.search(indexVar).any()) return null
return TextRange(element.startOffset, element.body?.startOffset ?: element.endOffset)
} }
override fun applyTo(element: JetForExpression, editor: Editor) { override fun applyTo(element: JetForExpression, editor: Editor) {
val parameter = element.getMultiParameter()!! val multiParameter = element.multiParameter!!
val range = element.getLoopRange() as JetDotQualifiedExpression val loopRange = element.loopRange as JetDotQualifiedExpression
val parameters = parameter.getEntries()
val loop = JetPsiFactory(element).createExpression("for (${parameters[1].getText()} in _) {}") as JetForExpression val elementVar = multiParameter.entries[1]
parameter.replace(loop.getLoopParameter()!!) val loop = JetPsiFactory(element).createExpressionByPattern("for ($0 in _) {}", elementVar.text) as JetForExpression
multiParameter.replace(loop.loopParameter!!)
range.replace(range.getReceiverExpression()) loopRange.replace(loopRange.receiverExpression)
} }
} }