1 19 20 package org.netbeans.modules.java.source.usages; 21 22 import com.sun.source.util.JavacTask; 23 import com.sun.tools.javac.api.JavacTaskImpl; 24 import com.sun.tools.javac.model.JavacElements; 25 import java.util.Arrays ; 26 import java.util.Collections ; 27 import java.util.LinkedList ; 28 import java.util.StringTokenizer ; 29 import java.util.zip.ZipEntry ; 30 import java.util.zip.ZipFile ; 31 import javax.lang.model.element.Element; 32 import javax.lang.model.element.ElementKind; 33 import javax.lang.model.element.ExecutableElement; 34 import javax.lang.model.element.TypeElement; 35 import javax.lang.model.element.VariableElement; 36 import javax.lang.model.util.Elements; 37 import javax.tools.JavaCompiler; 38 import javax.tools.JavaCompiler.CompilationTask; 39 import javax.tools.JavaFileObject; 40 import javax.tools.StandardJavaFileManager; 41 import javax.tools.ToolProvider; 42 import java.io.File ; 43 import java.io.InputStream ; 44 import java.util.EnumSet ; 45 import java.util.HashSet ; 46 import java.util.List ; 47 import java.util.Set ; 48 import org.netbeans.junit.NbTestCase; 49 import org.netbeans.modules.classfile.ClassFile; 50 import org.netbeans.modules.classfile.ClassName; 51 import org.netbeans.modules.classfile.Method; 52 import org.netbeans.modules.classfile.Variable; 53 import org.netbeans.modules.java.source.parsing.FileObjects; 54 import org.netbeans.modules.java.source.usages.ClassIndexImpl.UsageType; 55 56 60 public class CompromiseSATest extends NbTestCase { 61 62 private static final String TEST_CLASS = "java.util.ArrayList"; private static final String TEST_INNER_CLASS = "java.util.Collections$SingletonSet"; private static final String TEST_INNER_CLASS_2 = "java.util.Collections$SingletonMap$ImmutableEntry"; private static final String TEST_INNER_CLASS_3 = "javax.swing.JTable$AccessibleJTable$AccessibleJTableCell"; private static final String TEST_ANNON_CLASS = "java.lang.String$1"; 68 private static final String [] METHOD_TYPE_SIGNATURES = new String [] { 69 "<S:Ljava/lang/String;L:Ljava/lang/Long;>(TS;TL;)TT;", 70 "<C::Ljava/lang/Comparable<+Lfoo/A;>;>(TC;Lfoo/A;)I", 71 "(ILjava/util/Set<Ljava/lang/Integer;>;)V", 72 "<X:Ljava/lang/Object;:Ljava/lang/Comparable<-TX;>;>(Ljava/util/Set<TX;>;)TX;" 73 }; 74 75 private static final String [][] METHOD_TYPE_SIGNATURES_RESULT = new String [][] { 76 new String [] { 77 "java/lang/String", 78 "java/lang/Long" 79 }, 80 new String [] { 81 "java/lang/Comparable", 82 "foo/A" 83 }, 84 new String [] { 85 "java/lang/Integer" 86 }, 87 new String [] { 88 "java/lang/Object", 89 "java/lang/Comparable", 90 } 91 }; 92 93 private static final String [] FIELD_TYPE_SIGNATURES = new String [] { 94 "TT;", 95 "Ljava/util/Collection<Ljava/lang/Long;>;", 96 "Lfoo/A<TT;>;", 97 "Ljava/util/Set<Ljava/lang/Integer;>;", 98 "Ljava/util/Set<TX;>;", 99 }; 100 101 private static final String [][] FIELD_TYPE_SIGNATURES_RESULT = new String [][] { 102 new String [0], 103 new String [] { 104 "java/lang/Long" 105 }, 106 new String [0], 107 new String [] { 108 "java/lang/Integer", 109 }, 110 new String [0] 111 }; 112 113 private static final String [] CLASS_TYPE_SIGNATURES = new String [] { 114 "<T:Ljava/lang/Integer;>Ljava/lang/Object;" 115 }; 116 117 private static final String [][] CLASS_TYPE_SIGNATURES_RESLT = new String [][] { 118 new String [] { 119 "java/lang/Integer" 120 } 121 }; 122 123 public CompromiseSATest(String testName) { 124 super(testName); 125 } 126 127 protected @Override void setUp() throws Exception { 128 super.setUp(); 129 this.clearWorkDir(); 130 } 131 132 133 136 public void testEncodeUsageType() { 137 EnumSet <UsageType> c = EnumSet.noneOf(UsageType.class); 138 c.add (UsageType.SUPER_CLASS); 139 c.add (UsageType.SUPER_INTERFACE); 140 String s = DocumentUtil.encodeUsage("foo", c); 141 Set <UsageType> r = EnumSet.noneOf(UsageType.class); 142 DocumentUtil.decodeUsage(s,r); 143 assertEquals(c.size(), r.size()); 144 assertTrue(r.containsAll(c)); 145 c.clear(); 146 c.add (UsageType.TYPE_REFERENCE); 147 s = DocumentUtil.encodeUsage("foo", c); 148 r = EnumSet.noneOf(UsageType.class); 149 DocumentUtil.decodeUsage(s,r); 150 assertEquals(c.size(), r.size()); 151 assertTrue(r.containsAll(c)); 152 c.clear(); 153 c.add (UsageType.SUPER_CLASS); 154 c.add (UsageType.TYPE_REFERENCE); 155 c.add (UsageType.FIELD_REFERENCE); 156 s = DocumentUtil.encodeUsage("foo", c); 157 r = EnumSet.noneOf(UsageType.class); 158 DocumentUtil.decodeUsage(s,r); 159 assertEquals(c.size(), r.size()); 160 assertTrue(r.containsAll(c)); 161 c.clear(); 162 c.add (UsageType.SUPER_CLASS); 163 c.add (UsageType.METHOD_REFERENCE); 164 s = DocumentUtil.encodeUsage("foo", c); 165 r = EnumSet.noneOf(UsageType.class); 166 DocumentUtil.decodeUsage(s,r); 167 assertEquals(c.size(), r.size()); 168 assertTrue(r.containsAll(c)); 169 c.clear(); 170 c.allOf(UsageType.class); 171 s = DocumentUtil.encodeUsage("foo", c); 172 r = EnumSet.noneOf(UsageType.class); 173 DocumentUtil.decodeUsage(s,r); 174 assertEquals(c.size(), r.size()); 175 assertTrue(r.containsAll(c)); 176 c.clear(); 177 c.add (UsageType.SUPER_INTERFACE); 178 c.add (UsageType.METHOD_REFERENCE); 179 s = DocumentUtil.encodeUsage("foo", c); 180 r = EnumSet.noneOf(UsageType.class); 181 DocumentUtil.decodeUsage(s,r); 182 assertEquals(c.size(), r.size()); 183 assertTrue(r.containsAll(c)); 184 c.clear(); 185 } 186 187 188 public void testClassTypeSignatureParser () { 189 for (int i=0; i< CLASS_TYPE_SIGNATURES.length; i++) { 190 String sig = CLASS_TYPE_SIGNATURES[i]; 191 ClassName[] names = ClassFileUtil.getTypesFromClassTypeSignature(sig); 192 assertEquals(CLASS_TYPE_SIGNATURES_RESLT[i].length, names.length); 193 assertEqulas (CLASS_TYPE_SIGNATURES_RESLT[i], names); 194 } 195 } 196 197 public void testFieldTypeSignatureParser () { 198 for (int i=0; i< FIELD_TYPE_SIGNATURES.length; i++) { 199 String sig = FIELD_TYPE_SIGNATURES[i]; 200 ClassName[] names = ClassFileUtil.getTypesFromFiledTypeSignature(sig); 201 assertEquals(FIELD_TYPE_SIGNATURES_RESULT[i].length, names.length); 202 assertEqulas (FIELD_TYPE_SIGNATURES_RESULT[i], names); 203 } 204 } 205 206 public void testMethodTypeSignatureParser () { 207 for (int i=0; i< METHOD_TYPE_SIGNATURES.length; i++) { 208 String sig = METHOD_TYPE_SIGNATURES[i]; 209 ClassName[] names = ClassFileUtil.getTypesFromMethodTypeSignature(sig); 210 assertEquals(METHOD_TYPE_SIGNATURES_RESULT[i].length, names.length); 211 assertEqulas (METHOD_TYPE_SIGNATURES_RESULT[i], names); 212 } 213 } 214 215 public void testClassSignatureFromElement () throws Exception { 216 performClassSignatureFromElementTest (TEST_CLASS); 217 performClassSignatureFromElementTest (TEST_INNER_CLASS); 218 performClassSignatureFromElementTest (TEST_INNER_CLASS_2); 219 performClassSignatureFromElementTest (TEST_INNER_CLASS_3); 220 performClassSignatureFromElementTest (TEST_ANNON_CLASS); 221 } 222 223 private void performClassSignatureFromElementTest (final String testClassName) throws Exception { 224 InputStream in = this.prepareData (testClassName); 225 try { 226 JavacTask jt = prepareJavac (); 227 JavacElements elements = (JavacElements) jt.getElements(); 228 TypeElement be = elements.getTypeElementByBinaryName(testClassName); 229 assertNotNull ("Javac Error", be); 230 String className = ClassFileUtil.encodeClassName(be); 231 ClassFile cf = new ClassFile (in, true); 232 String expectedName = cf.getName().getInternalName().replace('/','.'); assertEquals (expectedName, className); 234 } finally { 235 in.close (); 236 } 237 } 238 239 public void testMethodSignatureFromElement () throws Exception { 240 InputStream in = this.prepareData(TEST_CLASS); 241 try { 242 JavacTask jt = prepareJavac (); 243 Elements elements = jt.getElements(); 244 TypeElement be = elements.getTypeElement(TEST_CLASS); 245 ClassFile cf = new ClassFile (in, true); 246 String className = cf.getName().getInternalName().replace('/','.'); List <? extends Element> members = be.getEnclosedElements(); 248 for (Element e : members) { 249 if (e.getKind() == ElementKind.METHOD) { 250 String [] msig = ClassFileUtil.createExecutableDescriptor((ExecutableElement) e); 251 assertEquals (className,msig[0]); 252 assertEquals (e.getSimpleName().toString(),msig[1]); 253 Method m = cf.getMethod(e.getSimpleName().toString(),msig[2]); 254 assertNotNull (m); 255 } 256 } 257 } finally { 258 in.close (); 259 } 260 } 261 262 public void testConstructorSignatureFromElement () throws Exception { 263 InputStream in = this.prepareData(TEST_CLASS); 264 try { 265 JavacTask jt = prepareJavac (); 266 Elements elements = jt.getElements(); 267 TypeElement be = elements.getTypeElement(TEST_CLASS); 268 ClassFile cf = new ClassFile (in, true); 269 String className = cf.getName().getInternalName().replace('/','.'); List <? extends Element> members = be.getEnclosedElements(); 271 for (Element e : members) { 272 if (e.getKind() == ElementKind.CONSTRUCTOR) { 273 String [] msig = ClassFileUtil.createExecutableDescriptor((ExecutableElement) e); 274 assertEquals (className,msig[0]); 275 assertEquals (e.getSimpleName().toString(),msig[1]); 276 Method m = cf.getMethod (e.getSimpleName().toString(),msig[2]); 277 assertNotNull (m); 278 } 279 } 280 } finally { 281 in.close (); 282 } 283 } 284 285 public void testFieldSignatureFromElement () throws Exception { 286 InputStream in = this.prepareData(TEST_CLASS); 287 try { 288 JavacTask jt = prepareJavac (); 289 Elements elements = jt.getElements(); 290 TypeElement be = elements.getTypeElement(TEST_CLASS); 291 ClassFile cf = new ClassFile (in, true); 292 String className = cf.getName().getInternalName().replace('/','.'); List <? extends Element> members = be.getEnclosedElements(); 294 for (Element e : members) { 295 if (e.getKind() == ElementKind.FIELD) { 296 String [] msig = ClassFileUtil.createFieldDescriptor((VariableElement) e); 297 assertEquals (className,msig[0]); 298 assertEquals (e.getSimpleName().toString(),msig[1]); 299 Variable v = cf.getVariable (e.getSimpleName().toString()); 300 assertNotNull (v); 301 assertEquals (v.getDescriptor(), msig[2]); 302 } 303 } 304 } finally { 305 in.close (); 306 } 307 } 308 309 330 private String getBootClassPath () { 331 String bootCp = System.getProperty ("sun.boot.class.path"); 332 assert bootCp != null; 333 return bootCp; 334 } 335 336 private File getRT_JAR () { 337 StringTokenizer tk = new StringTokenizer (getBootClassPath (), File.pathSeparator); 338 while (tk.hasMoreTokens()) { 339 String token = tk.nextToken(); 340 if (token.endsWith("rt.jar")) { 341 File f = new File (token); 342 assert f.canRead(); 343 return f; 344 } 345 } 346 throw new AssertionError (); 347 } 348 349 private InputStream prepareData (final String testClassName) throws Exception { 350 ZipFile zf = new ZipFile (getRT_JAR()); 351 ZipEntry ze = zf.getEntry(testClassName.replace('.','/')+".class"); 352 InputStream in = zf.getInputStream(ze); 353 return in; 354 } 355 356 private JavacTask prepareJavac () throws Exception { 357 return prepareJavac (Collections.<JavaFileObject>emptySet()); 358 } 359 360 361 private JavacTask prepareJavac (Iterable <JavaFileObject> toParse) throws Exception { 362 JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); 363 StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); 364 List <String > options = new LinkedList <String >(); 365 options.add ("-Xjcov"); options.add ("-g:"); options.add ("-g:lines" ); options.add("-g:vars" ); options.add ("-bootclasspath"); 370 options.add (getBootClassPath()); 371 CompilationTask jt = tool.getTask(null,fm,null,options,null,toParse); 372 assert jt instanceof JavacTask; 373 return (JavacTask)jt; 374 } 375 376 private void assertEqulas (String [] result, ClassName[] names) { 377 Set <String > res = new HashSet <String > (Arrays.asList(result)); 378 for (ClassName cn: names) { 379 String in = cn.getInternalName(); 380 if (!res.remove(in)) { 381 assertTrue(false); 382 } 383 } 384 } 385 386 387 388 } 389 | Popular Tags |