/**
* Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Eclipse Public License (EPL).
* Please see the license.txt included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
/*
* Created on Jan 20, 2005
*
* @author Fabio Zadrozny
*/
package org.python.pydev.editor.codecompletion.revisited.visitors;
import org.python.pydev.core.ILocalScope;
import org.python.pydev.core.structure.FastStack;
import org.python.pydev.parser.jython.SimpleNode;
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.Module;
import org.python.pydev.parser.visitors.NodeUtils;
/**
* @author Fabio Zadrozny
*/
public class FindScopeVisitor extends AbstractVisitor {
/**
* Stack of classes / methods representing the scope.
*/
protected FastStack<SimpleNode> stackScope = new FastStack<SimpleNode>(20);
/**
* This is the scope.
*/
public ILocalScope scope = new LocalScope(new FastStack<SimpleNode>(20));
/**
* Variable to mark if we found scope.
*/
protected boolean found = false;
/**
* line to find
*/
private int line;
/**
* column to find
*/
private int col;
/**
* Only for subclasses
*/
protected FindScopeVisitor() {
}
/**
* Constructor
*
* @param line in ast coords (starts at 1)
* @param col in ast coords (starts at 1)
*/
public FindScopeVisitor(int line, int col) {
this.line = line;
this.col = col;
}
/**
* @see org.python.pydev.parser.jython.ast.VisitorBase#unhandled_node(org.python.pydev.parser.jython.SimpleNode)
*/
protected Object unhandled_node(SimpleNode node) throws Exception {
//the line passed in starts at 1 and the lines for the visitor nodes start at 0
if (!found && !(node instanceof Module)) {
if (line <= node.beginLine) {
//scope is locked at this time.
found = true;
int original = scope.getIfMainLine();
scope = new LocalScope((FastStack<SimpleNode>) this.stackScope.createCopy());
scope.setIfMainLine(original);
}
} else {
if (scope.getScopeEndLine() == -1 && line < node.beginLine && col >= node.beginColumn) {
scope.setScopeEndLine(node.beginLine);
}
}
return node;
}
/**
* @see org.python.pydev.parser.jython.ast.VisitorBase#traverse(org.python.pydev.parser.jython.SimpleNode)
*/
public void traverse(SimpleNode node) throws Exception {
node.traverse(this);
}
/**
* @see org.python.pydev.parser.jython.ast.VisitorBase#visitIf(org.python.pydev.parser.jython.ast.If)
*/
public Object visitIf(If node) throws Exception {
checkIfMainNode(node);
return super.visitIf(node);
}
/**
* Checks if we found an 'if' main node
*/
protected void checkIfMainNode(If node) {
boolean isIfMainNode = NodeUtils.isIfMAinNode(node);
if (isIfMainNode) {
scope.setIfMainLine(node.beginLine);
}
}
/**
* @see org.python.pydev.parser.jython.ast.VisitorBase#visitClassDef(org.python.pydev.parser.jython.ast.ClassDef)
*/
public Object visitClassDef(ClassDef node) throws Exception {
if (!found) {
stackScope.push(node);
node.traverse(this);
stackScope.pop();
}
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 {
if (!found) {
stackScope.push(node);
node.traverse(this);
stackScope.pop();
}
return null;
}
@Override
public Object visitModule(Module node) throws Exception {
stackScope.push(node);
return super.visitModule(node);
}
}