am 5eafc91a: Merge "merge "SDK: make \'mkstub\' less verbose." from HC. Do not merge." into gingerbread

* commit '5eafc91ad3216561d2287f327580644fb1e04cfb':
  merge "SDK: make 'mkstub' less verbose." from HC. Do not merge.
This commit is contained in:
Raphael
2011-02-04 14:49:19 -08:00
committed by Android Git Automerger
6 changed files with 168 additions and 65 deletions

View File

@@ -16,6 +16,8 @@
package com.android.mkstubs;
import com.android.mkstubs.Main.Logger;
import org.objectweb.asm.ClassReader;
import java.io.IOException;
@@ -76,8 +78,9 @@ class AsmAnalyzer {
* @param classes The in-out map of classes to examine and filter. The map is filtered
* in-place.
* @param filter A filter describing which classes to include and which ones to exclude.
* @param log
*/
void filter(Map<String, ClassReader> classes, Filter filter) {
void filter(Map<String, ClassReader> classes, Filter filter, Logger log) {
Set<String> keys = classes.keySet();
for(Iterator<String> it = keys.iterator(); it.hasNext(); ) {
@@ -87,7 +90,7 @@ class AsmAnalyzer {
// remove if we don't keep it
if (!filter.accept(key)) {
System.out.println("- Remove class " + key);
log.debug("- Remove class " + key);
it.remove();
}
}

View File

@@ -16,6 +16,8 @@
package com.android.mkstubs;
import com.android.mkstubs.Main.Logger;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassAdapter;
@@ -30,12 +32,14 @@ import org.objectweb.asm.Opcodes;
*/
class FilterClassAdapter extends ClassAdapter {
private final Logger mLog;
private final Filter mFilter;
private String mClassName;
public FilterClassAdapter(ClassVisitor writer, Filter filter) {
public FilterClassAdapter(ClassVisitor writer, Filter filter, Logger log) {
super(writer);
mFilter = filter;
mLog = log;
}
@Override
@@ -73,7 +77,7 @@ class FilterClassAdapter extends ClassAdapter {
String filterName = String.format("%s#%s", mClassName, name);
if (!mFilter.accept(filterName)) {
System.out.println("- Remove field " + filterName);
mLog.debug("- Remove field " + filterName);
return null;
}
@@ -105,7 +109,7 @@ class FilterClassAdapter extends ClassAdapter {
String filterName = String.format("%s#%s%s", mClassName, name, desc);
if (!mFilter.accept(filterName)) {
System.out.println("- Remove method " + filterName);
mLog.debug("- Remove method " + filterName);
return null;
}
@@ -114,7 +118,7 @@ class FilterClassAdapter extends ClassAdapter {
filterName = String.format("%s#%s%s", mClassName, name, signature);
if (!mFilter.accept(filterName)) {
System.out.println("- Remove method " + filterName);
mLog.debug("- Remove method " + filterName);
return null;
}
}

View File

@@ -16,6 +16,8 @@
package com.android.mkstubs;
import com.android.mkstubs.Main.Params;
import org.objectweb.asm.ClassReader;
import java.io.BufferedReader;
@@ -39,13 +41,23 @@ public class Main {
private String mInputJarPath;
private String mOutputJarPath;
private Filter mFilter;
private boolean mVerbose;
private boolean mDumpSource;
public Params(String inputJarPath, String outputJarPath) {
mInputJarPath = inputJarPath;
mOutputJarPath = outputJarPath;
public Params() {
mFilter = new Filter();
}
/** Sets the name of the input jar, where to read classes from. Must not be null. */
public void setInputJarPath(String inputJarPath) {
mInputJarPath = inputJarPath;
}
/** Sets the name of the output jar, where to write classes to. Must not be null. */
public void setOutputJarPath(String outputJarPath) {
mOutputJarPath = outputJarPath;
}
/** Returns the name of the input jar, where to read classes from. */
public String getInputJarPath() {
return mInputJarPath;
@@ -60,13 +72,53 @@ public class Main {
public Filter getFilter() {
return mFilter;
}
/** Sets verbose mode on. Default is off. */
public void setVerbose() {
mVerbose = true;
}
/** Returns true if verbose mode is on. */
public boolean isVerbose() {
return mVerbose;
}
/** Sets dump source mode on. Default is off. */
public void setDumpSource() {
mDumpSource = true;
}
/** Returns true if source should be dumped. */
public boolean isDumpSource() {
return mDumpSource;
}
}
/** Logger that writes on stdout depending a conditional verbose mode. */
static class Logger {
private final boolean mVerbose;
public Logger(boolean verbose) {
mVerbose = verbose;
}
/** Writes to stdout only in verbose mode. */
public void debug(String msg, Object...params) {
if (mVerbose) {
System.out.println(String.format(msg, params));
}
}
/** Writes to stdout all the time. */
public void info(String msg, Object...params) {
System.out.println(String.format(msg, params));
}
}
/**
* Main entry point. Processes arguments then performs the "real" work.
*/
public static void main(String[] args) {
Main m = new Main();
try {
Params p = m.processArgs(args);
@@ -88,15 +140,30 @@ public class Main {
* @throws IOException on failure to read a pattern file.
*/
private Params processArgs(String[] args) throws IOException {
Params p = new Params();
if (args.length < 2) {
usage();
for (String arg : args) {
if (arg.startsWith("--")) {
if (arg.startsWith("--v")) {
p.setVerbose();
} else if (arg.startsWith("--s")) {
p.setDumpSource();
} else if (arg.startsWith("--h")) {
usage(null);
} else {
usage("Unknown argument: " + arg);
}
} else if (p.getInputJarPath() == null) {
p.setInputJarPath(arg);
} else if (p.getOutputJarPath() == null) {
p.setOutputJarPath(arg);
} else {
addString(p, arg);
}
}
Params p = new Params(args[0], args[1]);
for (int i = 2; i < args.length; i++) {
addString(p, args[i]);
if (p.getInputJarPath() == null && p.getOutputJarPath() == null) {
usage("Missing input or output JAR.");
}
return p;
@@ -179,9 +246,19 @@ public class Main {
/**
* Prints some help to stdout.
* @param error The error that generated the usage, if any. Can be null.
*/
private void usage() {
System.out.println("Usage: mkstub input.jar output.jar [excluded-class @excluded-classes-file ...]");
private void usage(String error) {
if (error != null) {
System.out.println("ERROR: " + error);
}
System.out.println("Usage: mkstub [--h|--s|--v] input.jar output.jar [excluded-class @excluded-classes-file ...]");
System.out.println("Options:\n" +
" --h | --help : print this usage.\n" +
" --v | --verbose : verbose mode.\n" +
" --s | --source : dump source equivalent to modified byte code.\n\n");
System.out.println("Include syntax:\n" +
"+com.package.* : whole package, with glob\n" +
@@ -193,6 +270,7 @@ public class Main {
"-com.package.Class[$Inner] or ...Class*: whole classes with optional glob\n" +
"-com.package.Class#method: whole method or field\n" +
"-com.package.Class#method(IILjava/lang/String;)V: specific method with signature.\n\n");
System.exit(1);
}
@@ -211,20 +289,22 @@ public class Main {
AsmAnalyzer aa = new AsmAnalyzer();
Map<String, ClassReader> classes = aa.parseInputJar(p.getInputJarPath());
System.out.println(String.format("Classes loaded: %d", classes.size()));
Logger log = new Logger(p.isVerbose());
log.info("Classes loaded: %d", classes.size());
aa.filter(classes, p.getFilter());
System.out.println(String.format("Classes filtered: %d", classes.size()));
aa.filter(classes, p.getFilter(), log);
log.info("Classes filtered: %d", classes.size());
// dump as Java source files, mostly for debugging
SourceGenerator src_gen = new SourceGenerator();
File dst_src_dir = new File(p.getOutputJarPath() + "_sources");
dst_src_dir.mkdir();
src_gen.generateSource(dst_src_dir, classes, p.getFilter());
if (p.isDumpSource()) {
SourceGenerator src_gen = new SourceGenerator(log);
File dst_src_dir = new File(p.getOutputJarPath() + "_sources");
dst_src_dir.mkdir();
src_gen.generateSource(dst_src_dir, classes, p.getFilter());
}
// dump the stubbed jar
StubGenerator stub_gen = new StubGenerator();
StubGenerator stub_gen = new StubGenerator(log);
File dst_jar = new File(p.getOutputJarPath());
stub_gen.generateStubbedJar(dst_jar, classes, p.getFilter());
}

View File

@@ -16,6 +16,7 @@
package com.android.mkstubs;
import com.android.mkstubs.Main.Logger;
import com.android.mkstubs.sourcer.ClassSourcer;
import com.android.mkstubs.sourcer.Output;
@@ -38,6 +39,12 @@ import java.util.Map.Entry;
*/
class SourceGenerator {
private Logger mLog;
public SourceGenerator(Logger log) {
mLog = log;
}
/**
* Generate source for the stubbed classes, mostly for debug purposes.
* @throws IOException
@@ -65,7 +72,7 @@ class SourceGenerator {
File f = new File(baseDir, name);
f.getParentFile().mkdirs();
System.out.println("Writing " + f.getPath());
mLog.debug("Writing " + f.getPath());
return new FileWriter(f);
}
@@ -83,10 +90,10 @@ class SourceGenerator {
* minus all exclusions
*/
void visitClassSource(Writer fw, ClassReader cr, Filter filter) {
System.out.println("Dump " + cr.getClassName());
mLog.debug("Dump " + cr.getClassName());
ClassVisitor javaWriter = new ClassSourcer(new Output(fw));
ClassVisitor classFilter = new FilterClassAdapter(javaWriter, filter);
ClassVisitor classFilter = new FilterClassAdapter(javaWriter, filter, mLog);
cr.accept(classFilter, 0 /*flags*/);
}

View File

@@ -16,6 +16,7 @@
package com.android.mkstubs;
import com.android.mkstubs.Main.Logger;
import com.android.mkstubs.stubber.ClassStubber;
import org.objectweb.asm.ClassReader;
@@ -26,8 +27,8 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
@@ -40,6 +41,12 @@ import java.util.jar.JarOutputStream;
*/
class StubGenerator {
private Logger mLog;
public StubGenerator(Logger log) {
mLog = log;
}
/**
* Generate source for the stubbed classes, mostly for debug purposes.
* @throws IOException
@@ -60,7 +67,7 @@ class StubGenerator {
createJar(new FileOutputStream(destJar), all);
System.out.println(String.format("Wrote %s", destJar.getPath()));
mLog.debug("Wrote %s", destJar.getPath());
}
/**
@@ -92,14 +99,14 @@ class StubGenerator {
}
byte[] visitClassStubber(ClassReader cr, Filter filter) {
System.out.println("Stub " + cr.getClassName());
mLog.debug("Stub " + cr.getClassName());
// Rewrite the new class from scratch, without reusing the constant pool from the
// original class reader.
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
ClassVisitor stubWriter = new ClassStubber(cw);
ClassVisitor classFilter = new FilterClassAdapter(stubWriter, filter);
ClassVisitor classFilter = new FilterClassAdapter(stubWriter, filter, mLog);
cr.accept(classFilter, 0 /*flags*/);
return cw.toByteArray();
}

View File

@@ -17,6 +17,8 @@
package com.android.mkstubs;
import com.android.mkstubs.Main.Logger;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@@ -34,7 +36,7 @@ public class SourceGeneratorTest {
@Before
public void setUp() throws Exception {
mGen = new SourceGenerator();
mGen = new SourceGenerator(new Logger(false));
}
@After