From 18950b448cf5ed04e3b80b162307ed949b9bb3ff Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 9 Dec 2022 15:53:59 +0100 Subject: [PATCH] IR: simplify for-loop lowering internals a bit Remove ExpressionHandler, HeaderInfoFromCallHandler, ProgressionHandler. --- .../common/lower/RangeContainsLowering.kt | 14 ++++++----- .../backend/common/lower/loops/HeaderInfo.kt | 24 +++---------------- .../loops/handlers/DefaultIterableHandler.kt | 9 ++++--- .../handlers/DefaultProgressionHandler.kt | 10 ++++---- .../loops/handlers/DefaultSequenceHandler.kt | 9 ++++--- .../lower/loops/handlers/DownToHandler.kt | 10 ++++---- .../handlers/IndexedGetIterationHandlers.kt | 8 +++---- .../lower/loops/handlers/IndicesHandlers.kt | 20 +++++++++------- .../lower/loops/handlers/RangeToHandler.kt | 10 ++++---- .../lower/loops/handlers/ReversedHandler.kt | 11 +++++---- .../lower/loops/handlers/StepHandler.kt | 12 +++++----- .../lower/loops/handlers/UntilHandler.kt | 10 ++++---- .../lower/loops/handlers/WithIndexHandler.kt | 14 ++++++----- 13 files changed, 74 insertions(+), 87 deletions(-) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/RangeContainsLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/RangeContainsLowering.kt index 0b91dceabcf..347454f44f5 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/RangeContainsLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/RangeContainsLowering.kt @@ -411,15 +411,16 @@ internal open class RangeHeaderInfoBuilder(context: CommonBackendContext, scopeO } /** Builds a [HeaderInfo] for closed floating-point ranges built using the `rangeTo` function. */ -internal object FloatingPointRangeToHandler : HeaderInfoFromCallHandler { - - override val matcher = SimpleCalleeMatcher { +internal object FloatingPointRangeToHandler : HeaderInfoHandler { + private val matcher = SimpleCalleeMatcher { fqName { it == FqName("kotlin.ranges.${OperatorNameConventions.RANGE_TO}") } extensionReceiver { it != null && it.type.run { isFloat() || isDouble() } } parameterCount { it == 1 } parameter(0) { it.type.run { isFloat() || isDouble() } } } + override fun matchIterable(expression: IrCall): Boolean = matcher(expression) + override fun build(expression: IrCall, data: Nothing?, scopeOwner: IrSymbol) = FloatingPointRangeHeaderInfo( start = expression.extensionReceiver!!, @@ -428,14 +429,15 @@ internal object FloatingPointRangeToHandler : HeaderInfoFromCallHandler { - - override val matcher = SimpleCalleeMatcher { +internal class ComparableRangeToHandler(context: CommonBackendContext) : HeaderInfoHandler { + private val matcher = SimpleCalleeMatcher { fqName { it == FqName("kotlin.ranges.${OperatorNameConventions.RANGE_TO}") } extensionReceiver { it != null && it.type.isSubtypeOfClass(context.ir.symbols.comparable) } parameterCount { it == 1 } } + override fun matchIterable(expression: IrCall): Boolean = matcher(expression) + override fun build(expression: IrCall, data: Nothing?, scopeOwner: IrSymbol) = ComparableRangeInfo( start = expression.extensionReceiver!!, diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderInfo.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderInfo.kt index 0ff3e3c7ba2..27af592e1f6 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderInfo.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderInfo.kt @@ -3,8 +3,6 @@ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ -@file:OptIn(ExperimentalUnsignedTypes::class) - package org.jetbrains.kotlin.backend.common.lower.loops import org.jetbrains.kotlin.backend.common.CommonBackendContext @@ -258,27 +256,11 @@ internal interface HeaderInfoHandler { } } -internal interface ExpressionHandler : HeaderInfoHandler { - fun build(expression: IrExpression, scopeOwner: IrSymbol): HeaderInfo? - override fun build(expression: IrExpression, data: Nothing?, scopeOwner: IrSymbol) = build(expression, scopeOwner) -} - -/** Matches a call to build an iterable and builds a [HeaderInfo] from the call's context. */ -internal interface HeaderInfoFromCallHandler : HeaderInfoHandler { - val matcher: IrCallMatcher - - override fun matchIterable(expression: IrCall) = matcher(expression) -} - -internal typealias ProgressionHandler = HeaderInfoFromCallHandler - internal abstract class HeaderInfoBuilder( context: CommonBackendContext, private val scopeOwnerSymbol: () -> IrSymbol, private val allowUnsignedBounds: Boolean = false -) : - IrElementVisitor { - +) : IrElementVisitor { private val symbols = context.ir.symbols protected open val progressionHandlers = listOf( @@ -291,8 +273,8 @@ internal abstract class HeaderInfoBuilder( StepHandler(context, this) ) - protected abstract val callHandlers: List> - protected abstract val expressionHandlers: List + protected abstract val callHandlers: List> + protected abstract val expressionHandlers: List> override fun visitElement(element: IrElement, data: IrCall?): HeaderInfo? = null diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/DefaultIterableHandler.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/DefaultIterableHandler.kt index 86edb302492..aafbbf29c35 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/DefaultIterableHandler.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/DefaultIterableHandler.kt @@ -7,8 +7,8 @@ package org.jetbrains.kotlin.backend.common.lower.loops.handlers import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.lower.createIrBuilder -import org.jetbrains.kotlin.backend.common.lower.loops.ExpressionHandler import org.jetbrains.kotlin.backend.common.lower.loops.HeaderInfo +import org.jetbrains.kotlin.backend.common.lower.loops.HeaderInfoHandler import org.jetbrains.kotlin.backend.common.lower.loops.IterableHeaderInfo import org.jetbrains.kotlin.ir.builders.createTmpVariable import org.jetbrains.kotlin.ir.builders.irCall @@ -19,13 +19,12 @@ import org.jetbrains.kotlin.ir.util.getSimpleFunction import org.jetbrains.kotlin.util.OperatorNameConventions /** Builds a [HeaderInfo] for Iterables not handled by more specialized handlers. */ -internal class DefaultIterableHandler(private val context: CommonBackendContext) : ExpressionHandler { - +internal class DefaultIterableHandler(private val context: CommonBackendContext) : HeaderInfoHandler { private val iterableClassSymbol = context.ir.symbols.iterable override fun matchIterable(expression: IrExpression) = expression.type.isSubtypeOfClass(iterableClassSymbol) - override fun build(expression: IrExpression, scopeOwner: IrSymbol): HeaderInfo? = + override fun build(expression: IrExpression, data: Nothing?, scopeOwner: IrSymbol): HeaderInfo = with(context.createIrBuilder(scopeOwner, expression.startOffset, expression.endOffset)) { val iteratorFun = iterableClassSymbol.getSimpleFunction(OperatorNameConventions.ITERATOR.asString())!!.owner @@ -33,4 +32,4 @@ internal class DefaultIterableHandler(private val context: CommonBackendContext) scope.createTmpVariable(irCall(iteratorFun).apply { dispatchReceiver = expression }, nameHint = "iterator") ) } -} \ No newline at end of file +} diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/DefaultProgressionHandler.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/DefaultProgressionHandler.kt index a07d4e13a35..2fdb45cba94 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/DefaultProgressionHandler.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/DefaultProgressionHandler.kt @@ -18,9 +18,9 @@ import org.jetbrains.kotlin.ir.util.getPropertyGetter import org.jetbrains.kotlin.ir.util.shallowCopy /** Builds a [HeaderInfo] for progressions not handled by more specialized handlers. */ -internal class DefaultProgressionHandler(private val context: CommonBackendContext, private val allowUnsignedBounds: Boolean = false) : - ExpressionHandler { - +internal class DefaultProgressionHandler( + private val context: CommonBackendContext, private val allowUnsignedBounds: Boolean = false +) : HeaderInfoHandler { private val symbols = context.ir.symbols private val rangeClassesTypes = symbols.rangeClasses.map { it.defaultType }.toSet() @@ -30,7 +30,7 @@ internal class DefaultProgressionHandler(private val context: CommonBackendConte allowUnsignedBounds ) != null - override fun build(expression: IrExpression, scopeOwner: IrSymbol): HeaderInfo? = + override fun build(expression: IrExpression, data: Nothing?, scopeOwner: IrSymbol): HeaderInfo = with(context.createIrBuilder(scopeOwner, expression.startOffset, expression.endOffset)) { // Directly use the `first/last/step` properties of the progression. val (progressionVar, progressionExpression) = createTemporaryVariableIfNecessary(expression, nameHint = "progression") @@ -62,4 +62,4 @@ internal class DefaultProgressionHandler(private val context: CommonBackendConte direction = direction ) } -} \ No newline at end of file +} diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/DefaultSequenceHandler.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/DefaultSequenceHandler.kt index 4a318937582..0b485b07f16 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/DefaultSequenceHandler.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/DefaultSequenceHandler.kt @@ -7,8 +7,8 @@ package org.jetbrains.kotlin.backend.common.lower.loops.handlers import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.lower.createIrBuilder -import org.jetbrains.kotlin.backend.common.lower.loops.ExpressionHandler import org.jetbrains.kotlin.backend.common.lower.loops.HeaderInfo +import org.jetbrains.kotlin.backend.common.lower.loops.HeaderInfoHandler import org.jetbrains.kotlin.backend.common.lower.loops.IterableHeaderInfo import org.jetbrains.kotlin.ir.builders.createTmpVariable import org.jetbrains.kotlin.ir.builders.irCall @@ -19,14 +19,13 @@ import org.jetbrains.kotlin.ir.util.getSimpleFunction import org.jetbrains.kotlin.util.OperatorNameConventions /** Builds a [HeaderInfo] for Sequences not handled by more specialized handlers. */ -internal class DefaultSequenceHandler(private val context: CommonBackendContext) : ExpressionHandler { - +internal class DefaultSequenceHandler(private val context: CommonBackendContext) : HeaderInfoHandler { private val sequenceClassSymbol = context.ir.symbols.sequence override fun matchIterable(expression: IrExpression) = sequenceClassSymbol != null && expression.type.isSubtypeOfClass(sequenceClassSymbol) - override fun build(expression: IrExpression, scopeOwner: IrSymbol): HeaderInfo? = + override fun build(expression: IrExpression, data: Nothing?, scopeOwner: IrSymbol): HeaderInfo = with(context.createIrBuilder(scopeOwner, expression.startOffset, expression.endOffset)) { val iteratorFun = sequenceClassSymbol!!.getSimpleFunction(OperatorNameConventions.ITERATOR.asString())!!.owner @@ -34,4 +33,4 @@ internal class DefaultSequenceHandler(private val context: CommonBackendContext) scope.createTmpVariable(irCall(iteratorFun).apply { dispatchReceiver = expression }, nameHint = "iterator") ) } -} \ No newline at end of file +} diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/DownToHandler.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/DownToHandler.kt index e713addab83..c303638f355 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/DownToHandler.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/DownToHandler.kt @@ -20,19 +20,19 @@ import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.name.FqName /** Builds a [HeaderInfo] for progressions built using the `downTo` extension function. */ -internal class DownToHandler(private val context: CommonBackendContext) : - ProgressionHandler { - +internal class DownToHandler(private val context: CommonBackendContext) : HeaderInfoHandler { private val preferJavaLikeCounterLoop = context.preferJavaLikeCounterLoop private val progressionElementTypes = context.ir.symbols.progressionElementTypes - override val matcher = SimpleCalleeMatcher { + private val matcher = SimpleCalleeMatcher { singleArgumentExtension(FqName("kotlin.ranges.downTo"), progressionElementTypes) parameterCount { it == 1 } parameter(0) { it.type in progressionElementTypes } } + override fun matchIterable(expression: IrCall): Boolean = matcher(expression) + override fun build(expression: IrCall, data: ProgressionType, scopeOwner: IrSymbol) = with(context.createIrBuilder(scopeOwner, expression.startOffset, expression.endOffset)) { val first = expression.extensionReceiver!! @@ -108,4 +108,4 @@ internal class DownToHandler(private val context: CommonBackendContext) : null } } -} \ No newline at end of file +} diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/IndexedGetIterationHandlers.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/IndexedGetIterationHandlers.kt index 29f0e895dfa..685ccde9614 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/IndexedGetIterationHandlers.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/IndexedGetIterationHandlers.kt @@ -7,8 +7,8 @@ package org.jetbrains.kotlin.backend.common.lower.loops.handlers import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.lower.createIrBuilder -import org.jetbrains.kotlin.backend.common.lower.loops.ExpressionHandler import org.jetbrains.kotlin.backend.common.lower.loops.HeaderInfo +import org.jetbrains.kotlin.backend.common.lower.loops.HeaderInfoHandler import org.jetbrains.kotlin.backend.common.lower.loops.IndexedGetHeaderInfo import org.jetbrains.kotlin.backend.common.lower.matchers.Quantifier import org.jetbrains.kotlin.backend.common.lower.matchers.SimpleCalleeMatcher @@ -31,8 +31,8 @@ import org.jetbrains.kotlin.util.OperatorNameConventions abstract class IndexedGetIterationHandler( protected val context: CommonBackendContext, private val canCacheLast: Boolean -) : ExpressionHandler { - override fun build(expression: IrExpression, scopeOwner: IrSymbol): HeaderInfo? = +) : HeaderInfoHandler { + override fun build(expression: IrExpression, data: Nothing?, scopeOwner: IrSymbol): HeaderInfo? = with(context.createIrBuilder(scopeOwner, expression.startOffset, expression.endOffset)) { // Consider the case like: // @@ -156,4 +156,4 @@ internal class StringIterationHandler(context: CommonBackendContext) : CharSeque override val IrType.getFunction: IrSimpleFunction get() = context.ir.symbols.string.getSimpleFunction(OperatorNameConventions.GET.asString())!!.owner -} \ No newline at end of file +} diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/IndicesHandlers.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/IndicesHandlers.kt index aa1b0d6f970..8d7344bf6b0 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/IndicesHandlers.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/IndicesHandlers.kt @@ -22,9 +22,7 @@ import org.jetbrains.kotlin.ir.util.isUnsignedArray import org.jetbrains.kotlin.name.FqName /** Builds a [HeaderInfo] for progressions built using the `indices` extension property. */ -internal abstract class IndicesHandler(protected val context: CommonBackendContext) : - ProgressionHandler { - +internal abstract class IndicesHandler(protected val context: CommonBackendContext) : HeaderInfoHandler { private val preferJavaLikeCounterLoop = context.preferJavaLikeCounterLoop override fun build(expression: IrCall, data: ProgressionType, scopeOwner: IrSymbol): HeaderInfo? = @@ -64,13 +62,14 @@ internal abstract class IndicesHandler(protected val context: CommonBackendConte } internal class CollectionIndicesHandler(context: CommonBackendContext) : IndicesHandler(context) { - - override val matcher = SimpleCalleeMatcher { + private val matcher = SimpleCalleeMatcher { extensionReceiver { it?.type?.isCollection() == true } fqName { it == FqName("kotlin.collections.") } parameterCount { it == 0 } } + override fun matchIterable(expression: IrCall): Boolean = matcher(expression) + override val IrType.sizePropertyGetter: IrSimpleFunction get() = context.ir.symbols.collection.getPropertyGetter("size")!!.owner } @@ -78,7 +77,7 @@ internal class CollectionIndicesHandler(context: CommonBackendContext) : Indices internal class ArrayIndicesHandler(context: CommonBackendContext) : IndicesHandler(context) { private val supportsUnsignedArrays = context.optimizeLoopsOverUnsignedArrays - override val matcher = SimpleCalleeMatcher { + private val matcher = SimpleCalleeMatcher { extensionReceiver { it != null && it.type.run { isArray() || isPrimitiveArray() || (supportsUnsignedArrays && isUnsignedArray()) @@ -88,18 +87,21 @@ internal class ArrayIndicesHandler(context: CommonBackendContext) : IndicesHandl parameterCount { it == 0 } } + override fun matchIterable(expression: IrCall): Boolean = matcher(expression) + override val IrType.sizePropertyGetter: IrSimpleFunction get() = getClass()!!.getPropertyGetter("size")!!.owner } internal class CharSequenceIndicesHandler(context: CommonBackendContext) : IndicesHandler(context) { - - override val matcher = SimpleCalleeMatcher { + private val matcher = SimpleCalleeMatcher { extensionReceiver { it != null && it.type.run { isCharSequence() } } fqName { it == FqName("kotlin.text.") } parameterCount { it == 0 } } + override fun matchIterable(expression: IrCall): Boolean = matcher(expression) + override val IrType.sizePropertyGetter: IrSimpleFunction get() = context.ir.symbols.charSequence.getPropertyGetter("length")!!.owner -} \ No newline at end of file +} diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/RangeToHandler.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/RangeToHandler.kt index 02ad8c56066..47d4510e339 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/RangeToHandler.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/RangeToHandler.kt @@ -17,20 +17,20 @@ import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable import org.jetbrains.kotlin.util.OperatorNameConventions /** Builds a [HeaderInfo] for progressions built using the `rangeTo` function. */ -internal class RangeToHandler(private val context: CommonBackendContext) : - ProgressionHandler { - +internal class RangeToHandler(private val context: CommonBackendContext) : HeaderInfoHandler { private val preferJavaLikeCounterLoop = context.preferJavaLikeCounterLoop private val progressionElementTypes = context.ir.symbols.progressionElementTypes - override val matcher = SimpleCalleeMatcher { + private val matcher = SimpleCalleeMatcher { dispatchReceiver { it != null && it.type in progressionElementTypes } fqName { it.pathSegments().last() == OperatorNameConventions.RANGE_TO } parameterCount { it == 1 } parameter(0) { it.type in progressionElementTypes } } + override fun matchIterable(expression: IrCall): Boolean = matcher(expression) + override fun build(expression: IrCall, data: ProgressionType, scopeOwner: IrSymbol) = with(context.createIrBuilder(scopeOwner, expression.startOffset, expression.endOffset)) { val first = expression.dispatchReceiver!! @@ -145,4 +145,4 @@ internal class RangeToHandler(private val context: CommonBackendContext) : null } } -} \ No newline at end of file +} diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/ReversedHandler.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/ReversedHandler.kt index b0aaf0f08d4..e073f9e133f 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/ReversedHandler.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/ReversedHandler.kt @@ -7,7 +7,7 @@ package org.jetbrains.kotlin.backend.common.lower.loops.handlers import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.lower.loops.HeaderInfoBuilder -import org.jetbrains.kotlin.backend.common.lower.loops.HeaderInfoFromCallHandler +import org.jetbrains.kotlin.backend.common.lower.loops.HeaderInfoHandler import org.jetbrains.kotlin.backend.common.lower.matchers.Quantifier import org.jetbrains.kotlin.backend.common.lower.matchers.createIrCallMatcher import org.jetbrains.kotlin.ir.expressions.IrCall @@ -17,12 +17,11 @@ import org.jetbrains.kotlin.name.FqName /** Builds a [HeaderInfo] for calls to reverse an iterable. */ internal class ReversedHandler(context: CommonBackendContext, private val visitor: HeaderInfoBuilder) : - HeaderInfoFromCallHandler { - + HeaderInfoHandler { private val progressionClassesTypes = context.ir.symbols.progressionClasses.map { it.defaultType }.toSet() // Use Quantifier.ANY so we can handle all reversed iterables in the same manner. - override val matcher = + private val matcher = createIrCallMatcher(Quantifier.ANY) { // Matcher for reversed progression. callee { @@ -34,7 +33,9 @@ internal class ReversedHandler(context: CommonBackendContext, private val visito // TODO: Handle reversed String, Progression.withIndex(), etc. } + override fun matchIterable(expression: IrCall): Boolean = matcher(expression) + // Reverse the HeaderInfo from the underlying progression or array (if any). override fun build(expression: IrCall, data: Nothing?, scopeOwner: IrSymbol) = expression.extensionReceiver!!.accept(visitor, null)?.asReversed() -} \ No newline at end of file +} diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/StepHandler.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/StepHandler.kt index 9a24e578c11..45f356de202 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/StepHandler.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/StepHandler.kt @@ -28,19 +28,19 @@ import kotlin.math.absoluteValue /** Builds a [HeaderInfo] for progressions built using the `step` extension function. */ internal class StepHandler( - private val context: CommonBackendContext, - private val visitor: HeaderInfoBuilder -) : ProgressionHandler { - + private val context: CommonBackendContext, private val visitor: HeaderInfoBuilder +) : HeaderInfoHandler { private val symbols = context.ir.symbols - override val matcher = SimpleCalleeMatcher { + private val matcher = SimpleCalleeMatcher { singleArgumentExtension( FqName("kotlin.ranges.step"), symbols.progressionClasses.map { it.defaultType }) parameter(0) { it.type.isInt() || it.type.isLong() } } + override fun matchIterable(expression: IrCall): Boolean = matcher(expression) + override fun build(expression: IrCall, data: ProgressionType, scopeOwner: IrSymbol): HeaderInfo? = with(context.createIrBuilder(scopeOwner, expression.startOffset, expression.endOffset)) { // Retrieve the HeaderInfo from the underlying progression (if any). @@ -321,4 +321,4 @@ internal class StepHandler( } } } -} \ No newline at end of file +} diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/UntilHandler.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/UntilHandler.kt index 35ee8fd74a1..1610a51887e 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/UntilHandler.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/UntilHandler.kt @@ -16,18 +16,18 @@ import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.name.FqName /** Builds a [HeaderInfo] for progressions built using the `until` extension function. */ -internal class UntilHandler(private val context: CommonBackendContext) : - ProgressionHandler { - +internal class UntilHandler(private val context: CommonBackendContext) : HeaderInfoHandler { private val symbols = context.ir.symbols private val progressionElementTypes = symbols.progressionElementTypes - override val matcher = SimpleCalleeMatcher { + private val matcher = SimpleCalleeMatcher { singleArgumentExtension(FqName("kotlin.ranges.until"), progressionElementTypes) parameterCount { it == 1 } parameter(0) { it.type in progressionElementTypes } } + override fun matchIterable(expression: IrCall): Boolean = matcher(expression) + override fun build(expression: IrCall, data: ProgressionType, scopeOwner: IrSymbol): HeaderInfo? = with(context.createIrBuilder(scopeOwner, expression.startOffset, expression.endOffset)) { ProgressionHeaderInfo( @@ -40,4 +40,4 @@ internal class UntilHandler(private val context: CommonBackendContext) : direction = ProgressionDirection.INCREASING ) } -} \ No newline at end of file +} diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/WithIndexHandler.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/WithIndexHandler.kt index 196c0dfd56b..c0b8fd0d7bd 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/WithIndexHandler.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/WithIndexHandler.kt @@ -7,7 +7,7 @@ package org.jetbrains.kotlin.backend.common.lower.loops.handlers import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.lower.loops.HeaderInfo -import org.jetbrains.kotlin.backend.common.lower.loops.HeaderInfoFromCallHandler +import org.jetbrains.kotlin.backend.common.lower.loops.HeaderInfoHandler import org.jetbrains.kotlin.backend.common.lower.loops.NestedHeaderInfoBuilderForWithIndex import org.jetbrains.kotlin.backend.common.lower.loops.WithIndexHeaderInfo import org.jetbrains.kotlin.backend.common.lower.matchers.Quantifier @@ -23,13 +23,13 @@ import org.jetbrains.kotlin.ir.util.isUnsignedArray import org.jetbrains.kotlin.name.FqName /** Builds a [HeaderInfo] for calls to `withIndex()`. */ -internal class WithIndexHandler(context: CommonBackendContext, private val visitor: NestedHeaderInfoBuilderForWithIndex) : - HeaderInfoFromCallHandler { - +internal class WithIndexHandler( + context: CommonBackendContext, private val visitor: NestedHeaderInfoBuilderForWithIndex +) : HeaderInfoHandler { private val supportsUnsignedArrays = context.optimizeLoopsOverUnsignedArrays // Use Quantifier.ANY so we can handle all `withIndex()` calls in the same manner. - override val matcher = + private val matcher = createIrCallMatcher(Quantifier.ANY) { callee { fqName { it == FqName("kotlin.collections.withIndex") } @@ -53,6 +53,8 @@ internal class WithIndexHandler(context: CommonBackendContext, private val visit } } + override fun matchIterable(expression: IrCall): Boolean = matcher(expression) + override fun build(expression: IrCall, data: Nothing?, scopeOwner: IrSymbol): HeaderInfo? { // WithIndexHeaderInfo is a composite that contains the HeaderInfo for the underlying iterable (if any). val nestedInfo = expression.extensionReceiver!!.accept(visitor, null) ?: return null @@ -63,4 +65,4 @@ internal class WithIndexHandler(context: CommonBackendContext, private val visit return WithIndexHeaderInfo(nestedInfo) } -} \ No newline at end of file +}