/**
* 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.
*/
package org.python.pydev.parser.visitors.scope;
import org.python.pydev.core.structure.FastStack;
import org.python.pydev.parser.jython.SimpleNode;
import org.python.pydev.parser.jython.ast.VisitorBase;
import org.python.pydev.parser.jython.ast.exprType;
import org.python.pydev.parser.jython.ast.stmtType;
import org.python.pydev.parser.prettyprinterv2.PrettyPrinterUtilsV2;
/**
* This visitor will try to get the node where the extracted local should actually be added.
*/
public class GetNodeForExtractLocalVisitor extends VisitorBase {
protected final FastStack<FastStack<SimpleNode>> contextStack = new FastStack<FastStack<SimpleNode>>(10);
private int initialExtractLocalLine;
private boolean keepGoing = true;
private stmtType lastStmt;
public GetNodeForExtractLocalVisitor(int initialExtractLocalLine) {
this.initialExtractLocalLine = initialExtractLocalLine;
contextStack.push(new FastStack<SimpleNode>(10)); //start with a stack.
}
@Override
public void traverse(SimpleNode node) throws Exception {
if (!keepGoing) {
return;
}
boolean multiLineStmt = false;
if (node instanceof stmtType) {
multiLineStmt = PrettyPrinterUtilsV2.isMultiLineStmt((stmtType) node);
if (multiLineStmt) {
contextStack.push(new FastStack<SimpleNode>(10));
}
lastStmt = (stmtType) node;
node.traverse(this);
if (multiLineStmt && keepGoing) {
contextStack.pop();
}
} else {
FastStack<SimpleNode> peek = contextStack.peek();
boolean inExpr = peek.size() != 0;
if (!inExpr && node instanceof exprType) {
peek.push(node);
}
node.traverse(this);
if (!inExpr && node instanceof exprType && keepGoing) {
peek.pop();
}
}
}
@Override
protected Object unhandled_node(SimpleNode node) throws Exception {
if (node instanceof stmtType) {
return null;
}
if (node.beginLine >= initialExtractLocalLine) {
keepGoing = false;
}
return null;
}
public SimpleNode getLastInContextBeforePassedLine() {
FastStack<SimpleNode> peeked = contextStack.peek();
if (peeked.size() > 0) {
SimpleNode expr = peeked.peek();
if (lastStmt != null) {
if (expr.beginLine < lastStmt.beginLine) {
return expr;
} else {
return lastStmt;
}
}
}
return lastStmt;
}
}