diff options
author | corysmith <corysmith@google.com> | 2017-05-17 19:14:56 +0200 |
---|---|---|
committer | Dmitry Lomov <dslomov@google.com> | 2017-05-19 15:07:43 +0200 |
commit | ba23f313daf8d0afd8c35ccc72c5661fd897bd5e (patch) | |
tree | 322f19965d38f3040aa00cd636c883c5b721f081 /src/tools/android/java/com/google/devtools | |
parent | 98d29f81bafe7ab6b0ff05ade92b4987d7b27bbf (diff) |
Remove the RTxtSymbolEntry in favor of the FieldInitializer class.
RELNOTES: None
PiperOrigin-RevId: 156321468
Diffstat (limited to 'src/tools/android/java/com/google/devtools')
8 files changed, 90 insertions, 128 deletions
diff --git a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java index 11a7ba6476..444278ac86 100644 --- a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java +++ b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java @@ -31,7 +31,6 @@ import com.android.io.StreamException; import com.android.repository.Revision; import com.android.utils.ILogger; import com.android.utils.StdLogger; -import com.android.utils.StdLogger.Level; import com.android.xml.AndroidManifest; import com.google.common.base.Joiner; import com.google.common.collect.ArrayListMultimap; @@ -496,9 +495,8 @@ public class AndroidResourceProcessor { ListeningExecutorService executorService = MoreExecutors.listeningDecorator( Executors.newFixedThreadPool(numThreads)); try (Closeable closeable = ExecutorServiceCloser.createWith(executorService)) { - StdLogger iLogger = new StdLogger(Level.INFO); for (Entry<String, ListenableFuture<ResourceSymbols>> entry : - ResourceSymbols.loadFrom(libraries, executorService, iLogger, appPackageName).entries()) { + ResourceSymbols.loadFrom(libraries, executorService, appPackageName).entries()) { libMap.put(entry.getKey(), entry.getValue().get()); } if (primaryRTxt != null && Files.exists(primaryRTxt)) { @@ -547,7 +545,8 @@ public class AndroidResourceProcessor { RClassGenerator classWriter = RClassGenerator.fromSymbols(classesOut, fullSymbolValues, finalFields); for (String packageName : libMap.keySet()) { - classWriter.write(packageName, ResourceSymbols.merge(libMap.get(packageName)).asFilterMap()); + classWriter.write( + packageName, ResourceSymbols.merge(libMap.get(packageName)).asInitializers()); } if (appPackageName != null) { // Unlike the R.java generation, we also write the app's R.class file so that the class diff --git a/src/tools/android/java/com/google/devtools/build/android/resources/FieldInitializer.java b/src/tools/android/java/com/google/devtools/build/android/resources/FieldInitializer.java index eb671ddd03..edcc464c18 100644 --- a/src/tools/android/java/com/google/devtools/build/android/resources/FieldInitializer.java +++ b/src/tools/android/java/com/google/devtools/build/android/resources/FieldInitializer.java @@ -15,7 +15,7 @@ package com.google.devtools.build.android.resources; import java.io.IOException; import java.io.Writer; -import java.util.Set; +import java.util.Collection; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.commons.InstructionAdapter; @@ -41,6 +41,9 @@ public interface FieldInitializer extends Comparable<FieldInitializer> { /** Write the source code for the initializer to the given writer. */ void writeInitSource(Writer writer, boolean finalFields) throws IOException; - /** Tests if the field's name is in the provided set. */ - boolean nameIsIn(Set<String> fieldNames); + /** Tests if the field's name is in the provided collection. */ + boolean nameIsIn(Collection<String> fieldNames); + + /** Adds fieldName to the provided set. */ + void addTo(Collection<String> fieldNames); } diff --git a/src/tools/android/java/com/google/devtools/build/android/resources/FieldInitializers.java b/src/tools/android/java/com/google/devtools/build/android/resources/FieldInitializers.java index c8961f9f16..45ffadf66d 100644 --- a/src/tools/android/java/com/google/devtools/build/android/resources/FieldInitializers.java +++ b/src/tools/android/java/com/google/devtools/build/android/resources/FieldInitializers.java @@ -14,6 +14,7 @@ package com.google.devtools.build.android.resources; import com.android.resources.ResourceType; +import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableMap; import com.google.common.collect.MultimapBuilder; import com.google.common.collect.SortedSetMultimap; @@ -21,9 +22,12 @@ import java.util.Collection; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; +import java.util.SortedSet; -/** A wrapper for a {@link Collection} of {@link FieldInitializer}s. */ +/** + * Represents a collection of resource symbols and values suitable for writing java sources and + * classes. + */ public class FieldInitializers implements Iterable<Entry<ResourceType, Collection<FieldInitializer>>> { @@ -40,10 +44,22 @@ public class FieldInitializers } public Iterable<Entry<ResourceType, Collection<FieldInitializer>>> filter( - Map<ResourceType, Set<String>> symbolsToWrite) { + FieldInitializers fieldsToWrite) { final SortedSetMultimap<ResourceType, FieldInitializer> initializersToWrite = MultimapBuilder.enumKeys(ResourceType.class).treeSetValues().build(); - for (Entry<ResourceType, Set<String>> entry : symbolsToWrite.entrySet()) { + + // Create a map to filter with. + final SortedSetMultimap<ResourceType, String> symbolsToWrite = + MultimapBuilder.enumKeys(ResourceType.class).treeSetValues().build(); + for (Entry<ResourceType, Collection<FieldInitializer>> entry : + fieldsToWrite.initializers.entrySet()) { + for (FieldInitializer initializer : entry.getValue()) { + final SortedSet<String> fieldNames = symbolsToWrite.get(entry.getKey()); + initializer.addTo(fieldNames); + } + } + + for (Entry<ResourceType, Collection<String>> entry : symbolsToWrite.asMap().entrySet()) { // Resource type may be missing if resource overriding eliminates resources at the binary // level, which were originally present at the library level. if (initializers.containsKey(entry.getKey())) { @@ -61,4 +77,11 @@ public class FieldInitializers public Iterator<Entry<ResourceType, Collection<FieldInitializer>>> iterator() { return initializers.entrySet().iterator(); } + + @Override + public String toString() { + return MoreObjects.toStringHelper(FieldInitializers.class) + .add("initializers", initializers) + .toString(); + } } diff --git a/src/tools/android/java/com/google/devtools/build/android/resources/IntArrayFieldInitializer.java b/src/tools/android/java/com/google/devtools/build/android/resources/IntArrayFieldInitializer.java index df3a80dcda..2f595c90f5 100644 --- a/src/tools/android/java/com/google/devtools/build/android/resources/IntArrayFieldInitializer.java +++ b/src/tools/android/java/com/google/devtools/build/android/resources/IntArrayFieldInitializer.java @@ -20,8 +20,8 @@ import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableList; import java.io.IOException; import java.io.Writer; +import java.util.Collection; import java.util.Objects; -import java.util.Set; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Type; import org.objectweb.asm.commons.InstructionAdapter; @@ -103,7 +103,7 @@ public final class IntArrayFieldInitializer implements FieldInitializer { } @Override - public boolean nameIsIn(Set<String> fieldNames) { + public boolean nameIsIn(Collection<String> fieldNames) { return fieldNames.contains(fieldName); } @@ -128,14 +128,18 @@ public final class IntArrayFieldInitializer implements FieldInitializer { public int hashCode() { return Objects.hash(fieldName, values); } - + @Override public boolean equals(Object obj) { if (obj instanceof IntArrayFieldInitializer) { IntArrayFieldInitializer other = (IntArrayFieldInitializer) obj; - return Objects.equals(fieldName, other.fieldName) - && Objects.equals(values, other.values); + return Objects.equals(fieldName, other.fieldName) && Objects.equals(values, other.values); } return false; } + + @Override + public void addTo(Collection<String> fieldNames) { + fieldNames.add(fieldName); + } } diff --git a/src/tools/android/java/com/google/devtools/build/android/resources/IntFieldInitializer.java b/src/tools/android/java/com/google/devtools/build/android/resources/IntFieldInitializer.java index 85679eb484..ffbd64fcda 100644 --- a/src/tools/android/java/com/google/devtools/build/android/resources/IntFieldInitializer.java +++ b/src/tools/android/java/com/google/devtools/build/android/resources/IntFieldInitializer.java @@ -16,8 +16,8 @@ package com.google.devtools.build.android.resources; import com.google.common.base.MoreObjects; import java.io.IOException; import java.io.Writer; +import java.util.Collection; import java.util.Objects; -import java.util.Set; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.commons.InstructionAdapter; @@ -63,7 +63,7 @@ public final class IntFieldInitializer implements FieldInitializer { } @Override - public boolean nameIsIn(Set<String> fieldNames) { + public boolean nameIsIn(Collection<String> fieldNames) { return fieldNames.contains(fieldName); } @@ -83,19 +83,23 @@ public final class IntFieldInitializer implements FieldInitializer { // IntFields will go before Intarrays return -1; } - + @Override public int hashCode() { return Objects.hash(fieldName, value); } - + @Override public boolean equals(Object obj) { if (obj instanceof IntFieldInitializer) { IntFieldInitializer other = (IntFieldInitializer) obj; - return Objects.equals(fieldName, other.fieldName) - && value == other.value; + return Objects.equals(fieldName, other.fieldName) && value == other.value; } return false; } + + @Override + public void addTo(Collection<String> fieldNames) { + fieldNames.add(fieldName); + } } diff --git a/src/tools/android/java/com/google/devtools/build/android/resources/RClassGenerator.java b/src/tools/android/java/com/google/devtools/build/android/resources/RClassGenerator.java index b36b752829..54375fab14 100644 --- a/src/tools/android/java/com/google/devtools/build/android/resources/RClassGenerator.java +++ b/src/tools/android/java/com/google/devtools/build/android/resources/RClassGenerator.java @@ -25,7 +25,6 @@ import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; @@ -80,8 +79,7 @@ public class RClassGenerator { * Builds bytecode and writes out R.class file, and R$inner.class files for provided package and * symbols. */ - public void write(String packageName, Map<ResourceType, Set<String>> symbolsToWrite) - throws IOException { + public void write(String packageName, FieldInitializers symbolsToWrite) throws IOException { writeClasses(packageName, initializers.filter(symbolsToWrite)); } @@ -103,7 +101,7 @@ public class RClassGenerator { // At least create the outFolder that was requested. However, if there are no symbols, don't // create the R.class and inner class files (no need to have an empty class). Files.createDirectories(packageDir); - + if (Iterables.isEmpty(initializersToWrite)) { return; } @@ -124,12 +122,11 @@ public class RClassGenerator { writeConstructor(classWriter); // Build the R.class w/ the inner classes, then later build the individual R$inner.class. for (Entry<ResourceType, Collection<FieldInitializer>> entry : initializersToWrite) { - final String resourceType = entry.getKey().toString(); - String innerClassName = rClassName + "$" + resourceType; + String innerClassName = rClassName + "$" + entry.getKey().toString(); classWriter.visitInnerClass( innerClassName, rClassName, - resourceType, + entry.getKey().toString(), Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC); } classWriter.visitEnd(); diff --git a/src/tools/android/java/com/google/devtools/build/android/resources/RSourceGenerator.java b/src/tools/android/java/com/google/devtools/build/android/resources/RSourceGenerator.java index e2d19b1c73..4c3ef8581f 100644 --- a/src/tools/android/java/com/google/devtools/build/android/resources/RSourceGenerator.java +++ b/src/tools/android/java/com/google/devtools/build/android/resources/RSourceGenerator.java @@ -23,9 +23,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collection; -import java.util.Map; import java.util.Map.Entry; -import java.util.Set; /** Writes out an R.java source. */ public class RSourceGenerator { @@ -48,23 +46,21 @@ public class RSourceGenerator { /** Writes the java source with the writer values to the specified package and derived dir. */ public void write(String packageName) throws IOException { - write(packageName, values); + writeSource(packageName, values); } /** * Writes the java source with the passed subset of the writer values. * - * @param packageName The package and the dir to write the R java source to under the output - * path. + * @param packageName The package and the dir to write the R java source to under the output path. * @param symbolsToWrite A map of ResourceType to resource name that will be written. If the map * specifies a resource that does not exist in the writer values, it will be ignored. */ - public void write(String packageName, Map<ResourceType, Set<String>> symbolsToWrite) - throws IOException { - write(packageName, values.filter(symbolsToWrite)); + public void write(String packageName, FieldInitializers symbolsToWrite) throws IOException { + writeSource(packageName, values.filter(symbolsToWrite)); } - private void write( + private void writeSource( String packageName, Iterable<Entry<ResourceType, Collection<FieldInitializer>>> initializersToWrite) throws IOException { diff --git a/src/tools/android/java/com/google/devtools/build/android/resources/ResourceSymbols.java b/src/tools/android/java/com/google/devtools/build/android/resources/ResourceSymbols.java index d18eceeca5..6b2dbcff7b 100644 --- a/src/tools/android/java/com/google/devtools/build/android/resources/ResourceSymbols.java +++ b/src/tools/android/java/com/google/devtools/build/android/resources/ResourceSymbols.java @@ -16,14 +16,10 @@ package com.google.devtools.build.android.resources; import com.android.builder.core.VariantConfiguration; import com.android.builder.dependency.SymbolFileProvider; import com.android.resources.ResourceType; -import com.android.utils.ILogger; -import com.google.common.base.Preconditions; -import com.google.common.collect.HashBasedTable; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import com.google.common.collect.MultimapBuilder; -import com.google.common.collect.SetMultimap; -import com.google.common.collect.Table; +import com.google.common.collect.SortedSetMultimap; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import java.io.File; @@ -32,57 +28,20 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collection; -import java.util.EnumMap; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; -import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.logging.Logger; import javax.annotation.Nullable; -/** This provides a unified interface for working with R.txt symbols files. */ +/** Encapsulates the logic for loading and writing resource symbols. */ public class ResourceSymbols { private static final Logger logger = Logger.getLogger(ResourceSymbols.class.getCanonicalName()); - /** Represents a resource symbol with a value. */ - // Forked from com.android.builder.internal.SymbolLoader.SymbolEntry. - static class RTxtSymbolEntry { - private final String name; - private final String type; - private final String value; - - RTxtSymbolEntry(String name, String type, String value) { - this.name = name; - this.type = type; - this.value = value; - } - - public String getValue() { - return value; - } - - public String getName() { - return name; - } - - public String getType() { - return type; - } - - public FieldInitializer toInitializer() { - if (type.equals("int")) { - return IntFieldInitializer.of(name, value); - } - Preconditions.checkArgument(type.equals("int[]")); - return IntArrayFieldInitializer.of(name, value); - } - } - /** Task to load and parse R.txt symbols */ private static final class SymbolLoadingTask implements Callable<ResourceSymbols> { @@ -96,7 +55,8 @@ public class ResourceSymbols { public ResourceSymbols call() throws Exception { List<String> lines = Files.readAllLines(rTxtSymbols, StandardCharsets.UTF_8); - Table<String, String, RTxtSymbolEntry> symbols = HashBasedTable.create(); + final SortedSetMultimap<ResourceType, FieldInitializer> initializers = + MultimapBuilder.enumKeys(ResourceType.class).treeSetValues().build(); for (int lineIndex = 1; lineIndex <= lines.size(); lineIndex++) { String line = null; @@ -113,7 +73,12 @@ public class ResourceSymbols { String name = line.substring(pos2 + 1, pos3); String value = line.substring(pos3 + 1); - symbols.put(className, name, new RTxtSymbolEntry(name, type, value)); + final ResourceType resourceType = ResourceType.getEnum(className); + if ("int".equals(type)) { + initializers.put(resourceType, IntFieldInitializer.of(name, value)); + } else { + initializers.put(resourceType, IntArrayFieldInitializer.of(name, value)); + } } catch (IndexOutOfBoundsException e) { String s = String.format( @@ -123,7 +88,7 @@ public class ResourceSymbols { throw new IOException(s, e); } } - return ResourceSymbols.from(symbols); + return ResourceSymbols.from(FieldInitializers.copyOf(initializers.asMap())); } } @@ -146,7 +111,6 @@ public class ResourceSymbols { * * @param dependencies The full set of library symbols to load. * @param executor The executor use during loading. - * @param iLogger Android logger to use. * @param packageToExclude A string package to elide if it exists in the providers. * @return A list of loading {@link ResourceSymbols} instances. * @throws ExecutionException @@ -155,7 +119,6 @@ public class ResourceSymbols { public static Multimap<String, ListenableFuture<ResourceSymbols>> loadFrom( Collection<SymbolFileProvider> dependencies, ListeningExecutorService executor, - ILogger iLogger, @Nullable String packageToExclude) throws InterruptedException, ExecutionException { Map<SymbolFileProvider, ListenableFuture<String>> providerToPackage = new HashMap<>(); @@ -173,16 +136,20 @@ public class ResourceSymbols { return packageToTable; } - public static ResourceSymbols from(Table<String, String, RTxtSymbolEntry> table) { - return new ResourceSymbols(table); + public static ResourceSymbols from(FieldInitializers fieldInitializers) { + return new ResourceSymbols(fieldInitializers); } public static ResourceSymbols merge(Collection<ResourceSymbols> symbolTables) { - final Table<String, String, RTxtSymbolEntry> mergedTable = HashBasedTable.create(); + final SortedSetMultimap<ResourceType, FieldInitializer> initializers = + MultimapBuilder.enumKeys(ResourceType.class).treeSetValues().build(); for (ResourceSymbols symbolTableProvider : symbolTables) { - mergedTable.putAll(symbolTableProvider.asTable()); + for (Entry<ResourceType, Collection<FieldInitializer>> entry : + symbolTableProvider.asInitializers()) { + initializers.putAll(entry.getKey(), entry.getValue()); + } } - return from(mergedTable); + return from(FieldInitializers.copyOf(initializers.asMap())); } /** Read the symbols from the provided symbol file. */ @@ -191,14 +158,10 @@ public class ResourceSymbols { return executorService.submit(new SymbolLoadingTask(primaryRTxt)); } - private final Table<String, String, RTxtSymbolEntry> values; + private final FieldInitializers values; - private ResourceSymbols(Table<String, String, RTxtSymbolEntry> values) { - this.values = values; - } - - public Table<String, String, RTxtSymbolEntry> asTable() { - return values; + private ResourceSymbols(FieldInitializers fieldInitializers) { + this.values = fieldInitializers; } /** @@ -216,39 +179,12 @@ public class ResourceSymbols { Collection<ResourceSymbols> packageSymbols, boolean finalFields) throws IOException { - - Map<ResourceType, Set<String>> symbols = new EnumMap<>(ResourceType.class); - for (ResourceSymbols packageSymbol : packageSymbols) { - symbols.putAll(packageSymbol.asFilterMap()); - } - RSourceGenerator.with(sourceOut, asInitializers(), finalFields).write(packageName, symbols); + RSourceGenerator.with(sourceOut, asInitializers(), finalFields) + .write(packageName, merge(packageSymbols).asInitializers()); } public FieldInitializers asInitializers() { - SetMultimap<ResourceType, FieldInitializer> valuesOut = - MultimapBuilder.enumKeys(ResourceType.class).treeSetValues().build(); - Table<String, String, RTxtSymbolEntry> symbolTable = asTable(); - for (String typeName : symbolTable.rowKeySet()) { - final ResourceType type = ResourceType.getEnum(typeName); - for (RTxtSymbolEntry symbolEntry : symbolTable.row(typeName).values()) { - valuesOut.put(type, symbolEntry.toInitializer()); - } - } - return FieldInitializers.copyOf(valuesOut.asMap()); + return values; } - public Map<ResourceType, Set<String>> asFilterMap() { - Map<ResourceType, Set<String>> filter = new EnumMap<>(ResourceType.class); - Table<String, String, RTxtSymbolEntry> symbolTable = asTable(); - for (String typeName : symbolTable.rowKeySet()) { - Set<String> fields = new HashSet<>(); - for (RTxtSymbolEntry symbolEntry : symbolTable.row(typeName).values()) { - fields.add(symbolEntry.getName()); - } - if (!fields.isEmpty()) { - filter.put(ResourceType.getEnum(typeName), fields); - } - } - return filter; - } } |