### 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.42 diff -u -r1.42 PreferenceConstants.java --- src/org/eclipse/cdt/ui/PreferenceConstants.java 16 Jan 2008 09:50:35 -0000 1.42 +++ src/org/eclipse/cdt/ui/PreferenceConstants.java 22 Jan 2008 04:52:07 -0000 @@ -792,7 +792,7 @@ * */ public static final String EDITOR_FOLDING_ENABLED= "editor_folding_enabled"; //$NON-NLS-1$ - + /** * A named preference that stores the configured folding provider. *

@@ -813,6 +813,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 22 Jan 2008 04:52:04 -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 22 Jan 2008 04:52:01 -0000 @@ -74,6 +74,7 @@ overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_HEADERS)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_INACTIVE_CODE)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_PREPROCESSOR_BRANCHES_ENABLED)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_STATEMENTS)); return (OverlayKey[]) overlayKeys.toArray(new OverlayKey[overlayKeys.size()]); } @@ -92,6 +93,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 +103,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.24 diff -u -r1.24 DefaultCFoldingStructureProvider.java --- src/org/eclipse/cdt/internal/ui/text/folding/DefaultCFoldingStructureProvider.java 18 Jan 2008 08:38:19 -0000 1.24 +++ src/org/eclipse/cdt/internal/ui/text/folding/DefaultCFoldingStructureProvider.java 22 Jan 2008 04:52:04 -0000 @@ -50,6 +50,22 @@ 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.IASTDefaultStatement; +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; @@ -86,17 +102,19 @@ * Derived from JDT counterpart. *

*/ -public class DefaultCFoldingStructureProvider implements ICFoldingStructureProvider { +public class DefaultCFoldingStructureProvider implements + ICFoldingStructureProvider { /** * Listen to cursor position changes. */ private final class SelectionListener implements ISelectionChangedListener { public void selectionChanged(SelectionChangedEvent event) { - ISelection s= event.getSelection(); + ISelection s = event.getSelection(); if (s instanceof ITextSelection) { - ITextSelection selection= (ITextSelection)event.getSelection(); - fCursorPosition= selection.getOffset(); + ITextSelection selection = (ITextSelection) event + .getSelection(); + fCursorPosition = selection.getOffset(); } } } @@ -104,45 +122,48 @@ /** * Reconcile annotation positions from preprocessor branches. */ - private class PreprocessorBranchesReconciler implements ICReconcilingListener { + private class PreprocessorBranchesReconciler implements + ICReconcilingListener { volatile boolean fReconciling; /* * @see org.eclipse.cdt.internal.ui.text.ICReconcilingListener#aboutToBeReconciled() */ public void aboutToBeReconciled() { - + } /* - * @see org.eclipse.cdt.internal.ui.text.ICReconcilingListener#reconciled(IASTTranslationUnit, boolean, IProgressMonitor) + * @see org.eclipse.cdt.internal.ui.text.ICReconcilingListener#reconciled(IASTTranslationUnit, + * boolean, IProgressMonitor) */ - public void reconciled(IASTTranslationUnit ast, boolean force, IProgressMonitor progressMonitor) { + public void reconciled(IASTTranslationUnit ast, boolean force, + IProgressMonitor progressMonitor) { if (fInput == null || fReconciling) { return; } if (fPreprocessorBranchFoldingEnabled && ast == null) { return; } - fReconciling= true; + fReconciling = true; try { - FoldingStructureComputationContext ctx= createContext(fInitialReconcilePending); - fInitialReconcilePending= false; + FoldingStructureComputationContext ctx = createContext(fInitialReconcilePending); + fInitialReconcilePending = false; if (ctx != null) { - ctx.fAST= ast; + ctx.fAST = ast; update(ctx); } } finally { - fReconciling= false; + fReconciling = false; } } } - /** - * A context that contains the information needed to compute the folding structure of an - * {@link ITranslationUnit}. Computed folding regions are collected via + * A context that contains the information needed to compute the folding + * structure of an {@link ITranslationUnit}. Computed folding regions are + * collected via * {@linkplain #addProjectionRange(DefaultCFoldingStructureProvider.CProjectionAnnotation, Position) addProjectionRange}. */ protected final class FoldingStructureComputationContext { @@ -152,27 +173,28 @@ private ISourceReference fFirstType; private boolean fHasHeaderComment; - private LinkedHashMap fMap= new LinkedHashMap(); + private LinkedHashMap fMap = new LinkedHashMap(); private IASTTranslationUnit fAST; - FoldingStructureComputationContext(IDocument document, ProjectionAnnotationModel model, boolean allowCollapsing) { + FoldingStructureComputationContext(IDocument document, + ProjectionAnnotationModel model, boolean allowCollapsing) { Assert.isNotNull(document); Assert.isNotNull(model); - fDocument= document; - fModel= model; - fAllowCollapsing= allowCollapsing; + fDocument = document; + fModel = model; + fAllowCollapsing = allowCollapsing; } - + void setFirstType(ISourceReference reference) { if (hasFirstType()) throw new IllegalStateException(); - fFirstType= reference; + fFirstType = reference; } - + boolean hasFirstType() { return fFirstType != null; } - + ISourceReference getFirstType() { return fFirstType; } @@ -182,17 +204,18 @@ } void setHasHeaderComment() { - fHasHeaderComment= true; + fHasHeaderComment = true; } - + /** - * Returns true if newly created folding regions may be collapsed, - * false if not. This is usually false when updating the - * folding structure while typing; it may be true when computing or restoring - * the initial folding structure. + * Returns true if newly created folding regions may be + * collapsed, false if not. This is usually + * false when updating the folding structure while + * typing; it may be true when computing or restoring the + * initial folding structure. * - * @return true if newly created folding regions may be collapsed, - * false if not + * @return true if newly created folding regions may be + * collapsed, false if not */ public boolean allowCollapsing() { return fAllowCollapsing; @@ -210,16 +233,20 @@ ProjectionAnnotationModel getModel() { return fModel; } - + /** - * Adds a projection (folding) region to this context. The created annotation / position - * pair will be added to the {@link ProjectionAnnotationModel} of the - * {@link ProjectionViewer} of the editor. + * Adds a projection (folding) region to this context. The created + * annotation / position pair will be added to the + * {@link ProjectionAnnotationModel} of the {@link ProjectionViewer} of + * the editor. * - * @param annotation the annotation to add - * @param position the corresponding position + * @param annotation + * the annotation to add + * @param position + * the corresponding position */ - public void addProjectionRange(CProjectionAnnotation annotation, Position position) { + public void addProjectionRange(CProjectionAnnotation annotation, + Position position) { fMap.put(annotation, position); } @@ -293,34 +320,35 @@ return fAST; } } - private static class CProjectionAnnotation extends ProjectionAnnotation { - public final static int COMMENT= 1; - public final static int BRANCH= 2; - + public final static int COMMENT = 1; + public final static int BRANCH = 2; + private Object fKey; private int fCategory; - - public CProjectionAnnotation(boolean isCollapsed, Object key, boolean isComment) { + + public CProjectionAnnotation(boolean isCollapsed, Object key, + boolean isComment) { this(isCollapsed, key, isComment ? COMMENT : 0); } - - public CProjectionAnnotation(boolean isCollapsed, Object key, int category) { + + public CProjectionAnnotation(boolean isCollapsed, Object key, + int category) { super(isCollapsed); - fKey= key; - fCategory= category; + fKey = key; + fCategory = category; } - + public Object getElement() { return fKey; } - + public void setElement(Object element) { - fKey= element; + fKey = element; } - + public int getCategory() { return fCategory; } @@ -332,38 +360,39 @@ public boolean isComment() { return fCategory == COMMENT; } - + public void setIsComment(boolean isComment) { - fCategory= isComment ? COMMENT : 0; + fCategory = isComment ? COMMENT : 0; } + /* * @see java.lang.Object#toString() */ public String toString() { return "CProjectionAnnotation:\n" + //$NON-NLS-1$ - "\tkey: \t"+ fKey + "\n" + //$NON-NLS-1$ //$NON-NLS-2$ + "\tkey: \t" + fKey + "\n" + //$NON-NLS-1$ //$NON-NLS-2$ "\tcollapsed: \t" + isCollapsed() + "\n" + //$NON-NLS-1$ //$NON-NLS-2$ "\tcomment: \t" + isComment() + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ } } - private static final class Tuple { CProjectionAnnotation annotation; Position position; + Tuple(CProjectionAnnotation annotation, Position position) { - this.annotation= annotation; - this.position= position; + this.annotation = annotation; + this.position = position; } } - /** - * Projection position that will return two foldable regions: one folding away - * the region from after the '/*' to the beginning of the content, the other - * from after the first content line until after the comment. + * Projection position that will return two foldable regions: one folding + * away the region from after the '/*' to the beginning of the content, the + * other from after the first content line until after the comment. */ - private static final class CommentPosition extends Position implements IProjectionPosition { + private static final class CommentPosition extends Position implements + IProjectionPosition { CommentPosition(int offset, int length) { super(offset, length); } @@ -371,31 +400,37 @@ /* * @see org.eclipse.jface.text.source.projection.IProjectionPosition#computeFoldingRegions(org.eclipse.jface.text.IDocument) */ - public IRegion[] computeProjectionRegions(IDocument document) throws BadLocationException { - DocumentCharacterIterator sequence= new DocumentCharacterIterator(document, offset, offset + length); - int prefixEnd= 0; - int contentStart= findFirstContent(sequence, prefixEnd); - - int firstLine= document.getLineOfOffset(offset + prefixEnd); - int captionLine= document.getLineOfOffset(offset + contentStart); - int lastLine= document.getLineOfOffset(offset + length); - - Assert.isTrue(firstLine <= captionLine, "first folded line is greater than the caption line"); //$NON-NLS-1$ - Assert.isTrue(captionLine <= lastLine, "caption line is greater than the last folded line"); //$NON-NLS-1$ + public IRegion[] computeProjectionRegions(IDocument document) + throws BadLocationException { + DocumentCharacterIterator sequence = new DocumentCharacterIterator( + document, offset, offset + length); + int prefixEnd = 0; + int contentStart = findFirstContent(sequence, prefixEnd); + + int firstLine = document.getLineOfOffset(offset + prefixEnd); + int captionLine = document.getLineOfOffset(offset + contentStart); + int lastLine = document.getLineOfOffset(offset + length); + + Assert.isTrue(firstLine <= captionLine, + "first folded line is greater than the caption line"); //$NON-NLS-1$ + Assert.isTrue(captionLine <= lastLine, + "caption line is greater than the last folded line"); //$NON-NLS-1$ IRegion preRegion; if (firstLine < captionLine) { - int preOffset= document.getLineOffset(firstLine); - IRegion preEndLineInfo= document.getLineInformation(captionLine); - int preEnd= preEndLineInfo.getOffset(); - preRegion= new Region(preOffset, preEnd - preOffset); + int preOffset = document.getLineOffset(firstLine); + IRegion preEndLineInfo = document + .getLineInformation(captionLine); + int preEnd = preEndLineInfo.getOffset(); + preRegion = new Region(preOffset, preEnd - preOffset); } else { - preRegion= null; + preRegion = null; } if (captionLine < lastLine) { - int postOffset= document.getLineOffset(captionLine + 1); - IRegion postRegion= new Region(postOffset, offset + length - postOffset); + int postOffset = document.getLineOffset(captionLine + 1); + IRegion postRegion = new Region(postOffset, offset + length + - postOffset); if (preRegion == null) return new IRegion[] { postRegion }; @@ -410,16 +445,17 @@ } /** - * Finds the offset of the first identifier part within content. - * Returns 0 if none is found. - * - * @param content the content to search - * @return the first index of a unicode identifier part, or zero if none can - * be found + * Finds the offset of the first identifier part within + * content. Returns 0 if none is found. + * + * @param content + * the content to search + * @return the first index of a unicode identifier part, or zero if none + * can be found */ private int findFirstContent(final CharSequence content, int prefixEnd) { - int lenght= content.length(); - for (int i= prefixEnd; i < lenght; i++) { + int lenght = content.length(); + for (int i = prefixEnd; i < lenght; i++) { if (Character.isUnicodeIdentifierPart(content.charAt(i))) return i; } @@ -430,77 +466,87 @@ * @see org.eclipse.jface.text.source.projection.IProjectionPosition#computeCaptionOffset(org.eclipse.jface.text.IDocument) */ public int computeCaptionOffset(IDocument document) { -// return 0; - DocumentCharacterIterator sequence= new DocumentCharacterIterator(document, offset, offset + length); + // return 0; + DocumentCharacterIterator sequence = new DocumentCharacterIterator( + document, offset, offset + length); return findFirstContent(sequence, 0); } } /** - * Projection position that will return two foldable regions: one folding away - * the lines before the one containing the simple name of the C element, one - * folding away any lines after the caption. + * Projection position that will return two foldable regions: one folding + * away the lines before the one containing the simple name of the C + * element, one folding away any lines after the caption. */ - private static final class CElementPosition extends Position implements IProjectionPosition { + private static final class CElementPosition extends Position implements + IProjectionPosition { private ICElement fElement; public CElementPosition(int offset, int length, ICElement element) { super(offset, length); Assert.isNotNull(element); - fElement= element; + fElement = element; } - + public void setElement(ICElement member) { Assert.isNotNull(member); - fElement= member; + fElement = member; } - + /* * @see org.eclipse.jface.text.source.projection.IProjectionPosition#computeFoldingRegions(org.eclipse.jface.text.IDocument) */ - public IRegion[] computeProjectionRegions(IDocument document) throws BadLocationException { - int nameStart= offset; + public IRegion[] computeProjectionRegions(IDocument document) + throws BadLocationException { + int nameStart = offset; try { - /* The member's name range may not be correct. However, + /* + * The member's name range may not be correct. However, * reconciling would trigger another element delta which would * lead to reentrant situations. Therefore, we optimistically * assume that the name range is correct, but double check the - * received lines below. */ + * received lines below. + */ if (fElement instanceof ISourceReference) { - ISourceRange sourceRange= ((ISourceReference) fElement).getSourceRange(); + ISourceRange sourceRange = ((ISourceReference) fElement) + .getSourceRange(); if (sourceRange != null) - nameStart= sourceRange.getIdStartPos(); + nameStart = sourceRange.getIdStartPos(); } } catch (CModelException e) { // ignore and use default } - int firstLine= document.getLineOfOffset(offset); - int captionLine= document.getLineOfOffset(nameStart); - int lastLine= document.getLineOfOffset(offset + length); + int firstLine = document.getLineOfOffset(offset); + int captionLine = document.getLineOfOffset(nameStart); + int lastLine = document.getLineOfOffset(offset + length); - /* see comment above - adjust the caption line to be inside the + /* + * see comment above - adjust the caption line to be inside the * entire folded region, and rely on later element deltas to correct - * the name range. */ + * the name range. + */ if (captionLine < firstLine) - captionLine= firstLine; + captionLine = firstLine; if (captionLine > lastLine) - captionLine= lastLine; + captionLine = lastLine; IRegion preRegion; if (firstLine < captionLine) { - int preOffset= document.getLineOffset(firstLine); - IRegion preEndLineInfo= document.getLineInformation(captionLine); - int preEnd= preEndLineInfo.getOffset(); - preRegion= new Region(preOffset, preEnd - preOffset); + int preOffset = document.getLineOffset(firstLine); + IRegion preEndLineInfo = document + .getLineInformation(captionLine); + int preEnd = preEndLineInfo.getOffset(); + preRegion = new Region(preOffset, preEnd - preOffset); } else { - preRegion= null; + preRegion = null; } if (captionLine < lastLine) { - int postOffset= document.getLineOffset(captionLine + 1); - IRegion postRegion= new Region(postOffset, offset + length - postOffset); + int postOffset = document.getLineOffset(captionLine + 1); + IRegion postRegion = new Region(postOffset, offset + length + - postOffset); if (preRegion == null) return new IRegion[] { postRegion }; @@ -517,14 +563,16 @@ /* * @see org.eclipse.jface.text.source.projection.IProjectionPosition#computeCaptionOffset(org.eclipse.jface.text.IDocument) */ - public int computeCaptionOffset(IDocument document) throws BadLocationException { - int nameStart= offset; + public int computeCaptionOffset(IDocument document) + throws BadLocationException { + int nameStart = offset; try { // need a reconcile here? if (fElement instanceof ISourceReference) { - ISourceRange sourceRange= ((ISourceReference) fElement).getSourceRange(); + ISourceRange sourceRange = ((ISourceReference) fElement) + .getSourceRange(); if (sourceRange != null) - nameStart= sourceRange.getIdStartPos(); + nameStart = sourceRange.getIdStartPos(); } } catch (CModelException e) { // ignore and use default @@ -534,7 +582,7 @@ } } - + /** * Internal projection listener. */ @@ -544,24 +592,26 @@ /** * Registers the listener with the viewer. * - * @param viewer the viewer to register a listener with + * @param viewer + * the viewer to register a listener with */ public ProjectionListener(ProjectionViewer viewer) { Assert.isLegal(viewer != null); - fViewer= viewer; + fViewer = viewer; fViewer.addProjectionListener(this); } - + /** - * Disposes of this listener and removes the projection listener from the viewer. + * Disposes of this listener and removes the projection listener from + * the viewer. */ public void dispose() { if (fViewer != null) { fViewer.removeProjectionListener(this); - fViewer= null; + fViewer = null; } } - + /* * @see org.eclipse.jface.text.source.projection.IProjectionListener#projectionEnabled() */ @@ -578,13 +628,14 @@ } /** - * Implementation of IRegion that can be reused - * by setting the offset and the length. + * Implementation of IRegion that can be reused by setting + * the offset and the length. */ private static class ModifiableRegion extends Position implements IRegion { ModifiableRegion() { super(); } + ModifiableRegion(int offset, int length) { super(offset, length); } @@ -604,7 +655,7 @@ */ Branch(int offset, boolean taken) { super(offset, 0); - fTaken= taken; + fTaken = taken; } /** @@ -614,7 +665,7 @@ */ Branch(int offset, int length, boolean taken) { super(offset, length); - fTaken= taken; + fTaken = taken; } public void setEndOffset(int endOffset) { @@ -626,60 +677,62 @@ } public void setInclusive(boolean inclusive) { - fInclusive= inclusive; + fInclusive = inclusive; } } - private final static boolean DEBUG= "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.cdt.ui/debug/folding")); //$NON-NLS-1$//$NON-NLS-2$; + private final static boolean DEBUG = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.cdt.ui/debug/folding")); //$NON-NLS-1$//$NON-NLS-2$; private ITextEditor fEditor; private ProjectionListener fProjectionListener; protected ICElement fInput; private IElementChangedListener fElementListener; - - private boolean fCollapseHeaderComments= true; - private boolean fCollapseComments= false; - private boolean fCollapseMacros= false; - private boolean fCollapseFunctions= true; - private boolean fCollapseStructures= true; - private boolean fCollapseMethods= false; - private boolean fCollapseInactiveCode= true; - - private int fMinCommentLines= 1; - private boolean fPreprocessorBranchFoldingEnabled= true; - private boolean fCommentFoldingEnabled= true; + + private boolean fCollapseHeaderComments = true; + private boolean fCollapseComments = false; + private boolean fCollapseMacros = false; + private boolean fCollapseFunctions = true; + private boolean fCollapseStructures = true; + private boolean fCollapseMethods = false; + private boolean fCollapseInactiveCode = true; + + private int fMinCommentLines = 1; + private boolean fPreprocessorBranchFoldingEnabled = true; + private boolean fStatementsFoldingEnabled = false; + private boolean fCommentFoldingEnabled = true; private ICReconcilingListener fReconilingListener; - boolean fInitialReconcilePending= true; + boolean fInitialReconcilePending = true; private int fCursorPosition; private SelectionListener fSelectionListener; - /** * Creates a new folding provider. It must be - * {@link #install(ITextEditor, ProjectionViewer) installed} on an editor/viewer pair before it - * can be used, and {@link #uninstall() uninstalled} when not used any longer. + * {@link #install(ITextEditor, ProjectionViewer) installed} on an + * editor/viewer pair before it can be used, and + * {@link #uninstall() uninstalled} when not used any longer. *

* The projection state may be reset by calling {@link #initialize()}. *

*/ public DefaultCFoldingStructureProvider() { } - + /* - * @see org.eclipse.cdt.ui.text.folding.ICFoldingStructureProvider#install(org.eclipse.ui.texteditor.ITextEditor, org.eclipse.jface.text.source.projection.ProjectionViewer) + * @see org.eclipse.cdt.ui.text.folding.ICFoldingStructureProvider#install(org.eclipse.ui.texteditor.ITextEditor, + * org.eclipse.jface.text.source.projection.ProjectionViewer) */ public void install(ITextEditor editor, ProjectionViewer viewer) { Assert.isLegal(editor != null); Assert.isLegal(viewer != null); internalUninstall(); - + if (editor instanceof CEditor) { - fEditor= editor; - fProjectionListener= new ProjectionListener(viewer); + fEditor = editor; + fProjectionListener = new ProjectionListener(viewer); } } @@ -689,7 +742,7 @@ public void uninstall() { internalUninstall(); } - + /** * Internal implementation of {@link #uninstall()}. */ @@ -697,69 +750,78 @@ if (isInstalled()) { handleProjectionDisabled(); fProjectionListener.dispose(); - fProjectionListener= null; - fEditor= null; + fProjectionListener = null; + fEditor = null; } } /** - * Returns true if the provider is installed, false otherwise. + * Returns true if the provider is installed, + * false otherwise. * - * @return true if the provider is installed, false otherwise + * @return true if the provider is installed, + * false otherwise */ protected final boolean isInstalled() { return fEditor != null; } - + /** - * Called whenever projection is enabled, for example when the viewer issues a - * {@link IProjectionListener#projectionEnabled() projectionEnabled} message. When the provider - * is already enabled when this method is called, it is first - * {@link #handleProjectionDisabled() disabled}. + * Called whenever projection is enabled, for example when the viewer issues + * a {@link IProjectionListener#projectionEnabled() projectionEnabled} + * message. When the provider is already enabled when this method is called, + * it is first {@link #handleProjectionDisabled() disabled}. *

* Subclasses may extend. *

*/ protected void handleProjectionEnabled() { - if (DEBUG) System.out.println("DefaultCFoldingStructureProvider.handleProjectionEnabled()"); //$NON-NLS-1$ - // projectionEnabled messages are not always paired with projectionDisabled + if (DEBUG) + System.out + .println("DefaultCFoldingStructureProvider.handleProjectionEnabled()"); //$NON-NLS-1$ + // projectionEnabled messages are not always paired with + // projectionDisabled // i.e. multiple enabled messages may be sent out. // we have to make sure that we disable first when getting an enable // message. handleProjectionDisabled(); if (fEditor instanceof CEditor) { - fInitialReconcilePending= true; + fInitialReconcilePending = true; initialize(); - fReconilingListener= new PreprocessorBranchesReconciler(); - ((CEditor)fEditor).addReconcileListener(fReconilingListener); - fSelectionListener= new SelectionListener(); - fEditor.getSelectionProvider().addSelectionChangedListener(fSelectionListener); + fReconilingListener = new PreprocessorBranchesReconciler(); + ((CEditor) fEditor).addReconcileListener(fReconilingListener); + fSelectionListener = new SelectionListener(); + fEditor.getSelectionProvider().addSelectionChangedListener( + fSelectionListener); } } /** * Called whenever projection is disabled, for example when the provider is * {@link #uninstall() uninstalled}, when the viewer issues a - * {@link IProjectionListener#projectionDisabled() projectionDisabled} message and before - * {@link #handleProjectionEnabled() enabling} the provider. Implementations must be prepared to - * handle multiple calls to this method even if the provider is already disabled. + * {@link IProjectionListener#projectionDisabled() projectionDisabled} + * message and before {@link #handleProjectionEnabled() enabling} the + * provider. Implementations must be prepared to handle multiple calls to + * this method even if the provider is already disabled. *

* Subclasses may extend. *

*/ protected void handleProjectionDisabled() { if (fElementListener != null) { - CoreModel.getDefault().removeElementChangedListener(fElementListener); - fElementListener= null; + CoreModel.getDefault().removeElementChangedListener( + fElementListener); + fElementListener = null; } if (fReconilingListener != null) { - ((CEditor)fEditor).removeReconcileListener(fReconilingListener); - fReconilingListener= null; + ((CEditor) fEditor).removeReconcileListener(fReconilingListener); + fReconilingListener = null; } if (fSelectionListener != null) { - fEditor.getSelectionProvider().removeSelectionChangedListener(fSelectionListener); - fSelectionListener= null; + fEditor.getSelectionProvider().removeSelectionChangedListener( + fSelectionListener); + fSelectionListener = null; } } @@ -767,107 +829,134 @@ * @see org.eclipse.cdt.ui.text.folding.ICFoldingStructureProvider#initialize() */ public final void initialize() { - if (DEBUG) System.out.println("DefaultCFoldingStructureProvider.initialize()"); //$NON-NLS-1$ + if (DEBUG) + System.out.println("DefaultCFoldingStructureProvider.initialize()"); //$NON-NLS-1$ update(createInitialContext()); } private FoldingStructureComputationContext createInitialContext() { initializePreferences(); - fInput= getInputElement(); + fInput = getInputElement(); if (fInput == null) return null; - + return createContext(true); } - private FoldingStructureComputationContext createContext(boolean allowCollapse) { + private FoldingStructureComputationContext createContext( + boolean allowCollapse) { if (!isInstalled()) return null; - ProjectionAnnotationModel model= getModel(); + ProjectionAnnotationModel model = getModel(); if (model == null) return null; - IDocument doc= getDocument(); + IDocument doc = getDocument(); if (doc == null) return null; - + return new FoldingStructureComputationContext(doc, model, allowCollapse); } - + private ICElement getInputElement() { if (fEditor instanceof CEditor) { - return ((CEditor)fEditor).getInputCElement(); + return ((CEditor) fEditor).getInputCElement(); } return null; } private void initializePreferences() { - IPreferenceStore store= CUIPlugin.getDefault().getPreferenceStore(); - fCollapseFunctions= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_FUNCTIONS); - fCollapseStructures= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_STRUCTURES); - fCollapseMacros= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_MACROS); - fCollapseMethods= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_METHODS); - fCollapseHeaderComments= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_HEADERS); - fCollapseComments= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_COMMENTS); - fCollapseInactiveCode= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_INACTIVE_CODE); - fPreprocessorBranchFoldingEnabled= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_PREPROCESSOR_BRANCHES_ENABLED); - fCommentFoldingEnabled= true; + IPreferenceStore store = CUIPlugin.getDefault().getPreferenceStore(); + fCollapseFunctions = store + .getBoolean(PreferenceConstants.EDITOR_FOLDING_FUNCTIONS); + fCollapseStructures = store + .getBoolean(PreferenceConstants.EDITOR_FOLDING_STRUCTURES); + fCollapseMacros = store + .getBoolean(PreferenceConstants.EDITOR_FOLDING_MACROS); + fCollapseMethods = store + .getBoolean(PreferenceConstants.EDITOR_FOLDING_METHODS); + fCollapseHeaderComments = store + .getBoolean(PreferenceConstants.EDITOR_FOLDING_HEADERS); + 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; } private void update(FoldingStructureComputationContext ctx) { - if (ctx == null) + if (ctx == null) return; if (!fInitialReconcilePending && fSelectionListener != null) { - fEditor.getSelectionProvider().removeSelectionChangedListener(fSelectionListener); - fSelectionListener= null; + fEditor.getSelectionProvider().removeSelectionChangedListener( + fSelectionListener); + fSelectionListener = null; } - Map additions= new HashMap(); - List deletions= new ArrayList(); - List updates= new ArrayList(); - + Map additions = new HashMap(); + List deletions = new ArrayList(); + List updates = new ArrayList(); + computeFoldingStructure(ctx); - Map updated= ctx.fMap; - Map previous= computeCurrentStructure(ctx); + Map updated = ctx.fMap; + Map previous = computeCurrentStructure(ctx); - Iterator e= updated.keySet().iterator(); + Iterator e = updated.keySet().iterator(); while (e.hasNext()) { - CProjectionAnnotation newAnnotation= (CProjectionAnnotation) e.next(); - Object key= newAnnotation.getElement(); - Position newPosition= (Position) updated.get(newAnnotation); + CProjectionAnnotation newAnnotation = (CProjectionAnnotation) e + .next(); + Object key = newAnnotation.getElement(); + Position newPosition = (Position) updated.get(newAnnotation); - List annotations= (List) previous.get(key); + List annotations = (List) previous.get(key); if (annotations == null) { - if (DEBUG) System.out.println("DefaultCFoldingStructureProvider.update() new annotation " + newAnnotation); //$NON-NLS-1$ + if (DEBUG) + System.out + .println("DefaultCFoldingStructureProvider.update() new annotation " + newAnnotation); //$NON-NLS-1$ additions.put(newAnnotation, newPosition); } else { - Iterator x= annotations.iterator(); - boolean matched= false; + Iterator x = annotations.iterator(); + boolean matched = false; while (x.hasNext()) { - Tuple tuple= (Tuple) x.next(); - CProjectionAnnotation existingAnnotation= tuple.annotation; - Position existingPosition= tuple.position; - if (newAnnotation.isComment() == existingAnnotation.isComment()) { - if (existingPosition != null && (!newPosition.equals(existingPosition) || ctx.allowCollapsing() && existingAnnotation.isCollapsed() != newAnnotation.isCollapsed())) { + Tuple tuple = (Tuple) x.next(); + CProjectionAnnotation existingAnnotation = tuple.annotation; + Position existingPosition = tuple.position; + if (newAnnotation.isComment() == existingAnnotation + .isComment()) { + if (existingPosition != null + && (!newPosition.equals(existingPosition) || ctx + .allowCollapsing() + && existingAnnotation.isCollapsed() != newAnnotation + .isCollapsed())) { existingPosition.setOffset(newPosition.getOffset()); existingPosition.setLength(newPosition.getLength()); - if (ctx.allowCollapsing() && existingAnnotation.isCollapsed() != newAnnotation.isCollapsed()) - if (DEBUG) System.out.println("DefaultCFoldingStructureProvider.update() change annotation " + newAnnotation); //$NON-NLS-1$ - if (newAnnotation.isCollapsed()) - existingAnnotation.markCollapsed(); - else - existingAnnotation.markExpanded(); + if (ctx.allowCollapsing() + && existingAnnotation.isCollapsed() != newAnnotation + .isCollapsed()) + if (DEBUG) + System.out + .println("DefaultCFoldingStructureProvider.update() change annotation " + newAnnotation); //$NON-NLS-1$ + if (newAnnotation.isCollapsed()) + existingAnnotation.markCollapsed(); + else + existingAnnotation.markExpanded(); updates.add(existingAnnotation); } - matched= true; + matched = true; x.remove(); break; } } if (!matched) { - if (DEBUG) System.out.println("DefaultCFoldingStructureProvider.update() new annotation " + newAnnotation); //$NON-NLS-1$ + if (DEBUG) + System.out + .println("DefaultCFoldingStructureProvider.update() new annotation " + newAnnotation); //$NON-NLS-1$ additions.put(newAnnotation, newPosition); } @@ -876,73 +965,84 @@ } } - e= previous.values().iterator(); + e = previous.values().iterator(); while (e.hasNext()) { - List list= (List) e.next(); - int size= list.size(); - for (int i= 0; i < size; i++) { - CProjectionAnnotation annotation= ((Tuple) list.get(i)).annotation; - if (DEBUG) System.out.println("DefaultCFoldingStructureProvider.update() deleted annotation " + annotation); //$NON-NLS-1$ + List list = (List) e.next(); + int size = list.size(); + for (int i = 0; i < size; i++) { + CProjectionAnnotation annotation = ((Tuple) list.get(i)).annotation; + if (DEBUG) + System.out + .println("DefaultCFoldingStructureProvider.update() deleted annotation " + annotation); //$NON-NLS-1$ deletions.add(annotation); } } match(deletions, additions, updates, ctx); - Annotation[] removals= new Annotation[deletions.size()]; + Annotation[] removals = new Annotation[deletions.size()]; deletions.toArray(removals); - Annotation[] changes= new Annotation[updates.size()]; + Annotation[] changes = new Annotation[updates.size()]; updates.toArray(changes); - if (DEBUG) System.out.println("DefaultCFoldingStructureProvider.update() "+removals.length+" deleted, "+additions.size()+" added, "+changes.length+" changed"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + if (DEBUG) + System.out + .println("DefaultCFoldingStructureProvider.update() " + removals.length + " deleted, " + additions.size() + " added, " + changes.length + " changed"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ ctx.getModel().modifyAnnotations(removals, additions, changes); - } + } /** * Matches deleted annotations to changed or added ones. A deleted - * annotation/position tuple that has a matching addition / change - * is updated and marked as changed. The matching tuple is not added - * (for additions) or marked as deletion instead (for changes). The - * result is that more annotations are changed and fewer get - * deleted/re-added. + * annotation/position tuple that has a matching addition / change is + * updated and marked as changed. The matching tuple is not added (for + * additions) or marked as deletion instead (for changes). The result is + * that more annotations are changed and fewer get deleted/re-added. */ - private void match(List deletions, Map additions, List changes, FoldingStructureComputationContext ctx) { + private void match(List deletions, Map additions, List changes, + FoldingStructureComputationContext ctx) { if (deletions.isEmpty() || (additions.isEmpty() && changes.isEmpty())) return; - List newDeletions= new ArrayList(); - List newChanges= new ArrayList(); + List newDeletions = new ArrayList(); + List newChanges = new ArrayList(); - Iterator deletionIterator= deletions.iterator(); + Iterator deletionIterator = deletions.iterator(); while (deletionIterator.hasNext()) { - CProjectionAnnotation deleted= (CProjectionAnnotation) deletionIterator.next(); - Position deletedPosition= ctx.getModel().getPosition(deleted); + CProjectionAnnotation deleted = (CProjectionAnnotation) deletionIterator + .next(); + Position deletedPosition = ctx.getModel().getPosition(deleted); if (deletedPosition == null) continue; - - Tuple deletedTuple= new Tuple(deleted, deletedPosition); - Tuple match= findMatch(deletedTuple, changes, null, ctx); - boolean addToDeletions= true; + Tuple deletedTuple = new Tuple(deleted, deletedPosition); + + Tuple match = findMatch(deletedTuple, changes, null, ctx); + boolean addToDeletions = true; if (match == null) { - match= findMatch(deletedTuple, additions.keySet(), additions, ctx); - addToDeletions= false; + match = findMatch(deletedTuple, additions.keySet(), additions, + ctx); + addToDeletions = false; } - + if (match != null) { - Object element= match.annotation.getElement(); + Object element = match.annotation.getElement(); deleted.setElement(element); deletedPosition.setLength(match.position.getLength()); - if (deletedPosition instanceof CElementPosition && element instanceof ICElement) { - CElementPosition cep= (CElementPosition) deletedPosition; + if (deletedPosition instanceof CElementPosition + && element instanceof ICElement) { + CElementPosition cep = (CElementPosition) deletedPosition; cep.setElement((ICElement) element); } deletionIterator.remove(); - if (DEBUG) System.out.println("DefaultCFoldingStructureProvider.update() changed annotation " + deleted); //$NON-NLS-1$ + if (DEBUG) + System.out + .println("DefaultCFoldingStructureProvider.update() changed annotation " + deleted); //$NON-NLS-1$ newChanges.add(deleted); if (addToDeletions) { - if (DEBUG) System.out.println("DefaultCFoldingStructureProvider.update() deleted annotation " + match.annotation); //$NON-NLS-1$ + if (DEBUG) + System.out + .println("DefaultCFoldingStructureProvider.update() deleted annotation " + match.annotation); //$NON-NLS-1$ newDeletions.add(match.annotation); } } @@ -953,34 +1053,39 @@ } /** - * Finds a match for tuple in a collection of - * annotations. The positions for the - * CProjectionAnnotation instances in + * Finds a match for tuple in a collection of annotations. + * The positions for the CProjectionAnnotation instances in * annotations can be found in the passed * positionMap or fCachedModel if * positionMap is null. *

- * A tuple is said to match another if their annotations have the - * same comment flag and their position offsets are equal. + * A tuple is said to match another if their annotations have the same + * comment flag and their position offsets are equal. *

*

* If a match is found, the annotation gets removed from * annotations. *

* - * @param tuple the tuple for which we want to find a match - * @param annotations collection of - * CProjectionAnnotation - * @param positionMap a Map<Annotation, Position> - * or null + * @param tuple + * the tuple for which we want to find a match + * @param annotations + * collection of CProjectionAnnotation + * @param positionMap + * a Map<Annotation, Position> or + * null * @return a matching tuple or null for no match */ - private Tuple findMatch(Tuple tuple, Collection annotations, Map positionMap, FoldingStructureComputationContext ctx) { - Iterator it= annotations.iterator(); + private Tuple findMatch(Tuple tuple, Collection annotations, + Map positionMap, FoldingStructureComputationContext ctx) { + Iterator it = annotations.iterator(); while (it.hasNext()) { - CProjectionAnnotation annotation= (CProjectionAnnotation) it.next(); + CProjectionAnnotation annotation = (CProjectionAnnotation) it + .next(); if (tuple.annotation.isComment() == annotation.isComment()) { - Position position= positionMap == null ? ctx.getModel().getPosition(annotation) : (Position) positionMap.get(annotation); + Position position = positionMap == null ? ctx.getModel() + .getPosition(annotation) : (Position) positionMap + .get(annotation); if (position == null) continue; @@ -990,71 +1095,80 @@ } } } - + return null; } private Map computeCurrentStructure(FoldingStructureComputationContext ctx) { - boolean includeBranches= fPreprocessorBranchFoldingEnabled && ctx.fAST != null; - Map map= new HashMap(); - ProjectionAnnotationModel model= ctx.getModel(); - Iterator e= model.getAnnotationIterator(); + boolean includeBranches = fPreprocessorBranchFoldingEnabled + && ctx.fAST != null; + Map map = new HashMap(); + ProjectionAnnotationModel model = ctx.getModel(); + Iterator e = model.getAnnotationIterator(); while (e.hasNext()) { - Object annotation= e.next(); + Object annotation = e.next(); if (annotation instanceof CProjectionAnnotation) { - CProjectionAnnotation cAnnotation= (CProjectionAnnotation) annotation; - if (!includeBranches && cAnnotation.getCategory() == CProjectionAnnotation.BRANCH) { + CProjectionAnnotation cAnnotation = (CProjectionAnnotation) annotation; + if (!includeBranches + && cAnnotation.getCategory() == CProjectionAnnotation.BRANCH) { continue; } - Position position= model.getPosition(cAnnotation); + Position position = model.getPosition(cAnnotation); Assert.isNotNull(position); - List list= (List) map.get(cAnnotation.getElement()); + List list = (List) map.get(cAnnotation.getElement()); if (list == null) { - list= new ArrayList(2); + list = new ArrayList(2); map.put(cAnnotation.getElement(), list); } list.add(new Tuple(cAnnotation, position)); } } - Comparator comparator= new Comparator() { + Comparator comparator = new Comparator() { public int compare(Object o1, Object o2) { - return ((Tuple) o1).position.getOffset() - ((Tuple) o2).position.getOffset(); + return ((Tuple) o1).position.getOffset() + - ((Tuple) o2).position.getOffset(); } }; - for (Iterator it= map.values().iterator(); it.hasNext();) { - List list= (List) it.next(); + for (Iterator it = map.values().iterator(); it.hasNext();) { + List list = (List) it.next(); Collections.sort(list, comparator); } return map; } - - private void computeFoldingStructure(final FoldingStructureComputationContext ctx) { + private void computeFoldingStructure( + final FoldingStructureComputationContext ctx) { if (fCommentFoldingEnabled) { // compute comment positions from partitioning try { - IDocument doc= ctx.getDocument(); - ITypedRegion[] partitions = TextUtilities.computePartitioning(doc, ICPartitions.C_PARTITIONING, 0, doc.getLength(), false); + IDocument doc = ctx.getDocument(); + ITypedRegion[] partitions = TextUtilities.computePartitioning( + doc, ICPartitions.C_PARTITIONING, 0, doc.getLength(), + false); computeFoldingStructure(partitions, ctx); } catch (BadLocationException e) { // ignore } } - if (fPreprocessorBranchFoldingEnabled) { - IASTTranslationUnit ast= ctx.getAST(); + if (fPreprocessorBranchFoldingEnabled || fStatementsFoldingEnabled) { + IASTTranslationUnit ast = ctx.getAST(); if (ast == null) { - final ASTProvider astProvider= CUIPlugin.getDefault().getASTProvider(); - IStatus status= astProvider.runOnAST(getInputElement(), ASTProvider.WAIT_ACTIVE_ONLY, null, new ASTCache.ASTRunnable() { - public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) { - if (ast != null) { - ctx.fAST= ast; - fInitialReconcilePending= false; - computeFoldingStructure(ast, ctx); - } - return Status.OK_STATUS; - } - }); + final ASTProvider astProvider = CUIPlugin.getDefault() + .getASTProvider(); + IStatus status = astProvider.runOnAST(getInputElement(), + ASTProvider.WAIT_ACTIVE_ONLY, null, + new ASTCache.ASTRunnable() { + public IStatus runOnAST(ILanguage lang, + IASTTranslationUnit ast) { + if (ast != null) { + ctx.fAST = ast; + fInitialReconcilePending = false; + computeFoldingStructure(ast, ctx); + } + return Status.OK_STATUS; + } + }); if (status.matches(IStatus.ERROR)) { CUIPlugin.getDefault().log(status); } @@ -1063,31 +1177,152 @@ } } if (!fInitialReconcilePending || isConsistent(fInput)) { - IParent parent= (IParent) fInput; + IParent parent = (IParent) fInput; try { computeFoldingStructure(parent.getChildren(), ctx); } catch (CModelException x) { } } } - + static boolean isConsistent(ICElement element) { if (element instanceof ITranslationUnit) { try { - return ((ITranslationUnit)element).isConsistent(); + return ((ITranslationUnit) element).isConsistent(); } catch (CModelException exc) { } } 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; + } + + /** + * Computes folding structure for preprocessor branches for the given AST. + * + * @param ast + * @param ctx + */ + private void computeStatementFoldingStructure(IASTTranslationUnit ast, FoldingStructureComputationContext ctx) { + final Stack iral = new Stack(); + ast.accept(new ASTVisitor() { + { + shouldVisitStatements = true; + } + + public int visit(IASTStatement statement) { + // if it's not part of the displayed - file, we don't need it + if (!statement.isPartOfTranslationUnitFile()) + return PROCESS_SKIP;// we neither need its descendants + 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; + tmp = ifstmt.getElseClause(); + if (tmp==null) { + mr.inclusive = true; + iral.push(mr); + return PROCESS_CONTINUE; + } + iral.push(mr); + mr = new ModifiableRegionExtra(); + fl = tmp.getFileLocation(); + 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) { + IASTStatement switchstmt = ((IASTSwitchStatement)statement).getBody(); + if (switchstmt instanceof IASTCompoundStatement) { + IASTStatement[] stmts = ((IASTCompoundStatement)switchstmt).getStatements(); + boolean pushedMR = false; + for (int i = 0; i < stmts.length; i++) { + IASTStatement tmpstmt = stmts[i]; + ModifiableRegionExtra tmpmr; + if (!(tmpstmt instanceof IASTCaseStatement || tmpstmt instanceof IASTDefaultStatement)) { + if (!pushedMR) return PROCESS_SKIP; + IASTFileLocation tmpfl = tmpstmt.getFileLocation(); + tmpmr = (ModifiableRegionExtra) iral.peek(); + tmpmr.setLength(tmpfl.getNodeLength()+tmpfl.getNodeOffset()-tmpmr.getOffset()); + if (tmpstmt instanceof IASTBreakStatement) pushedMR = false; + continue; + } + IASTFileLocation tmpfl; + tmpmr = new ModifiableRegionExtra(); + tmpmr.inclusive = true; + if (tmpstmt instanceof IASTCaseStatement) { + IASTCaseStatement casestmt = (IASTCaseStatement) tmpstmt; + tmpfl = casestmt.getExpression().getFileLocation(); + tmpmr.setOffset(tmpfl.getNodeOffset()); + tmpmr.setLength(tmpfl.getNodeLength()); + } else if (tmpstmt instanceof IASTDefaultStatement) { + IASTDefaultStatement defstmt = (IASTDefaultStatement) tmpstmt; + tmpfl = defstmt.getFileLocation(); + tmpmr.setOffset(tmpfl.getNodeOffset()+tmpfl.getNodeLength()); + tmpmr.setLength(0); + } + iral.push(tmpmr); + pushedMR = true; + } + } + } + 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 = (ModifiableRegionExtra) 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); + } + } + } + /** - * Compute folding structure of the preprocessor branches for the given AST. + * Compute folding structure of things related to the AST tree. Currently it + * computes the folding structure for: preprocessor branches for the given + * AST. Also, it computes statements folding (if/else do/while for and + * switch) * * @param ast * @param ctx */ - private void computeFoldingStructure(IASTTranslationUnit ast, FoldingStructureComputationContext ctx) { + private void computeFoldingStructure(IASTTranslationUnit ast, + FoldingStructureComputationContext ctx) { if (ast == null) { return; } @@ -1095,10 +1330,28 @@ if (fileName == null) { return; } - List branches= new ArrayList(); + + if (fStatementsFoldingEnabled) + computeStatementFoldingStructure(ast, ctx); + + if (fPreprocessorBranchFoldingEnabled) + computePreprocessorFoldingStructure(ast, ctx, fileName); + } + + /** + * Computes folding structure for preprocessor branches for the given AST. + * + * @param ast + * @param ctx + * @param fileName + */ + private void computePreprocessorFoldingStructure(IASTTranslationUnit ast, + FoldingStructureComputationContext ctx, String fileName) { + List branches = new ArrayList(); Stack branchStack = new Stack(); - IASTPreprocessorStatement[] preprocStmts = ast.getAllPreprocessorStatements(); + IASTPreprocessorStatement[] preprocStmts = ast + .getAllPreprocessorStatements(); for (int i = 0; i < preprocStmts.length; i++) { IASTPreprocessorStatement statement = preprocStmts[i]; @@ -1110,24 +1363,28 @@ if (nodeLocations.length != 1) { continue; } - IASTNodeLocation stmtLocation= nodeLocations[0]; + IASTNodeLocation stmtLocation = nodeLocations[0]; if (statement instanceof IASTPreprocessorIfStatement) { - IASTPreprocessorIfStatement ifStmt = (IASTPreprocessorIfStatement)statement; - branchStack.push(new Branch(stmtLocation.getNodeOffset(), ifStmt.taken())); + IASTPreprocessorIfStatement ifStmt = (IASTPreprocessorIfStatement) statement; + branchStack.push(new Branch(stmtLocation.getNodeOffset(), + ifStmt.taken())); } else if (statement instanceof IASTPreprocessorIfdefStatement) { - IASTPreprocessorIfdefStatement ifdefStmt = (IASTPreprocessorIfdefStatement)statement; - branchStack.push(new Branch(stmtLocation.getNodeOffset(), ifdefStmt.taken())); + IASTPreprocessorIfdefStatement ifdefStmt = (IASTPreprocessorIfdefStatement) statement; + branchStack.push(new Branch(stmtLocation.getNodeOffset(), + ifdefStmt.taken())); } else if (statement instanceof IASTPreprocessorIfndefStatement) { - IASTPreprocessorIfndefStatement ifndefStmt = (IASTPreprocessorIfndefStatement)statement; - branchStack.push(new Branch(stmtLocation.getNodeOffset(), ifndefStmt.taken())); + IASTPreprocessorIfndefStatement ifndefStmt = (IASTPreprocessorIfndefStatement) statement; + branchStack.push(new Branch(stmtLocation.getNodeOffset(), + ifndefStmt.taken())); } else if (statement instanceof IASTPreprocessorElseStatement) { if (branchStack.isEmpty()) { // #else without #if continue; } - Branch branch= (Branch)branchStack.pop(); - IASTPreprocessorElseStatement elseStmt = (IASTPreprocessorElseStatement)statement; - branchStack.push(new Branch(stmtLocation.getNodeOffset(), elseStmt.taken())); + Branch branch = (Branch) branchStack.pop(); + IASTPreprocessorElseStatement elseStmt = (IASTPreprocessorElseStatement) statement; + branchStack.push(new Branch(stmtLocation.getNodeOffset(), + elseStmt.taken())); branch.setEndOffset(stmtLocation.getNodeOffset()); branches.add(branch); } else if (statement instanceof IASTPreprocessorElifStatement) { @@ -1135,9 +1392,10 @@ // #elif without #if continue; } - Branch branch= (Branch)branchStack.pop(); + Branch branch = (Branch) branchStack.pop(); IASTPreprocessorElifStatement elifStmt = (IASTPreprocessorElifStatement) statement; - branchStack.push(new Branch(stmtLocation.getNodeOffset(), elifStmt.taken())); + branchStack.push(new Branch(stmtLocation.getNodeOffset(), + elifStmt.taken())); branch.setEndOffset(stmtLocation.getNodeOffset()); branches.add(branch); } else if (statement instanceof IASTPreprocessorEndifStatement) { @@ -1145,19 +1403,24 @@ // #endif without #if continue; } - Branch branch= (Branch)branchStack.pop(); - branch.setEndOffset(stmtLocation.getNodeOffset() + stmtLocation.getNodeLength()); + Branch branch = (Branch) branchStack.pop(); + branch.setEndOffset(stmtLocation.getNodeOffset() + + stmtLocation.getNodeLength()); branch.setInclusive(true); branches.add(branch); } } - for (Iterator iter = branches.iterator(); iter.hasNext(); ) { - Branch branch= (Branch) iter.next(); + for (Iterator iter = branches.iterator(); iter.hasNext();) { + Branch branch = (Branch) iter.next(); IRegion aligned = alignRegion(branch, ctx, branch.fInclusive); if (aligned != null) { - Position alignedPos= new Position(aligned.getOffset(), aligned.getLength()); - final boolean collapse= !branch.taken() && ctx.collapseInactiveCode() && !alignedPos.includes(fCursorPosition); - ctx.addProjectionRange(new CProjectionAnnotation(collapse, computeKey(branch, ctx), false), alignedPos); + Position alignedPos = new Position(aligned.getOffset(), aligned + .getLength()); + final boolean collapse = !branch.taken() + && ctx.collapseInactiveCode() + && !alignedPos.includes(fCursorPosition); + ctx.addProjectionRange(new CProjectionAnnotation(collapse, + computeKey(branch, ctx), false), alignedPos); } } } @@ -1169,7 +1432,8 @@ * @param ctx * @return a key to recognise an annotation position */ - private Object computeKey(Position pos, FoldingStructureComputationContext ctx) { + private Object computeKey(Position pos, + FoldingStructureComputationContext ctx) { try { return ctx.getDocument().get(pos.offset, Math.min(16, pos.length)); } catch (BadLocationException exc) { @@ -1180,36 +1444,49 @@ /** * Compute folding structure based on partioning information. * - * @param partitions array of document partitions - * @param ctx the folding structure context - * @throws BadLocationException + * @param partitions + * array of document partitions + * @param ctx + * the folding structure context + * @throws BadLocationException */ - private void computeFoldingStructure(ITypedRegion[] partitions, FoldingStructureComputationContext ctx) throws BadLocationException { + private void computeFoldingStructure(ITypedRegion[] partitions, + FoldingStructureComputationContext ctx) throws BadLocationException { boolean collapse = ctx.collapseComments(); - IDocument doc= ctx.getDocument(); + IDocument doc = ctx.getDocument(); int startLine = -1; int endLine = -1; - List comments= new ArrayList(); + List comments = new ArrayList(); ModifiableRegion commentRange = new ModifiableRegion(); for (int i = 0; i < partitions.length; i++) { ITypedRegion partition = partitions[i]; - boolean singleLine= false; + boolean singleLine = false; if (ICPartitions.C_MULTI_LINE_COMMENT.equals(partition.getType())) { - Position position= createCommentPosition(alignRegion(partition, ctx, true)); + Position position = createCommentPosition(alignRegion( + partition, ctx, true)); if (position != null) { - if (startLine >= 0 && endLine - startLine >= fMinCommentLines) { - Position projection = createCommentPosition(alignRegion(commentRange, ctx, true)); + if (startLine >= 0 + && endLine - startLine >= fMinCommentLines) { + Position projection = createCommentPosition(alignRegion( + commentRange, ctx, true)); if (projection != null) { - comments.add(new Tuple(new CProjectionAnnotation(collapse, doc.get(projection.offset, Math.min(16, projection.length)), true), projection)); + comments.add(new Tuple( + new CProjectionAnnotation(collapse, doc + .get(projection.offset, Math.min( + 16, projection.length)), + true), projection)); } - startLine= -1; + startLine = -1; } - comments.add(new Tuple(new CProjectionAnnotation(collapse, doc.get(position.offset, Math.min(16, position.length)), true), position)); + comments.add(new Tuple(new CProjectionAnnotation(collapse, + doc.get(position.offset, Math.min(16, + position.length)), true), position)); } else { - singleLine= true; + singleLine = true; } } else { - singleLine= ICPartitions.C_SINGLE_LINE_COMMENT.equals(partition.getType()); + singleLine = ICPartitions.C_SINGLE_LINE_COMMENT + .equals(partition.getType()); } if (singleLine) { // if comment starts at column 0 and spans only one line @@ -1217,21 +1494,30 @@ // to the commentRange int lineNr = doc.getLineOfOffset(partition.getOffset()); IRegion lineRegion = doc.getLineInformation(lineNr); - boolean isLineStart = partition.getOffset() == lineRegion.getOffset(); + boolean isLineStart = partition.getOffset() == lineRegion + .getOffset(); if (!isLineStart) { continue; } if (!singleLine) { - singleLine = lineRegion.getOffset() + lineRegion.getLength() >= partition.getOffset() + partition.getLength(); + singleLine = lineRegion.getOffset() + + lineRegion.getLength() >= partition.getOffset() + + partition.getLength(); if (!singleLine) { continue; } } if (startLine < 0 || lineNr - endLine > 1) { - if (startLine >= 0 && endLine - startLine >= fMinCommentLines) { - Position projection = createCommentPosition(alignRegion(commentRange, ctx, true)); + if (startLine >= 0 + && endLine - startLine >= fMinCommentLines) { + Position projection = createCommentPosition(alignRegion( + commentRange, ctx, true)); if (projection != null) { - comments.add(new Tuple(new CProjectionAnnotation(collapse, doc.get(projection.offset, Math.min(16, projection.length)), true), projection)); + comments.add(new Tuple( + new CProjectionAnnotation(collapse, doc + .get(projection.offset, Math.min( + 16, projection.length)), + true), projection)); } } startLine = lineNr; @@ -1240,19 +1526,24 @@ commentRange.length = lineRegion.getLength(); } else { endLine = lineNr; - int delta = lineRegion.getOffset() + lineRegion.getLength() - commentRange.offset - commentRange.length; + int delta = lineRegion.getOffset() + lineRegion.getLength() + - commentRange.offset - commentRange.length; commentRange.length += delta; } } } if (startLine >= 0 && endLine - startLine >= fMinCommentLines) { - Position projection = createCommentPosition(alignRegion(commentRange, ctx, true)); + Position projection = createCommentPosition(alignRegion( + commentRange, ctx, true)); if (projection != null) { - comments.add(new Tuple(new CProjectionAnnotation(collapse, doc.get(projection.offset, Math.min(16, projection.length)), true), projection)); + comments.add(new Tuple(new CProjectionAnnotation(collapse, + doc.get(projection.offset, Math.min(16, + projection.length)), true), projection)); } } if (!comments.isEmpty()) { - // first comment starting before line 10 is considered the header comment + // first comment starting before line 10 is considered the header + // comment Iterator iter = comments.iterator(); Tuple tuple = (Tuple) iter.next(); int lineNr = doc.getLineOfOffset(tuple.position.getOffset()); @@ -1271,27 +1562,28 @@ } } - private void computeFoldingStructure(ICElement[] elements, FoldingStructureComputationContext ctx) throws CModelException { - for (int i= 0; i < elements.length; i++) { - ICElement element= elements[i]; + private void computeFoldingStructure(ICElement[] elements, + FoldingStructureComputationContext ctx) throws CModelException { + for (int i = 0; i < elements.length; i++) { + ICElement element = elements[i]; computeFoldingStructure(element, ctx); if (element instanceof IParent) { - IParent parent= (IParent) element; + IParent parent = (IParent) element; computeFoldingStructure(parent.getChildren(), ctx); } } } /** - * Computes the folding structure for a given {@link ICElement C element}. Computed - * projection annotations are + * Computes the folding structure for a given {@link ICElement C element}. + * Computed projection annotations are * {@link DefaultCFoldingStructureProvider.FoldingStructureComputationContext#addProjectionRange(DefaultCFoldingStructureProvider.CProjectionAnnotation, Position) added} * to the computation context. *

- * Subclasses may extend or replace. The default implementation creates projection annotations - * for the following elements: + * Subclasses may extend or replace. The default implementation creates + * projection annotations for the following elements: *

*

* - * @param element the C element to compute the folding structure for - * @param ctx the computation context + * @param element + * the C element to compute the folding structure for + * @param ctx + * the computation context */ - protected void computeFoldingStructure(ICElement element, FoldingStructureComputationContext ctx) { + protected void computeFoldingStructure(ICElement element, + FoldingStructureComputationContext ctx) { - boolean collapse= false; + boolean collapse = false; switch (element.getElementType()) { case ICElement.C_STRUCT: @@ -1314,56 +1609,61 @@ case ICElement.C_TEMPLATE_STRUCT: case ICElement.C_TEMPLATE_CLASS: case ICElement.C_TEMPLATE_UNION: - collapse= ctx.collapseStructures(); + collapse = ctx.collapseStructures(); break; case ICElement.C_MACRO: - collapse= ctx.collapseMacros(); + collapse = ctx.collapseMacros(); break; case ICElement.C_FUNCTION: case ICElement.C_TEMPLATE_FUNCTION: - collapse= ctx.collapseFunctions(); + collapse = ctx.collapseFunctions(); break; case ICElement.C_METHOD: case ICElement.C_TEMPLATE_METHOD: - collapse= ctx.collapseMethods(); + collapse = ctx.collapseMethods(); break; default: return; } - IRegion[] regions= computeProjectionRanges((ISourceReference) element, ctx); + IRegion[] regions = computeProjectionRanges((ISourceReference) element, + ctx); if (regions.length > 0) { - IRegion normalized= alignRegion(regions[regions.length - 1], ctx, true); + IRegion normalized = alignRegion(regions[regions.length - 1], ctx, + true); if (normalized != null) { - Position position= createElementPosition(normalized, element); + Position position = createElementPosition(normalized, element); if (position != null) { - collapse= collapse && !position.includes(fCursorPosition); - ctx.addProjectionRange(new CProjectionAnnotation(collapse, element, false), position); + collapse = collapse && !position.includes(fCursorPosition); + ctx.addProjectionRange(new CProjectionAnnotation(collapse, + element, false), position); } } } } /** - * Computes the projection ranges for a given ISourceReference. More than one - * range or none at all may be returned. If there are no foldable regions, an empty array is - * returned. + * Computes the projection ranges for a given ISourceReference. + * More than one range or none at all may be returned. If there are no + * foldable regions, an empty array is returned. *

- * The last region in the returned array (if not empty) describes the region for the C - * element that implements the source reference. Any preceding regions describe comments - * of that element. + * The last region in the returned array (if not empty) describes the region + * for the C element that implements the source reference. Any preceding + * regions describe comments of that element. *

* - * @param reference a C element that is a source reference - * @param ctx the folding context + * @param reference + * a C element that is a source reference + * @param ctx + * the folding context * @return the regions to be folded */ - protected final IRegion[] computeProjectionRanges(ISourceReference reference, FoldingStructureComputationContext ctx) { + protected final IRegion[] computeProjectionRanges( + ISourceReference reference, FoldingStructureComputationContext ctx) { try { - ISourceRange range= reference.getSourceRange(); - return new IRegion[] { - new Region(range.getStartPos(), range.getLength()) - }; + ISourceRange range = reference.getSourceRange(); + return new IRegion[] { new Region(range.getStartPos(), range + .getLength()) }; } catch (CModelException e) { } @@ -1375,7 +1675,8 @@ * {@link #alignRegion(IRegion, DefaultCFoldingStructureProvider.FoldingStructureComputationContext, boolean) aligned} * region. * - * @param aligned an aligned region + * @param aligned + * an aligned region * @return a folding position corresponding to aligned */ protected final Position createCommentPosition(IRegion aligned) { @@ -1390,82 +1691,98 @@ * {@link #alignRegion(IRegion, DefaultCFoldingStructureProvider.FoldingStructureComputationContext, boolean) aligned} * region. * - * @param aligned an aligned region - * @param element the element to remember + * @param aligned + * an aligned region + * @param element + * the element to remember * @return a folding position corresponding to aligned */ - protected final Position createElementPosition(IRegion aligned, ICElement element) { - return new CElementPosition(aligned.getOffset(), aligned.getLength(), element); + protected final Position createElementPosition(IRegion aligned, + ICElement element) { + return new CElementPosition(aligned.getOffset(), aligned.getLength(), + element); } /** - * Aligns region to start and end at a line offset. The region's start is - * decreased to the next line offset, and the end offset increased to the next line start or the - * end of the document. null is returned if region is - * null itself or does not comprise at least one line delimiter, as a single line - * cannot be folded. + * Aligns region to start and end at a line offset. The + * region's start is decreased to the next line offset, and the end offset + * increased to the next line start or the end of the document. + * null is returned if region is + * null itself or does not comprise at least one line + * delimiter, as a single line cannot be folded. * - * @param region the region to align, may be null - * @param ctx the folding context - * @return a region equal or greater than region that is aligned with line - * offsets, null if the region is too small to be foldable (e.g. covers - * only one line) + * @param region + * the region to align, may be null + * @param ctx + * the folding context + * @return a region equal or greater than region that is + * aligned with line offsets, null if the region is + * too small to be foldable (e.g. covers only one line) */ - protected final IRegion alignRegion(IRegion region, FoldingStructureComputationContext ctx) { + protected final IRegion alignRegion(IRegion region, + FoldingStructureComputationContext ctx) { return alignRegion(region, ctx, true); } /** - * Aligns region to start and end at a line offset. The region's start is - * decreased to the next line offset, and the end offset increased to the next line start or the - * end of the document. null is returned if region is - * null itself or does not comprise at least one line delimiter, as a single line - * cannot be folded. + * Aligns region to start and end at a line offset. The + * region's start is decreased to the next line offset, and the end offset + * increased to the next line start or the end of the document. + * null is returned if region is + * null itself or does not comprise at least one line + * delimiter, as a single line cannot be folded. * - * @param region the region to align, may be null - * @param ctx the folding context - * @param inclusive include line of end offset - * @return a region equal or greater than region that is aligned with line - * offsets, null if the region is too small to be foldable (e.g. covers - * only one line) + * @param region + * the region to align, may be null + * @param ctx + * the folding context + * @param inclusive + * include line of end offset + * @return a region equal or greater than region that is + * aligned with line offsets, null if the region is + * too small to be foldable (e.g. covers only one line) */ - protected final IRegion alignRegion(IRegion region, FoldingStructureComputationContext ctx, boolean inclusive) { + protected final IRegion alignRegion(IRegion region, + FoldingStructureComputationContext ctx, boolean inclusive) { if (region == null) return null; - - IDocument document= ctx.getDocument(); - + + IDocument document = ctx.getDocument(); + try { - - int start= document.getLineOfOffset(region.getOffset()); - int end= document.getLineOfOffset(region.getOffset() + region.getLength()); + + int start = document.getLineOfOffset(region.getOffset()); + int end = document.getLineOfOffset(region.getOffset() + + region.getLength()); if (start >= end) return null; - - int offset= document.getLineOffset(start); + + int offset = document.getLineOffset(start); int endOffset; if (inclusive) { if (document.getNumberOfLines() > end + 1) - endOffset= document.getLineOffset(end + 1); + endOffset = document.getLineOffset(end + 1); else - endOffset= document.getLineOffset(end) + document.getLineLength(end); + endOffset = document.getLineOffset(end) + + document.getLineLength(end); } else { - endOffset= document.getLineOffset(end); + endOffset = document.getLineOffset(end); } return new Region(offset, endOffset - offset); - + } catch (BadLocationException x) { // concurrent modification return null; } } - + private ProjectionAnnotationModel getModel() { - return (ProjectionAnnotationModel) fEditor.getAdapter(ProjectionAnnotationModel.class); + return (ProjectionAnnotationModel) fEditor + .getAdapter(ProjectionAnnotationModel.class); } private IDocument getDocument() { - IDocumentProvider provider= fEditor.getDocumentProvider(); + IDocumentProvider provider = fEditor.getDocumentProvider(); return provider.getDocument(fEditor.getEditorInput()); } 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 22 Jan 2008 04:52:04 -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);