Skip to content

Commit 0aeaf95

Browse files
author
rcartwright
committed
This revision contains a substantially revised language level
converter (embedded in javalanglevels-base.jar. It also reworks testCloseFiles() in SingleDisplayModelTest which has been intermittently failing on a dual core Linux box. Even the revised test (like many of our unit tests) is not properly synchronized. This revision also moves the .class file deletion process for classes in language levels files to just before rather than just after language level conversion. The following files were modified: M testFiles/drjava.basic.config M lib/javalanglevels-base.jar M src/edu/rice/cs/drjava/model/SingleDisplayModelTest.java M src/edu/rice/cs/drjava/model/compiler/DefaultCompilerModel.java M src/edu/rice/cs/drjava/model/AbstractGlobalModel.java M src/edu/rice/cs/drjava/ui/RegionsTreePanel.java git-svn-id: file:///tmp/test-svn/trunk@4816 fe72c1cf-3628-48e9-8b72-1c46755d3cff
1 parent 6c7308b commit 0aeaf95

File tree

6 files changed

+50
-38
lines changed

6 files changed

+50
-38
lines changed

drjava/lib/javalanglevels-base.jar

240 Bytes
Binary file not shown.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ public File getMainClassContainingFile(){
494494
break;
495495

496496
path = path.substring(0, path.lastIndexOf(File.separatorChar));
497-
tempFile = new File(getProjectRoot(), path+".java");
497+
tempFile = new File(getProjectRoot(), path + ".java");
498498
}
499499

500500
return null;

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,8 @@ public synchronized boolean canAbandonFile(OpenDefinitionsDocument doc) {
281281

282282
_log.log("Just before calling _model.closeAllFiles()");
283283
// Close all files, ensure new one was created
284-
_model.closeAllFiles();
284+
Utilities.invokeAndWait(new Runnable() { public void run() { _model.closeAllFiles(); } });
285+
Utilities.clearEventQueue();
285286
Utilities.clearEventQueue();
286287
// we want a ready notification here; closeAllFiles is supposed to reset
287288
// the interactions pane, but the interpreter is supposed to be in a fresh running state

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

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -343,12 +343,11 @@ private static List<File> _testFileSort(List<File> files) {
343343
*/
344344
private List<File> _compileLanguageLevelsFiles(List<File> files, List<DJError> errors,
345345
Iterable<File> classPath, Iterable<File> bootClassPath) {
346-
/* Rename any .dj0 files in files to be .java files, so the correct thing is compiled. The hashset is used to
347-
* make sure we never send in duplicate files. This can happen if the java file was sent in along with the
348-
* corresponding .dj* file. The dj* file is renamed to a .java file and thus we have two of the same file in
349-
* the list. By adding the renamed file to the hashset, the hashset efficiently removes duplicates.
346+
/* Construct the collection of files to be compild by javac, renaming any language levels (.dj*) files to the
347+
* corresponding java (.java) files. By using a HashSet, we avoid creating duplicates in this collection.
350348
*/
351349
HashSet<File> javaFileSet = new HashSet<File>();
350+
LinkedList<File> newFiles = new LinkedList<File>(); // Used to record the LL files that must be converted
352351
boolean containsLanguageLevels = false;
353352
for (File f : files) {
354353
File canonicalFile = IOUtil.attemptCanonicalFile(f);
@@ -358,25 +357,16 @@ private List<File> _compileLanguageLevelsFiles(List<File> files, List<DJError> e
358357
containsLanguageLevels = true;
359358
File javaFile = new File(fileName.substring(0, lastIndex) + ".java");
360359
javaFileSet.add(javaFile);
360+
newFiles.add(javaFile);
361361

362-
// Delete the .java file, it will be regenerated later
362+
// Delete the stale .java file (if it exists), a file with this name will subsequently be generated
363363
javaFile.delete();
364364
}
365365
else { javaFileSet.add(canonicalFile); }
366366
}
367367

368-
LanguageLevelConverter llc = new LanguageLevelConverter();
369-
Options llOpts;
370-
if (bootClassPath == null) { llOpts = new Options(getActiveCompiler().version(), classPath); }
371-
else { llOpts = new Options(getActiveCompiler().version(), classPath, bootClassPath); }
372-
Map<File,Set<String>> sourceToTopLevelClassMap = new HashMap<File,Set<String>>();
373-
/* LanguageLevels Bug Workaround: JUnit test files can generate spurious conversion errors. This
374-
* problem can be mitigated by compiling JUnit test files, which contain the substring "Test", last.
375-
*/
376-
Pair<LinkedList<JExprParseException>, LinkedList<Pair<String, JExpressionIF>>> llErrors =
377-
llc.convert(_testFileSort(files).toArray(new File[0]), llOpts, sourceToTopLevelClassMap);
378-
379368
if (containsLanguageLevels) {
369+
Map<File,Set<String>> sourceToTopLevelClassMap = new HashMap<File,Set<String>>();
380370
final File buildDir = _model.getBuildDirectory();
381371
final File sourceDir = _model.getProjectRoot();
382372
// System.out.println("Build dir : "+buildDir);
@@ -399,7 +389,7 @@ private List<File> _compileLanguageLevelsFiles(List<File> files, List<DJError> e
399389
dir = new File(buildDir,rel);
400390
}
401391
Set<String> classNames = dirToClassNameMap.get(dir);
402-
if (classNames==null) classNames = new HashSet<String>();
392+
if (classNames == null) classNames = new HashSet<String>();
403393
classNames.addAll(e.getValue());
404394
dirToClassNameMap.put(dir,classNames);
405395
// System.out.println(e.getKey()+" --> "+dir);
@@ -418,28 +408,45 @@ private List<File> _compileLanguageLevelsFiles(List<File> files, List<DJError> e
418408
public boolean accept(File dir, String name) {
419409
// System.out.println("\t"+name);
420410
int endPos = name.lastIndexOf(".class");
421-
if (endPos<0) return false; // can't be a class file
411+
if (endPos < 0) return false; // can't be a class file
422412
int dollarPos = name.indexOf('$');
423-
if ((dollarPos>=0) && (dollarPos<endPos)) endPos = dollarPos;
413+
if ((dollarPos >= 0) && (dollarPos < endPos)) endPos = dollarPos;
424414
// class name goes to the .class or the first $, whichever comes first
425415
Set<String> classNames = e.getValue();
426416
if (classNames.contains(name.substring(0,endPos))) {
427417
// this is a class file that is generated from a .dj? file
428-
new File(dir,name).delete();
418+
new File(dir, name).delete();
429419
// don't need to return true, we're deleting the file here already
430420
// System.out.println("\t\tDeleted");
431421
}
432422
return false;
433423
}
434424
});
435425
}
436-
}
426+
/* Perform language levels conversion, creating corresponding .java files. */
427+
LanguageLevelConverter llc = new LanguageLevelConverter();
428+
Options llOpts;
429+
if (bootClassPath == null) { llOpts = new Options(getActiveCompiler().version(), classPath); }
430+
else { llOpts = new Options(getActiveCompiler().version(), classPath, bootClassPath); }
431+
432+
// NOTE: the following workaround ("_testFileSort(files)" instead of simply "files") may no longer be necessary.
433+
/* Perform the conversion incorporating the following Bug Workaround: Forward references can generate spurious
434+
* conversion errors in some cases. This problem can be mitigated by compiling JUnit test files (with names
435+
* containing the substring "Test") last.
436+
*/
437+
Pair<LinkedList<JExprParseException>, LinkedList<Pair<String, JExpressionIF>>> llErrors =
438+
llc.convert(_testFileSort(files).toArray(new File[0]), llOpts, sourceToTopLevelClassMap);
439+
/* Add any errors encountered in conversion to the compilation error log. */
440+
errors.addAll(_parseExceptions2CompilerErrors(llErrors.getFirst()));
441+
errors.addAll(_visitorErrors2CompilerErrors(llErrors.getSecond()));
442+
443+
// // Confirm that the .java files corresponding to .dj* files exist.
444+
// for (File f: newFiles)
445+
// if (! f.exists()) Utilities.show(f + " does not exist");
437446

438-
files = new LinkedList<File>(javaFileSet);
447+
}
439448

440-
errors.addAll(_parseExceptions2CompilerErrors(llErrors.getFirst()));
441-
errors.addAll(_visitorErrors2CompilerErrors(llErrors.getSecond()));
442-
if (containsLanguageLevels) { return files; }
449+
if (containsLanguageLevels) { return new LinkedList<File>(javaFileSet); }
443450
else { return null; }
444451
}
445452

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

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -635,21 +635,24 @@ public void removeRegion(final R r) {
635635
assert EventQueue.isDispatchThread();
636636
_changeState.setLastAdded(null);
637637
DefaultMutableTreeNode regionNode = _regionToTreeNode.get(r);
638-
if (regionNode == null) throw new UnexpectedException("Region node for region " + r + " is null");
638+
// if (regionNode == null) throw new UnexpectedException("Region node for region " + r + " is null"); // should not happen but it does
639+
if (regionNode != null) {
640+
639641
// _regionManager.removeRegion(r);
640-
_regionToTreeNode.remove(r);
641-
642+
_regionToTreeNode.remove(r);
643+
642644
// DefaultMutableTreeNode docNode = _regionManager.getTreeNode(doc);
643-
DefaultMutableTreeNode parent = (DefaultMutableTreeNode) regionNode.getParent(); // TreeNode for document
644-
_regTreeModel.removeNodeFromParent(regionNode);
645+
DefaultMutableTreeNode parent = (DefaultMutableTreeNode) regionNode.getParent(); // TreeNode for document
646+
_regTreeModel.removeNodeFromParent(regionNode);
645647
// System.err.println("panel region count in " + r.getDocument() + " = " + parent.getChildCount());
646-
// check for empty subtree for this document (rooted at parent)
647-
if (parent.getChildCount() == 0) {
648-
// this document has no more regions, remove it
649-
OpenDefinitionsDocument doc = r.getDocument(); // r must not have been disposed above
650-
_docToTreeNode.remove(doc);
651-
_regTreeModel.removeNodeFromParent(parent);
648+
// check for empty subtree for this document (rooted at parent)
649+
if (parent.getChildCount() == 0) {
650+
// this document has no more regions, remove it
651+
OpenDefinitionsDocument doc = r.getDocument(); // r must not have been disposed above
652+
_docToTreeNode.remove(doc);
653+
_regTreeModel.removeNodeFromParent(parent);
652654
// if (parent == _cachedDocNode) _cachedDoc = null;
655+
}
653656
}
654657
// expandTree();
655658
_changeState.updateButtons();

drjava/testFiles/drjava.basic.config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ window.x = 240
77
window.y = 50
88
last.dir = /private/tmp/DrJava-test39882.java
99
last.interactions.dir = /Users/cork
10+
#compile.before.junit = true

0 commit comments

Comments
 (0)