mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 14:42:11 +02:00
Bug 507138 - Avoid collisions between the keys of CProjectAnnotations used for statement folding
This is mostly to mitigate the effects of a bug in ProjectionViewer (bug 509559). See the discussion in bug 507138 for details. Change-Id: Icf36b54d6a11892f02214a168ef1c9c284478710
This commit is contained in:
parent
a5fb52baa3
commit
19ce7cc137
2 changed files with 70 additions and 10 deletions
|
@ -14,13 +14,15 @@ package org.eclipse.cdt.ui.tests.text;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.jface.preference.IPreferenceStore;
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
|
@ -33,17 +35,20 @@ import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
|
|||
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.core.testplugin.CProjectHelper;
|
||||
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
import org.eclipse.cdt.ui.PreferenceConstants;
|
||||
import org.eclipse.cdt.ui.testplugin.EditorTestHelper;
|
||||
import org.eclipse.cdt.ui.testplugin.ResourceTestHelper;
|
||||
import org.eclipse.cdt.ui.tests.BaseUITestCase;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.editor.CEditor;
|
||||
import org.eclipse.cdt.internal.ui.text.folding.DefaultCFoldingStructureProvider.CProjectionAnnotation;
|
||||
|
||||
/**
|
||||
* Code folding tests.
|
||||
*/
|
||||
public class FoldingTest extends TestCase {
|
||||
public class FoldingTest extends BaseUITestCase {
|
||||
|
||||
private static class ProjectionPosition extends Position implements IProjectionPosition, IRegion {
|
||||
private int fCaptionOffset;
|
||||
|
@ -67,9 +72,9 @@ public class FoldingTest extends TestCase {
|
|||
private ICProject fCProject;
|
||||
private final String fTestFilename= "/FoldingTest/src/FoldingTest.cpp";
|
||||
|
||||
private static CEditor fEditor;
|
||||
private CEditor fEditor;
|
||||
|
||||
private static SourceViewer fSourceViewer;
|
||||
private SourceViewer fSourceViewer;
|
||||
|
||||
public static Test suite() {
|
||||
return new TestSuite(FoldingTest.class);
|
||||
|
@ -81,9 +86,21 @@ public class FoldingTest extends TestCase {
|
|||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
|
||||
super.setUp();
|
||||
fCProject= EditorTestHelper.createCProject(PROJECT, LINKED_FOLDER);
|
||||
|
||||
StringBuilder[] contents = getContentsForTest(1);
|
||||
assert contents.length == 1;
|
||||
String code = contents[0].toString();
|
||||
String filename;
|
||||
if (code.trim().isEmpty()) {
|
||||
filename = fTestFilename;
|
||||
} else {
|
||||
TestSourceReader.createFile(fCProject.getProject(), new Path("FoldingTest.cpp"), code);
|
||||
filename = "/FoldingTest/FoldingTest.cpp";
|
||||
}
|
||||
|
||||
IPreferenceStore store= CUIPlugin.getDefault().getPreferenceStore();
|
||||
store.setValue(PreferenceConstants.EDITOR_FOLDING_ENABLED, true);
|
||||
store.setValue(PreferenceConstants.EDITOR_FOLDING_STATEMENTS, true);
|
||||
|
@ -91,7 +108,7 @@ public class FoldingTest extends TestCase {
|
|||
store.setValue(PreferenceConstants.EDITOR_FOLDING_INACTIVE_CODE, false);
|
||||
store.setValue(PreferenceConstants.EDITOR_FOLDING_HEADERS, false);
|
||||
|
||||
fEditor= (CEditor) EditorTestHelper.openInEditor(ResourceTestHelper.findFile(fTestFilename), true);
|
||||
fEditor= (CEditor) EditorTestHelper.openInEditor(ResourceTestHelper.findFile(filename), true);
|
||||
fSourceViewer= EditorTestHelper.getSourceViewer(fEditor);
|
||||
assertTrue(EditorTestHelper.joinReconciler(fSourceViewer, 0, 10000, 300));
|
||||
}
|
||||
|
@ -198,6 +215,7 @@ public class FoldingTest extends TestCase {
|
|||
return positions.toArray(new Position[positions.size()]);
|
||||
}
|
||||
|
||||
//
|
||||
public void testInitialFolding() throws BadLocationException {
|
||||
Position[] actual= getFoldingPositions();
|
||||
Position[] expected= new Position[] {
|
||||
|
@ -244,6 +262,7 @@ public class FoldingTest extends TestCase {
|
|||
assertEqualPositions(expected, actual);
|
||||
}
|
||||
|
||||
//
|
||||
public void testToggleFolding_Bug186729() throws BadLocationException {
|
||||
fEditor.getAction("FoldingToggle").run();
|
||||
IPreferenceStore store= CUIPlugin.getDefault().getPreferenceStore();
|
||||
|
@ -283,6 +302,7 @@ public class FoldingTest extends TestCase {
|
|||
assertEqualPositions(expected, actual);
|
||||
}
|
||||
|
||||
//
|
||||
public void testToggleFoldingNoASTRequired() throws BadLocationException {
|
||||
fEditor.getAction("FoldingToggle").run();
|
||||
IPreferenceStore store= CUIPlugin.getDefault().getPreferenceStore();
|
||||
|
@ -311,4 +331,44 @@ public class FoldingTest extends TestCase {
|
|||
assertEqualPositions(expected, actual);
|
||||
}
|
||||
|
||||
private void assertNoKeyCollisions() {
|
||||
ProjectionAnnotationModel model = (ProjectionAnnotationModel) fEditor.getAdapter(ProjectionAnnotationModel.class);
|
||||
assertNotNull(model);
|
||||
int annotations = 0;
|
||||
Set<Object> keys = new HashSet<>();
|
||||
for (Iterator<Annotation> iter= model.getAnnotationIterator(); iter.hasNext(); ) {
|
||||
Annotation ann= iter.next();
|
||||
if (ann instanceof CProjectionAnnotation) {
|
||||
++annotations;
|
||||
System.out.println("key is: " + ((CProjectionAnnotation) ann).getElement());
|
||||
keys.add(((CProjectionAnnotation) ann).getElement());
|
||||
System.out.println(" after adding key, set has size " + keys.size());
|
||||
}
|
||||
}
|
||||
assertEquals(annotations, keys.size());
|
||||
}
|
||||
|
||||
// int func(const char*);
|
||||
//
|
||||
// void foo() {
|
||||
// if (func("a looooooooooooooooooooooooooong string") == 1) {
|
||||
// }
|
||||
// if (func("a looooooooooooooooooooooooooong string") == 2) {
|
||||
// }
|
||||
// }
|
||||
public void testStatementsSharingFirst32Chars_507138() throws BadLocationException {
|
||||
assertNoKeyCollisions();
|
||||
}
|
||||
|
||||
// bool func();
|
||||
//
|
||||
// void foo() {
|
||||
// if (func()) {
|
||||
// }
|
||||
// if (func()) {
|
||||
// }
|
||||
// }
|
||||
public void testIdenticalStatements_507138() throws BadLocationException {
|
||||
assertNoKeyCollisions();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -514,7 +514,7 @@ public class DefaultCFoldingStructureProvider implements ICFoldingStructureProvi
|
|||
}
|
||||
|
||||
|
||||
private static class CProjectionAnnotation extends ProjectionAnnotation {
|
||||
public static class CProjectionAnnotation extends ProjectionAnnotation {
|
||||
|
||||
public final static int CMODEL= 0;
|
||||
public final static int COMMENT= 1;
|
||||
|
@ -1085,11 +1085,13 @@ public class DefaultCFoldingStructureProvider implements ICFoldingStructureProvi
|
|||
existingPosition.setOffset(newPosition.getOffset());
|
||||
existingPosition.setLength(newPosition.getLength());
|
||||
if (collapseChanged) {
|
||||
if (DEBUG) System.out.println("DefaultCFoldingStructureProvider.update() change annotation " + newAnnotation); //$NON-NLS-1$
|
||||
if (DEBUG) System.out.println("DefaultCFoldingStructureProvider.update() change annotation due to collapse state change " + newAnnotation); //$NON-NLS-1$
|
||||
if (newAnnotation.isCollapsed())
|
||||
existingAnnotation.markCollapsed();
|
||||
else
|
||||
existingAnnotation.markExpanded();
|
||||
} else {
|
||||
if (DEBUG) System.out.println("DefaultCFoldingStructureProvider.update() change annotation due to position change " + newAnnotation); //$NON-NLS-1$
|
||||
}
|
||||
updates.add(existingAnnotation);
|
||||
}
|
||||
|
@ -1278,7 +1280,6 @@ public class DefaultCFoldingStructureProvider implements ICFoldingStructureProvi
|
|||
return map;
|
||||
}
|
||||
|
||||
|
||||
private void computeFoldingStructure(final FoldingStructureComputationContext ctx) {
|
||||
if (fCommentFoldingEnabled) {
|
||||
// compute comment positions from partitioning
|
||||
|
@ -1491,8 +1492,7 @@ public class DefaultCFoldingStructureProvider implements ICFoldingStructureProvi
|
|||
private Object computeKey(Position pos, FoldingStructureComputationContext ctx) {
|
||||
try {
|
||||
final IDocument document= ctx.getDocument();
|
||||
IRegion line= document.getLineInformationOfOffset(pos.offset);
|
||||
return document.get(pos.offset, Math.min(32, line.getOffset() + line.getLength() - pos.offset));
|
||||
return document.getLineOfOffset(pos.offset);
|
||||
} catch (BadLocationException exc) {
|
||||
return exc;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue