Skip to content

Commit 3b64166

Browse files
author
rcartwright
committed
This revision is another small step toward streamlining the operations
involved in indenting documents. In addition, it adds document write locking to the processAll method in FindReplaceMachine. It appears that the document processing performed by processAll was not protected by a lock unless the passed command did the locking. Now the command code can assume that a write lock is already held. The following files were modified: M src/edu/rice/cs/drjava/model/cache/DocumentCache.java M src/edu/rice/cs/drjava/model/definitions/indent/ActionStartPrevStmtPlus.java M src/edu/rice/cs/drjava/model/definitions/indent/ActionBracePlus.java M src/edu/rice/cs/drjava/model/definitions/indent/QuestionBraceIsParenOrBracket.java M src/edu/rice/cs/drjava/model/definitions/indent/IndentRuleWithTrace.java M src/edu/rice/cs/drjava/model/definitions/indent/ActionStartStmtOfBracePlus.java M src/edu/rice/cs/drjava/model/definitions/indent/Indenter.java M src/edu/rice/cs/drjava/model/definitions/indent/IndentRule.java M src/edu/rice/cs/drjava/model/definitions/DefinitionsDocument.java M src/edu/rice/cs/drjava/model/definitions/reducedmodel/BraceInfo.java M src/edu/rice/cs/drjava/model/FindReplaceMachineTest.java M src/edu/rice/cs/drjava/model/Query.java M src/edu/rice/cs/drjava/model/AbstractDJDocument.java M src/edu/rice/cs/drjava/model/FindReplaceMachine.java M src/edu/rice/cs/drjava/model/AbstractGlobalModel.java M src/edu/rice/cs/drjava/ui/FindReplacePanel.java M src/edu/rice/cs/util/LogTest.java M src/edu/rice/cs/util/StringOpsTest.java git-svn-id: file:///tmp/test-svn/trunk@4389 fe72c1cf-3628-48e9-8b72-1c46755d3cff
1 parent 1824c23 commit 3b64166

18 files changed

+288
-284
lines changed

drjava/src/edu/rice/cs/drjava/model/AbstractDJDocument.java

Lines changed: 113 additions & 129 deletions
Large diffs are not rendered by default.

drjava/src/edu/rice/cs/drjava/model/AbstractGlobalModel.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1306,7 +1306,8 @@ else if ( doc.isAuxiliaryFile()) {
13061306
* @param file where to save the project
13071307
* @param info
13081308
*/
1309-
public ProjectProfile _makeProjectProfile(File file, Hashtable<OpenDefinitionsDocument, DocumentInfoGetter> info) throws IOException {
1309+
public ProjectProfile _makeProjectProfile(File file, Hashtable<OpenDefinitionsDocument, DocumentInfoGetter> info)
1310+
throws IOException {
13101311
ProjectProfile builder = new ProjectProfile(file);
13111312

13121313
// add project root

drjava/src/edu/rice/cs/drjava/model/FindReplaceMachine.java

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public void positionChanged() {
115115

116116
public void setLastFindWord() { _lastFindWord = _findWord; }
117117

118-
public boolean getSearchBackwards() { return ! _isForward; }
118+
public boolean isSearchBackwards() { return ! _isForward; }
119119

120120
public void setSearchBackwards(boolean searchBackwards) {
121121
if (_isForward == searchBackwards) {
@@ -339,18 +339,21 @@ private int processAll(Lambda<Void, FindResult> findAction, boolean searchAll) {
339339
else return _processAllInCurrentDoc(findAction);
340340
}
341341

342-
/** Processes all occurences of _findWord in _doc. Never processes other documents. Starts at
343-
* the beginning or the end of the document (depending on find direction). This convention ensures that matches
344-
* created by string replacement will not be replaced as in the following example:<p>
345-
* findString: "hello"<br>
346-
* replaceString: "e"<br>
347-
* document text: "hhellollo"<p>
348-
* Only executes in event thread.
349-
* @param findAction action to perform on the occurrences; input is the FindResult, output is ignored
350-
* @return the number of replacements
351-
*/
342+
/** Processes all occurences of _findWord in _doc. Never processes other documents. Starts at the beginning or the
343+
* end of the document (depending on find direction). This convention ensures that matches created by string
344+
* replacement will not be replaced as in the following example:<p>
345+
* findString: "hello"<br>
346+
* replaceString: "e"<br>
347+
* document text: "hhellollo"<p>
348+
* Only executes in event thread.
349+
* @param findAction action to perform on the occurrences; input is the FindResult, output is ignored
350+
* @return the number of replacements
351+
*/
352352
private int _processAllInCurrentDoc(Lambda<Void, FindResult> findAction) {
353353

354+
_doc.acquireWriteLock(); // may modify the document!
355+
try {
356+
354357
if (_isForward) setPosition(0);
355358
else setPosition(_doc.getLength());
356359

@@ -363,20 +366,21 @@ private int _processAllInCurrentDoc(Lambda<Void, FindResult> findAction) {
363366
fr = findNext(false); // find next match in current doc
364367
}
365368
return count;
369+
}
370+
finally { _doc.releaseWriteLock(); }
366371
}
367372

368373
public FindResult findNext() { return findNext(_searchAllDocuments); }
369374

370375
/** Finds the next occurrence of the find word and returns an offset at the end of that occurrence or -1 if the word
371-
* was not found. Selectors should select backwards the length of the find word from the find offset. This
372-
* position is stored in the current offset of the machine, and that is why it is after: in subsequent searches, the
373-
* same instance won't be found twice. In a backward search, the position returned is at the beginning of the word.
374-
* Also returns a flag indicating whether the end of the document was reached and wrapped around. This is done
375-
* using the FindResult class which contains the matching document, an integer offset and two flag indicated whether
376-
* the search wrapped (within _doc and across all documents). Only executes in the event thread.
377-
* @param searchAll whether to search all documents (or just _doc)
378-
* @return a FindResult object containing foundOffset and a flag indicating wrapping to the beginning during a search
379-
*/
376+
* was not found. In a forward search, the match offset is the RIGHT edge of the word. In subsequent searches, the
377+
* same instance won't be found again. In a backward search, the position returned is the LEFT edge of the word.
378+
* Also returns a flag indicating whether the end of the document was reached and wrapped around. This is done
379+
* using the FindResult class which contains the matching document, an integer offset and two flag indicated whether
380+
* the search wrapped (within _doc and across all documents). Only executes in the event thread.
381+
* @param searchAll whether to search all documents (or just _doc)
382+
* @return a FindResult object containing foundOffset and a flag indicating wrapping to the beginning during a search
383+
*/
380384
private FindResult findNext(boolean searchAll) {
381385

382386
assert EventQueue.isDispatchThread();
@@ -443,31 +447,31 @@ private FindResult _findWrapped(OpenDefinitionsDocument doc, int start, int len,
443447

444448
final int docLen = doc.getLength();
445449
if (docLen == 0) return new FindResult(doc, -1, true, allWrapped); // failure result
450+
451+
final int wordLen = _findWord.length();
446452

447-
assert (start >= 0 && start <= docLen) && (len >= 0 && len <= docLen);
453+
assert (start >= 0 && start <= docLen) && (len >= 0 && len <= docLen) && wordLen > 0;
448454
assert (_isForward && start + len == docLen) || (! _isForward && start == 0);
449455
// Utilities.show("_findWrapped(" + doc + ", " + start + ", " + len + ", " + allWrapped + ") docLength = " +
450456
// doc.getLength() + ", _isForward = " + _isForward);
451457
_log.log("_findWrapped(" + doc + ", " + start + ", " + len + ", " + allWrapped + ") docLength = " +
452458
doc.getLength() + ", _isForward = " + _isForward);
453-
454-
if (docLen == 0) return new FindResult(doc, -1, true, allWrapped); // failure result
455459

456460
int newLen;
457-
final int newStart;
461+
int newStart;
458462

459-
final int adjustment = _findWord.length() - 1; // max size of the findWord suffix (prefix) within preceding text
463+
final int adjustment = wordLen - 1; // non-negative max size of the findWord suffix (prefix) within preceding text
460464

461465
if (_isForward) {
462466
newStart = 0;
463467
newLen = start + adjustment; // formerly start, which was an annoying bug
468+
if (newLen > docLen) newLen = docLen;
464469
}
465470
else {
466-
newStart = len;
467-
newLen = (docLen - len) + adjustment;
471+
newStart = len - adjustment;
472+
if (newStart < 0) newStart = 0;
473+
newLen = docLen - newStart;
468474
}
469-
470-
if (newLen > docLen) newLen = docLen;
471475

472476
_log.log("Calling _findNextInDocSegment(" + doc.getText() + ", newStart = " + newStart + ", newLen = " +
473477
newLen + ", allWrapped = " + allWrapped + ") and _isForward = " + _isForward);
@@ -577,12 +581,12 @@ private FindResult _findNextInDocSegment(final OpenDefinitionsDocument doc, fina
577581
}
578582

579583
/** Searches all documents following startDoc for _findWord, cycling through the documents in the direction specified
580-
* by _isForward. If the search cycles back to doc without finding a match, performs a wrapped search on doc.
581-
* @param startDoc document where searching started and just failed
582-
* @param start location in startDoc of the document segment where search failed.
583-
* @param len length of the text segment where search failed.
584-
* @return the FindResult containing the information for where we found _findWord or a dummy FindResult.
585-
*/
584+
* by _isForward. If the search cycles back to doc without finding a match, performs a wrapped search on doc.
585+
* @param startDoc document where searching started and just failed
586+
* @param start location in startDoc of the document segment where search failed.
587+
* @param len length of the text segment where search failed.
588+
* @return the FindResult containing the information for where we found _findWord or a dummy FindResult.
589+
*/
586590
private FindResult _findNextInOtherDocs(final OpenDefinitionsDocument startDoc, int start, int len) {
587591

588592
// System.err.println("_findNextInOtherDocs(" + startDoc.getText() + ", " + start + ", " + len + ")");

drjava/src/edu/rice/cs/drjava/model/FindReplaceMachineTest.java

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import edu.rice.cs.util.swing.Utilities;
4444
import edu.rice.cs.util.text.AbstractDocumentInterface;
4545

46+
import java.awt.EventQueue;
4647
import javax.swing.text.BadLocationException;
4748
import java.io.File;
4849
import java.io.IOException;
@@ -155,7 +156,7 @@ public void testCreateMachineSuccess() throws BadLocationException {
155156
public void testFindNextUpdatesCurrent() throws BadLocationException {
156157
_doc.insertString(0, EVIL_TEXT, null);
157158
_initFrm(0);
158-
_assertOffsets(_frm, 0, 0);
159+
_assertOffset(_frm, 0);
159160
_frm.setFindWord("evil");
160161

161162
_testFindNextSucceeds(_frm, 0, 12);
@@ -165,14 +166,37 @@ public void testFindNextUpdatesCurrent() throws BadLocationException {
165166
public void testFindNextAndFailIsOnMatch() throws BadLocationException {
166167
_doc.insertString(0, EVIL_TEXT, null);
167168
_initFrm(0);
168-
_assertOffsets(_frm, 0, 0);
169+
_assertOffset(_frm, 0);
169170
_frm.setFindWord("evil");
170171
_testFindNextSucceeds(_frm, 0, 12);
171172
_doc.insertString(9, "-", null);
172173
assertTrue("no longer on find text", !_frm.onMatch());
173174
// System.err.println("testFindNextAndFailIsOnMatch completed");
174175
}
175176

177+
public void testFindNextOnSuffix() throws BadLocationException {
178+
_doc.insertString(0, EVIL_TEXT, null);
179+
_initFrm(1);
180+
_assertOffset(_frm, 1);
181+
_frm.setFindWord("Hear");
182+
_testFindNextSucceeds(_frm, 0, 4);
183+
_doc.insertString(1, "-", null);
184+
assertTrue("no longer on find text", ! _frm.onMatch());
185+
// System.err.println("testFindNextAndFailIsOnMatch completed");
186+
}
187+
188+
public void testFindPrevOnPrefix() throws BadLocationException {
189+
_doc.insertString(0, EVIL_TEXT, null);
190+
_initFrm(3);
191+
_frm.setSearchBackwards(true);
192+
_assertOffset(_frm, 3);
193+
_frm.setFindWord("Hear");
194+
_testFindNextSucceeds(_frm, 0, 0);
195+
_doc.insertString(1, "-", null);
196+
assertTrue("no longer on find text", ! _frm.onMatch());
197+
// System.err.println("testFindNextAndFailIsOnMatch completed");
198+
}
199+
176200
public void testMultipleCallsToFindNext() throws BadLocationException {
177201
_doc.insertString(0, EVIL_TEXT, null);
178202
_initFrm(0);
@@ -660,17 +684,21 @@ public void run() {
660684
assertEquals("findNext return value", -1, _offset);
661685
_assertOffsets(frm, start, current);
662686
}
663-
687+
664688
private void _assertOffsets(FindReplaceMachine frm, int start, int current) {
665689
// Utilities.show("_assertOffsets(" + start + ", " + current + ")");
666690
// assertEquals("start offset", start, frm.getStartOffset());
667691
assertEquals("current offset", current, frm.getCurrentOffset());
668692
}
669693

694+
private void _assertOffset(FindReplaceMachine frm, int current) {
695+
assertEquals("current offset", current, frm.getCurrentOffset());
696+
}
697+
670698
private void replaceAll() {
671699
Utilities.invokeAndWait(new Runnable() { public void run() { _frm.replaceAll(); } });
672700
}
673-
701+
674702
// /** A thunk returning boolean. */
675703
// private interface ContinueCommand {
676704
// public boolean shouldContinue();

drjava/src/edu/rice/cs/drjava/model/Query.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,10 @@ public static class PosInParenPhrase extends Pos {
192192
public PosInParenPhrase(int pos) { super(pos); }
193193
}
194194

195+
public static class LineEnclosingBrace extends Pos {
196+
public LineEnclosingBrace(int pos) { super(pos); }
197+
}
198+
195199
public static class EnclosingBrace extends Pos {
196200
public EnclosingBrace(int pos) { super(pos); }
197201
}

drjava/src/edu/rice/cs/drjava/model/cache/DocumentCache.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,9 +216,11 @@ public int getLength() {
216216

217217

218218
/** Gets the text of this document using in order of preference (i) cached _doc; (ii) cached reconstructor _image;
219-
* and (iii) the document after forcing it to be loaded. */
219+
* and (iii) the document after forcing it to be loaded. If document is not locked, may return stale data. */
220220
public String getText() {
221221
final DefinitionsDocument doc = _doc; // create a snapshot of _doc
222+
// if (doc == null || ! doc.isModifiedSinceSave()) return _rec.getText();
223+
// return doc.getText();
222224
if (doc != null) return doc.getText();
223225
return _rec.getText(); // There is a technical race here; _doc could be set and modified before here
224226
}

drjava/src/edu/rice/cs/drjava/model/definitions/DefinitionsDocument.java

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,31 +1041,31 @@ else if (!cn.equals(className)) {
10411041
}
10421042

10431043
/** Returns the name of the class or interface enclosing the caret position at the top level.
1044-
* @return Name of enclosing class or interface
1045-
* @throws ClassNameNotFoundException if no enclosing class found
1044+
* @return Name of enclosing class or interface
1045+
* @throws ClassNameNotFoundException if no enclosing class found
10461046
*/
10471047
public String getEnclosingTopLevelClassName(int pos) throws ClassNameNotFoundException {
10481048
acquireReadLock();
10491049
synchronized(_reduced) {
1050-
int oldLocation = _currentLocation;
1050+
int oldPos = _currentLocation;
10511051
try {
10521052
setCurrentLocation(pos);
1053-
IndentInfo info = getIndentInformation();
1053+
BraceInfo info = getEnclosingBrace();
10541054

10551055
// Find top level open brace
10561056
int topLevelBracePos = -1;
1057-
String braceType = info.enclosingBraceType();
1058-
while (! braceType.equals(IndentInfo.NONE)) {
1059-
if (braceType.equals(IndentInfo.OPEN_CURLY)) {
1060-
topLevelBracePos = _currentLocation - info.distToEnclosingBrace();
1057+
String braceType = info.braceType();
1058+
while (! braceType.equals(BraceInfo.NONE)) {
1059+
if (braceType.equals(BraceInfo.OPEN_CURLY)) {
1060+
topLevelBracePos = _currentLocation - info.distance();
10611061
}
1062-
move(-info.distToEnclosingBrace());
1063-
info = getIndentInformation();
1064-
braceType = info.enclosingBraceType();
1062+
move(-info.distance());
1063+
info = getEnclosingBrace();
1064+
braceType = info.braceType();
10651065
}
10661066
if (topLevelBracePos == -1) {
10671067
// No top level brace was found, so we can't find a top level class name
1068-
setCurrentLocation(oldLocation);
1068+
setCurrentLocation(oldPos);
10691069
throw new ClassNameNotFoundException("no top level brace found");
10701070
}
10711071

@@ -1076,14 +1076,14 @@ public String getEnclosingTopLevelClassName(int pos) throws ClassNameNotFoundExc
10761076
prevDelimPos = 0;
10771077
}
10781078
else prevDelimPos++;
1079-
setCurrentLocation(oldLocation);
1079+
setCurrentLocation(oldPos);
10801080

10811081
// Parse out the class name
10821082
return getNextTopLevelClassName(prevDelimPos, topLevelBracePos);
10831083
}
10841084
catch (BadLocationException ble) { throw new UnexpectedException(ble); }
10851085
finally {
1086-
setCurrentLocation(oldLocation);
1086+
setCurrentLocation(oldPos);
10871087
releaseReadLock();
10881088
}
10891089
}
@@ -1106,7 +1106,7 @@ private String getFirstClassName(int indexOfClass, int indexOfInterface) throws
11061106
public String getMainClassName() throws ClassNameNotFoundException {
11071107
acquireReadLock();
11081108
synchronized(_reduced) {
1109-
final int oldLocation = _currentLocation;
1109+
final int oldPos = _currentLocation;
11101110

11111111
try {
11121112
setCurrentLocation(0);
@@ -1136,7 +1136,7 @@ public String getMainClassName() throws ClassNameNotFoundException {
11361136

11371137
}
11381138
finally {
1139-
setCurrentLocation(oldLocation);
1139+
setCurrentLocation(oldPos);
11401140
releaseReadLock();
11411141
}
11421142
}
@@ -1156,7 +1156,7 @@ public String getNextTopLevelClassName(int startPos, int endPos) throws ClassNam
11561156

11571157
acquireReadLock();
11581158
synchronized(_reduced) {
1159-
int oldLocation = _currentLocation;
1159+
int oldPos = _currentLocation;
11601160

11611161
try {
11621162
setCurrentLocation(startPos);
@@ -1194,7 +1194,7 @@ else if (indexOfEnum > -1 && (indexOfClass <= -1 || indexOfEnum < indexOfClass)
11941194
catch (BadLocationException ble) { throw new UnexpectedException(ble); }
11951195
catch (IllegalStateException e) { throw new ClassNameNotFoundException("No top level class name found"); }
11961196
finally {
1197-
setCurrentLocation(oldLocation);
1197+
setCurrentLocation(oldPos);
11981198
releaseReadLock();
11991199
}
12001200
}
@@ -1254,7 +1254,7 @@ private int _findKeywordAtToplevel(String keyword, String text, int textOffset)
12541254

12551255
acquireReadLock();
12561256
synchronized(_reduced) {
1257-
int oldLocation = _currentLocation;
1257+
int oldPos = _currentLocation;
12581258
int index = 0;
12591259
try {
12601260
while (true) {
@@ -1282,7 +1282,7 @@ private int _findKeywordAtToplevel(String keyword, String text, int textOffset)
12821282
}
12831283
}
12841284
}
1285-
setCurrentLocation(oldLocation);
1285+
setCurrentLocation(oldPos);
12861286
// _log.log("findKeyWord(" + keyword + ", ..., " + textOffset + ")");
12871287
return index;
12881288
}

drjava/src/edu/rice/cs/drjava/model/definitions/indent/ActionBracePlus.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,15 @@ public boolean indentLine(AbstractDJDocument doc, Indenter.IndentReason reason)
6464
IndentInfo info = doc.getIndentInformation();
6565

6666
// Check preconditions
67-
if ((info.lineEnclosingBraceType().equals("")) ||
68-
(info.distToLineEnclosingBrace() < 0)) {
67+
if (info.lineEnclosingBraceType().equals("") || info.distToLineEnclosingBrace() < 0) {
6968
// Can't find brace, so do nothing.
7069
return supResult;
7170
}
7271

7372
// Find length to brace
7473
int bracePos = startLine - info.distToLineEnclosingBrace();
7574
int braceNewline = 0;
76-
if (info.distToEnclosingBraceStart() >=0) {
75+
if (info.distToEnclosingBraceStart() >= 0) {
7776
braceNewline = startLine - info.distToEnclosingBraceStart();
7877
}
7978
int braceLen = bracePos - braceNewline;

0 commit comments

Comments
 (0)