Intrinsics for 'reversed': infrastructure & primitive range support
#KT-21323 In Progress
This commit is contained in:
@@ -188,6 +188,14 @@ fun isPrimitiveNumberRangeExtensionContainsPrimitiveNumber(descriptor: CallableD
|
||||
return true
|
||||
}
|
||||
|
||||
fun isPrimitiveProgressionReverse(descriptor: CallableDescriptor): Boolean {
|
||||
if (!isTopLevelInPackage(descriptor, "reversed", "kotlin.ranges")) return false
|
||||
if (descriptor.valueParameters.isNotEmpty()) return false
|
||||
val extensionReceiverType = descriptor.extensionReceiverParameter?.type ?: return false
|
||||
if (!isPrimitiveProgression(extensionReceiverType)) return false
|
||||
return true
|
||||
}
|
||||
|
||||
private fun isPrimitiveNumberType(type: KotlinType) =
|
||||
KotlinBuiltIns.isByte(type) ||
|
||||
KotlinBuiltIns.isShort(type) ||
|
||||
|
||||
+6
-1
@@ -33,7 +33,8 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class PrimitiveNumberRangeLiteralRangeValue(
|
||||
rangeCall: ResolvedCall<out CallableDescriptor>
|
||||
): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
||||
) : PrimitiveNumberRangeIntrinsicRangeValue(rangeCall),
|
||||
ReversableRangeValue {
|
||||
|
||||
override fun getBoundedValue(codegen: ExpressionCodegen) =
|
||||
SimpleBoundedValue(codegen, rangeCall)
|
||||
@@ -42,6 +43,10 @@ class PrimitiveNumberRangeLiteralRangeValue(
|
||||
getConstRangeForInRangeLiteralGenerator(codegen, forExpression) ?:
|
||||
ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStep1(codegen, forExpression, getBoundedValue(codegen))
|
||||
|
||||
override fun createForInReversedLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator =
|
||||
// TODO const-bounded version
|
||||
ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStepMinus1(codegen, forExpression, getBoundedValue(codegen))
|
||||
|
||||
private fun getConstRangeForInRangeLiteralGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator? {
|
||||
val rhsExpression = rangeCall.valueArgumentsByIndex?.run { get(0).arguments[0].getArgumentExpression() } ?: return null
|
||||
val constValue = codegen.getCompileTimeConstant(rhsExpression).safeAs<IntegerValueConstant<*>>() ?: return null
|
||||
|
||||
@@ -32,6 +32,11 @@ interface RangeValue {
|
||||
}
|
||||
|
||||
|
||||
interface ReversableRangeValue : RangeValue {
|
||||
fun createForInReversedLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator
|
||||
}
|
||||
|
||||
|
||||
interface BoundedValue {
|
||||
val instanceType: Type
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -127,7 +128,15 @@ private fun ExpressionCodegen.createIntrinsifiedRangeValueOrNull(rangeCall: Reso
|
||||
CharSequenceIndicesRangeValue(rangeCall)
|
||||
isComparableRangeTo(rangeCallee) ->
|
||||
ComparableRangeLiteralRangeValue(this, rangeCall)
|
||||
isPrimitiveProgressionReverse(rangeCallee) ->
|
||||
createReversedRangeValueOrNull(rangeCall)
|
||||
else ->
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun ExpressionCodegen.createReversedRangeValueOrNull(rangeCall: ResolvedCall<out CallableDescriptor>): RangeValue? {
|
||||
val receiver = rangeCall.extensionReceiver as? ExpressionReceiver ?: return null
|
||||
val receiverRangeValue = createRangeValueForExpression(receiver.expression) as? ReversableRangeValue ?: return null
|
||||
return ReversedRangeValue(receiverRangeValue)
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.range
|
||||
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForLoopGenerator
|
||||
import org.jetbrains.kotlin.codegen.range.inExpression.InExpressionGenerator
|
||||
import org.jetbrains.kotlin.psi.KtForExpression
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
|
||||
class ReversedRangeValue(private val original: ReversableRangeValue) : RangeValue, ReversableRangeValue {
|
||||
override fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator =
|
||||
original.createInExpressionGenerator(codegen, operatorReference)
|
||||
|
||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator =
|
||||
original.createForInReversedLoopGenerator(codegen, forExpression)
|
||||
|
||||
override fun createForInReversedLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator =
|
||||
original.createForLoopGenerator(codegen, forExpression)
|
||||
}
|
||||
Reference in New Issue
Block a user