1 /* 2 * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.tools.javac.sym; 27 28 import com.sun.tools.javac.api.JavacTaskImpl; 29 import com.sun.tools.javac.code.Kinds; 30 import com.sun.tools.javac.code.Scope; 31 import com.sun.tools.javac.code.Symbol.*; 32 import com.sun.tools.javac.code.Symbol; 33 import com.sun.tools.javac.code.Attribute; 34 import com.sun.tools.javac.code.Symtab; 35 import com.sun.tools.javac.code.Type; 36 import com.sun.tools.javac.code.Types; 37 import com.sun.tools.javac.jvm.ClassReader; 38 import com.sun.tools.javac.jvm.ClassWriter; 39 import com.sun.tools.javac.jvm.Pool; 40 import com.sun.tools.javac.processing.JavacProcessingEnvironment; 41 import com.sun.tools.javac.util.List; 42 import com.sun.tools.javac.util.Pair; 43 44 import java.io.File; 45 import java.io.IOException; 46 import java.util.ArrayList; 47 import java.util.EnumSet; 48 import java.util.Enumeration; 49 import java.util.HashSet; 50 import java.util.ResourceBundle; 51 import java.util.Set; 52 53 import javax.annotation.processing.AbstractProcessor; 54 import javax.annotation.processing.RoundEnvironment; 55 import javax.annotation.processing.SupportedAnnotationTypes; 56 import javax.annotation.processing.SupportedOptions; 57 import javax.lang.model.SourceVersion; 58 import javax.lang.model.element.ElementKind; 59 import javax.lang.model.element.TypeElement; 60 import javax.tools.Diagnostic; 61 import javax.tools.JavaCompiler; 62 import javax.tools.JavaFileManager.Location; 63 import javax.tools.JavaFileObject; 64 import static javax.tools.JavaFileObject.Kind.CLASS; 65 import javax.tools.StandardJavaFileManager; 66 import javax.tools.StandardLocation; 67 import javax.tools.ToolProvider; 68 69 /** 70 * Used to generate a "symbol file" representing rt.jar that only 71 * includes supported or legacy proprietary API. Valid annotation 72 * processor options: 73 * 74 * <dl> 75 * <dt>com.sun.tools.javac.sym.Jar</dt> 76 * <dd>Specifies the location of rt.jar.</dd> 77 * <dt>com.sun.tools.javac.sym.Dest</dt> 78 * <dd>Specifies the destination directory.</dd> 79 * </dl> 80 * 81 * <p><b>This is NOT part of any supported API. 82 * If you write code that depends on this, you do so at your own 83 * risk. This code and its internal interfaces are subject to change 84 * or deletion without notice.</b></p> 85 * 86 * @author Peter von der Ah\u00e9 87 */ 88 @SupportedOptions({"com.sun.tools.javac.sym.Jar","com.sun.tools.javac.sym.Dest"}) 89 @SupportedAnnotationTypes("*") 90 public class CreateSymbols extends AbstractProcessor { 91 92 static Set<String> getLegacyPackages() { 93 ResourceBundle legacyBundle 94 = ResourceBundle.getBundle("com.sun.tools.javac.resources.legacy"); 95 Set<String> keys = new HashSet<String>(); 96 for (Enumeration<String> e = legacyBundle.getKeys(); e.hasMoreElements(); ) 97 keys.add(e.nextElement()); 98 return keys; 99 } 100 101 public boolean process(Set<? extends TypeElement> tes, RoundEnvironment renv) { 102 try { 103 if (renv.processingOver()) 104 createSymbols(); 105 } catch (IOException e) { 106 processingEnv.getMessager() 107 .printMessage(Diagnostic.Kind.ERROR, e.getLocalizedMessage()); 108 } catch (Throwable t) { 109 Throwable cause = t.getCause(); 110 if (cause == null) 111 cause = t; 112 processingEnv.getMessager() 113 .printMessage(Diagnostic.Kind.ERROR, cause.getLocalizedMessage()); 114 } 115 return true; 116 } 117 118 void createSymbols() throws IOException { 119 Set<String> legacy = getLegacyPackages(); 120 Set<String> legacyProprietary = getLegacyPackages(); 121 Set<String> documented = new HashSet<String>(); 122 Set<PackageSymbol> packages = 123 ((JavacProcessingEnvironment)processingEnv).getSpecifiedPackages(); 124 String jarName = processingEnv.getOptions().get("com.sun.tools.javac.sym.Jar"); 125 if (jarName == null) 126 throw new RuntimeException("Must use -Acom.sun.tools.javac.sym.Jar=LOCATION_OF_JAR"); 127 String destName = processingEnv.getOptions().get("com.sun.tools.javac.sym.Dest"); 128 if (destName == null) 129 throw new RuntimeException("Must use -Acom.sun.tools.javac.sym.Dest=LOCATION_OF_JAR"); 130 131 for (PackageSymbol psym : packages) { 132 String name = psym.getQualifiedName().toString(); 133 legacyProprietary.remove(name); 134 documented.add(name); 135 } 136 137 JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); 138 StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); 139 Location jarLocation = StandardLocation.locationFor(jarName); 140 File jarFile = new File(jarName); 141 fm.setLocation(jarLocation, List.of(jarFile)); 142 fm.setLocation(StandardLocation.CLASS_PATH, List.<File>nil()); 143 fm.setLocation(StandardLocation.SOURCE_PATH, List.<File>nil()); 144 { 145 ArrayList<File> bootClassPath = new ArrayList<File>(); 146 bootClassPath.add(jarFile); 147 for (File path : fm.getLocation(StandardLocation.PLATFORM_CLASS_PATH)) { 148 if (!new File(path.getName()).equals(new File("rt.jar"))) 149 bootClassPath.add(path); 150 } 151 System.err.println("Using boot class path = " + bootClassPath); 152 fm.setLocation(StandardLocation.PLATFORM_CLASS_PATH, bootClassPath); 153 } 154 // System.out.println(fm.getLocation(StandardLocation.PLATFORM_CLASS_PATH)); 155 File destDir = new File(destName); 156 if (!destDir.exists()) 157 if (!destDir.mkdirs()) 158 throw new RuntimeException("Could not create " + destDir); 159 fm.setLocation(StandardLocation.CLASS_OUTPUT, List.of(destDir)); 160 Set<String> hiddenPackages = new HashSet<String>(); 161 Set<String> crisp = new HashSet<String>(); 162 List<String> options = List.of("-XDdev"); 163 // options = options.prepend("-doe"); 164 // options = options.prepend("-verbose"); 165 JavacTaskImpl task = (JavacTaskImpl) 166 tool.getTask(null, fm, null, options, null, null); 167 com.sun.tools.javac.main.JavaCompiler compiler = 168 com.sun.tools.javac.main.JavaCompiler.instance(task.getContext()); 169 ClassReader reader = ClassReader.instance(task.getContext()); 170 ClassWriter writer = ClassWriter.instance(task.getContext()); 171 Symtab syms = Symtab.instance(task.getContext()); 172 Attribute.Compound proprietary = 173 new Attribute.Compound(syms.proprietaryType, 174 List.<Pair<Symbol.MethodSymbol,Attribute>>nil()); 175 176 Type.moreInfo = true; 177 Types types = Types.instance(task.getContext()); 178 Pool pool = new Pool(types); 179 for (JavaFileObject file : fm.list(jarLocation, "", EnumSet.of(CLASS), true)) { 180 String className = fm.inferBinaryName(jarLocation, file); 181 int index = className.lastIndexOf('.'); 182 String pckName = index == -1 ? "" : className.substring(0, index); 183 boolean addLegacyAnnotation = false; 184 if (documented.contains(pckName)) { 185 if (!legacy.contains(pckName)) 186 crisp.add(pckName); 187 // System.out.println("Documented: " + className); 188 } else if (legacyProprietary.contains(pckName)) { 189 addLegacyAnnotation = true; 190 // System.out.println("Legacy proprietary: " + className); 191 } else { 192 // System.out.println("Hidden " + className); 193 hiddenPackages.add(pckName); 194 continue; 195 } 196 TypeSymbol sym = (TypeSymbol)compiler.resolveIdent(className); 197 if (sym.kind != Kinds.TYP) { 198 if (className.indexOf('$') < 0) { 199 System.err.println("Ignoring (other) " + className + " : " + sym); 200 System.err.println(" " + sym.getClass().getSimpleName() + " " + sym.type); 201 } 202 continue; 203 } 204 sym.complete(); 205 if (sym.getEnclosingElement().getKind() != ElementKind.PACKAGE) { 206 System.err.println("Ignoring (bad) " + sym.getQualifiedName()); 207 continue; 208 } 209 ClassSymbol cs = (ClassSymbol) sym; 210 if (addLegacyAnnotation) { 211 cs.annotations.prepend(List.of(proprietary)); 212 } 213 writeClass(pool, cs, writer); 214 } 215 216 if (false) { 217 for (String pckName : crisp) 218 System.out.println("Crisp: " + pckName); 219 for (String pckName : hiddenPackages) 220 System.out.println("Hidden: " + pckName); 221 for (String pckName : legacyProprietary) 222 System.out.println("Legacy proprietary: " + pckName); 223 for (String pckName : documented) 224 System.out.println("Documented: " + pckName); 225 } 226 } 227 228 void writeClass(final Pool pool, final ClassSymbol cs, final ClassWriter writer) 229 throws IOException 230 { 231 try { 232 pool.reset(); 233 cs.pool = pool; 234 writer.writeClass(cs); 235 for (Scope.Entry e = cs.members().elems; e != null; e = e.sibling) { 236 if (e.sym.kind == Kinds.TYP) { 237 ClassSymbol nestedClass = (ClassSymbol)e.sym; 238 nestedClass.complete(); 239 writeClass(pool, nestedClass, writer); 240 } 241 } 242 } catch (ClassWriter.StringOverflow ex) { 243 throw new RuntimeException(ex); 244 } catch (ClassWriter.PoolOverflow ex) { 245 throw new RuntimeException(ex); 246 } 247 } 248 249 public SourceVersion getSupportedSourceVersion() { 250 return SourceVersion.latest(); 251 } 252 253 // used for debugging 254 public static void main(String... args) { 255 String rt_jar = args[0]; 256 String dest = args[1]; 257 args = new String[] { 258 "-Xbootclasspath:" + rt_jar, 259 "-XDprocess.packages", 260 "-proc:only", 261 "-processor", 262 "com.sun.tools.javac.sym.CreateSymbols", 263 "-Acom.sun.tools.javac.sym.Jar=" + rt_jar, 264 "-Acom.sun.tools.javac.sym.Dest=" + dest, 265 // <editor-fold defaultstate="collapsed"> 266 "java.applet", 267 "java.awt", 268 "java.awt.color", 269 "java.awt.datatransfer", 270 "java.awt.dnd", 271 "java.awt.event", 272 "java.awt.font", 273 "java.awt.geom", 274 "java.awt.im", 275 "java.awt.im.spi", 276 "java.awt.image", 277 "java.awt.image.renderable", 278 "java.awt.print", 279 "java.beans", 280 "java.beans.beancontext", 281 "java.io", 282 "java.lang", 283 "java.lang.annotation", 284 "java.lang.instrument", 285 "java.lang.management", 286 "java.lang.ref", 287 "java.lang.reflect", 288 "java.math", 289 "java.net", 290 "java.nio", 291 "java.nio.channels", 292 "java.nio.channels.spi", 293 "java.nio.charset", 294 "java.nio.charset.spi", 295 "java.rmi", 296 "java.rmi.activation", 297 "java.rmi.dgc", 298 "java.rmi.registry", 299 "java.rmi.server", 300 "java.security", 301 "java.security.acl", 302 "java.security.cert", 303 "java.security.interfaces", 304 "java.security.spec", 305 "java.sql", 306 "java.text", 307 "java.text.spi", 308 "java.util", 309 "java.util.concurrent", 310 "java.util.concurrent.atomic", 311 "java.util.concurrent.locks", 312 "java.util.jar", 313 "java.util.logging", 314 "java.util.prefs", 315 "java.util.regex", 316 "java.util.spi", 317 "java.util.zip", 318 "javax.accessibility", 319 "javax.activation", 320 "javax.activity", 321 "javax.annotation", 322 "javax.annotation.processing", 323 "javax.crypto", 324 "javax.crypto.interfaces", 325 "javax.crypto.spec", 326 "javax.imageio", 327 "javax.imageio.event", 328 "javax.imageio.metadata", 329 "javax.imageio.plugins.jpeg", 330 "javax.imageio.plugins.bmp", 331 "javax.imageio.spi", 332 "javax.imageio.stream", 333 "javax.jws", 334 "javax.jws.soap", 335 "javax.lang.model", 336 "javax.lang.model.element", 337 "javax.lang.model.type", 338 "javax.lang.model.util", 339 "javax.management", 340 "javax.management.loading", 341 "javax.management.monitor", 342 "javax.management.relation", 343 "javax.management.openmbean", 344 "javax.management.timer", 345 "javax.management.modelmbean", 346 "javax.management.remote", 347 "javax.management.remote.rmi", 348 "javax.naming", 349 "javax.naming.directory", 350 "javax.naming.event", 351 "javax.naming.ldap", 352 "javax.naming.spi", 353 "javax.net", 354 "javax.net.ssl", 355 "javax.print", 356 "javax.print.attribute", 357 "javax.print.attribute.standard", 358 "javax.print.event", 359 "javax.rmi", 360 "javax.rmi.CORBA", 361 "javax.rmi.ssl", 362 "javax.script", 363 "javax.security.auth", 364 "javax.security.auth.callback", 365 "javax.security.auth.kerberos", 366 "javax.security.auth.login", 367 "javax.security.auth.spi", 368 "javax.security.auth.x500", 369 "javax.security.cert", 370 "javax.security.sasl", 371 "javax.sound.sampled", 372 "javax.sound.sampled.spi", 373 "javax.sound.midi", 374 "javax.sound.midi.spi", 375 "javax.sql", 376 "javax.sql.rowset", 377 "javax.sql.rowset.serial", 378 "javax.sql.rowset.spi", 379 "javax.swing", 380 "javax.swing.border", 381 "javax.swing.colorchooser", 382 "javax.swing.filechooser", 383 "javax.swing.event", 384 "javax.swing.table", 385 "javax.swing.text", 386 "javax.swing.text.html", 387 "javax.swing.text.html.parser", 388 "javax.swing.text.rtf", 389 "javax.swing.tree", 390 "javax.swing.undo", 391 "javax.swing.plaf", 392 "javax.swing.plaf.basic", 393 "javax.swing.plaf.metal", 394 "javax.swing.plaf.multi", 395 "javax.swing.plaf.synth", 396 "javax.tools", 397 "javax.transaction", 398 "javax.transaction.xa", 399 "javax.xml.parsers", 400 "javax.xml.bind", 401 "javax.xml.bind.annotation", 402 "javax.xml.bind.annotation.adapters", 403 "javax.xml.bind.attachment", 404 "javax.xml.bind.helpers", 405 "javax.xml.bind.util", 406 "javax.xml.soap", 407 "javax.xml.ws", 408 "javax.xml.ws.handler", 409 "javax.xml.ws.handler.soap", 410 "javax.xml.ws.http", 411 "javax.xml.ws.soap", 412 "javax.xml.ws.spi", 413 "javax.xml.transform", 414 "javax.xml.transform.sax", 415 "javax.xml.transform.dom", 416 "javax.xml.transform.stax", 417 "javax.xml.transform.stream", 418 "javax.xml", 419 "javax.xml.crypto", 420 "javax.xml.crypto.dom", 421 "javax.xml.crypto.dsig", 422 "javax.xml.crypto.dsig.dom", 423 "javax.xml.crypto.dsig.keyinfo", 424 "javax.xml.crypto.dsig.spec", 425 "javax.xml.datatype", 426 "javax.xml.validation", 427 "javax.xml.namespace", 428 "javax.xml.xpath", 429 "javax.xml.stream", 430 "javax.xml.stream.events", 431 "javax.xml.stream.util", 432 "org.ietf.jgss", 433 "org.omg.CORBA", 434 "org.omg.CORBA.DynAnyPackage", 435 "org.omg.CORBA.ORBPackage", 436 "org.omg.CORBA.TypeCodePackage", 437 "org.omg.stub.java.rmi", 438 "org.omg.CORBA.portable", 439 "org.omg.CORBA_2_3", 440 "org.omg.CORBA_2_3.portable", 441 "org.omg.CosNaming", 442 "org.omg.CosNaming.NamingContextExtPackage", 443 "org.omg.CosNaming.NamingContextPackage", 444 "org.omg.SendingContext", 445 "org.omg.PortableServer", 446 "org.omg.PortableServer.CurrentPackage", 447 "org.omg.PortableServer.POAPackage", 448 "org.omg.PortableServer.POAManagerPackage", 449 "org.omg.PortableServer.ServantLocatorPackage", 450 "org.omg.PortableServer.portable", 451 "org.omg.PortableInterceptor", 452 "org.omg.PortableInterceptor.ORBInitInfoPackage", 453 "org.omg.Messaging", 454 "org.omg.IOP", 455 "org.omg.IOP.CodecFactoryPackage", 456 "org.omg.IOP.CodecPackage", 457 "org.omg.Dynamic", 458 "org.omg.DynamicAny", 459 "org.omg.DynamicAny.DynAnyPackage", 460 "org.omg.DynamicAny.DynAnyFactoryPackage", 461 "org.w3c.dom", 462 "org.w3c.dom.events", 463 "org.w3c.dom.bootstrap", 464 "org.w3c.dom.ls", 465 "org.xml.sax", 466 "org.xml.sax.ext", 467 "org.xml.sax.helpers", 468 "com.sun.java.browser.dom", 469 "org.w3c.dom", 470 "org.w3c.dom.bootstrap", 471 "org.w3c.dom.ls", 472 "org.w3c.dom.ranges", 473 "org.w3c.dom.traversal", 474 "org.w3c.dom.html", 475 "org.w3c.dom.stylesheets", 476 "org.w3c.dom.css", 477 "org.w3c.dom.events", 478 "org.w3c.dom.views", 479 "com.sun.management", 480 "com.sun.security.auth", 481 "com.sun.security.auth.callback", 482 "com.sun.security.auth.login", 483 "com.sun.security.auth.module", 484 "com.sun.security.jgss", 485 "com.sun.net.httpserver", 486 "com.sun.net.httpserver.spi", 487 "javax.smartcardio" 488 // </editor-fold> 489 }; 490 com.sun.tools.javac.Main.compile(args); 491 } 492 493 }