| // Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| package com.android.tools.r8.desugar.desugaredlibrary; | |
| import com.android.tools.r8.TestParameters; | |
| import com.android.tools.r8.utils.BooleanUtils; | |
| import java.time.Instant; | |
| import java.time.ZonedDateTime; | |
| import java.util.Date; | |
| import java.util.GregorianCalendar; | |
| import java.util.List; | |
| import java.util.concurrent.atomic.AtomicInteger; | |
| import java.util.function.IntUnaryOperator; | |
| import org.junit.Test; | |
| import org.junit.runner.RunWith; | |
| import org.junit.runners.Parameterized; | |
| import org.junit.runners.Parameterized.Parameters; | |
| @RunWith(Parameterized.class) | |
| public class RetargetOverrideTest extends DesugaredLibraryTestBase { | |
| private final TestParameters parameters; | |
| private final boolean shrinkDesugaredLibrary; | |
| @Parameters(name = "{1}, shrinkDesugaredLibrary: {0}") | |
| public static List<Object[]> data() { | |
| return buildParameters( | |
| BooleanUtils.values(), getTestParameters().withDexRuntimes().withAllApiLevels().build()); | |
| } | |
| public RetargetOverrideTest(boolean shrinkDesugaredLibrary, TestParameters parameters) { | |
| this.shrinkDesugaredLibrary = shrinkDesugaredLibrary; | |
| this.parameters = parameters; | |
| } | |
| @Test | |
| public void testRetargetOverrideD8() throws Exception { | |
| KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters); | |
| String stdout = | |
| testForD8() | |
| .addInnerClasses(RetargetOverrideTest.class) | |
| .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer) | |
| .setMinApi(parameters.getApiLevel()) | |
| .compile() | |
| .addDesugaredCoreLibraryRunClassPath( | |
| this::buildDesugaredLibrary, | |
| parameters.getApiLevel(), | |
| keepRuleConsumer.get(), | |
| shrinkDesugaredLibrary) | |
| .run(parameters.getRuntime(), Executor.class) | |
| .assertSuccess() | |
| .getStdOut(); | |
| assertLines2By2Correct(stdout); | |
| } | |
| @Test | |
| public void testRetargetOverrideR8() throws Exception { | |
| KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters); | |
| String stdout = | |
| testForR8(Backend.DEX) | |
| .addKeepMainRule(Executor.class) | |
| .addInnerClasses(RetargetOverrideTest.class) | |
| .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer) | |
| .setMinApi(parameters.getApiLevel()) | |
| .compile() | |
| .addDesugaredCoreLibraryRunClassPath( | |
| this::buildDesugaredLibrary, | |
| parameters.getApiLevel(), | |
| keepRuleConsumer.get(), | |
| shrinkDesugaredLibrary) | |
| .run(parameters.getRuntime(), Executor.class) | |
| .assertSuccess() | |
| .getStdOut(); | |
| assertLines2By2Correct(stdout); | |
| } | |
| static class Executor { | |
| public static void main(String[] args) { | |
| directTypes(); | |
| polyTypes(); | |
| baseTypes(); | |
| } | |
| public static void directTypes() { | |
| MyCalendarOverride myCal = new MyCalendarOverride(1990, 2, 22); | |
| System.out.println(myCal.toZonedDateTime()); | |
| System.out.println("1990-11-22T00:00Z[GMT]"); | |
| System.out.println(myCal.toInstant()); | |
| System.out.println("1990-03-22T00:00:00Z"); | |
| MyCalendarNoOverride myCalN = new MyCalendarNoOverride(1990, 2, 22); | |
| System.out.println(myCalN.toZonedDateTime()); | |
| System.out.println("1990-03-22T00:00Z[GMT]"); | |
| System.out.println(myCalN.superToZonedDateTime()); | |
| System.out.println("1990-03-22T00:00Z[GMT]"); | |
| System.out.println(myCalN.toInstant()); | |
| System.out.println("1990-03-22T00:00:00Z"); | |
| System.out.println(myCalN.superToInstant()); | |
| System.out.println("1990-03-22T00:00:00Z"); | |
| MyDateDoubleOverride myDateCast2 = new MyDateDoubleOverride(123456789); | |
| System.out.println(myDateCast2.toInstant()); | |
| System.out.println("1970-01-02T10:17:48.789Z"); | |
| MyDateOverride myDate = new MyDateOverride(123456789); | |
| System.out.println(myDate.toInstant()); | |
| System.out.println("1970-01-02T10:17:45.789Z"); | |
| MyDateNoOverride myDateN = new MyDateNoOverride(123456789); | |
| System.out.println(myDateN.toInstant()); | |
| System.out.println("1970-01-02T10:17:36.789Z"); | |
| System.out.println(myDateN.superToInstant()); | |
| System.out.println("1970-01-02T10:17:36.789Z"); | |
| MyAtomicInteger myAtomicInteger = new MyAtomicInteger(42); | |
| System.out.println(myAtomicInteger.getAndUpdate(x -> x + 1)); | |
| System.out.println("42"); | |
| System.out.println(myAtomicInteger.superGetAndUpdate(x -> x + 2)); | |
| System.out.println("43"); | |
| System.out.println(myAtomicInteger.updateAndGet(x -> x + 100)); | |
| System.out.println("145"); | |
| } | |
| public static void polyTypes() { | |
| Date myDateCast = new MyDateOverride(123456789); | |
| System.out.println(myDateCast.toInstant()); | |
| System.out.println("1970-01-02T10:17:45.789Z"); | |
| Date myDateCast2 = new MyDateDoubleOverride(123456789); | |
| System.out.println(myDateCast2.toInstant()); | |
| System.out.println("1970-01-02T10:17:48.789Z"); | |
| Date myDateN = new MyDateNoOverride(123456789); | |
| System.out.println(myDateN.toInstant()); | |
| System.out.println("1970-01-02T10:17:36.789Z"); | |
| GregorianCalendar myCalCast = new MyCalendarOverride(1990, 2, 22); | |
| System.out.println(myCalCast.toZonedDateTime()); | |
| System.out.println("1990-11-22T00:00Z[GMT]"); | |
| System.out.println(myCalCast.toInstant()); | |
| System.out.println("1990-03-22T00:00:00Z"); | |
| GregorianCalendar myCalN = new MyCalendarNoOverride(1990, 2, 22); | |
| System.out.println(myCalN.toZonedDateTime()); | |
| System.out.println("1990-03-22T00:00Z[GMT]"); | |
| System.out.println(myCalN.toInstant()); | |
| System.out.println("1990-03-22T00:00:00Z"); | |
| } | |
| public static void baseTypes() { | |
| java.sql.Date date = new java.sql.Date(123456789); | |
| // The following one is not working on JVMs, but works on Android... | |
| System.out.println(date.toInstant()); | |
| System.out.println("1970-01-02T10:17:36.789Z"); | |
| GregorianCalendar gregCal = new GregorianCalendar(1990, 2, 22); | |
| System.out.println(gregCal.toInstant()); | |
| System.out.println("1990-03-22T00:00:00Z"); | |
| } | |
| } | |
| static class MyCalendarOverride extends GregorianCalendar { | |
| public MyCalendarOverride(int year, int month, int dayOfMonth) { | |
| super(year, month, dayOfMonth); | |
| } | |
| // Cannot override toInstant (final). | |
| @Override | |
| public ZonedDateTime toZonedDateTime() { | |
| return super.toZonedDateTime().withMonth(11); | |
| } | |
| } | |
| static class MyCalendarNoOverride extends GregorianCalendar { | |
| public MyCalendarNoOverride(int year, int month, int dayOfMonth) { | |
| super(year, month, dayOfMonth); | |
| } | |
| public Instant superToInstant() { | |
| return super.toInstant(); | |
| } | |
| public ZonedDateTime superToZonedDateTime() { | |
| return super.toZonedDateTime(); | |
| } | |
| } | |
| static class MyDateOverride extends Date { | |
| public MyDateOverride(long date) { | |
| super(date); | |
| } | |
| @Override | |
| public Instant toInstant() { | |
| return super.toInstant().plusSeconds(9); | |
| } | |
| } | |
| static class MyDateDoubleOverride extends MyDateOverride { | |
| public MyDateDoubleOverride(long date) { | |
| super(date); | |
| } | |
| @Override | |
| public Instant toInstant() { | |
| return super.toInstant().plusSeconds(3); | |
| } | |
| } | |
| static class MyDateNoOverride extends Date { | |
| public MyDateNoOverride(long date) { | |
| super(date); | |
| } | |
| public Instant superToInstant() { | |
| return super.toInstant(); | |
| } | |
| } | |
| static class MyAtomicInteger extends AtomicInteger { | |
| // No overrides, all final methods. | |
| public MyAtomicInteger(int initialValue) { | |
| super(initialValue); | |
| } | |
| public int superGetAndUpdate(IntUnaryOperator op) { | |
| return super.getAndUpdate(op); | |
| } | |
| } | |
| } |