1
0
Fork 0
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:
Nathan Ridge 2016-12-21 01:02:47 -05:00
parent a5fb52baa3
commit 19ce7cc137
2 changed files with 70 additions and 10 deletions

View file

@ -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,8 +86,20 @@ 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);
@ -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();
}
}

View file

@ -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;
}