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

📄 transinner.java

📁 java编译器gjc源码 java编译环境
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/**
 * @(#)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,

⌨️ 快捷键说明

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