JS: support int overflow behaviour in augmented assignment
This commit is contained in:
+14
-2
@@ -3,13 +3,14 @@ import kotlin.test.*
|
||||
|
||||
var log = ""
|
||||
var result = 20
|
||||
var doubleResult = 40.0
|
||||
|
||||
fun <T> id(value: T) = value
|
||||
|
||||
fun box(): String {
|
||||
result += if (id("true") == "true") {
|
||||
result += 10
|
||||
log += "true chosen"
|
||||
log += "true chosen;"
|
||||
3
|
||||
}
|
||||
else {
|
||||
@@ -17,7 +18,18 @@ fun box(): String {
|
||||
}
|
||||
|
||||
assertEquals(23, result)
|
||||
assertEquals("true chosen", log)
|
||||
|
||||
doubleResult += if (id("true") == "true") {
|
||||
doubleResult += 100
|
||||
log += "true chosen;"
|
||||
2
|
||||
}
|
||||
else {
|
||||
5
|
||||
}
|
||||
|
||||
assertEquals(42, (doubleResult + 0.1).toInt())
|
||||
assertEquals("true chosen;true chosen;", log)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -1,6 +1,3 @@
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
class A() {
|
||||
var x = 0
|
||||
}
|
||||
|
||||
@@ -5951,6 +5951,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("js/js.translator/testData/box/number"), Pattern.compile("^([^_](.+))\\.kt$"), TargetBackend.JS, true);
|
||||
}
|
||||
|
||||
@TestMetadata("assignmentIntOverflow.kt")
|
||||
public void testAssignmentIntOverflow() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/number/assignmentIntOverflow.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("byteAndShortConversions.kt")
|
||||
public void testByteAndShortConversions() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/number/byteAndShortConversions.kt");
|
||||
|
||||
+1
-7
@@ -12366,13 +12366,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
@TestMetadata("assignmentOperations.kt")
|
||||
public void testAssignmentOperations() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/operatorConventions/assignmentOperations.kt");
|
||||
try {
|
||||
doTest(fileName);
|
||||
}
|
||||
catch (Throwable ignore) {
|
||||
return;
|
||||
}
|
||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("incDecOnObject.kt")
|
||||
|
||||
+20
@@ -22,11 +22,16 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.kotlin.js.translate.callTranslator.CallTranslator;
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
|
||||
import org.jetbrains.kotlin.js.translate.general.Translation;
|
||||
import org.jetbrains.kotlin.js.translate.reference.AccessTranslator;
|
||||
import org.jetbrains.kotlin.psi.KtBinaryExpression;
|
||||
import org.jetbrains.kotlin.psi.KtExpression;
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class OverloadedAssignmentTranslator extends AssignmentTranslator {
|
||||
@NotNull
|
||||
public static JsExpression doTranslate(@NotNull KtBinaryExpression expression,
|
||||
@@ -63,6 +68,21 @@ public final class OverloadedAssignmentTranslator extends AssignmentTranslator {
|
||||
JsBlock innerBlock = new JsBlock();
|
||||
TranslationContext innerContext = context().innerBlock(innerBlock);
|
||||
JsExpression oldValue = accessTranslator.translateAsGet();
|
||||
|
||||
JsBlock argumentBlock = new JsBlock();
|
||||
TranslationContext argumentContext = innerContext.innerBlock(argumentBlock);
|
||||
KtExpression argumentPsi = expression.getRight();
|
||||
assert argumentPsi != null;
|
||||
JsExpression argument = Translation.translateAsExpression(argumentPsi, argumentContext);
|
||||
if (!argumentBlock.isEmpty()) {
|
||||
oldValue = innerContext.defineTemporary(oldValue);
|
||||
innerContext.addStatementsToCurrentBlockFrom(argumentBlock);
|
||||
}
|
||||
|
||||
Map<KtExpression, JsExpression> aliases = new HashMap<KtExpression, JsExpression>();
|
||||
aliases.put(argumentPsi, argument);
|
||||
innerContext = innerContext.innerContextWithAliasesForExpressions(aliases);
|
||||
|
||||
JsExpression result = CallTranslator.translate(innerContext, resolvedCall, oldValue);
|
||||
context().addStatementsToCurrentBlockFrom(innerBlock);
|
||||
return result;
|
||||
|
||||
@@ -242,7 +242,10 @@ public final class TranslationUtils {
|
||||
if (operationDescriptor == null || !(operationDescriptor instanceof FunctionDescriptor)) return true;
|
||||
|
||||
KotlinType returnType = operationDescriptor.getReturnType();
|
||||
if (returnType != null && (KotlinBuiltIns.isChar(returnType) || KotlinBuiltIns.isLong(returnType))) return false;
|
||||
if (returnType != null &&
|
||||
(KotlinBuiltIns.isChar(returnType) || KotlinBuiltIns.isLong(returnType) || KotlinBuiltIns.isInt(returnType))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (context.intrinsics().getFunctionIntrinsic((FunctionDescriptor) operationDescriptor).exists()) return true;
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: factAbsNoInline1
|
||||
// CHECK_CONTAINS_NO_CALLS: factAbsNoInline1 except=imul
|
||||
|
||||
internal class State(value: Int) {
|
||||
public var value: Int = value
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package foo
|
||||
|
||||
fun bigValue() = 0x7FFFFFFC
|
||||
|
||||
fun mediumValue() = 0x12345
|
||||
|
||||
fun box(): String {
|
||||
var v = bigValue()
|
||||
v += 1
|
||||
if (v != 0x7FFFFFFD) return "fail1: $v"
|
||||
|
||||
v = bigValue()
|
||||
v += 8
|
||||
if (v != -0x7FFFFFFC) return "fail2: $v"
|
||||
|
||||
v = mediumValue()
|
||||
v *= 0x23456
|
||||
if (v != -2112496338) return "fail3: $v"
|
||||
|
||||
v = bigValue()
|
||||
v *= bigValue()
|
||||
if (v != 16) return "fail4: $v"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Reference in New Issue
Block a user