Author: [email protected]
Date: Wed Jul 1 08:34:40 2009
New Revision: 5656
Added:
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/CollectReferencesVisitorTest.java
Modified:
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/CollectClassData.java
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/CollectReferencesVisitor.java
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/AsmTestCase.java
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/CollectClassDataTest.java
Log:
Add ASM visitor tests.
Modified:
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/CollectClassData.java
==============================================================================
---
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/CollectClassData.java
(original)
+++
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/CollectClassData.java
Wed Jul 1 08:34:40 2009
@@ -20,7 +20,6 @@
import com.google.gwt.dev.asm.MethodVisitor;
import com.google.gwt.dev.asm.Opcodes;
import com.google.gwt.dev.asm.commons.EmptyVisitor;
-import com.google.gwt.dev.resource.Resource;
import com.google.gwt.dev.util.Name;
import java.util.ArrayList;
@@ -134,7 +133,9 @@
private List<CollectAnnotationData> annotations = new
ArrayList<CollectAnnotationData>();
private String source = null;
- private List<Resource> innerClasses = new ArrayList<Resource>();
+
+ // TODO(jat): do we need to collect inner classes?
+// private List<Resource> innerClasses = new ArrayList<Resource>();
// internal name
private String name;
@@ -194,12 +195,12 @@
return fields;
}
- /**
- * @return the innerClasses
- */
- public List<Resource> getInnerClasses() {
- return innerClasses;
- }
+// /**
+// * @return the innerClasses
+// */
+// public List<Resource> getInnerClasses() {
+// return innerClasses;
+// }
/**
* @return the interfaces
Modified:
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/CollectReferencesVisitor.java
==============================================================================
---
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/CollectReferencesVisitor.java
(original)
+++
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/CollectReferencesVisitor.java
Wed Jul 1 08:34:40 2009
@@ -15,10 +15,13 @@
*/
package com.google.gwt.dev.javac.asm;
+import com.google.gwt.dev.asm.AnnotationVisitor;
import com.google.gwt.dev.asm.FieldVisitor;
import com.google.gwt.dev.asm.MethodVisitor;
import com.google.gwt.dev.asm.Type;
import com.google.gwt.dev.asm.commons.EmptyVisitor;
+import com.google.gwt.dev.asm.signature.SignatureReader;
+import com.google.gwt.dev.asm.signature.SignatureVisitor;
import java.util.HashSet;
import java.util.Set;
@@ -27,22 +30,80 @@
* Collect all the types which are referenced by a particular class.
*/
public class CollectReferencesVisitor extends EmptyVisitor {
- // TODO(jat): support annotation types, types in generic signatures
- private static final EmptyVisitor emptyVisitor = new EmptyVisitor();
-
+ /**
+ * Collect type names from generic signatures.
+ *
+ * All we care about is picking up type names, so we just return
ourselves
+ * for nested visitors.
+ */
+ private class CollectGenericTypes implements SignatureVisitor {
+ public SignatureVisitor visitArrayType() {
+ return this;
+ }
+
+ public void visitBaseType(char descriptor) {
+ }
+
+ public SignatureVisitor visitClassBound() {
+ return this;
+ }
+
+ public void visitClassType(String name) {
+ referencedTypes.add(name);
+ }
+
+ public void visitEnd() {
+ }
+
+ public SignatureVisitor visitExceptionType() {
+ return this;
+ }
+
+ public void visitFormalTypeParameter(String name) {
+ }
+
+ public void visitInnerClassType(String name) {
+ }
+
+ public SignatureVisitor visitInterface() {
+ return this;
+ }
+
+ public SignatureVisitor visitInterfaceBound() {
+ return this;
+ }
+
+ public SignatureVisitor visitParameterType() {
+ return this;
+ }
+
+ public SignatureVisitor visitReturnType() {
+ return this;
+ }
+
+ public SignatureVisitor visitSuperclass() {
+ return this;
+ }
+
+ public void visitTypeArgument() {
+ }
+
+ public SignatureVisitor visitTypeArgument(char wildcard) {
+ return this;
+ }
+
+ public void visitTypeVariable(String name) {
+ }
+ }
+
// internal names
- private Set<String> referencedTypes = new HashSet<String>();
+ protected Set<String> referencedTypes = new HashSet<String>();
public Set<String> getReferencedTypes() {
return referencedTypes;
}
- /**
- * @param name internal name of the class
- * @param superName internal name of the super class
- * @param interfaces array of internal names of implemented interfaces
- */
@Override
public void visit(int version, int access, String name, String signature,
String superName, String[] interfaces) {
@@ -52,13 +113,28 @@
referencedTypes.add(intf);
}
}
+ collectTypesFromClassSignature(signature);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+ addTypeIfClass(desc);
+ // we don't use visitEnd, so we can just use ourselves for nested
visitors
+ return this;
+ }
+
+ @Override
+ public void visitEnum(String name, String desc, String value) {
+ addTypeIfClass(desc);
}
@Override
public FieldVisitor visitField(int access, String name, String desc,
String signature, Object value) {
- addTypeIfClass(Type.getType(desc));
- return emptyVisitor;
+ addTypeIfClass(desc);
+ collectTypesFromFieldSignature(signature);
+ // we don't use visitEnd, so we can just use ourselves for nested
visitors
+ return this;
}
/**
@@ -80,8 +156,10 @@
for (Type type : Type.getArgumentTypes(desc)) {
addTypeIfClass(type);
}
- addTypeIfClass(Type.getReturnType(desc));
- return emptyVisitor;
+ addTypeIfClass(desc);
+ collectTypesFromClassSignature(signature);
+ // we don't use visitEnd, so we can just use ourselves for nested
visitors
+ return this;
}
/**
@@ -92,9 +170,29 @@
referencedTypes.add(owner);
}
- private void addTypeIfClass(Type type) {
+ protected void addTypeIfClass(String desc) {
+ addTypeIfClass(Type.getReturnType(desc));
+ }
+
+ protected void addTypeIfClass(Type type) {
if (type.getSort() == Type.OBJECT) {
referencedTypes.add(type.getInternalName());
}
}
-}
\ No newline at end of file
+
+ private void collectTypesFromClassSignature(String signature) {
+ if (signature == null) {
+ return;
+ }
+ SignatureReader reader = new SignatureReader(signature);
+ reader.accept(new CollectGenericTypes());
+ }
+
+ private void collectTypesFromFieldSignature(String signature) {
+ if (signature == null) {
+ return;
+ }
+ SignatureReader reader = new SignatureReader(signature);
+ reader.acceptType(new CollectGenericTypes());
+ }
+}
Modified:
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/AsmTestCase.java
==============================================================================
---
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/AsmTestCase.java
(original)
+++
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/AsmTestCase.java
Wed Jul 1 08:34:40 2009
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2009 Google Inc.
+ *
+ * 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.gwt.dev.javac.asm;
import com.google.gwt.dev.util.Util;
@@ -6,6 +21,9 @@
import java.io.InputStream;
+/**
+ * Base class for ASM unit tests that defines some useful methods.
+ */
public abstract class AsmTestCase extends TestCase {
private static final ClassLoader CLASSLOADER =
CollectClassDataTest.class.getClassLoader();
@@ -18,14 +36,29 @@
super(name);
}
+ /**
+ * Read the bytes of a class.
+ *
+ * @param clazz class literal of the class to read
+ * @return bytes from class file or null if not found
+ */
protected byte[] getClassBytes(Class<?> clazz) {
- byte[] bytes;
+ return getClassBytes(clazz.getName());
+ }
+
+
+ /**
+ * Read the bytes of a class.
+ *
+ * @param className binary name (ie com.Foo$Bar) of the class to read
+ * @return bytes from class file or null if not found
+ */
+ protected byte[] getClassBytes(String className) {
InputStream str = CLASSLOADER.getResourceAsStream(
- clazz.getName().replace('.', '/') + ".class");
+ className.replace('.', '/') + ".class");
if (str == null) {
return null;
}
return Util.readStreamAsBytes(str);
}
-
-}
\ No newline at end of file
+}
Modified:
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/CollectClassDataTest.java
==============================================================================
---
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/CollectClassDataTest.java
(original)
+++
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/CollectClassDataTest.java
Wed Jul 1 08:34:40 2009
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Google Inc.
+ * Copyright 2009 Google Inc.
*
* 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
@@ -25,7 +25,6 @@
import com.google.gwt.dev.javac.asm.CollectAnnotationData.AnnotationData;
import com.google.gwt.dev.javac.asm.CollectClassData.ClassType;
-
import java.util.List;
/**
@@ -33,11 +32,16 @@
*/
public class CollectClassDataTest extends AsmTestCase {
- @SuppressWarnings("unused")
public static class One extends EmptyVisitor {
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible)
{
+ new EmptyVisitor() {
+ @Override
+ public void visit(int version, int access, String name,
+ String signature, String superName, String[] interfaces) {
+ }
+ };
return new CollectAnnotationData(desc, visible);
}
}
@@ -45,6 +49,9 @@
@PrimitiveValuesAnnotation(b = 42, i = 42)
protected static class Two {
+ public class TwoInner {
+ }
+
private String field;
@TestAnnotation("field")
@@ -60,11 +67,22 @@
}
public Two(int a, String b) {
+ new TwoInner();
field = b;
annotatedField = field;
}
}
+ public void testAnonymous() {
+ CollectClassData cd = collect(One.class.getName() + "$1");
+ // Don't check for super bit, as it will depend on the JDK used to
compile.
+ assertEquals(0, cd.getAccess() & ~Opcodes.ACC_SUPER);
+ assertEquals(ClassType.Anonymous, cd.getClassType());
+ assertEquals(0, cd.getFields().size());
+ List<CollectMethodData> methods = cd.getMethods();
+ assertEquals(2, methods.size());
+ }
+
public void testOne() {
CollectClassData cd = collect(One.class);
// Don't check for super bit, as it will depend on the JDK used to
compile.
@@ -72,9 +90,7 @@
cd.getAccess() & ~Opcodes.ACC_SUPER);
assertEquals(ClassType.Nested, cd.getClassType());
assertEquals(0, cd.getFields().size());
- assertEquals(0, cd.getInnerClasses().size());
assertEquals(0, cd.getInterfaces().length);
- // Note that @SuppressWarnings is a source-only annotation
assertEquals(0, cd.getAnnotations().size());
assertEquals("com/google/gwt/dev/asm/commons/EmptyVisitor",
cd.getSuperName());
@@ -110,6 +126,13 @@
assertEquals(0, method.getExceptions().length);
}
+ public void testTopLevel() {
+ CollectClassData cd = collect(CollectClassDataTest.class);
+ // Don't check for super bit, as it will depend on the JDK used to
compile.
+ assertEquals(Opcodes.ACC_PUBLIC, cd.getAccess() & ~Opcodes.ACC_SUPER);
+ assertEquals(ClassType.TopLevel, cd.getClassType());
+ }
+
public void testTwo() {
CollectClassData cd = collect(Two.class);
// Don't check for super bit, as it will depend on the JDK used to
compile.
@@ -132,7 +155,6 @@
assertEquals("Lcom/google/gwt/core/ext/typeinfo/test/TestAnnotation;",
annotation.getDesc());
assertEquals("field", annotation.getValues().get("value"));
- assertEquals(0, cd.getInnerClasses().size());
assertEquals(0, cd.getInterfaces().length);
annotations = cd.getAnnotations();
assertEquals(1, annotations.size());
@@ -187,9 +209,20 @@
assertEquals(0, method.getExceptions().length);
}
+ public void testTwoInner() {
+ CollectClassData cd = collect(Two.TwoInner.class);
+ // Don't check for super bit, as it will depend on the JDK used to
compile.
+ assertEquals(Opcodes.ACC_PUBLIC , cd.getAccess() & ~Opcodes.ACC_SUPER);
+ assertEquals(ClassType.Inner, cd.getClassType());
+ }
+
private CollectClassData collect(Class<?> clazz) {
- byte[] bytes = getClassBytes(clazz);
- assertNotNull("Couldn't load bytes for " + clazz, bytes);
+ return collect(clazz.getName());
+ }
+
+ private CollectClassData collect(String className) {
+ byte[] bytes = getClassBytes(className);
+ assertNotNull("Couldn't load bytes for " + className, bytes);
CollectClassData cv = new CollectClassData(bytes);
ClassReader reader = new ClassReader(bytes);
reader.accept(cv, 0);
Added:
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/CollectReferencesVisitorTest.java
==============================================================================
--- (empty file)
+++
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/CollectReferencesVisitorTest.java
Wed Jul 1 08:34:40 2009
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2009 Google Inc.
+ *
+ * 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.gwt.dev.javac.asm;
+
+import com.google.gwt.core.ext.typeinfo.test.TestAnnotation;
+import com.google.gwt.dev.asm.ClassReader;
+import com.google.gwt.dev.util.Name.BinaryName;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Tests for {...@link CollectClassData}.
+ */
+public class CollectReferencesVisitorTest extends AsmTestCase {
+
+ /**
+ * This class is empty, but it still has references to itself, its
superclass
+ * (Object), and its enclosing class.
+ */
+ public static class Empty {
+ }
+
+ /**
+ * In addition to the visible types, this class has references to
itself, its
+ * superclass (Object), and its enclosing class.
+ */
+ public static class Full {
+
+ protected Integer i;
+ protected String s;
+
+ @TestAnnotation("foo")
+ public Map<Boolean, String> getMap() {
+ return null;
+ }
+ }
+
+ public void testEmpty() {
+ CollectReferencesVisitor rv = collect(Empty.class);
+ Set<String> referencedTypes = rv.getReferencedTypes();
+ assertEquals(3, referencedTypes.size());
+ assertContainsInternalName(Object.class, referencedTypes);
+ assertContainsInternalName(CollectReferencesVisitorTest.class,
+ referencedTypes);
+ assertContainsInternalName(Empty.class, referencedTypes);
+ }
+
+ public void testFull() {
+ CollectReferencesVisitor rv = collect(Full.class);
+ Set<String> referencedTypes = rv.getReferencedTypes();
+ assertEquals(8, referencedTypes.size());
+ assertContainsInternalName(Object.class, referencedTypes);
+ assertContainsInternalName(CollectReferencesVisitorTest.class,
+ referencedTypes);
+ assertContainsInternalName(Full.class, referencedTypes);
+ assertContainsInternalName(Map.class, referencedTypes);
+ assertContainsInternalName(Integer.class, referencedTypes);
+ assertContainsInternalName(String.class, referencedTypes);
+ assertContainsInternalName(Boolean.class, referencedTypes);
+ assertContainsInternalName(TestAnnotation.class, referencedTypes);
+ }
+
+ private void assertContainsInternalName(Class<?> clazz, Set<String> set)
{
+ String className = BinaryName.toInternalName(clazz.getName());
+ assertTrue("Should contain " + className, set.contains(className));
+ }
+
+ private CollectReferencesVisitor collect(Class<?> clazz) {
+ return collect(clazz.getName());
+ }
+
+ private CollectReferencesVisitor collect(String className) {
+ byte[] bytes = getClassBytes(className);
+ assertNotNull("Couldn't load bytes for " + className, bytes);
+ CollectReferencesVisitor cv = new CollectReferencesVisitor();
+ ClassReader reader = new ClassReader(bytes);
+ reader.accept(cv, 0);
+ return cv;
+ }
+}
--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---