Merge "Only remove visibility bridges"
diff --git a/build.gradle b/build.gradle
index 0663b8a..45eade1 100644
--- a/build.gradle
+++ b/build.gradle
@@ -151,6 +151,7 @@
"gmscore/v8.tar.gz",
"gmscore/gmscore_v9.tar.gz",
"gmscore/gmscore_v10.tar.gz",
+ "photos/2017-06-06.tar.gz",
"youtube/youtube.android_11.47.tar.gz",
"youtube/youtube.android_12.10.tar.gz",
"youtube/youtube.android_12.17.tar.gz",
diff --git a/src/main/java/com/android/tools/r8/Resource.java b/src/main/java/com/android/tools/r8/Resource.java
index c7760bb..eaabc99 100644
--- a/src/main/java/com/android/tools/r8/Resource.java
+++ b/src/main/java/com/android/tools/r8/Resource.java
@@ -1,30 +1,97 @@
// Copyright (c) 2017, 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;
import com.google.common.io.Closer;
+import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.file.Path;
import java.util.Set;
/** Represents application resources. */
-public interface Resource {
-
- /** Application resource kind. */
- enum Kind {
- PROGRAM, CLASSPATH, LIBRARY
+public abstract class Resource {
+ /** Kind of the resource describing the resource content. */
+ public enum Kind {
+ DEX, CLASSFILE
}
- /** Get the kind of the resource. */
- Kind getKind();
+ private Resource(Kind kind) {
+ this.kind = kind;
+ }
+
+ /** Kind of the resource. */
+ public final Kind kind;
+
+ /** Create an application resource for a given file. */
+ public static Resource fromFile(Kind kind, Path file) {
+ return new FileResource(kind, file);
+ }
+
+ /** Create an application resource for a given content. */
+ public static Resource fromBytes(Kind kind, byte[] bytes) {
+ return fromBytes(kind, bytes, null);
+ }
+
+ /** Create an application resource for a given content and type descriptor. */
+ public static Resource fromBytes(Kind kind, byte[] bytes, Set<String> typeDescriptors) {
+ return new ByteResource(kind, bytes, typeDescriptors);
+ }
/**
* Returns the set of class descriptors for classes represented
* by the resource if known, or `null' otherwise.
*/
- Set<String> getClassDescriptors();
+ public abstract Set<String> getClassDescriptors();
/** Get the resource as a stream. */
- InputStream getStream(Closer closer) throws IOException;
+ public abstract InputStream getStream(Closer closer) throws IOException;
+
+ /** File based application resource. */
+ private static class FileResource extends Resource {
+ final Path file;
+
+ FileResource(Kind kind, Path file) {
+ super(kind);
+ assert file != null;
+ this.file = file;
+ }
+
+ @Override
+ public Set<String> getClassDescriptors() {
+ return null;
+ }
+
+ @Override
+ public InputStream getStream(Closer closer) throws IOException {
+ return closer.register(new FileInputStream(file.toFile()));
+ }
+ }
+
+ /** Byte content based application resource. */
+ private static class ByteResource extends Resource {
+ final Set<String> classDescriptors;
+ final byte[] bytes;
+
+ ByteResource(Kind kind, byte[] bytes, Set<String> classDescriptors) {
+ super(kind);
+ assert bytes != null;
+ this.classDescriptors = classDescriptors;
+ this.bytes = bytes;
+ }
+
+ @Override
+ public Set<String> getClassDescriptors() {
+ return classDescriptors;
+ }
+
+ @Override
+ public InputStream getStream(Closer closer) throws IOException {
+ // Note: closing a byte-array input stream is a no-op.
+ return new ByteArrayInputStream(bytes);
+ }
+ }
}
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationReader.java b/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
index 35f9bfe..af6bebe 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
@@ -13,6 +13,7 @@
import com.android.tools.r8.Resource;
import com.android.tools.r8.ResourceProvider;
import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.graph.ClassKind;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
@@ -22,7 +23,6 @@
import com.android.tools.r8.naming.ProguardMapReader;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.InternalOptions;
-import com.android.tools.r8.utils.InternalResource;
import com.android.tools.r8.utils.LazyClassCollection;
import com.android.tools.r8.utils.MainDexList;
import com.android.tools.r8.utils.ThreadUtils;
@@ -32,6 +32,7 @@
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -90,67 +91,68 @@
JarApplicationReader application = new JarApplicationReader(options);
JarClassFileReader reader = new JarClassFileReader(
application, builder::addClassIgnoringLibraryDuplicates);
- for (InternalResource input : inputApp.getClassProgramResources()) {
- reader.read(DEFAULT_DEX_FILENAME, Resource.Kind.PROGRAM, input.getStream(closer));
+ for (Resource input : inputApp.getClassProgramResources()) {
+ reader.read(DEFAULT_DEX_FILENAME, ClassKind.PROGRAM, input.getStream(closer));
}
- for (InternalResource input : inputApp.getClassClasspathResources()) {
- if (options.lazyClasspathLoading && input.getSingleClassDescriptorOrNull() != null) {
- addLazyLoader(application, builder, input);
+ for (Resource input : inputApp.getClassClasspathResources()) {
+ if (options.lazyClasspathLoading && getResourceClassDescriptorOrNull(input) != null) {
+ addLazyLoader(application, ClassKind.CLASSPATH, builder, input);
} else {
- reader.read(DEFAULT_DEX_FILENAME, Resource.Kind.CLASSPATH, input.getStream(closer));
+ reader.read(DEFAULT_DEX_FILENAME, ClassKind.CLASSPATH, input.getStream(closer));
}
}
- for (InternalResource input : inputApp.getClassLibraryResources()) {
- if (options.lazyLibraryLoading && input.getSingleClassDescriptorOrNull() != null) {
- addLazyLoader(application, builder, input);
+ for (Resource input : inputApp.getClassLibraryResources()) {
+ if (options.lazyLibraryLoading && getResourceClassDescriptorOrNull(input) != null) {
+ addLazyLoader(application, ClassKind.LIBRARY, builder, input);
} else {
- reader.read(DEFAULT_DEX_FILENAME, Resource.Kind.LIBRARY, input.getStream(closer));
+ reader.read(DEFAULT_DEX_FILENAME, ClassKind.LIBRARY, input.getStream(closer));
}
}
}
private void initializeLazyClassCollection(DexApplication.Builder builder) {
- List<ResourceProvider> providers = inputApp.getLazyResourceProviders();
- if (!providers.isEmpty()) {
- builder.setLazyClassCollection(
- new LazyClassCollection(new JarApplicationReader(options), providers));
+ List<ResourceProvider> classpathProviders = inputApp.getClasspathResourceProviders();
+ List<ResourceProvider> libraryProviders = inputApp.getLibraryResourceProviders();
+ if (!classpathProviders.isEmpty() || !libraryProviders.isEmpty()) {
+ builder.setLazyClassCollection(new LazyClassCollection(
+ new JarApplicationReader(options), classpathProviders, libraryProviders));
}
}
private void addLazyLoader(JarApplicationReader application,
- DexApplication.Builder builder, InternalResource resource) {
+ ClassKind classKind, DexApplication.Builder builder, Resource resource) {
// Generate expected DEX type.
- String classDescriptor = resource.getSingleClassDescriptorOrNull();
+ String classDescriptor = getResourceClassDescriptorOrNull(resource);
assert classDescriptor != null;
DexType type = options.itemFactory.createType(classDescriptor);
- LazyClassFileLoader newLoader = new LazyClassFileLoader(type, resource, application);
+ LazyClassFileLoader newLoader = new LazyClassFileLoader(type, resource, classKind, application);
builder.addClassPromise(newLoader, true);
}
private void readDexSources(DexApplication.Builder builder, ExecutorService executorService,
List<Future<?>> futures, Closer closer)
throws IOException, ExecutionException {
- List<InternalResource> dexProgramSources = inputApp.getDexProgramResources();
- List<InternalResource> dexClasspathSources = inputApp.getDexClasspathResources();
- List<InternalResource> dexLibrarySources = inputApp.getDexLibraryResources();
+ List<Resource> dexProgramSources = inputApp.getDexProgramResources();
+ List<Resource> dexClasspathSources = inputApp.getDexClasspathResources();
+ List<Resource> dexLibrarySources = inputApp.getDexLibraryResources();
int numberOfFiles = dexProgramSources.size()
+ dexLibrarySources.size() + dexClasspathSources.size();
if (numberOfFiles > 0) {
List<DexFileReader> fileReaders = new ArrayList<>(numberOfFiles);
int computedMinApiLevel = options.minApiLevel;
- for (InternalResource input : dexProgramSources) {
+ for (Resource input : dexProgramSources) {
DexFile file = new DexFile(input.getStream(closer));
computedMinApiLevel = verifyOrComputeMinApiLevel(computedMinApiLevel, file);
- fileReaders.add(new DexFileReader(file, Resource.Kind.PROGRAM, itemFactory));
+ fileReaders.add(new DexFileReader(file, ClassKind.PROGRAM, itemFactory));
}
- for (InternalResource input : dexClasspathSources) {
+ for (Resource input : dexClasspathSources) {
DexFile file = new DexFile(input.getStream(closer));
- fileReaders.add(new DexFileReader(file, Resource.Kind.CLASSPATH, itemFactory));
+ fileReaders.add(new DexFileReader(file, ClassKind.CLASSPATH, itemFactory));
}
- for (InternalResource input : dexLibrarySources) {
+ for (Resource input : dexLibrarySources) {
DexFile file = new DexFile(input.getStream(closer));
computedMinApiLevel = verifyOrComputeMinApiLevel(computedMinApiLevel, file);
- fileReaders.add(new DexFileReader(file, Resource.Kind.LIBRARY, itemFactory));
+ fileReaders.add(new DexFileReader(file, ClassKind.LIBRARY, itemFactory));
}
options.minApiLevel = computedMinApiLevel;
for (DexFileReader reader : fileReaders) {
@@ -230,4 +232,9 @@
}
}
+ private static String getResourceClassDescriptorOrNull(Resource resource) {
+ Set<String> descriptors = resource.getClassDescriptors();
+ return (descriptors == null) || (descriptors.size() != 1)
+ ? null : descriptors.iterator().next();
+ }
}
diff --git a/src/main/java/com/android/tools/r8/dex/DexFileReader.java b/src/main/java/com/android/tools/r8/dex/DexFileReader.java
index 02b0ce8..6aacd55 100644
--- a/src/main/java/com/android/tools/r8/dex/DexFileReader.java
+++ b/src/main/java/com/android/tools/r8/dex/DexFileReader.java
@@ -11,6 +11,7 @@
import com.android.tools.r8.Resource;
import com.android.tools.r8.code.Instruction;
import com.android.tools.r8.code.InstructionFactory;
+import com.android.tools.r8.graph.ClassKind;
import com.android.tools.r8.graph.Descriptor;
import com.android.tools.r8.graph.DexAccessFlags;
import com.android.tools.r8.graph.DexAnnotation;
@@ -68,12 +69,12 @@
private DexFile file;
private final Segment[] segments;
private int[] stringIDs;
- private final Resource.Kind fileKind;
+ private final ClassKind classKind;
public static Segment[] parseMapFrom(Path file) throws IOException {
DexFileReader reader =
new DexFileReader(
- new DexFile(file.toString()), Resource.Kind.PROGRAM, new DexItemFactory());
+ new DexFile(file.toString()), ClassKind.PROGRAM, new DexItemFactory());
return reader.parseMap();
}
@@ -98,14 +99,13 @@
// Factory to canonicalize certain dexitems.
private final DexItemFactory dexItemFactory;
- public DexFileReader(
- DexFile file, Resource.Kind fileKind, DexItemFactory dexItemFactory) {
+ public DexFileReader(DexFile file, ClassKind classKind, DexItemFactory dexItemFactory) {
this.file = file;
this.dexItemFactory = dexItemFactory;
file.setByteOrder();
segments = parseMap();
parseStringIDs();
- this.fileKind = fileKind;
+ this.classKind = classKind;
}
public OffsetToObjectMapping getIndexedItemsMap() {
@@ -113,7 +113,7 @@
}
void addCodeItemsTo() {
- if (fileKind == Resource.Kind.LIBRARY) {
+ if (classKind == ClassKind.LIBRARY) {
// Ignore contents of library files.
return;
}
@@ -644,17 +644,17 @@
directMethodsSize,
annotationsDirectory.methods,
annotationsDirectory.parameters,
- fileKind != Resource.Kind.PROGRAM);
+ classKind != ClassKind.PROGRAM);
virtualMethods =
readMethods(
virtualMethodsSize,
annotationsDirectory.methods,
annotationsDirectory.parameters,
- fileKind != Resource.Kind.PROGRAM);
+ classKind != ClassKind.PROGRAM);
}
- clazz = DexClass.factoryForResourceKind(fileKind).create(
+ clazz = classKind.create(
type,
- DexClass.Origin.Dex,
+ Resource.Kind.DEX,
flags,
superclass,
typeListAt(interfacesOffsets[i]),
diff --git a/src/main/java/com/android/tools/r8/dex/VirtualFile.java b/src/main/java/com/android/tools/r8/dex/VirtualFile.java
index ad5420d..07fce3a 100644
--- a/src/main/java/com/android/tools/r8/dex/VirtualFile.java
+++ b/src/main/java/com/android/tools/r8/dex/VirtualFile.java
@@ -63,7 +63,6 @@
private static final int MAX_PREFILL_ENTRIES = MAX_ENTRIES - 5000;
private final int id;
- private final Set<String> classDescriptors = new HashSet<>();
private final VirtualFileIndexedItemCollection indexedItems;
private final IndexedItemTransaction transaction;
@@ -74,6 +73,11 @@
}
public Set<String> getClassDescriptors() {
+ Set<String> classDescriptors = new HashSet<>();
+ for (DexProgramClass clazz : indexedItems.classes) {
+ boolean added = classDescriptors.add(clazz.type.descriptor.toString());
+ assert added;
+ }
return classDescriptors;
}
@@ -289,7 +293,6 @@
private void addClass(DexProgramClass clazz) {
transaction.addClassAndDependencies(clazz);
- classDescriptors.add(clazz.type.descriptor.toString());
}
private static boolean isFull(int numberOfMethods, int numberOfFields, int maximum) {
diff --git a/src/main/java/com/android/tools/r8/graph/ClassKind.java b/src/main/java/com/android/tools/r8/graph/ClassKind.java
new file mode 100644
index 0000000..6f53a40
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/graph/ClassKind.java
@@ -0,0 +1,33 @@
+package com.android.tools.r8.graph;
+
+import com.android.tools.r8.Resource;
+
+/** Kind of the application class. Can be program, classpath or library. */
+public enum ClassKind {
+ PROGRAM(DexProgramClass::new),
+ CLASSPATH(DexClasspathClass::new),
+ LIBRARY(DexLibraryClass::new);
+
+ private interface Factory {
+ DexClass create(DexType type, Resource.Kind origin, DexAccessFlags accessFlags,
+ DexType superType,
+ DexTypeList interfaces, DexString sourceFile, DexAnnotationSet annotations,
+ DexEncodedField[] staticFields, DexEncodedField[] instanceFields,
+ DexEncodedMethod[] directMethods, DexEncodedMethod[] virtualMethods);
+ }
+
+ private final Factory factory;
+
+ ClassKind(Factory factory) {
+ this.factory = factory;
+ }
+
+ public DexClass create(
+ DexType type, Resource.Kind origin, DexAccessFlags accessFlags, DexType superType,
+ DexTypeList interfaces, DexString sourceFile, DexAnnotationSet annotations,
+ DexEncodedField[] staticFields, DexEncodedField[] instanceFields,
+ DexEncodedMethod[] directMethods, DexEncodedMethod[] virtualMethods) {
+ return factory.create(type, origin, accessFlags, superType, interfaces, sourceFile,
+ annotations, staticFields, instanceFields, directMethods, virtualMethods);
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/graph/DexApplication.java b/src/main/java/com/android/tools/r8/graph/DexApplication.java
index bcc845e..acbc205 100644
--- a/src/main/java/com/android/tools/r8/graph/DexApplication.java
+++ b/src/main/java/com/android/tools/r8/graph/DexApplication.java
@@ -6,6 +6,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.graph;
+import com.android.tools.r8.Resource;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.ir.desugar.LambdaRewriter;
import com.android.tools.r8.logging.Log;
@@ -387,8 +388,8 @@
private static boolean allowProgramClassConflict(DexClassPromise a, DexClassPromise b) {
// Currently only allow collapsing synthetic lambda classes.
- return a.getOrigin() == DexClass.Origin.Dex
- && b.getOrigin() == DexClass.Origin.Dex
+ return a.getOrigin() == Resource.Kind.DEX
+ && b.getOrigin() == Resource.Kind.DEX
&& a.get().accessFlags.isSynthetic()
&& b.get().accessFlags.isSynthetic()
&& LambdaRewriter.hasLambdaClassPrefix(a.getType())
diff --git a/src/main/java/com/android/tools/r8/graph/DexClass.java b/src/main/java/com/android/tools/r8/graph/DexClass.java
index 90828b7..f684309 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -7,27 +7,14 @@
import com.android.tools.r8.dex.MixedSectionCollection;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.utils.InternalResource;
import com.google.common.base.MoreObjects;
public abstract class DexClass extends DexItem implements DexClassPromise {
- public interface Factory {
-
- DexClass create(DexType type, Origin origin, DexAccessFlags accessFlags, DexType superType,
- DexTypeList interfaces, DexString sourceFile, DexAnnotationSet annotations,
- DexEncodedField[] staticFields, DexEncodedField[] instanceFields,
- DexEncodedMethod[] directMethods, DexEncodedMethod[] virtualMethods);
- }
-
- public enum Origin {
- Dex, ClassFile, Synthetic
- }
-
private static final DexEncodedMethod[] NO_METHODS = {};
private static final DexEncodedField[] NO_FIELDS = {};
- public final Origin origin;
+ public final Resource.Kind origin;
public final DexType type;
public final DexAccessFlags accessFlags;
public DexType superType;
@@ -43,7 +30,7 @@
DexString sourceFile, DexTypeList interfaces, DexAccessFlags accessFlags, DexType superType,
DexType type, DexEncodedField[] staticFields, DexEncodedField[] instanceFields,
DexEncodedMethod[] directMethods, DexEncodedMethod[] virtualMethods,
- DexAnnotationSet annotations, Origin origin) {
+ DexAnnotationSet annotations, Resource.Kind origin) {
this.origin = origin;
this.sourceFile = sourceFile;
this.interfaces = interfaces;
@@ -168,7 +155,7 @@
}
@Override
- public Origin getOrigin() {
+ public Resource.Kind getOrigin() {
return this.origin;
}
@@ -182,19 +169,6 @@
return type;
}
- /** Get a class factory for a particular resource kind */
- public static Factory factoryForResourceKind(Resource.Kind kind) {
- switch (kind) {
- case PROGRAM:
- return DexProgramClass::new;
- case CLASSPATH:
- return DexClasspathClass::new;
- case LIBRARY:
- return DexLibraryClass::new;
- }
- throw new Unreachable();
- }
-
public boolean hasClassInitializer() {
return getClassInitializer() != null;
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexClassPromise.java b/src/main/java/com/android/tools/r8/graph/DexClassPromise.java
index 243eadf..c0bdf20 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClassPromise.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClassPromise.java
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.graph;
+import com.android.tools.r8.Resource;
+
/**
* Provides a way for delayed DexClass discovery.
*
@@ -15,7 +17,7 @@
public interface DexClassPromise {
DexType getType();
- DexClass.Origin getOrigin();
+ Resource.Kind getOrigin();
boolean isProgramClass();
diff --git a/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java b/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java
index 0ec8cf7..dd5efbb 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java
@@ -3,13 +3,14 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.graph;
+import com.android.tools.r8.Resource;
import com.android.tools.r8.dex.IndexedItemCollection;
import com.android.tools.r8.dex.MixedSectionCollection;
import com.android.tools.r8.errors.Unreachable;
public class DexClasspathClass extends DexClass {
- public DexClasspathClass(DexType type, Origin origin, DexAccessFlags accessFlags,
+ public DexClasspathClass(DexType type, Resource.Kind origin, DexAccessFlags accessFlags,
DexType superType, DexTypeList interfaces, DexString sourceFile, DexAnnotationSet annotations,
DexEncodedField[] staticFields, DexEncodedField[] instanceFields,
DexEncodedMethod[] directMethods, DexEncodedMethod[] virtualMethods) {
diff --git a/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java b/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java
index c4ed702..c1b9205 100644
--- a/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java
@@ -3,14 +3,15 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.graph;
+import com.android.tools.r8.Resource;
import com.android.tools.r8.dex.IndexedItemCollection;
import com.android.tools.r8.dex.MixedSectionCollection;
import com.android.tools.r8.errors.Unreachable;
public class DexLibraryClass extends DexClass {
- public DexLibraryClass(DexType type, Origin origin, DexAccessFlags accessFlags, DexType superType,
- DexTypeList interfaces, DexString sourceFile, DexAnnotationSet annotations,
+ public DexLibraryClass(DexType type, Resource.Kind origin, DexAccessFlags accessFlags,
+ DexType superType, DexTypeList interfaces, DexString sourceFile, DexAnnotationSet annotations,
DexEncodedField[] staticFields, DexEncodedField[] instanceFields,
DexEncodedMethod[] directMethods, DexEncodedMethod[] virtualMethods) {
super(sourceFile, interfaces, accessFlags, superType, type,
diff --git a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
index 6713083..094a039 100644
--- a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.graph;
+import com.android.tools.r8.Resource;
import com.android.tools.r8.dex.IndexedItemCollection;
import com.android.tools.r8.dex.MixedSectionCollection;
import java.util.Arrays;
@@ -12,7 +13,7 @@
private DexEncodedArray staticValues;
public DexProgramClass(DexType type,
- Origin origin,
+ Resource.Kind origin,
DexAccessFlags accessFlags,
DexType superType,
DexTypeList interfaces,
diff --git a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
index 3cc3ac4..c738e17 100644
--- a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
+++ b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
@@ -58,10 +58,10 @@
this.classConsumer = classConsumer;
}
- public void read(String file, Resource.Kind kind, InputStream input) throws IOException {
+ public void read(String file, ClassKind classKind, InputStream input) throws IOException {
ClassReader reader = new ClassReader(input);
reader.accept(new CreateDexClassVisitor(
- file, kind, reader.b, application, classConsumer), SKIP_FRAMES);
+ file, classKind, reader.b, application, classConsumer), SKIP_FRAMES);
}
private static DexAccessFlags createAccessFlags(int access) {
@@ -70,11 +70,11 @@
}
private static AnnotationVisitor createAnnotationVisitor(String desc, boolean visible,
- AnnotationVisitor annotationVisitor, List<DexAnnotation> annotations,
+ List<DexAnnotation> annotations,
JarApplicationReader application) {
assert annotations != null;
int visiblity = visible ? DexAnnotation.VISIBILITY_RUNTIME : DexAnnotation.VISIBILITY_BUILD;
- return new CreateAnnotationVisitor(annotationVisitor, application, (names, values) ->
+ return new CreateAnnotationVisitor(application, (names, values) ->
annotations.add(new DexAnnotation(visiblity,
createEncodedAnnotation(desc, names, values, application))));
}
@@ -92,7 +92,7 @@
private static class CreateDexClassVisitor extends ClassVisitor {
private final String file;
- private final Resource.Kind kind;
+ private final ClassKind classKind;
private final JarApplicationReader application;
private final Consumer<DexClass> classConsumer;
private final ReparseContext context = new ReparseContext();
@@ -115,13 +115,13 @@
public CreateDexClassVisitor(
String file,
- Resource.Kind kind,
+ ClassKind classKind,
byte[] classCache,
JarApplicationReader application,
Consumer<DexClass> classConsumer) {
super(ASM5);
this.file = file;
- this.kind = kind;
+ this.classKind = classKind;
this.classConsumer = classConsumer;
this.context.classCache = classCache;
this.application = application;
@@ -210,7 +210,7 @@
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
- return createAnnotationVisitor(desc, visible, null, getAnnotations(), application);
+ return createAnnotationVisitor(desc, visible, getAnnotations(), application);
}
@Override
@@ -247,9 +247,9 @@
addAnnotation(DexAnnotation.createAnnotationDefaultAnnotation(
type, defaultAnnotations, application.getFactory()));
}
- DexClass clazz = DexClass.factoryForResourceKind(kind).create(
+ DexClass clazz = classKind.create(
type,
- DexClass.Origin.ClassFile,
+ Resource.Kind.CLASSFILE,
accessFlags,
superType,
interfaces,
@@ -259,7 +259,7 @@
instanceFields.toArray(new DexEncodedField[instanceFields.size()]),
directMethods.toArray(new DexEncodedMethod[directMethods.size()]),
virtualMethods.toArray(new DexEncodedMethod[virtualMethods.size()]));
- if (kind == Resource.Kind.PROGRAM) {
+ if (classKind == ClassKind.PROGRAM) {
context.owner = clazz.asProgramClass();
}
classConsumer.accept(clazz);
@@ -314,7 +314,7 @@
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
- return createAnnotationVisitor(desc, visible, null, getAnnotations(), parent.application);
+ return createAnnotationVisitor(desc, visible, getAnnotations(), parent.application);
}
@Override
@@ -424,15 +424,12 @@
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
- return createAnnotationVisitor(desc, visible,
- mv == null ? null : mv.visitAnnotation(desc, visible),
- getAnnotations(), parent.application);
+ return createAnnotationVisitor(desc, visible, getAnnotations(), parent.application);
}
@Override
public AnnotationVisitor visitAnnotationDefault() {
- return new CreateAnnotationVisitor(mv == null ? null : mv.visitAnnotationDefault(),
- parent.application, (names, elements) -> {
+ return new CreateAnnotationVisitor(parent.application, (names, elements) -> {
assert elements.size() == 1;
defaultAnnotation = elements.get(0);
});
@@ -455,8 +452,12 @@
// never see this non-existing annotation descriptor. ASM uses the same check to make
// sure to undo their workaround for the javac bug in their MethodWriter.
if (desc.equals("Ljava/lang/Synthetic;")) {
- assert parameterAnnotations == null;
- fakeParameterAnnotations++;
+ // We can iterate through all the parameters twice. Once for visible and once for
+ // invisible parameter annotations. We only record the number of fake parameter
+ // annotations once.
+ if (parameterAnnotations == null) {
+ fakeParameterAnnotations++;
+ }
return null;
}
if (parameterAnnotations == null) {
@@ -466,8 +467,8 @@
parameterAnnotations.add(new ArrayList<>());
}
}
+ assert mv == null;
return createAnnotationVisitor(desc, visible,
- mv == null ? null : mv.visitParameterAnnotation(parameter, desc, visible),
parameterAnnotations.get(parameter - fakeParameterAnnotations), parent.application);
}
@@ -511,7 +512,7 @@
Code code = null;
if (!flags.isAbstract()
&& !flags.isNative()
- && parent.kind == Resource.Kind.PROGRAM) {
+ && parent.classKind == ClassKind.PROGRAM) {
code = new JarCode(method, parent.context, parent.application);
}
DexAnnotationSetRefList parameterAnnotationSets;
@@ -584,10 +585,9 @@
private List<DexString> names = null;
private final List<DexValue> values = new ArrayList<>();
- public CreateAnnotationVisitor(AnnotationVisitor annotationVisitor,
- JarApplicationReader application,
- BiConsumer<List<DexString>, List<DexValue>> onVisitEnd) {
- super(ASM5, annotationVisitor);
+ public CreateAnnotationVisitor(
+ JarApplicationReader application, BiConsumer<List<DexString>, List<DexValue>> onVisitEnd) {
+ super(ASM5);
this.application = application;
this.onVisitEnd = onVisitEnd;
}
@@ -605,14 +605,14 @@
@Override
public AnnotationVisitor visitAnnotation(String name, String desc) {
- return new CreateAnnotationVisitor(av, application, (names, values) ->
+ return new CreateAnnotationVisitor(application, (names, values) ->
addElement(name, new DexValueAnnotation(
createEncodedAnnotation(desc, names, values, application))));
}
@Override
public AnnotationVisitor visitArray(String name) {
- return new CreateAnnotationVisitor(av, application, (names, values) -> {
+ return new CreateAnnotationVisitor(application, (names, values) -> {
assert names == null;
addElement(name, new DexValueArray(values.toArray(new DexValue[values.size()])));
});
diff --git a/src/main/java/com/android/tools/r8/graph/LazyClassFileLoader.java b/src/main/java/com/android/tools/r8/graph/LazyClassFileLoader.java
index ce40d19..e5792cd 100644
--- a/src/main/java/com/android/tools/r8/graph/LazyClassFileLoader.java
+++ b/src/main/java/com/android/tools/r8/graph/LazyClassFileLoader.java
@@ -9,14 +9,15 @@
import com.android.tools.r8.Resource;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.utils.InternalResource;
import com.google.common.io.Closer;
import java.io.IOException;
// Lazily loads a class file represented by resource.
public final class LazyClassFileLoader implements DexClassPromise {
// Resource representing file definition.
- private final InternalResource resource;
+ private final Resource resource;
+ // Class kind to be created.
+ private final ClassKind classKind;
// Application reader to be used. Note that the reader may be reused in
// many loaders and may be used concurrently, it is considered to be
@@ -32,10 +33,13 @@
// field is only accessed in context synchronized on `this`.
private DexClass loadedClass = null;
- public LazyClassFileLoader(DexType type, InternalResource resource, JarApplicationReader reader) {
+ public LazyClassFileLoader(DexType type,
+ Resource resource, ClassKind classKind, JarApplicationReader reader) {
this.resource = resource;
this.reader = reader;
this.type = type;
+ this.classKind = classKind;
+ assert classKind != ClassKind.PROGRAM;
}
// Callback method for JarClassFileReader, is always called in synchronized context.
@@ -51,23 +55,23 @@
}
@Override
- public DexClass.Origin getOrigin() {
- return DexClass.Origin.ClassFile;
+ public Resource.Kind getOrigin() {
+ return Resource.Kind.CLASSFILE;
}
@Override
public boolean isProgramClass() {
- return resource.getKind() == Resource.Kind.PROGRAM;
+ return false;
}
@Override
public boolean isClasspathClass() {
- return resource.getKind() == Resource.Kind.CLASSPATH;
+ return classKind == ClassKind.CLASSPATH;
}
@Override
public boolean isLibraryClass() {
- return resource.getKind() == Resource.Kind.LIBRARY;
+ return classKind == ClassKind.LIBRARY;
}
// Loads the class from the resource. Synchronized on `this` to avoid
@@ -81,7 +85,7 @@
try (Closer closer = Closer.create()) {
JarClassFileReader reader = new JarClassFileReader(this.reader, this::addClass);
- reader.read(DEFAULT_DEX_FILENAME, resource.getKind(), resource.getStream(closer));
+ reader.read(DEFAULT_DEX_FILENAME, classKind, resource.getStream(closer));
} catch (IOException e) {
throw new CompilationError("Failed to load class: " + type.toSourceString(), e);
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
index 215cfba..01be50d 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
@@ -4,12 +4,12 @@
package com.android.tools.r8.ir.desugar;
+import com.android.tools.r8.Resource;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.graph.DexApplication.Builder;
import com.android.tools.r8.graph.DexCallSite;
import com.android.tools.r8.graph.DexClass;
-import com.android.tools.r8.graph.DexClassPromise;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
@@ -217,7 +217,7 @@
private static boolean shouldProcess(
DexProgramClass clazz, Flavor flavour, boolean mustBeInterface) {
- return (clazz.getOrigin() != DexClass.Origin.Dex || flavour == Flavor.IncludeAllResources)
+ return (clazz.getOrigin() != Resource.Kind.DEX || flavour == Flavor.IncludeAllResources)
&& clazz.isInterface() == mustBeInterface;
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
index 66cd7d9..d1b1577 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
@@ -9,7 +9,6 @@
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DexAccessFlags;
import com.android.tools.r8.graph.DexAnnotationSet;
-import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
@@ -128,7 +127,7 @@
DexType companionClassType = rewriter.getCompanionClassType(iface.type);
DexProgramClass companionClass = new DexProgramClass(
companionClassType,
- DexClass.Origin.Synthetic,
+ null,
companionClassFlags,
rewriter.factory.objectType,
DexTypeList.empty(),
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
index db28115..37bfdaa 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
@@ -10,7 +10,6 @@
import com.android.tools.r8.graph.DexAccessFlags;
import com.android.tools.r8.graph.DexAnnotationSet;
import com.android.tools.r8.graph.DexAnnotationSetRefList;
-import com.android.tools.r8.graph.DexApplication.Builder;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexClassPromise;
import com.android.tools.r8.graph.DexCode;
@@ -114,7 +113,7 @@
final DexProgramClass synthesizeLambdaClass() {
return new DexProgramClass(
type,
- DexClass.Origin.Synthetic,
+ null,
new DexAccessFlags(Constants.ACC_FINAL | Constants.ACC_SYNTHETIC),
rewriter.factory.objectType,
buildInterfaces(),
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
index 80a5975..42b5220 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
@@ -1028,7 +1028,7 @@
DexAccessFlags accessFlags = new DexAccessFlags(Constants.ACC_PUBLIC);
DexProgramClass clazz = new DexProgramClass(
type,
- DexClass.Origin.Synthetic,
+ null,
accessFlags,
superType,
interfaces,
diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
index a981990..3a96ac2 100644
--- a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
+++ b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
@@ -870,7 +870,7 @@
assert leftReg != NO_REGISTER && rightReg != NO_REGISTER;
// The dalvik bug is actually only for overlap with the second operand, For now we
// make sure that there is no overlap with either operand.
- if ((leftReg + 1) == register|| (rightReg + 1) == register) {
+ if ((leftReg + 1) == register || (rightReg + 1) == register) {
return true;
}
return false;
@@ -977,14 +977,8 @@
// Get the register (pair) that is free the longest. That is the register with the largest
// free position.
- int candidate = getLargestCandidate(registerConstraint, freePositions, needsRegisterPair);
- if (needsOverlappingLongRegisterWorkaround(unhandledInterval)) {
- while (hasOverlappingLongRegisters(unhandledInterval, candidate)) {
- // Make the overlapping register unavailable for allocation and try again.
- freePositions.set(candidate, 0);
- candidate = getLargestCandidate(registerConstraint, freePositions, needsRegisterPair);
- }
- }
+ int candidate = getLargestValidCandidate(
+ unhandledInterval, registerConstraint, needsRegisterPair, freePositions);
int largestFreePosition = freePositions.get(candidate);
if (needsRegisterPair) {
largestFreePosition = Math.min(largestFreePosition, freePositions.get(candidate + 1));
@@ -1162,6 +1156,19 @@
return candidate;
}
+ private int getLargestValidCandidate(LiveIntervals unhandledInterval, int registerConstraint,
+ boolean needsRegisterPair, RegisterPositions freePositions) {
+ int candidate = getLargestCandidate(registerConstraint, freePositions, needsRegisterPair);
+ if (needsOverlappingLongRegisterWorkaround(unhandledInterval)) {
+ while (hasOverlappingLongRegisters(unhandledInterval, candidate)) {
+ // Make the overlapping register unavailable for allocation and try again.
+ freePositions.set(candidate, 0);
+ candidate = getLargestCandidate(registerConstraint, freePositions, needsRegisterPair);
+ }
+ }
+ return candidate;
+ }
+
private void allocateBlockedRegister(LiveIntervals unhandledInterval) {
int registerConstraint = unhandledInterval.getRegisterLimit();
if (registerConstraint < Constants.U16BIT_MAX) {
@@ -1225,9 +1232,9 @@
inactive, unhandledInterval, registerConstraint, usePositions, blockedPositions);
// Get the register (pair) that has the highest use position.
- assert unhandledInterval.requiredRegisters() <= 2;
boolean needsRegisterPair = unhandledInterval.requiredRegisters() == 2;
- int candidate = getLargestCandidate(registerConstraint, usePositions, needsRegisterPair);
+ int candidate = getLargestValidCandidate(
+ unhandledInterval, registerConstraint, needsRegisterPair, usePositions);
int largestUsePosition = usePositions.get(candidate);
int blockedPosition = blockedPositions.get(candidate);
if (needsRegisterPair) {
diff --git a/src/main/java/com/android/tools/r8/utils/AndroidApp.java b/src/main/java/com/android/tools/r8/utils/AndroidApp.java
index 2b78295..453a250 100644
--- a/src/main/java/com/android/tools/r8/utils/AndroidApp.java
+++ b/src/main/java/com/android/tools/r8/utils/AndroidApp.java
@@ -10,6 +10,8 @@
import com.android.tools.r8.Resource;
import com.android.tools.r8.ResourceProvider;
import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.ClassKind;
import com.google.common.collect.ImmutableList;
import com.google.common.io.ByteStreams;
import com.google.common.io.Closer;
@@ -50,26 +52,32 @@
public static final String DEFAULT_PROGUARD_SEEDS_FILE = "proguard.seeds";
public static final String DEFAULT_PACKAGE_DISTRIBUTION_FILE = "package.map";
- private final ImmutableList<InternalResource> dexSources;
- private final ImmutableList<InternalResource> classSources;
- private final ImmutableList<ResourceProvider> resourceProviders;
- private final InternalResource proguardMap;
- private final InternalResource proguardSeeds;
- private final InternalResource packageDistribution;
- private final InternalResource mainDexList;
+ private final ImmutableList<Resource> programResources;
+ private final ImmutableList<Resource> classpathResources;
+ private final ImmutableList<Resource> libraryResources;
+ private final ImmutableList<ResourceProvider> classpathResourceProviders;
+ private final ImmutableList<ResourceProvider> libraryResourceProviders;
+ private final Resource proguardMap;
+ private final Resource proguardSeeds;
+ private final Resource packageDistribution;
+ private final Resource mainDexList;
// See factory methods and AndroidApp.Builder below.
private AndroidApp(
- ImmutableList<InternalResource> dexSources,
- ImmutableList<InternalResource> classSources,
- ImmutableList<ResourceProvider> resourceProviders,
- InternalResource proguardMap,
- InternalResource proguardSeeds,
- InternalResource packageDistribution,
- InternalResource mainDexList) {
- this.dexSources = dexSources;
- this.classSources = classSources;
- this.resourceProviders = resourceProviders;
+ ImmutableList<Resource> programResources,
+ ImmutableList<Resource> classpathResources,
+ ImmutableList<Resource> libraryResources,
+ ImmutableList<ResourceProvider> classpathResourceProviders,
+ ImmutableList<ResourceProvider> libraryResourceProviders,
+ Resource proguardMap,
+ Resource proguardSeeds,
+ Resource packageDistribution,
+ Resource mainDexList) {
+ this.programResources = programResources;
+ this.classpathResources = classpathResources;
+ this.libraryResources = libraryResources;
+ this.classpathResourceProviders = classpathResourceProviders;
+ this.libraryResourceProviders = libraryResourceProviders;
this.proguardMap = proguardMap;
this.proguardSeeds = proguardSeeds;
this.packageDistribution = packageDistribution;
@@ -140,45 +148,49 @@
}
/** Get input streams for all dex program resources. */
- public List<InternalResource> getDexProgramResources() {
- return filter(dexSources, Resource.Kind.PROGRAM);
+ public List<Resource> getDexProgramResources() {
+ return filter(programResources, Resource.Kind.DEX);
}
/** Get input streams for all Java-bytecode program resources. */
- public List<InternalResource> getClassProgramResources() {
- return filter(classSources, Resource.Kind.PROGRAM);
+ public List<Resource> getClassProgramResources() {
+ return filter(programResources, Resource.Kind.CLASSFILE);
}
/** Get input streams for all dex program classpath resources. */
- public List<InternalResource> getDexClasspathResources() {
- return filter(dexSources, Resource.Kind.CLASSPATH);
+ public List<Resource> getDexClasspathResources() {
+ return filter(classpathResources, Resource.Kind.DEX);
}
/** Get input streams for all Java-bytecode classpath resources. */
- public List<InternalResource> getClassClasspathResources() {
- return filter(classSources, Resource.Kind.CLASSPATH);
+ public List<Resource> getClassClasspathResources() {
+ return filter(classpathResources, Resource.Kind.CLASSFILE);
}
/** Get input streams for all dex library resources. */
- public List<InternalResource> getDexLibraryResources() {
- return filter(dexSources, Resource.Kind.LIBRARY);
+ public List<Resource> getDexLibraryResources() {
+ return filter(libraryResources, Resource.Kind.DEX);
}
/** Get input streams for all Java-bytecode library resources. */
- public List<InternalResource> getClassLibraryResources() {
- return filter(classSources, Resource.Kind.LIBRARY);
+ public List<Resource> getClassLibraryResources() {
+ return filter(libraryResources, Resource.Kind.CLASSFILE);
}
- /** Get lazy resource providers. */
- public List<ResourceProvider> getLazyResourceProviders() {
- return resourceProviders;
+ /** Get classpath resource providers. */
+ public List<ResourceProvider> getClasspathResourceProviders() {
+ return classpathResourceProviders;
}
- private List<InternalResource> filter(
- List<InternalResource> resources, Resource.Kind kind) {
- List<InternalResource> out = new ArrayList<>(resources.size());
- for (InternalResource resource : resources) {
- if (kind == resource.getKind()) {
+ /** Get library resource providers. */
+ public List<ResourceProvider> getLibraryResourceProviders() {
+ return libraryResourceProviders;
+ }
+
+ private List<Resource> filter(List<Resource> resources, Resource.Kind kind) {
+ List<Resource> out = new ArrayList<>(resources.size());
+ for (Resource resource : resources) {
+ if (kind == resource.kind) {
out.add(resource);
}
}
@@ -273,7 +285,7 @@
Path directory, OutputMode outputMode, boolean overwrite) throws IOException {
CopyOption[] options = copyOptions(overwrite);
try (Closer closer = Closer.create()) {
- List<InternalResource> dexProgramSources = getDexProgramResources();
+ List<Resource> dexProgramSources = getDexProgramResources();
for (int i = 0; i < dexProgramSources.size(); i++) {
Path fileName = directory.resolve(outputMode.getFileName(dexProgramSources.get(i), i));
Files.copy(dexProgramSources.get(i).getStream(closer), fileName, options);
@@ -286,7 +298,7 @@
public List<byte[]> writeToMemory() throws IOException {
List<byte[]> dex = new ArrayList<>();
try (Closer closer = Closer.create()) {
- List<InternalResource> dexProgramSources = getDexProgramResources();
+ List<Resource> dexProgramSources = getDexProgramResources();
for (int i = 0; i < dexProgramSources.size(); i++) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteStreams.copy(dexProgramSources.get(i).getStream(closer), out);
@@ -312,7 +324,7 @@
OpenOption[] options = openOptions(overwrite);
try (Closer closer = Closer.create()) {
try (ZipOutputStream out = new ZipOutputStream(Files.newOutputStream(archive, options))) {
- List<InternalResource> dexProgramSources = getDexProgramResources();
+ List<Resource> dexProgramSources = getDexProgramResources();
for (int i = 0; i < dexProgramSources.size(); i++) {
ZipEntry zipEntry = new ZipEntry(outputMode.getFileName(dexProgramSources.get(i), i));
byte[] bytes = ByteStreams.toByteArray(dexProgramSources.get(i).getStream(closer));
@@ -368,13 +380,15 @@
*/
public static class Builder {
- private final List<InternalResource> dexSources = new ArrayList<>();
- private final List<InternalResource> classSources = new ArrayList<>();
- private final List<ResourceProvider> resourceProviders = new ArrayList<>();
- private InternalResource proguardMap;
- private InternalResource proguardSeeds;
- private InternalResource packageDistribution;
- private InternalResource mainDexList;
+ private final List<Resource> programResources = new ArrayList<>();
+ private final List<Resource> classpathResources = new ArrayList<>();
+ private final List<Resource> libraryResources = new ArrayList<>();
+ private final List<ResourceProvider> classpathResourceProviders = new ArrayList<>();
+ private final List<ResourceProvider> libraryResourceProviders = new ArrayList<>();
+ private Resource proguardMap;
+ private Resource proguardSeeds;
+ private Resource packageDistribution;
+ private Resource mainDexList;
// See AndroidApp::builder().
private Builder() {
@@ -382,9 +396,11 @@
// See AndroidApp::builder(AndroidApp).
private Builder(AndroidApp app) {
- dexSources.addAll(app.dexSources);
- classSources.addAll(app.classSources);
- resourceProviders.addAll(app.resourceProviders);
+ programResources.addAll(app.programResources);
+ classpathResources.addAll(app.classpathResources);
+ libraryResources.addAll(app.libraryResources);
+ classpathResourceProviders.addAll(app.classpathResourceProviders);
+ libraryResourceProviders.addAll(app.libraryResourceProviders);
proguardMap = app.proguardMap;
proguardSeeds = app.proguardSeeds;
packageDistribution = app.packageDistribution;
@@ -405,7 +421,7 @@
public Builder addProgramDirectory(Path directory) throws IOException {
File[] resources = directory.toFile().listFiles(file -> isDexFile(file.toPath()));
for (File source : resources) {
- addFile(source.toPath(), Resource.Kind.PROGRAM);
+ addFile(source.toPath(), ClassKind.PROGRAM);
}
File mapFile = new File(directory.toFile(), DEFAULT_PROGUARD_MAP_FILE);
if (mapFile.exists()) {
@@ -426,7 +442,7 @@
*/
public Builder addProgramFiles(Collection<Path> files) throws IOException {
for (Path file : files) {
- addFile(file, Resource.Kind.PROGRAM);
+ addFile(file, ClassKind.PROGRAM);
}
return this;
}
@@ -443,7 +459,7 @@
*/
public Builder addClasspathFiles(Collection<Path> files) throws IOException {
for (Path file : files) {
- addFile(file, Resource.Kind.CLASSPATH);
+ addFile(file, ClassKind.CLASSPATH);
}
return this;
}
@@ -452,7 +468,7 @@
* Add classpath resource provider.
*/
public Builder addClasspathResourceProvider(ResourceProvider provider) {
- resourceProviders.add(provider);
+ classpathResourceProviders.add(provider);
return this;
}
@@ -468,7 +484,7 @@
*/
public Builder addLibraryFiles(Collection<Path> files) throws IOException {
for (Path file : files) {
- addFile(file, Resource.Kind.LIBRARY);
+ addFile(file, ClassKind.LIBRARY);
}
return this;
}
@@ -477,7 +493,7 @@
* Add library resource provider.
*/
public Builder addLibraryResourceProvider(ResourceProvider provider) {
- resourceProviders.add(provider);
+ libraryResourceProviders.add(provider);
return this;
}
@@ -485,7 +501,8 @@
* Add dex program-data with class descriptor.
*/
public Builder addDexProgramData(byte[] data, Set<String> classDescriptors) {
- dexSources.add(InternalResource.fromBytes(Resource.Kind.PROGRAM, data, classDescriptors));
+ resources(ClassKind.PROGRAM).add(
+ Resource.fromBytes(Resource.Kind.DEX, data, classDescriptors));
return this;
}
@@ -501,7 +518,7 @@
*/
public Builder addDexProgramData(Collection<byte[]> data) {
for (byte[] datum : data) {
- dexSources.add(InternalResource.fromBytes(Resource.Kind.PROGRAM, datum));
+ resources(ClassKind.PROGRAM).add(Resource.fromBytes(Resource.Kind.DEX, datum));
}
return this;
}
@@ -518,7 +535,7 @@
*/
public Builder addClassProgramData(Collection<byte[]> data) {
for (byte[] datum : data) {
- classSources.add(InternalResource.fromBytes(Resource.Kind.PROGRAM, datum));
+ resources(ClassKind.PROGRAM).add(Resource.fromBytes(Resource.Kind.CLASSFILE, datum));
}
return this;
}
@@ -527,7 +544,7 @@
* Set proguard-map file.
*/
public Builder setProguardMapFile(Path file) {
- proguardMap = file == null ? null : InternalResource.fromFile(null, file);
+ proguardMap = file == null ? null : Resource.fromFile(null, file);
return this;
}
@@ -542,7 +559,7 @@
* Set proguard-map data.
*/
public Builder setProguardMapData(byte[] content) {
- proguardMap = content == null ? null : InternalResource.fromBytes(null, content);
+ proguardMap = content == null ? null : Resource.fromBytes(null, content);
return this;
}
@@ -550,7 +567,7 @@
* Set proguard-seeds data.
*/
public Builder setProguardSeedsData(byte[] content) {
- proguardSeeds = content == null ? null : InternalResource.fromBytes(null, content);
+ proguardSeeds = content == null ? null : Resource.fromBytes(null, content);
return this;
}
@@ -558,7 +575,7 @@
* Set the package-distribution file.
*/
public Builder setPackageDistributionFile(Path file) {
- packageDistribution = file == null ? null : InternalResource.fromFile(null, file);
+ packageDistribution = file == null ? null : Resource.fromFile(null, file);
return this;
}
@@ -566,7 +583,7 @@
* Set the main-dex list file.
*/
public Builder setMainDexListFile(Path file) {
- mainDexList = file == null ? null : InternalResource.fromFile(null, file);
+ mainDexList = file == null ? null : Resource.fromFile(null, file);
return this;
}
@@ -575,31 +592,45 @@
*/
public AndroidApp build() {
return new AndroidApp(
- ImmutableList.copyOf(dexSources),
- ImmutableList.copyOf(classSources),
- ImmutableList.copyOf(resourceProviders),
+ ImmutableList.copyOf(programResources),
+ ImmutableList.copyOf(classpathResources),
+ ImmutableList.copyOf(libraryResources),
+ ImmutableList.copyOf(classpathResourceProviders),
+ ImmutableList.copyOf(libraryResourceProviders),
proguardMap,
proguardSeeds,
packageDistribution,
mainDexList);
}
- private void addFile(Path file, Resource.Kind kind) throws IOException {
+ private List<Resource> resources(ClassKind classKind) {
+ switch (classKind) {
+ case PROGRAM:
+ return programResources;
+ case CLASSPATH:
+ return classpathResources;
+ case LIBRARY:
+ return libraryResources;
+ }
+ throw new Unreachable();
+ }
+
+ private void addFile(Path file, ClassKind classKind) throws IOException {
if (!Files.exists(file)) {
throw new FileNotFoundException("Non-existent input file: " + file);
}
if (isDexFile(file)) {
- dexSources.add(InternalResource.fromFile(kind, file));
+ resources(classKind).add(Resource.fromFile(Resource.Kind.DEX, file));
} else if (isClassFile(file)) {
- classSources.add(InternalResource.fromFile(kind, file));
+ resources(classKind).add(Resource.fromFile(Resource.Kind.CLASSFILE, file));
} else if (isArchive(file)) {
- addArchive(file, kind);
+ addArchive(file, classKind);
} else {
throw new CompilationError("Unsupported source file type for file: " + file);
}
}
- private void addArchive(Path archive, Resource.Kind kind) throws IOException {
+ private void addArchive(Path archive, ClassKind classKind) throws IOException {
assert isArchive(archive);
boolean containsDexData = false;
boolean containsClassData = false;
@@ -609,12 +640,13 @@
Path name = Paths.get(entry.getName());
if (isDexFile(name)) {
containsDexData = true;
- dexSources.add(InternalResource.fromBytes(kind, ByteStreams.toByteArray(stream)));
+ resources(classKind).add(Resource.fromBytes(
+ Resource.Kind.DEX, ByteStreams.toByteArray(stream)));
} else if (isClassFile(name)) {
containsClassData = true;
String descriptor = PreloadedResourceProvider.guessTypeDescriptor(name);
- classSources.add(InternalResource.fromBytes(
- kind, ByteStreams.toByteArray(stream), Collections.singleton(descriptor)));
+ resources(classKind).add(Resource.fromBytes(Resource.Kind.CLASSFILE,
+ ByteStreams.toByteArray(stream), Collections.singleton(descriptor)));
}
}
} catch (ZipException e) {
diff --git a/src/main/java/com/android/tools/r8/utils/DirectoryResourceProvider.java b/src/main/java/com/android/tools/r8/utils/DirectoryResourceProvider.java
index 1d2ff81..b003d86 100644
--- a/src/main/java/com/android/tools/r8/utils/DirectoryResourceProvider.java
+++ b/src/main/java/com/android/tools/r8/utils/DirectoryResourceProvider.java
@@ -10,13 +10,15 @@
import java.io.File;
import java.nio.file.Path;
-/** Lazy resource provider based on filesystem directory content. */
+/**
+ * Lazy resource provider based on filesystem directory content.
+ *
+ * NOTE: only handles classfile resources.
+ */
public final class DirectoryResourceProvider implements ResourceProvider {
- private final Resource.Kind kind;
private final Path root;
- private DirectoryResourceProvider(Resource.Kind kind, Path root) {
- this.kind = kind;
+ private DirectoryResourceProvider(Path root) {
this.root = root;
}
@@ -30,11 +32,11 @@
File file = filePath.toFile();
return (file.exists() && !file.isDirectory())
- ? InternalResource.fromFile(kind, filePath) : null;
+ ? Resource.fromFile(Resource.Kind.CLASSFILE, filePath) : null;
}
/** Create resource provider from directory path. */
- public static ResourceProvider fromDirectory(Resource.Kind kind, Path dir) {
- return new DirectoryResourceProvider(kind, dir.toAbsolutePath());
+ public static ResourceProvider fromDirectory(Path dir) {
+ return new DirectoryResourceProvider(dir.toAbsolutePath());
}
}
diff --git a/src/main/java/com/android/tools/r8/utils/InternalResource.java b/src/main/java/com/android/tools/r8/utils/InternalResource.java
deleted file mode 100644
index 9181092..0000000
--- a/src/main/java/com/android/tools/r8/utils/InternalResource.java
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (c) 2017, 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.utils;
-
-import com.android.tools.r8.Resource;
-import com.google.common.io.Closer;
-import java.io.ByteArrayInputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Path;
-import java.util.Set;
-
-/**
- * Internal resource class that is not intended for use from the outside.
- *
- * <p>This is only here to hide the creation and class descriptor methods
- * from the javadoc for the D8 API. If we decide to expose those methods
- * later the split between Resource and InternalResource can be removed.
- */
-public abstract class InternalResource implements Resource {
-
- private final Kind kind;
-
- private InternalResource(Kind kind) {
- this.kind = kind;
- }
-
- /** Get the kind of the resource. */
- public Kind getKind() {
- return kind;
- }
-
- /** Create an application resource for a given file and kind. */
- public static InternalResource fromFile(Kind kind, Path file) {
- return new FileResource(kind, file);
- }
-
- /** Create an application resource for a given content and kind. */
- public static InternalResource fromBytes(Kind kind, byte[] bytes) {
- return fromBytes(kind, bytes, null);
- }
-
- /** Create an application resource for a given content, kind and type descriptor. */
- public static InternalResource fromBytes(Kind kind, byte[] bytes, Set<String> typeDescriptors) {
- return new ByteResource(kind, bytes, typeDescriptors);
- }
-
- /**
- * If the resource represents a single class returns
- * its descriptor, returns `null` otherwise.
- */
- public String getSingleClassDescriptorOrNull() {
- Set<String> descriptors = getClassDescriptors();
- return (descriptors == null) || (descriptors.size() != 1)
- ? null : descriptors.iterator().next();
- }
-
- /** File based application resource. */
- private static class FileResource extends InternalResource {
- final Path file;
-
- FileResource(Kind kind, Path file) {
- super(kind);
- assert file != null;
- this.file = file;
- }
-
- @Override
- public Set<String> getClassDescriptors() {
- return null;
- }
-
- @Override
- public InputStream getStream(Closer closer) throws IOException {
- return closer.register(new FileInputStream(file.toFile()));
- }
- }
-
- /** Byte content based application resource. */
- private static class ByteResource extends InternalResource {
- final Set<String> classDescriptors;
- final byte[] bytes;
-
- ByteResource(Kind kind, byte[] bytes, Set<String> classDescriptors) {
- super(kind);
- assert bytes != null;
- this.classDescriptors = classDescriptors;
- this.bytes = bytes;
- }
-
- @Override
- public Set<String> getClassDescriptors() {
- return classDescriptors;
- }
-
- @Override
- public InputStream getStream(Closer closer) throws IOException {
- // Note: closing a byte-array input stream is a no-op.
- return new ByteArrayInputStream(bytes);
- }
- }
-}
diff --git a/src/main/java/com/android/tools/r8/utils/LazyClassCollection.java b/src/main/java/com/android/tools/r8/utils/LazyClassCollection.java
index 4f36811..0e71973 100644
--- a/src/main/java/com/android/tools/r8/utils/LazyClassCollection.java
+++ b/src/main/java/com/android/tools/r8/utils/LazyClassCollection.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.ResourceProvider;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.ClassKind;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexClassPromise;
@@ -39,7 +40,8 @@
private final Map<DexType, DexClassPromise> classes = new IdentityHashMap<>();
// Available lazy resource providers.
- private final List<ResourceProvider> providers;
+ private final List<ResourceProvider> classpathProviders;
+ private final List<ResourceProvider> libraryProviders;
// Application reader to be used. Note that the reader may be reused in
// many loaders and may be used concurrently, it is considered to be
@@ -48,8 +50,10 @@
// which is thread-safe).
private final JarApplicationReader reader;
- public LazyClassCollection(JarApplicationReader reader, List<ResourceProvider> providers) {
- this.providers = ImmutableList.copyOf(providers);
+ public LazyClassCollection(JarApplicationReader reader,
+ List<ResourceProvider> classpathProviders, List<ResourceProvider> libraryProviders) {
+ this.classpathProviders = ImmutableList.copyOf(classpathProviders);
+ this.libraryProviders = ImmutableList.copyOf(libraryProviders);
this.reader = reader;
}
@@ -92,25 +96,30 @@
// provided resource for this type.
private DexClassPromise buildPromiseChain(DexType type) {
String descriptor = type.descriptor.toString();
- DexClassPromise promise = null;
- int size = providers.size();
- for (int i = size - 1; i >= 0; i--) {
- Resource resource = providers.get(i).getResource(descriptor);
+ DexClassPromise promise = buildPromiseChain(
+ type, descriptor, null, classpathProviders, ClassKind.CLASSPATH);
+ promise = buildPromiseChain(
+ type, descriptor, promise, libraryProviders, ClassKind.LIBRARY);
+ return promise == null ? EmptyPromise.INSTANCE : promise;
+ }
+
+ private DexClassPromise buildPromiseChain(DexType type, String descriptor,
+ DexClassPromise promise, List<ResourceProvider> providers, ClassKind classKind) {
+ for (ResourceProvider provider : providers) {
+ Resource resource = provider.getResource(descriptor);
if (resource == null) {
continue;
}
- if (resource.getKind() == Resource.Kind.PROGRAM) {
- throw new CompilationError("Attempt to load program class " +
- type.toSourceString() + " via lazy resource provider");
+ if (resource.kind != Resource.Kind.CLASSFILE) {
+ throw new CompilationError("Resource returned by resource provider for type " +
+ type.toSourceString() + " must be a class file resource.");
}
- assert resource instanceof InternalResource;
- LazyClassFileLoader loader =
- new LazyClassFileLoader(type, (InternalResource) resource, reader);
+ LazyClassFileLoader loader = new LazyClassFileLoader(type, resource, classKind, reader);
promise = (promise == null) ? loader : new DexClassPromiseChain(loader, promise);
}
- return promise == null ? EmptyPromise.INSTANCE : promise;
+ return promise;
}
// Chooses the proper promise. Recursion is not expected to be deep.
@@ -130,7 +139,7 @@
}
@Override
- public DexClass.Origin getOrigin() {
+ public Resource.Kind getOrigin() {
throw new Unreachable();
}
@@ -172,7 +181,7 @@
}
@Override
- public DexClass.Origin getOrigin() {
+ public Resource.Kind getOrigin() {
return promise.getOrigin();
}
diff --git a/src/main/java/com/android/tools/r8/utils/OutputMode.java b/src/main/java/com/android/tools/r8/utils/OutputMode.java
index c27429a..ce743e8 100644
--- a/src/main/java/com/android/tools/r8/utils/OutputMode.java
+++ b/src/main/java/com/android/tools/r8/utils/OutputMode.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.utils;
import com.android.tools.r8.Resource;
+import java.util.Set;
/** Defines way the output is formed. */
public enum OutputMode {
@@ -16,9 +17,10 @@
FilePerClass {
@Override
String getFileName(Resource resource, int index) {
- assert resource instanceof InternalResource;
- String classDescriptor = ((InternalResource) resource).getSingleClassDescriptorOrNull();
- assert classDescriptor != null;
+ Set<String> classDescriptors = resource.getClassDescriptors();
+ assert classDescriptors != null;
+ assert classDescriptors.size() == 1;
+ String classDescriptor = classDescriptors.iterator().next();
assert !classDescriptor.contains(".");
return DescriptorUtils.descriptorToJavaType(classDescriptor) + ".dex";
}
diff --git a/src/main/java/com/android/tools/r8/utils/PreloadedResourceProvider.java b/src/main/java/com/android/tools/r8/utils/PreloadedResourceProvider.java
index e3d5652..fcb89d4 100644
--- a/src/main/java/com/android/tools/r8/utils/PreloadedResourceProvider.java
+++ b/src/main/java/com/android/tools/r8/utils/PreloadedResourceProvider.java
@@ -22,13 +22,15 @@
import java.util.zip.ZipException;
import java.util.zip.ZipInputStream;
-/** Lazy resource provider based on preloaded/prebuilt context. */
+/**
+ * Lazy resource provider based on preloaded/prebuilt context.
+ *
+ * NOTE: only handles classfile resources.
+ */
public final class PreloadedResourceProvider implements ResourceProvider {
- private final Resource.Kind kind;
private final Map<String, byte[]> content;
- private PreloadedResourceProvider(Resource.Kind kind, Map<String, byte[]> content) {
- this.kind = kind;
+ private PreloadedResourceProvider(Map<String, byte[]> content) {
this.content = content;
}
@@ -38,12 +40,11 @@
if (bytes == null) {
return null;
}
- return InternalResource.fromBytes(kind, bytes, Collections.singleton(descriptor));
+ return Resource.fromBytes(Resource.Kind.CLASSFILE, bytes, Collections.singleton(descriptor));
}
/** Create preloaded content resource provider from archive file. */
- public static ResourceProvider fromArchive(
- Resource.Kind kind, Path archive) throws IOException {
+ public static ResourceProvider fromArchive(Path archive) throws IOException {
assert isArchive(archive);
Builder builder = builder();
try (ZipInputStream stream = new ZipInputStream(new FileInputStream(archive.toFile()))) {
@@ -59,7 +60,7 @@
"Zip error while reading '" + archive + "': " + e.getMessage(), e);
}
- return builder.build(kind);
+ return builder.build();
}
// Guess class descriptor from location of the class file.
@@ -99,10 +100,9 @@
return this;
}
- public PreloadedResourceProvider build(Resource.Kind kind) {
+ public PreloadedResourceProvider build() {
assert content != null;
- assert kind != null;
- PreloadedResourceProvider provider = new PreloadedResourceProvider(kind, content);
+ PreloadedResourceProvider provider = new PreloadedResourceProvider(content);
content = null;
return provider;
}
diff --git a/src/test/examples/regress_62300145/Regress.java b/src/test/examples/regress_62300145/Regress.java
index 77aa6bd..f151e83 100644
--- a/src/test/examples/regress_62300145/Regress.java
+++ b/src/test/examples/regress_62300145/Regress.java
@@ -3,9 +3,13 @@
// BSD-style license that can be found in the LICENSE file.
package regress_62300145;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
public class Regress {
@@ -13,13 +17,18 @@
public @interface A {
}
+ @Retention(CLASS)
+ @Target({ElementType.PARAMETER})
+ public @interface B {
+ }
+
public class InnerClass {
- public InnerClass(@A String p) {}
+ public InnerClass(@A @B String p1, @A String p2, @B String p3) { }
}
public static void main(String[] args) throws NoSuchMethodException {
- Constructor<InnerClass> constructor =
- InnerClass.class.getDeclaredConstructor(Regress.class, String.class);
+ Constructor<InnerClass> constructor = InnerClass.class.getDeclaredConstructor(
+ Regress.class, String.class, String.class, String.class);
int i = 0;
for (Annotation[] annotations : constructor.getParameterAnnotations()) {
System.out.print(i++ + ": ");
diff --git a/src/test/java/com/android/tools/r8/D8IncrementalRunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/D8IncrementalRunExamplesAndroidOTest.java
index e2e88e2..728f769 100644
--- a/src/test/java/com/android/tools/r8/D8IncrementalRunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/D8IncrementalRunExamplesAndroidOTest.java
@@ -10,7 +10,6 @@
import com.android.tools.r8.errors.InternalCompilerError;
import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.utils.AndroidApp;
-import com.android.tools.r8.utils.InternalResource;
import com.android.tools.r8.utils.OffOrAuto;
import com.android.tools.r8.utils.OutputMode;
import com.beust.jcommander.internal.Lists;
@@ -26,6 +25,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.function.UnaryOperator;
@@ -74,9 +74,11 @@
List<String> classFiles = collectClassFiles(testJarFile);
AndroidApp app = compileClassFiles(
testJarFile, classFiles, output, OutputMode.FilePerClass);
- for (InternalResource resource : app.getDexProgramResources()) {
- String classDescriptor = resource.getSingleClassDescriptorOrNull();
- Assert.assertNotNull("Add resources are expected to have a descriptor", classDescriptor);
+ for (Resource resource : app.getDexProgramResources()) {
+ Set<String> descriptors = resource.getClassDescriptors();
+ Assert.assertNotNull(descriptors);
+ Assert.assertEquals(1, descriptors.size());
+ String classDescriptor = descriptors.iterator().next();
classDescriptor = classDescriptor.substring(1, classDescriptor.length() - 1);
fileToResource.put(classDescriptor + ".class", resource);
}
diff --git a/src/test/java/com/android/tools/r8/D8ResourceProviderRunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/D8ResourceProviderRunExamplesAndroidOTest.java
index b7181b8..7cef1a4 100644
--- a/src/test/java/com/android/tools/r8/D8ResourceProviderRunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/D8ResourceProviderRunExamplesAndroidOTest.java
@@ -25,14 +25,13 @@
private void addClasspathPath(Path location, D8Command.Builder builder) {
builder.addClasspathResourceProvider(
- DirectoryResourceProvider.fromDirectory(
- Resource.Kind.CLASSPATH, location.resolve("..")));
+ DirectoryResourceProvider.fromDirectory(location.resolve("..")));
}
@Override
void addLibraryReference(D8Command.Builder builder, Path location) throws IOException {
builder.addLibraryResourceProvider(
- PreloadedResourceProvider.fromArchive(Resource.Kind.LIBRARY, location));
+ PreloadedResourceProvider.fromArchive(location));
}
}
diff --git a/src/test/java/com/android/tools/r8/internal/D8PhotosVerificationTest.java b/src/test/java/com/android/tools/r8/internal/D8PhotosVerificationTest.java
new file mode 100644
index 0000000..de72fb2
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/internal/D8PhotosVerificationTest.java
@@ -0,0 +1,29 @@
+// Copyright (c) 2017, 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.internal;
+
+import com.android.tools.r8.CompilationException;
+import com.android.tools.r8.CompilationMode;
+import com.android.tools.r8.R8RunArtTestsTest.CompilerUnderTest;
+import com.android.tools.r8.shaking.ProguardRuleParserException;
+import java.io.IOException;
+import java.util.concurrent.ExecutionException;
+import org.junit.Test;
+
+public class D8PhotosVerificationTest extends CompilationTestBase {
+ public static final String PHOTOS =
+ "third_party/photos/2017-06-06/PhotosEnglishOnlyLegacy_proguard.jar";
+
+ public void runD8AndCheckVerification(CompilationMode mode, String version)
+ throws ProguardRuleParserException, ExecutionException, IOException, CompilationException {
+ runAndCheckVerification(
+ CompilerUnderTest.D8, mode, version, null, null, version);
+ }
+
+ @Test
+ public void verify()
+ throws ExecutionException, IOException, ProguardRuleParserException, CompilationException {
+ runD8AndCheckVerification(CompilationMode.RELEASE, PHOTOS);
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/internal/R8GMSCoreDeterministicTest.java b/src/test/java/com/android/tools/r8/internal/R8GMSCoreDeterministicTest.java
index d9314d8..2bc8dba 100644
--- a/src/test/java/com/android/tools/r8/internal/R8GMSCoreDeterministicTest.java
+++ b/src/test/java/com/android/tools/r8/internal/R8GMSCoreDeterministicTest.java
@@ -8,10 +8,10 @@
import com.android.tools.r8.CompilationException;
import com.android.tools.r8.R8Command;
+import com.android.tools.r8.Resource;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.shaking.ProguardRuleParserException;
import com.android.tools.r8.utils.AndroidApp;
-import com.android.tools.r8.utils.InternalResource;
import com.android.tools.r8.utils.OutputMode;
import com.google.common.io.ByteStreams;
import com.google.common.io.Closer;
@@ -43,8 +43,8 @@
// Verify that the result of the two compilations was the same.
try (Closer closer = Closer.create()) {
- List<InternalResource> files1 = app1.getDexProgramResources();
- List<InternalResource> files2 = app2.getDexProgramResources();
+ List<Resource> files1 = app1.getDexProgramResources();
+ List<Resource> files2 = app2.getDexProgramResources();
assertEquals(files1.size(), files2.size());
for (int index = 0; index < files1.size(); index++) {
InputStream file1 = files1.get(index).getStream(closer);
diff --git a/src/test/java/com/android/tools/r8/internal/R8GMSCoreTreeShakeJarVerificationTest.java b/src/test/java/com/android/tools/r8/internal/R8GMSCoreTreeShakeJarVerificationTest.java
index fecc360..d28c37d 100644
--- a/src/test/java/com/android/tools/r8/internal/R8GMSCoreTreeShakeJarVerificationTest.java
+++ b/src/test/java/com/android/tools/r8/internal/R8GMSCoreTreeShakeJarVerificationTest.java
@@ -10,7 +10,7 @@
import com.android.tools.r8.R8RunArtTestsTest.CompilerUnderTest;
import com.android.tools.r8.shaking.ProguardRuleParserException;
import com.android.tools.r8.utils.AndroidApp;
-import com.android.tools.r8.utils.InternalResource;
+import com.android.tools.r8.Resource;
import com.google.common.collect.ImmutableList;
import com.google.common.io.ByteStreams;
import com.google.common.io.Closer;
@@ -33,7 +33,7 @@
ImmutableList.of());
int bytes = 0;
try (Closer closer = Closer.create()) {
- for (InternalResource dex : app.getDexProgramResources()) {
+ for (Resource dex : app.getDexProgramResources()) {
bytes += ByteStreams.toByteArray(dex.getStream(closer)).length;
}
}
diff --git a/src/test/java/com/android/tools/r8/internal/YouTubeTreeShakeJarVerificationTest.java b/src/test/java/com/android/tools/r8/internal/YouTubeTreeShakeJarVerificationTest.java
index 8b5b814..b26d1aa 100644
--- a/src/test/java/com/android/tools/r8/internal/YouTubeTreeShakeJarVerificationTest.java
+++ b/src/test/java/com/android/tools/r8/internal/YouTubeTreeShakeJarVerificationTest.java
@@ -10,7 +10,7 @@
import com.android.tools.r8.R8RunArtTestsTest.CompilerUnderTest;
import com.android.tools.r8.shaking.ProguardRuleParserException;
import com.android.tools.r8.utils.AndroidApp;
-import com.android.tools.r8.utils.InternalResource;
+import com.android.tools.r8.Resource;
import com.google.common.collect.ImmutableList;
import com.google.common.io.ByteStreams;
import com.google.common.io.Closer;
@@ -35,7 +35,7 @@
ImmutableList.of());
int bytes = 0;
try (Closer closer = Closer.create()) {
- for (InternalResource dex : app.getDexProgramResources()) {
+ for (Resource dex : app.getDexProgramResources()) {
bytes += ByteStreams.toByteArray(dex.getStream(closer)).length;
}
}
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
index 29cef19..44c2156 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
@@ -24,7 +24,6 @@
import com.android.tools.r8.graph.DexAnnotationSet;
import com.android.tools.r8.graph.DexAnnotationSetRefList;
import com.android.tools.r8.graph.DexApplication;
-import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
@@ -291,7 +290,7 @@
builder.addClassPromise(
new DexProgramClass(
type,
- DexClass.Origin.Synthetic,
+ null,
new DexAccessFlags(),
factory.objectType,
DexTypeList.empty(),
diff --git a/third_party/photos/2017-06-06.tar.gz.sha1 b/third_party/photos/2017-06-06.tar.gz.sha1
new file mode 100644
index 0000000..b21e5a6
--- /dev/null
+++ b/third_party/photos/2017-06-06.tar.gz.sha1
@@ -0,0 +1 @@
+80389d76881463daf28b47f402c5013f499966bf
\ No newline at end of file