⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lower.java

📁 是一款用JAVA 编写的编译器 具有很强的编译功能
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/* * Copyright 1999-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.comp;import java.util.*;import com.sun.tools.javac.code.*;import com.sun.tools.javac.jvm.*;import com.sun.tools.javac.tree.*;import com.sun.tools.javac.util.*;import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;import com.sun.tools.javac.util.List;import com.sun.tools.javac.code.Symbol.*;import com.sun.tools.javac.tree.JCTree.*;import com.sun.tools.javac.code.Type.*;import com.sun.tools.javac.jvm.Target;import static com.sun.tools.javac.code.Flags.*;import static com.sun.tools.javac.code.Kinds.*;import static com.sun.tools.javac.code.TypeTags.*;import static com.sun.tools.javac.jvm.ByteCodes.*;/** This pass translates away some syntactic sugar: inner classes, *  class literals, assertions, foreach loops, etc. * *  <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> */public class Lower extends TreeTranslator {    protected static final Context.Key<Lower> lowerKey =	new Context.Key<Lower>();    public static Lower instance(Context context) {	Lower instance = context.get(lowerKey);	if (instance == null)	    instance = new Lower(context);	return instance;    }    private Name.Table names;    private Log log;    private Symtab syms;    private Resolve rs;    private Check chk;    private Attr attr;    private TreeMaker make;    private DiagnosticPosition make_pos;    private ClassWriter writer;    private ClassReader reader;    private ConstFold cfolder;    private Target target;    private Source source;    private boolean allowEnums;    private final Name dollarAssertionsDisabled;    private final Name classDollar;    private Types types;    private boolean debugLower;    protected Lower(Context context) {	context.put(lowerKey, this);	names = Name.Table.instance(context);	log = Log.instance(context);	syms = Symtab.instance(context);	rs = Resolve.instance(context);	chk = Check.instance(context);	attr = Attr.instance(context);	make = TreeMaker.instance(context);	writer = ClassWriter.instance(context);	reader = ClassReader.instance(context);	cfolder = ConstFold.instance(context);	target = Target.instance(context);	source = Source.instance(context);	allowEnums = source.allowEnums();	dollarAssertionsDisabled = names.	    fromString(target.syntheticNameChar() + "assertionsDisabled");	classDollar = names.	    fromString("class" + target.syntheticNameChar());		types = Types.instance(context);	Options options = Options.instance(context);	debugLower = options.get("debuglower") != null;    }    /** The currently enclosing class.     */    ClassSymbol currentClass;    /** A queue of all translated classes.     */    ListBuffer<JCTree> translated;    /** Environment for symbol lookup, set by translateTopLevelClass.     */    Env<AttrContext> attrEnv;    /** A hash table mapping syntax trees to their ending source positions.     */    Map<JCTree, Integer> endPositions;/************************************************************************** * Global mappings *************************************************************************/    /** A hash table mapping local classes to their definitions.     */    Map<ClassSymbol, JCClassDecl> classdefs;    /** A hash table mapping virtual accessed symbols in outer subclasses     *  to the actually referred symbol in superclasses.     */    Map<Symbol,Symbol> actualSymbols;    /** The current method definition.     */    JCMethodDecl currentMethodDef;    /** The current method symbol.     */    MethodSymbol currentMethodSym;    /** The currently enclosing outermost class definition.     */    JCClassDecl outermostClassDef;    /** The currently enclosing outermost member definition.     */    JCTree outermostMemberDef;    /** A navigator class for assembling a mapping from local class symbols     *  to class definition trees.     *  There is only one case; all other cases simply traverse down the tree.     */    class ClassMap extends TreeScanner {	/** All encountered class defs are entered into classdefs table.	 */	public void visitClassDef(JCClassDecl tree) {	    classdefs.put(tree.sym, tree);	    super.visitClassDef(tree);	}    }    ClassMap classMap = new ClassMap();    /** Map a class symbol to its definition.     *  @param c    The class symbol of which we want to determine the definition.     */    JCClassDecl classDef(ClassSymbol c) {	// First lookup the class in the classdefs table.	JCClassDecl def = classdefs.get(c);	if (def == null && outermostMemberDef != null) {	    // If this fails, traverse outermost member definition, entering all	    // local classes into classdefs, and try again.	    classMap.scan(outermostMemberDef);	    def = classdefs.get(c);	}	if (def == null) {	    // If this fails, traverse outermost class definition, entering all	    // local classes into classdefs, and try again.	    classMap.scan(outermostClassDef);	    def = classdefs.get(c);	}	return def;    }    /** A hash table mapping class symbols to lists of free variables.     *  accessed by them. Only free variables of the method immediately containing     *  a class are associated with that class.     */    Map<ClassSymbol,List<VarSymbol>> freevarCache;    /** A navigator class for collecting the free variables accessed     *  from a local class.     *  There is only one case; all other cases simply traverse down the tree.     */    class FreeVarCollector extends TreeScanner {	/** The owner of the local class.	 */	Symbol owner;	/** The local class.	 */	ClassSymbol clazz;	/** The list of owner's variables accessed from within the local class,	 *  without any duplicates.	 */	List<VarSymbol> fvs;	FreeVarCollector(ClassSymbol clazz) {	    this.clazz = clazz;	    this.owner = clazz.owner;	    this.fvs = List.nil();	}	/** Add free variable to fvs list unless it is already there.	 */	private void addFreeVar(VarSymbol v) {	    for (List<VarSymbol> l = fvs; l.nonEmpty(); l = l.tail)		if (l.head == v) return;	    fvs = fvs.prepend(v);	}	/** Add all free variables of class c to fvs list	 *  unless they are already there.	 */	private void addFreeVars(ClassSymbol c) {	    List<VarSymbol> fvs = freevarCache.get(c);	    if (fvs != null) {		for (List<VarSymbol> l = fvs; l.nonEmpty(); l = l.tail) {		    addFreeVar(l.head);		}	    }	}	/** If tree refers to a variable in owner of local class, add it to	 *  free variables list.	 */	public void visitIdent(JCIdent tree) {	    result = tree;	    visitSymbol(tree.sym);	}	// where	private void visitSymbol(Symbol _sym) {	    Symbol sym = _sym;	    if (sym.kind == VAR || sym.kind == MTH) {		while (sym != null && sym.owner != owner)		    sym = proxies.lookup(proxyName(sym.name)).sym;		if (sym != null && sym.owner == owner) {		    VarSymbol v = (VarSymbol)sym;		    if (v.getConstValue() == null) {			addFreeVar(v);		    }		} else {		    if (outerThisStack.head != null &&			outerThisStack.head != _sym)			visitSymbol(outerThisStack.head);		}	    }	}	/** If tree refers to a class instance creation expression	 *  add all free variables of the freshly created class.	 */        public void visitNewClass(JCNewClass tree) {	    ClassSymbol c = (ClassSymbol)tree.constructor.owner;	    addFreeVars(c);	    if (tree.encl == null &&		c.hasOuterInstance() &&		outerThisStack.head != null)		visitSymbol(outerThisStack.head);	    super.visitNewClass(tree);	}	/** If tree refers to a qualified this or super expression	 *  for anything but the current class, add the outer this	 *  stack as a free variable.	 */	public void visitSelect(JCFieldAccess tree) {	    if ((tree.name == names._this || tree.name == names._super) &&		tree.selected.type.tsym != clazz &&		outerThisStack.head != null)		visitSymbol(outerThisStack.head);	    super.visitSelect(tree);	}	/** If tree refers to a superclass constructor call,	 *  add all free variables of the superclass.	 */        public void visitApply(JCMethodInvocation tree) {	    if (TreeInfo.name(tree.meth) == names._super) {		addFreeVars((ClassSymbol) TreeInfo.symbol(tree.meth).owner);		Symbol constructor = TreeInfo.symbol(tree.meth);		ClassSymbol c = (ClassSymbol)constructor.owner;		if (c.hasOuterInstance() &&		    tree.meth.getTag() != JCTree.SELECT &&		    outerThisStack.head != null)		    visitSymbol(outerThisStack.head);	    }	    super.visitApply(tree);	}    }    /** Return the variables accessed from within a local class, which     *  are declared in the local class' owner.     *  (in reverse order of first access).     */    List<VarSymbol> freevars(ClassSymbol c)  {	if ((c.owner.kind & (VAR | MTH)) != 0) {	    List<VarSymbol> fvs = freevarCache.get(c);	    if (fvs == null) {		FreeVarCollector collector = new FreeVarCollector(c);		collector.scan(classDef(c));		fvs = collector.fvs;		freevarCache.put(c, fvs);	    }	    return fvs;	} else {	    return List.nil();	}    }    Map<TypeSymbol,EnumMapping> enumSwitchMap = new LinkedHashMap<TypeSymbol,EnumMapping>();    EnumMapping mapForEnum(DiagnosticPosition pos, TypeSymbol enumClass) {        EnumMapping map = enumSwitchMap.get(enumClass);        if (map == null)            enumSwitchMap.put(enumClass, map = new EnumMapping(pos, enumClass));        return map;    }    /** This map gives a translation table to be used for enum     *  switches.     *     *  <p>For each enum that appears as the type of a switch     *  expression, we maintain an EnumMapping to assist in the     *  translation, as exemplified by the following example:     *     *  <p>we translate     *  <pre>     *          switch(colorExpression) {     *          case red: stmt1;     *          case green: stmt2;     *          }     *  </pre>     *  into     *  <pre>     *          switch(Outer$0.$EnumMap$Color[colorExpression.ordinal()]) {     *          case 1: stmt1;     *          case 2: stmt2     *          }     *  </pre>     *  with the auxilliary table intialized as follows:     *  <pre>     *          class Outer$0 {     *              synthetic final int[] $EnumMap$Color = new int[Color.values().length];     *              static {     *                  try { $EnumMap$Color[red.ordinal()] = 1; } catch (NoSuchFieldError ex) {}     *                  try { $EnumMap$Color[green.ordinal()] = 2; } catch (NoSuchFieldError ex) {}     *              }     *          }     *  </pre>     *  class EnumMapping provides mapping data and support methods for this translation.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -