[Pydev-cvs] org.python.pydev.parser/src/org/python/pydev/parser/visitors/scope CodeFoldingVisitor.
Brought to you by:
fabioz
Update of /cvsroot/pydev/org.python.pydev.parser/src/org/python/pydev/parser/visitors/scope In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20369/src/org/python/pydev/parser/visitors/scope Modified Files: ASTEntry.java EasyAstIteratorBase.java EasyASTIteratorWithChildrenVisitor.java Added Files: CodeFoldingVisitor.java Log Message: Integrated code-folding for elements (for, while, try, etc) Index: ASTEntry.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.parser/src/org/python/pydev/parser/visitors/scope/ASTEntry.java,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** ASTEntry.java 26 Feb 2007 02:05:05 -0000 1.14 --- ASTEntry.java 31 Oct 2007 00:54:36 -0000 1.15 *************** *** 9,13 **** --- 9,15 ---- import org.python.pydev.parser.jython.ast.Attribute; import org.python.pydev.parser.jython.ast.ClassDef; + import org.python.pydev.parser.jython.ast.For; 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; *************** *** 16,19 **** --- 18,25 ---- import org.python.pydev.parser.jython.ast.NameTok; import org.python.pydev.parser.jython.ast.Str; + import org.python.pydev.parser.jython.ast.TryExcept; + import org.python.pydev.parser.jython.ast.TryFinally; + import org.python.pydev.parser.jython.ast.While; + import org.python.pydev.parser.jython.ast.With; import org.python.pydev.parser.jython.ast.aliasType; import org.python.pydev.parser.jython.ast.commentType; *************** *** 129,132 **** --- 135,156 ---- name = "Str"; + }else if(node instanceof While){ + name = "While"; + + }else if(node instanceof If){ + name = "If"; + + }else if(node instanceof For){ + name = "For"; + + }else if(node instanceof TryExcept){ + name = "TryExcept"; + + }else if(node instanceof TryFinally){ + name = "TryFinally"; + + }else if(node instanceof With){ + name = "With"; + }else if(node instanceof commentType){ name = "comment"; Index: EasyAstIteratorBase.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.parser/src/org/python/pydev/parser/visitors/scope/EasyAstIteratorBase.java,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** EasyAstIteratorBase.java 19 Jun 2007 00:30:43 -0000 1.19 --- EasyAstIteratorBase.java 31 Oct 2007 00:54:36 -0000 1.20 *************** *** 37,42 **** protected Object unhandled_node(SimpleNode node) throws Exception { this.lastVisited = node; ! if (this.lastVisited.beginLine > higherLine){ ! higherLine = this.lastVisited.beginLine; } if(node.specialsAfter != null){ --- 37,43 ---- protected Object unhandled_node(SimpleNode node) throws Exception { this.lastVisited = node; ! int l = NodeUtils.getLineEnd(this.lastVisited); ! if (l > higherLine){ ! higherLine = l; } if(node.specialsAfter != null){ *************** *** 69,73 **** * @return */ ! private ASTEntry before(SimpleNode node) { ASTEntry entry; entry = createEntry(); --- 70,74 ---- * @return */ ! protected ASTEntry before(SimpleNode node) { ASTEntry entry; entry = createEntry(); *************** *** 92,102 **** * @param entry */ ! private void after(ASTEntry entry) { stack.pop(); ! int lineEnd = NodeUtils.getLineEnd(lastVisited); ! if(lineEnd > higherLine){ ! entry.endLine = lineEnd; ! }else{ ! entry.endLine = higherLine; } } --- 93,107 ---- * @param entry */ ! protected void after(ASTEntry entry) { stack.pop(); ! ! //only set the end line if it was still not set ! if(entry.endLine == 0){ ! int lineEnd = NodeUtils.getLineEnd(lastVisited); ! if(lineEnd > higherLine){ ! entry.endLine = lineEnd; ! }else{ ! entry.endLine = higherLine; ! } } } *************** *** 142,146 **** protected boolean isInGlobal() { ! Iterator iterator = stack.iterator(); while(iterator.hasNext()){ SimpleNode node = (SimpleNode) iterator.next(); --- 147,151 ---- protected boolean isInGlobal() { ! Iterator<SimpleNode> iterator = stack.iterator(); while(iterator.hasNext()){ SimpleNode node = (SimpleNode) iterator.next(); *************** *** 157,161 **** */ protected boolean isInClassMethodDecl() { ! Iterator iterator = stack.iterator(); while(iterator.hasNext()){ SimpleNode node = (SimpleNode) iterator.next(); --- 162,166 ---- */ protected boolean isInClassMethodDecl() { ! Iterator<SimpleNode> iterator = stack.iterator(); while(iterator.hasNext()){ SimpleNode node = (SimpleNode) iterator.next(); *************** *** 263,273 **** * @see EasyASTIteratorVisitor#getIterator(Class[]) */ public Iterator<ASTEntry> getIterator(Class class_) { return getIterator(new Class[]{class_}); } public List<ASTEntry> getAsList(Class ... classes) { List<ASTEntry> newList = new ArrayList<ASTEntry>(); ! for (Iterator iter = nodes.iterator(); iter.hasNext();) { ASTEntry entry = (ASTEntry) iter.next(); if(isFromClass(entry.node, classes)){ --- 268,280 ---- * @see EasyASTIteratorVisitor#getIterator(Class[]) */ + @SuppressWarnings("unchecked") public Iterator<ASTEntry> getIterator(Class class_) { return getIterator(new Class[]{class_}); } + @SuppressWarnings("unchecked") public List<ASTEntry> getAsList(Class ... classes) { List<ASTEntry> newList = new ArrayList<ASTEntry>(); ! for (Iterator<ASTEntry> iter = nodes.iterator(); iter.hasNext();) { ASTEntry entry = (ASTEntry) iter.next(); if(isFromClass(entry.node, classes)){ *************** *** 278,281 **** --- 285,289 ---- } + @SuppressWarnings("unchecked") public List<ASTEntry> getAsList(Class class_) { return getAsList(new Class[]{class_}); *************** *** 286,289 **** --- 294,298 ---- * @return an iterator with nodes found from the passed classes */ + @SuppressWarnings("unchecked") public Iterator<ASTEntry> getIterator(Class ... classes) { return getAsList(classes).iterator(); --- NEW FILE: CodeFoldingVisitor.java --- package org.python.pydev.parser.visitors.scope; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.python.pydev.parser.jython.SimpleNode; import org.python.pydev.parser.jython.ast.BoolOp; import org.python.pydev.parser.jython.ast.For; 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.Str; import org.python.pydev.parser.jython.ast.TryExcept; import org.python.pydev.parser.jython.ast.TryFinally; import org.python.pydev.parser.jython.ast.While; import org.python.pydev.parser.jython.ast.With; import org.python.pydev.parser.jython.ast.exprType; import org.python.pydev.parser.jython.ast.stmtType; public class CodeFoldingVisitor extends EasyASTIteratorWithChildrenVisitor{ /** * Creates the iterator and traverses the passed root so that the results can be gotten. */ public static CodeFoldingVisitor create(SimpleNode root){ CodeFoldingVisitor visitor = new CodeFoldingVisitor(); try { root.accept(visitor); } catch (Exception e) { throw new RuntimeException(e); } return visitor; } @Override public Object visitIf(If node) throws Exception { ASTEntry entry = before(node); parents.push(entry); traverse(node); after(entry); parents.pop(); return null; } @Override protected void doAddNode(ASTEntry entry) { ASTEntry parent = entry.parent; if(entry.node instanceof If){ If entryIf = (If) entry.node; //treat elifs if(parent != null && parent.node instanceof If){ If parentIf = (If) parent.node; if(parentIf.orelse != null && parentIf.orelse.length > 0 && parentIf.orelse[0] == entryIf){ parent.endLine = entry.node.beginLine-1; if(entry.parent != null){ entry.parent = entry.parent.parent; } super.doAddNode(entry); return; } } } super.doAddNode(entry); } @Override protected void after(ASTEntry entry) { super.after(entry); //if we just added a node, we have to check if it's an If that has an ending else... if(entry.node instanceof If){ If entryIf = (If) entry.node; checkElse(entryIf, entry); } } /** * Check if the passed if has an else... If it has, generate a 'fake' If entry for it (so that it's gotten later) */ private void checkElse(If entryIf, ASTEntry parentIf) { //treat elses if(entryIf.orelse != null && entryIf.orelse.length > 0){ stmtType firstOrElseStmt = entryIf.orelse[0]; if(!(firstOrElseStmt instanceof If)){ If generatedIf = new If(new BoolOp(BoolOp.And, new exprType[0]), new stmtType[0], new stmtType[0]); generatedIf.beginLine = firstOrElseStmt.beginLine-1; generatedIf.beginColumn = 1; ASTEntry generatedEntry = createEntry(); generatedEntry.endLine = parentIf.endLine; parentIf.endLine = generatedIf.beginLine-1; generatedEntry.node = generatedIf; if(generatedEntry.parent != null){ generatedEntry.parent = generatedEntry.parent.parent; } //actually go on and add the entry... super.doAddNode(generatedEntry); } } } @Override public Object visitFor(For node) throws Exception { return defaultVisit(node); } @Override public Object visitWhile(While node) throws Exception { return defaultVisit(node); } @Override public Object visitTryExcept(TryExcept node) throws Exception { return defaultVisit(node); } @Override public Object visitTryFinally(TryFinally node) throws Exception { return defaultVisit(node); } @Override public Object visitWith(With node) throws Exception { return defaultVisit(node); } //not all methods have bodies... (some have 'atomic' adds) @Override public Object visitImport(Import node) throws Exception { atomic(node); return null; } @Override public Object visitImportFrom(ImportFrom node) throws Exception { atomic(node); return null; } @Override public Object visitStr(Str node) throws Exception { atomic(node); return null; } @Override protected ASTEntry atomic(SimpleNode node) { try { unhandled_node(node); } catch (Exception e) { throw new RuntimeException(e); } return super.atomic(node); } private Object defaultVisit(SimpleNode node) throws Exception { unhandled_node(node); ASTEntry entry = before(node); parents.push(entry); traverse(node); after(entry); parents.pop(); return null; } /** * Overriden so that we consider the children when iterating (and don't get only the roots) * because we're interested in having a flat list in this case, and not actually the hierachical info. */ @SuppressWarnings("unchecked") @Override public List<ASTEntry> getAsList(Class ... classes) { List<ASTEntry> newList = new ArrayList<ASTEntry>(); for (Iterator<ASTEntry> iter = nodes.iterator(); iter.hasNext();) { ASTEntryWithChildren entry = (ASTEntryWithChildren) iter.next(); checkEntry(newList, entry, classes); } return newList; } @SuppressWarnings("unchecked") private void checkEntry(List<ASTEntry> newList, ASTEntryWithChildren entry, Class... classes) { if(isFromClass(entry.node, classes)){ newList.add(entry); } if(entry.children != null){ for(ASTEntry child:entry.children){ checkEntry(newList, (ASTEntryWithChildren) child, classes); } } } } Index: EasyASTIteratorWithChildrenVisitor.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.parser/src/org/python/pydev/parser/visitors/scope/EasyASTIteratorWithChildrenVisitor.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** EasyASTIteratorWithChildrenVisitor.java 10 Jun 2006 18:43:19 -0000 1.1 --- EasyASTIteratorWithChildrenVisitor.java 31 Oct 2007 00:54:36 -0000 1.2 *************** *** 7,14 **** import java.util.ArrayList; ! public class EasyASTIteratorWithChildrenVisitor extends EasyAstIteratorBase{ /** ! * Overriden because we deal only with the nodes with children in this iterator * * @see org.python.pydev.parser.visitors.scope.EasyAstIteratorBase#createEntry() --- 7,22 ---- import java.util.ArrayList; ! /** ! * The ASTEntries in this visitor should know about which context (parent) they're in. ! * ! * The definition of what's a context (e.g.: should an if generate a new context or only a class/method?) ! * is up to the actual visitor. ! * ! * @author Fabio ! */ ! public abstract class EasyASTIteratorWithChildrenVisitor extends EasyAstIteratorBase{ /** ! * Overridden because we deal only with the nodes with children in this iterator * * @see org.python.pydev.parser.visitors.scope.EasyAstIteratorBase#createEntry() |