Skip to content

Commit 816d98b

Browse files
committed
Path to JUnitPanel.java that attempts to fix an intermittent threading bug regarding the progress bar in the Testing panel (JUnitPanel). The progress intermittently fails to display. The attempted fix is to add the final modifier to the declaration of the local field _progressBar which is accessed from multiple threads (by invoking methods in the JUnitPanel class). Variables shared across threads should be volatile or final.
modified: ../model/compiler/JavacCompiler.java modified: ../model/compiler/JavaxToolsCompiler.java modified: JUnitPanel.java modified: ../../../../../../../platform/src-openjdk6/edu/rice/cs/drjava/model/compiler/Javac160OpenJDKCompiler.java
1 parent 022278f commit 816d98b

File tree

4 files changed

+103
-97
lines changed

4 files changed

+103
-97
lines changed

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,10 @@ public abstract class JavacCompiler implements CompilerInterface {
5959
/** The set of class names that are run as ACM Java Task Force library programs. */
6060
protected static final Set<String> ACM_PROGRAM_CLASSES = new HashSet<String>();
6161
static {
62-
Collections.addAll(ACM_PROGRAM_CLASSES, new String[] {
63-
"acm.program.Program",
64-
"acm.graphics.GTurtle"
65-
});
62+
Collections.addAll(ACM_PROGRAM_CLASSES, new String[] {"acm.program.Program", "acm.graphics.GTurtle"});
6663
}
6764

65+
/** Standard Constructor */
6866
protected JavacCompiler(JavaVersion.FullVersion version, String location, List<? extends File> defaultBootClassPath) {
6967
_version = version;
7068
_location = location;

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

Lines changed: 92 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package edu.rice.cs.drjava.model.compiler;
22

3+
import edu.rice.cs.drjava.DrJava;
4+
import edu.rice.cs.drjava.config.OptionConstants;
35
import edu.rice.cs.drjava.model.DJError;
6+
import edu.rice.cs.drjava.model.DrJavaFileUtils;
47
import edu.rice.cs.drjava.ui.SmartSourceFilter;
58
import edu.rice.cs.plt.reflect.JavaVersion;
69
import edu.rice.cs.util.ArgumentTokenizer;
@@ -10,37 +13,32 @@
1013
import java.io.IOException;
1114
import java.lang.reflect.Constructor;
1215
import java.util.*;
13-
import javax.tools.*;
14-
16+
import javax.tools.*; /* including ToolProvider, StandardLocation, DiagnosticCollector */
1517

18+
/** The CompilerInterface for the javax.tools compiler embedded in the executing JVM.
19+
* Manages the auxiliary naming methods.(?)
20+
*/
1621

1722
public class JavaxToolsCompiler implements CompilerInterface {
1823
/** The set of class names that are run as ACM Java Task Force library programs. */
1924
protected static final Set<String> ACM_PROGRAM_CLASSES = new HashSet<String>();
2025
static {
21-
Collections.addAll(ACM_PROGRAM_CLASSES, new String[] {
22-
"acm.program.Program",
23-
"acm.graphics.GTurtle"
24-
});
26+
Collections.addAll(ACM_PROGRAM_CLASSES, new String[] {"acm.program.Program", "acm.graphics.GTurtle"});
2527
}
2628
private final JavaCompiler compiler;
2729

28-
public JavaxToolsCompiler() {
29-
this.compiler = ToolProvider.getSystemJavaCompiler();
30-
}
30+
/** Standard Constructor */
31+
public JavaxToolsCompiler() { this.compiler = ToolProvider.getSystemJavaCompiler(); }
3132

32-
public boolean isAvailable() {
33-
return this.compiler != null;
34-
}
33+
public boolean isAvailable() { return this.compiler != null; }
3534

3635
public List<? extends DJError> compile(List<? extends File> files, List<? extends File> classPath,
3736
List<? extends File> sourcePath, File destination,
3837
List<? extends File> bootClassPath, String sourceVersion, boolean showWarnings) {
39-
// TODO: enforce using java8
4038
// Check if compiler is available
4139
if (compiler == null) {
4240
List<DJError> errors = new ArrayList<>();
43-
errors.add(new DJError("Compiler is not available", false));
41+
errors.add(new DJError("The SystemJavaCompiler is not available", false));
4442
return errors;
4543
}
4644

@@ -68,6 +66,7 @@ public List<? extends DJError> compile(List<? extends File> files, List<? extend
6866
Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(files);
6967

7068
// Prepare the compilation options
69+
/* Question (by Corky): is the "-source" option necessary? The JavaxTools compiler is part of the executing JVM. */
7170
List<String> optionList = new ArrayList<>();
7271
if (sourceVersion != null) {
7372
optionList.add("-source");
@@ -113,33 +112,23 @@ public List<? extends DJError> compile(List<? extends File> files, List<? extend
113112

114113
return errors;
115114
}
115+
/* Question (Corky): Shouldn't we retreive the version of this System (JVM). */
116+
public JavaVersion version() { return JavaVersion.JAVA_8; }
116117

117-
public JavaVersion version() {
118-
return JavaVersion.JAVA_8;
119-
}
120-
121-
public String getName() {
122-
return "javax.tools";
123-
}
118+
public String getName() { return "javax.tools"; }
124119

125-
public String getDescription() {
126-
return "Custom compiler implementation using javax.tools";
127-
}
120+
public String getDescription() { return "Standard compiler in javax.tools"; }
128121

129-
public String toString() {
130-
return getName();
131-
}
122+
public String toString() { return getName(); }
132123

133-
public List<File> additionalBootClassPathForInteractions() {
134-
return Collections.emptyList();
135-
}
124+
public List<File> additionalBootClassPathForInteractions() { return Collections.emptyList(); }
136125

137126
/** Transform the command line to be interpreted into something the Interactions JVM can use.
138-
* This replaces "java MyClass a b c" with Java code to call MyClass.main(new String[]{"a","b","c"}).
139-
* "import MyClass" is not handled here.
140-
* transformCommands should support at least "run", "java" and "applet".
141-
* @param interactionsString unprocessed command line
142-
* @return command line with commands transformed */
127+
* This replaces "java MyClass a b c" with Java code to call MyClass.main(new String[]{"a","b","c"}).
128+
* "import MyClass" is not handled here.
129+
* transformCommands should support at least "run", "java" and "applet".
130+
* @param interactionsString unprocessed command line
131+
* @return command line with commands transformed */
143132
public String transformCommands(String interactionsString) {
144133
if (interactionsString.startsWith("java ")) {
145134
interactionsString = transformJavaCommand(interactionsString);
@@ -342,30 +331,30 @@ public String transformRunCommand(String s) {
342331
}
343332

344333
/** Assumes a trimmed String. Returns a string of the call that the interpreter can use.
345-
* The arguments get formatted as comma-separated list of strings enclosed in quotes.
346-
* Example: _transformCommand("java MyClass arg1 arg2 arg3", "{0}.main(new String[]'{'{1}'}');")
347-
* returns "MyClass.main(new String[]{\"arg1\",\"arg2\",\"arg3\"});"
348-
* NOTE: the command to run is constructed using {@link java.text.MessageFormat}. That means that certain characters,
349-
* single quotes and curly braces, for example, are special. To write single quotes, you need to double them.
350-
* To write curly braces, you need to enclose them in single quotes. Example:
351-
* MessageFormat.format("Abc {0} ''foo'' '{'something'}'", "def") returns "Abc def 'foo' {something}".
352-
* @param s the command line, either "java MyApp arg1 arg2 arg3" or "applet MyApplet arg1 arg2 arg3"
353-
* @param command the command to execute, with {0} marking the place for the class name and {1} the place for the arguments
354-
* @return the transformed command
355-
*/
334+
* The arguments get formatted as comma-separated list of strings enclosed in quotes.
335+
* Example: _transformCommand("java MyClass arg1 arg2 arg3", "{0}.main(new String[]'{'{1}'}');")
336+
* returns "MyClass.main(new String[]{\"arg1\",\"arg2\",\"arg3\"});"
337+
* NOTE: the command to run is constructed using {@link java.text.MessageFormat}. That means that certain characters,
338+
* single quotes and curly braces, for example, are special. To write single quotes, you need to double them.
339+
* To write curly braces, you need to enclose them in single quotes. Example:
340+
* MessageFormat.format("Abc {0} ''foo'' '{'something'}'", "def") returns "Abc def 'foo' {something}".
341+
* @param s the command line, either "java MyApp arg1 arg2 arg3" or "applet MyApplet arg1 arg2 arg3"
342+
* @param command the command to execute, with {0} marking the place for the class name and {1} the place for the arguments
343+
* @return the transformed command
344+
*/
356345
protected static String _transformCommand(String s, String command) {
357-
if (s.endsWith(";")) s = _deleteSemiColon(s);
358-
List<String> args = ArgumentTokenizer.tokenize(s, true);
359-
final String classNameWithQuotes = args.get(1); // this is "MyClass"
360-
final String className = classNameWithQuotes.substring(1, classNameWithQuotes.length() - 1); // removes quotes, becomes MyClass
361-
final StringBuilder argsString = new StringBuilder();
362-
boolean seenArg = false;
363-
for (int i = 2; i < args.size(); i++) {
364-
if (seenArg) argsString.append(",");
365-
else seenArg = true;
366-
argsString.append(args.get(i));
367-
}
368-
return java.text.MessageFormat.format(command, className, argsString.toString());
346+
if (s.endsWith(";")) s = _deleteSemiColon(s);
347+
List<String> args = ArgumentTokenizer.tokenize(s, true);
348+
final String classNameWithQuotes = args.get(1); // this is "MyClass"
349+
final String className = classNameWithQuotes.substring(1, classNameWithQuotes.length() - 1); // removes quotes, becomes MyClass
350+
final StringBuilder argsString = new StringBuilder();
351+
boolean seenArg = false;
352+
for (int i = 2; i < args.size(); i++) {
353+
if (seenArg) argsString.append(",");
354+
else seenArg = true;
355+
argsString.append(args.get(i));
356+
}
357+
return java.text.MessageFormat.format(command, className, argsString.toString());
369358
}
370359

371360
/** Deletes the last character of a string. Assumes semicolon at the end, but does not check. Helper
@@ -375,32 +364,53 @@ protected static String _transformCommand(String s, String command) {
375364
*/
376365
protected static String _deleteSemiColon(String s) { return s.substring(0, s.length() - 1); }
377366

378-
379-
367+
// public boolean isSourceFileForThisCompiler(File f) {
368+
// if (f == null) return false;
369+
// String fileName = f.getName();
370+
// return fileName.endsWith(".java") || fileName.endsWith(".dj");
371+
// }
372+
373+
/** .java {@literal -->} true
374+
* .dj {@literal -->} true
375+
* .dj0 {@literal -->} true
376+
* .dj1 {@literal -->} true
377+
* .dj2 {@literal -->} true
378+
* otherwise false
379+
* @return true if the specified file is a source file for this compiler. */
380380
public boolean isSourceFileForThisCompiler(File f) {
381-
if (f == null) return false;
382-
String fileName = f.getName();
383-
return fileName.endsWith(".java");
384-
}
385-
386-
public Set<String> getSourceFileExtensions() {
387-
HashSet<String> extensions = new HashSet<String>();
388-
extensions.add("java");
389-
return extensions;
390-
}
391-
392-
public String getSuggestedFileExtension() {
393-
return ".java";
394-
}
395-
396-
public FileFilter getFileFilter() {
397-
// TODO: this might need to be different... (I think smartsourcefilter includes .dj files which idk ab)
398-
return new SmartSourceFilter();
381+
// by default, use DrJavaFileUtils.isSourceFile
382+
return DrJavaFileUtils.isSourceFile(f);
399383
}
400384

385+
// public Set<String> getSourceFileExtensions() {
386+
// HashSet<String> extensions = new HashSet<String>();
387+
// extensions.add("java");
388+
// return extensions;
389+
// }
390+
391+
/** Return the set of source file extensions that this compiler supports.
392+
* @return the set of source file extensions that this compiler supports. */
393+
public Set<String> getSourceFileExtensions() { return DrJavaFileUtils.getSourceFileExtensions(); }
394+
395+
// public String getSuggestedFileExtension() { return ".java"; }
396+
397+
/** Return the suggested file extension that will be appended to a file without extension.
398+
* @return the suggested file extension */
399+
public String getSuggestedFileExtension() { return DrJavaFileUtils.getSuggestedFileExtension(); }
400+
401+
/** Return a file filter that can be used to open files this compiler supports.
402+
* @return file filter for appropriate source files for this compiler */
403+
public FileFilter getFileFilter() { return new SmartSourceFilter(); }
404+
405+
// public String getOpenAllFilesInFolderExtension() {
406+
// // Should we use OptionConstants for this?
407+
// return ".java";
408+
// }
409+
410+
/** Return the extension of the files that should be opened with the "Open Folder..." command.
411+
* @return file extension for the "Open Folder..." command for this compiler. */
401412
public String getOpenAllFilesInFolderExtension() {
402-
// Should we use OptionConstants for this?
403-
return ".java";
413+
return OptionConstants.LANGUAGE_LEVEL_EXTENSIONS[DrJava.getConfig().getSetting(OptionConstants.LANGUAGE_LEVEL)];
404414
}
405415

406416
/** Return the set of keywords that should be highlighted in the specified file.
@@ -420,8 +430,6 @@ public String getOpenAllFilesInFolderExtension() {
420430
Collections.addAll(JAVA_KEYWORDS, words);
421431
}
422432

423-
public boolean supportsLanguageLevels() {
424-
// TODO: should we support LanguageLevels?
425-
return false;
426-
}
433+
/** @return true since this compiler can be used in conjunction with the language level facility. */
434+
public boolean supportsLanguageLevels() { return true; }
427435
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ private static final SimpleAttributeSet _getTestFailAttributes() {
8282

8383
protected JUnitErrorListPane _errorListPane;
8484
private final MainFrame _mainFrame; // only used in assert statements
85-
private int _testCount;
86-
private boolean _testsSuccessful;
85+
private volatile int _testCount;
86+
private volatile boolean _testsSuccessful;
8787

88-
private volatile JUnitProgressBar _progressBar;
88+
private final JUnitProgressBar _progressBar;
8989

9090
private Action _showStackTraceAction = new AbstractAction("Show Stack Trace") {
9191
public void actionPerformed(ActionEvent ae) {

platform/src-openjdk6/edu/rice/cs/drjava/model/compiler/Javac160OpenJDKCompiler.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@
5757
import static edu.rice.cs.plt.debug.DebugUtil.debug;
5858
import static edu.rice.cs.plt.debug.DebugUtil.error;
5959

60-
/**
61-
* An implementation of the CompilerInterface that supports compiling with
62-
* OpenJDK 6.0. It is a Java 6 compiler, but uses the Java 5 interface.
63-
*
64-
* @version $Id$
65-
*/
60+
/* Question (Corky): Is this adapter obsolete? */
61+
/** An implementation of the CompilerInterface (in DrJava) that supports compiling with
62+
* OpenJDK 6.0. It is a Java 6 compiler, but uses the Java 5 interface from DrJava.
63+
*
64+
* @version $Id$
65+
*/
6666
public class Javac160OpenJDKCompiler extends JavacCompiler {
6767
public static final String COMPILER_CLASS_NAME = "com.sun.tools.javac.main.JavaCompiler";
6868

0 commit comments

Comments
 (0)