heuristicfindattrs.java

来自「Python Development Environment (Python I」· Java 代码 · 共 238 行

JAVA
238
字号
/*
 * Created on Dec 21, 2004
 *
 * @author Fabio Zadrozny
 */
package org.python.pydev.editor.codecompletion.revisited.visitors;

import java.util.Stack;

import org.python.pydev.core.FullRepIterable;
import org.python.pydev.core.ICompletionState;
import org.python.pydev.parser.jython.SimpleNode;
import org.python.pydev.parser.jython.ast.Assign;
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.FunctionDef;
import org.python.pydev.parser.jython.ast.If;
import org.python.pydev.parser.jython.ast.Name;
import org.python.pydev.parser.jython.ast.NameTok;
import org.python.pydev.parser.jython.ast.Tuple;
import org.python.pydev.parser.jython.ast.exprType;

/**
 * This class defines how we should find attributes. 
 * 
 * Heuristics provided allow someone to find an attr inside a function definition (IN_INIT or IN_ANY)
 * or inside a method call (e.g. a method called properties.create(x=0) - that's what I use, so, that's specific).
 * Other uses may be customized later, once we know which other uses are done.
 * 
 * @author Fabio Zadrozny
 */
public class HeuristicFindAttrs extends AbstractVisitor {

    /**
     * Whether we should add the attributes that are added as 'self.xxx = 10'
     */
    private boolean discoverSelfAttrs = true;

    /**
     * @param where
     * @param how
     * @param methodCall
     * @param state 
     */
    public HeuristicFindAttrs(int where, int how, String methodCall, String moduleName, ICompletionState state) {
        this.where = where;
        this.how = how;
        this.methodCall = methodCall;
        this.moduleName = moduleName;
        if(state != null){
            if(state.getLookingFor() == ICompletionState.LOOKING_FOR_CLASSMETHOD_VARIABLE){
                this.discoverSelfAttrs = false;
            }
        }
    }
    
    public Stack<SimpleNode> stack = new Stack<SimpleNode>();
    
    public static final int WHITIN_METHOD_CALL = 0;
    public static final int WHITIN_INIT = 1;
    public static final int WHITIN_ANY = 2;
    
    public int where = -1;
    
    
    public static final int IN_ASSIGN = 0;
    public static final int IN_KEYWORDS = 1;

    public int how = -1;
    
    private boolean entryPointCorrect = false;
    
    private boolean inAssing = false;
    private boolean inFuncDef = false;
    
    /**
     * This is the method that can be used to declare them (e.g. properties.create)
     * It's only used it it is a method call.
     */
    public String methodCall = "";

    /**
     * @see org.python.pydev.parser.jython.ast.VisitorBase#unhandled_node(org.python.pydev.parser.jython.SimpleNode)
     */
    protected Object unhandled_node(SimpleNode node) throws Exception {
        return null;
    }

    /**
     * @see org.python.pydev.parser.jython.ast.VisitorBase#traverse(org.python.pydev.parser.jython.SimpleNode)
     */
    public void traverse(SimpleNode node) throws Exception {
    }
    
    
    
    //ENTRY POINTS
    /**
     * @see org.python.pydev.parser.jython.ast.VisitorBase#visitCall(org.python.pydev.parser.jython.ast.Call)
     */
    public Object visitCall(Call node) throws Exception {
        if(entryPointCorrect == false && methodCall.length() > 0){
	        entryPointCorrect = true;
	        String[] c = FullRepIterable.dotSplit(methodCall);
	        
	        
	        
	        if (node.func instanceof Attribute){
		        Attribute func = (Attribute)node.func;
		        if(((NameTok)func.attr).id.equals(c[1])){
		        
			        if(func.value instanceof Name){
			            Name name = (Name) func.value;
			            if(name.id.equals(c[0])){
			                for (int i=0; i<node.keywords.length; i++){
			                    addToken(node.keywords[i]);
			                }
			            }
			        }
		        }
	        }
	        
	        entryPointCorrect = false;
        }
        return null;
    }

    /**
     * @see org.python.pydev.parser.jython.ast.VisitorBase#visitFunctionDef(org.python.pydev.parser.jython.ast.FunctionDef)
     */
    public Object visitFunctionDef(FunctionDef node) throws Exception {
        stack.push(node);
        if(entryPointCorrect == false){
	        entryPointCorrect = true;
	        inFuncDef = true;
	        
	        if(where == WHITIN_ANY){
	            node.traverse(this);
	        
	        } else if(where == WHITIN_INIT && node.name.equals("__init__")){
	            node.traverse(this);
	        }
	        entryPointCorrect = false;
	        inFuncDef = false;
        } 
        stack.pop();
        
        return null;
    }
    //END ENTRY POINTS
    
    @Override
    public Object visitClassDef(ClassDef node) throws Exception {
        stack.push(node);
        Object r = super.visitClassDef(node);
        stack.pop();
        return r;
    }
    
    
    
    /**
     * Name should be whithin assign.
     * 
     * @see org.python.pydev.parser.jython.ast.VisitorIF#visitAssign(org.python.pydev.parser.jython.ast.Assign)
     */
    public Object visitAssign(Assign node) throws Exception {
        if(how == IN_ASSIGN){
            inAssing = true;
            
            for (int i = 0; i < node.targets.length; i++) {
                if(node.targets[i] instanceof Attribute){
                    visitAttribute((Attribute)node.targets[i]);
                    
                }else if(node.targets[i] instanceof Name && inFuncDef == false){
                    String id = ((Name)node.targets[i]).id;
                    if(id != null){
                        addToken(node.targets[i]);
                    }
                    
                }else if(node.targets[i] instanceof Tuple && inFuncDef == false){
                	//that's for finding the definition: a,b,c = range(3) inside a class definition
                	Tuple tuple = (Tuple) node.targets[i];
                	for(exprType t :tuple.elts){
                		if(t instanceof Name){
                			String id = ((Name)t).id;
                			if(id != null){
                				addToken(t);
                			}
                		}
                	}
                	
                }
            }
            
            inAssing = false;
        }
        return null;
    }
    
    /**
     * @see org.python.pydev.parser.jython.ast.VisitorBase#visitAttribute(org.python.pydev.parser.jython.ast.Attribute)
     */
    public Object visitAttribute(Attribute node) throws Exception {
        if(how == IN_ASSIGN && inAssing){
            if(node.value instanceof Name){
                String id = ((Name)node.value).id;
                if(id != null){
                    if(this.discoverSelfAttrs){
                        if(id.equals("self")){
                            addToken(node);
                           
                        }
                    }else{
                        if (id.equals("cls")){
                            addToken(node);
                        }
                    }
                }
            }
        }
        return null;
    }
    

    /**
     * @see org.python.pydev.parser.jython.ast.VisitorIF#visitIf(org.python.pydev.parser.jython.ast.If)
     */
    public Object visitIf(If node) throws Exception {
        node.traverse(this);
        return null;
    }



}

⌨️ 快捷键说明

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