From b14eef7eed8703824773467606f3be0c03a04b33 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Thu, 5 Aug 2010 23:46:34 +0200 Subject: Created utility class to casually inspect class files on the usage of classes, fields and methods --- test/bytecode/resource/Bar.java | 3 + test/bytecode/resource/Baz.java | 2 + test/bytecode/resource/Buux.java | 10 ++ test/bytecode/resource/Foo.java | 9 + .../src/lombok/bytecode/ClassFileMetaDataTest.java | 196 +++++++++++++++++++++ 5 files changed, 220 insertions(+) create mode 100644 test/bytecode/resource/Bar.java create mode 100644 test/bytecode/resource/Baz.java create mode 100644 test/bytecode/resource/Buux.java create mode 100644 test/bytecode/resource/Foo.java create mode 100644 test/bytecode/src/lombok/bytecode/ClassFileMetaDataTest.java (limited to 'test/bytecode') diff --git a/test/bytecode/resource/Bar.java b/test/bytecode/resource/Bar.java new file mode 100644 index 00000000..13cbf425 --- /dev/null +++ b/test/bytecode/resource/Bar.java @@ -0,0 +1,3 @@ +public interface Bar extends java.util.RandomAccess, java.util.Map { + String getName(); +} \ No newline at end of file diff --git a/test/bytecode/resource/Baz.java b/test/bytecode/resource/Baz.java new file mode 100644 index 00000000..2525ed00 --- /dev/null +++ b/test/bytecode/resource/Baz.java @@ -0,0 +1,2 @@ +public interface Baz { +} \ No newline at end of file diff --git a/test/bytecode/resource/Buux.java b/test/bytecode/resource/Buux.java new file mode 100644 index 00000000..33b352e2 --- /dev/null +++ b/test/bytecode/resource/Buux.java @@ -0,0 +1,10 @@ +public class Buux extends java.util.ArrayList { + public Buux() { + super(7); + addSomething(); + } + + public void addSomething() { + super.add("H\u3404l\0"); + } +} \ No newline at end of file diff --git a/test/bytecode/resource/Foo.java b/test/bytecode/resource/Foo.java new file mode 100644 index 00000000..95a2c820 --- /dev/null +++ b/test/bytecode/resource/Foo.java @@ -0,0 +1,9 @@ +public class Foo implements java.util.RandomAccess { + private static final String ONE = "Eén"; + + { + String value = toString(); + System.out.print(value); + System.out.print("Two" + "Four"); + } +} \ No newline at end of file diff --git a/test/bytecode/src/lombok/bytecode/ClassFileMetaDataTest.java b/test/bytecode/src/lombok/bytecode/ClassFileMetaDataTest.java new file mode 100644 index 00000000..a2fa919f --- /dev/null +++ b/test/bytecode/src/lombok/bytecode/ClassFileMetaDataTest.java @@ -0,0 +1,196 @@ +/* + * Copyright © 2010 Reinier Zwitserloot and Roel Spilker. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.bytecode; + +import static org.junit.Assert.*; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.StringWriter; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import javax.tools.JavaCompiler; +import javax.tools.SimpleJavaFileObject; +import javax.tools.ToolProvider; +import javax.tools.JavaCompiler.CompilationTask; + +import lombok.Lombok; + +import org.junit.Test; + +public class ClassFileMetaDataTest { + + private ClassFileMetaData foo = create(new File("test/bytecode/resource/Foo.java")); + private ClassFileMetaData bar = create(new File("test/bytecode/resource/Bar.java")); + private ClassFileMetaData baz = create(new File("test/bytecode/resource/Baz.java")); + private ClassFileMetaData buux = create(new File("test/bytecode/resource/Buux.java")); + + @Test + public void testGetClassName() { + assertTrue(foo.containsUtf8("Foo")); + assertEquals("Foo", foo.getClassName()); + + assertTrue(bar.containsUtf8("Bar")); + assertEquals("Bar", bar.getClassName()); + + assertTrue(baz.containsUtf8("Baz")); + assertEquals("Baz", baz.getClassName()); + } + + @Test + public void testGetSuperClassName() { + assertTrue(foo.containsUtf8("java/lang/Object")); + assertEquals("java/lang/Object", foo.getSuperClassName()); + + assertEquals("java/lang/Object", bar.getSuperClassName()); + assertEquals("java/lang/Object", baz.getSuperClassName()); + + assertEquals("java/util/ArrayList", buux.getSuperClassName()); + } + + + + @Test + public void testUsesClass() { + assertTrue(foo.usesClass("java/lang/System")); +// assertTrue(foo.usesClass("java/lang/String")); + } + + @Test + public void testUsesField() { + assertTrue(foo.usesField("java/lang/System", "out")); + } + + @Test + public void testUsesMethodWithName() { + assertTrue(foo.usesMethod("java/io/PrintStream", "print")); + + assertTrue(buux.usesMethod("java/util/ArrayList", "")); + assertTrue(buux.usesMethod("java/util/ArrayList", "add")); + assertTrue(buux.usesMethod("Buux", "addSomething")); + } + + @Test + public void testUsesMethodWithNameAndDescriptor() { + assertTrue(foo.usesMethod("java/io/PrintStream", "print", "(Ljava/lang/String;)V")); + + assertTrue(buux.usesMethod("java/util/ArrayList", "", "(I)V")); + assertTrue(buux.usesMethod("java/util/ArrayList", "add", "(Ljava/lang/Object;)Z")); + assertTrue(buux.usesMethod("Buux", "addSomething", "()V")); + } + + @Test + public void testGetInterfaces() { + assertTrue(foo.containsUtf8("java/util/RandomAccess")); + + List fooInterfaces = foo.getInterfaces(); + assertEquals(1, fooInterfaces.size()); + assertEquals("java/util/RandomAccess", fooInterfaces.get(0)); + + assertTrue(bar.containsUtf8("java/util/RandomAccess")); + assertTrue(bar.containsUtf8("java/util/Map")); + + List barInterfaces = bar.getInterfaces(); + assertEquals(2, barInterfaces.size()); + assertEquals("java/util/RandomAccess", barInterfaces.get(0)); + assertEquals("java/util/Map", barInterfaces.get(1)); + } + + @Test + public void testContainsStringConstant() { + assertTrue(foo.containsStringConstant("Eén")); + assertTrue(foo.containsStringConstant("TwoFour")); + + assertTrue(buux.containsStringConstant("H\u3404l\0")); + } + + private ClassFileMetaData create(File file) { + return new ClassFileMetaData(compile(file)); + } + + private byte[] compile(File file) { + try { + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + File tempDir = getTempDir(); + tempDir.mkdirs(); + List options = Arrays.asList("-nowarn", "-proc:none", "-d", tempDir.getAbsolutePath()); + StringWriter captureWarnings = new StringWriter(); + CompilationTask task = compiler.getTask(captureWarnings, null, null, options, null, Collections.singleton(new ContentBasedJavaFileObject(file.getPath(), readFileAsString(file)))); + assertTrue(task.call()); + return PostCompilerApp.readFile(new File(tempDir, file.getName().replaceAll("\\.java$", ".class"))); + } catch (Exception e) { + throw Lombok.sneakyThrow(e); + } + } + + private File getTempDir() { + String[] rawDirs = { + System.getProperty("java.io.tmpdir"), + "/tmp", + "C:\\Windows\\Temp" + }; + + for (String dir : rawDirs) { + if (dir == null) continue; + File f = new File(dir); + if (!f.isDirectory()) continue; + return new File(f, "lombok.bytecode-test"); + } + + return new File("./build/tmp"); + } + + static class ContentBasedJavaFileObject extends SimpleJavaFileObject { + private final String content; + + protected ContentBasedJavaFileObject(String name, String content) { + super(new File(name).toURI(), Kind.SOURCE); + this.content = content; + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { + return content; + } + } + + private String readFileAsString(File file) { + try { + BufferedReader reader = new BufferedReader(new FileReader(file)); + StringWriter writer = new StringWriter(); + String line = reader.readLine(); + while(line != null) { + writer.append(line).append("\n"); + line = reader.readLine(); + } + reader.close(); + writer.close(); + return writer.toString(); + } catch (Exception e) { + throw Lombok.sneakyThrow(e); + } + } +} -- cgit From 2683c24ee96fd7228198512f5cfcb2fd0b0cfabd Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Sat, 7 Aug 2010 22:27:32 +0200 Subject: Fixed some bugs in reading the constant pool and added tests --- src/core/lombok/bytecode/ClassFileMetaData.java | 122 ++++++++++++++++++++- test/bytecode/resource/Foo.java | 11 ++ .../src/lombok/bytecode/ClassFileMetaDataTest.java | 76 +++++++++++-- 3 files changed, 199 insertions(+), 10 deletions(-) (limited to 'test/bytecode') diff --git a/src/core/lombok/bytecode/ClassFileMetaData.java b/src/core/lombok/bytecode/ClassFileMetaData.java index df50969a..693a9ad5 100644 --- a/src/core/lombok/bytecode/ClassFileMetaData.java +++ b/src/core/lombok/bytecode/ClassFileMetaData.java @@ -40,6 +40,7 @@ public class ClassFileMetaData { private static final byte NAME_TYPE = 12; private static final int NOT_FOUND = -1; + private static final int START_OF_CONSTANT_POOL = 8; private final byte[] byteCode; @@ -52,12 +53,12 @@ public class ClassFileMetaData { public ClassFileMetaData(byte[] byteCode) { this.byteCode = byteCode; - maxPoolSize = readValue(8) + 1; + maxPoolSize = readValue(START_OF_CONSTANT_POOL); offsets = new int[maxPoolSize]; types = new byte[maxPoolSize]; utf8s = new String[maxPoolSize]; int position = 10; - for (int i = 1; i < maxPoolSize - 1; i++) { + for (int i = 1; i < maxPoolSize; i++) { byte type = byteCode[position]; types[i] = type; position++; @@ -84,6 +85,7 @@ public class ClassFileMetaData { case LONG: case DOUBLE: position += 8; + i++; break; case 0: break; @@ -178,6 +180,65 @@ public class ClassFileMetaData { return false; } + public boolean containsLong(long value) { + for (int i = 1; i < maxPoolSize; i++) { + if (types[i] == LONG && readLong(i) == value) return true; + } + return false; + } + + public boolean containsDouble(double value) { + boolean isNan = Double.isNaN(value); + for (int i = 1; i < maxPoolSize; i++) { + if (types[i] == DOUBLE) { + double d = readDouble(i); + if (d == value || (isNan && Double.isNaN(d))) return true; + } + } + return false; + } + + public boolean containsInteger(int value) { + for (int i = 1; i < maxPoolSize; i++) { + if (types[i] == INTEGER && readInteger(i) == value) return true; + } + return false; + } + + public boolean containsFloat(float value) { + boolean isNan = Float.isNaN(value); + for (int i = 1; i < maxPoolSize; i++) { + if (types[i] == FLOAT) { + float f = readFloat(i); + if (f == value || (isNan && Float.isNaN(f))) return true; + } + } + return false; + } + + private long readLong(int index) { + int pos = offsets[index]; + return ((long)read32(pos)) << 32 | read32(pos + 4); + } + + private double readDouble(int index) { + int pos = offsets[index]; + long bits = ((long)read32(pos)) << 32 | (read32(pos + 4) & 0x00000000FFFFFFFF); + return Double.longBitsToDouble(bits); + } + + private long readInteger(int index) { + return read32(offsets[index]); + } + + private float readFloat(int index) { + return Float.intBitsToFloat(read32(offsets[index])); + } + + private int read32(int pos) { + return (byteCode[pos] & 0xFF) << 24 | (byteCode[pos + 1] & 0xFF) << 16 | (byteCode[pos + 2] & 0xFF) << 8 | (byteCode[pos + 3] &0xFF); + } + public String getClassName() { return getClassName(readValue(endOfPool + 2)); } @@ -197,6 +258,63 @@ public class ClassFileMetaData { return result; } + public String poolContent() { + StringBuilder result = new StringBuilder(); + for (int i = 1; i < maxPoolSize; i++) { + result.append(String.format("#%02d: ", i)); + int pos = offsets[i]; + switch(types[i]) { + case UTF8: + result.append("Utf8 ").append(utf8s[i]); + break; + case CLASS: + result.append("Class ").append(getClassName(i)); + break; + case STRING: + result.append("String \"").append(utf8s[readValue(pos)]).append("\""); + break; + case INTEGER: + result.append("int ").append(readInteger(i)); + break; + case FLOAT: + result.append("float ").append(readFloat(i)); + break; + case FIELD: + appendAccess(result.append("Field "), i); + break; + case METHOD: + case IMETHOD: + appendAccess(result.append("Method "), i); + break; + case NAME_TYPE: + appendNameAndType(result.append("Name&Type "), i); + break; + case LONG: + result.append("long ").append(readLong(i)); + break; + case DOUBLE: + result.append("double ").append(readDouble(i)); + break; + case 0: + result.append("(cont.)"); + break; + } + result.append("\n"); + } + return result.toString(); + } + + private void appendAccess(StringBuilder result, int index) { + int pos = offsets[index]; + result.append(getClassName(readValue(pos))).append("."); + appendNameAndType(result, readValue(pos + 2)); + } + + private void appendNameAndType(StringBuilder result, int index) { + int pos = offsets[index]; + result.append(utf8s[readValue(pos)]).append(":").append(utf8s[readValue(pos + 2)]); + } + private String getClassName(int classIndex) { if (classIndex < 1) return null; return utf8s[readValue(offsets[classIndex])]; diff --git a/test/bytecode/resource/Foo.java b/test/bytecode/resource/Foo.java index 95a2c820..2726026c 100644 --- a/test/bytecode/resource/Foo.java +++ b/test/bytecode/resource/Foo.java @@ -1,5 +1,16 @@ public class Foo implements java.util.RandomAccess { + private static final long LONG = 123L; private static final String ONE = "Eén"; + private static final int INT = 123; + private static final double DOUBLE = 1.23; + private static final double DOUBLE_NAN = Double.NaN; + private static final double DOUBLE_INF = Double.POSITIVE_INFINITY; + private static final double DOUBLE_NEG_INF = Double.NEGATIVE_INFINITY; + + private static final float FLOAT = 1.23F; + private static final float FLOAT_NAN = Float.NaN; + private static final float FLOAT_INF = Float.POSITIVE_INFINITY; + private static final float FLOAT_NEG_INF = Float.NEGATIVE_INFINITY; { String value = toString(); diff --git a/test/bytecode/src/lombok/bytecode/ClassFileMetaDataTest.java b/test/bytecode/src/lombok/bytecode/ClassFileMetaDataTest.java index a2fa919f..191ec70d 100644 --- a/test/bytecode/src/lombok/bytecode/ClassFileMetaDataTest.java +++ b/test/bytecode/src/lombok/bytecode/ClassFileMetaDataTest.java @@ -43,10 +43,24 @@ import org.junit.Test; public class ClassFileMetaDataTest { - private ClassFileMetaData foo = create(new File("test/bytecode/resource/Foo.java")); - private ClassFileMetaData bar = create(new File("test/bytecode/resource/Bar.java")); - private ClassFileMetaData baz = create(new File("test/bytecode/resource/Baz.java")); - private ClassFileMetaData buux = create(new File("test/bytecode/resource/Buux.java")); + private static ClassFileMetaData foo = create(new File("test/bytecode/resource/Foo.java")); + private static ClassFileMetaData bar = create(new File("test/bytecode/resource/Bar.java")); + private static ClassFileMetaData baz = create(new File("test/bytecode/resource/Baz.java")); + private static ClassFileMetaData buux = create(new File("test/bytecode/resource/Buux.java")); + +// @Test +// public void dump() { +// byte[] bytes = compile(new File("test/bytecode/resource/Foo.java")); +// int count = 0; +// for (byte b : bytes) { +// System.out.printf("%02x ", (b & 0xFF)); +// count++; +// if (count % 20 == 0) System.out.println(); +// } +// System.out.println(); +// System.out.println(); +// System.out.println(foo.poolContent()); +// } @Test public void testGetClassName() { @@ -125,13 +139,59 @@ public class ClassFileMetaDataTest { assertTrue(foo.containsStringConstant("TwoFour")); assertTrue(buux.containsStringConstant("H\u3404l\0")); + + assertFalse(foo.containsStringConstant("Seven")); + } + + @Test + public void testContainsDouble() { + assertTrue(foo.containsDouble(1.23)); + assertTrue(foo.containsDouble(Double.NaN)); + assertTrue(foo.containsDouble(Double.POSITIVE_INFINITY)); + assertTrue(foo.containsDouble(Double.NEGATIVE_INFINITY)); + + assertFalse(foo.containsDouble(1.0)); + assertFalse(buux.containsDouble(1.0)); + assertFalse(buux.containsDouble(Double.NaN)); + assertFalse(buux.containsDouble(Double.POSITIVE_INFINITY)); + assertFalse(buux.containsDouble(Double.NEGATIVE_INFINITY)); + } + + @Test + public void testContainsFloat() { + assertTrue(foo.containsFloat(1.23F)); + assertTrue(foo.containsFloat(Float.NaN)); + assertTrue(foo.containsFloat(Float.POSITIVE_INFINITY)); + assertTrue(foo.containsFloat(Float.NEGATIVE_INFINITY)); + + assertFalse(foo.containsFloat(1.0F)); + assertFalse(buux.containsFloat(1.0F)); + assertFalse(buux.containsFloat(Float.NaN)); + assertFalse(buux.containsFloat(Float.POSITIVE_INFINITY)); + assertFalse(buux.containsFloat(Float.NEGATIVE_INFINITY)); + } + + @Test + public void testContainsInteger() { + assertTrue(foo.containsInteger(123)); + + assertFalse(foo.containsInteger(1)); + assertFalse(buux.containsInteger(1)); + } + + @Test + public void testContainsLong() { + assertTrue(foo.containsLong(123)); + + assertFalse(foo.containsLong(1)); + assertFalse(buux.containsLong(1)); } - private ClassFileMetaData create(File file) { + private static ClassFileMetaData create(File file) { return new ClassFileMetaData(compile(file)); } - private byte[] compile(File file) { + private static byte[] compile(File file) { try { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); File tempDir = getTempDir(); @@ -146,7 +206,7 @@ public class ClassFileMetaDataTest { } } - private File getTempDir() { + private static File getTempDir() { String[] rawDirs = { System.getProperty("java.io.tmpdir"), "/tmp", @@ -177,7 +237,7 @@ public class ClassFileMetaDataTest { } } - private String readFileAsString(File file) { + private static String readFileAsString(File file) { try { BufferedReader reader = new BufferedReader(new FileReader(file)); StringWriter writer = new StringWriter(); -- cgit From e4845802a7d66415e330325dd434c0df4315c895 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Sun, 15 Aug 2010 22:35:29 +0200 Subject: Updated buildscript to include tests and eclipse .project generation for the new bytecode tests in test/bytecode/src --- build.xml | 5 + .../src/lombok/bytecode/ClassFileMetaDataTest.java | 256 --------------------- .../src/lombok/bytecode/TestClassFileMetaData.java | 256 +++++++++++++++++++++ 3 files changed, 261 insertions(+), 256 deletions(-) delete mode 100644 test/bytecode/src/lombok/bytecode/ClassFileMetaDataTest.java create mode 100644 test/bytecode/src/lombok/bytecode/TestClassFileMetaData.java (limited to 'test/bytecode') diff --git a/build.xml b/build.xml index d438a7bf..fe1f500c 100644 --- a/build.xml +++ b/build.xml @@ -171,6 +171,7 @@ the common tasks and can be called on to run the main aspects of all the sub-scr + @@ -208,6 +209,7 @@ the common tasks and can be called on to run the main aspects of all the sub-scr + @@ -228,6 +230,9 @@ the common tasks and can be called on to run the main aspects of all the sub-scr + + + All tests successful. diff --git a/test/bytecode/src/lombok/bytecode/ClassFileMetaDataTest.java b/test/bytecode/src/lombok/bytecode/ClassFileMetaDataTest.java deleted file mode 100644 index 191ec70d..00000000 --- a/test/bytecode/src/lombok/bytecode/ClassFileMetaDataTest.java +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright © 2010 Reinier Zwitserloot and Roel Spilker. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package lombok.bytecode; - -import static org.junit.Assert.*; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.StringWriter; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import javax.tools.JavaCompiler; -import javax.tools.SimpleJavaFileObject; -import javax.tools.ToolProvider; -import javax.tools.JavaCompiler.CompilationTask; - -import lombok.Lombok; - -import org.junit.Test; - -public class ClassFileMetaDataTest { - - private static ClassFileMetaData foo = create(new File("test/bytecode/resource/Foo.java")); - private static ClassFileMetaData bar = create(new File("test/bytecode/resource/Bar.java")); - private static ClassFileMetaData baz = create(new File("test/bytecode/resource/Baz.java")); - private static ClassFileMetaData buux = create(new File("test/bytecode/resource/Buux.java")); - -// @Test -// public void dump() { -// byte[] bytes = compile(new File("test/bytecode/resource/Foo.java")); -// int count = 0; -// for (byte b : bytes) { -// System.out.printf("%02x ", (b & 0xFF)); -// count++; -// if (count % 20 == 0) System.out.println(); -// } -// System.out.println(); -// System.out.println(); -// System.out.println(foo.poolContent()); -// } - - @Test - public void testGetClassName() { - assertTrue(foo.containsUtf8("Foo")); - assertEquals("Foo", foo.getClassName()); - - assertTrue(bar.containsUtf8("Bar")); - assertEquals("Bar", bar.getClassName()); - - assertTrue(baz.containsUtf8("Baz")); - assertEquals("Baz", baz.getClassName()); - } - - @Test - public void testGetSuperClassName() { - assertTrue(foo.containsUtf8("java/lang/Object")); - assertEquals("java/lang/Object", foo.getSuperClassName()); - - assertEquals("java/lang/Object", bar.getSuperClassName()); - assertEquals("java/lang/Object", baz.getSuperClassName()); - - assertEquals("java/util/ArrayList", buux.getSuperClassName()); - } - - - - @Test - public void testUsesClass() { - assertTrue(foo.usesClass("java/lang/System")); -// assertTrue(foo.usesClass("java/lang/String")); - } - - @Test - public void testUsesField() { - assertTrue(foo.usesField("java/lang/System", "out")); - } - - @Test - public void testUsesMethodWithName() { - assertTrue(foo.usesMethod("java/io/PrintStream", "print")); - - assertTrue(buux.usesMethod("java/util/ArrayList", "")); - assertTrue(buux.usesMethod("java/util/ArrayList", "add")); - assertTrue(buux.usesMethod("Buux", "addSomething")); - } - - @Test - public void testUsesMethodWithNameAndDescriptor() { - assertTrue(foo.usesMethod("java/io/PrintStream", "print", "(Ljava/lang/String;)V")); - - assertTrue(buux.usesMethod("java/util/ArrayList", "", "(I)V")); - assertTrue(buux.usesMethod("java/util/ArrayList", "add", "(Ljava/lang/Object;)Z")); - assertTrue(buux.usesMethod("Buux", "addSomething", "()V")); - } - - @Test - public void testGetInterfaces() { - assertTrue(foo.containsUtf8("java/util/RandomAccess")); - - List fooInterfaces = foo.getInterfaces(); - assertEquals(1, fooInterfaces.size()); - assertEquals("java/util/RandomAccess", fooInterfaces.get(0)); - - assertTrue(bar.containsUtf8("java/util/RandomAccess")); - assertTrue(bar.containsUtf8("java/util/Map")); - - List barInterfaces = bar.getInterfaces(); - assertEquals(2, barInterfaces.size()); - assertEquals("java/util/RandomAccess", barInterfaces.get(0)); - assertEquals("java/util/Map", barInterfaces.get(1)); - } - - @Test - public void testContainsStringConstant() { - assertTrue(foo.containsStringConstant("Eén")); - assertTrue(foo.containsStringConstant("TwoFour")); - - assertTrue(buux.containsStringConstant("H\u3404l\0")); - - assertFalse(foo.containsStringConstant("Seven")); - } - - @Test - public void testContainsDouble() { - assertTrue(foo.containsDouble(1.23)); - assertTrue(foo.containsDouble(Double.NaN)); - assertTrue(foo.containsDouble(Double.POSITIVE_INFINITY)); - assertTrue(foo.containsDouble(Double.NEGATIVE_INFINITY)); - - assertFalse(foo.containsDouble(1.0)); - assertFalse(buux.containsDouble(1.0)); - assertFalse(buux.containsDouble(Double.NaN)); - assertFalse(buux.containsDouble(Double.POSITIVE_INFINITY)); - assertFalse(buux.containsDouble(Double.NEGATIVE_INFINITY)); - } - - @Test - public void testContainsFloat() { - assertTrue(foo.containsFloat(1.23F)); - assertTrue(foo.containsFloat(Float.NaN)); - assertTrue(foo.containsFloat(Float.POSITIVE_INFINITY)); - assertTrue(foo.containsFloat(Float.NEGATIVE_INFINITY)); - - assertFalse(foo.containsFloat(1.0F)); - assertFalse(buux.containsFloat(1.0F)); - assertFalse(buux.containsFloat(Float.NaN)); - assertFalse(buux.containsFloat(Float.POSITIVE_INFINITY)); - assertFalse(buux.containsFloat(Float.NEGATIVE_INFINITY)); - } - - @Test - public void testContainsInteger() { - assertTrue(foo.containsInteger(123)); - - assertFalse(foo.containsInteger(1)); - assertFalse(buux.containsInteger(1)); - } - - @Test - public void testContainsLong() { - assertTrue(foo.containsLong(123)); - - assertFalse(foo.containsLong(1)); - assertFalse(buux.containsLong(1)); - } - - private static ClassFileMetaData create(File file) { - return new ClassFileMetaData(compile(file)); - } - - private static byte[] compile(File file) { - try { - JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - File tempDir = getTempDir(); - tempDir.mkdirs(); - List options = Arrays.asList("-nowarn", "-proc:none", "-d", tempDir.getAbsolutePath()); - StringWriter captureWarnings = new StringWriter(); - CompilationTask task = compiler.getTask(captureWarnings, null, null, options, null, Collections.singleton(new ContentBasedJavaFileObject(file.getPath(), readFileAsString(file)))); - assertTrue(task.call()); - return PostCompilerApp.readFile(new File(tempDir, file.getName().replaceAll("\\.java$", ".class"))); - } catch (Exception e) { - throw Lombok.sneakyThrow(e); - } - } - - private static File getTempDir() { - String[] rawDirs = { - System.getProperty("java.io.tmpdir"), - "/tmp", - "C:\\Windows\\Temp" - }; - - for (String dir : rawDirs) { - if (dir == null) continue; - File f = new File(dir); - if (!f.isDirectory()) continue; - return new File(f, "lombok.bytecode-test"); - } - - return new File("./build/tmp"); - } - - static class ContentBasedJavaFileObject extends SimpleJavaFileObject { - private final String content; - - protected ContentBasedJavaFileObject(String name, String content) { - super(new File(name).toURI(), Kind.SOURCE); - this.content = content; - } - - @Override - public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { - return content; - } - } - - private static String readFileAsString(File file) { - try { - BufferedReader reader = new BufferedReader(new FileReader(file)); - StringWriter writer = new StringWriter(); - String line = reader.readLine(); - while(line != null) { - writer.append(line).append("\n"); - line = reader.readLine(); - } - reader.close(); - writer.close(); - return writer.toString(); - } catch (Exception e) { - throw Lombok.sneakyThrow(e); - } - } -} diff --git a/test/bytecode/src/lombok/bytecode/TestClassFileMetaData.java b/test/bytecode/src/lombok/bytecode/TestClassFileMetaData.java new file mode 100644 index 00000000..ad5a3cee --- /dev/null +++ b/test/bytecode/src/lombok/bytecode/TestClassFileMetaData.java @@ -0,0 +1,256 @@ +/* + * Copyright © 2010 Reinier Zwitserloot and Roel Spilker. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.bytecode; + +import static org.junit.Assert.*; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.StringWriter; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import javax.tools.JavaCompiler; +import javax.tools.SimpleJavaFileObject; +import javax.tools.ToolProvider; +import javax.tools.JavaCompiler.CompilationTask; + +import lombok.Lombok; + +import org.junit.Test; + +public class TestClassFileMetaData { + + private static ClassFileMetaData foo = create(new File("test/bytecode/resource/Foo.java")); + private static ClassFileMetaData bar = create(new File("test/bytecode/resource/Bar.java")); + private static ClassFileMetaData baz = create(new File("test/bytecode/resource/Baz.java")); + private static ClassFileMetaData buux = create(new File("test/bytecode/resource/Buux.java")); + +// @Test +// public void dump() { +// byte[] bytes = compile(new File("test/bytecode/resource/Foo.java")); +// int count = 0; +// for (byte b : bytes) { +// System.out.printf("%02x ", (b & 0xFF)); +// count++; +// if (count % 20 == 0) System.out.println(); +// } +// System.out.println(); +// System.out.println(); +// System.out.println(foo.poolContent()); +// } + + @Test + public void testGetClassName() { + assertTrue(foo.containsUtf8("Foo")); + assertEquals("Foo", foo.getClassName()); + + assertTrue(bar.containsUtf8("Bar")); + assertEquals("Bar", bar.getClassName()); + + assertTrue(baz.containsUtf8("Baz")); + assertEquals("Baz", baz.getClassName()); + } + + @Test + public void testGetSuperClassName() { + assertTrue(foo.containsUtf8("java/lang/Object")); + assertEquals("java/lang/Object", foo.getSuperClassName()); + + assertEquals("java/lang/Object", bar.getSuperClassName()); + assertEquals("java/lang/Object", baz.getSuperClassName()); + + assertEquals("java/util/ArrayList", buux.getSuperClassName()); + } + + + + @Test + public void testUsesClass() { + assertTrue(foo.usesClass("java/lang/System")); +// assertTrue(foo.usesClass("java/lang/String")); + } + + @Test + public void testUsesField() { + assertTrue(foo.usesField("java/lang/System", "out")); + } + + @Test + public void testUsesMethodWithName() { + assertTrue(foo.usesMethod("java/io/PrintStream", "print")); + + assertTrue(buux.usesMethod("java/util/ArrayList", "")); + assertTrue(buux.usesMethod("java/util/ArrayList", "add")); + assertTrue(buux.usesMethod("Buux", "addSomething")); + } + + @Test + public void testUsesMethodWithNameAndDescriptor() { + assertTrue(foo.usesMethod("java/io/PrintStream", "print", "(Ljava/lang/String;)V")); + + assertTrue(buux.usesMethod("java/util/ArrayList", "", "(I)V")); + assertTrue(buux.usesMethod("java/util/ArrayList", "add", "(Ljava/lang/Object;)Z")); + assertTrue(buux.usesMethod("Buux", "addSomething", "()V")); + } + + @Test + public void testGetInterfaces() { + assertTrue(foo.containsUtf8("java/util/RandomAccess")); + + List fooInterfaces = foo.getInterfaces(); + assertEquals(1, fooInterfaces.size()); + assertEquals("java/util/RandomAccess", fooInterfaces.get(0)); + + assertTrue(bar.containsUtf8("java/util/RandomAccess")); + assertTrue(bar.containsUtf8("java/util/Map")); + + List barInterfaces = bar.getInterfaces(); + assertEquals(2, barInterfaces.size()); + assertEquals("java/util/RandomAccess", barInterfaces.get(0)); + assertEquals("java/util/Map", barInterfaces.get(1)); + } + + @Test + public void testContainsStringConstant() { + assertTrue(foo.containsStringConstant("Eén")); + assertTrue(foo.containsStringConstant("TwoFour")); + + assertTrue(buux.containsStringConstant("H\u3404l\0")); + + assertFalse(foo.containsStringConstant("Seven")); + } + + @Test + public void testContainsDouble() { + assertTrue(foo.containsDouble(1.23)); + assertTrue(foo.containsDouble(Double.NaN)); + assertTrue(foo.containsDouble(Double.POSITIVE_INFINITY)); + assertTrue(foo.containsDouble(Double.NEGATIVE_INFINITY)); + + assertFalse(foo.containsDouble(1.0)); + assertFalse(buux.containsDouble(1.0)); + assertFalse(buux.containsDouble(Double.NaN)); + assertFalse(buux.containsDouble(Double.POSITIVE_INFINITY)); + assertFalse(buux.containsDouble(Double.NEGATIVE_INFINITY)); + } + + @Test + public void testContainsFloat() { + assertTrue(foo.containsFloat(1.23F)); + assertTrue(foo.containsFloat(Float.NaN)); + assertTrue(foo.containsFloat(Float.POSITIVE_INFINITY)); + assertTrue(foo.containsFloat(Float.NEGATIVE_INFINITY)); + + assertFalse(foo.containsFloat(1.0F)); + assertFalse(buux.containsFloat(1.0F)); + assertFalse(buux.containsFloat(Float.NaN)); + assertFalse(buux.containsFloat(Float.POSITIVE_INFINITY)); + assertFalse(buux.containsFloat(Float.NEGATIVE_INFINITY)); + } + + @Test + public void testContainsInteger() { + assertTrue(foo.containsInteger(123)); + + assertFalse(foo.containsInteger(1)); + assertFalse(buux.containsInteger(1)); + } + + @Test + public void testContainsLong() { + assertTrue(foo.containsLong(123)); + + assertFalse(foo.containsLong(1)); + assertFalse(buux.containsLong(1)); + } + + private static ClassFileMetaData create(File file) { + return new ClassFileMetaData(compile(file)); + } + + private static byte[] compile(File file) { + try { + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + File tempDir = getTempDir(); + tempDir.mkdirs(); + List options = Arrays.asList("-nowarn", "-proc:none", "-d", tempDir.getAbsolutePath()); + StringWriter captureWarnings = new StringWriter(); + CompilationTask task = compiler.getTask(captureWarnings, null, null, options, null, Collections.singleton(new ContentBasedJavaFileObject(file.getPath(), readFileAsString(file)))); + assertTrue(task.call()); + return PostCompilerApp.readFile(new File(tempDir, file.getName().replaceAll("\\.java$", ".class"))); + } catch (Exception e) { + throw Lombok.sneakyThrow(e); + } + } + + private static File getTempDir() { + String[] rawDirs = { + System.getProperty("java.io.tmpdir"), + "/tmp", + "C:\\Windows\\Temp" + }; + + for (String dir : rawDirs) { + if (dir == null) continue; + File f = new File(dir); + if (!f.isDirectory()) continue; + return new File(f, "lombok.bytecode-test"); + } + + return new File("./build/tmp"); + } + + static class ContentBasedJavaFileObject extends SimpleJavaFileObject { + private final String content; + + protected ContentBasedJavaFileObject(String name, String content) { + super(new File(name).toURI(), Kind.SOURCE); + this.content = content; + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { + return content; + } + } + + private static String readFileAsString(File file) { + try { + BufferedReader reader = new BufferedReader(new FileReader(file)); + StringWriter writer = new StringWriter(); + String line = reader.readLine(); + while(line != null) { + writer.append(line).append("\n"); + line = reader.readLine(); + } + reader.close(); + writer.close(); + return writer.toString(); + } catch (Exception e) { + throw Lombok.sneakyThrow(e); + } + } +} -- cgit From 4c23804837e854c4f4ebb0008b10241467550d3f Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Sun, 15 Aug 2010 22:59:10 +0200 Subject: Update to force reading of test sources as UTF-8, which they are. --- .../src/lombok/bytecode/TestClassFileMetaData.java | 28 +++++++++++++--------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'test/bytecode') diff --git a/test/bytecode/src/lombok/bytecode/TestClassFileMetaData.java b/test/bytecode/src/lombok/bytecode/TestClassFileMetaData.java index ad5a3cee..2caf9372 100644 --- a/test/bytecode/src/lombok/bytecode/TestClassFileMetaData.java +++ b/test/bytecode/src/lombok/bytecode/TestClassFileMetaData.java @@ -25,8 +25,9 @@ import static org.junit.Assert.*; import java.io.BufferedReader; import java.io.File; -import java.io.FileReader; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStreamReader; import java.io.StringWriter; import java.util.Arrays; import java.util.Collections; @@ -196,7 +197,7 @@ public class TestClassFileMetaData { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); File tempDir = getTempDir(); tempDir.mkdirs(); - List options = Arrays.asList("-nowarn", "-proc:none", "-d", tempDir.getAbsolutePath()); + List options = Arrays.asList("-proc:none", "-d", tempDir.getAbsolutePath()); StringWriter captureWarnings = new StringWriter(); CompilationTask task = compiler.getTask(captureWarnings, null, null, options, null, Collections.singleton(new ContentBasedJavaFileObject(file.getPath(), readFileAsString(file)))); assertTrue(task.call()); @@ -239,16 +240,21 @@ public class TestClassFileMetaData { private static String readFileAsString(File file) { try { - BufferedReader reader = new BufferedReader(new FileReader(file)); - StringWriter writer = new StringWriter(); - String line = reader.readLine(); - while(line != null) { - writer.append(line).append("\n"); - line = reader.readLine(); + FileInputStream in = new FileInputStream(file); + try { + BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8")); + StringWriter writer = new StringWriter(); + String line = reader.readLine(); + while(line != null) { + writer.append(line).append("\n"); + line = reader.readLine(); + } + reader.close(); + writer.close(); + return writer.toString(); + } finally { + in.close(); } - reader.close(); - writer.close(); - return writer.toString(); } catch (Exception e) { throw Lombok.sneakyThrow(e); } -- cgit