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 + -
显示快捷键?