📄 treeinfo.java
字号:
/**
* @(#)TreeInfo.java 1.26 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.tree;
import java.io.File;
import com.sun.tools.javac.v8.util.*;
import com.sun.tools.javac.v8.code.*;
import com.sun.tools.javac.v8.code.Type.*;
import com.sun.tools.javac.v8.code.Symbol.*;
import com.sun.tools.javac.v8.tree.Tree.*;
/**
* Utility class containing inspector methods for trees.
*/
public class TreeInfo implements Flags {
private static final Context.Key treeInfoKey = new Context.Key();
public static TreeInfo instance(Context context) {
TreeInfo instance = (TreeInfo) context.get(treeInfoKey);
if (instance == null)
instance = new TreeInfo(context);
return instance;
}
/**
* The names of all operators.
*/
private Name[] opname = new Name[Tree.MOD - Tree.POS + 1];
private TreeInfo(Context context) {
super();
context.put(treeInfoKey, this);
Name.Table names = Name.Table.instance(context);
opname[Tree.POS - Tree.POS] = names.fromString("+");
opname[Tree.NEG - Tree.POS] = names.hyphen;
opname[Tree.NOT - Tree.POS] = names.fromString("!");
opname[Tree.COMPL - Tree.POS] = names.fromString("~");
opname[Tree.PREINC - Tree.POS] = names.fromString("++");
opname[Tree.PREDEC - Tree.POS] = names.fromString("--");
opname[Tree.POSTINC - Tree.POS] = names.fromString("++");
opname[Tree.POSTDEC - Tree.POS] = names.fromString("--");
opname[Tree.NULLCHK - Tree.POS] = names.fromString("<*nullchk*>");
opname[Tree.OR - Tree.POS] = names.fromString("||");
opname[Tree.AND - Tree.POS] = names.fromString("&&");
opname[Tree.EQ - Tree.POS] = names.fromString("==");
opname[Tree.NE - Tree.POS] = names.fromString("!=");
opname[Tree.LT - Tree.POS] = names.fromString("<");
opname[Tree.GT - Tree.POS] = names.fromString(">");
opname[Tree.LE - Tree.POS] = names.fromString("<=");
opname[Tree.GE - Tree.POS] = names.fromString(">=");
opname[Tree.BITOR - Tree.POS] = names.fromString("|");
opname[Tree.BITXOR - Tree.POS] = names.fromString("^");
opname[Tree.BITAND - Tree.POS] = names.fromString("&");
opname[Tree.SL - Tree.POS] = names.fromString("<<");
opname[Tree.SR - Tree.POS] = names.fromString(">>");
opname[Tree.USR - Tree.POS] = names.fromString(">>>");
opname[Tree.PLUS - Tree.POS] = names.fromString("+");
opname[Tree.MINUS - Tree.POS] = names.hyphen;
opname[Tree.MUL - Tree.POS] = names.asterisk;
opname[Tree.DIV - Tree.POS] = names.slash;
opname[Tree.MOD - Tree.POS] = names.fromString("%");
}
/**
* Return name of operator with given tree tag.
*/
public Name operatorName(int tag) {
return opname[tag - Tree.POS];
}
/**
* Is tree a constructor declaration?
*/
public static boolean isConstructor(Tree tree) {
if (tree.tag == Tree.METHODDEF) {
Name name = ((MethodDef) tree).name;
return name == name.table.init;
} else {
return false;
}
}
/**
* Is there a constructor declaration in the given list of trees?
*/
public static boolean hasConstructors(List trees) {
for (List l = trees; l.nonEmpty(); l = l.tail)
if (isConstructor((Tree) l.head))
return true;
return false;
}
/**
* Is statement an initializer for a synthetic field?
*/
public static boolean isSyntheticInit(Tree stat) {
if (stat.tag == Tree.EXEC) {
Exec exec = (Exec) stat;
if (exec.expr.tag == Tree.ASSIGN) {
Assign assign = (Assign) exec.expr;
if (assign.lhs.tag == Tree.SELECT) {
Select select = (Select) assign.lhs;
if ((select.sym.flags() & SYNTHETIC) != 0) {
Name selected = name(select.selected);
if (selected != null && selected == selected.table._this)
return true;
}
}
}
}
return false;
}
/**
* If the expression is a method call, return the method name, null
* otherwise.
*/
public static Name calledMethodName(Tree tree) {
if (tree.tag == Tree.EXEC) {
Exec exec = (Exec) tree;
if (exec.expr.tag == Tree.APPLY) {
Name mname = TreeInfo.name(((Apply) exec.expr).meth);
return mname;
}
}
return null;
}
/**
* Is this a call to this or super?
*/
public static boolean isSelfCall(Tree tree) {
Name name = calledMethodName(tree);
if (name != null) {
Name.Table names = name.table;
return name == names._this || name == names._super;
} else {
return false;
}
}
/**
* Is this a constructor whose first (non-synthetic) statement is not
* of the form this(...)?
*/
public static boolean isInitialConstructor(Tree tree) {
Apply app = firstConstructorCall(tree);
if (app == null)
return false;
Name meth = name(app.meth);
return meth == null || meth != meth.table._this;
}
/**
* Return the first call in a constructor definition.
*/
public static Apply firstConstructorCall(Tree tree) {
if (tree.tag != Tree.METHODDEF)
return null;
MethodDef md = (MethodDef) tree;
Name.Table names = md.name.table;
if (md.name != names.init)
return null;
if (md.body == null)
return null;
List stats = md.body.stats;
while (stats.nonEmpty() && isSyntheticInit((Tree) stats.head))
stats = stats.tail;
if (stats.isEmpty())
return null;
if (((Tree) stats.head).tag != Tree.EXEC)
return null;
Exec exec = (Exec) stats.head;
if (exec.expr.tag != Tree.APPLY)
return null;
return (Apply) exec.expr;
}
/**
* The position of the first statement in a block, or the position of
* the block itself if it is empty.
*/
public static int firstStatPos(Tree tree) {
if (tree.tag == Tree.BLOCK && ((Block) tree).stats.nonEmpty())
return ((Tree)((Block) tree).stats.head).pos;
else
return tree.pos;
}
/**
* The end position of given tree, if it is a block with
* defined endpos.
*/
public static int endPos(Tree tree) {
if (tree.tag == Tree.BLOCK && ((Block) tree).endpos != Position.NOPOS)
return ((Block) tree).endpos;
else if (tree.tag == Tree.SYNCHRONIZED)
return endPos(((Synchronized) tree).body);
else if (tree.tag == Tree.TRY) {
Try t = (Try) tree;
return endPos((t.finalizer != null) ? t.finalizer :
((Catch) t.catchers.last()).body);
} else
return tree.pos;
}
/**
* The position of the finalizer of given try/synchronized statement.
*/
public static int finalizerPos(Tree tree) {
if (tree.tag == Tree.TRY) {
Try t = (Try) tree;
assert t.finalizer != null;
return firstStatPos(t.finalizer);
} else if (tree.tag == Tree.SYNCHRONIZED) {
return endPos(((Synchronized) tree).body);
} else {
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 Tree tree) {
class PosScanner extends TreeScanner {
PosScanner() {
super();
}
int pos = tree.pos;
public void visitClassDef(ClassDef that) {
if (that.sym == sym)
pos = that.pos;
super.visitClassDef(that);
}
public void visitMethodDef(MethodDef that) {
if (that.sym == sym)
pos = that.pos;
super.visitMethodDef(that);
}
public void visitVarDef(VarDef that) {
if (that.sym == sym)
pos = that.pos;
super.visitVarDef(that);
}
}
PosScanner s = new PosScanner();
tree.accept(s);
return s.pos;
}
/**
* 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 Tree referencedStatement(Labelled tree) {
Tree t = tree;
do
t = ((Labelled) t).body;
while (t.tag == Tree.LABELLED)
;
switch (t.tag) {
case Tree.DOLOOP:
case Tree.WHILELOOP:
case Tree.FORLOOP:
case Tree.SWITCH:
return t;
default:
return tree;
}
}
/**
* Skip parens and return the enclosed expression
*/
public static Tree skipParens(Tree tree) {
while (tree.tag == Tree.PARENS) {
tree = ((Parens) tree).expr;
}
return tree;
}
/**
* Return the types of a list of trees.
*/
public static List types(List trees) {
ListBuffer ts = new ListBuffer();
for (List l = trees; l.nonEmpty(); l = l.tail)
ts.append(((Tree) 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(Tree tree) {
switch (tree.tag) {
case Tree.IDENT:
return ((Ident) tree).name;
case Tree.SELECT:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -