Author: j...@google.com Date: Tue Jun 30 17:14:14 2009 New Revision: 5650 Added: changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/ changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/AsmTestCase.java (contents, props changed) changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/CollectClassDataTest.java (contents, props changed) Modified: changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/CollectAnnotationData.java
Log: Add tests for data-collection ASM visitors. Modified: changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/CollectAnnotationData.java ============================================================================== --- changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/CollectAnnotationData.java (original) +++ changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/CollectAnnotationData.java Tue Jun 30 17:14:14 2009 @@ -114,10 +114,23 @@ private Callback<CollectAnnotationData.AnnotationData> callback; private CollectAnnotationData.AnnotationData annotation; + /** + * Construct the collector. + * + * @param desc class descriptor of the annotation class + * @param visible true if the annotation is visible at runtime + */ public CollectAnnotationData(String desc, boolean visible) { this(desc, visible, null); } + /** + * Construct the collector. + * + * @param desc class descriptor of the annotation class + * @param visible true if the annotation is visible at runtime + * @param callback callback to be called when the annotation is finished + */ public CollectAnnotationData(String desc, boolean visible, Callback<CollectAnnotationData.AnnotationData> callback) { annotation = new AnnotationData(desc, visible); Added: changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/AsmTestCase.java ============================================================================== --- (empty file) +++ changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/AsmTestCase.java Tue Jun 30 17:14:14 2009 @@ -0,0 +1,31 @@ +package com.google.gwt.dev.javac.asm; + +import com.google.gwt.dev.util.Util; + +import junit.framework.TestCase; + +import java.io.InputStream; + +public abstract class AsmTestCase extends TestCase { + + private static final ClassLoader CLASSLOADER = CollectClassDataTest.class.getClassLoader(); + + public AsmTestCase() { + super(); + } + + public AsmTestCase(String name) { + super(name); + } + + protected byte[] getClassBytes(Class<?> clazz) { + byte[] bytes; + InputStream str = CLASSLOADER.getResourceAsStream( + clazz.getName().replace('.', '/') + ".class"); + if (str == null) { + return null; + } + return Util.readStreamAsBytes(str); + } + +} \ No newline at end of file Added: changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/CollectClassDataTest.java ============================================================================== --- (empty file) +++ changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/CollectClassDataTest.java Tue Jun 30 17:14:14 2009 @@ -0,0 +1,198 @@ +/* + * Copyright 2008 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.PrimitiveValuesAnnotation; +import com.google.gwt.core.ext.typeinfo.test.TestAnnotation; +import com.google.gwt.dev.asm.AnnotationVisitor; +import com.google.gwt.dev.asm.ClassReader; +import com.google.gwt.dev.asm.Opcodes; +import com.google.gwt.dev.asm.Type; +import com.google.gwt.dev.asm.commons.EmptyVisitor; +import com.google.gwt.dev.javac.asm.CollectAnnotationData.AnnotationData; +import com.google.gwt.dev.javac.asm.CollectClassData.ClassType; + + +import java.util.List; + +/** + * Tests for {...@link CollectClassData}. + */ +public class CollectClassDataTest extends AsmTestCase { + + @SuppressWarnings("unused") + public static class One extends EmptyVisitor { + + @Override + public AnnotationVisitor visitAnnotation(String desc, boolean visible) { + return new CollectAnnotationData(desc, visible); + } + } + + @PrimitiveValuesAnnotation(b = 42, i = 42) + protected static class Two { + + private String field; + + @TestAnnotation("field") + private String annotatedField; + + public Two(int a) { + this(a, null); + } + + @TestAnnotation("foo") + public String foo(int a) throws IllegalStateException { + return annotatedField; + } + + public Two(int a, String b) { + field = b; + annotatedField = field; + } + } + + public void testOne() { + CollectClassData cd = collect(One.class); + // Don't check for super bit, as it will depend on the JDK used to compile. + assertEquals(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, + 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()); + + List<CollectMethodData> methods = cd.getMethods(); + assertEquals(2, methods.size()); + // TODO(jat): Is it safe to assume the implicit constructor is always first? + CollectMethodData method = methods.get(0); + Type[] argTypes = method.getArgTypes(); + String[] argNames = method.getArgNames(); + assertEquals("<init>", method.getName()); + assertEquals(0, argTypes.length); + assertEquals(0, argNames.length); + assertEquals(0, method.getArgAnnotations().length); + assertEquals(0, method.getAnnotations().size()); + assertEquals(0, method.getExceptions().length); + + method = methods.get(1); + argTypes = method.getArgTypes(); + argNames = method.getArgNames(); + assertEquals("visitAnnotation", method.getName()); + assertEquals(2, argTypes.length); + assertEquals("java.lang.String", argTypes[0].getClassName()); + assertEquals("boolean", argTypes[1].getClassName()); + assertEquals(2, argNames.length); + assertEquals("desc", argNames[0]); + assertEquals("visible", argNames[1]); + assertEquals(2, method.getArgAnnotations().length); + assertEquals(0, method.getArgAnnotations()[0].size()); + assertEquals(0, method.getArgAnnotations()[1].size()); + // Note that @Override is a source-only annotation + assertEquals(0, method.getAnnotations().size()); + assertEquals(0, method.getExceptions().length); + } + + public void testTwo() { + CollectClassData cd = collect(Two.class); + // Don't check for super bit, as it will depend on the JDK used to compile. + assertEquals(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, + cd.getAccess() & ~Opcodes.ACC_SUPER); + assertEquals(ClassType.Nested, cd.getClassType()); + List<CollectFieldData> fields = cd.getFields(); + assertEquals(2, fields.size()); + CollectFieldData field = fields.get(0); + assertEquals("field", field.getName()); + assertEquals("Ljava/lang/String;", field.getDesc()); + List<CollectAnnotationData> annotations = field.getAnnotations(); + assertEquals(0, annotations.size()); + field = fields.get(1); + assertEquals("annotatedField", field.getName()); + assertEquals("Ljava/lang/String;", field.getDesc()); + annotations = field.getAnnotations(); + assertEquals(1, annotations.size()); + AnnotationData annotation = annotations.get(0).getAnnotation(); + 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()); + annotation = annotations.get(0).getAnnotation(); + assertEquals( + "Lcom/google/gwt/core/ext/typeinfo/test/PrimitiveValuesAnnotation;", + annotation.getDesc()); + assertEquals(Byte.valueOf((byte) 42), annotation.getValues().get("b")); + assertEquals(42, annotation.getValues().get("i")); + assertEquals("java/lang/Object", cd.getSuperName()); + + List<CollectMethodData> methods = cd.getMethods(); + assertEquals(3, methods.size()); + // TODO(jat): Is it safe to assume the order? + CollectMethodData method = methods.get(0); + Type[] argTypes = method.getArgTypes(); + String[] argNames = method.getArgNames(); + assertEquals("<init>", method.getName()); + assertEquals(1, argTypes.length); + assertEquals(1, argNames.length); + assertEquals(1, method.getArgAnnotations().length); + assertEquals(0, method.getAnnotations().size()); + assertEquals(0, method.getExceptions().length); + + method = methods.get(1); + argTypes = method.getArgTypes(); + argNames = method.getArgNames(); + assertEquals("foo", method.getName()); + assertEquals(1, argTypes.length); + assertEquals("int", argTypes[0].getClassName()); + assertEquals(1, argNames.length); + assertEquals("a", argNames[0]); + assertEquals(1, method.getArgAnnotations().length); + assertEquals(0, method.getArgAnnotations()[0].size()); + assertEquals(1, method.getAnnotations().size()); + assertEquals(1, method.getExceptions().length); + + method = methods.get(2); + argTypes = method.getArgTypes(); + argNames = method.getArgNames(); + assertEquals("<init>", method.getName()); + assertEquals(2, argTypes.length); + assertEquals("int", argTypes[0].getClassName()); + assertEquals("java.lang.String", argTypes[1].getClassName()); + assertEquals(2, argNames.length); + assertEquals("a", argNames[0]); + assertEquals("b", argNames[1]); + assertEquals(2, method.getArgAnnotations().length); + assertEquals(0, method.getArgAnnotations()[0].size()); + assertEquals(0, method.getArgAnnotations()[1].size()); + assertEquals(0, method.getAnnotations().size()); + assertEquals(0, method.getExceptions().length); + } + + private CollectClassData collect(Class<?> clazz) { + byte[] bytes = getClassBytes(clazz); + assertNotNull("Couldn't load bytes for " + clazz, bytes); + CollectClassData cv = new CollectClassData(bytes); + ClassReader reader = new ClassReader(bytes); + reader.accept(cv, 0); + return cv; + } +} --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~----------~----~----~----~------~----~------~--~---