📄 nodeutils.java
字号:
/*
* Created on 13/07/2005
*/
package org.python.pydev.parser.visitors;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.python.pydev.core.FullRepIterable;
import org.python.pydev.core.REF;
import org.python.pydev.core.log.Log;
import org.python.pydev.parser.jython.SimpleNode;
import org.python.pydev.parser.jython.SpecialStr;
import org.python.pydev.parser.jython.ast.Attribute;
import org.python.pydev.parser.jython.ast.Call;
import org.python.pydev.parser.jython.ast.ClassDef;
import org.python.pydev.parser.jython.ast.Compare;
import org.python.pydev.parser.jython.ast.Dict;
import org.python.pydev.parser.jython.ast.Expr;
import org.python.pydev.parser.jython.ast.FunctionDef;
import org.python.pydev.parser.jython.ast.If;
import org.python.pydev.parser.jython.ast.Import;
import org.python.pydev.parser.jython.ast.ImportFrom;
import org.python.pydev.parser.jython.ast.ListComp;
import org.python.pydev.parser.jython.ast.Name;
import org.python.pydev.parser.jython.ast.NameTok;
import org.python.pydev.parser.jython.ast.Num;
import org.python.pydev.parser.jython.ast.Str;
import org.python.pydev.parser.jython.ast.Subscript;
import org.python.pydev.parser.jython.ast.Tuple;
import org.python.pydev.parser.jython.ast.aliasType;
import org.python.pydev.parser.jython.ast.commentType;
import org.python.pydev.parser.jython.ast.excepthandlerType;
import org.python.pydev.parser.jython.ast.exprType;
import org.python.pydev.parser.jython.ast.keywordType;
import org.python.pydev.parser.jython.ast.stmtType;
import org.python.pydev.parser.visitors.scope.ASTEntry;
import org.python.pydev.parser.visitors.scope.EasyASTIteratorVisitor;
public class NodeUtils {
/**
* @param node a function definition (if other will return an empty string)
* @return a string with the representation of the parameters of the function
*/
public static String getNodeArgs(SimpleNode node) {
if(node instanceof ClassDef){
ClassDef c = (ClassDef) node;
for(stmtType t: c.body){
if(t instanceof FunctionDef){
FunctionDef def = (FunctionDef) t;
if(((NameTok)def.name).id.equals("__init__")){
node = def;
break; //keep going to get the arguments of the __init__
}
}
}
}
if(node instanceof FunctionDef){
FunctionDef f = (FunctionDef)node;
String startPar = "( ";
StringBuffer buffer = new StringBuffer(startPar);
for (int i = 0; i < f.args.args.length; i++) {
if(buffer.length() > startPar.length()){
buffer.append(", ");
}
buffer.append( getRepresentationString(f.args.args[i]) );
}
buffer.append(" )");
return buffer.toString();
}
return "";
}
/**
* Get the representation for the passed parameter (if it is a String, it is itself, if it
* is a SimpleNode, get its representation
*/
private static String discoverRep(Object o){
if(o instanceof String){
return (String) o;
}
if(o instanceof NameTok){
return ((NameTok) o).id;
}
if(o instanceof SimpleNode){
return getRepresentationString((SimpleNode) o);
}
throw new RuntimeException("Expecting a String or a SimpleNode");
}
public static String getRepresentationString(SimpleNode node) {
return getRepresentationString(node, false);
}
/**
* @param node this is the node from whom we want to get the representation
* @return A suitable String representation for some node.
*/
public static String getRepresentationString(SimpleNode node, boolean useTypeRepr) {
if(node instanceof NameTok){
NameTok tok = (NameTok) node;
return tok.id;
}
if(node instanceof Name){
Name name = (Name) node;
return name.id;
}
if(node instanceof aliasType){
aliasType type = (aliasType) node;
return ((NameTok)type.name).id;
}
if(node instanceof Attribute){
Attribute attribute = (Attribute) node;
return discoverRep(attribute.attr);
}
if(node instanceof keywordType){
keywordType type = (keywordType) node;
return discoverRep(type.arg);
}
if(node instanceof ClassDef){
ClassDef def = (ClassDef) node;
return ((NameTok)def.name).id;
}
if(node instanceof FunctionDef){
FunctionDef def = (FunctionDef) node;
return ((NameTok)def.name).id;
}
if (node instanceof Call){
Call call = ((Call)node);
return getRepresentationString(call.func, useTypeRepr);
}
if (node instanceof org.python.pydev.parser.jython.ast.List || node instanceof ListComp){
String val = "[]";
if(useTypeRepr){
val = getBuiltinType(val);
}
return val;
}
if (node instanceof Str){
String val;
if(useTypeRepr){
val = getBuiltinType("''");
}else{
val = "'"+((Str)node).s+"'";
}
return val;
}
if (node instanceof Tuple){
StringBuffer buf = new StringBuffer();
Tuple t = (Tuple)node;
for ( exprType e : t.elts){
buf.append(getRepresentationString(e, useTypeRepr));
buf.append(", ");
}
if(t.elts.length > 0){
int l = buf.length();
buf.deleteCharAt(l-1);
buf.deleteCharAt(l-2);
}
String val = "("+buf+")";
if(useTypeRepr){
val = getBuiltinType(val);
}
return val;
}
if (node instanceof Num){
String val = ((Num)node).n.toString();
if(useTypeRepr){
val = getBuiltinType(val);
}
return val;
}
if (node instanceof Import){
aliasType[] names = ((Import)node).names;
for (aliasType n : names) {
if(n.asname != null){
return ((NameTok)n.asname).id;
}
return ((NameTok)n.name).id;
}
}
if(node instanceof commentType){
commentType type = (commentType) node;
return type.id;
}
if(node instanceof excepthandlerType){
excepthandlerType type = (excepthandlerType) node;
return type.name.toString();
}
return null;
}
/**
* @param node
* @param t
*/
public static String getNodeDocString(SimpleNode node) {
Str s = getNodeDocStringNode(node);
if(s != null){
return s.s;
}
return null;
}
public static Str getNodeDocStringNode(SimpleNode node) {
Str s = null;
stmtType body[] = null;
if(node instanceof FunctionDef){
FunctionDef def = (FunctionDef) node;
body = def.body;
} else if(node instanceof ClassDef){
ClassDef def = (ClassDef) node;
body = def.body;
}
if (body != null && body.length > 0) {
if (body[0] instanceof Expr) {
Expr e = (Expr) body[0];
if (e.value instanceof Str) {
s = (Str) e.value;
}
}
}
return s;
}
public static String getFullRepresentationString(SimpleNode node) {
return getFullRepresentationString(node, false);
}
public static String getFullRepresentationString(SimpleNode node, boolean fullOnSubscriptOrCall) {
if (node instanceof Dict){
return "dict";
}
if (node instanceof Str || node instanceof Num){
return getRepresentationString(node, true);
}
if (node instanceof Tuple){
return getRepresentationString(node, true);
}
if (node instanceof Subscript){
return getFullRepresentationString(((Subscript)node).value);
}
if(node instanceof Call){
Call c = (Call) node;
node = c.func;
if (REF.hasAttr(node, "value") && REF.hasAttr(node, "attr")) {
return getFullRepresentationString((SimpleNode) REF.getAttrObj(node, "value")) + "." +discoverRep(REF.getAttrObj(node, "attr"));
}
}
if (node instanceof Attribute){
//attributes are tricky because we only have backwards access initially, so, we have to:
//get it forwards
List attributeParts = getAttributeParts((Attribute) node);
StringBuffer buf = new StringBuffer();
for (Object part : attributeParts) {
if(part instanceof Call){
//stop on a call (that's what we usually want, since the end will depend on the things that
//return from the call).
if(!fullOnSubscriptOrCall){
return buf.toString();
}else{
buf.append("()");//call
}
}else if (part instanceof Subscript){
if(!fullOnSubscriptOrCall){
//stop on a subscript : e.g.: in bb.cc[10].d we only want the bb.cc part
return getFullRepresentationString(((Subscript)part).value);
}else{
buf.append(getFullRepresentationString(((Subscript)part).value));
buf.append("[]");//subscript access
}
}else{
//otherwise, just add another dot and keep going.
if(buf.length() > 0){
buf.append(".");
}
buf.append(getRepresentationString((SimpleNode) part, true));
}
}
return buf.toString();
}
return getRepresentationString(node, true);
}
/**
* line and col start at 1
*/
public static boolean isWithin(int line, int col, SimpleNode node){
int colDefinition = NodeUtils.getColDefinition(node);
int lineDefinition = NodeUtils.getLineDefinition(node);
int[] colLineEnd = NodeUtils.getColLineEnd(node, false);
if(lineDefinition <= line && colDefinition <= col &&
colLineEnd[0] >= line && colLineEnd[1] >= col){
return true;
}
return false;
}
public static SimpleNode getNameTokFromNode(SimpleNode ast2){
if (ast2 instanceof ClassDef){
ClassDef c = (ClassDef) ast2;
return c.name;
}
if (ast2 instanceof FunctionDef){
FunctionDef c = (FunctionDef) ast2;
return c.name;
}
return ast2;
}
public static int getNameLineDefinition(SimpleNode ast2) {
return getLineDefinition(getNameTokFromNode(ast2));
}
public static int getNameColDefinition(SimpleNode ast2) {
return getColDefinition(getNameTokFromNode(ast2));
}
/**
* @param ast2 the node to work with
* @return the line definition of a node
*/
public static int getLineDefinition(SimpleNode ast2) {
while(ast2 instanceof Attribute){
exprType val = ((Attribute)ast2).value;
if(!(val instanceof Call)){
ast2 = val;
}else{
break;
}
}
if(ast2 instanceof FunctionDef){
return ((FunctionDef)ast2).name.beginLine;
}
if(ast2 instanceof ClassDef){
return ((ClassDef)ast2).name.beginLine;
}
return ast2.beginLine;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -