treeinfo.java

来自「是一款用JAVA 编写的编译器 具有很强的编译功能」· Java 代码 · 共 867 行 · 第 1/2 页

JAVA
867
字号
	    throw new AssertionError();	}    }    /** Find the position for reporting an error about a symbol, where     *  that symbol is defined somewhere in the given tree. */    public static int positionFor(final Symbol sym, final JCTree tree) {        JCTree decl = declarationFor(sym, tree);        return ((decl != null) ? decl : tree).pos;    }    /** Find the position for reporting an error about a symbol, where     *  that symbol is defined somewhere in the given tree. */    public static DiagnosticPosition diagnosticPositionFor(final Symbol sym, final JCTree tree) {        JCTree decl = declarationFor(sym, tree);        return ((decl != null) ? decl : tree).pos();    }    /** Find the declaration for a symbol, where     *  that symbol is defined somewhere in the given tree. */    public static JCTree declarationFor(final Symbol sym, final JCTree tree) {	class DeclScanner extends TreeScanner {            JCTree result = null;            public void scan(JCTree tree) {                if (tree!=null && result==null)                    tree.accept(this);            }	    public void visitTopLevel(JCCompilationUnit that) {		if (that.packge == sym) result = that;		else super.visitTopLevel(that);	    }	    public void visitClassDef(JCClassDecl that) {		if (that.sym == sym) result = that;		else super.visitClassDef(that);	    }	    public void visitMethodDef(JCMethodDecl that) {		if (that.sym == sym) result = that;		else super.visitMethodDef(that);	    }	    public void visitVarDef(JCVariableDecl that) {		if (that.sym == sym) result = that;		else super.visitVarDef(that);	    }	}	DeclScanner s = new DeclScanner();	tree.accept(s);	return s.result;    }    public static Env<AttrContext> scopeFor(JCTree node, JCCompilationUnit unit) {	return scopeFor(pathFor(node, unit));    }    public static Env<AttrContext> scopeFor(List<JCTree> path) {	// TODO: not implemented yet	throw new UnsupportedOperationException("not implemented yet");    }    public static List<JCTree> pathFor(final JCTree node, final JCCompilationUnit unit) {	class Result extends Error {	    static final long serialVersionUID = -5942088234594905625L;	    List<JCTree> path;	    Result(List<JCTree> path) {		this.path = path;	    }	}	class PathFinder extends TreeScanner {	    List<JCTree> path = List.nil();	    public void scan(JCTree tree) {		if (tree != null) {		    path = path.prepend(tree);		    if (tree == node)			throw new Result(path);		    super.scan(tree);		    path = path.tail;		}	    }	}	try {	    new PathFinder().scan(unit);	} catch (Result result) {	    return result.path;	}        return List.nil();    }        /** Return the statement referenced by a label.     *  If the label refers to a loop or switch, return that switch     *  otherwise return the labelled statement itself     */    public static JCTree referencedStatement(JCLabeledStatement tree) {	JCTree t = tree;	do t = ((JCLabeledStatement) t).body;	while (t.getTag() == JCTree.LABELLED);	switch (t.getTag()) {	case JCTree.DOLOOP: case JCTree.WHILELOOP: case JCTree.FORLOOP: case JCTree.FOREACHLOOP: case JCTree.SWITCH:	    return t;	default:	    return tree;	}    }    /** Skip parens and return the enclosed expression     */    public static JCExpression skipParens(JCExpression tree) {	while (tree.getTag() == JCTree.PARENS) {	    tree = ((JCParens) tree).expr;	}	return tree;    }    /** Skip parens and return the enclosed expression     */    public static JCTree skipParens(JCTree tree) {	if (tree.getTag() == JCTree.PARENS)	    return skipParens((JCParens)tree);	else	    return tree;    }    /** Return the types of a list of trees.     */    public static List<Type> types(List<? extends JCTree> trees) {	ListBuffer<Type> ts = new ListBuffer<Type>();	for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail)	    ts.append(l.head.type);	return ts.toList();    }    /** If this tree is an identifier or a field or a parameterized type,     *  return its name, otherwise return null.     */    public static Name name(JCTree tree) {	switch (tree.getTag()) {	case JCTree.IDENT:	    return ((JCIdent) tree).name;	case JCTree.SELECT:	    return ((JCFieldAccess) tree).name;	case JCTree.TYPEAPPLY:	    return name(((JCTypeApply) tree).clazz);	default:	    return null;	}    }    /** If this tree is a qualified identifier, its return fully qualified name,     *  otherwise return null.     */    public static Name fullName(JCTree tree) {	tree = skipParens(tree);	switch (tree.getTag()) {	case JCTree.IDENT:	    return ((JCIdent) tree).name;	case JCTree.SELECT:	    Name sname = fullName(((JCFieldAccess) tree).selected);	    return sname == null ? null : sname.append('.', name(tree));	default:	    return null;	}    }    public static Symbol symbolFor(JCTree node) {	node = skipParens(node);	switch (node.getTag()) {	case JCTree.CLASSDEF:	    return ((JCClassDecl) node).sym;	case JCTree.METHODDEF:	    return ((JCMethodDecl) node).sym;	case JCTree.VARDEF:	    return ((JCVariableDecl) node).sym;	default:	    return null;	}    }    /** If this tree is an identifier or a field, return its symbol,     *  otherwise return null.     */    public static Symbol symbol(JCTree tree) {	tree = skipParens(tree);	switch (tree.getTag()) {	case JCTree.IDENT:	    return ((JCIdent) tree).sym;	case JCTree.SELECT:	    return ((JCFieldAccess) tree).sym;	case JCTree.TYPEAPPLY:	    return symbol(((JCTypeApply) tree).clazz);	default:	    return null;	}    }    /** Return true if this is a nonstatic selection. */    public static boolean nonstaticSelect(JCTree tree) {	tree = skipParens(tree);	if (tree.getTag() != JCTree.SELECT) return false;	JCFieldAccess s = (JCFieldAccess) tree;	Symbol e = symbol(s.selected);	return e == null || (e.kind != Kinds.PCK && e.kind != Kinds.TYP);    }    /** If this tree is an identifier or a field, set its symbol, otherwise skip.     */    public static void setSymbol(JCTree tree, Symbol sym) {	tree = skipParens(tree);	switch (tree.getTag()) {	case JCTree.IDENT:	    ((JCIdent) tree).sym = sym; break;	case JCTree.SELECT:	    ((JCFieldAccess) tree).sym = sym; break;	default:	}    }    /** If this tree is a declaration or a block, return its flags field,     *  otherwise return 0.     */    public static long flags(JCTree tree) {	switch (tree.getTag()) {	case JCTree.VARDEF:	    return ((JCVariableDecl) tree).mods.flags;	case JCTree.METHODDEF:	    return ((JCMethodDecl) tree).mods.flags;	case JCTree.CLASSDEF:	    return ((JCClassDecl) tree).mods.flags;	case JCTree.BLOCK:	    return ((JCBlock) tree).flags;	default:	    return 0;	}    }    /** Return first (smallest) flag in `flags':     *  pre: flags != 0     */    public static long firstFlag(long flags) {	int flag = 1;        while ((flag & StandardFlags) != 0 && (flag & flags) == 0)	    flag = flag << 1;        return flag;    }    /** Return flags as a string, separated by " ".     */    public static String flagNames(long flags) {        return Flags.toString(flags & StandardFlags).trim();    }    /** Operator precedences values.     */    public static final int        notExpression = -1,   // not an expression        noPrec = 0,           // no enclosing expression        assignPrec = 1,	assignopPrec = 2,	condPrec = 3,	orPrec = 4,	andPrec = 5,	bitorPrec = 6,	bitxorPrec = 7,	bitandPrec = 8,	eqPrec = 9,	ordPrec = 10,	shiftPrec = 11,	addPrec = 12,	mulPrec = 13,	prefixPrec = 14,	postfixPrec = 15,	precCount = 16;    /** Map operators to their precedence levels.     */    public static int opPrec(int op) {	switch(op) {	case JCTree.POS:	case JCTree.NEG:	case JCTree.NOT:	case JCTree.COMPL:	case JCTree.PREINC:	case JCTree.PREDEC: return prefixPrec;	case JCTree.POSTINC:	case JCTree.POSTDEC:	case JCTree.NULLCHK: return postfixPrec;	case JCTree.ASSIGN: return assignPrec;	case JCTree.BITOR_ASG:	case JCTree.BITXOR_ASG:	case JCTree.BITAND_ASG:	case JCTree.SL_ASG:	case JCTree.SR_ASG:	case JCTree.USR_ASG:	case JCTree.PLUS_ASG:	case JCTree.MINUS_ASG:	case JCTree.MUL_ASG:	case JCTree.DIV_ASG:	case JCTree.MOD_ASG: return assignopPrec;        case JCTree.OR: return orPrec;        case JCTree.AND: return andPrec;        case JCTree.EQ:        case JCTree.NE: return eqPrec;        case JCTree.LT:        case JCTree.GT:        case JCTree.LE:        case JCTree.GE: return ordPrec;        case JCTree.BITOR: return bitorPrec;        case JCTree.BITXOR: return bitxorPrec;        case JCTree.BITAND: return bitandPrec;        case JCTree.SL:        case JCTree.SR:        case JCTree.USR: return shiftPrec;        case JCTree.PLUS:        case JCTree.MINUS: return addPrec;        case JCTree.MUL:        case JCTree.DIV:        case JCTree.MOD: return mulPrec;	case JCTree.TYPETEST: return ordPrec;	default: throw new AssertionError();	}    }    static Tree.Kind tagToKind(int tag) {        switch (tag) {        // Postfix expressions        case JCTree.POSTINC:           // _ ++            return Tree.Kind.POSTFIX_INCREMENT;        case JCTree.POSTDEC:           // _ --            return Tree.Kind.POSTFIX_DECREMENT;        // Unary operators        case JCTree.PREINC:            // ++ _            return Tree.Kind.PREFIX_INCREMENT;        case JCTree.PREDEC:            // -- _            return Tree.Kind.PREFIX_DECREMENT;        case JCTree.POS:               // +            return Tree.Kind.UNARY_PLUS;        case JCTree.NEG:               // -            return Tree.Kind.UNARY_MINUS;        case JCTree.COMPL:             // ~            return Tree.Kind.BITWISE_COMPLEMENT;        case JCTree.NOT:               // !            return Tree.Kind.LOGICAL_COMPLEMENT;        // Binary operators        // Multiplicative operators        case JCTree.MUL:               // *            return Tree.Kind.MULTIPLY;        case JCTree.DIV:               // /            return Tree.Kind.DIVIDE;        case JCTree.MOD:               // %            return Tree.Kind.REMAINDER;        // Additive operators        case JCTree.PLUS:              // +            return Tree.Kind.PLUS;        case JCTree.MINUS:             // -            return Tree.Kind.MINUS;        // Shift operators        case JCTree.SL:                // <<            return Tree.Kind.LEFT_SHIFT;        case JCTree.SR:                // >>            return Tree.Kind.RIGHT_SHIFT;        case JCTree.USR:               // >>>            return Tree.Kind.UNSIGNED_RIGHT_SHIFT;        // Relational operators        case JCTree.LT:                // <            return Tree.Kind.LESS_THAN;        case JCTree.GT:                // >            return Tree.Kind.GREATER_THAN;        case JCTree.LE:                // <=            return Tree.Kind.LESS_THAN_EQUAL;        case JCTree.GE:                // >=            return Tree.Kind.GREATER_THAN_EQUAL;        // Equality operators        case JCTree.EQ:                // ==            return Tree.Kind.EQUAL_TO;        case JCTree.NE:                // !=            return Tree.Kind.NOT_EQUAL_TO;        // Bitwise and logical operators        case JCTree.BITAND:            // &            return Tree.Kind.AND;        case JCTree.BITXOR:            // ^            return Tree.Kind.XOR;        case JCTree.BITOR:             // |            return Tree.Kind.OR;        // Conditional operators        case JCTree.AND:               // &&            return Tree.Kind.CONDITIONAL_AND;        case JCTree.OR:                // ||            return Tree.Kind.CONDITIONAL_OR;        // Assignment operators        case JCTree.MUL_ASG:           // *=            return Tree.Kind.MULTIPLY_ASSIGNMENT;        case JCTree.DIV_ASG:           // /=            return Tree.Kind.DIVIDE_ASSIGNMENT;        case JCTree.MOD_ASG:           // %=            return Tree.Kind.REMAINDER_ASSIGNMENT;        case JCTree.PLUS_ASG:          // +=            return Tree.Kind.PLUS_ASSIGNMENT;        case JCTree.MINUS_ASG:         // -=            return Tree.Kind.MINUS_ASSIGNMENT;        case JCTree.SL_ASG:            // <<=            return Tree.Kind.LEFT_SHIFT_ASSIGNMENT;        case JCTree.SR_ASG:            // >>=            return Tree.Kind.RIGHT_SHIFT_ASSIGNMENT;        case JCTree.USR_ASG:           // >>>=            return Tree.Kind.UNSIGNED_RIGHT_SHIFT_ASSIGNMENT;        case JCTree.BITAND_ASG:        // &=            return Tree.Kind.AND_ASSIGNMENT;        case JCTree.BITXOR_ASG:        // ^=            return Tree.Kind.XOR_ASSIGNMENT;        case JCTree.BITOR_ASG:         // |=            return Tree.Kind.OR_ASSIGNMENT;        // Null check (implementation detail), for example, __.getClass()        case JCTree.NULLCHK:            return Tree.Kind.OTHER;        default:            return null;        }    }}

⌨️ 快捷键说明

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