diff options
author | Søren Gjesse <sgjesse@google.com> | 2017-10-25 16:27:00 +0200 |
---|---|---|
committer | Søren Gjesse <sgjesse@google.com> | 2017-10-25 16:27:00 +0200 |
commit | 6a6117560d9f9bf6c0c82c1205f539d22adf7f8d (patch) | |
tree | 9d4fb429650b845eacc39e1b29388998729435b9 | |
parent | 9567018de1d5061edab34ab01cb04d5252560d54 (diff) | |
parent | 1a0b0daf39e15abeab62eee35cd658d18fddaa47 (diff) | |
download | r8-6a6117560d9f9bf6c0c82c1205f539d22adf7f8d.tar.gz |
Update external/r8 to 1a0b0da
Merge remote-tracking branch 'aosp/upstream-mirror' into merge-r8-1a0b0da
Test: m -j USE_D8=true USE_R8=true
Change-Id: I96089c1eb1bf66085d2434b053d3c112d0ecf3a9
19 files changed, 209 insertions, 91 deletions
diff --git a/build.gradle b/build.gradle index ef09f766e..9299592c7 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,17 @@ def errorProneConfiguration = [ '-Xep:RemoveUnusedImports:WARN', '-Xep:MissingOverride:WARN', '-Xep:OvershadowingSubclassFields:WARN', - '-Xep:IntLongMath:WARN'] + '-Xep:IntLongMath:WARN', + '-Xep:EqualsHashCode:WARN', + '-Xep:ArrayHashCode:WARN', + '-Xep:EqualsIncompatibleType:WARN', + '-Xep:NonOverridingEquals:WARN', + '-Xep:FallThrough:WARN', + '-Xep:MissingCasesInEnumSwitch:WARN', + '-Xep:MissingDefault:WARN', + '-Xep:MultipleTopLevelClasses:WARN', + '-Xep:NarrowingCompoundAssignment:WARN', + '-Xep:BoxedPrimitiveConstructor:WARN'] apply from: 'copyAdditionalJctfCommonFiles.gradle' diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java index 5b3cfb5ee..1df56dbe7 100644 --- a/src/main/java/com/android/tools/r8/R8Command.java +++ b/src/main/java/com/android/tools/r8/R8Command.java @@ -224,6 +224,7 @@ public class R8Command extends BaseCompilerCommand { throw new CompilationException(e.getMessage(), e.getCause()); } configurationBuilder = parser.getConfigurationBuilder(); + configurationBuilder.setForceProguardCompatibility(forceProguardCompatibility); } if (proguardConfigurationConsumer != null) { diff --git a/src/main/java/com/android/tools/r8/bisect/BisectState.java b/src/main/java/com/android/tools/r8/bisect/BisectState.java index b9359a303..f1810223f 100644 --- a/src/main/java/com/android/tools/r8/bisect/BisectState.java +++ b/src/main/java/com/android/tools/r8/bisect/BisectState.java @@ -104,6 +104,11 @@ public class BisectState { return start == o.start && end == o.end; } + @Override + public int hashCode() { + return 31 * start + end; + } + private boolean verify() { return start <= end; } diff --git a/src/main/java/com/android/tools/r8/compatdexbuilder/CompatDexBuilder.java b/src/main/java/com/android/tools/r8/compatdexbuilder/CompatDexBuilder.java index 93b1b249b..356451a86 100644 --- a/src/main/java/com/android/tools/r8/compatdexbuilder/CompatDexBuilder.java +++ b/src/main/java/com/android/tools/r8/compatdexbuilder/CompatDexBuilder.java @@ -75,6 +75,9 @@ public class CompatDexBuilder { case "--nolocals": noLocals = true; break; + default: + System.err.println("Unsupported option: " + flag); + System.exit(1); } } diff --git a/src/main/java/com/android/tools/r8/compatproguard/CompatProguardCommandBuilder.java b/src/main/java/com/android/tools/r8/compatproguard/CompatProguardCommandBuilder.java index 2c7c43b7a..71bc6eb0d 100644 --- a/src/main/java/com/android/tools/r8/compatproguard/CompatProguardCommandBuilder.java +++ b/src/main/java/com/android/tools/r8/compatproguard/CompatProguardCommandBuilder.java @@ -7,7 +7,7 @@ package com.android.tools.r8.compatproguard; import com.android.tools.r8.R8Command; public class CompatProguardCommandBuilder extends R8Command.Builder { - CompatProguardCommandBuilder(boolean forceProguardCompatibility) { + public CompatProguardCommandBuilder(boolean forceProguardCompatibility) { super(true, forceProguardCompatibility); setEnableDesugaring(false); } diff --git a/src/main/java/com/android/tools/r8/dex/Marker.java b/src/main/java/com/android/tools/r8/dex/Marker.java index ef17aa761..463d4843f 100644 --- a/src/main/java/com/android/tools/r8/dex/Marker.java +++ b/src/main/java/com/android/tools/r8/dex/Marker.java @@ -53,7 +53,7 @@ public class Marker { public Marker put(String key, int value) { // value is converted to Long ensuring equals works with the parsed json string. - return internalPut(key, new Long(value)); + return internalPut(key, Long.valueOf(value)); } public Marker put(String key, String value) { diff --git a/src/main/java/com/android/tools/r8/ir/code/Position.java b/src/main/java/com/android/tools/r8/ir/code/Position.java index a8312fbd4..08298bb15 100644 --- a/src/main/java/com/android/tools/r8/ir/code/Position.java +++ b/src/main/java/com/android/tools/r8/ir/code/Position.java @@ -4,6 +4,7 @@ package com.android.tools.r8.ir.code; import com.android.tools.r8.graph.DexString; +import java.util.Objects; public class Position { @@ -53,6 +54,14 @@ public class Position { } @Override + public int hashCode() { + int result = line; + result = 31 * result + Objects.hashCode(file); + result = 31 * result + (synthetic ? 1 : 0); + return result; + } + + @Override public String toString() { if (isNone()) { return "--"; diff --git a/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java index 4d97764cd..042232b82 100644 --- a/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java +++ b/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java @@ -1219,6 +1219,8 @@ public class DexBuilder { throw new Unreachable("Unexpected type: " + move.outType()); } break; + default: + throw new Unreachable("Unexpected size: " + size); } instruction.setOffset(getOffset()); instructions.add(instruction); diff --git a/src/main/java/com/android/tools/r8/ir/conversion/JarSourceCode.java b/src/main/java/com/android/tools/r8/ir/conversion/JarSourceCode.java index 18622775f..3cd2b5799 100644 --- a/src/main/java/com/android/tools/r8/ir/conversion/JarSourceCode.java +++ b/src/main/java/com/android/tools/r8/ir/conversion/JarSourceCode.java @@ -2600,9 +2600,9 @@ public class JarSourceCode implements SourceCode { case Type.METHOD: return new DexValue.DexValueMethodType( application.getProto(((Type) value).getDescriptor())); + default: + throw new Unreachable("Type sort is not supported: " + type.getSort()); } - throw new Unreachable("Type sort is not supported: " + type.getSort()); - } else if (value instanceof Handle) { return new DexValue.DexValueMethodHandle(getMethodHandle(application, (Handle) value)); } else { diff --git a/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureParser.java b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureParser.java index 2d9154a89..9a5baafa8 100644 --- a/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureParser.java +++ b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureParser.java @@ -360,8 +360,9 @@ public class GenericSignatureParser<T> { case '<': case '.': return true; + default: + return false; } - return false; } // PRE: symbol is the first char of the identifier. diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java index 4a843215f..b3cfcb2aa 100644 --- a/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java +++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java @@ -44,6 +44,8 @@ public class ProguardConfiguration { private boolean useUniqueClassMemberNames; private boolean keepParameterNames; private ProguardClassFilter.Builder adaptClassStrings = ProguardClassFilter.builder(); + private boolean forceProguardCompatibility = false; + private Builder(DexItemFactory dexItemFactory) { this.dexItemFactory = dexItemFactory; resetProguardDefaults(); @@ -205,7 +207,22 @@ public class ProguardConfiguration { adaptClassStrings.addPattern(pattern); } + public void setForceProguardCompatibility(boolean forceProguardCompatibility) { + this.forceProguardCompatibility = forceProguardCompatibility; + } + public ProguardConfiguration build() throws CompilationException { + ProguardKeepAttributes keepAttributes; + + + if (forceProguardCompatibility + && !isObfuscating() + && keepAttributePatterns.size() == 0) { + keepAttributes = ProguardKeepAttributes.fromPatterns(ProguardKeepAttributes.KEEP_ALL); + } else { + keepAttributes = ProguardKeepAttributes.fromPatterns(keepAttributePatterns); + } + return new ProguardConfiguration( dexItemFactory, injars, @@ -224,7 +241,7 @@ public class ProguardConfiguration { applyMappingFile, verbose, renameSourceFileAttribute, - keepAttributePatterns, + keepAttributes, dontWarnPatterns.build(), rules, printSeeds, @@ -285,7 +302,7 @@ public class ProguardConfiguration { Path applyMappingFile, boolean verbose, String renameSourceFileAttribute, - List<String> keepAttributesPatterns, + ProguardKeepAttributes keepAttributes, ProguardClassFilter dontWarnPatterns, List<ProguardConfigurationRule> rules, boolean printSeeds, @@ -313,7 +330,7 @@ public class ProguardConfiguration { this.applyMappingFile = applyMappingFile; this.verbose = verbose; this.renameSourceFileAttribute = renameSourceFileAttribute; - this.keepAttributes = ProguardKeepAttributes.fromPatterns(keepAttributesPatterns); + this.keepAttributes = keepAttributes; this.dontWarnPatterns = dontWarnPatterns; this.rules = ImmutableList.copyOf(rules); this.printSeeds = printSeeds; diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java index 40b759810..d24a3578f 100644 --- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java +++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java @@ -683,6 +683,8 @@ public class ProguardConfigurationParser { flags.setVolatile(); } break; + default: + // Intentionally left empty. } } } diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java index f3e6c6f33..121641b69 100644 --- a/src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java +++ b/src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java @@ -203,6 +203,7 @@ public class ProguardMemberRule { if (method.isClassInitializer()) { break; } + // Fall through for all other methods. case ALL: // Access flags check. if (!method.accessFlags.containsAllOf(getAccessFlags()) || @@ -319,6 +320,7 @@ public class ProguardMemberRule { case METHOD: result.append(getType()); result.append(' '); + // Fall through for rest of method signature. case CONSTRUCTOR: case INIT: { result.append(getName()); diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardTypeMatcher.java b/src/main/java/com/android/tools/r8/shaking/ProguardTypeMatcher.java index e50a1e389..ef149f74f 100644 --- a/src/main/java/com/android/tools/r8/shaking/ProguardTypeMatcher.java +++ b/src/main/java/com/android/tools/r8/shaking/ProguardTypeMatcher.java @@ -48,12 +48,13 @@ public abstract class ProguardTypeMatcher { return MatchClassTypes.LEGACY_MATCH_CLASS_TYPES; case MATCH_BASIC_PATTERN: return MatchBasicTypes.MATCH_BASIC_TYPES; + default: + if (!pattern.contains("*") && !pattern.contains("%") && !pattern.contains("?")) { + return new MatchSpecificType( + dexItemFactory.createType(DescriptorUtils.javaTypeToDescriptor(pattern))); + } + return new MatchTypePattern(pattern, kind); } - if (!pattern.contains("*") && !pattern.contains("%") && !pattern.contains("?")) { - return new MatchSpecificType( - dexItemFactory.createType(DescriptorUtils.javaTypeToDescriptor(pattern))); - } - return new MatchTypePattern(pattern, kind); } public static ProguardTypeMatcher defaultAllMatcher() { diff --git a/src/test/java/com/android/tools/r8/debug/DebugTestBase.java b/src/test/java/com/android/tools/r8/debug/DebugTestBase.java index 35760ef76..de8c673d2 100644 --- a/src/test/java/com/android/tools/r8/debug/DebugTestBase.java +++ b/src/test/java/com/android/tools/r8/debug/DebugTestBase.java @@ -25,6 +25,7 @@ import com.android.tools.r8.utils.AndroidApiLevel; import com.android.tools.r8.utils.DescriptorUtils; import com.android.tools.r8.utils.InternalOptions; import com.android.tools.r8.utils.OffOrAuto; +import com.google.common.collect.ImmutableList; import it.unimi.dsi.fastutil.longs.LongArrayList; import it.unimi.dsi.fastutil.longs.LongList; import java.io.File; @@ -434,14 +435,39 @@ public abstract class DebugTestBase { private JUnit3Wrapper.Command step(StepKind stepKind, StepLevel stepLevel, StepFilter stepFilter) { - return new JUnit3Wrapper.Command.StepCommand(stepKind.jdwpValue, stepLevel.jdwpValue, - stepFilter, state -> true); + return new JUnit3Wrapper.Command.StepCommand(stepKind, stepLevel, stepFilter); } protected JUnit3Wrapper.Command stepUntil(StepKind stepKind, StepLevel stepLevel, Function<JUnit3Wrapper.DebuggeeState, Boolean> stepUntil) { - return new JUnit3Wrapper.Command.StepCommand(stepKind.jdwpValue, stepLevel.jdwpValue, NO_FILTER, - stepUntil); + return stepUntil(stepKind, stepLevel, stepUntil, DEFAULT_FILTER); + } + + protected JUnit3Wrapper.Command stepUntil(StepKind stepKind, StepLevel stepLevel, + Function<JUnit3Wrapper.DebuggeeState, Boolean> stepUntil, StepFilter stepFilter) { + // We create an extension to the given step filter which will also check whether we need to + // step again according to the given stepUntil function. + StepFilter stepUntilFilter = new StepFilter() { + @Override + public List<String> getExcludedClasses() { + return stepFilter.getExcludedClasses(); + } + + @Override + public boolean skipLocation(JUnit3Wrapper.DebuggeeState debuggeeState, JUnit3Wrapper wrapper, + JUnit3Wrapper.Command.StepCommand stepCommand) { + if (stepFilter.skipLocation(debuggeeState, wrapper, stepCommand)) { + return true; + } + if (stepUntil.apply(debuggeeState) == Boolean.FALSE) { + // We did not reach the expected location so step again. + wrapper.enqueueCommandFirst(stepCommand); + return true; + } + return false; + } + }; + return new JUnit3Wrapper.Command.StepCommand(stepKind, stepLevel, stepUntilFilter); } protected final JUnit3Wrapper.Command checkLocal(String localName) { @@ -1512,23 +1538,14 @@ public abstract class DebugTestBase { class StepCommand implements Command { - private final byte stepDepth; - private final byte stepSize; + private final StepKind stepDepth; + private final StepLevel stepSize; private final StepFilter stepFilter; - /** - * A {@link Function} taking a {@link DebuggeeState} as input and returns {@code true} to - * stop stepping, {@code false} to continue. - */ - private final Function<JUnit3Wrapper.DebuggeeState, Boolean> stepUntil; - - public StepCommand(byte stepDepth, - byte stepSize, StepFilter stepFilter, - Function<DebuggeeState, Boolean> stepUntil) { + public StepCommand(StepKind stepDepth, StepLevel stepSize, StepFilter stepFilter) { this.stepDepth = stepDepth; this.stepSize = stepSize; this.stepFilter = stepFilter; - this.stepUntil = stepUntil; } @Override @@ -1537,14 +1554,13 @@ public abstract class DebugTestBase { int stepRequestID; { EventBuilder eventBuilder = Event.builder(EventKind.SINGLE_STEP, SuspendPolicy.ALL); - eventBuilder.setStep(threadId, stepSize, stepDepth); + eventBuilder.setStep(threadId, stepSize.jdwpValue, stepDepth.jdwpValue); stepFilter.getExcludedClasses().stream().forEach(s -> eventBuilder.setClassExclude(s)); ReplyPacket replyPacket = testBase.getMirror().setEvent(eventBuilder.build()); stepRequestID = replyPacket.getNextValueAsInt(); testBase.assertAllDataRead(replyPacket); } - testBase.events - .put(stepRequestID, new StepEventHandler(this, stepRequestID, stepFilter, stepUntil)); + testBase.events.put(stepRequestID, new StepEventHandler(this, stepRequestID, stepFilter)); // Resume all threads. testBase.resume(); @@ -1552,8 +1568,8 @@ public abstract class DebugTestBase { @Override public String toString() { - return String.format("step %s/%s", JDWPConstants.StepDepth.getName(stepDepth), - JDWPConstants.StepSize.getName(stepSize)); + return String.format("step %s/%s", JDWPConstants.StepDepth.getName(stepDepth.jdwpValue), + JDWPConstants.StepSize.getName(stepSize.jdwpValue)); } } @@ -1607,17 +1623,14 @@ public abstract class DebugTestBase { private final JUnit3Wrapper.Command.StepCommand stepCommand; private final int stepRequestID; private final StepFilter stepFilter; - private final Function<DebuggeeState, Boolean> stepUntil; private StepEventHandler( JUnit3Wrapper.Command.StepCommand stepCommand, int stepRequestID, - StepFilter stepFilter, - Function<DebuggeeState, Boolean> stepUntil) { + StepFilter stepFilter) { this.stepCommand = stepCommand; this.stepRequestID = stepRequestID; this.stepFilter = stepFilter; - this.stepUntil = stepUntil; } @Override @@ -1626,18 +1639,11 @@ public abstract class DebugTestBase { testBase.getMirror().clearEvent(EventKind.SINGLE_STEP, stepRequestID); testBase.events.remove(Integer.valueOf(stepRequestID)); - // Do we need to step again ? - boolean repeatStep = false; - if (stepFilter - .skipLocation(testBase.getMirror(), testBase.getDebuggeeState().getLocation())) { - repeatStep = true; - } else if (stepUntil.apply(testBase.getDebuggeeState()) == Boolean.FALSE) { - repeatStep = true; - } - if (repeatStep) { - // In order to repeat the step now, we need to add it at the beginning of the queue. - testBase.enqueueCommandFirst(stepCommand); - } + // Let the filtering happen. + // Note: we don't need to know whether the location was skipped or not because we are + // going to process the next command(s) in the queue anyway. + stepFilter.skipLocation(testBase.getDebuggeeState(), testBase, stepCommand); + super.handle(testBase); } } @@ -1659,7 +1665,8 @@ public abstract class DebugTestBase { /** * Indicates whether the given location must be skipped. */ - boolean skipLocation(VmMirror mirror, Location location); + boolean skipLocation(JUnit3Wrapper.DebuggeeState debuggeeState, JUnit3Wrapper wrapper, + JUnit3Wrapper.Command.StepCommand stepCommand); /** * A {@link StepFilter} that does not filter anything. @@ -1672,7 +1679,8 @@ public abstract class DebugTestBase { } @Override - public boolean skipLocation(VmMirror mirror, Location location) { + public boolean skipLocation(JUnit3Wrapper.DebuggeeState debuggeeState, JUnit3Wrapper wrapper, + JUnit3Wrapper.Command.StepCommand stepCommand) { return false; } } @@ -1687,7 +1695,7 @@ public abstract class DebugTestBase { @Override public List<String> getExcludedClasses() { - return Arrays.asList( + return ImmutableList.of( "com.sun.*", "java.*", "javax.*", @@ -1707,8 +1715,10 @@ public abstract class DebugTestBase { } @Override - public boolean skipLocation(VmMirror mirror, Location location) { - // TODO(b/67225390) we also need to skip class loaders to act like IntelliJ. + public boolean skipLocation(JUnit3Wrapper.DebuggeeState debuggeeState, JUnit3Wrapper wrapper, + JUnit3Wrapper.Command.StepCommand stepCommand) { + VmMirror mirror = debuggeeState.getMirror(); + Location location = debuggeeState.getLocation(); // Skip synthetic methods. if (isLambdaMethod(mirror, location)) { // Lambda methods are synthetic but we do want to stop there. @@ -1722,14 +1732,37 @@ public abstract class DebugTestBase { if (DEBUG_TESTS) { System.out.println("Skipping lambda class wrapper method"); } + wrapper.enqueueCommandFirst(stepCommand); return true; } if (isSyntheticMethod(mirror, location)) { if (DEBUG_TESTS) { System.out.println("Skipping synthetic method"); } + wrapper.enqueueCommandFirst(stepCommand); return true; } + if (isClassLoader(mirror, location)) { + if (DEBUG_TESTS) { + System.out.println("Skipping class loader"); + } + wrapper.enqueueCommandFirst( + new JUnit3Wrapper.Command.StepCommand(StepKind.OUT, StepLevel.LINE, this)); + return true; + } + return false; + } + + private static boolean isClassLoader(VmMirror mirror, Location location) { + final long classLoaderClassID = mirror.getClassID("Ljava/lang/ClassLoader;"); + assert classLoaderClassID != -1; + long classID = location.classID; + while (classID != 0) { + if (classID == classLoaderClassID) { + return true; + } + classID = mirror.getSuperclassId(classID); + } return false; } @@ -1751,7 +1784,7 @@ public abstract class DebugTestBase { return classSig.contains("$$Lambda$"); } - private boolean isLambdaMethod(VmMirror mirror, Location location) { + private static boolean isLambdaMethod(VmMirror mirror, Location location) { String methodName = mirror.getMethodName(location.classID, location.methodID); return methodName.startsWith("lambda$"); } diff --git a/src/test/java/com/android/tools/r8/debug/InterfaceMethodTest.java b/src/test/java/com/android/tools/r8/debug/InterfaceMethodTest.java index 46ad8156c..713d04290 100644 --- a/src/test/java/com/android/tools/r8/debug/InterfaceMethodTest.java +++ b/src/test/java/com/android/tools/r8/debug/InterfaceMethodTest.java @@ -22,10 +22,6 @@ public class InterfaceMethodTest extends DebugTestBase { @Test public void testDefaultMethod() throws Throwable { - // TODO(b/67225390) Dalvik steps into class loader first. - Assume.assumeTrue("Dalvik suspends in class loader", - ToolHelper.getDexVm().getVersion().isNewerThan(Version.V4_4_4)); - String debuggeeClass = "DebugInterfaceMethod"; String parameterName = "msg"; String localVariableName = "name"; @@ -38,16 +34,16 @@ public class InterfaceMethodTest extends DebugTestBase { if (!supportsDefaultMethod()) { // We desugared default method. This means we're going to step through an extra (forward) // method first. - commands.add(stepInto()); + commands.add(stepInto(INTELLIJ_FILTER)); } - commands.add(stepInto()); + commands.add(stepInto(INTELLIJ_FILTER)); commands.add(checkLine(SOURCE_FILE, 9)); // TODO(shertz) we should see the local variable this even when desugaring. if (supportsDefaultMethod()) { commands.add(checkLocal("this")); } commands.add(checkLocal(parameterName)); - commands.add(stepOver()); + commands.add(stepOver(INTELLIJ_FILTER)); commands.add(checkLocal(parameterName)); commands.add(checkLocal(localVariableName)); // TODO(shertz) check current method name ? diff --git a/src/test/java/com/android/tools/r8/debug/MinificationTest.java b/src/test/java/com/android/tools/r8/debug/MinificationTest.java index 6a297cde7..db4117338 100644 --- a/src/test/java/com/android/tools/r8/debug/MinificationTest.java +++ b/src/test/java/com/android/tools/r8/debug/MinificationTest.java @@ -3,14 +3,9 @@ // BSD-style license that can be found in the LICENSE file. package com.android.tools.r8.debug; -import com.android.tools.r8.ToolHelper; -import com.android.tools.r8.ToolHelper.DexVm; -import com.android.tools.r8.debug.DebugTestBase.JUnit3Wrapper.Command; import com.google.common.collect.ImmutableList; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.List; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; @@ -68,28 +63,18 @@ public class MinificationTest extends DebugTestBase { final String innerClassName = minifiedNames ? "a" : "Minified$Inner"; final String innerMethodName = minifiedNames ? "a" : "innerTest"; final String innerSignature = "()I"; - List<Command> commands = - new ArrayList<>( - Arrays.asList( - breakpoint(className, methodName, signature), - run(), - checkMethod(className, methodName, signature), - checkLine(SOURCE_FILE, 14), - stepOver(), - checkMethod(className, methodName, signature), - checkLine(SOURCE_FILE, 15), - stepInto())); - // Dalvik first enters ClassLoader, step over it. - // See also b/67225390. - if (ToolHelper.getDexVm() == DexVm.ART_4_4_4_HOST) { - commands.add(stepOver()); - } - commands.addAll( - Arrays.asList( - checkMethod(innerClassName, innerMethodName, innerSignature), - checkLine(SOURCE_FILE, 8), - run())); - runDebugTestR8(className, commands); + runDebugTestR8(className, + breakpoint(className, methodName, signature), + run(), + checkMethod(className, methodName, signature), + checkLine(SOURCE_FILE, 14), + stepOver(INTELLIJ_FILTER), + checkMethod(className, methodName, signature), + checkLine(SOURCE_FILE, 15), + stepInto(INTELLIJ_FILTER), + checkMethod(innerClassName, innerMethodName, innerSignature), + checkLine(SOURCE_FILE, 8), + run()); } @Test diff --git a/src/test/java/com/android/tools/r8/shaking/forceproguardcompatibility/ForceProguardCompatibilityTest.java b/src/test/java/com/android/tools/r8/shaking/forceproguardcompatibility/ForceProguardCompatibilityTest.java index 4d59f630f..1519f6c8a 100644 --- a/src/test/java/com/android/tools/r8/shaking/forceproguardcompatibility/ForceProguardCompatibilityTest.java +++ b/src/test/java/com/android/tools/r8/shaking/forceproguardcompatibility/ForceProguardCompatibilityTest.java @@ -8,7 +8,10 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import com.android.tools.r8.R8Command; import com.android.tools.r8.TestBase; +import com.android.tools.r8.ToolHelper; +import com.android.tools.r8.compatproguard.CompatProguardCommandBuilder; import com.android.tools.r8.naming.MemberNaming.MethodSignature; import com.android.tools.r8.utils.DexInspector; import com.android.tools.r8.utils.DexInspector.ClassSubject; @@ -49,4 +52,45 @@ public class ForceProguardCompatibilityTest extends TestBase { test(TestMainArrayType.class, TestMainArrayType.MentionedClass.class, true, true); test(TestMainArrayType.class, TestMainArrayType.MentionedClass.class, true, false); } + + private void runAnnotationsTest(boolean forceProguardCompatibility, boolean keepAnnotations) throws Exception { + R8Command.Builder builder = + new CompatProguardCommandBuilder(forceProguardCompatibility); + // Add application classes including the annotation class. + Class mainClass = TestMain.class; + Class mentionedClassWithAnnotations = TestMain.MentionedClassWithAnnotation.class; + Class annotationClass = TestAnnotation.class; + builder.addProgramFiles(ToolHelper.getClassFileForTestClass(mainClass)); + builder.addProgramFiles(ToolHelper.getClassFileForTestClass(TestMain.MentionedClass.class)); + builder.addProgramFiles(ToolHelper.getClassFileForTestClass(mentionedClassWithAnnotations)); + builder.addProgramFiles(ToolHelper.getClassFileForTestClass(annotationClass)); + // Keep main class and the annotation class. + builder.addProguardConfiguration( + ImmutableList.of(keepMainProguardConfiguration(mainClass, true, false))); + builder.addProguardConfiguration( + ImmutableList.of("-keep class " + annotationClass.getCanonicalName() + " { }")); + if (keepAnnotations) { + builder.addProguardConfiguration(ImmutableList.of("-keepattributes *Annotation*")); + } + + DexInspector inspector = new DexInspector(ToolHelper.runR8(builder.build())); + assertTrue(inspector.clazz(mainClass.getCanonicalName()).isPresent()); + ClassSubject clazz = inspector.clazz(getJavacGeneratedClassName(mentionedClassWithAnnotations)); + assertTrue(clazz.isPresent()); + + assertEquals(!keepAnnotations && forceProguardCompatibility, + clazz.annotation("dalvik.annotation.EnclosingClass").isPresent()); + assertEquals(!keepAnnotations && forceProguardCompatibility, + clazz.annotation("dalvik.annotation.InnerClass").isPresent()); + assertEquals(forceProguardCompatibility || keepAnnotations, + clazz.annotation(annotationClass.getCanonicalName()).isPresent()); + } + + @Test + public void testAnnotations() throws Exception { + runAnnotationsTest(true, true); + runAnnotationsTest(true, false); + runAnnotationsTest(false, true); + runAnnotationsTest(false, false); + } } diff --git a/src/test/java/com/android/tools/r8/shaking/forceproguardcompatibility/TestMain.java b/src/test/java/com/android/tools/r8/shaking/forceproguardcompatibility/TestMain.java index 94a9d0a62..1a484b596 100644 --- a/src/test/java/com/android/tools/r8/shaking/forceproguardcompatibility/TestMain.java +++ b/src/test/java/com/android/tools/r8/shaking/forceproguardcompatibility/TestMain.java @@ -11,7 +11,14 @@ public class TestMain { } } + @TestAnnotation(0) + public static class MentionedClassWithAnnotation { + public MentionedClassWithAnnotation() { + } + } + public static void main(String[] args) { System.out.println(MentionedClass.class.getCanonicalName()); + System.out.println(MentionedClassWithAnnotation.class.getCanonicalName()); } } |