📄 transinner.java
字号:
/** * @(#)TransInner.java 1.92 03/04/10 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.tools.javac.v8.comp;import com.sun.tools.javac.v8.util.*;import com.sun.tools.javac.v8.code.*;import com.sun.tools.javac.v8.tree.*;import com.sun.tools.javac.v8.code.Symbol.*;import com.sun.tools.javac.v8.tree.Tree.*;import com.sun.tools.javac.v8.code.Type.*;/** * This pass maps Java with inner classes to flat Java without * inner classes. */public class TransInner extends TreeTranslator implements Flags, Kinds, TypeTags,ByteCodes { private static final Context.Key transInnerKey = new Context.Key(); public static TransInner instance(Context context) { TransInner instance = (TransInner) context.get(transInnerKey); if (instance == null) instance = new TransInner(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 ClassWriter writer; private ClassReader reader; private ConstFold cfolder; private Target target; private TransInner(Context context) { super(); context.put(transInnerKey, 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); } /** * The currently enclosing class. */ ClassSymbol currentClass; /** * A queue of all translated classes. */ ListBuffer translated; /** * Environment for symbol lookup, set by translateTopLevelClass. */ Env attrEnv; /** * A hash table mapping syntax trees to their ending source positions. */ Hashtable endPositions; /** * A hash table mapping local classes to their definitions. */ Hashtable classdefs; /** * A hash table mapping virtual accessed symbols in outer subclasses * to the actually referred symbol in superclasses. */ Hashtable actualSymbols; /** * The currently enclosing outermost class definition. */ ClassDef outermostClassDef; /** * The currently enclosing outermost member definition. */ Tree 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 { ClassMap() { super(); } /** * All encountered class defs are entered into classdefs table. */ public void visitClassDef(ClassDef tree) { classdefs.put(tree.sym, tree); super.visitClassDef(tree); } } /** * Map a class symbol to its definition. * @param c The class symbol of which we want to determine the definition. */ ClassDef classDef(ClassSymbol c) { ClassDef def = (Tree.ClassDef) classdefs.get(c); if (def == null && outermostMemberDef != null) { new ClassMap().scan(outermostMemberDef); def = (Tree.ClassDef) classdefs.get(c); } if (def == null) { new ClassMap().scan(outermostClassDef); def = (Tree.ClassDef) 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. */ Hashtable 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 current class. */ ClassSymbol clazz; /** * The list of owner's variables accessed from within the local class, * without any duplicates. */ List fvs; FreeVarCollector(ClassSymbol clazz) { super(); this.clazz = clazz; this.owner = clazz.owner; this.fvs = VarSymbol.emptyList; } /** * Add free variable to fvs list unless it is already there. */ private void addFreeVar(VarSymbol v) { for (List 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 fvs = (List) freevarCache.get(c); if (fvs != null) { for (List l = fvs; l.nonEmpty(); l = l.tail) { addFreeVar((Symbol.VarSymbol) l.head); } } } /** * If tree refers to a variable in owner of local class, add it to * free variables list. */ public void visitIdent(Ident tree) { result = tree; visitSymbol(tree.sym); } private void visitSymbol(Symbol sym) { if (sym.kind == VAR) { 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.constValue == null) { addFreeVar(v); } } } } /** * If tree refers to a class instance creation expression * add all free variables of the freshly created class. */ public void visitNewClass(NewClass tree) { ClassSymbol c = (ClassSymbol) tree.constructor.owner; addFreeVars(c); if (tree.encl == null && c.hasOuterInstance() && outerThisStack.head != null) visitSymbol((Symbol) 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(Select tree) { if ((tree.name == names._this || tree.name == names._super) && tree.selected.type.tsym != clazz && outerThisStack.head != null) visitSymbol((Symbol) outerThisStack.head); super.visitSelect(tree); } /** * If tree refers to a superclass constructor call, * add all free variables of the superclass. */ public void visitApply(Apply 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.tag != Tree.SELECT && outerThisStack.head != null) visitSymbol((Symbol) 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 freevars(ClassSymbol c) { if ((c.owner.kind & (VAR | MTH)) != 0) { List fvs = (List) 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 VarSymbol.emptyList; } } /** * Make an attributed tree representing a literal. This will be an * Ident node in the case of boolean literals, a Literal node in all * other cases. * @param type The literal's type. * @param value The literal's value. */ Tree makeLit(Type type, Object value) { if (type.tag == BOOLEAN) { return make.Ident(((Integer) value).intValue() == 0 ? syms.falseConst : syms.trueConst); } else { return make.Literal(type.tag, value).setType(type.constType(value)); } } /** * Make an attributed class instance creation expression. * @param ctype The class type. * @param args The constructor arguments. */ NewClass makeNewClass(Type ctype, List args) { NewClass tree = make.NewClass(null, make.QualIdent(ctype.tsym), args, null); tree.constructor = rs.resolveConstructor(make.pos, attrEnv, ctype, TreeInfo.types(args)); tree.type = ctype; return tree; } /** * Make an attributed unary expression. * @param optag The operators tree tag. * @param arg The operator's argument. */ Tree makeUnary(int optag, Tree arg) { Unary tree = make.Unary(optag, arg); tree.operator = rs.resolveUnaryOperator(make.pos, optag, attrEnv, arg.type); tree.type = tree.operator.type.restype(); return tree; } /** * Make an attributed binary expression. * @param optag The operators tree tag. * @param lhs The operator's left argument. * @param rhs The operator's right argument. */ Binary makeBinary(int optag, Tree lhs, Tree rhs) { Binary tree = make.Binary(optag, lhs, rhs); tree.operator = rs.resolveBinaryOperator(make.pos, optag, attrEnv, lhs.type, rhs.type); tree.type = tree.operator.type.restype(); return tree; } /** * Convert tree into string object, unless it has already a * reference type.. */ Tree makeString(Tree tree) { if (tree.type.tag >= CLASS) { return tree; } else { Symbol valueOfSym = rs.resolveInternalMethod(tree.pos, attrEnv, syms.stringType, names.valueOf, Type.emptyList.prepend(tree.type)); return make.App(make.QualIdent(valueOfSym), List.make(tree)); } } /** * Create an empty anonymous class definition and enter and complete * its symbol. Return the class definition's symbol. * and create * @param flags The class symbol's flags
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -