Skip to content

Commit bd7a2dd

Browse files
author
rcartwright
committed
This revision fully integrates the new .dj language level with the
main drjava code base. It also appears to fix a few timing bugs in unit tests when run on a dual core Linux laptop. We still have a long way to go in converting the DrJava unit tests to exploit Concutest. My impression is that all uses of MultithreadedUnitTest should be eliminated. The following files were modified: M lib/javalanglevels-base.jar M src/edu/rice/cs/drjava/model/BrowserHistoryManager.java M src/edu/rice/cs/drjava/model/junit/JUnitErrorModelTest.java M src/edu/rice/cs/drjava/model/compiler/CompilerOptions.java M src/edu/rice/cs/drjava/model/Region.java M src/edu/rice/cs/drjava/model/BrowserDocumentRegion.java M src/edu/rice/cs/drjava/model/OrderedDocumentRegion.java M src/edu/rice/cs/drjava/ui/ProjectMenuTest.java git-svn-id: file:///tmp/test-svn/trunk@5425 fe72c1cf-3628-48e9-8b72-1c46755d3cff
1 parent 02bb605 commit bd7a2dd

File tree

8 files changed

+112
-94
lines changed

8 files changed

+112
-94
lines changed

drjava/lib/javalanglevels-base.jar

27.9 KB
Binary file not shown.

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,30 +42,29 @@
4242

4343
/** Class for document regions that totally ordered by allocation chronology. They do not conform to the invariants
4444
* required for OrderedDocumentRegions.
45-
* Warning: this class defines compareTo which implicits defines a coarser equality relation than equals
45+
* Warning: this class defines compareTo which implicitly defines a coarser equality relation than equals
4646
* @version $Id$
4747
*/
4848
public class BrowserDocumentRegion implements IDocumentRegion, Comparable<BrowserDocumentRegion> {
49-
private static volatile int _indexCounter = 0; // sequence number counter for browser regions
49+
private static volatile int _indexCounter = 0; // sequence number counter for browser regions
5050
private final int _index; // unique sequence number for this region
5151
protected final OpenDefinitionsDocument _doc; // document for this region
5252
protected final File _file; // file for this region
5353
protected Position _startPosition; // start position for this region
5454
protected Position _endPosition; // final position for this region
5555
protected volatile DefaultMutableTreeNode _treeNode;
5656

57-
/** Create a new simple document region.
57+
/** Create a new simple document region with a bona fide document.
5858
* @param doc document that contains this region
5959
* @param file file that contains the region
6060
* @param sp start position of the region
6161
* @param ep end position of the region
6262
*/
63-
/** Create a new simple document region with a bona fide document */
6463
public BrowserDocumentRegion(OpenDefinitionsDocument doc, Position sp, Position ep) {
6564
assert doc != null;
6665
_index = _indexCounter++; // sequence number records allocation order
6766
_doc = doc;
68-
_file = doc.getRawFile(); // don't check the validity of _file here
67+
_file = doc.getRawFile(); // don't check the validity of _file here
6968
_startPosition = sp;
7069
_endPosition = ep;
7170
_treeNode = null;
@@ -93,6 +92,12 @@ public BrowserDocumentRegion(OpenDefinitionsDocument doc, Position sp, Position
9392
/** @return the end offset */
9493
public int getEndOffset() { return _endPosition.getOffset(); }
9594

95+
/* The following are commented out because a Position object includes a reference to the corresponding object,
96+
* preventing it from being garbage-collected. We cannot retain any Position objects for documents that have
97+
* been kicked out the document cache assuming we want such documents to be garbage-collected (which is the
98+
* primary motivation for creating the document cache).
99+
*/
100+
96101
// /** @return the start position */
97102
// public Position getStartPosition() { return _startPosition; }
98103

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,13 @@
4343
import edu.rice.cs.plt.lambda.Lambda;
4444
import edu.rice.cs.util.swing.Utilities;
4545

46-
/** Browser history manager for the entire model. Follows readers/writers locking protocol of EventNotifier.
47-
*/
46+
/** Browser history manager for the entire model. Follows readers/writers locking protocol of EventNotifier. */
4847
public class BrowserHistoryManager extends EventNotifier<RegionManagerListener<BrowserDocumentRegion>> {
4948
/** Two regions are similar if they are in the same document and not more than DIFF_THRESHOLD lines apart. */
5049
public static final int DIFF_THRESHOLD = 5;
5150

52-
/** List of regions. */
51+
/** List of regions. In Java 6, ArrayDeque is a better choice than Stack; should be changed once compatibility
52+
* with Java 5 is abandoned. */
5353
private volatile Stack<BrowserDocumentRegion> _pastRegions = new Stack<BrowserDocumentRegion>();
5454
private volatile Stack<BrowserDocumentRegion> _futureRegions = new Stack<BrowserDocumentRegion>();
5555

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
* of lexicographic ordering on the name), then by start Position and then by end Position.
4444
*
4545
* All implementations of this interface should be immutable (at the level of the field bindings in those classes),
46-
* but a given document Postion can "move" when the associated document is modified. As a result, hashing on
46+
* but a given document Position can "move" when the associated document is modified. As a result, hashing on
4747
* OrderedDocumentRegions will produce upredictable results (WiLL NOT WORK) unless hashing on Positions works
4848
* (which this design does NOT presume). On the other hand, the relative ordering of Positions is invariant
4949
* (except for possible coalescing of formerly distinct Positions) regardless of how the associated document is

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@
3636

3737
package edu.rice.cs.drjava.model;
3838

39-
/** The minimal interface for all region classes. Excludes a document field because DummyDocumentRegions are created before
40-
* their corresponding document.
39+
/** The minimal interface for all region classes. Excludes a document field because DummyDocumentRegions are created
40+
* before their corresponding document.
4141
* @version $Id$
4242
*/
4343
public interface Region {

drjava/src/edu/rice/cs/drjava/model/compiler/CompilerOptions.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ public class CompilerOptions implements OptionConstants {
5454

5555
private static WarningOptionListener wol = new WarningOptionListener();
5656

57-
/** The OptionListener for the Warning Options
58-
*/
57+
/** The OptionListener for the Warning Options */
5958
private static class WarningOptionListener implements OptionListener<Boolean> {
6059
public void optionChanged(OptionEvent<Boolean> oce) {
6160
updateWarnings();

drjava/src/edu/rice/cs/drjava/model/junit/JUnitErrorModelTest.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import edu.rice.cs.util.swing.Utilities;
4242

4343
import java.io.File;
44+
import javax.swing.text.BadLocationException;
4445

4546
import static edu.rice.cs.plt.debug.DebugUtil.debug;
4647

@@ -172,8 +173,17 @@ public void testErrorsArrayInOrder_NOJOIN() throws Exception {
172173
// runJUnit waits until the thread started in DefaultJUnitModel._rawJUnitOpenDefDocs has called notify
173174

174175
listener.assertJUnitStartCount(1);
175-
// Clear document so we can make sure it's written to after startJUnit
176-
_model.getJUnitModel().getJUnitDocument().remove(0, _model.getJUnitModel().getJUnitDocument().getLength() - 1);
176+
// Clear document so we can make sure it's written to after startJUnit;
177+
// ?? When does the clear operation happen? How is the timing of this clear operation controlled?
178+
// Perform the clear operation atomically in the event thread.
179+
Utilities.invokeAndWait(new Runnable() {
180+
public void run() {
181+
try {
182+
_model.getJUnitModel().getJUnitDocument().remove(0, _model.getJUnitModel().getJUnitDocument().getLength() - 1);
183+
}
184+
catch(BadLocationException e) { fail("BadLocationException in clearing JUnitDocument"); }
185+
}
186+
});
177187
//final TestResult testResults = doc.startJUnit();
178188

179189
//_m = new JUnitErrorModel(doc.getDocument(), "MonkeyTestFail", testResults);

drjava/src/edu/rice/cs/drjava/ui/ProjectMenuTest.java

Lines changed: 83 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737
package edu.rice.cs.drjava.ui;
3838

39-
import edu.rice.cs.drjava.model.MultiThreadedTestCase;
39+
import edu.rice.cs.drjava.DrJavaTestCase;
4040
import edu.rice.cs.drjava.model.OpenDefinitionsDocument;
4141
import edu.rice.cs.drjava.model.SingleDisplayModel;
4242
import edu.rice.cs.drjava.project.DocFile;
@@ -51,12 +51,14 @@
5151
import edu.rice.cs.util.UnexpectedException;
5252
import edu.rice.cs.util.swing.Utilities;
5353

54+
import java.awt.EventQueue;
55+
import java.awt.Toolkit;
5456
import java.io.*;
5557
import java.util.List;
5658

5759
/** Test functions of Project Facility working through the main frame and model. */
58-
public final class ProjectMenuTest extends MultiThreadedTestCase {
59-
60+
public final class ProjectMenuTest extends DrJavaTestCase {
61+
6062
private volatile MainFrame _frame;
6163

6264
private volatile SingleDisplayModel _model;
@@ -84,7 +86,7 @@ public final class ProjectMenuTest extends MultiThreadedTestCase {
8486
public void setUp() throws Exception {
8587
// Perform Swing setup in event thread because the event thread is ALREADY running
8688
superSetUp(); // super.setUp() should be called first; contains an embedded invokeAndWait
87-
89+
8890
Utilities.invokeAndWait(new Runnable() {
8991
public void run() {
9092
try {
@@ -124,13 +126,23 @@ public void run() {
124126
}
125127
});
126128
}
127-
129+
128130
public void tearDown() throws Exception {
131+
129132
Utilities.invokeAndWait(new Runnable() {
130133
public void run() {
131134
IOUtil.deleteOnExitRecursively(_parent);
132135
_auxFile.delete();
133136
//FileOps.deleteDirectory(_parent);
137+
}
138+
});
139+
140+
/* Ensure that all pending actions in the event queue have completed. */
141+
EventQueue current = java.awt.Toolkit.getDefaultToolkit().getSystemEventQueue();
142+
while (current.peekEvent() != null) { Thread.sleep(200); }
143+
144+
Utilities.invokeAndWait(new Runnable() {
145+
public void run() {
134146
_frame.dispose();
135147
_projFile = FileOps.NULL_FILE;
136148
_model = null;
@@ -144,92 +156,84 @@ public void testSetBuildDirectory() throws MalformedProjectFileException, IOExce
144156

145157
// Utilities.showDebug("executing testSetBuildDirectory");
146158

147-
//test set build directory when not in project mode
148-
File f = FileOps.NULL_FILE;
149-
_model.setBuildDirectory(f);
150-
Utilities.clearEventQueue(); // ensure that listener tasks have completed
151-
assertEquals("Build directory should not have been set", FileOps.NULL_FILE, _model.getBuildDirectory());
152-
153-
// System.err.println("Opening Project File");
154-
Utilities.invokeAndWait(new Runnable() {
155-
public void run() {
156-
try { _model.openProject(_projFile); }
159+
Utilities.invokeAndWait(new Runnable() {
160+
public void run() {
161+
try {
162+
// Test set build directory when not in project mode
163+
File f = FileOps.NULL_FILE;
164+
_model.setBuildDirectory(f);
165+
assertEquals("Build directory should not have been set", FileOps.NULL_FILE, _model.getBuildDirectory());
166+
167+
// System.err.println("Opening Project File");
168+
_model.openProject(_projFile);
169+
170+
// System.err.println("Completed Opening Project File");
171+
// System.err.println("Project documents are: " + _model.getProjectDocuments());
172+
173+
assertEquals("Build directory should not have been set", FileOps.NULL_FILE, _model.getBuildDirectory());
174+
175+
_model.setBuildDirectory(f);
176+
assertEquals("Build directory should have been set", f, _model.getBuildDirectory());
177+
}
157178
catch(Exception e) { throw new UnexpectedException(e); }
158-
}
179+
}
159180
});
160-
// System.err.println("Completed Opening Project File");
161-
// System.err.println("Project documents are: " + _model.getProjectDocuments());
162-
163-
Utilities.clearEventQueue();
164-
165-
assertEquals("Build directory should not have been set", FileOps.NULL_FILE, _model.getBuildDirectory());
166-
167-
_model.setBuildDirectory(f);
168-
Utilities.clearEventQueue();
169-
assertEquals("Build directory should have been set", f, _model.getBuildDirectory());
170181
}
171182

172-
public void testCloseAllClosesProject() throws MalformedProjectFileException, IOException {
173-
183+
public void testCloseAllClosesProject() {
174184
// Utilities.showDebug("executing testCloseAllClosesProject");
175-
Utilities.invokeAndWait(new Runnable() {
176-
public void run() {
177-
try { _model.openProject(_projFile); }
178-
catch(Exception e) { throw new UnexpectedException(e); }
179-
}
180-
});
181-
Utilities.clearEventQueue();
182-
183-
assertTrue("Project should have been opened", _model.isProjectActive());
184-
185-
Utilities.invokeAndWait(new Runnable() {
186-
public void run() {
187-
try { _frame.closeAll(); }
185+
Utilities.invokeAndWait(new Runnable() {
186+
public void run() {
187+
try {
188+
_model.openProject(_projFile);
189+
assertTrue("Project should have been opened", _model.isProjectActive());
190+
191+
_frame.closeAll();
192+
assertFalse("Project should have been closed", _model.isProjectActive());
193+
}
188194
catch(Exception e) { throw new UnexpectedException(e); }
189-
}
195+
}
190196
});
191-
Utilities.clearEventQueue();
192-
193-
assertFalse("Project should have been closed", _model.isProjectActive());
194197
}
195198

196-
public void testSaveProject() throws IOException, MalformedProjectFileException {
197-
199+
public void testSaveProject() {
198200
// Utilities.showDebug("executing testSaveProject");
199201

200202
Utilities.invokeAndWait(new Runnable() {
201-
public void run() {
202-
_frame.openProject(new FileOpenSelector() {
203-
public File[] getFiles() throws OperationCanceledException { return new File[] {_projFile}; }
204-
});
205-
206-
// open a new file and make it an auxiliary file
207-
_frame.open(new FileOpenSelector() {
208-
public File[] getFiles() throws OperationCanceledException { return new File[] {_auxFile}; }
209-
});
210-
_frame._moveToAuxiliary();
211-
212-
List<OpenDefinitionsDocument> auxDocs = _model.getAuxiliaryDocuments();
213-
assertEquals("One auxiliary document", 1, auxDocs.size());
214-
_frame.saveProject();
215-
_frame._closeProject();
216-
}
203+
public void run() {
204+
try {
205+
_frame.openProject(new FileOpenSelector() {
206+
public File[] getFiles() throws OperationCanceledException { return new File[] { _projFile}; }
207+
});
208+
209+
// open a new file and make it an auxiliary file
210+
_frame.open(new FileOpenSelector() {
211+
public File[] getFiles() throws OperationCanceledException { return new File[] { _auxFile}; }
212+
});
213+
_frame._moveToAuxiliary();
214+
215+
List<OpenDefinitionsDocument> auxDocs = _model.getAuxiliaryDocuments();
216+
assertEquals("One auxiliary document", 1, auxDocs.size());
217+
_frame.saveProject();
218+
_frame._closeProject();
219+
220+
List<OpenDefinitionsDocument> docs = _model.getOpenDefinitionsDocuments();
221+
assertEquals("One empty document remaining", 1, docs.size());
222+
assertEquals("Name is (Untitled)", "(Untitled)", _model.getActiveDocument().toString());
223+
224+
ProjectFileIR pfir = ProjectFileParserFacade.ONLY.parse(_projFile);
225+
DocFile[] src = pfir.getSourceFiles();
226+
// System.err.println(Arrays.toString(src));
227+
DocFile[] aux = pfir.getAuxiliaryFiles();
228+
// System.err.println(Arrays.toString(aux));
229+
assertEquals("Number of saved src files", 2, src.length);
230+
assertEquals("Number of saved aux files", 1, aux.length);
231+
assertEquals("wrong name for _file2", _file2.getCanonicalPath(), src[1].getCanonicalPath()); // assumes same (not reverse) order
232+
assertEquals("Wrong name for _file1", _file1.getCanonicalPath(), src[0].getCanonicalPath());
233+
assertEquals("Wrong aux file", _auxFile.getCanonicalPath(), aux[0].getCanonicalPath());
234+
}
235+
catch(Exception e) { throw new UnexpectedException(e); }
236+
}
217237
});
218-
Utilities.clearEventQueue();
219-
220-
List<OpenDefinitionsDocument> docs = _model.getOpenDefinitionsDocuments();
221-
assertEquals("One empty document remaining", 1, docs.size());
222-
assertEquals("Name is (Untitled)", "(Untitled)", _model.getActiveDocument().toString());
223-
224-
ProjectFileIR pfir = ProjectFileParserFacade.ONLY.parse(_projFile);
225-
DocFile[] src = pfir.getSourceFiles();
226-
// System.err.println(Arrays.toString(src));
227-
DocFile[] aux = pfir.getAuxiliaryFiles();
228-
// System.err.println(Arrays.toString(aux));
229-
assertEquals("Number of saved src files", 2, src.length);
230-
assertEquals("Number of saved aux files", 1, aux.length);
231-
assertEquals("wrong name for _file2", _file2.getCanonicalPath(), src[1].getCanonicalPath()); // assumes same (not reverse) order
232-
assertEquals("Wrong name for _file1", _file1.getCanonicalPath(), src[0].getCanonicalPath());
233-
assertEquals("Wrong aux file", _auxFile.getCanonicalPath(), aux[0].getCanonicalPath());
234238
}
235239
}

0 commit comments

Comments
 (0)