AI 145983: am: CL 145911 ADT #1778786: tool to generate stubbed jar file.

This is only a preliminary CL. More will follow but this is
  a good start, with the following caveats:
  What it does:
  - take an input jar, a list of includes, a list of excludes.
  - generate actual Java source for the filtered classes.
  What it doesn't do yet:
  - some more work on filtering inner elements (methods, etc.)
  - properly generate inner classes.
  - hide synthetic fields.
  - some classes body are missing
  - directly generate a stubbed bytecode/jar rather than source.
  I'll likely want to keep the source generator for debugging
  purposes or if we want to integrate with a build system instead.
  - classpath will be changed in the final CL to refer to the external
  ASM lib rather than the project. I need the source for debugging
  rigth now.
  - will review comments before submitting.
  Original author: raphael
  Merged from: //branches/cupcake/...

Automated import of CL 145983
This commit is contained in:
Raphael Moll
2009-04-13 18:21:16 -07:00
committed by The Android Open Source Project
parent ca7264c7b7
commit 1297169e09
26 changed files with 2337 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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.android.mkstubs;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.objectweb.asm.ClassReader;
import java.io.StringWriter;
import java.util.ArrayList;
/**
*
*/
public class AsmGeneratorTest {
private AsmGenerator mGen;
@Before
public void setUp() throws Exception {
mGen = new AsmGenerator();
}
@After
public void tearDown() throws Exception {
}
@Test
public void testDumpClass() throws Exception {
StringWriter sw = new StringWriter();
ClassReader cr = new ClassReader("data/TestBaseClass");
mGen.dumpClass(sw, cr, new ArrayList<String>());
String s = sw.toString();
Assert.assertNotNull(s);
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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.android.mkstubs;
import org.junit.After;
import org.junit.Before;
public class FilterClassAdapterTest {
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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.android.mkstubs.sourcer;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.objectweb.asm.Opcodes;
import java.io.StringWriter;
public class AccessSourcerTest {
private StringWriter mWriter;
private AccessSourcer mSourcer;
@Before
public void setUp() throws Exception {
mWriter = new StringWriter();
mSourcer = new AccessSourcer(new Output(mWriter));
}
@After
public void tearDown() throws Exception {
mWriter = null;
mSourcer = null;
}
@Test
public void testAbstractPublic() throws Exception {
mSourcer.write(Opcodes.ACC_ABSTRACT | Opcodes.ACC_PUBLIC, AccessSourcer.IS_CLASS);
String s = mWriter.toString();
Assert.assertEquals("public abstract", s);
}
@Test
public void testPrivateFinalStatic() throws Exception {
mSourcer.write(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC,
AccessSourcer.IS_METHOD);
String s = mWriter.toString();
Assert.assertEquals("private static final", s);
}
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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.android.mkstubs.sourcer;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.objectweb.asm.Opcodes;
import java.io.StringWriter;
/**
*
*/
public class FieldSourcerTest {
private StringWriter mWriter;
@Before
public void setUp() throws Exception {
mWriter = new StringWriter();
}
@After
public void tearDown() throws Exception {
mWriter = null;
}
@Test
public void testStringField() throws Exception {
FieldSourcer fs = new FieldSourcer(new Output(mWriter),
Opcodes.ACC_PUBLIC, // access
"mArg", // name
"Ljava/lang/String;", // desc
null // signature
);
fs.visitEnd();
String s = mWriter.toString();
Assert.assertEquals("public java.lang.String mArg;\n", s);
}
@Test
public void testTemplateTypeField() throws Exception {
FieldSourcer fs = new FieldSourcer(new Output(mWriter),
Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, // access
"mList", // name
"Ljava/util/ArrayList;", // desc
"Ljava/util/ArrayList<Ljava/lang/String;>;" // signature
);
fs.visitEnd();
String s = mWriter.toString();
Assert.assertEquals("private final java.util.ArrayList<java.lang.String> mList;\n", s);
}
}

View File

@@ -0,0 +1,139 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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.android.mkstubs.sourcer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.objectweb.asm.ClassReader;
import java.io.StringWriter;
/**
*
*/
public class JavaSourcerTest extends TestHelper {
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() throws Exception {
}
@Test
public void testBaseClassSource() throws Exception {
StringWriter sw = new StringWriter();
ClassReader cr = new ClassReader("data/TestBaseClass");
JavaSourcer jw = new JavaSourcer(new Output(sw));
cr.accept(jw, 0);
assertSourceEquals(
"package data;\n" +
"public class TestBaseClass extends java.lang.Object implements java.lang.Runnable {\n" +
"\n" +
" private final java.lang.String mArg;\n" +
" \n" +
" public TestBaseClass() {\n" +
" throw new RuntimeException(\"Stub\");" +
" }\n" +
" public TestBaseClass(java.lang.String arg0) {\n" +
" throw new RuntimeException(\"Stub\");" +
" }\n" +
" public java.lang.String getArg() {\n" +
" throw new RuntimeException(\"Stub\");" +
" }\n" +
" public void run() {\n" +
" throw new RuntimeException(\"Stub\");" +
" }\n" +
"}",
sw.toString());
}
@Test
public void testInnerClassSource() throws Exception {
StringWriter sw = new StringWriter();
ClassReader cr = new ClassReader("data/TestInnerClass");
JavaSourcer jw = new JavaSourcer(new Output(sw));
cr.accept(jw, 0);
assertSourceEquals(
"package data;\n" +
"public class TestInnerClass extends java.lang.Object {\n" +
" private final java.lang.String mArg;\n" +
" public TestInnerClass() {\n" +
" throw new RuntimeException(\"Stub\");\n" +
" }\n" +
" public TestInnerClass(java.lang.String arg0) {\n" +
" throw new RuntimeException(\"Stub\");\n" +
" }\n" +
" public java.lang.String getArg() {\n" +
" throw new RuntimeException(\"Stub\");\n" +
" }\n" +
" public data.TestInnerClass$InnerPubClass getInnerPubClass() {\n" +
" throw new RuntimeException(\"Stub\");\n" +
" }\n" +
"}",
sw.toString());
}
@Test
public void testTemplateClassSource() throws Exception {
StringWriter sw = new StringWriter();
ClassReader cr = new ClassReader("data/TestTemplateClass");
JavaSourcer jw = new JavaSourcer(new Output(sw));
cr.accept(jw, 0);
assertSourceEquals(
"package data;\n" +
"public class TestTemplateClass<T extends java.io.InputStream, U extends java.lang.Object> extends java.lang.Object {\n" +
" private final java.util.Map<T, U> mMap_T_U;\n" +
" public java.util.Map<java.util.ArrayList<T>, java.util.Map<java.lang.String, java.util.ArrayList<U>>> mMap_T_S_U;\n" +
" public TestTemplateClass() {\n" +
" throw new RuntimeException(\"Stub\");\n" +
" }\n" +
" public java.util.Map<T, U> getMap_T_U() {\n" +
" throw new RuntimeException(\"Stub\");\n" +
" }\n" +
" public java.util.Map<java.util.ArrayList<T>, java.util.Map<java.lang.String, java.util.ArrayList<U>>> getMap_T_S_U() {\n" +
" throw new RuntimeException(\"Stub\");\n" +
" }\n" +
" public void draw(java.util.List<? extends org.w3c.dom.css.Rect> arg0) {\n" +
" throw new RuntimeException(\"Stub\");\n" +
" }\n" +
" public static <T extends java.lang.Comparable<? super T>> void sort(java.util.List<T> arg0) {\n" +
" throw new RuntimeException(\"Stub\");\n" +
" }\n" +
" public <X extends T, Y extends java.lang.Object> void getMap(java.util.List<T> arg0, java.util.Map<T, U> arg1, java.util.Map<X, java.util.Set<? super Y>> arg2) {\n" +
" throw new RuntimeException(\"Stub\");\n" +
" }\n" +
"}",
sw.toString());
}
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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.android.mkstubs.sourcer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.objectweb.asm.Opcodes;
import java.io.StringWriter;
/**
*
*/
public class MethodSourcerTest extends TestHelper {
private StringWriter mWriter;
private Output mOutput;
@Before
public void setUp() throws Exception {
mWriter = new StringWriter();
mOutput = new Output(mWriter);
}
@After
public void tearDown() throws Exception {
mWriter = null;
}
@Test
public void testVoid() {
MethodSourcer m = new MethodSourcer(mOutput,
"foo", //classname
Opcodes.ACC_PUBLIC, //access
"testVoid", //name
"()V", //desc
null, //signature
null); //exception
m.visitEnd();
assertSourceEquals(
"public void testVoid() { }",
mWriter.toString());
}
@Test
public void testVoidThrow() {
MethodSourcer m = new MethodSourcer(mOutput,
"foo", //classname
Opcodes.ACC_PUBLIC, //access
"testVoid", //name
"()V", //desc
null, //signature
new String[] { "java/lang/Exception" }); //exception
m.visitEnd();
assertSourceEquals(
"public void testVoid() throws java.lang.Exception { }",
mWriter.toString());
}
@Test
public void testReturnMap() {
MethodSourcer m = new MethodSourcer(mOutput,
"foo", //classname
Opcodes.ACC_PUBLIC, //access
"getMap_T_U", //name
"()Ljava/util/Map;", //desc
"()Ljava/util/Map<TT;TU;>;", //signature
null); //exception
m.visitEnd();
assertSourceEquals(
"public java.util.Map<T, U> getMap_T_U() { }",
mWriter.toString());
}
}

View File

@@ -0,0 +1,146 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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.android.mkstubs.sourcer;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.objectweb.asm.signature.SignatureReader;
import java.util.ArrayList;
/**
*
*/
public class SignatureSourcerTest {
private SignatureSourcer mSourcer;
@Before
public void setUp() throws Exception {
mSourcer = new SignatureSourcer();
}
@After
public void tearDown() throws Exception {
}
@Test
public void testReturnMapNoArgs() {
SignatureReader reader = new SignatureReader(
"()Ljava/util/Map<Ljava/util/ArrayList<TT;>;Ljava/util/Map<Ljava/lang/String;Ljava/util/ArrayList<TU;>;>;>;");
reader.accept(mSourcer);
String result = mSourcer.getReturnType().toString();
Assert.assertEquals(
"java.util.Map<java.util.ArrayList<T>, java.util.Map<java.lang.String, java.util.ArrayList<U>>>",
result);
}
@Test
public void testReturnVoid() {
SignatureReader reader = new SignatureReader(
"(Ljava/util/List<+Lorg/w3c/dom/css/Rect;>;)V");
reader.accept(mSourcer);
String result = mSourcer.getReturnType().toString();
Assert.assertEquals(
"void",
result);
}
@Test
public void testSimpleArg() {
SignatureReader reader = new SignatureReader(
"(Ljava/util/List<+Lorg/w3c/dom/css/Rect;>;)V");
reader.accept(mSourcer);
ArrayList<SignatureSourcer> params = mSourcer.getParameters();
Assert.assertNotNull(params);
String[] array = toStringArray(params);
Assert.assertArrayEquals(
new String[] { "java.util.List<? extends org.w3c.dom.css.Rect>" },
array);
}
@Test
public void testFormalParameters1() {
SignatureReader reader = new SignatureReader("<X:TT;Y:Ljava/lang/Object;>()V");
reader.accept(mSourcer);
Assert.assertTrue(mSourcer.hasFormalsContent());
String result = mSourcer.formalsToString();
Assert.assertEquals(
"<X extends T, Y extends java.lang.Object>",
result);
}
@Test
public void testFormalParameters2() {
SignatureReader reader = new SignatureReader("<T::Ljava/lang/Comparable<-TT;>;>(Ljava/util/List<TT;>;)V");
reader.accept(mSourcer);
Assert.assertTrue(mSourcer.hasFormalsContent());
String result = mSourcer.formalsToString();
Assert.assertEquals(
"<T extends java.lang.Comparable<? super T>>",
result);
}
@Test
public void testManyArgs() {
SignatureReader reader = new SignatureReader(
"<X:TT;Y:Ljava/lang/Object;>(Ljava/util/List<TT;>;Ljava/util/Map<TT;TU;>;Ljava/util/Map<TX;Ljava/util/Set<-TY;>;>;)V");
reader.accept(mSourcer);
Assert.assertTrue(mSourcer.hasFormalsContent());
String formals = mSourcer.formalsToString();
Assert.assertEquals(
"<X extends T, Y extends java.lang.Object>",
formals);
String result = mSourcer.getReturnType().toString();
Assert.assertEquals(
"void",
result);
ArrayList<SignatureSourcer> params = mSourcer.getParameters();
Assert.assertNotNull(params);
String[] array = toStringArray(params);
Assert.assertArrayEquals(
new String[] { "java.util.List<T>",
"java.util.Map<T, U>",
"java.util.Map<X, java.util.Set<? super Y>>" },
array);
}
private String[] toStringArray(ArrayList<?> params) {
String[] array = new String[params.size()];
for (int i = 0; i < params.size(); i++) {
array[i] = params.get(i).toString();
}
return array;
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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.android.mkstubs.sourcer;
import org.junit.Assert;
/**
*
*/
abstract class TestHelper {
/**
* Test source equality after normalizing all whitespace.
*/
public void assertSourceEquals(String expected, String actual) {
String en = expected.replaceAll("[\\s]+", " ").trim();
String an = actual.replaceAll( "[\\s]+", " ").trim();
Assert.assertEquals(
String.format("Source comparison failure: expected:<%s> but was:<%s>", expected, actual),
en, an);
}
}