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

📄 transtypes.java

📁 java编译器gjc源码 java编译环境
💻 JAVA
字号:
/**
 * @(#)TransTypes.java	1.39 03/01/23
 *
 * 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 translates Generic Java to conventional Java.
 */
public class TransTypes extends TreeTranslator implements Flags, Kinds, TypeTags {

    /**
     * The context key for the TransTypes phase.
     */
    private static final Context.Key transTypesKey = new Context.Key();

    /**
     * Get the instance for this context.
     */
    public static TransTypes instance(Context context) {
        TransTypes instance = (TransTypes) context.get(transTypesKey);
        if (instance == null)
            instance = new TransTypes(context);
        return instance;
    }
    private Name.Table names;
    private Log log;
    private Symtab syms;
    private TreeMaker make;

    private TransTypes(Context context) {
        super();
        context.put(transTypesKey, this);
        names = Name.Table.instance(context);
        log = Log.instance(context);
        syms = Symtab.instance(context);
    }

    /**
      * A hashtable mapping bridge methods to the methods they override after
      *  type erasure.
      */
    Hashtable overridden;

    /**
     * Construct an attributed tree for a cast of expression to target type,
     *  unless it already has precisely that type.
     *  @param tree    The expression tree.
     *  @param target  The target type.
     */
    Tree cast(Tree tree, Type target) {
        int oldpos = make.pos;
        make.at(tree.pos);
        if (!tree.type.isSameType(target)) {
            tree = make.TypeCast(make.Type(target), tree).setType(target);
        }
        make.pos = oldpos;
        return tree;
    }

    /**
      * Construct an attributed tree to coerce an expression to some erased
      *  target type, unless the expression is already assignable to that type.
      *  If target type is a constant type, use its base type instead.
      *  @param tree    The expression tree.
      *  @param target  The target type.
      */
    Tree coerce(Tree tree, Type target) {
        Type btarget = target.baseType();
        return tree.type.isAssignable(btarget) ? tree : cast(tree, btarget);
    }

    /**
      * Given an erased reference type, assume this type as the tree's type.
      *  Then, coerce to some given target type unless target type is null.
      *  This operation is used in situations like the following:
      *
      *  class Cell<A> { A value; }
      *  ...
      *  Cell<Integer> cell;
      *  Integer x = cell.value;
      *
      *  Since the erasure of Cell.value is Object, but the type
      *  of cell.value in the assignment is Integer, we need to
      *  adjust the original type of cell.value to Object, and insert
      *  a cast to Integer. That is, the last assignment becomes:
      *
      *  Integer x = (Integer)cell.value;
      *
      *  @param tree       The expression tree whose type might need adjustment.
      *  @param erasedType The expression's type after erasure.
      *  @param target     The target type, which is usually the erasure of the
      *                    expression's original type.
      */
    Tree retype(Tree tree, Type erasedType, Type target) {
        if (erasedType.tag > lastBaseTag) {
            tree.type = erasedType;
            if (target != null)
                return coerce(tree, target);
        }
        return tree;
    }

    /**
      * Translate method argument list, casting each argument
      *  to its corresponding type in a list of target types.
      *  @param trees     The method argument list.
      *  @param targets   The list of target types.
      */
    List translateArgs(List trees, List targets) {
        for (List l = trees; l.nonEmpty(); l = l.tail) {
            l.head = translate((Tree) l.head, (Type) targets.head);
            targets = targets.tail;
        }
        return trees;
    }

    /**
      * Visitor argument: proto-type.
      */
    private Type pt;

    /**
     * Visitor method: perform a type translation on tree.
     */
    public Tree translate(Tree tree, Type pt) {
        Type prevPt = this.pt;
        try {
            this.pt = pt;
            if (tree == null)
                result = null;
            else
                tree.accept(this);
        }
        finally { this.pt = prevPt;
                } return result;
    }

    /**
      * Visitor method: perform a type translation on list of trees.
      */
    public List translate(List trees, Type pt) {
        Type prevPt = this.pt;
        List res;
        try {
            this.pt = pt;
            res = translate(trees);
        }
        finally { this.pt = prevPt;
                } return res;
    }

    public void visitClassDef(ClassDef tree) {
        tree.typarams = TypeParameter.emptyList;
        super.visitClassDef(tree);
        make.at(tree.pos);
        tree.type = tree.type.erasure();
        result = tree;
    }

    public void visitMethodDef(MethodDef tree) {
        tree.restype = translate(tree.restype, null);
        tree.typarams = TypeParameter.emptyList;
        tree.params = translateVarDefs(tree.params);
        tree.thrown = translate(tree.thrown, null);
        tree.body = (Block) translate(tree.body, tree.sym.erasure().restype());
        tree.type = tree.type.erasure();
        result = tree;
        for (Scope.Entry e = tree.sym.owner.members().lookup(tree.name);
                e.sym != null; e = e.next()) {
            if (e.sym != tree.sym && e.sym.type.erasure().isSameType(tree.type)) {
                log.error(tree.pos, "name.clash.same.erasure", tree.sym.toJava(),
                        e.sym.toJava());
                return;
            }
        }
    }

    public void visitVarDef(VarDef tree) {
        tree.vartype = translate(tree.vartype, null);
        tree.init = translate(tree.init, tree.sym.erasure());
        tree.type = tree.type.erasure();
        result = tree;
    }

    public void visitDoLoop(DoLoop tree) {
        tree.body = translate(tree.body);
        tree.cond = translate(tree.cond, null);
        result = tree;
    }

    public void visitWhileLoop(WhileLoop tree) {
        tree.cond = translate(tree.cond, null);
        tree.body = translate(tree.body);
        result = tree;
    }

    public void visitForLoop(ForLoop tree) {
        tree.init = translate(tree.init, null);
        tree.cond = translate(tree.cond, null);
        tree.step = translate(tree.step, null);
        tree.body = translate(tree.body);
        result = tree;
    }

    public void visitSwitch(Switch tree) {
        tree.selector = translate(tree.selector, null);
        tree.cases = translateCases(tree.cases);
        result = tree;
    }

    public void visitCase(Case tree) {
        tree.pat = translate(tree.pat, null);
        tree.stats = translate(tree.stats);
        result = tree;
    }

    public void visitSynchronized(Synchronized tree) {
        tree.lock = translate(tree.lock, null);
        tree.body = translate(tree.body);
        result = tree;
    }

    public void visitConditional(Conditional tree) {
        tree.cond = translate(tree.cond, null);
        tree.truepart = translate(tree.truepart, tree.type.erasure());
        tree.falsepart = translate(tree.falsepart, tree.type.erasure());
        result = tree;
    }

    public void visitIf(If tree) {
        tree.cond = translate(tree.cond, null);
        tree.thenpart = translate(tree.thenpart);
        tree.elsepart = translate(tree.elsepart);
        result = tree;
    }

    public void visitExec(Exec tree) {
        tree.expr = translate(tree.expr, null);
        result = tree;
    }

    public void visitReturn(Return tree) {
        tree.expr = translate(tree.expr);
        result = tree;
    }

    public void visitThrow(Throw tree) {
        tree.expr = translate(tree.expr, tree.expr.type.erasure());
        result = tree;
    }

    public void visitAssert(Assert tree) {
        tree.cond = translate(tree.cond, null);
        if (tree.detail != null)
            tree.detail = translate(tree.detail, null);
        result = tree;
    }

    public void visitApply(Apply tree) {
        tree.meth = translate(tree.meth, null);
        Type mt = TreeInfo.symbol(tree.meth).erasure();
        tree.args = translateArgs(tree.args, mt.argtypes());
        result = retype(tree, mt.restype(), pt);
    }

    public void visitNewClass(NewClass tree) {
        if (tree.encl != null)
            tree.encl = translate(tree.encl, tree.encl.type.erasure());
        tree.clazz = translate(tree.clazz, null);
        tree.args = translateArgs(tree.args, tree.constructor.erasure().argtypes());
        tree.def = (ClassDef) translate(tree.def, null);
        tree.type = tree.type.erasure();
        result = tree;
    }

    public void visitNewArray(NewArray tree) {
        tree.elemtype = translate(tree.elemtype, null);
        tree.dims = translate(tree.dims, null);
        tree.elems = translate(tree.elems, tree.type.elemtype().erasure());
        tree.type = tree.type.erasure();
        result = tree;
    }

    public void visitParens(Parens tree) {
        tree.expr = translate(tree.expr, null);
        tree.type = tree.type.erasure();
        result = tree;
    }

    public void visitAssign(Assign tree) {
        tree.lhs = translate(tree.lhs, null);
        tree.rhs = translate(tree.rhs, tree.lhs.type.erasure());
        tree.type = tree.type.erasure();
        result = tree;
    }

    public void visitAssignop(Assignop tree) {
        tree.lhs = translate(tree.lhs, null);
        tree.rhs = translate(tree.rhs, null);
        tree.type = tree.type.erasure();
        result = tree;
    }

    public void visitUnary(Unary tree) {
        tree.arg = translate(tree.arg, (Type) tree.operator.type.argtypes().head);
        result = tree;
    }

    public void visitBinary(Binary tree) {
        tree.lhs = translate(tree.lhs, (Type) tree.operator.type.argtypes().head);
        tree.rhs =
                translate(tree.rhs, (Type) tree.operator.type.argtypes().tail.head);
        result = tree;
    }

    public void visitTypeCast(TypeCast tree) {
        tree.clazz = translate(tree.clazz, null);
        tree.expr = translate(tree.expr, null);
        tree.type = tree.type.erasure();
        result = tree;
    }

    public void visitTypeTest(TypeTest tree) {
        tree.expr = translate(tree.expr, null);
        tree.clazz = translate(tree.clazz, null);
        result = tree;
    }

    public void visitIndexed(Indexed tree) {
        tree.indexed = translate(tree.indexed, tree.indexed.type.erasure());
        tree.index = translate(tree.index, null);
        result = retype(tree, tree.indexed.type.elemtype(), pt);
    }

    public void visitIdent(Ident tree) {
        Type et = tree.sym.erasure();
        if (tree.type.constValue != null) {
            result = tree;
        } else if (tree.sym.kind == VAR) {
            result = retype(tree, et, pt);
        } else {
            tree.type = tree.type.erasure();
            result = tree;
        }
    }

    public void visitSelect(Select tree) {
        Type t = tree.selected.type;
        tree.selected = translate(tree.selected, t.erasure());
        if (tree.type.constValue != null) {
            result = tree;
        } else if (tree.sym.kind == VAR) {
            result = retype(tree, tree.sym.erasure(), pt);
        } else {
            tree.type = tree.type.erasure();
            result = tree;
        }
    }

    public void visitTypeArray(TypeArray tree) {
        tree.elemtype = translate(tree.elemtype, null);
        tree.type = tree.type.erasure();
        result = tree;
    }

    /**
      * Translate a toplevel class definition.
      *  @param cdef    The definition to be translated.
      */
    public Tree translateTopLevelClass(Tree cdef, TreeMaker make) {
        try {
            this.make = make;
            overridden = Hashtable.make();
            pt = null;
            return translate(cdef, null);
        }
        finally { this.make = null;
                  overridden = null;
                  pt = null;
                } }
}

⌨️ 快捷键说明

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