createsymbols.java
来自「是一款用JAVA 编写的编译器 具有很强的编译功能」· Java 代码 · 共 496 行 · 第 1/2 页
JAVA
496 行
/* * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */package com.sun.tools.javac.sym;import com.sun.tools.javac.api.JavacTaskImpl;import com.sun.tools.javac.code.Kinds;import com.sun.tools.javac.code.Scope;import com.sun.tools.javac.code.Symbol.*;import com.sun.tools.javac.code.Symbol;import com.sun.tools.javac.code.Attribute;import com.sun.tools.javac.code.Symtab;import com.sun.tools.javac.code.Type;import com.sun.tools.javac.jvm.ClassReader;import com.sun.tools.javac.jvm.ClassWriter;import com.sun.tools.javac.jvm.Pool;import com.sun.tools.javac.processing.JavacProcessingEnvironment;import com.sun.tools.javac.util.List;import com.sun.tools.javac.util.Pair;import com.sun.tools.javac.util.Name;import java.io.File;import java.io.IOException;import java.util.ArrayList;import java.util.EnumSet;import java.util.Enumeration;import java.util.HashSet;import java.util.Properties;import java.util.ResourceBundle;import java.util.Set;import javax.annotation.processing.AbstractProcessor;import javax.annotation.processing.RoundEnvironment;import javax.annotation.processing.SupportedAnnotationTypes;import javax.annotation.processing.SupportedOptions;import javax.lang.model.SourceVersion;import javax.lang.model.element.ElementKind;import javax.lang.model.element.TypeElement;import javax.tools.Diagnostic;import javax.tools.JavaCompiler;import javax.tools.JavaFileManager.Location;import javax.tools.JavaFileObject;import static javax.tools.JavaFileObject.Kind.CLASS;import javax.tools.StandardJavaFileManager;import javax.tools.StandardLocation;import javax.tools.ToolProvider;/** * Used to generate a "symbol file" representing rt.jar that only * includes supported or legacy proprietary API. Valid annotation * processor options: * * <dl> * <dt>com.sun.tools.javac.sym.Jar</dt> * <dd>Specifies the location of rt.jar.</dd> * <dt>com.sun.tools.javac.sym.Dest</dt> * <dd>Specifies the destination directory.</dd> * </dl> * * <p><b>This is NOT part of any API supported by Sun Microsystems. * If you write code that depends on this, you do so at your own * risk. This code and its internal interfaces are subject to change * or deletion without notice.</b></p> * * @author Peter von der Ah\u00e9 */@SupportedOptions({"com.sun.tools.javac.sym.Jar","com.sun.tools.javac.sym.Dest"})@SupportedAnnotationTypes("*")public class CreateSymbols extends AbstractProcessor { static Set<String> getLegacyPackages() { ResourceBundle legacyBundle = ResourceBundle.getBundle("com.sun.tools.javac.resources.legacy"); Set<String> keys = new HashSet<String>(); for (Enumeration<String> e = legacyBundle.getKeys(); e.hasMoreElements(); ) keys.add(e.nextElement()); return keys; } public boolean process(Set<? extends TypeElement> tes, RoundEnvironment renv) { try { if (renv.processingOver()) createSymbols(); } catch (IOException e) { processingEnv.getMessager() .printMessage(Diagnostic.Kind.ERROR, e.getLocalizedMessage()); } catch (Throwable t) { Throwable cause = t.getCause(); if (cause == null) cause = t; processingEnv.getMessager() .printMessage(Diagnostic.Kind.ERROR, cause.getLocalizedMessage()); } return true; } void createSymbols() throws IOException { Set<String> legacy = getLegacyPackages(); Set<String> legacyProprietary = getLegacyPackages(); Set<String> documented = new HashSet<String>(); Set<PackageSymbol> packages = ((JavacProcessingEnvironment)processingEnv).getSpecifiedPackages(); String jarName = processingEnv.getOptions().get("com.sun.tools.javac.sym.Jar"); if (jarName == null) throw new RuntimeException("Must use -Acom.sun.tools.javac.sym.Jar=LOCATION_OF_JAR"); String destName = processingEnv.getOptions().get("com.sun.tools.javac.sym.Dest"); if (destName == null) throw new RuntimeException("Must use -Acom.sun.tools.javac.sym.Dest=LOCATION_OF_JAR"); for (PackageSymbol psym : packages) { String name = psym.getQualifiedName().toString(); legacyProprietary.remove(name); documented.add(name); } JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); Location jarLocation = StandardLocation.locationFor(jarName); File jarFile = new File(jarName); fm.setLocation(jarLocation, List.of(jarFile)); fm.setLocation(StandardLocation.CLASS_PATH, List.<File>nil()); fm.setLocation(StandardLocation.SOURCE_PATH, List.<File>nil()); { ArrayList<File> bootClassPath = new ArrayList<File>(); bootClassPath.add(jarFile); for (File path : fm.getLocation(StandardLocation.PLATFORM_CLASS_PATH)) { if (!new File(path.getName()).equals(new File("rt.jar"))) bootClassPath.add(path); } System.err.println("Using boot class path = " + bootClassPath); fm.setLocation(StandardLocation.PLATFORM_CLASS_PATH, bootClassPath); } // System.out.println(fm.getLocation(StandardLocation.PLATFORM_CLASS_PATH)); File destDir = new File(destName); if (!destDir.exists()) if (!destDir.mkdirs()) throw new RuntimeException("Could not create " + destDir); fm.setLocation(StandardLocation.CLASS_OUTPUT, List.of(destDir)); Set<String> hiddenPackages = new HashSet<String>(); Set<String> crisp = new HashSet<String>(); List<String> options = List.of("-XDdev"); // options = options.prepend("-doe"); // options = options.prepend("-verbose"); JavacTaskImpl task = (JavacTaskImpl) tool.getTask(null, fm, null, options, null, null); com.sun.tools.javac.main.JavaCompiler compiler = com.sun.tools.javac.main.JavaCompiler.instance(task.getContext()); ClassReader reader = ClassReader.instance(task.getContext()); ClassWriter writer = ClassWriter.instance(task.getContext()); Symtab syms = Symtab.instance(task.getContext()); Attribute.Compound proprietary = new Attribute.Compound(syms.proprietaryType, List.<Pair<Symbol.MethodSymbol,Attribute>>nil()); Type.moreInfo = true; Pool pool = new Pool(); for (JavaFileObject file : fm.list(jarLocation, "", EnumSet.of(CLASS), true)) { String className = fm.inferBinaryName(jarLocation, file); int index = className.lastIndexOf('.'); String pckName = index == -1 ? "" : className.substring(0, index); boolean addLegacyAnnotation = false; if (documented.contains(pckName)) { if (!legacy.contains(pckName)) crisp.add(pckName); // System.out.println("Documented: " + className); } else if (legacyProprietary.contains(pckName)) { addLegacyAnnotation = true; // System.out.println("Legacy proprietary: " + className); } else { // System.out.println("Hidden " + className); hiddenPackages.add(pckName); continue; } TypeSymbol sym = (TypeSymbol)compiler.resolveIdent(className); if (sym.kind != Kinds.TYP) { if (className.indexOf('$') < 0) { System.err.println("Ignoring (other) " + className + " : " + sym); System.err.println(" " + sym.getClass().getSimpleName() + " " + sym.type); } continue; } sym.complete(); if (sym.getEnclosingElement().getKind() != ElementKind.PACKAGE) { System.err.println("Ignoring (bad) " + sym.getQualifiedName()); continue; } ClassSymbol cs = (ClassSymbol) sym; if (addLegacyAnnotation) { cs.attributes_field = (cs.attributes_field == null) ? List.of(proprietary) : cs.attributes_field.prepend(proprietary); } writeClass(pool, cs, writer); } if (false) { for (String pckName : crisp) System.out.println("Crisp: " + pckName); for (String pckName : hiddenPackages) System.out.println("Hidden: " + pckName); for (String pckName : legacyProprietary) System.out.println("Legacy proprietary: " + pckName); for (String pckName : documented) System.out.println("Documented: " + pckName); } } void writeClass(final Pool pool, final ClassSymbol cs, final ClassWriter writer) throws IOException { try { pool.reset(); cs.pool = pool; writer.writeClass(cs); for (Scope.Entry e = cs.members().elems; e != null; e = e.sibling) { if (e.sym.kind == Kinds.TYP) { ClassSymbol nestedClass = (ClassSymbol)e.sym; nestedClass.complete(); writeClass(pool, nestedClass, writer); } } } catch (ClassWriter.StringOverflow ex) { throw new RuntimeException(ex); } catch (ClassWriter.PoolOverflow ex) { throw new RuntimeException(ex); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?