4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import java.nicl.metadata.C; 25 import java.nicl.metadata.CallingConvention; 26 import java.nicl.metadata.NativeHeader; 27 import java.nicl.metadata.NativeType; 28 import java.nicl.metadata.Offset; 29 import java.nio.file.Files; 30 import java.io.ByteArrayInputStream; 31 import java.io.ByteArrayOutputStream; 32 import java.io.File; 33 import java.io.IOException; 34 import java.io.PrintWriter; 35 import java.lang.annotation.Annotation; 36 import java.lang.reflect.Method; 37 import java.nio.file.Path; 38 import java.nio.file.Paths; 39 import java.util.Arrays; 40 import java.util.HashMap; 41 import java.util.HashSet; 42 import java.util.Map; 43 import java.util.Set; 44 import java.util.jar.JarEntry; 45 import java.util.jar.JarInputStream; 46 import java.util.jar.JarOutputStream; 123 JarInputStream jis = new JarInputStream(new ByteArrayInputStream(bos.toByteArray())); 124 125 // List all classes in the jar 126 Set<String> files = new HashSet<>(); 127 for (JarEntry e = jis.getNextJarEntry(); e != null; e = jis.getNextJarEntry()) { 128 if (e.isDirectory()) { 129 continue; 130 } 131 String name = e.getName(); 132 if (! name.endsWith(".class")) { 133 // Should not have file not class files 134 System.err.println("Warning: unexpected file " + name); 135 } 136 name = name.substring(0, name.length() - 6); 137 files.add(name.replace(File.separatorChar, '.')); 138 } 139 140 assertEquals(files, mfm.listClasses()); 141 } 142 143 private void verifyAnnotationC(C actual, C expected) { 144 // Only check the filename, not full path 145 assertNotNull(actual); 146 assertNotNull(expected); 147 assertEquals(Paths.get(actual.file()).getFileName(), 148 Paths.get(expected.file()).getFileName()); 149 assertEquals(actual.line(), expected.line()); 150 assertEquals(actual.column(), expected.column()); 151 } 152 153 private void verifyMethodAnnotation(Method actual, Method expected) { 154 Annotation[] aa = actual.getAnnotations(); 155 Annotation[] ea = expected.getAnnotations(); 156 // allow test case has extra annotation used by test case 157 assertTrue(ea.length >= aa.length); 158 159 for (Annotation a: ea) { 160 if (a instanceof C) { 161 verifyAnnotationC(actual.getAnnotation(C.class), (C) a); 162 } else if (a instanceof NativeType) { 163 assertEquals(actual.getAnnotation(NativeType.class), (NativeType) a); 164 } else if (a instanceof Offset) { 165 assertEquals(actual.getAnnotation(Offset.class), (Offset) a); 166 } else if (a instanceof CallingConvention) { 167 assertNotNull(actual.getAnnotation(CallingConvention.class)); 168 } 169 } 170 } 171 172 @Test(dataProvider = "classes") 173 public void testMethods(Class<?> actual, Class<?> expected) { 174 Method[] am = actual.getMethods(); 175 Method[] em = expected.getMethods(); 176 HashMap<String, Method> ams = new HashMap<>(); 177 for (Method m: am) { 178 ams.put(m.toGenericString(), m); 179 } 180 HashMap<String, Method> ems = new HashMap<>(); 181 for (Method m: em) { 182 String sig = m.toGenericString(); 183 Method ma = ams.remove(sig); 184 if (ma == null) { 185 System.out.println("Missing " + sig); 186 ems.put(m.toGenericString(), m); 187 } else { 196 System.out.println("Got: " + sig); 197 }); 198 assertTrue(ams.isEmpty()); 199 assertTrue(ems.isEmpty()); 200 } 201 202 @Test(dataProvider = "classes") 203 public void testAnnotations(Class<?> actual, Class<?> expected) { 204 Annotation[] aa = actual.getAnnotations(); 205 Annotation[] ea = expected.getAnnotations(); 206 // allow test case has extra annotation used by test case 207 assertTrue(ea.length >= aa.length); 208 209 if (actual.getName().contains("$")) { 210 assertTrue(actual.getName().contains("$")); 211 assertTrue(expected.isMemberClass()); 212 assertTrue(actual.isMemberClass()); 213 NativeType ant = actual.getAnnotation(NativeType.class); 214 assertNotNull(ant); 215 assertEquals(ant, expected.getAnnotation(NativeType.class)); 216 C ac = actual.getAnnotation(C.class); 217 assertNotNull(ac); 218 verifyAnnotationC(ac, expected.getAnnotation(C.class)); 219 } else { 220 NativeHeader ah = actual.getAnnotation(NativeHeader.class); 221 assertNotNull(ah); 222 NativeHeader eh = actual.getAnnotation(NativeHeader.class); 223 assertNotNull(eh); 224 assertEquals(Paths.get(ah.headerPath()).getFileName(), 225 Paths.get(eh.headerPath()).getFileName()); 226 } 227 228 } 229 230 private void AsmCheckClass(String name) { 231 ClassReader cr = new ClassReader(actualClz.get(name)); 232 PrintWriter pw = new PrintWriter(System.out); 233 TraceClassVisitor tcv = new TraceClassVisitor( 234 new CheckClassAdapter(new ClassNode()), 235 new Textifier(), pw); 236 try { 237 cr.accept(tcv, ClassReader.SKIP_FRAMES); 238 } catch (Throwable e) { 239 tcv.p.print(pw); 240 e.printStackTrace(pw); 241 } 242 pw.flush(); 243 } 244 245 private void AsmifyClass(String name) throws IOException { | 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import java.nicl.metadata.NativeHeader; 25 import java.nicl.metadata.NativeLocation; 26 import java.nicl.metadata.NativeStruct; 27 import java.nicl.metadata.NativeType; 28 import java.nicl.metadata.Offset; 29 import java.nio.file.Files; 30 import java.io.ByteArrayInputStream; 31 import java.io.ByteArrayOutputStream; 32 import java.io.File; 33 import java.io.IOException; 34 import java.io.PrintWriter; 35 import java.lang.annotation.Annotation; 36 import java.lang.reflect.Method; 37 import java.nio.file.Path; 38 import java.nio.file.Paths; 39 import java.util.Arrays; 40 import java.util.HashMap; 41 import java.util.HashSet; 42 import java.util.Map; 43 import java.util.Set; 44 import java.util.jar.JarEntry; 45 import java.util.jar.JarInputStream; 46 import java.util.jar.JarOutputStream; 123 JarInputStream jis = new JarInputStream(new ByteArrayInputStream(bos.toByteArray())); 124 125 // List all classes in the jar 126 Set<String> files = new HashSet<>(); 127 for (JarEntry e = jis.getNextJarEntry(); e != null; e = jis.getNextJarEntry()) { 128 if (e.isDirectory()) { 129 continue; 130 } 131 String name = e.getName(); 132 if (! name.endsWith(".class")) { 133 // Should not have file not class files 134 System.err.println("Warning: unexpected file " + name); 135 } 136 name = name.substring(0, name.length() - 6); 137 files.add(name.replace(File.separatorChar, '.')); 138 } 139 140 assertEquals(files, mfm.listClasses()); 141 } 142 143 private void verifyNativeLocation(NativeLocation actual, NativeLocation expected) { 144 // Only check the filename, not full path 145 assertNotNull(actual); 146 assertNotNull(expected); 147 assertEquals(Paths.get(actual.file()).getFileName(), 148 Paths.get(expected.file()).getFileName()); 149 assertEquals(actual.line(), expected.line()); 150 assertEquals(actual.column(), expected.column()); 151 } 152 153 private void verifyMethodAnnotation(Method actual, Method expected) { 154 Annotation[] aa = actual.getAnnotations(); 155 Annotation[] ea = expected.getAnnotations(); 156 // allow test case has extra annotation used by test case 157 assertTrue(ea.length >= aa.length); 158 159 for (Annotation a: ea) { 160 if (a instanceof NativeLocation) { 161 verifyNativeLocation(actual.getAnnotation(NativeLocation.class), (NativeLocation) a); 162 } else if (a instanceof NativeType) { 163 assertEquals(actual.getAnnotation(NativeType.class), (NativeType) a); 164 } else if (a instanceof Offset) { 165 assertEquals(actual.getAnnotation(Offset.class), (Offset) a); 166 } 167 } 168 } 169 170 @Test(dataProvider = "classes") 171 public void testMethods(Class<?> actual, Class<?> expected) { 172 Method[] am = actual.getMethods(); 173 Method[] em = expected.getMethods(); 174 HashMap<String, Method> ams = new HashMap<>(); 175 for (Method m: am) { 176 ams.put(m.toGenericString(), m); 177 } 178 HashMap<String, Method> ems = new HashMap<>(); 179 for (Method m: em) { 180 String sig = m.toGenericString(); 181 Method ma = ams.remove(sig); 182 if (ma == null) { 183 System.out.println("Missing " + sig); 184 ems.put(m.toGenericString(), m); 185 } else { 194 System.out.println("Got: " + sig); 195 }); 196 assertTrue(ams.isEmpty()); 197 assertTrue(ems.isEmpty()); 198 } 199 200 @Test(dataProvider = "classes") 201 public void testAnnotations(Class<?> actual, Class<?> expected) { 202 Annotation[] aa = actual.getAnnotations(); 203 Annotation[] ea = expected.getAnnotations(); 204 // allow test case has extra annotation used by test case 205 assertTrue(ea.length >= aa.length); 206 207 if (actual.getName().contains("$")) { 208 assertTrue(actual.getName().contains("$")); 209 assertTrue(expected.isMemberClass()); 210 assertTrue(actual.isMemberClass()); 211 NativeType ant = actual.getAnnotation(NativeType.class); 212 assertNotNull(ant); 213 assertEquals(ant, expected.getAnnotation(NativeType.class)); 214 NativeLocation loc = actual.getAnnotation(NativeLocation.class); 215 assertNotNull(loc); 216 verifyNativeLocation(loc, expected.getAnnotation(NativeLocation.class)); 217 } else { 218 NativeHeader ah = actual.getAnnotation(NativeHeader.class); 219 assertNotNull(ah); 220 NativeHeader eh = actual.getAnnotation(NativeHeader.class); 221 assertNotNull(eh); 222 assertEquals(Paths.get(ah.path()).getFileName(), 223 Paths.get(eh.path()).getFileName()); 224 } 225 226 } 227 228 private void AsmCheckClass(String name) { 229 ClassReader cr = new ClassReader(actualClz.get(name)); 230 PrintWriter pw = new PrintWriter(System.out); 231 TraceClassVisitor tcv = new TraceClassVisitor( 232 new CheckClassAdapter(new ClassNode()), 233 new Textifier(), pw); 234 try { 235 cr.accept(tcv, ClassReader.SKIP_FRAMES); 236 } catch (Throwable e) { 237 tcv.p.print(pw); 238 e.printStackTrace(pw); 239 } 240 pw.flush(); 241 } 242 243 private void AsmifyClass(String name) throws IOException { |