Refactoring

This commit is contained in:
Valentin Kipyatkov
2016-05-13 15:41:00 +03:00
parent ebdff775f3
commit 46055dfd2d
2 changed files with 31 additions and 26 deletions
@@ -103,7 +103,7 @@ data class MatchingState(
*/ */
val indexVariable: KtCallableDeclaration?, val indexVariable: KtCallableDeclaration?,
val initializationStatementsToDelete: Collection<KtExpression> = emptyList(), val initializationStatementsToDelete: Collection<KtExpression> = emptyList(),
val previousTransformations: List<SequenceTransformation>, val previousTransformations: MutableList<SequenceTransformation> = arrayListOf(),
val pseudocodeProvider: () -> Pseudocode val pseudocodeProvider: () -> Pseudocode
) )
@@ -46,7 +46,6 @@ import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.addToStdlib.check import org.jetbrains.kotlin.utils.addToStdlib.check
import java.util.*
object MatcherRegistrar { object MatcherRegistrar {
val matchers: Collection<TransformationMatcher> = listOf( val matchers: Collection<TransformationMatcher> = listOf(
@@ -70,31 +69,11 @@ data class MatchResult(
fun match(loop: KtForExpression): MatchResult? { fun match(loop: KtForExpression): MatchResult? {
val (inputVariable, indexVariable, sequenceExpression) = extractLoopData(loop) ?: return null val (inputVariable, indexVariable, sequenceExpression) = extractLoopData(loop) ?: return null
var state = createInitialMatchingState(loop, inputVariable, indexVariable) ?: return null
// used just as optimization to avoid unnecessary checks // used just as optimization to avoid unnecessary checks
val loopContainsEmbeddedBreakOrContinue = loop.containsEmbeddedBreakOrContinue() val loopContainsEmbeddedBreakOrContinue = loop.containsEmbeddedBreakOrContinue()
val sequenceTransformations = ArrayList<SequenceTransformation>()
val pseudocodeProvider: () -> Pseudocode = object : () -> Pseudocode {
val pseudocode: Pseudocode by lazy {
val declaration = loop.containingDeclarationForPseudocode!!
val bindingContext = loop.analyze(BodyResolveMode.FULL)
PseudocodeUtil.generatePseudocode(declaration, bindingContext)
}
override fun invoke() = pseudocode
}
var state = MatchingState(
outerLoop = loop,
innerLoop = loop,
statements = listOf(loop.body ?: return null),
inputVariable = inputVariable,
indexVariable = indexVariable,
previousTransformations = sequenceTransformations,
pseudocodeProvider = pseudocodeProvider
)
MatchLoop@ MatchLoop@
while (true) { while (true) {
state = state.unwrapBlock() state = state.unwrapBlock()
@@ -116,7 +95,7 @@ fun match(loop: KtForExpression): MatchResult? {
if (match != null) { if (match != null) {
if (!inputVariableUsed && match.allTransformations.any { it.shouldUseInputVariable }) return null if (!inputVariableUsed && match.allTransformations.any { it.shouldUseInputVariable }) return null
sequenceTransformations.addAll(match.sequenceTransformations) state.previousTransformations += match.sequenceTransformations
when (match) { when (match) {
is TransformationMatch.Sequence -> { is TransformationMatch.Sequence -> {
@@ -143,7 +122,7 @@ fun match(loop: KtForExpression): MatchResult? {
is TransformationMatch.Result -> { is TransformationMatch.Result -> {
if (restContainsEmbeddedBreakOrContinue && !matcher.embeddedBreakOrContinuePossible) continue@MatchersLoop if (restContainsEmbeddedBreakOrContinue && !matcher.embeddedBreakOrContinuePossible) continue@MatchersLoop
return TransformationMatch.Result(match.resultTransformation, sequenceTransformations) return TransformationMatch.Result(match.resultTransformation, state.previousTransformations)
.let { mergeTransformations(it) } .let { mergeTransformations(it) }
.let { MatchResult(sequenceExpression, it, state.initializationStatementsToDelete) } .let { MatchResult(sequenceExpression, it, state.initializationStatementsToDelete) }
.check { checkSmartCastsPreserved(loop, it) } .check { checkSmartCastsPreserved(loop, it) }
@@ -209,6 +188,32 @@ private fun extractLoopData(loop: KtForExpression): LoopData? {
return LoopData(loop.loopParameter ?: return null, null, loopRange) return LoopData(loop.loopParameter ?: return null, null, loopRange)
} }
private fun createInitialMatchingState(
loop: KtForExpression,
inputVariable: KtCallableDeclaration,
indexVariable: KtCallableDeclaration?
): MatchingState? {
val pseudocodeProvider: () -> Pseudocode = object : () -> Pseudocode {
val pseudocode: Pseudocode by lazy {
val declaration = loop.containingDeclarationForPseudocode!!
val bindingContext = loop.analyze(BodyResolveMode.FULL)
PseudocodeUtil.generatePseudocode(declaration, bindingContext)
}
override fun invoke() = pseudocode
}
return MatchingState(
outerLoop = loop,
innerLoop = loop,
statements = listOf(loop.body ?: return null),
inputVariable = inputVariable,
indexVariable = indexVariable,
pseudocodeProvider = pseudocodeProvider
)
}
private fun isExpressionTypeSupported(expression: KtExpression): Boolean { private fun isExpressionTypeSupported(expression: KtExpression): Boolean {
val type = expression.analyze(BodyResolveMode.PARTIAL).getType(expression) ?: return false val type = expression.analyze(BodyResolveMode.PARTIAL).getType(expression) ?: return false