1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 09:25:31 +02:00

Fix for 184189: CReconciler exception

This commit is contained in:
Anton Leherbauer 2007-04-27 09:05:30 +00:00
parent 5afe61ff79
commit 51d62cd4f5
3 changed files with 138 additions and 56 deletions

View file

@ -2128,12 +2128,15 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
// preprocessor directive is from a different file
continue;
}
IASTNodeLocation nodeLocation = statement.getFileLocation();
if (nodeLocation == null) {
continue;
}
if (statement instanceof IASTPreprocessorIfStatement) {
IASTPreprocessorIfStatement ifStmt = (IASTPreprocessorIfStatement)statement;
inactiveCodeStack.push(Boolean.valueOf(inInactiveCode));
if (!ifStmt.taken()) {
if (!inInactiveCode) {
IASTNodeLocation nodeLocation = ifStmt.getFileLocation();
inactiveCodeStart = nodeLocation.getNodeOffset() + nodeLocation.getNodeLength();
inInactiveCode = true;
}
@ -2143,7 +2146,6 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
inactiveCodeStack.push(Boolean.valueOf(inInactiveCode));
if (!ifdefStmt.taken()) {
if (!inInactiveCode) {
IASTNodeLocation nodeLocation = ifdefStmt.getFileLocation();
inactiveCodeStart = nodeLocation.getNodeOffset() + nodeLocation.getNodeLength();
inInactiveCode = true;
}
@ -2153,7 +2155,6 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
inactiveCodeStack.push(Boolean.valueOf(inInactiveCode));
if (!ifndefStmt.taken()) {
if (!inInactiveCode) {
IASTNodeLocation nodeLocation = ifndefStmt.getFileLocation();
inactiveCodeStart = nodeLocation.getNodeOffset() + nodeLocation.getNodeLength();
inInactiveCode = true;
}
@ -2161,11 +2162,9 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} else if (statement instanceof IASTPreprocessorElseStatement) {
IASTPreprocessorElseStatement elseStmt = (IASTPreprocessorElseStatement)statement;
if (!elseStmt.taken() && !inInactiveCode) {
IASTNodeLocation nodeLocation = elseStmt.getFileLocation();
inactiveCodeStart = nodeLocation.getNodeOffset() + nodeLocation.getNodeLength();
inInactiveCode = true;
} else if (elseStmt.taken() && inInactiveCode) {
IASTNodeLocation nodeLocation = elseStmt.getFileLocation();
int inactiveCodeEnd = nodeLocation.getNodeOffset();
positions.add(new Position(inactiveCodeStart, inactiveCodeEnd - inactiveCodeStart));
inInactiveCode = false;
@ -2173,21 +2172,17 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} else if (statement instanceof IASTPreprocessorElifStatement) {
IASTPreprocessorElifStatement elifStmt = (IASTPreprocessorElifStatement)statement;
if (!elifStmt.taken() && !inInactiveCode) {
IASTNodeLocation nodeLocation = elifStmt.getFileLocation();
inactiveCodeStart = nodeLocation.getNodeOffset() + nodeLocation.getNodeLength();
inInactiveCode = true;
} else if (elifStmt.taken() && inInactiveCode) {
IASTNodeLocation nodeLocation = elifStmt.getFileLocation();
int inactiveCodeEnd = nodeLocation.getNodeOffset();
positions.add(new Position(inactiveCodeStart, inactiveCodeEnd - inactiveCodeStart));
inInactiveCode = false;
}
} else if (statement instanceof IASTPreprocessorEndifStatement) {
IASTPreprocessorEndifStatement endifStmt = (IASTPreprocessorEndifStatement)statement;
try {
boolean wasInInactiveCode = ((Boolean)inactiveCodeStack.pop()).booleanValue();
if (inInactiveCode && !wasInInactiveCode) {
IASTNodeLocation nodeLocation = endifStmt.getFileLocation();
int inactiveCodeEnd = nodeLocation.getNodeOffset();
positions.add(new Position(inactiveCodeStart, inactiveCodeEnd - inactiveCodeStart));
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006 Wind River Systems, Inc. and others.
* Copyright (c) 2006, 2007 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -22,7 +22,10 @@ import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextInputListener;
import org.eclipse.jface.text.TypedPosition;
import org.eclipse.swt.widgets.Display;
@ -52,7 +55,7 @@ import org.eclipse.cdt.internal.ui.text.ICReconcilingListener;
* @see LineBackgroundPainter
* @since 4.0
*/
public class InactiveCodeHighlighting implements ICReconcilingListener {
public class InactiveCodeHighlighting implements ICReconcilingListener, ITextInputListener {
/**
* Implementation of <code>IRegion</code> that can be reused
@ -82,6 +85,7 @@ public class InactiveCodeHighlighting implements ICReconcilingListener {
private CEditor fEditor;
/** The list of currently highlighted positions */
private List fInactiveCodePositions= Collections.EMPTY_LIST;
private IDocument fDocument;
/**
* Create a highlighter for the given key.
@ -134,13 +138,15 @@ public class InactiveCodeHighlighting implements ICReconcilingListener {
assert editor != null && lineBackgroundPainter != null;
fEditor= editor;
fLineBackgroundPainter= lineBackgroundPainter;
fEditor.addReconcileListener(this);
ICElement cElement= fEditor.getInputCElement();
if (cElement instanceof ITranslationUnit) {
fTranslationUnit = (ITranslationUnit)cElement;
} else {
fTranslationUnit = null;
}
fDocument= fEditor.getDocumentProvider().getDocument(fEditor.getEditorInput());
fEditor.getViewer().addTextInputListener(this);
fEditor.addReconcileListener(this);
}
/**
@ -159,8 +165,12 @@ public class InactiveCodeHighlighting implements ICReconcilingListener {
}
if (fEditor != null) {
fEditor.removeReconcileListener(this);
if (fEditor.getViewer() != null) {
fEditor.getViewer().removeTextInputListener(this);
}
fEditor= null;
fTranslationUnit= null;
fDocument= null;
}
}
@ -232,13 +242,17 @@ public class InactiveCodeHighlighting implements ICReconcilingListener {
// preprocessor directive is from a different file
continue;
}
IASTNodeLocation[] nodeLocations = statement.getNodeLocations();
if (nodeLocations.length != 1) {
continue;
}
IASTNodeLocation stmtLocation= nodeLocations[0];
if (statement instanceof IASTPreprocessorIfStatement) {
IASTPreprocessorIfStatement ifStmt = (IASTPreprocessorIfStatement)statement;
inactiveCodeStack.push(Boolean.valueOf(inInactiveCode));
if (!ifStmt.taken()) {
if (!inInactiveCode) {
IASTNodeLocation nodeLocation = ifStmt.getNodeLocations()[0];
inactiveCodeStart = nodeLocation.getNodeOffset();
inactiveCodeStart = stmtLocation.getNodeOffset();
inInactiveCode = true;
}
}
@ -247,8 +261,7 @@ public class InactiveCodeHighlighting implements ICReconcilingListener {
inactiveCodeStack.push(Boolean.valueOf(inInactiveCode));
if (!ifdefStmt.taken()) {
if (!inInactiveCode) {
IASTNodeLocation nodeLocation = ifdefStmt.getNodeLocations()[0];
inactiveCodeStart = nodeLocation.getNodeOffset();
inactiveCodeStart = stmtLocation.getNodeOffset();
inInactiveCode = true;
}
}
@ -257,43 +270,36 @@ public class InactiveCodeHighlighting implements ICReconcilingListener {
inactiveCodeStack.push(Boolean.valueOf(inInactiveCode));
if (!ifndefStmt.taken()) {
if (!inInactiveCode) {
IASTNodeLocation nodeLocation = ifndefStmt.getNodeLocations()[0];
inactiveCodeStart = nodeLocation.getNodeOffset();
inactiveCodeStart = stmtLocation.getNodeOffset();
inInactiveCode = true;
}
}
} else if (statement instanceof IASTPreprocessorElseStatement) {
IASTPreprocessorElseStatement elseStmt = (IASTPreprocessorElseStatement)statement;
if (!elseStmt.taken() && !inInactiveCode) {
IASTNodeLocation nodeLocation = elseStmt.getNodeLocations()[0];
inactiveCodeStart = nodeLocation.getNodeOffset();
inactiveCodeStart = stmtLocation.getNodeOffset();
inInactiveCode = true;
} else if (elseStmt.taken() && inInactiveCode) {
IASTNodeLocation nodeLocation = elseStmt.getNodeLocations()[0];
int inactiveCodeEnd = nodeLocation.getNodeOffset();
positions.add(new HighlightPosition(inactiveCodeStart, inactiveCodeEnd - inactiveCodeStart, fHighlightKey));
int inactiveCodeEnd = stmtLocation.getNodeOffset();
positions.add(createHighlightPosition(inactiveCodeStart, inactiveCodeEnd, false, fHighlightKey));
inInactiveCode = false;
}
} else if (statement instanceof IASTPreprocessorElifStatement) {
IASTPreprocessorElifStatement elifStmt = (IASTPreprocessorElifStatement)statement;
if (!elifStmt.taken() && !inInactiveCode) {
IASTNodeLocation nodeLocation = elifStmt.getNodeLocations()[0];
inactiveCodeStart = nodeLocation.getNodeOffset();
inactiveCodeStart = stmtLocation.getNodeOffset();
inInactiveCode = true;
} else if (elifStmt.taken() && inInactiveCode) {
IASTNodeLocation nodeLocation = elifStmt.getNodeLocations()[0];
int inactiveCodeEnd = nodeLocation.getNodeOffset();
positions.add(new HighlightPosition(inactiveCodeStart, inactiveCodeEnd - inactiveCodeStart, fHighlightKey));
int inactiveCodeEnd = stmtLocation.getNodeOffset();
positions.add(createHighlightPosition(inactiveCodeStart, inactiveCodeEnd, false, fHighlightKey));
inInactiveCode = false;
}
} else if (statement instanceof IASTPreprocessorEndifStatement) {
IASTPreprocessorEndifStatement endifStmt = (IASTPreprocessorEndifStatement)statement;
try {
boolean wasInInactiveCode = ((Boolean)inactiveCodeStack.pop()).booleanValue();
if (inInactiveCode && !wasInInactiveCode) {
IASTNodeLocation nodeLocation = endifStmt.getNodeLocations()[0];
int inactiveCodeEnd = nodeLocation.getNodeOffset() + nodeLocation.getNodeLength();
positions.add(new HighlightPosition(inactiveCodeStart, inactiveCodeEnd - inactiveCodeStart, fHighlightKey));
int inactiveCodeEnd = stmtLocation.getNodeOffset() + stmtLocation.getNodeLength();
positions.add(createHighlightPosition(inactiveCodeStart, inactiveCodeEnd, true, fHighlightKey));
}
inInactiveCode = wasInInactiveCode;
}
@ -306,4 +312,52 @@ public class InactiveCodeHighlighting implements ICReconcilingListener {
return positions;
}
/**
* Create a highlight position aligned to start at a line offset. The region's start is
* decreased to the line offset, and the end offset decreased to the line start if
* <code>inclusive</code> is <code>false</code>.
*
* @param startOffset the start offset of the region to align
* @param endOffset the (exclusive) end offset of the region to align
* @param inclusive whether the last line should be included or not
* @param key the highlight key
* @return a position aligned for background highlighting
*/
private HighlightPosition createHighlightPosition(int startOffset, int endOffset, boolean inclusive, String key) {
final IDocument document= fDocument;
try {
if (document != null) {
int start= document.getLineOfOffset(startOffset);
int end= document.getLineOfOffset(endOffset);
startOffset= document.getLineOffset(start);
if (!inclusive) {
endOffset= document.getLineOffset(end);
}
}
return new HighlightPosition(startOffset, endOffset - startOffset, key);
} catch (BadLocationException x) {
// concurrent modification?
return null;
}
}
/*
* @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument)
*/
public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
}
/*
* @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument)
*/
public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
fDocument= newInput;
if (fEditor != null && fLineBackgroundPainter != null && !fLineBackgroundPainter.isDisposed()) {
List newInactiveCodePositions= Collections.EMPTY_LIST;
fLineBackgroundPainter.replaceHighlightPositions(fInactiveCodePositions, newInactiveCodePositions);
fInactiveCodePositions= newInactiveCodePositions;
}
}
}

View file

@ -651,6 +651,7 @@ public class DefaultCFoldingStructureProvider implements ICFoldingStructureProvi
private static class Branch extends ModifiableRegion {
private boolean fTaken;
public boolean fInclusive;
/**
* @param offset
@ -671,9 +672,6 @@ public class DefaultCFoldingStructureProvider implements ICFoldingStructureProvi
fTaken= taken;
}
/**
* @param endOffset
*/
public void setEndOffset(int endOffset) {
setLength(endOffset - getOffset());
}
@ -681,6 +679,10 @@ public class DefaultCFoldingStructureProvider implements ICFoldingStructureProvi
public boolean taken() {
return fTaken;
}
public void setInclusive(boolean inclusive) {
fInclusive= inclusive;
}
}
private final static boolean DEBUG= "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.cdt.ui/debug/folding")); //$NON-NLS-1$//$NON-NLS-2$;
@ -1162,9 +1164,12 @@ public class DefaultCFoldingStructureProvider implements ICFoldingStructureProvi
Branch branch= (Branch)branchStack.pop();
IASTPreprocessorElseStatement elseStmt = (IASTPreprocessorElseStatement)statement;
branchStack.push(new Branch(stmtLocation.getNodeOffset(), elseStmt.taken()));
branch.setEndOffset(stmtLocation.getNodeOffset() - 1);
IRegion converted= converter != null ? converter.historicToActual(branch) : branch;
branches.add(new Branch(converted.getOffset(), converted.getLength(), branch.taken()));
branch.setEndOffset(stmtLocation.getNodeOffset());
if (converter != null) {
IRegion converted= converter.historicToActual(branch);
branch= new Branch(converted.getOffset(), converted.getLength(), branch.taken());
}
branches.add(branch);
} else if (statement instanceof IASTPreprocessorElifStatement) {
if (branchStack.isEmpty()) {
// #elif without #if
@ -1173,9 +1178,12 @@ public class DefaultCFoldingStructureProvider implements ICFoldingStructureProvi
Branch branch= (Branch)branchStack.pop();
IASTPreprocessorElifStatement elifStmt = (IASTPreprocessorElifStatement) statement;
branchStack.push(new Branch(stmtLocation.getNodeOffset(), elifStmt.taken()));
branch.setEndOffset(stmtLocation.getNodeOffset() - 1);
IRegion converted= converter != null ? converter.historicToActual(branch) : branch;
branches.add(new Branch(converted.getOffset(), converted.getLength(), branch.taken()));
branch.setEndOffset(stmtLocation.getNodeOffset());
if (converter != null) {
IRegion converted= converter.historicToActual(branch);
branch= new Branch(converted.getOffset(), converted.getLength(), branch.taken());
}
branches.add(branch);
} else if (statement instanceof IASTPreprocessorEndifStatement) {
if (branchStack.isEmpty()) {
// #endif without #if
@ -1183,13 +1191,17 @@ public class DefaultCFoldingStructureProvider implements ICFoldingStructureProvi
}
Branch branch= (Branch)branchStack.pop();
branch.setEndOffset(stmtLocation.getNodeOffset() + stmtLocation.getNodeLength());
IRegion converted= converter != null ? converter.historicToActual(branch) : branch;
branches.add(new Branch(converted.getOffset(), converted.getLength(), branch.taken()));
if (converter != null) {
IRegion converted= converter.historicToActual(branch);
branch= new Branch(converted.getOffset(), converted.getLength(), branch.taken());
}
branch.setInclusive(true);
branches.add(branch);
}
}
for (Iterator iter = branches.iterator(); iter.hasNext(); ) {
Branch branch= (Branch) iter.next();
IRegion aligned = alignRegion(branch, ctx);
IRegion aligned = alignRegion(branch, ctx, branch.fInclusive);
if (aligned != null) {
Position alignedPos= new Position(aligned.getOffset(), aligned.getLength());
ctx.addProjectionRange(new CProjectionAnnotation(!branch.taken() && ctx.collapseInactiveCode(), computeKey(branch, ctx), false), alignedPos);
@ -1230,10 +1242,10 @@ public class DefaultCFoldingStructureProvider implements ICFoldingStructureProvi
ITypedRegion partition = partitions[i];
boolean singleLine= false;
if (ICPartitions.C_MULTI_LINE_COMMENT.equals(partition.getType())) {
Position position= createCommentPosition(alignRegion(partition, ctx));
Position position= createCommentPosition(alignRegion(partition, ctx, true));
if (position != null) {
if (startLine >= 0 && endLine - startLine >= fMinCommentLines) {
Position projection = createCommentPosition(alignRegion(commentRange, ctx));
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));
}
@ -1264,7 +1276,7 @@ public class DefaultCFoldingStructureProvider implements ICFoldingStructureProvi
}
if (startLine < 0 || lineNr - endLine > 1) {
if (startLine >= 0 && endLine - startLine >= fMinCommentLines) {
Position projection = createCommentPosition(alignRegion(commentRange, ctx));
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));
}
@ -1281,7 +1293,7 @@ public class DefaultCFoldingStructureProvider implements ICFoldingStructureProvi
}
}
if (startLine >= 0 && endLine - startLine >= fMinCommentLines) {
Position projection = createCommentPosition(alignRegion(commentRange, ctx));
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));
}
@ -1368,7 +1380,7 @@ public class DefaultCFoldingStructureProvider implements ICFoldingStructureProvi
IRegion[] regions= computeProjectionRanges((ISourceReference) element, ctx);
if (regions.length > 0) {
IRegion normalized= alignRegion(regions[regions.length - 1], ctx);
IRegion normalized= alignRegion(regions[regions.length - 1], ctx, true);
if (normalized != null) {
Position position= element instanceof IMember ? createMemberPosition(normalized, (IMember) element) : createCommentPosition(normalized);
if (position != null)
@ -1405,7 +1417,7 @@ public class DefaultCFoldingStructureProvider implements ICFoldingStructureProvi
/**
* Creates a comment folding position from an
* {@link #alignRegion(IRegion, DefaultCFoldingStructureProvider.FoldingStructureComputationContext) aligned}
* {@link #alignRegion(IRegion, DefaultCFoldingStructureProvider.FoldingStructureComputationContext, boolean) aligned}
* region.
*
* @param aligned an aligned region
@ -1420,7 +1432,7 @@ public class DefaultCFoldingStructureProvider implements ICFoldingStructureProvi
/**
* Creates a folding position that remembers its member from an
* {@link #alignRegion(IRegion, DefaultCFoldingStructureProvider.FoldingStructureComputationContext) aligned}
* {@link #alignRegion(IRegion, DefaultCFoldingStructureProvider.FoldingStructureComputationContext, boolean) aligned}
* region.
*
* @param aligned an aligned region
@ -1445,6 +1457,24 @@ public class DefaultCFoldingStructureProvider implements ICFoldingStructureProvi
* only one line)
*/
protected final IRegion alignRegion(IRegion region, FoldingStructureComputationContext ctx) {
return alignRegion(region, ctx, true);
}
/**
* Aligns <code>region</code> 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. <code>null</code> is returned if <code>region</code> is
* <code>null</code> 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 <code>null</code>
* @param ctx the folding context
* @param inclusive include line of end offset
* @return a region equal or greater than <code>region</code> that is aligned with line
* offsets, <code>null</code> 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) {
if (region == null)
return null;
@ -1459,11 +1489,14 @@ public class DefaultCFoldingStructureProvider implements ICFoldingStructureProvi
int offset= document.getLineOffset(start);
int endOffset;
if (document.getNumberOfLines() > end + 1)
endOffset= document.getLineOffset(end + 1);
else
endOffset= document.getLineOffset(end) + document.getLineLength(end);
if (inclusive) {
if (document.getNumberOfLines() > end + 1)
endOffset= document.getLineOffset(end + 1);
else
endOffset= document.getLineOffset(end) + document.getLineLength(end);
} else {
endOffset= document.getLineOffset(end);
}
return new Region(offset, endOffset - offset);
} catch (BadLocationException x) {