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