From d0c261c779298dfe699b2950690fea6690b96565 Mon Sep 17 00:00:00 2001 From: Mark Punzalan Date: Wed, 6 Nov 2019 15:54:13 -0800 Subject: [PATCH] Ensure the correct functions (with correct params) are being used in ForLoopsLowering. --- .../common/lower/loops/HeaderProcessor.kt | 4 ++-- .../common/lower/loops/ProgressionHandlers.kt | 22 ++++++++++++++----- .../backend/common/lower/loops/Utils.kt | 12 +++++++--- ...rInCharSequenceWithMultipleGetFunctions.kt | 21 ++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 5 +++++ .../LightAnalysisModeTestGenerated.java | 5 +++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 5 +++++ .../IrJsCodegenBoxTestGenerated.java | 5 +++++ .../semantics/JsCodegenBoxTestGenerated.java | 5 +++++ 9 files changed, 74 insertions(+), 10 deletions(-) create mode 100644 compiler/testData/codegen/box/ranges/forInCharSequenceWithMultipleGetFunctions.kt diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt index 77a550c4f02..56e10ff58a1 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt @@ -63,8 +63,8 @@ internal sealed class ForLoopHeader( /** Statement used to increment the induction variable. */ fun incrementInductionVariable(builder: DeclarationIrBuilder): IrStatement = with(builder) { // inductionVariable = inductionVariable + step - val plusFun = inductionVariable.type.getClass()!!.functions.first { - it.name.asString() == "plus" && + val plusFun = inductionVariable.type.getClass()!!.functions.single { + it.name == OperatorNameConventions.PLUS && it.valueParameters.size == 1 && it.valueParameters[0].type == step.type } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionHandlers.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionHandlers.kt index 93e89adb5a6..769703cc8f8 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionHandlers.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionHandlers.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.util.OperatorNameConventions import kotlin.math.absoluteValue /** Builds a [HeaderInfo] for progressions built using the `rangeTo` function. */ @@ -31,7 +32,7 @@ internal class RangeToHandler(private val context: CommonBackendContext, private override val matcher = SimpleCalleeMatcher { dispatchReceiver { it != null && it.type in progressionElementTypes } - fqName { it.pathSegments().last() == Name.identifier("rangeTo") } + fqName { it.pathSegments().last() == OperatorNameConventions.RANGE_TO } parameterCount { it == 1 } parameter(0) { it.type in progressionElementTypes } } @@ -649,7 +650,11 @@ internal class ArrayIterationHandler(context: CommonBackendContext) : IndexedGet get() = getClass()!!.getPropertyGetter("size")!!.owner override val IrType.getFunction - get() = getClass()!!.functions.first { it.name.asString() == "get" } + get() = getClass()!!.functions.single { + it.name == OperatorNameConventions.GET && + it.valueParameters.size == 1 && + it.valueParameters[0].type.isInt() + } } /** Builds a [HeaderInfo] for iteration over characters in a [String]. */ @@ -660,7 +665,11 @@ internal class StringIterationHandler(context: CommonBackendContext) : IndexedGe get() = getClass()!!.getPropertyGetter("length")!!.owner override val IrType.getFunction - get() = getClass()!!.functions.first { it.name.asString() == "get" } + get() = getClass()!!.functions.single { + it.name == OperatorNameConventions.GET && + it.valueParameters.size == 1 && + it.valueParameters[0].type.isInt() + } } /** @@ -679,6 +688,9 @@ internal class CharSequenceIterationHandler(context: CommonBackendContext) : Ind get() = getClass()?.getPropertyGetter("length")?.owner ?: context.ir.symbols.charSequence.getPropertyGetter("length")!!.owner override val IrType.getFunction - get() = getClass()?.functions?.first { it.name.asString() == "get" } - ?: context.ir.symbols.charSequence.getSimpleFunction("get")!!.owner + get() = getClass()?.functions?.single { + it.name == OperatorNameConventions.GET && + it.valueParameters.size == 1 && + it.valueParameters[0].type.isInt() + } ?: context.ir.symbols.charSequence.getSimpleFunction(OperatorNameConventions.GET.asString())!!.owner } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/Utils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/Utils.kt index ac5941143b4..854293cf82a 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/Utils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/Utils.kt @@ -25,7 +25,7 @@ internal fun IrExpression.castIfNecessary(targetType: IrType, numberCastFunction return if (type == targetType || type.isNothing()) { this } else { - val castFun = type.getClass()!!.functions.first { it.name == numberCastFunctionName } + val castFun = type.getClass()!!.functions.single { it.name == numberCastFunctionName && it.valueParameters.isEmpty() } IrCallImpl(startOffset, endOffset, castFun.returnType, castFun.symbol) .apply { dispatchReceiver = this@castIfNecessary } } @@ -40,7 +40,10 @@ internal fun IrExpression.negate(): IrExpression { // This expression's type could be Nothing from an exception throw, in which case the unary minus function will not exist. if (type.isNothing()) return this - val unaryMinusFun = type.getClass()!!.functions.first { it.name == OperatorNameConventions.UNARY_MINUS } + val unaryMinusFun = type.getClass()!!.functions.single { + it.name == OperatorNameConventions.UNARY_MINUS && + it.valueParameters.isEmpty() + } IrCallImpl(startOffset, endOffset, type, unaryMinusFun.symbol, unaryMinusFun.descriptor).apply { dispatchReceiver = this@negate } @@ -55,7 +58,10 @@ internal fun IrExpression.decrement(): IrExpression { is Long -> IrConstImpl(startOffset, endOffset, type, IrConstKind.Long, thisValue - 1) is Char -> IrConstImpl(startOffset, endOffset, type, IrConstKind.Char, thisValue - 1) else -> { - val decFun = type.getClass()!!.functions.first { it.name == OperatorNameConventions.DEC } + val decFun = type.getClass()!!.functions.single { + it.name == OperatorNameConventions.DEC && + it.valueParameters.isEmpty() + } IrCallImpl(startOffset, endOffset, type, decFun.symbol, decFun.descriptor).apply { dispatchReceiver = this@decrement } diff --git a/compiler/testData/codegen/box/ranges/forInCharSequenceWithMultipleGetFunctions.kt b/compiler/testData/codegen/box/ranges/forInCharSequenceWithMultipleGetFunctions.kt new file mode 100644 index 00000000000..968e2762f14 --- /dev/null +++ b/compiler/testData/codegen/box/ranges/forInCharSequenceWithMultipleGetFunctions.kt @@ -0,0 +1,21 @@ +// KJS_WITH_FULL_RUNTIME +// WITH_RUNTIME +import kotlin.test.* + +class MyCharSequence(val s: String) : CharSequence { + fun get(foo: String): Char = TODO("shouldn't be called!") + override val length = s.length + override fun subSequence(startIndex: Int, endIndex: Int) = s.subSequence(startIndex, endIndex) + override fun get(index: Int) = s.get(index) +} + +fun box(): String { + val cs = MyCharSequence("1234") + val result = StringBuilder() + for (c in cs) { + result.append(c) + } + assertEquals("1234", result.toString()) + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 6951e32f793..5b297653417 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -19096,6 +19096,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/ranges/forInCharSequenceLengthIncreasedInLoopBody.kt"); } + @TestMetadata("forInCharSequenceWithMultipleGetFunctions.kt") + public void testForInCharSequenceWithMultipleGetFunctions() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInCharSequenceWithMultipleGetFunctions.kt"); + } + @TestMetadata("forInRangeLiteralWithMixedTypeBounds.kt") public void testForInRangeLiteralWithMixedTypeBounds() throws Exception { runTest("compiler/testData/codegen/box/ranges/forInRangeLiteralWithMixedTypeBounds.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 94282e9b4d1..0f8c1a13b0c 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -19096,6 +19096,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/ranges/forInCharSequenceLengthIncreasedInLoopBody.kt"); } + @TestMetadata("forInCharSequenceWithMultipleGetFunctions.kt") + public void testForInCharSequenceWithMultipleGetFunctions() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInCharSequenceWithMultipleGetFunctions.kt"); + } + @TestMetadata("forInRangeLiteralWithMixedTypeBounds.kt") public void testForInRangeLiteralWithMixedTypeBounds() throws Exception { runTest("compiler/testData/codegen/box/ranges/forInRangeLiteralWithMixedTypeBounds.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index bca9482c7c8..6856cee36bf 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -17915,6 +17915,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/ranges/forInCharSequenceLengthIncreasedInLoopBody.kt"); } + @TestMetadata("forInCharSequenceWithMultipleGetFunctions.kt") + public void testForInCharSequenceWithMultipleGetFunctions() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInCharSequenceWithMultipleGetFunctions.kt"); + } + @TestMetadata("forInRangeLiteralWithMixedTypeBounds.kt") public void testForInRangeLiteralWithMixedTypeBounds() throws Exception { runTest("compiler/testData/codegen/box/ranges/forInRangeLiteralWithMixedTypeBounds.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index ab89aa0525d..480f4185a65 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -14851,6 +14851,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/ranges/forInCharSequenceLengthIncreasedInLoopBody.kt"); } + @TestMetadata("forInCharSequenceWithMultipleGetFunctions.kt") + public void testForInCharSequenceWithMultipleGetFunctions() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInCharSequenceWithMultipleGetFunctions.kt"); + } + @TestMetadata("forInRangeLiteralWithMixedTypeBounds.kt") public void testForInRangeLiteralWithMixedTypeBounds() throws Exception { runTest("compiler/testData/codegen/box/ranges/forInRangeLiteralWithMixedTypeBounds.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 5960cc5c397..28cb0173ca9 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -16006,6 +16006,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/ranges/forInCharSequenceLengthIncreasedInLoopBody.kt"); } + @TestMetadata("forInCharSequenceWithMultipleGetFunctions.kt") + public void testForInCharSequenceWithMultipleGetFunctions() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInCharSequenceWithMultipleGetFunctions.kt"); + } + @TestMetadata("forInRangeLiteralWithMixedTypeBounds.kt") public void testForInRangeLiteralWithMixedTypeBounds() throws Exception { runTest("compiler/testData/codegen/box/ranges/forInRangeLiteralWithMixedTypeBounds.kt");