Skip to content

Commit

Permalink
Desugar Integer.{divide,remainder}Unsigned and {Integer,Long}.toUnsig…
Browse files Browse the repository at this point in the history
…nedString

Note Long.{divide,remainder}Unsigned are already desugared

PiperOrigin-RevId: 335511222
  • Loading branch information
kevin1e100 authored and copybara-github committed Oct 5, 2020
1 parent 080547f commit 73929f9
Show file tree
Hide file tree
Showing 7 changed files with 447 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,24 @@ java_test(
],
)

java_test(
name = "UnsignedIntsTest",
srcs = ["UnsignedIntsTest.java"],
deps = [
"//src/tools/android/java/com/google/devtools/build/android/desugar/runtime:primitives",
"//third_party:junit4",
],
)

java_test(
name = "UnsignedLongsTest",
srcs = ["UnsignedLongsTest.java"],
deps = [
"//src/tools/android/java/com/google/devtools/build/android/desugar/runtime:primitives",
"//third_party:junit4",
],
)

test_suite(
name = "windows_tests",
tags = [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Copyright 2020 The Bazel Authors. All rights reserved.
//
// 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 com.google.devtools.build.android.desugar.runtime;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

import java.util.Random;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link UnsignedInts}. */
@RunWith(JUnit4.class)
public class UnsignedIntsTest {
private static final long[] UNSIGNED_INTS = {
0L,
1L,
2L,
3L,
0x12345678L,
0x5a4316b8L,
0x6cf78a4bL,
0xff1a618bL,
0xfffffffdL,
0xfffffffeL,
0xffffffffL
};

@Test
public void testToLong() {
for (long a : UNSIGNED_INTS) {
assertEquals(a, UnsignedInts.toLong((int) a));
}
}

@Test
public void testCompare() {
for (long a : UNSIGNED_INTS) {
for (long b : UNSIGNED_INTS) {
int cmpAsLongs = Long.compare(a, b);
int cmpAsUInt = UnsignedInts.compare((int) a, (int) b);
assertEquals(Integer.signum(cmpAsLongs), Integer.signum(cmpAsUInt));
}
}
}

@Test
public void testDivide() {
for (long a : UNSIGNED_INTS) {
for (long b : UNSIGNED_INTS) {
try {
assertEquals((int) (a / b), UnsignedInts.divide((int) a, (int) b));
assertFalse(b == 0);
} catch (ArithmeticException e) {
assertEquals(0, b);
}
}
}
}

@Test
public void testRemainder() {
for (long a : UNSIGNED_INTS) {
for (long b : UNSIGNED_INTS) {
try {
assertEquals((int) (a % b), UnsignedInts.remainder((int) a, (int) b));
assertFalse(b == 0);
} catch (ArithmeticException e) {
assertEquals(0, b);
}
}
}
}

@Test
public void testDivideRemainderEuclideanProperty() {
// Use a seed so that the test is deterministic:
Random r = new Random(0L);
for (int i = 0; i < 1000000; i++) {
int dividend = r.nextInt();
int divisor = r.nextInt();
// Test that the Euclidean property is preserved:
assertEquals(
0,
dividend
- (divisor * UnsignedInts.divide(dividend, divisor)
+ UnsignedInts.remainder(dividend, divisor)));
}
}

@Test
public void testToString() {
int[] bases = {2, 5, 7, 8, 10, 16};
for (long a : UNSIGNED_INTS) {
for (int base : bases) {
assertEquals(UnsignedInts.toString((int) a, base), Long.toString(a, base));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.math.BigInteger;
import java.util.Random;
import org.junit.Test;
import org.junit.runner.RunWith;
Expand Down Expand Up @@ -87,4 +88,24 @@ public void testDivideRemainderEuclideanProperty() {
+ UnsignedLongs.remainderUnsigned(dividend, divisor)));
}
}

@Test
public void testToString() {
String[] tests = {
"0",
"ffffffffffffffff",
"7fffffffffffffff",
"ff1a618b7f65ea12",
"5a4316b8c153ac4d",
"6cf78a4b139a4e2a"
};
int[] bases = {2, 5, 7, 8, 10, 16};
for (int base : bases) {
for (String x : tests) {
BigInteger xValue = new BigInteger(x, 16);
long xLong = xValue.longValue(); // signed
assertEquals(xValue.toString(base), UnsignedLongs.toString(xLong, base));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,95 @@ replacements {
range: REPLACE_CALLS_TO_PRIMITIVE_WRAPPERS
}

replacements {
source {
opcode: 184
method_id {
owner: "java/lang/Integer"
name: "divideUnsigned"
desc: "(II)I"
}
is_interface: false
}
destination {
opcode: 184
method_id {
owner: "com/google/devtools/build/android/desugar/runtime/UnsignedInts"
name: "divide"
desc: "(II)I"
}
is_interface: false
}
# TODO(deltazulu): adjust flag name to include INT_UNSIGNED
range: REPLACE_CALLS_TO_LONG_UNSIGNED
}

replacements {
source {
opcode: 184
method_id {
owner: "java/lang/Integer"
name: "remainderUnsigned"
desc: "(II)I"
}
is_interface: false
}
destination {
opcode: 184
method_id {
owner: "com/google/devtools/build/android/desugar/runtime/UnsignedInts"
name: "remainder"
desc: "(II)I"
}
is_interface: false
}
range: REPLACE_CALLS_TO_LONG_UNSIGNED
}

replacements {
source {
opcode: 184
method_id {
owner: "java/lang/Integer"
name: "toUnsignedString"
desc: "(I)Ljava/lang/String;"
}
is_interface: false
}
destination {
opcode: 184
method_id {
owner: "com/google/devtools/build/android/desugar/runtime/UnsignedInts"
name: "toString"
desc: "(I)Ljava/lang/String;"
}
is_interface: false
}
range: REPLACE_CALLS_TO_LONG_UNSIGNED
}

replacements {
source {
opcode: 184
method_id {
owner: "java/lang/Integer"
name: "toUnsignedString"
desc: "(II)Ljava/lang/String;"
}
is_interface: false
}
destination {
opcode: 184
method_id {
owner: "com/google/devtools/build/android/desugar/runtime/UnsignedInts"
name: "toString"
desc: "(II)Ljava/lang/String;"
}
is_interface: false
}
range: REPLACE_CALLS_TO_LONG_UNSIGNED
}

replacements {
source {
opcode: 184
Expand Down Expand Up @@ -221,6 +310,50 @@ replacements {
range: REPLACE_CALLS_TO_LONG_UNSIGNED
}

replacements {
source {
opcode: 184
method_id {
owner: "java/lang/Long"
name: "toUnsignedString"
desc: "(J)Ljava/lang/String;"
}
is_interface: false
}
destination {
opcode: 184
method_id {
owner: "com/google/devtools/build/android/desugar/runtime/UnsignedLongs"
name: "toString"
desc: "(J)Ljava/lang/String;"
}
is_interface: false
}
range: REPLACE_CALLS_TO_LONG_UNSIGNED
}

replacements {
source {
opcode: 184
method_id {
owner: "java/lang/Long"
name: "toUnsignedString"
desc: "(JI)Ljava/lang/String;"
}
is_interface: false
}
destination {
opcode: 184
method_id {
owner: "com/google/devtools/build/android/desugar/runtime/UnsignedLongs"
name: "toString"
desc: "(JI)Ljava/lang/String;"
}
is_interface: false
}
range: REPLACE_CALLS_TO_LONG_UNSIGNED
}

# ==== DESUGAR_JAVA8_LIBS ====

replacements {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ java_library(
name = "primitives",
srcs = [
"PrimitiveHashcode.java",
"UnsignedInts.java",
"UnsignedLongs.java",
],
# This library must be compiled with java7, as we directly copy it to the desugared jar.
Expand Down
Loading

0 comments on commit 73929f9

Please sign in to comment.