### Eclipse Workspace Patch 1.0 #P org.eclipse.cdt.ui Index: src/org/eclipse/cdt/ui/PreferenceConstants.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.cdt/all/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java,v retrieving revision 1.40 diff -u -r1.40 PreferenceConstants.java --- src/org/eclipse/cdt/ui/PreferenceConstants.java 12 Dec 2007 13:34:28 -0000 1.40 +++ src/org/eclipse/cdt/ui/PreferenceConstants.java 19 Jan 2008 21:17:42 -0000 @@ -779,7 +779,7 @@ * */ public static final String EDITOR_FOLDING_ENABLED= "editor_folding_enabled"; //$NON-NLS-1$ - + /** * A named preference that stores the configured folding provider. *

@@ -800,6 +800,14 @@ public static final String EDITOR_FOLDING_STRUCTURES= "editor_folding_default_structures"; //$NON-NLS-1$ /** + * A named preference that stores the value for statements (if/else while/do, for, switch statements) + *

+ * Value is of type Boolean. + *

+ */ + public static final String EDITOR_FOLDING_STATEMENTS = "editor_folding_statements"; //$NON-NLS-1$ + + /** * A named preference that stores the value for functions folding for the default folding provider. *

* Value is of type Boolean. Index: src/org/eclipse/cdt/internal/ui/text/folding/FoldingMessages.properties =================================================================== RCS file: /cvsroot/tools/org.eclipse.cdt/all/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/FoldingMessages.properties,v retrieving revision 1.7 diff -u -r1.7 FoldingMessages.properties --- src/org/eclipse/cdt/internal/ui/text/folding/FoldingMessages.properties 28 May 2007 20:25:51 -0000 1.7 +++ src/org/eclipse/cdt/internal/ui/text/folding/FoldingMessages.properties 19 Jan 2008 21:17:39 -0000 @@ -20,5 +20,6 @@ DefaultCFoldingPreferenceBlock_headers= &Header Comments DefaultCFoldingPreferenceBlock_inactive_code= &Inactive Preprocessor Branches DefaultCFoldingPreferenceBlock_preprocessor_enabled= Enable folding of preprocessor branches (#if/#endif) +DefaultCFoldingPreferenceBlock_statements_enabled= Enable folding of control flow statements (if, else, do/while, for, switch) EmptyCFoldingPreferenceBlock_emptyCaption= Index: src/org/eclipse/cdt/internal/ui/text/folding/DefaultCFoldingPreferenceBlock.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.cdt/all/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/DefaultCFoldingPreferenceBlock.java,v retrieving revision 1.7 diff -u -r1.7 DefaultCFoldingPreferenceBlock.java --- src/org/eclipse/cdt/internal/ui/text/folding/DefaultCFoldingPreferenceBlock.java 3 Dec 2007 14:04:09 -0000 1.7 +++ src/org/eclipse/cdt/internal/ui/text/folding/DefaultCFoldingPreferenceBlock.java 19 Jan 2008 21:17:36 -0000 @@ -92,6 +92,7 @@ inner.setLayout(layout); addCheckBox(inner, FoldingMessages.DefaultCFoldingPreferenceBlock_preprocessor_enabled, PreferenceConstants.EDITOR_FOLDING_PREPROCESSOR_BRANCHES_ENABLED, 1); + addCheckBox(inner, FoldingMessages.DefaultCFoldingPreferenceBlock_statements_enabled, PreferenceConstants.EDITOR_FOLDING_STATEMENTS, 1); ControlFactory.createEmptySpace(inner); Composite group= ControlFactory.createGroup(inner, FoldingMessages.DefaultCFoldingPreferenceBlock_title, 1); @@ -101,7 +102,7 @@ addCheckBox(group, FoldingMessages.DefaultCFoldingPreferenceBlock_methods, PreferenceConstants.EDITOR_FOLDING_METHODS, 0); addCheckBox(group, FoldingMessages.DefaultCFoldingPreferenceBlock_structures, PreferenceConstants.EDITOR_FOLDING_STRUCTURES, 0); addCheckBox(group, FoldingMessages.DefaultCFoldingPreferenceBlock_comments, PreferenceConstants.EDITOR_FOLDING_COMMENTS, 0); - addCheckBox(group, FoldingMessages.DefaultCFoldingPreferenceBlock_headers, PreferenceConstants.EDITOR_FOLDING_HEADERS, 0); + addCheckBox(group, FoldingMessages.DefaultCFoldingPreferenceBlock_headers, PreferenceConstants.EDITOR_FOLDING_HEADERS, 0); fInactiveCodeFoldingCheckBox= addCheckBox(group, FoldingMessages.DefaultCFoldingPreferenceBlock_inactive_code, PreferenceConstants.EDITOR_FOLDING_INACTIVE_CODE, 0); return inner; Index: src/org/eclipse/cdt/internal/ui/text/folding/DefaultCFoldingStructureProvider.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.cdt/all/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/DefaultCFoldingStructureProvider.java,v retrieving revision 1.23 diff -u -r1.23 DefaultCFoldingStructureProvider.java --- src/org/eclipse/cdt/internal/ui/text/folding/DefaultCFoldingStructureProvider.java 30 Oct 2007 10:32:30 -0000 1.23 +++ src/org/eclipse/cdt/internal/ui/text/folding/DefaultCFoldingStructureProvider.java 19 Jan 2008 21:17:39 -0000 @@ -50,6 +50,21 @@ import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.IASTBreakStatement; +import org.eclipse.cdt.core.dom.ast.IASTCaseStatement; +import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; +import org.eclipse.cdt.core.dom.ast.IASTDoStatement; +import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTExpression; +import org.eclipse.cdt.core.dom.ast.IASTFileLocation; +import org.eclipse.cdt.core.dom.ast.IASTForStatement; +import org.eclipse.cdt.core.dom.ast.IASTWhileStatement; +import org.eclipse.cdt.core.dom.ast.IASTIfStatement; +import org.eclipse.cdt.core.dom.ast.IASTStatement; +import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement; + import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorElifStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorElseStatement; @@ -59,6 +74,7 @@ import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfndefStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSwitchStatement; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ICElement; @@ -645,6 +661,7 @@ private int fMinCommentLines= 1; private boolean fPreprocessorBranchFoldingEnabled= true; + private boolean fStatementsFoldingEnabled = false; private boolean fCommentFoldingEnabled= true; private ICReconcilingListener fReconilingListener; @@ -808,6 +825,7 @@ fCollapseComments= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_COMMENTS); fCollapseInactiveCode= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_INACTIVE_CODE); fPreprocessorBranchFoldingEnabled= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_PREPROCESSOR_BRANCHES_ENABLED); + fStatementsFoldingEnabled = store.getBoolean(PreferenceConstants.EDITOR_FOLDING_STATEMENTS); fCommentFoldingEnabled= true; } @@ -1079,6 +1097,13 @@ return false; } + class ModifiableRegionExtra extends ModifiableRegion { + /* A modifiable region with extra information about the + * region it holds. It tells us whether or not to include + * the last line of the region */ + public boolean inclusive; + } + /** * Compute folding structure of the preprocessor branches for the given AST. * @@ -1094,7 +1119,108 @@ return; } List branches= new ArrayList(); - Stack branchStack = new Stack(); + Stack branchStack = new Stack(); + final Stack iral = new Stack(); + + ast.accept(new ASTVisitor() { + { + shouldVisitStatements = true; + } + + public int visit(IASTStatement statement) { + try { + ModifiableRegionExtra mr; + IASTFileLocation fl; + if (statement instanceof IASTIfStatement) { + IASTIfStatement ifstmt = (IASTIfStatement) statement; + IASTStatement tmp; + mr = new ModifiableRegionExtra(); + tmp = ifstmt.getThenClause(); + if (tmp==null) return PROCESS_CONTINUE; + fl = tmp.getFileLocation(); + mr.setLength(fl.getNodeLength()); + mr.setOffset(fl.getNodeOffset()); + mr.inclusive = false; + //System.out.printf("If %d %d\n",fl.getNodeOffset(),fl.getNodeLength()); + tmp = ifstmt.getElseClause(); + if (tmp==null) { + mr.inclusive = true; + iral.push(mr); + return PROCESS_CONTINUE; + } + iral.push(mr); + mr = new ModifiableRegionExtra(); + fl = tmp.getFileLocation(); + //System.out.printf("ELse %d %d\n",fl.getNodeOffset(),fl.getNodeLength()); + mr.setLength(fl.getNodeLength()); + mr.setOffset(fl.getNodeOffset()); + mr.inclusive = true; + iral.push(mr); + } + mr = new ModifiableRegionExtra(); + mr.inclusive = true; + if (statement instanceof IASTDoStatement) + mr.inclusive = false; + //if (statement instanceof IASTSwitchStatement) { + /* The following code should visit any case statements within the + * switch statement, and add folding to each case statement. + * For some unknown reason, it fails to even visit a single child statement + * of the switch statement, the visit function in the anonymous class is never + * visited. + * I leave the code commented in case anyone wish to fix it. + statement.accept(new ASTVisitor() { + { + shouldVisitStatements = true; + } + boolean pushedMR = false; + //did we pushed a ModifiableRegion to iral stack? If we did we might need to update it + public int visit(IASTStatement stmt) { + ModifiableRegionExtra tmpmr; + if (!(stmt instanceof IASTCaseStatement)) { + if (!pushedMR) return PROCESS_SKIP; + tmpmr = iral.peek(); + tmpmr.setLength(tmpmr.getLength()+stmt.getFileLocation().getNodeLength()); + System.out.printf("%d is good\n", tmpmr.getLength()+stmt.getFileLocation().getNodeLength()); //$NON-NLS-1$ + if (stmt instanceof IASTBreakStatement) pushedMR = false; + return PROCESS_SKIP; + } + IASTCaseStatement casestmt = (IASTCaseStatement) stmt; + tmpmr = new ModifiableRegionExtra(); + IASTFileLocation tmpfl = casestmt.getExpression().getFileLocation(); + tmpmr.setOffset(tmpfl.getNodeOffset()); + tmpmr.setLength(tmpfl.getNodeLength()); + iral.push(tmpmr); + pushedMR = true; + + return PROCESS_SKIP; + } + });*/ + //} + if (statement instanceof IASTForStatement || + statement instanceof IASTWhileStatement || + statement instanceof IASTDoStatement || + statement instanceof IASTSwitchStatement) { + fl = statement.getFileLocation(); + mr.setLength(fl.getNodeLength()); + mr.setOffset(fl.getNodeOffset()); + iral.push(mr); + } + return PROCESS_CONTINUE; + } catch (Throwable e) { + CCorePlugin.log(e); + return PROCESS_CONTINUE; + } + } + }); + while (!iral.empty()) { + ModifiableRegionExtra mr = iral.pop(); + IRegion aligned = alignRegion(mr, ctx,mr.inclusive); + if (aligned != null) { + Position alignedPos= new Position(aligned.getOffset(), aligned.getLength()); + ctx.addProjectionRange(new CProjectionAnnotation(false, computeKey(mr, ctx), false), alignedPos); + } + } + IASTPreprocessorStatement[] preprocStmts = ast.getAllPreprocessorStatements(); Index: src/org/eclipse/cdt/internal/ui/text/folding/FoldingMessages.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.cdt/all/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/FoldingMessages.java,v retrieving revision 1.5 diff -u -r1.5 FoldingMessages.java --- src/org/eclipse/cdt/internal/ui/text/folding/FoldingMessages.java 13 Nov 2006 09:44:13 -0000 1.5 +++ src/org/eclipse/cdt/internal/ui/text/folding/FoldingMessages.java 19 Jan 2008 21:17:39 -0000 @@ -30,6 +30,7 @@ public static String DefaultCFoldingPreferenceBlock_inactive_code; public static String DefaultCFoldingPreferenceBlock_preprocessor_enabled; public static String EmptyCFoldingPreferenceBlock_emptyCaption; + public static String DefaultCFoldingPreferenceBlock_statements_enabled; static { NLS.initializeMessages(BUNDLE_NAME, FoldingMessages.class);