Skip to content

Commit 74a0810

Browse files
committed
WIP
Fixes #3685
1 parent 4ba0593 commit 74a0810

File tree

4 files changed

+81
-72
lines changed

4 files changed

+81
-72
lines changed

bundles/org.eclipse.core.filebuffers/META-INF/MANIFEST.MF

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ Export-Package:
1010
org.eclipse.core.filebuffers.manipulation,
1111
org.eclipse.core.internal.filebuffers;x-internal:=true
1212
Require-Bundle:
13-
org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)",
14-
org.eclipse.core.resources;bundle-version="[3.5.0,4.0.0)";resolution:=optional,
15-
org.eclipse.text;bundle-version="[3.5.0,4.0.0)",
16-
org.eclipse.core.filesystem;bundle-version="[1.2.0,2.0.0)"
13+
org.eclipse.core.runtime;bundle-version="[3.34.0,4.0.0)",
14+
org.eclipse.core.resources;bundle-version="[3.23.0,4.0.0)";resolution:=optional,
15+
org.eclipse.text;bundle-version="[3.15.0,4.0.0)",
16+
org.eclipse.core.filesystem;bundle-version="[1.11.0,2.0.0)"
1717
Bundle-RequiredExecutionEnvironment: JavaSE-17
1818
Automatic-Module-Name: org.eclipse.core.filebuffers

bundles/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/SynchronizableDocument.java

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -250,38 +250,29 @@ public long getModificationStamp() {
250250

251251
@Override
252252
public void replace(int offset, int length, String text) throws BadLocationException {
253-
Object lockObject= getLockObject();
254-
if (lockObject == null) {
255-
super.replace(offset, length, text);
256-
return;
257-
}
258-
synchronized (lockObject) {
259-
super.replace(offset, length, text);
260-
}
253+
super.replace(offset, length, text);
261254
}
262255

263256
@Override
264-
public void replace(int offset, int length, String text, long modificationStamp) throws BadLocationException {
257+
public final void replace(int offset, int length, String text, long modificationStamp) throws BadLocationException {
265258
Object lockObject= getLockObject();
266259
if (lockObject == null) {
267260
super.replace(offset, length, text, modificationStamp);
268261
return;
269262
}
270-
synchronized (lockObject) {
271-
super.replace(offset, length, text, modificationStamp);
263+
try {
264+
stopListenerNotification();
265+
synchronized (lockObject) {
266+
super.replace(offset, length, text, modificationStamp);
267+
}
268+
} finally {
269+
resumeListenerNotification();
272270
}
273271
}
274272

275273
@Override
276274
public void set(String text) {
277-
Object lockObject= getLockObject();
278-
if (lockObject == null) {
279-
super.set(text);
280-
return;
281-
}
282-
synchronized (lockObject) {
283-
super.set(text);
284-
}
275+
super.set(text);
285276
}
286277

287278
@Override
@@ -291,11 +282,22 @@ public void set(String text, long modificationStamp) {
291282
super.set(text, modificationStamp);
292283
return;
293284
}
294-
synchronized (lockObject) {
295-
super.set(text, modificationStamp);
285+
try {
286+
stopListenerNotification();
287+
synchronized (lockObject) {
288+
super.set(text, modificationStamp);
289+
}
290+
} finally {
291+
resumeListenerNotification();
296292
}
297293
}
298294

295+
@Override
296+
protected void doFireDocumentChanged2(DocumentEvent event) {
297+
// TODO this code could use a job to dispatch updates to listeners asynchronously
298+
super.doFireDocumentChanged2(event);
299+
}
300+
299301
@Override
300302
public void addPosition(String category, Position position) throws BadLocationException, BadPositionCategoryException {
301303
Object lockObject= getLockObject();

bundles/org.eclipse.text/META-INF/MANIFEST.MF

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
22
Bundle-ManifestVersion: 2
33
Bundle-Name: %pluginName
44
Bundle-SymbolicName: org.eclipse.text
5-
Bundle-Version: 3.14.600.qualifier
5+
Bundle-Version: 3.15.0.qualifier
66
Bundle-Vendor: %providerName
77
Bundle-Localization: plugin
88
Export-Package:

bundles/org.eclipse.text/src/org/eclipse/jface/text/AbstractDocument.java

Lines changed: 53 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
import java.util.Map;
2424
import java.util.Map.Entry;
2525
import java.util.concurrent.CopyOnWriteArrayList;
26+
import java.util.concurrent.atomic.AtomicInteger;
27+
import java.util.concurrent.atomic.AtomicLong;
28+
import java.util.concurrent.atomic.AtomicReference;
2629
import java.util.regex.PatternSyntaxException;
2730

2831
import org.eclipse.core.runtime.Assert;
@@ -115,17 +118,17 @@ static private class RegisteredReplace {
115118
* The list of post notification changes
116119
* @since 2.0
117120
*/
118-
private List<RegisteredReplace> fPostNotificationChanges;
121+
private volatile List<RegisteredReplace> fPostNotificationChanges;
119122
/**
120123
* The reentrance count for post notification changes.
121124
* @since 2.0
122125
*/
123-
private int fReentranceCount= 0;
126+
private volatile int fReentranceCount;
124127
/**
125128
* Indicates whether post notification change processing has been stopped.
126129
* @since 2.0
127130
*/
128-
private int fStoppedCount= 0;
131+
private volatile int fStoppedCount;
129132
/**
130133
* Indicates whether the registration of post notification changes should be ignored.
131134
* @since 2.1
@@ -135,22 +138,22 @@ static private class RegisteredReplace {
135138
* Indicates whether the notification of listeners has been stopped.
136139
* @since 2.1
137140
*/
138-
private int fStoppedListenerNotification= 0;
141+
private final AtomicInteger fStoppedListenerNotification;
139142
/**
140-
* The document event to be sent after listener notification has been resumed.
141-
* @since 2.1
143+
* The document event list to be sent after listener notification has been resumed.
144+
* @since 3.15
142145
*/
143-
private DocumentEvent fDeferredDocumentEvent;
146+
private final List<DocumentEvent> fDeferredDocumentEvents;
144147
/**
145148
* The registered document partitioners.
146149
* @since 3.0
147150
*/
148151
private Map<String, IDocumentPartitioner> fDocumentPartitioners;
149152
/**
150153
* The partitioning changed event.
151-
* @since 3.0
154+
* @since 3.15.0
152155
*/
153-
private DocumentPartitioningChangedEvent fDocumentPartitioningChangedEvent;
156+
private final AtomicReference<DocumentPartitioningChangedEvent> fDocumentPartitioningChangedEvent;
154157
/**
155158
* The find/replace document adapter.
156159
* @since 3.0
@@ -175,7 +178,7 @@ static private class RegisteredReplace {
175178
* Keeps track of next modification stamp.
176179
* @since 3.1.1
177180
*/
178-
private long fNextModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
181+
private final AtomicLong fNextModificationStamp= new AtomicLong(IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP);
179182
/**
180183
* This document's default line delimiter.
181184
* @since 3.1
@@ -191,6 +194,9 @@ static private class RegisteredReplace {
191194
*/
192195
protected AbstractDocument() {
193196
fModificationStamp= getNextModificationStamp();
197+
fStoppedListenerNotification = new AtomicInteger();
198+
fDeferredDocumentEvents = new CopyOnWriteArrayList<>();
199+
fDocumentPartitioningChangedEvent = new AtomicReference<>();
194200
}
195201

196202

@@ -437,7 +443,7 @@ public boolean containsPositionCategory(String category) {
437443
* @see IDocument#computeIndexInCategory(String, int)
438444
* @deprecated As of 3.4, replaced by {@link #computeIndexInPositionList(List, int, boolean)}
439445
*/
440-
@Deprecated
446+
@Deprecated(forRemoval = true, since= "3.15.0")
441447
protected int computeIndexInPositionList(List<? extends Position> positions, int offset) {
442448
return computeIndexInPositionList(positions, offset, true);
443449
}
@@ -542,7 +548,7 @@ public int computeIndexInCategory(String category, int offset) throws BadLocatio
542548
*
543549
* @deprecated as of 2.0. Use <code>fireDocumentPartitioningChanged(IRegion)</code> instead.
544550
*/
545-
@Deprecated
551+
@Deprecated(forRemoval = true, since= "3.15.0")
546552
protected void fireDocumentPartitioningChanged() {
547553
if (fDocumentPartitioningListeners == null) {
548554
return;
@@ -565,7 +571,7 @@ protected void fireDocumentPartitioningChanged() {
565571
* <code>fireDocumentPartitioningChanged(DocumentPartitioningChangedEvent)</code>
566572
* instead.
567573
*/
568-
@Deprecated
574+
@Deprecated(forRemoval = true, since= "3.15.0")
569575
protected void fireDocumentPartitioningChanged(IRegion region) {
570576
if (fDocumentPartitioningListeners == null) {
571577
return;
@@ -670,7 +676,7 @@ protected void fireDocumentAboutToBeChanged(DocumentEvent event) {
670676
protected void updateDocumentStructures(DocumentEvent event) {
671677

672678
if (fDocumentPartitioners != null) {
673-
fDocumentPartitioningChangedEvent= new DocumentPartitioningChangedEvent(this);
679+
DocumentPartitioningChangedEvent newValue= new DocumentPartitioningChangedEvent(this);
674680
for (Entry<String, IDocumentPartitioner> entry : fDocumentPartitioners.entrySet()) {
675681

676682
String partitioning= entry.getKey();
@@ -685,14 +691,15 @@ protected void updateDocumentStructures(DocumentEvent event) {
685691
if (partitioner instanceof IDocumentPartitionerExtension extension) {
686692
IRegion r= extension.documentChanged2(event);
687693
if (r != null) {
688-
fDocumentPartitioningChangedEvent.setPartitionChange(partitioning, r.getOffset(), r.getLength());
694+
newValue.setPartitionChange(partitioning, r.getOffset(), r.getLength());
689695
}
690696
} else {
691697
if (partitioner.documentChanged(event)) {
692-
fDocumentPartitioningChangedEvent.setPartitionChange(partitioning, 0, event.getDocument().getLength());
698+
newValue.setPartitionChange(partitioning, 0, event.getDocument().getLength());
693699
}
694700
}
695701
}
702+
fDocumentPartitioningChangedEvent.set(newValue);
696703
}
697704

698705
if (!fPositions.isEmpty()) {
@@ -709,8 +716,9 @@ protected void updateDocumentStructures(DocumentEvent event) {
709716
* @param event the event to be sent out.
710717
*/
711718
protected void doFireDocumentChanged(DocumentEvent event) {
712-
boolean changed= fDocumentPartitioningChangedEvent != null && !fDocumentPartitioningChangedEvent.isEmpty();
713-
IRegion change= changed ? fDocumentPartitioningChangedEvent.getCoverage() : null;
719+
DocumentPartitioningChangedEvent changedEvent= fDocumentPartitioningChangedEvent.get();
720+
boolean changed= changedEvent != null && !changedEvent.isEmpty();
721+
IRegion change= changed ? changedEvent.getCoverage() : null;
714722
doFireDocumentChanged(event, changed, change);
715723
}
716724

@@ -725,7 +733,7 @@ protected void doFireDocumentChanged(DocumentEvent event) {
725733
* @since 2.0
726734
* @deprecated as of 3.0. Use <code>doFireDocumentChanged2(DocumentEvent)</code> instead; this method will be removed.
727735
*/
728-
@Deprecated
736+
@Deprecated(forRemoval = true, since= "3.15.0")
729737
protected void doFireDocumentChanged(DocumentEvent event, boolean firePartitionChange, IRegion partitionChange) {
730738
doFireDocumentChanged2(event);
731739
}
@@ -743,8 +751,7 @@ protected void doFireDocumentChanged(DocumentEvent event, boolean firePartitionC
743751
*/
744752
protected void doFireDocumentChanged2(DocumentEvent event) {
745753

746-
DocumentPartitioningChangedEvent p= fDocumentPartitioningChangedEvent;
747-
fDocumentPartitioningChangedEvent= null;
754+
DocumentPartitioningChangedEvent p= fDocumentPartitioningChangedEvent.getAndSet(null);
748755
if (p != null && !p.isEmpty()) {
749756
fireDocumentPartitioningChanged(p);
750757
}
@@ -786,10 +793,10 @@ protected void doFireDocumentChanged2(DocumentEvent event) {
786793
protected void fireDocumentChanged(DocumentEvent event) {
787794
updateDocumentStructures(event);
788795

789-
if (fStoppedListenerNotification == 0) {
796+
if (fStoppedListenerNotification.get() == 0) {
790797
doFireDocumentChanged(event);
791798
} else {
792-
fDeferredDocumentEvent= event;
799+
fDeferredDocumentEvents.add(event);
793800
}
794801
}
795802

@@ -1099,13 +1106,13 @@ public void removePositionUpdater(IPositionUpdater updater) {
10991106
}
11001107

11011108
private long getNextModificationStamp() {
1102-
if (fNextModificationStamp == Long.MAX_VALUE || fNextModificationStamp == IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP) {
1103-
fNextModificationStamp= 0;
1104-
} else {
1105-
fNextModificationStamp= fNextModificationStamp + 1;
1106-
}
1107-
1108-
return fNextModificationStamp;
1109+
return fNextModificationStamp.getAndUpdate(current -> {
1110+
if (current == Long.MAX_VALUE || current == IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP) {
1111+
return 0;
1112+
} else {
1113+
return current + 1;
1114+
}
1115+
});
11091116
}
11101117

11111118
@Override
@@ -1126,7 +1133,7 @@ public void replace(int pos, int length, String text, long modificationStamp) th
11261133
getTracker().replace(pos, length, text);
11271134

11281135
fModificationStamp= modificationStamp;
1129-
fNextModificationStamp= Math.max(fModificationStamp, fNextModificationStamp);
1136+
fNextModificationStamp.getAndAccumulate(fModificationStamp, Math::max);
11301137
e.fModificationStamp= fModificationStamp;
11311138

11321139
fireDocumentChanged(e);
@@ -1167,7 +1174,7 @@ public void set(String text, long modificationStamp) {
11671174
getTracker().set(text);
11681175

11691176
fModificationStamp= modificationStamp;
1170-
fNextModificationStamp= Math.max(fModificationStamp, fNextModificationStamp);
1177+
fNextModificationStamp.getAndAccumulate(fModificationStamp, Math::max);
11711178
e.fModificationStamp= fModificationStamp;
11721179

11731180
fireDocumentChanged(e);
@@ -1192,7 +1199,7 @@ protected void updatePositions(DocumentEvent event) {
11921199
*
11931200
* @deprecated as of 3.0 search is provided by {@link FindReplaceDocumentAdapter}
11941201
*/
1195-
@Deprecated
1202+
@Deprecated(forRemoval = true, since= "3.15.0")
11961203
@Override
11971204
public int search(int startPosition, String findString, boolean forwardSearch, boolean caseSensitive, boolean wholeWord) throws BadLocationException {
11981205
try {
@@ -1295,7 +1302,7 @@ public void resumePostNotificationProcessing() {
12951302
* {@link IDocumentExtension4#startRewriteSession(DocumentRewriteSessionType)}
12961303
* instead.
12971304
*/
1298-
@Deprecated
1305+
@Deprecated(forRemoval = true, since= "3.15.0")
12991306
@Override
13001307
public void startSequentialRewrite(boolean normalized) {
13011308
}
@@ -1306,22 +1313,21 @@ public void startSequentialRewrite(boolean normalized) {
13061313
* @since 2.0
13071314
* @deprecated As of 3.1, replaced by {@link IDocumentExtension4#stopRewriteSession(DocumentRewriteSession)}
13081315
*/
1309-
@Deprecated
1316+
@Deprecated(forRemoval = true, since= "3.15.0")
13101317
@Override
13111318
public void stopSequentialRewrite() {
13121319
}
13131320

13141321
@Override
13151322
public void resumeListenerNotification() {
1316-
-- fStoppedListenerNotification;
1317-
if (fStoppedListenerNotification == 0) {
1323+
if (fStoppedListenerNotification.decrementAndGet() == 0) {
13181324
resumeDocumentListenerNotification();
13191325
}
13201326
}
13211327

13221328
@Override
13231329
public void stopListenerNotification() {
1324-
++ fStoppedListenerNotification;
1330+
fStoppedListenerNotification.incrementAndGet();
13251331
}
13261332

13271333
/**
@@ -1331,17 +1337,18 @@ public void stopListenerNotification() {
13311337
* @since 2.1
13321338
*/
13331339
private void resumeDocumentListenerNotification() {
1334-
if (fDeferredDocumentEvent != null) {
1335-
DocumentEvent event= fDeferredDocumentEvent;
1336-
fDeferredDocumentEvent= null;
1337-
doFireDocumentChanged(event);
1340+
while (!fDeferredDocumentEvents.isEmpty()) {
1341+
if (fStoppedListenerNotification.get() == 0) {
1342+
try {
1343+
DocumentEvent event= fDeferredDocumentEvents.remove(0);
1344+
doFireDocumentChanged(event);
1345+
} catch (IndexOutOfBoundsException ex) {
1346+
log(ex);
1347+
}
1348+
}
13381349
}
13391350
}
13401351

1341-
/*
1342-
* @see org.eclipse.jface.text.IDocumentExtension3#computeZeroLengthPartitioning(java.lang.String, int, int)
1343-
* @since 3.0
1344-
*/
13451352
@Override
13461353
public ITypedRegion[] computePartitioning(String partitioning, int offset, int length, boolean includeZeroLengthPartitions) throws BadLocationException, BadPartitioningException {
13471354
if ((0 > offset) || (0 > length) || (offset + length > getLength())) {

0 commit comments

Comments
 (0)