diff options
author | 2016-06-21 01:41:17 +0000 | |
---|---|---|
committer | 2016-06-21 09:59:19 +0000 | |
commit | 32c6c15c8b9bc4e203529f60bedbc5cd8a496a36 (patch) | |
tree | 12662ce5f6f786bcc79f7f241d0aa40f40f580e0 /src/tools/android/java/com/google/devtools/build/android/resources | |
parent | cecca155c50b2b58890c7b84448d72c28a0ee7cf (diff) |
Rollback of commit 1f1f207573c7b9c3e2d3ca1ffb0780a8fd592214.
*** Reason for rollback ***
Doesn't handle aapt that doesn't generate R.txt properly.
--
MOS_MIGRATED_REVID=125405481
Diffstat (limited to 'src/tools/android/java/com/google/devtools/build/android/resources')
-rw-r--r-- | src/tools/android/java/com/google/devtools/build/android/resources/BUILD | 24 | ||||
-rw-r--r-- | src/tools/android/java/com/google/devtools/build/android/resources/RClassWriter.java | 317 |
2 files changed, 0 insertions, 341 deletions
diff --git a/src/tools/android/java/com/google/devtools/build/android/resources/BUILD b/src/tools/android/java/com/google/devtools/build/android/resources/BUILD deleted file mode 100644 index c1d565e561..0000000000 --- a/src/tools/android/java/com/google/devtools/build/android/resources/BUILD +++ /dev/null @@ -1,24 +0,0 @@ -# Description: -# Tools for android resource processing - -package(default_visibility = [ - "//src/test/java/com/google/devtools/build/android/resources:__pkg__", - "//src/tools/android/java/com/google/devtools/build/android:__pkg__", -]) - -java_library( - name = "resources", - srcs = glob(["*.java"]), - deps = [ - "//third_party:android_common", - "//third_party:asm", - "//third_party:asm-commons", - "//third_party:guava", - ], -) - -filegroup( - name = "srcs", - srcs = glob(["**"]), - visibility = ["//src/tools/android/java/com/google/devtools/build/android:__pkg__"], -) diff --git a/src/tools/android/java/com/google/devtools/build/android/resources/RClassWriter.java b/src/tools/android/java/com/google/devtools/build/android/resources/RClassWriter.java deleted file mode 100644 index 53bb945dc1..0000000000 --- a/src/tools/android/java/com/google/devtools/build/android/resources/RClassWriter.java +++ /dev/null @@ -1,317 +0,0 @@ -// Copyright 2016 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -package com.google.devtools.build.android.resources; - -import com.google.common.base.Preconditions; -import com.google.common.base.Splitter; -import com.google.common.collect.HashBasedTable; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Table; -import com.google.common.io.Files; - -import com.android.SdkConstants; -import com.android.builder.internal.SymbolLoader; -import com.android.builder.internal.SymbolLoader.SymbolEntry; - -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.Type; -import org.objectweb.asm.commons.InstructionAdapter; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Writes out bytecode for an R.class directly, rather than go through an R.java and compile. This - * avoids re-parsing huge R.java files and other time spent in the java compiler (e.g., plugins like - * ErrorProne). A difference is that this doesn't generate line number tables and other debugging - * information. Also, the order of the constant pool tends to be different. - */ -public class RClassWriter { - - private static final int JAVA_VERSION = Opcodes.V1_7; - private static final String SUPER_CLASS = "java/lang/Object"; - private final File outFolder; - private final String packageName; - private final List<SymbolLoader> symbolTables = new ArrayList<>(); - private final SymbolLoader symbolValues; - private final boolean finalFields; - - public RClassWriter(File outFolder, - String packageName, - SymbolLoader values, - boolean finalFields) { - this.outFolder = outFolder; - this.packageName = packageName; - this.symbolValues = values; - this.finalFields = finalFields; - } - - public void addSymbolsToWrite(SymbolLoader symbols) { - symbolTables.add(symbols); - } - - private Table<String, String, SymbolEntry> getAllSymbols() throws IOException { - Table<String, String, SymbolEntry> symbols = HashBasedTable.create(); - for (SymbolLoader symbolLoader : symbolTables) { - symbols.putAll(getSymbols(symbolLoader)); - } - return symbols; - } - - private Method symbolsMethod; - - private Table<String, String, SymbolEntry> getSymbols(SymbolLoader symbolLoader) - throws IOException { - // TODO(bazel-team): upstream a patch to change the visibility instead of hacking it. - try { - if (symbolsMethod == null) { - Method getSymbols = SymbolLoader.class.getDeclaredMethod("getSymbols"); - getSymbols.setAccessible(true); - symbolsMethod = getSymbols; - } - @SuppressWarnings("unchecked") - Table<String, String, SymbolEntry> result = (Table<String, String, SymbolEntry>) - symbolsMethod.invoke(symbolLoader); - return result; - } catch (ReflectiveOperationException e) { - throw new IOException(e); - } - } - - /** - * Builds the bytecode and writes out the R.class file, and R$inner.class files. - */ - public void write() throws IOException { - Splitter splitter = Splitter.on('.'); - Iterable<String> folders = splitter.split(packageName); - File packageDir = outFolder; - for (String folder : folders) { - packageDir = new File(packageDir, folder); - } - File rClassFile = new File(packageDir, SdkConstants.FN_COMPILED_RESOURCE_CLASS); - Files.createParentDirs(rClassFile); - String packageWithSlashes = packageName.replaceAll("\\.", "/"); - String rClassName = packageWithSlashes + "/R"; - ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS); - classWriter - .visit(JAVA_VERSION, Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_SUPER, - rClassName, null, SUPER_CLASS, null); - classWriter.visitSource(SdkConstants.FN_RESOURCE_CLASS, null); - writeConstructor(classWriter); - - Table<String, String, SymbolEntry> symbols = getAllSymbols(); - Table<String, String, SymbolEntry> values = getSymbols(symbolValues); - - Set<String> rowSet = symbols.rowKeySet(); - List<String> rowList = new ArrayList<>(rowSet); - Collections.sort(rowList); - - // Build the R.class w/ the inner classes, then later build the individual R$inner.class. - for (String row : rowList) { - String innerClassName = rClassName + "$" + row; - classWriter.visitInnerClass(innerClassName, rClassName, row, - Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC); - } - classWriter.visitEnd(); - Files.write(classWriter.toByteArray(), rClassFile); - - // Now generate the R$inner.class files. - for (String row : rowList) { - writeInnerClass(symbols, values, packageDir, rClassName, row); - } - } - - /** - * Represents an int or int[] field and its initializer (where initialization is done via code in - * the static clinit function). - */ - private interface DeferredInitializer { - - /** - * Write the code for the initializer via insts. - * - * @return the number of stack slots needed for the code. - */ - int writeCLInit(String className, InstructionAdapter insts); - } - - private static final class IntArrayDeferredInitializer implements DeferredInitializer { - - private final String fieldName; - private final ImmutableList<Integer> values; - - IntArrayDeferredInitializer(String fieldName, ImmutableList<Integer> values) { - this.fieldName = fieldName; - this.values = values; - } - - public static DeferredInitializer of(String name, String value) { - Preconditions.checkArgument(value.startsWith("{ "), "Expected list starting with { "); - Preconditions.checkArgument(value.endsWith(" }"), "Expected list ending with } "); - // Check for an empty list, which is "{ }". - if (value.length() < 4) { - return new IntArrayDeferredInitializer(name, ImmutableList.<Integer>of()); - } - ImmutableList.Builder<Integer> intValues = ImmutableList.builder(); - String trimmedValue = value.substring(2, value.length() - 2); - Iterable<String> valueStrings = Splitter.on(',') - .trimResults() - .omitEmptyStrings() - .split(trimmedValue); - for (String valueString : valueStrings) { - intValues.add(Integer.decode(valueString)); - } - return new IntArrayDeferredInitializer(name, intValues.build()); - } - - @Override - public int writeCLInit(String className, InstructionAdapter insts) { - insts.iconst(values.size()); - insts.newarray(Type.INT_TYPE); - int curIndex = 0; - for (Integer value : values) { - insts.dup(); - insts.iconst(curIndex); - insts.iconst(value); - insts.astore(Type.INT_TYPE); - ++curIndex; - } - insts.putstatic(className, fieldName, "[I"); - // Needs up to 4 stack slots for: the array ref for the putstatic, the dup of the array ref - // for the store, the index, and the value to store. - return 4; - } - } - - private static final class IntDeferredInitializer implements DeferredInitializer { - - private final String fieldName; - private final Integer value; - - IntDeferredInitializer(String fieldName, Integer value) { - this.fieldName = fieldName; - this.value = value; - } - - public static DeferredInitializer of(String name, String value) { - return new IntDeferredInitializer(name, Integer.decode(value)); - } - - @Override - public int writeCLInit(String className, InstructionAdapter insts) { - insts.iconst(value); - insts.putstatic(className, fieldName, "I"); - // Just needs one stack slot for the iconst. - return 1; - } - } - - private void writeInnerClass( - Table<String, String, SymbolEntry> symbols, - Table<String, String, SymbolEntry> values, - File packageDir, - String fullyQualifiedOuterClass, - String innerClass) throws IOException { - ClassWriter innerClassWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS); - String fullyQualifiedInnerClass = fullyQualifiedOuterClass + "$" + innerClass; - innerClassWriter - .visit(JAVA_VERSION, Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_SUPER, - fullyQualifiedInnerClass, null, SUPER_CLASS, null); - innerClassWriter.visitSource("R.java", null); - writeConstructor(innerClassWriter); - innerClassWriter.visitInnerClass( - fullyQualifiedInnerClass, fullyQualifiedOuterClass, innerClass, - Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC); - - Map<String, SymbolEntry> rowMap = symbols.row(innerClass); - Set<String> symbolSet = rowMap.keySet(); - List<String> symbolList = new ArrayList<>(symbolSet); - Collections.sort(symbolList); - List<DeferredInitializer> deferredInitializers = new ArrayList<>(); - int fieldAccessLevel = Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC; - if (finalFields) { - fieldAccessLevel |= Opcodes.ACC_FINAL; - } - for (String symbolName : symbolList) { - // get the matching SymbolEntry from the values Table. - SymbolEntry value = values.get(innerClass, symbolName); - if (value != null) { - String desc; - Object initializer = null; - if (value.getType().equals("int")) { - desc = "I"; - if (finalFields) { - initializer = Integer.decode(value.getValue()); - } else { - deferredInitializers.add(IntDeferredInitializer.of(value.getName(), value.getValue())); - } - } else { - Preconditions.checkArgument(value.getType().equals("int[]")); - desc = "[I"; - deferredInitializers - .add(IntArrayDeferredInitializer.of(value.getName(), value.getValue())); - } - innerClassWriter - .visitField(fieldAccessLevel, value.getName(), desc, null, initializer) - .visitEnd(); - } - } - - if (!deferredInitializers.isEmpty()) { - // build the <clinit> method. - writeStaticClassInit(innerClassWriter, fullyQualifiedInnerClass, deferredInitializers); - } - - innerClassWriter.visitEnd(); - File innerFile = new File(packageDir, "R$" + innerClass + ".class"); - Files.write(innerClassWriter.toByteArray(), innerFile); - } - - private static void writeConstructor(ClassWriter classWriter) { - MethodVisitor constructor = classWriter.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", - null, null); - constructor.visitCode(); - constructor.visitVarInsn(Opcodes.ALOAD, 0); - constructor.visitMethodInsn(Opcodes.INVOKESPECIAL, SUPER_CLASS, "<init>", "()V", false); - constructor.visitInsn(Opcodes.RETURN); - constructor.visitMaxs(1, 1); - constructor.visitEnd(); - } - - private static void writeStaticClassInit( - ClassWriter classWriter, - String className, - List<DeferredInitializer> deferredInitializers) { - MethodVisitor visitor = classWriter.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", - null, null); - visitor.visitCode(); - int stackSlotsNeeded = 0; - InstructionAdapter insts = new InstructionAdapter(visitor); - for (DeferredInitializer fieldInit : deferredInitializers) { - stackSlotsNeeded = Math.max(stackSlotsNeeded, fieldInit.writeCLInit(className, insts)); - } - insts.areturn(Type.VOID_TYPE); - visitor.visitMaxs(stackSlotsNeeded, 0); - visitor.visitEnd(); - } - -} |