diff --git a/.gitignore b/.gitignore index 0dd9c852a..24425b5b2 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,7 @@ drjava/classes drjava/drjava.jar drjava/build.xml.* drjava/coverage_report -scratch \ No newline at end of file +scratch +.idea/ +*.iml +*.exec \ No newline at end of file diff --git a/drjava.jar b/drjava.jar new file mode 100644 index 000000000..d78e4ee65 Binary files /dev/null and b/drjava.jar differ diff --git a/drjava/.gitignore b/drjava/.gitignore index 4c8e5864d..794f549de 100644 --- a/drjava/.gitignore +++ b/drjava/.gitignore @@ -1,3 +1,4 @@ drjava.jar classes/ - +arch/ +docs/ diff --git a/drjava/build.xml b/drjava/build.xml index 8b1f25c78..8e72d38f9 100644 --- a/drjava/build.xml +++ b/drjava/build.xml @@ -1,4 +1,3 @@ - - + - + + + + - - - - + + + + + @@ -184,10 +188,64 @@ ******************* --> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -200,9 +258,9 @@ - - @@ -346,7 +404,19 @@ - + + + + + + + + + + + + + @@ -426,16 +496,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + @@ -455,7 +567,7 @@ - + @@ -464,6 +576,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -755,7 +905,7 @@ @@ -765,7 +915,6 @@ - - - + @@ -979,20 +1125,37 @@ - - + + - - + + + + + + + + + + + + + + + + + + @@ -1010,30 +1173,27 @@ - - - - - - + + + + + + - + - + - + - - - - + diff --git a/drjava/build_old.xml b/drjava/build_old.xml new file mode 100644 index 000000000..37829a408 --- /dev/null +++ b/drjava/build_old.xml @@ -0,0 +1,1014 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/drjava/extlib/cldrdata.jar b/drjava/extlib/cldrdata.jar new file mode 100644 index 000000000..e5191fab2 Binary files /dev/null and b/drjava/extlib/cldrdata.jar differ diff --git a/drjava/extlib/dnsns.jar b/drjava/extlib/dnsns.jar new file mode 100644 index 000000000..e9174da44 Binary files /dev/null and b/drjava/extlib/dnsns.jar differ diff --git a/drjava/extlib/icedtea-sound.jar b/drjava/extlib/icedtea-sound.jar new file mode 100644 index 000000000..97da2257b Binary files /dev/null and b/drjava/extlib/icedtea-sound.jar differ diff --git a/drjava/extlib/jaccess.jar b/drjava/extlib/jaccess.jar new file mode 100644 index 000000000..846da5794 Binary files /dev/null and b/drjava/extlib/jaccess.jar differ diff --git a/drjava/extlib/java-atk-wrapper.jar b/drjava/extlib/java-atk-wrapper.jar new file mode 120000 index 000000000..d0b7bd0b2 --- /dev/null +++ b/drjava/extlib/java-atk-wrapper.jar @@ -0,0 +1 @@ +../../../../../../share/java/java-atk-wrapper.jar \ No newline at end of file diff --git a/drjava/extlib/libatk-wrapper.so b/drjava/extlib/libatk-wrapper.so new file mode 120000 index 000000000..fed87c67c --- /dev/null +++ b/drjava/extlib/libatk-wrapper.so @@ -0,0 +1 @@ +../../../../../x86_64-linux-gnu/jni/libatk-wrapper.so \ No newline at end of file diff --git a/drjava/extlib/localedata.jar b/drjava/extlib/localedata.jar new file mode 100644 index 000000000..7fc65a096 Binary files /dev/null and b/drjava/extlib/localedata.jar differ diff --git a/drjava/extlib/nashorn.jar b/drjava/extlib/nashorn.jar new file mode 100644 index 000000000..71df18d9c Binary files /dev/null and b/drjava/extlib/nashorn.jar differ diff --git a/drjava/extlib/rt.jar b/drjava/extlib/rt.jar new file mode 100644 index 000000000..186774f81 Binary files /dev/null and b/drjava/extlib/rt.jar differ diff --git a/drjava/extlib/sunec.jar b/drjava/extlib/sunec.jar new file mode 100644 index 000000000..90812e59c Binary files /dev/null and b/drjava/extlib/sunec.jar differ diff --git a/drjava/extlib/sunjce_provider.jar b/drjava/extlib/sunjce_provider.jar new file mode 100644 index 000000000..a7b89cada Binary files /dev/null and b/drjava/extlib/sunjce_provider.jar differ diff --git a/drjava/extlib/sunpkcs11.jar b/drjava/extlib/sunpkcs11.jar new file mode 100644 index 000000000..d0dc4d992 Binary files /dev/null and b/drjava/extlib/sunpkcs11.jar differ diff --git a/drjava/lib/tools.jar b/drjava/extlib/tools.jar similarity index 95% rename from drjava/lib/tools.jar rename to drjava/extlib/tools.jar index f38baa1fb..f3a8ac5ff 100644 Binary files a/drjava/lib/tools.jar and b/drjava/extlib/tools.jar differ diff --git a/drjava/extlib/zipfs.jar b/drjava/extlib/zipfs.jar new file mode 100644 index 000000000..d0a9c5fca Binary files /dev/null and b/drjava/extlib/zipfs.jar differ diff --git a/drjava/lib/asm-6.0.jar b/drjava/lib/asm-6.0.jar deleted file mode 100644 index cf2de272c..000000000 Binary files a/drjava/lib/asm-6.0.jar and /dev/null differ diff --git a/drjava/lib/asm-9.6.jar b/drjava/lib/asm-9.6.jar new file mode 100644 index 000000000..cc1c2cd8e Binary files /dev/null and b/drjava/lib/asm-9.6.jar differ diff --git a/drjava/lib/asm-commons-6.0.jar b/drjava/lib/asm-commons-6.0.jar deleted file mode 100644 index 33ba0c463..000000000 Binary files a/drjava/lib/asm-commons-6.0.jar and /dev/null differ diff --git a/drjava/lib/asm-commons-9.6.jar b/drjava/lib/asm-commons-9.6.jar new file mode 100644 index 000000000..75f3bad86 Binary files /dev/null and b/drjava/lib/asm-commons-9.6.jar differ diff --git a/drjava/lib/asm-tree-6.0.jar b/drjava/lib/asm-tree-6.0.jar deleted file mode 100644 index 2aa9815c9..000000000 Binary files a/drjava/lib/asm-tree-6.0.jar and /dev/null differ diff --git a/drjava/lib/asm-tree-9.6.jar b/drjava/lib/asm-tree-9.6.jar new file mode 100644 index 000000000..9fe527587 Binary files /dev/null and b/drjava/lib/asm-tree-9.6.jar differ diff --git a/drjava/lib/buildlib/asm-commons-9.6.jar b/drjava/lib/buildlib/asm-commons-9.6.jar new file mode 100644 index 000000000..75f3bad86 Binary files /dev/null and b/drjava/lib/buildlib/asm-commons-9.6.jar differ diff --git a/drjava/lib/buildlib/asm-debug-all-5.0.2.jar b/drjava/lib/buildlib/asm-debug-all-5.0.2.jar new file mode 100644 index 000000000..834c9d09a Binary files /dev/null and b/drjava/lib/buildlib/asm-debug-all-5.0.2.jar differ diff --git a/drjava/lib/buildlib/bcel-6.0-SNAPSHOT.jar b/drjava/lib/buildlib/bcel-6.0-SNAPSHOT.jar new file mode 100644 index 000000000..11a974b28 Binary files /dev/null and b/drjava/lib/buildlib/bcel-6.0-SNAPSHOT.jar differ diff --git a/drjava/lib/buildlib/commons-lang-2.6.jar b/drjava/lib/buildlib/commons-lang-2.6.jar new file mode 100644 index 000000000..98467d3a6 Binary files /dev/null and b/drjava/lib/buildlib/commons-lang-2.6.jar differ diff --git a/drjava/lib/buildlib/dom4j-1.6.1.jar b/drjava/lib/buildlib/dom4j-1.6.1.jar new file mode 100644 index 000000000..c8c4dbb92 Binary files /dev/null and b/drjava/lib/buildlib/dom4j-1.6.1.jar differ diff --git a/drjava/lib/buildlib/findbugs-ant.jar b/drjava/lib/buildlib/findbugs-ant.jar index 5e917ba50..c2ad778a6 100644 Binary files a/drjava/lib/buildlib/findbugs-ant.jar and b/drjava/lib/buildlib/findbugs-ant.jar differ diff --git a/drjava/lib/buildlib/findbugs.jar b/drjava/lib/buildlib/findbugs.jar new file mode 100644 index 000000000..b86140266 Binary files /dev/null and b/drjava/lib/buildlib/findbugs.jar differ diff --git a/drjava/lib/buildlib/jFormatString.jar b/drjava/lib/buildlib/jFormatString.jar new file mode 100644 index 000000000..bdcb8466b Binary files /dev/null and b/drjava/lib/buildlib/jFormatString.jar differ diff --git a/drjava/lib/buildlib/jacocoagent.jar b/drjava/lib/buildlib/jacocoagent.jar new file mode 100644 index 000000000..9eedac24b Binary files /dev/null and b/drjava/lib/buildlib/jacocoagent.jar differ diff --git a/drjava/lib/buildlib/jacocoant.jar b/drjava/lib/buildlib/jacocoant.jar index 09d4a4796..38c956372 100644 Binary files a/drjava/lib/buildlib/jacocoant.jar and b/drjava/lib/buildlib/jacocoant.jar differ diff --git a/drjava/lib/buildlib/jaxen-1.1.6.jar b/drjava/lib/buildlib/jaxen-1.1.6.jar new file mode 100644 index 000000000..52f47a4f4 Binary files /dev/null and b/drjava/lib/buildlib/jaxen-1.1.6.jar differ diff --git a/drjava/lib/buildlib/jsr305.jar b/drjava/lib/buildlib/jsr305.jar new file mode 100644 index 000000000..cc39b7383 Binary files /dev/null and b/drjava/lib/buildlib/jsr305.jar differ diff --git a/drjava/lib/hamcrest-2.2.jar b/drjava/lib/hamcrest-2.2.jar new file mode 100644 index 000000000..71065788d Binary files /dev/null and b/drjava/lib/hamcrest-2.2.jar differ diff --git a/drjava/lib/hamcrest-core-1.3.jar b/drjava/lib/hamcrest-core-1.3.jar deleted file mode 100644 index 9d5fe16e3..000000000 Binary files a/drjava/lib/hamcrest-core-1.3.jar and /dev/null differ diff --git a/drjava/lib/javalanglevels-base.jar b/drjava/lib/javalanglevels-base.jar index 3c6925ebb..6b01892cc 100644 Binary files a/drjava/lib/javalanglevels-base.jar and b/drjava/lib/javalanglevels-base.jar differ diff --git a/drjava/lib/junit.jar b/drjava/lib/junit.jar index acc3c4320..6da55d8b8 100644 Binary files a/drjava/lib/junit.jar and b/drjava/lib/junit.jar differ diff --git a/drjava/lib/org.jacoco.core-0.8.0.201801022044.jar b/drjava/lib/org.jacoco.core-0.8.0.201801022044.jar deleted file mode 100644 index 55335c21d..000000000 Binary files a/drjava/lib/org.jacoco.core-0.8.0.201801022044.jar and /dev/null differ diff --git a/drjava/lib/org.jacoco.core-0.8.11.202310140853.jar b/drjava/lib/org.jacoco.core-0.8.11.202310140853.jar new file mode 100644 index 000000000..732e29681 Binary files /dev/null and b/drjava/lib/org.jacoco.core-0.8.11.202310140853.jar differ diff --git a/drjava/lib/org.jacoco.report-0.8.0.201801022044.jar b/drjava/lib/org.jacoco.report-0.8.0.201801022044.jar deleted file mode 100644 index f02e4a5e3..000000000 Binary files a/drjava/lib/org.jacoco.report-0.8.0.201801022044.jar and /dev/null differ diff --git a/drjava/lib/org.jacoco.report-0.8.11.202310140853.jar b/drjava/lib/org.jacoco.report-0.8.11.202310140853.jar new file mode 100644 index 000000000..e7a744062 Binary files /dev/null and b/drjava/lib/org.jacoco.report-0.8.11.202310140853.jar differ diff --git a/drjava/lib/platform.jar b/drjava/lib/platform.jar index f58174143..610ab4f40 100644 Binary files a/drjava/lib/platform.jar and b/drjava/lib/platform.jar differ diff --git a/drjava/src/edu/rice/cs/drjava/DrJavaRoot.java b/drjava/src/edu/rice/cs/drjava/DrJavaRoot.java index 90463cce4..16526258b 100644 --- a/drjava/src/edu/rice/cs/drjava/DrJavaRoot.java +++ b/drjava/src/edu/rice/cs/drjava/DrJavaRoot.java @@ -260,7 +260,7 @@ private static void _openCommandLineFiles(final MainFrame mf, String[] filesToOp }; try { if (isProjectFile) mf.openProject(command); - else if (currFileName.endsWith(OptionConstants.EXTPROCESS_FILE_EXTENSION)) MainFrame.openExtProcessFile(file); +// else if (currFileName.endsWith(OptionConstants.EXTPROCESS_FILE_EXTENSION)) MainFrame.openExtProcessFile(file); else { if (jump && (lineNo >= 0)) { /* if a line number has been specified, open the file using MainFrame.open and jump to lineNo using diff --git a/drjava/src/edu/rice/cs/drjava/config/DrJavaPropertySetupTest.java b/drjava/src/edu/rice/cs/drjava/config/DrJavaPropertySetupTest.java index f962688db..1556b435b 100644 --- a/drjava/src/edu/rice/cs/drjava/config/DrJavaPropertySetupTest.java +++ b/drjava/src/edu/rice/cs/drjava/config/DrJavaPropertySetupTest.java @@ -949,8 +949,8 @@ public void testMisc() throws CloneNotSupportedException { // process.separator p = pm.getProperty("Config","process.separator"); - // enclosing.djapp.file - p = pm.getProperty("Misc","enclosing.djapp.file"); +// // enclosing.djapp.file +// p = pm.getProperty("Misc","enclosing.djapp.file"); // drjava.file // during testing, this is the classes/base directory diff --git a/drjava/src/edu/rice/cs/drjava/config/OptionConstants.java b/drjava/src/edu/rice/cs/drjava/config/OptionConstants.java index 71abf2d28..2ba932770 100644 --- a/drjava/src/edu/rice/cs/drjava/config/OptionConstants.java +++ b/drjava/src/edu/rice/cs/drjava/config/OptionConstants.java @@ -79,8 +79,8 @@ public interface OptionConstants { /** The alternative extension for a DrJava project file */ public static final String PROJECT_FILE_EXTENSION2 = ".xml"; - /** The extension for stand-alone DrJava external process file. */ - public static final String EXTPROCESS_FILE_EXTENSION = ".djapp"; +// /** The extension for stand-alone DrJava external process file. */ +// public static final String EXTPROCESS_FILE_EXTENSION = ".djapp"; /** The extension for a Java source file */ public static final String JAVA_FILE_EXTENSION = ".java"; @@ -112,8 +112,8 @@ public interface OptionConstants { OLD_DJ2_FILE_EXTENSION, // = .dj2 DJ_FILE_EXTENSION }; // = .dj - /** The configuration XML file that DrJava looks for inside a .djapp file */ - public static final String EXTPROCESS_FILE_NAME_INSIDE_JAR = "process" + EXTPROCESS_FILE_EXTENSION; +// /** The configuration XML file that DrJava looks for inside a .djapp file */ +// public static final String EXTPROCESS_FILE_NAME_INSIDE_JAR = "process" + EXTPROCESS_FILE_EXTENSION; /** The extension for a text file */ public static final String TEXT_FILE_EXTENSION = ".txt"; @@ -303,7 +303,9 @@ static class LookAndFeels { /** @return the look-and-feel class name to use by default */ public static String getDefaultLookAndFeel() { if (PlatformFactory.ONLY.isMacPlatform()) - return UIManager.getSystemLookAndFeelClassName(); // Mac: Let the system decide. + return "javax.swing.plaf.nimbus.NimbusLookAndFeel"; + // TODO: fix this up to work with the proper look and feel -> Mac was causing problems +// return UIManager.getSystemLookAndFeelClassName(); // Mac: Let the system decide. else // Set CrossPlatform "Nimbus" LookAndFeel try { for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) @@ -1797,11 +1799,11 @@ public static ArrayList evaluate() { new StringOption("",""), new Vector()); - /** The script file (or "" if none) of saved external processes. */ - public static final VectorOption EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES = - new VectorOption(EXTERNAL_SAVED_PREFIX + "enclosingdjappfiles", - new StringOption("",""), - new Vector()); +// /** The script file (or "" if none) of saved external processes. */ +// public static final VectorOption EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES = +// new VectorOption(EXTERNAL_SAVED_PREFIX + "enclosingdjappfiles", +// new StringOption("",""), +// new Vector()); /** Notification of new versions. */ public static final ArrayList NEW_VERSION_NOTIFICATION_CHOICES = diff --git a/drjava/src/edu/rice/cs/drjava/model/AbstractGlobalModel.java b/drjava/src/edu/rice/cs/drjava/model/AbstractGlobalModel.java index 67df370c6..6f9ffdb70 100644 --- a/drjava/src/edu/rice/cs/drjava/model/AbstractGlobalModel.java +++ b/drjava/src/edu/rice/cs/drjava/model/AbstractGlobalModel.java @@ -364,7 +364,8 @@ public void optionChanged(OptionEvent oce) { // ----- STATE ----- - /** Specifies the state of the navigator pane. The global model delegates the compileAll command to the _state. + /** Specifies the state of the navigator pane. + * The global model delegates the compileAll command to the _state. * FileGroupingState synchronization is handled by the compilerModel (??). */ protected volatile FileGroupingState _state; @@ -3474,40 +3475,44 @@ private File _locateClassFile() { _log.log("_locateClassFile() failed for " + this + " because getQualifedClassName returned ClassNotFound"); return FileOps.NULL_FILE; /* No source class name */ } -// _log.log("In _locateClassFile, className = " + className); + _log.log("In _locateClassFile, className = " + className); String ps = System.getProperty("file.separator"); // replace periods with the System's file separator className = StringOps.replace(className, ".", ps); String fileName = className + ".class"; -// _log.log("In _locateClassFile, classfileName = " + fileName); + _log.log("In _locateClassFile, classfileName = " + fileName); // Check source root set (open files) ArrayList roots = new ArrayList(); -// _log.log("build directory = " + getBuildDirectory()); + File bd = getBuildDirectory(); - if (getBuildDirectory() != FileOps.NULL_FILE) roots.add(getBuildDirectory()); + _log.log("build directory = " + bd); - // Add the current document to the beginning of the roots list + // Place the build directory at the front of the roots list + if (bd != FileOps.NULL_FILE) roots.add(getBuildDirectory()); + + // Add the current document to the end (formerly beginning) of the roots list; in the command line class file + // layout, class files reside in same directory as corresponding source files. try { File root = getSourceRoot(); -// _log.log("Directory " + root + " added to list of source roots"); - roots.add(root); + _log.log("Directory " + root + " added to list of class file roots"); + if (! roots.contains(root)) roots.add(root); } catch (InvalidPackageException ipe) { try { -// _log.log(this + " has no source root, using parent directory instead"); + _log.log(this + " has no source root, using parent directory of this source document instead"); File root = getFile().getParentFile(); if (root != FileOps.NULL_FILE) { roots.add(root); -// _log.log("Added parent directory " + root + " to list of source roots"); + _log.log("Added parent directory " + root + " to list of class file roots"); } } catch(NullPointerException e) { throw new UnexpectedException(e); } catch(FileMovedException fme) { // Moved, but we'll add the old file to the set anyway - _log.log("File for " + this + "has moved; adding parent directory to list of roots"); + _log.log("File for " + this + "has moved; adding parent directory of this source document instead"); File root = fme.getFile().getParentFile(); if (root != FileOps.NULL_FILE) roots.add(root); } @@ -3515,11 +3520,11 @@ private File _locateClassFile() { File classFile = findFileInPaths(fileName, roots); if (classFile != FileOps.NULL_FILE) { -// _log.log("Found source file " + classFile + " for " + this); + _log.log("Found class file " + classFile + " for " + this); return classFile; } -// _log.log(this + " not found on path of source roots"); + _log.log(fileName + " not found on list of class file roots"); // Class not on source root set, check system classpath classFile = findFileInPaths(fileName, ReflectUtil.SYSTEM_CLASS_PATH); diff --git a/drjava/src/edu/rice/cs/drjava/model/BrowserHistoryManager.java b/drjava/src/edu/rice/cs/drjava/model/BrowserHistoryManager.java index 4656a0ceb..5a224f672 100644 --- a/drjava/src/edu/rice/cs/drjava/model/BrowserHistoryManager.java +++ b/drjava/src/edu/rice/cs/drjava/model/BrowserHistoryManager.java @@ -140,7 +140,7 @@ private void shrinkManager() { } /** Remove the last region from the given stack and clean up. - * @param stack the non-empty ArrayDeque() to be shrunk. + * @param stack the non-empty ArrayDeque to be shrunk. */ public void removeLast(final ArrayDeque stack) { assert ! stack.isEmpty(); diff --git a/drjava/src/edu/rice/cs/drjava/model/DefaultGlobalModel.java b/drjava/src/edu/rice/cs/drjava/model/DefaultGlobalModel.java index da9f2a3c7..1c7aaca29 100644 --- a/drjava/src/edu/rice/cs/drjava/model/DefaultGlobalModel.java +++ b/drjava/src/edu/rice/cs/drjava/model/DefaultGlobalModel.java @@ -44,9 +44,7 @@ import edu.rice.cs.drjava.config.BooleanOption; import edu.rice.cs.drjava.model.FileSaveSelector; import edu.rice.cs.drjava.model.JDKDescriptor; -import edu.rice.cs.drjava.model.compiler.DummyCompilerListener; -//import edu.rice.cs.drjava.model.compiler.EclipseCompiler; -//import edu.rice.cs.drjava.model.compiler.descriptors.EclipseDescriptor; +import edu.rice.cs.drjava.model.compiler.*; import edu.rice.cs.drjava.model.definitions.ClassNameNotFoundException; import edu.rice.cs.drjava.model.definitions.InvalidPackageException; import edu.rice.cs.drjava.model.debug.Breakpoint; @@ -65,10 +63,6 @@ import edu.rice.cs.drjava.model.repl.InteractionsListener; import edu.rice.cs.drjava.model.repl.InteractionsScriptModel; import edu.rice.cs.drjava.model.repl.newjvm.MainJVM; -import edu.rice.cs.drjava.model.compiler.CompilerListener; -import edu.rice.cs.drjava.model.compiler.CompilerModel; -import edu.rice.cs.drjava.model.compiler.DefaultCompilerModel; -import edu.rice.cs.drjava.model.compiler.CompilerInterface; import edu.rice.cs.drjava.model.junit.DefaultJUnitModel; import edu.rice.cs.drjava.model.junit.JUnitModel; @@ -79,10 +73,10 @@ import edu.rice.cs.plt.reflect.ReflectUtil; import edu.rice.cs.plt.tuple.Pair; +import edu.rice.cs.util.AbsRelFile; import edu.rice.cs.util.FileOpenSelector; import edu.rice.cs.util.FileOps; import edu.rice.cs.util.NullFile; -import edu.rice.cs.util.AbsRelFile; import edu.rice.cs.util.OperationCanceledException; import edu.rice.cs.util.UnexpectedException; import edu.rice.cs.util.swing.Utilities; @@ -185,18 +179,23 @@ public void activeCompilerChanged() { /* CONSTRUCTORS */ /** Constructs a new GlobalModel. Creates a new MainJVM and starts its Interpreter JVM. */ public DefaultGlobalModel() { - Iterable tools = findLibraries(); + Iterable tools = findLibraries(); // findLibraries should be called findTools List compilers = new LinkedList(); - + + // TODO: should this be done a different way? + JavaxToolsCompiler javaxCompiler = new JavaxToolsCompiler(); + compilers.add(javaxCompiler); + /* Note: the only debugger used in DrJava is JPDADebugger in the DrJava code base which relies * on machinery provided by the tools.jar library included in every Java JDK (up through JDK 8). A copy of the * tools.jar library from Java 8 Open JDK is included in the drjava.jar file. */ _debugger = null; _javadocModel = null; + /* Gather tools: a list compilers, a debugger, and a javadoc tool. */ for (JDKToolsLibrary t : tools) { // Utilities.show("Found tools.jar library: " + t); - if (t.compiler().isAvailable() && t.version().supports(JavaVersion.JAVA_7)) compilers.add(t.compiler()); + if (t.compiler().isAvailable() && t.version().supports(JavaVersion.JAVA_8)) compilers.add(t.compiler()); if (_debugger == null && t.debugger().isAvailable()) { _debugger = t.debugger(); } if (_javadocModel == null && t.javadoc().isAvailable()) { _javadocModel = t.javadoc(); } } @@ -205,7 +204,7 @@ public DefaultGlobalModel() { File workDir = Utilities.TEST_MODE ? new File(System.getProperty("user.home")) : getWorkingDirectory(); _jvm = new MainJVM(workDir); -// AbstractMasterJVM._log.log(this + " has created a new MainJVM"); + _log.log(this + " has created a new MainJVM"); _compilerModel = new DefaultCompilerModel(this, compilers); _junitModel = new DefaultJUnitModel(_jvm, _compilerModel, this); _interactionsDocument = new InteractionsDJDocument(_notifier); diff --git a/drjava/src/edu/rice/cs/drjava/model/GlobalModelCompileErrorsTest.java b/drjava/src/edu/rice/cs/drjava/model/GlobalModelCompileErrorsTest.java index a13c408e3..6cf222f49 100644 --- a/drjava/src/edu/rice/cs/drjava/model/GlobalModelCompileErrorsTest.java +++ b/drjava/src/edu/rice/cs/drjava/model/GlobalModelCompileErrorsTest.java @@ -331,7 +331,7 @@ public void testCompileFailsCorrectLineNumbers() throws BadLocationException, IO Position p1 = cme.getPosition(ce1); Position p2 = cme.getPosition(ce2); assertTrue("location of first error should be between 20 and 29 inclusive (line 2), but was " + p1.getOffset(), - p1.getOffset() <= 20 && p1.getOffset() <= 29); + p1.getOffset() >= 20 && p1.getOffset() <= 29); assertTrue("location of error should be after 34 (line 3 or 4)", p2.getOffset() >= 34); debug.logEnd(); diff --git a/drjava/src/edu/rice/cs/drjava/model/JDKDescriptor.java b/drjava/src/edu/rice/cs/drjava/model/JDKDescriptor.java index 25020324c..b45915f03 100644 --- a/drjava/src/edu/rice/cs/drjava/model/JDKDescriptor.java +++ b/drjava/src/edu/rice/cs/drjava/model/JDKDescriptor.java @@ -40,8 +40,7 @@ import edu.rice.cs.plt.iter.IterUtil; /** A description of a JDK. - * Put subclasses of JDKDescriptor in the edu.rice.cs.drjava.model.compiler.descriptors package for DrJava - * to find. */ + * Put subclasses of JDKDescriptor in the edu.rice.cs.drjava.model.compiler.descriptors package for DrJava to find. */ public abstract class JDKDescriptor { /** Return the name of this JDK. * @return name */ @@ -181,7 +180,7 @@ public String getAdapterForDebugger(JavaVersion.FullVersion guessedVersion) { return JDKToolsLibrary.adapterForDebugger(guessedVersion); } public boolean containsCompiler(File f) { return true; } - public JavaVersion getMinimumMajorVersion() { return JavaVersion.JAVA_7; } + public JavaVersion getMinimumMajorVersion() { return JavaVersion.JAVA_8; } public Iterable getAdditionalCompilerFiles(File compiler) throws FileNotFoundException { return IterUtil.empty(); } diff --git a/drjava/src/edu/rice/cs/drjava/model/JDKToolsLibrary.java b/drjava/src/edu/rice/cs/drjava/model/JDKToolsLibrary.java index 2dc01eeb2..be2b40067 100644 --- a/drjava/src/edu/rice/cs/drjava/model/JDKToolsLibrary.java +++ b/drjava/src/edu/rice/cs/drjava/model/JDKToolsLibrary.java @@ -94,32 +94,36 @@ public boolean isValid() { public String toString() { return _jdkDescriptor.getDescription(_version); } - public static String adapterForCompiler(JavaVersion.FullVersion version) { - switch (version.majorVersion()) { - case FUTURE: return "edu.rice.cs.drjava.model.compiler.Javac170Compiler"; - case JAVA_8: return "edu.rice.cs.drjava.model.compiler.Javac170Compiler"; - case JAVA_7: return "edu.rice.cs.drjava.model.compiler.Javac170Compiler"; - case JAVA_6: { - switch (version.vendor()) { - case OPENJDK: return "edu.rice.cs.drjava.model.compiler.Javac160OpenJDKCompiler"; - case UNKNOWN: return null; - default: return "edu.rice.cs.drjava.model.compiler.Javac160Compiler"; - } - } - case JAVA_5: return "edu.rice.cs.drjava.model.compiler.Javac150Compiler"; - default: return null; - } + public static String adapterForCompiler(JavaVersion.FullVersion version) { + return "edu.rice.cs.drjava.model.compiler.Javac170Compiler"; + /* formerly the following */ +// switch (version.majorVersion()) { +// case FUTURE: return "edu.rice.cs.drjava.model.compiler.Javac170Compiler"; +// case JAVA_8: return "edu.rice.cs.drjava.model.compiler.Javac170Compiler"; +// case JAVA_7: return "edu.rice.cs.drjava.model.compiler.Javac170Compiler"; +// case JAVA_6: { +// switch (version.vendor()) { +// case OPENJDK: return "edu.rice.cs.drjava.model.compiler.Javac160OpenJDKCompiler"; +// case UNKNOWN: return null; +// default: return "edu.rice.cs.drjava.model.compiler.Javac160Compiler"; +// } +// } +// case JAVA_5: return "edu.rice.cs.drjava.model.compiler.Javac150Compiler"; +// default: return null; +// } } - public static String adapterForDebugger(JavaVersion.FullVersion version) { - switch (version.majorVersion()) { - case FUTURE: - case JAVA_8: - case JAVA_7: - case JAVA_6: - case JAVA_5: return "edu.rice.cs.drjava.model.debug.jpda.JPDADebugger"; - default: return null; - } + public static String adapterForDebugger(JavaVersion.FullVersion version) { + return "edu.rice.cs.drjava.model.debug.jpda.JPDADebugger"; + /* formerly */ +// switch (version.majorVersion()) { +// case FUTURE: +// case JAVA_8: +// case JAVA_7: +// case JAVA_6: +// case JAVA_5: return "edu.rice.cs.drjava.model.debug.jpda.JPDADebugger"; +// default: return null; +// } } protected static CompilerInterface getCompilerInterface(String className, FullVersion version) { diff --git a/drjava/src/edu/rice/cs/drjava/model/JarJDKToolsLibrary.java b/drjava/src/edu/rice/cs/drjava/model/JarJDKToolsLibrary.java index f11e6866f..e0f073ba0 100644 --- a/drjava/src/edu/rice/cs/drjava/model/JarJDKToolsLibrary.java +++ b/drjava/src/edu/rice/cs/drjava/model/JarJDKToolsLibrary.java @@ -416,7 +416,7 @@ protected static LinkedHashMap> getDefaultSearchRoots() String envJavaHome = null; String programFiles = null; String systemDrive = null; - if (JavaVersion.CURRENT.supports(JavaVersion.JAVA_7)) { /* formerly JavaVersion.JAVA_5 */ + if (JavaVersion.CURRENT.supports(JavaVersion.JAVA_8)) { /* formerly JavaVersion.JAVA_5 and later JavaVersion.JAVA_7 */ // System.getenv is deprecated under 1.3 and 1.4, and may throw a java.lang.Error (!), // which we'd rather not have to catch envJavaHome = System.getenv("JAVA_HOME"); @@ -446,44 +446,47 @@ protected static LinkedHashMap> getDefaultSearchRoots() addIfDir(new File(programFiles), roots); } - /* The following two lines were added to support OpenJDK8 on Windows 10. */ + /* The following three lines were added to support OpenJDK8 on Windows 10/11. */ addIfDir(new File("/C:/Program Files/Zulu/zulu-8"), roots); addIfDir(new File("/C:/Program Files (x86)/Zulu/zulu-8"), roots); + addIfDir(new File("/C:/Program Files/Amazon Corretto"), roots); addIfDir(new File("/C:/Program Files/Java"), roots); addIfDir(new File("/C:/Program Files (x86)/Java"), roots); - addIfDir(new File("/C:/Program Files"), roots); - addIfDir(new File("/C:/Program Files (x86)"), roots); +// addIfDir(new File("/C:/Program Files"), roots); +// addIfDir(new File("/C:/Program Files (x86)"), roots); if (systemDrive != null) { addIfDir(new File(systemDrive, "Java"), roots); addIfDir(new File(systemDrive), roots); } - addIfDir(new File("/C:/Java"), roots); - addIfDir(new File("/C:"), roots); +// addIfDir(new File("/C:/Java"), roots); +// addIfDir(new File("/C:"), roots); /* Entries for Mac OS X */ addIfDir(new File("/System/Library/Java/JavaVirtualMachines"), roots); addIfDir(new File("/Library/Java/JavaVirtualMachines"), roots); // addIfDir(new File("/System/Library/Java/JavaVirtualMachines"), roots); - /* Entries for Linux */ - addIfDir(new File("/usr/java"), roots); - addIfDir(new File("/usr/j2se"), roots); - addIfDir(new File("/usr"), roots); - addIfDir(new File("/usr/local/java"), roots); - addIfDir(new File("/usr/local/j2se"), roots); - addIfDir(new File("/usr/local"), roots); +// /* Entries for Linux */ +// addIfDir(new File("/usr/java"), roots); +// addIfDir(new File("/usr/j2se"), roots); +// addIfDir(new File("/usr"), roots); +// addIfDir(new File("/usr/local/java"), roots); +// addIfDir(new File("/usr/local/j2se"), roots); +// addIfDir(new File("/usr/local"), roots); /* Entries for Linux java packages */ addIfDir(new File("/usr/lib/jvm"), roots); addIfDir(new File("/usr/lib/jvm/java-8-oracle"), roots); addIfDir(new File("/usr/lib/jvm/java-8-openjdk"), roots); - addIfDir(new File("/usr/lib/jvm/java-7-oracle"), roots); - addIfDir(new File("/usr/lib/jvm/java-7-openjdk"), roots); - addIfDir(new File("/usr/lib/jvm/java-6-sun"), roots); - addIfDir(new File("/usr/lib/jvm/java-6-openjdk"), roots); - addIfDir(new File("/usr/lib/jvm/java-1.5.0-sun"), roots); + + /* Legacy versions of Java -- no longer supported */ +// addIfDir(new File("/usr/lib/jvm/java-7-oracle"), roots); +// addIfDir(new File("/usr/lib/jvm/java-7-openjdk"), roots); +// addIfDir(new File("/usr/lib/jvm/java-6-sun"), roots); +// addIfDir(new File("/usr/lib/jvm/java-6-openjdk"), roots); +// addIfDir(new File("/usr/lib/jvm/java-1.5.0-sun"), roots); // addIfDir(new File("/home/javaplt/java/Linux-i686"), roots); diff --git a/drjava/src/edu/rice/cs/drjava/model/compiler/CompilerInterface.java b/drjava/src/edu/rice/cs/drjava/model/compiler/CompilerInterface.java index 763b87377..40c850d19 100644 --- a/drjava/src/edu/rice/cs/drjava/model/compiler/CompilerInterface.java +++ b/drjava/src/edu/rice/cs/drjava/model/compiler/CompilerInterface.java @@ -81,8 +81,7 @@ List compile(List files, List /** @return string to display in a combo box (generally {@code getName()}) */ String toString(); - /** A compiler can instruct DrJava to include additional elements for the boot - * class path of the Interactions JVM. + /** A compiler can instruct DrJava to include additional elements for the boot class path of the Interactions JVM. * @return list of files on the class path */ List additionalBootClassPathForInteractions(); diff --git a/drjava/src/edu/rice/cs/drjava/model/compiler/JavacCompiler.java b/drjava/src/edu/rice/cs/drjava/model/compiler/JavacCompiler.java index 3b8a73496..9b6ad5740 100644 --- a/drjava/src/edu/rice/cs/drjava/model/compiler/JavacCompiler.java +++ b/drjava/src/edu/rice/cs/drjava/model/compiler/JavacCompiler.java @@ -59,12 +59,10 @@ public abstract class JavacCompiler implements CompilerInterface { /** The set of class names that are run as ACM Java Task Force library programs. */ protected static final Set ACM_PROGRAM_CLASSES = new HashSet(); static { - Collections.addAll(ACM_PROGRAM_CLASSES, new String[] { - "acm.program.Program", - "acm.graphics.GTurtle" - }); + Collections.addAll(ACM_PROGRAM_CLASSES, new String[] {"acm.program.Program", "acm.graphics.GTurtle"}); } + /** Standard Constructor */ protected JavacCompiler(JavaVersion.FullVersion version, String location, List defaultBootClassPath) { _version = version; _location = location; diff --git a/drjava/src/edu/rice/cs/drjava/model/compiler/JavaxToolsCompiler.java b/drjava/src/edu/rice/cs/drjava/model/compiler/JavaxToolsCompiler.java new file mode 100644 index 000000000..963910832 --- /dev/null +++ b/drjava/src/edu/rice/cs/drjava/model/compiler/JavaxToolsCompiler.java @@ -0,0 +1,435 @@ +package edu.rice.cs.drjava.model.compiler; + +import edu.rice.cs.drjava.DrJava; +import edu.rice.cs.drjava.config.OptionConstants; +import edu.rice.cs.drjava.model.DJError; +import edu.rice.cs.drjava.model.DrJavaFileUtils; +import edu.rice.cs.drjava.ui.SmartSourceFilter; +import edu.rice.cs.plt.reflect.JavaVersion; +import edu.rice.cs.util.ArgumentTokenizer; + +import javax.swing.filechooser.FileFilter; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.util.*; +import javax.tools.*; /* including ToolProvider, StandardLocation, DiagnosticCollector */ + +/** The CompilerInterface for the javax.tools compiler embedded in the executing JVM. + * Manages the auxiliary naming methods.(?) + */ + +public class JavaxToolsCompiler implements CompilerInterface { + /** The set of class names that are run as ACM Java Task Force library programs. */ + protected static final Set ACM_PROGRAM_CLASSES = new HashSet(); + static { + Collections.addAll(ACM_PROGRAM_CLASSES, new String[] {"acm.program.Program", "acm.graphics.GTurtle"}); + } + private final JavaCompiler compiler; + + /** Standard Constructor */ + public JavaxToolsCompiler() { this.compiler = ToolProvider.getSystemJavaCompiler(); } + + public boolean isAvailable() { return this.compiler != null; } + + public List compile(List files, List classPath, + List sourcePath, File destination, + List bootClassPath, String sourceVersion, boolean showWarnings) { + // Check if compiler is available + if (compiler == null) { + List errors = new ArrayList<>(); + errors.add(new DJError("The SystemJavaCompiler is not available", false)); + return errors; + } + + // Set up the file manager + StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); + + // Set the classpath, source path, and bootclasspath + try { + if (classPath != null) { + fileManager.setLocation(StandardLocation.CLASS_PATH, classPath); + } + if (sourcePath != null) { + fileManager.setLocation(StandardLocation.SOURCE_PATH, sourcePath); + } + if (bootClassPath != null) { + fileManager.setLocation(StandardLocation.PLATFORM_CLASS_PATH, bootClassPath); + } + } catch (IOException e) { + List errors = new ArrayList<>(); + errors.add(new DJError("Error setting paths: " + e.getMessage(), false)); + return errors; + } + + // Convert files to a format the compiler understands + Iterable compilationUnits = fileManager.getJavaFileObjectsFromFiles(files); + + // Prepare the compilation options + /* Question (by Corky): is the "-source" option necessary? The JavaxTools compiler is part of the executing JVM. */ + List optionList = new ArrayList<>(); + if (sourceVersion != null) { + optionList.add("-source"); + optionList.add(sourceVersion); + } + if (destination != null) { + try { + fileManager.setLocation(StandardLocation.CLASS_OUTPUT, Collections.singletonList(destination)); + } catch (IOException e) { + List errors = new ArrayList<>(); + errors.add(new DJError("Error setting build directory: " + e.getMessage(), false)); + return errors; + } + // This doesn't work for javax.tools compiler + // optionList.add("-d"); + // optionList.add(destination.getAbsolutePath()); + } + + // Prepare a diagnostic collector to collect compile errors + DiagnosticCollector diagnostics = new DiagnosticCollector<>(); + + // Create a compilation task + JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics, optionList, null, compilationUnits); + + // Perform the compile task + boolean success = task.call(); + + // Process diagnostics to create DJError list + List errors = new ArrayList<>(); + for (Diagnostic diagnostic : diagnostics.getDiagnostics()) { + DJError error = new DJError(new File(diagnostic.getSource().toUri()), + (int) diagnostic.getLineNumber() - 1, // DJError adds 1 to this number. + (int) diagnostic.getColumnNumber() - 1, // Fixes the cursor position offset. + diagnostic.getMessage(null), + diagnostic.getKind() == Diagnostic.Kind.ERROR); + errors.add(error); + } + + // If compilation failed and no errors were reported, add a generic error message + if (!success && errors.isEmpty()) { + errors.add(new DJError("Compilation failed with unknown error", true)); + } + + return errors; + } + /* Question (Corky): Shouldn't we retreive the version of this System (JVM). */ + public JavaVersion version() { return JavaVersion.JAVA_8; } + + public String getName() { return "javax.tools"; } + + public String getDescription() { return "Standard compiler in javax.tools"; } + + public String toString() { return getName(); } + + public List additionalBootClassPathForInteractions() { return Collections.emptyList(); } + + /** Transform the command line to be interpreted into something the Interactions JVM can use. + * This replaces "java MyClass a b c" with Java code to call MyClass.main(new String[]{"a","b","c"}). + * "import MyClass" is not handled here. + * transformCommands should support at least "run", "java" and "applet". + * @param interactionsString unprocessed command line + * @return command line with commands transformed */ + public String transformCommands(String interactionsString) { + if (interactionsString.startsWith("java ")) { + interactionsString = transformJavaCommand(interactionsString); + } + else if (interactionsString.startsWith("applet ")) { + interactionsString = transformAppletCommand(interactionsString); + } + else if (interactionsString.startsWith("run ")) { + interactionsString = transformRunCommand(interactionsString); + } + return interactionsString; + } + + public static String transformJavaCommand(String s) { + // check the return type and public access before executing, per bug #1585210 + String command = + "try '{'\n" + + " java.lang.reflect.Method m = {0}.class.getMethod(\"main\", java.lang.String[].class);\n" + + " if (!m.getReturnType().equals(void.class)) throw new java.lang.NoSuchMethodException();\n" + + "'}'\n" + + "catch (java.lang.NoSuchMethodException e) '{'\n" + + " throw new java.lang.NoSuchMethodError(\"main\");\n" + + "'}'\n" + + "{0}.main(new String[]'{'{1}'}');"; + return _transformCommand(s, command); + } + + public static String transformAppletCommand(String s) { + return _transformCommand(s,"edu.rice.cs.plt.swing.SwingUtil.showApplet(new {0}({1}), 400, 300);"); + } + + /** This method performs the "smart run". Unfortunately, we don't get the right static error messages. + * @param s full command line, i.e. "run MyClass 1 2 3" + * @param c class to be run, i.e. MyClass.class + * @throws Throwable if something goes wrong + */ + public static void runCommand(String s, Class c) throws Throwable { + if (s.endsWith(";")) s = _deleteSemiColon(s); + List tokens = ArgumentTokenizer.tokenize(s, true); + String[] args = new String[tokens.size() - 2]; + for (int i = 2; i < tokens.size(); i++) { + String t = tokens.get(i); + args[i - 2] = t.substring(1, t.length() - 1); + } + + boolean isProgram = false; + boolean isApplet = false; + Class oldC = c; + while(c != null) { + if (ACM_PROGRAM_CLASSES.contains(c.getName())) { isProgram = true; break; } + c = c.getSuperclass(); + } + c = oldC; + if (!isProgram) { + try { + // if this doesn't throw, c is a subclass of Applet + c.asSubclass(java.applet.Applet.class); + isApplet = true; + } catch(ClassCastException cce) { } + } + + java.lang.reflect.Method m = null; + if (isApplet) { + try { + m = c.getMethod("main", java.lang.String[].class); + if (!m.getReturnType().equals(void.class)) { m = null; } + } + catch (java.lang.NoSuchMethodException e) { m = null; } + if (m == null) { + java.applet.Applet instance = null; + if (args.length == 0) { + try { + // try default (nullary) constructor first + Constructor ctor = c.getConstructor(); + instance = java.applet.Applet.class.cast(ctor.newInstance()); + } + catch(NoSuchMethodException | InstantiationException | IllegalAccessException nsme) { + instance = null; + } + catch(java.lang.reflect.InvocationTargetException ite) { + if (ite.getCause()!=null) { + throw ite.getCause(); + } + else { + System.err.println("Error: Please turn off 'Smart Run' or use 'java' command instead of 'run'."); + } + } + if (instance == null) { + try { + // try String[] constructor next + Constructor ctor = c.getConstructor(String[].class); + instance = java.applet.Applet.class.cast(ctor.newInstance(new Object[] { new String[0] })); + } + catch(NoSuchMethodException | InstantiationException | IllegalAccessException nsme) { + instance = null; + } + catch(java.lang.reflect.InvocationTargetException ite) { + if (ite.getCause()!=null) { + throw ite.getCause(); + } + else { + System.err.println("Error: Please turn off 'Smart Run' or use 'java' command instead of 'run'."); + return; + } + } + } + if (instance == null) { + System.err.println("Static Error: This applet does not have a default constructor or a constructor "+ + "accepting String[]."); + return; + } + } + else { + try { + // try String[] constructor + Constructor ctor = c.getConstructor(String[].class); + instance = java.applet.Applet.class.cast(ctor.newInstance(new Object[] { args })); + } + catch(NoSuchMethodException | InstantiationException | IllegalAccessException nsme) { + instance = null; + } + catch(java.lang.reflect.InvocationTargetException ite) { + if (ite.getCause()!=null) { + throw ite.getCause(); + } + else { + System.err.println("Error: Please turn off 'Smart Run' or use 'java' command instead of 'run'."); + return; + } + } + if (instance == null) { + System.err.println("Static Error: This applet does not have a constructor accepting String[]."); + return; + } + } + edu.rice.cs.plt.swing.SwingUtil.showApplet(instance, 400, 300); + } + } + else { + try { + m = c.getMethod("main", java.lang.String[].class); + if (!m.getReturnType().equals(void.class)) { + System.err.println("Static Error: This class does not have a static void main method accepting String[]."); + m = null; + } + } + catch (java.lang.NoSuchMethodException e) { + System.err.println("Static Error: This class does not have a static void main method accepting String[]."); + m = null; + } + } + if (m != null) { + if (isProgram) { + String[] newArgs = new String[args.length+1]; + newArgs[0] = "code="+c.getName(); + System.arraycopy(args, 0, newArgs, 1, args.length); + args = newArgs; + } + try { + m.setAccessible(true); + m.invoke(null, new Object[] { args }); + } + catch(SecurityException | IllegalAccessException se) { + System.err.println("Error: Please turn off 'Smart Run' or use 'java' command instead of 'run'."); + } + catch(java.lang.reflect.InvocationTargetException ite) { + if (ite.getCause()!=null) { + throw ite.getCause(); + } + else { + System.err.println("Error: Please turn off 'Smart Run' or use 'java' command instead of 'run'."); + } + } + } + } + + /** This is a method that automatically detects if + * a) the class is an ACM Java Task Force program (subclass of acm.program.Program) + * b) an applet + * c) a class with a static main method + * + * If a), then DrJava inserts "code=MyClass" as argument 0. + * If b), then DrJava performs the same as "applet MyClass" (see above). + * If c), then DrJava executes MyClass.main (traditional java behavior). + * + * @param s the command to be transformed + * @return the transformed command + */ + public String transformRunCommand(String s) { + if (s.endsWith(";")) s = _deleteSemiColon(s); + List args = ArgumentTokenizer.tokenize(s, true); + final String classNameWithQuotes = args.get(1); // this is "MyClass" + final String className = + classNameWithQuotes.substring(1, classNameWithQuotes.length() - 1); // removes quotes, becomes MyClass + + // we pass MyClass.class just to get a "Static Error: Undefined class 'MyClass'" + String ret = JavacCompiler.class.getName()+".runCommand(\""+s.toString()+"\", "+className+".class)"; + // System.out.println(ret); + return ret; + } + + /** Assumes a trimmed String. Returns a string of the call that the interpreter can use. + * The arguments get formatted as comma-separated list of strings enclosed in quotes. + * Example: _transformCommand("java MyClass arg1 arg2 arg3", "{0}.main(new String[]'{'{1}'}');") + * returns "MyClass.main(new String[]{\"arg1\",\"arg2\",\"arg3\"});" + * NOTE: the command to run is constructed using {@link java.text.MessageFormat}. That means that certain characters, + * single quotes and curly braces, for example, are special. To write single quotes, you need to double them. + * To write curly braces, you need to enclose them in single quotes. Example: + * MessageFormat.format("Abc {0} ''foo'' '{'something'}'", "def") returns "Abc def 'foo' {something}". + * @param s the command line, either "java MyApp arg1 arg2 arg3" or "applet MyApplet arg1 arg2 arg3" + * @param command the command to execute, with {0} marking the place for the class name and {1} the place for the arguments + * @return the transformed command + */ + protected static String _transformCommand(String s, String command) { + if (s.endsWith(";")) s = _deleteSemiColon(s); + List args = ArgumentTokenizer.tokenize(s, true); + final String classNameWithQuotes = args.get(1); // this is "MyClass" + final String className = classNameWithQuotes.substring(1, classNameWithQuotes.length() - 1); // removes quotes, becomes MyClass + final StringBuilder argsString = new StringBuilder(); + boolean seenArg = false; + for (int i = 2; i < args.size(); i++) { + if (seenArg) argsString.append(","); + else seenArg = true; + argsString.append(args.get(i)); + } + return java.text.MessageFormat.format(command, className, argsString.toString()); + } + + /** Deletes the last character of a string. Assumes semicolon at the end, but does not check. Helper + * for _transformCommand(String,String). + * @param s the String containing the semicolon + * @return a substring of s with one less character + */ + protected static String _deleteSemiColon(String s) { return s.substring(0, s.length() - 1); } + +// public boolean isSourceFileForThisCompiler(File f) { +// if (f == null) return false; +// String fileName = f.getName(); +// return fileName.endsWith(".java") || fileName.endsWith(".dj"); +// } + + /** .java {@literal -->} true + * .dj {@literal -->} true + * .dj0 {@literal -->} true + * .dj1 {@literal -->} true + * .dj2 {@literal -->} true + * otherwise false + * @return true if the specified file is a source file for this compiler. */ + public boolean isSourceFileForThisCompiler(File f) { + // by default, use DrJavaFileUtils.isSourceFile + return DrJavaFileUtils.isSourceFile(f); + } + +// public Set getSourceFileExtensions() { +// HashSet extensions = new HashSet(); +// extensions.add("java"); +// return extensions; +// } + + /** Return the set of source file extensions that this compiler supports. + * @return the set of source file extensions that this compiler supports. */ + public Set getSourceFileExtensions() { return DrJavaFileUtils.getSourceFileExtensions(); } + +// public String getSuggestedFileExtension() { return ".java"; } + + /** Return the suggested file extension that will be appended to a file without extension. + * @return the suggested file extension */ + public String getSuggestedFileExtension() { return DrJavaFileUtils.getSuggestedFileExtension(); } + + /** Return a file filter that can be used to open files this compiler supports. + * @return file filter for appropriate source files for this compiler */ + public FileFilter getFileFilter() { return new SmartSourceFilter(); } + +// public String getOpenAllFilesInFolderExtension() { +// // Should we use OptionConstants for this? +// return ".java"; +// } + + /** Return the extension of the files that should be opened with the "Open Folder..." command. + * @return file extension for the "Open Folder..." command for this compiler. */ + public String getOpenAllFilesInFolderExtension() { + return OptionConstants.LANGUAGE_LEVEL_EXTENSIONS[DrJava.getConfig().getSetting(OptionConstants.LANGUAGE_LEVEL)]; + } + + /** Return the set of keywords that should be highlighted in the specified file. + * @param f file for which to return the keywords + * @return the set of keywords that should be highlighted in the specified file. */ + public Set getKeywordsForFile(File f) { return new HashSet<>(JAVA_KEYWORDS); } + + /** Set of Java/GJ keywords for special coloring. */ + public static final HashSet JAVA_KEYWORDS = new HashSet<>(); + static { + final String[] words = { + "import", "native", "package", "goto", "const", "if", "else", "switch", "while", "for", "do", "true", "false", + "null", "this", "super", "new", "instanceof", "return", "static", "synchronized", "transient", "volatile", + "final", "strictfp", "throw", "try", "catch", "finally", "throws", "extends", "implements", "interface", "class", + "break", "continue", "public", "protected", "private", "abstract", "case", "default", "assert", "enum" + }; + Collections.addAll(JAVA_KEYWORDS, words); + } + + /** @return true since this compiler can be used in conjunction with the language level facility. */ + public boolean supportsLanguageLevels() { return true; } +} \ No newline at end of file diff --git a/drjava/src/edu/rice/cs/drjava/model/compiler/NoCompilerAvailable.java b/drjava/src/edu/rice/cs/drjava/model/compiler/NoCompilerAvailable.java index cb4e02a77..fcc45e6d2 100644 --- a/drjava/src/edu/rice/cs/drjava/model/compiler/NoCompilerAvailable.java +++ b/drjava/src/edu/rice/cs/drjava/model/compiler/NoCompilerAvailable.java @@ -71,6 +71,8 @@ public List compile(List files, List additionalBootClassPathForInteractions() { return Arrays.asList(); } /** Transform the command line to be interpreted into something the Interactions JVM can use. diff --git a/drjava/src/edu/rice/cs/drjava/model/junit/DefaultJUnitModel.java b/drjava/src/edu/rice/cs/drjava/model/junit/DefaultJUnitModel.java index 3f934b1d1..d2cb78d3d 100644 --- a/drjava/src/edu/rice/cs/drjava/model/junit/DefaultJUnitModel.java +++ b/drjava/src/edu/rice/cs/drjava/model/junit/DefaultJUnitModel.java @@ -232,12 +232,11 @@ public void junit(OpenDefinitionsDocument doc) throws ClassNotFoundException, IO debug.logEnd("junit(doc)"); } - /** Ensures that all documents have been compiled since their last - * modification and then delegates the actual testing to - * _rawJUnitOpenTestDocs. - * @param lod list of open documents - * @param allTests true if all tests are to be run - */ + /** Ensures that all documents have been compiled since their last modification and then delegates the actual testing to + * _rawJUnitOpenTestDocs. + * @param lod list of open documents + * @param allTests true if all tests are to be run + */ private void junitOpenDefDocs(final List lod, final boolean allTests) { // If a test is running, don't start another one. @@ -409,7 +408,7 @@ private void _rawJUnitOpenDefDocs(List lod, final boole try { final Box className = new SimpleBox(); final Box sourceName = new SimpleBox(); - new ClassReader(IOUtil.toByteArray(entry)).accept(new ClassVisitor(Opcodes.ASM4) { + new ClassReader(IOUtil.toByteArray(entry)).accept(new ClassVisitor(Opcodes.ASM7) { public void visit(int version, int access, String name, String sig, String sup, String[] inters) { className.set(name.replace('/', '.')); } diff --git a/drjava/src/edu/rice/cs/drjava/model/junit/JUnitTestRunner.java b/drjava/src/edu/rice/cs/drjava/model/junit/JUnitTestRunner.java index dfffa12a0..b3a805c05 100644 --- a/drjava/src/edu/rice/cs/drjava/model/junit/JUnitTestRunner.java +++ b/drjava/src/edu/rice/cs/drjava/model/junit/JUnitTestRunner.java @@ -34,8 +34,9 @@ import edu.rice.cs.util.Log; import edu.rice.cs.util.UnexpectedException; -/** DrJava's own testrunner. It updates the document in the JUnit pane as error and failure events are fired. - * These methods run inan auxiliary thread. +/** Runs in the InterpreterJVM. It uses RMI calls to update the the JUnitPanel as test results are reported. Some methods are + * synchronized to maintain the consistency of local state. These methods run in an auxiliary thread. + * GUI actions must be transferred to the event handling thread (DispatchThread). * @version $Id$ */ public class JUnitTestRunner extends BaseTestRunner { @@ -56,8 +57,6 @@ public class JUnitTestRunner extends BaseTestRunner { /** The current number of failures in the result. */ private int _failureCount; - - /** Standard constructor. * @param jmc a JUnitModelCallback diff --git a/drjava/src/edu/rice/cs/drjava/model/repl/InteractionsModel.java b/drjava/src/edu/rice/cs/drjava/model/repl/InteractionsModel.java index 9e5050d24..62cdf2e1c 100644 --- a/drjava/src/edu/rice/cs/drjava/model/repl/InteractionsModel.java +++ b/drjava/src/edu/rice/cs/drjava/model/repl/InteractionsModel.java @@ -685,7 +685,7 @@ public void interpreterResetting() { if (! _waitingForFirstInterpreter) { Utilities.invokeLater(new Runnable() { public void run() { - _document.insertBeforeLastPrompt(" Resetting Interactions ...\n", InteractionsDocument.ERROR_STYLE); + _document.insertBeforeLastPrompt(" Resetting Interactions and Clearing Console ...\n", InteractionsDocument.ERROR_STYLE); _document.setInProgress(true); } }); diff --git a/drjava/src/edu/rice/cs/drjava/model/repl/newjvm/InterpreterJVM.java b/drjava/src/edu/rice/cs/drjava/model/repl/newjvm/InterpreterJVM.java index c22d4373f..81b11f1a8 100644 --- a/drjava/src/edu/rice/cs/drjava/model/repl/newjvm/InterpreterJVM.java +++ b/drjava/src/edu/rice/cs/drjava/model/repl/newjvm/InterpreterJVM.java @@ -1,37 +1,46 @@ /*BEGIN_COPYRIGHT_BLOCK * - * Copyright (c) 2001-2019, JavaPLT group at Rice University (drjava@rice.edu). All rights reserved. + * Copyright (c) 2001-2017, JavaPLT group at Rice University (drjava@rice.edu) + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific prior written permission. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * This software is Open Source Initiative approved Open Source Software. Open Source Initative Approved is a trademark - * of the Open Source Initiative. + * This software is Open Source Initiative approved Open Source Software. + * Open Source Initative Approved is a trademark of the Open Source Initiative. * - * This file is part of DrJava. Download the current version of this project from http://www.drjava.org/ or - * http://sourceforge.net/projects/drjava/ + * This file is part of DrJava. Download the current version of this project + * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/ * * END_COPYRIGHT_BLOCK*/ + package edu.rice.cs.drjava.model.repl.newjvm; import java.util.*; import java.io.*; import java.rmi.*; +import java.awt.EventQueue; // NOTE: Do NOT import/use the config framework in this class! // (This class runs in a different JVM, and will not share the config object) @@ -61,8 +70,16 @@ import edu.rice.cs.dynamicjava.symbol.*; import edu.rice.cs.dynamicjava.symbol.type.Type; +//for JShell because dynamicJava does not have support for java9+ +import jdk.jshell.*; +import java.util.List; +import java.util.Locale; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + // For Windows focus fix import javax.swing.JDialog; +import javax.tools.StandardLocation; import static edu.rice.cs.plt.debug.DebugUtil.debug; import static edu.rice.cs.plt.debug.DebugUtil.error; @@ -78,8 +95,8 @@ * @version $Id$ */ public class InterpreterJVM extends AbstractSlaveJVM implements InterpreterJVMRemoteI, JUnitModelCallback { - - public static final Log _log = new Log("GlobalModel.txt", false); + /** log for use in debugging */ + public static final Log _log = new Log("InterpreterJVM.txt", false); /** Singleton instance of this class. */ public static final InterpreterJVM ONLY = new InterpreterJVM(); @@ -92,11 +109,15 @@ public class InterpreterJVM extends AbstractSlaveJVM implements InterpreterJVMRe private final Interpreter _defaultInterpreter; private final Map _interpreters; private final Set _busyInterpreters; + private final JShell _js; // The following variable appears to be useless. // private final Map> _environments; private final ClassPathManager _classPathManager; private final ClassLoader _interpreterLoader; + private StringBuilder output_buf; + private StringBuilder input_buf; + private int num_input_braces; // Lock object for ensuring mutual exclusion on updates and compound accesses private final Object _stateLock = new Object(); @@ -104,9 +125,10 @@ public class InterpreterJVM extends AbstractSlaveJVM implements InterpreterJVMRe /** Responsible for running JUnit tests in this JVM. */ private final JUnitTestManager _junitTestManager; + /** Remote reference to the MainJVM class in DrJava's primary JVM. Assigned ONLY once. */ private volatile MainJVMRemoteI _mainJVM; - + /** Private constructor; use the singleton ONLY instance. */ private InterpreterJVM() { super("Reset Interactions Thread", "Poll DrJava Thread"); @@ -122,10 +144,35 @@ private InterpreterJVM() { // _interpreterOptions = Options.DEFAULT; _interpreterOptions = new InteractionsPaneOptions(); _defaultInterpreter = new Interpreter(_interpreterOptions, _interpreterLoader); +// _defaultInterpreter = _interpreters = new HashMap(); _busyInterpreters = new HashSet(); // _environments = new HashMap>(); _activeInterpreter = Pair.make("", _defaultInterpreter); + + // Create a StringBuilder to capture the JShell Output + output_buf = new StringBuilder(); + input_buf = new StringBuilder(); + num_input_braces = 0; + // Create a PrintStream that will write to our StringBuilder + PrintStream printStream = new PrintStream(new OutputStream() { + @Override + public void write(int b) { + output_buf.append((char) b); + } + }); + + try { + _js = JShell.builder() + .out(printStream) + .err(printStream) + .compilerOptions("-classpath", getClassPathString()) + .build(); + } catch(IllegalStateException e) { + //Potentially exit system or try to create a new JShell instance + System.err.println("JShell is not available in this environment"); + throw new RuntimeException(e); + } } /** Actions to perform when this JVM is started (through its superclass, AbstractSlaveJVM). Not synchronized @@ -144,11 +191,12 @@ protected String _getInput() { } } }); - - // redirect stdout + System.setOut(new PrintStream(new OutputStreamRedirector() { public void print(String s) { - try { _mainJVM.systemOutPrint(s); } + try { + _mainJVM.systemOutPrint(s); + } catch (RemoteException re) { error.log(re); throw new UnexpectedException("Main JVM can't be reached for output.\n" + re); @@ -213,7 +261,9 @@ private boolean isBusyInterpreter(Interpreter i) { * local state. * @param s Source code to interpret. */ - public InterpretResult interpret(String s) { return interpret(s, _activeInterpreter.second()); } + public InterpretResult interpret(String s) { + return interpret(s, _activeInterpreter.second()); + } /** Interprets the given string of source code with the given interpreter. The result is returned to * MainJVM via the interpretResult method. @@ -229,48 +279,98 @@ public InterpretResult interpret(String s, String name) { } return interpret(s, i); } - + + /** + * Interprets the given string of code with an instance of JShell and returns the result wrapped in a InterpretResult object + * Currently does NOT support differentiation between different types of results, only treats them as objects. + * Currently does NOT support printing of basic expressions, i.e. "2 + 2" will not print 4 (but it should) + * @param code - the code to be interpreted + * @return InterpretResult - the result of the interpretation + * @throws InterpreterException - in the case the JShell instance is not available or an error occurs during interpretation + */ + private InterpretResult interpretWithJShell(StringBuilder input_buf) throws InterpreterException { + InterpretResult res = null; + //TD set verbosity level so it doesn't freak out over things like semicolons + if (_js == null) { + //TODO create InterpretResultException here + return InterpretResult.exception(new EvaluatorException(new Throwable("An error has occured that has caused the Interpreter to not be available."))); + } + +// System.out.println("Evalulating: " + input_buf.toString()); + List events = _js.eval(input_buf.toString()); + //getting rid of new line character at the end + if (output_buf.length() > 0 && output_buf.charAt(output_buf.length() - 1) == '\n') { + output_buf.setLength(output_buf.length() - 1); + } + + boolean hasError = false; + + //TODO Jshell adds a lot of fluff to the output, try and only get the cause of the error + for (SnippetEvent e : events) { + if (e.status() == Snippet.Status.REJECTED) { + Diag diagnostics = _js.diagnostics(e.snippet()).collect(Collectors.toList()).get(0); + output_buf.append(diagnostics.getMessage(Locale.getDefault())); + res = InterpretResult.exception(new EvaluatorException(new Throwable(output_buf.toString()))); + hasError = true; + } else if (e.value() != null) { + output_buf.append(e.value()).append("\n"); + } + } + + if (!hasError && output_buf.length() > 0) { + // Remove the last newline character added + output_buf.setLength(output_buf.length() - 1); + res = InterpretResult.objectValue(output_buf.toString(), "JShellOutput"); + } + + if (res == null) { + //Setting InterpretResult as an object value rather than doing case work as JShell will internally keep track of state, bypassing need for us to do so + res = InterpretResult.objectValue(output_buf.toString(), "JShellOutput"); + } + + output_buf.setLength(0); + //clear input after setting multiple lines + input_buf.setLength(0); + return res; + } + private InterpretResult interpret(String input, Interpreter interpreter) { - debug.logStart("Interpret " + input); - +// System.out.println("Received input: " + input); boolean available = addBusyInterpreter(interpreter); if (! available) { debug.logEnd(); return InterpretResult.busy(); } - + // set the thread context class loader, this way NextGen and Mint can use the interpreter's class loader Thread.currentThread().setContextClassLoader(_interpreterLoader); // _interpreterLoader is final - - Option result = null; - try { result = interpreter.interpret(input); } + InterpretResult result = null; + + //Branching based on state of input_buffer to decide if we shoudl evalutate or not (i.e. when we are in a multi-line statement) + input_buf.append(input); + if (input.trim().endsWith("{")) { + num_input_braces += 1; + } + + if (num_input_braces > 0) { + if (input.endsWith("}")) { + num_input_braces -= 1; + } + } + + + try { + if (num_input_braces == 0) { + result = interpretWithJShell(input_buf); + } + } catch (InterpreterException e) { debug.logEnd(); return InterpretResult.exception(e); } catch (Throwable e) { debug.logEnd(); return InterpretResult.unexpectedException(e); } finally { removeBusyInterpreter(interpreter); } - - return result.apply(new OptionVisitor() { - public InterpretResult forNone() { return InterpretResult.noValue(); } - public InterpretResult forSome(Object obj) { - if (obj instanceof String) { debug.logEnd(); return InterpretResult.stringValue((String) obj); } - else if (obj instanceof Character) { debug.logEnd(); return InterpretResult.charValue((Character) obj); } - else if (obj instanceof Number) { debug.logEnd(); return InterpretResult.numberValue((Number) obj); } - else if (obj instanceof Boolean) { debug.logEnd(); return InterpretResult.booleanValue((Boolean) obj); } - else { - try { - String resultString = TextUtil.toString(obj); - String resultTypeStr = null; - if (obj!=null) { - Class c = obj.getClass(); - resultTypeStr = getClassName(c); - } - debug.logEnd(); - return InterpretResult.objectValue(resultString,resultTypeStr); - } - catch (Throwable t) { - // an exception occurred during toString - debug.logEnd(); - return InterpretResult.exception(new EvaluatorException(t)); - } - } - } - }); + + if (result == null) { + //TODO create something more robust here + return InterpretResult.noValue(); + } + + return result; } /** Gets the value of the variable with the given name in the current interpreter. @@ -533,7 +633,9 @@ public List findTestClasses(List classNames, * and does not involve mutable local state. * @return false if no test suite is cached; true otherwise */ - public boolean runTestSuite() throws RemoteException { return _junitTestManager.runTestSuite(); } + public boolean runTestSuite() throws RemoteException { + return _junitTestManager.runTestSuite(); + } /** Notifies Main JVM that JUnit has been invoked on a non TestCase class. Unsynchronized because it contains a * remote call and does not involve mutable local state. @@ -554,7 +656,7 @@ public void classFileError(ClassFileError e) { catch (RemoteException re) { error.log(re); } } - /** Notifies that a suite of tests has started running. Unsynchronized because it contains a remote call and does + /** Notifies the Main JVM that a suite of tests has started running. Unsynchronized because it contains a remote call and does * not involve mutable local state. * @param numTests The number of tests in the suite to be run. */ @@ -563,7 +665,7 @@ public void testSuiteStarted(int numTests) { catch (RemoteException re) { error.log(re); } } - /** Notifies that a particular test has started. Unsynchronized because it contains a remote call and does not + /** Notifies the Main JVM that a particular test has started. Unsynchronized because it contains a remote call and does not * involve mutable local state. * @param testName The name of the test being started. */ @@ -609,9 +711,16 @@ public void junitJVMReady() { } public void addBuildDirectoryClassPath(File f) { _classPathManager.addBuildDirectoryCP(f); } public void addProjectFilesClassPath(File f) { _classPathManager.addProjectFilesCP(f); } public void addExternalFilesClassPath(File f) { _classPathManager.addExternalFilesCP(f); } + public Iterable getClassPath() { // need to make a serializable snapshot return IterUtil.snapshot(_classPathManager.getClassPath()); } - + + private String getClassPathString() { + Iterable classPathFiles = _classPathManager.getClassPath(); + return StreamSupport.stream(Spliterators.spliteratorUnknownSize(classPathFiles.iterator(), 0), false) // Convert Iterable to Stream + .map(File::getAbsolutePath) + .collect(Collectors.joining(";")); + } } diff --git a/drjava/src/edu/rice/cs/drjava/model/repl/newjvm/MainJVM.java b/drjava/src/edu/rice/cs/drjava/model/repl/newjvm/MainJVM.java index da4a87d33..5b0c29603 100644 --- a/drjava/src/edu/rice/cs/drjava/model/repl/newjvm/MainJVM.java +++ b/drjava/src/edu/rice/cs/drjava/model/repl/newjvm/MainJVM.java @@ -28,9 +28,10 @@ * END_COPYRIGHT_BLOCK*/ package edu.rice.cs.drjava.model.repl.newjvm; -import java.rmi.*; +import java.awt.EventQueue; import java.io.*; import java.net.SocketException; +import java.rmi.*; import java.util.List; import java.util.ArrayList; @@ -601,85 +602,89 @@ private void _doStartup() { List jvmArgs = new ArrayList(); - // ConcJUnit argument: -Xbootclasspath/p:rt.concjunit.jar - // ------------------------------------------------------ - // this section here loops if the rt.concjunit.jar file is - // being re-generated or the settings are changed - final CompletionMonitor cm = new CompletionMonitor(); - boolean repeat; - do { - repeat = false; - File junitLocation = DrJava.getConfig().getSetting(OptionConstants.JUNIT_LOCATION); - boolean javaVersion7 = JavaVersion.CURRENT.supports(JavaVersion.JAVA_7); - // ConcJUnit is available if (a) the built-in framework is used, or (b) the external - // framework is a valid ConcJUnit jar file, AND the compiler is not Java 7 or newer. - boolean concJUnitAvailable = - !javaVersion7 && - (!DrJava.getConfig().getSetting(OptionConstants.JUNIT_LOCATION_ENABLED) || - edu.rice.cs.drjava.model.junit.ConcJUnitUtils.isValidConcJUnitFile(junitLocation)); + /* ConcJUnit is no longer available because it has not been updated beyonnd Java 6 */ + +// // ConcJUnit argument: -Xbootclasspath/p:rt.concjunit.jar +// // ------------------------------------------------------ +// // this section here loops if the rt.concjunit.jar file is +// // being re-generated or the settings are changed +// final CompletionMonitor cm = new CompletionMonitor(); +// boolean repeat; +// do { +// repeat = false; +// File junitLocation = DrJava.getConfig().getSetting(OptionConstants.JUNIT_LOCATION); +// + +// boolean javaVersion7 = JavaVersion.CURRENT.supports(JavaVersion.JAVA_7); +// // ConcJUnit is available if (a) the built-in framework is used, or (b) the external +// // framework is a valid ConcJUnit jar file, AND the compiler is not Java 7 or newer. +// boolean concJUnitAvailable = +// !javaVersion7 && +// (!DrJava.getConfig().getSetting(OptionConstants.JUNIT_LOCATION_ENABLED) || +// edu.rice.cs.drjava.model.junit.ConcJUnitUtils.isValidConcJUnitFile(junitLocation)); - File rtLocation = DrJava.getConfig().getSetting(OptionConstants.RT_CONCJUNIT_LOCATION); - boolean rtLocationConfigured = - edu.rice.cs.drjava.model.junit.ConcJUnitUtils.isValidRTConcJUnitFile(rtLocation); +// File rtLocation = DrJava.getConfig().getSetting(OptionConstants.RT_CONCJUNIT_LOCATION); +// boolean rtLocationConfigured = +// edu.rice.cs.drjava.model.junit.ConcJUnitUtils.isValidRTConcJUnitFile(rtLocation); - if (DrJava.getConfig().getSetting(OptionConstants.CONCJUNIT_CHECKS_ENABLED). - equals(OptionConstants.ConcJUnitCheckChoices.ALL) && // "lucky" enabled - !rtLocationConfigured && // not valid - (rtLocation != null) && // not null - (!FileOps.NULL_FILE.equals(rtLocation)) && // not NULL_FILE - (rtLocation.exists())) { // but exists - // invalid file, clear setting - DrJava.getConfig().setSetting(OptionConstants.CONCJUNIT_CHECKS_ENABLED, - OptionConstants.ConcJUnitCheckChoices.NO_LUCKY); - rtLocationConfigured = false; - javax.swing.JOptionPane.showMessageDialog(null, - "The selected file is invalid and was disabled:\n"+rtLocation, - "Invalid ConcJUnit Runtime File", - javax.swing.JOptionPane.ERROR_MESSAGE); - } - if (concJUnitAvailable && // ConcJUnit available - rtLocationConfigured && // runtime configured - DrJava.getConfig().getSetting(OptionConstants.CONCJUNIT_CHECKS_ENABLED). - equals(OptionConstants.ConcJUnitCheckChoices.ALL)) { // and "lucky" enabled - try { - // NOTE: this is a work-around - // it seems like it's impossible to pass long file names here on Windows - // so we are using a clumsy method that determines the short file name - File shortF = FileOps.getShortFile(rtLocation); - - // check the JavaVersion of the rt.concjunit.jar file to make sure it is compatible - if (edu.rice.cs.drjava.model.junit.ConcJUnitUtils.isCompatibleRTConcJUnitFile(shortF)) { - // enabled, valid and compatible - // add the JVM argument - jvmArgs.add("-Xbootclasspath/p:"+shortF.getAbsolutePath().replace(File.separatorChar, '/')); - } - else { - // enabled, valid but incompatible - // ask to regenerate - repeat = true; // re-check settings - cm.reset(); - boolean attempted = edu.rice.cs.drjava.model.junit.ConcJUnitUtils. - showIncompatibleWantToRegenerateDialog(null, - new Runnable() { public void run() { cm.signal(); } }, // yes - new Runnable() { public void run() { cm.signal(); } }); // no - while(!cm.attemptEnsureSignaled()); // wait for dialog to finish - if (!attempted) { repeat = false; } - } - } - catch(IOException ioe) { - // we couldn't get the short file name (on Windows), disable "lucky" warnings - DrJava.getConfig().setSetting(OptionConstants.CONCJUNIT_CHECKS_ENABLED, - OptionConstants.ConcJUnitCheckChoices.NO_LUCKY); - rtLocationConfigured = false; - javax.swing.JOptionPane.showMessageDialog(null, - "There was a problem with the selected file, and it was disabled:\n"+rtLocation, - "Invalid ConcJUnit Runtime File", - javax.swing.JOptionPane.ERROR_MESSAGE); - } - } - } while (repeat); - // end of the section that may loop - // ------------------------------------------------------ +// if (DrJava.getConfig().getSetting(OptionConstants.CONCJUNIT_CHECKS_ENABLED). +// equals(OptionConstants.ConcJUnitCheckChoices.ALL) && // "lucky" enabled +// !rtLocationConfigured && // not valid +// (rtLocation != null) && // not null +// (!FileOps.NULL_FILE.equals(rtLocation)) && // not NULL_FILE +// (rtLocation.exists())) { // but exists +// // invalid file, clear setting +// DrJava.getConfig().setSetting(OptionConstants.CONCJUNIT_CHECKS_ENABLED, +// OptionConstants.ConcJUnitCheckChoices.NO_LUCKY); +// rtLocationConfigured = false; +// javax.swing.JOptionPane.showMessageDialog(null, +// "The selected file is invalid and was disabled:\n"+rtLocation, +// "Invalid ConcJUnit Runtime File", +// javax.swing.JOptionPane.ERROR_MESSAGE); +// } +// if (concJUnitAvailable && // ConcJUnit available +// rtLocationConfigured && // runtime configured +// DrJava.getConfig().getSetting(OptionConstants.CONCJUNIT_CHECKS_ENABLED). +// equals(OptionConstants.ConcJUnitCheckChoices.ALL)) { // and "lucky" enabled +// try { +// // NOTE: this is a work-around +// // it seems like it's impossible to pass long file names here on Windows +// // so we are using a clumsy method that determines the short file name +// File shortF = FileOps.getShortFile(rtLocation); +// +// // check the JavaVersion of the rt.concjunit.jar file to make sure it is compatible +// if (edu.rice.cs.drjava.model.junit.ConcJUnitUtils.isCompatibleRTConcJUnitFile(shortF)) { +// // enabled, valid and compatible +// // add the JVM argument +// jvmArgs.add("-Xbootclasspath/p:"+shortF.getAbsolutePath().replace(File.separatorChar, '/')); +// } +// else { +// // enabled, valid but incompatible +// // ask to regenerate +// repeat = true; // re-check settings +// cm.reset(); +// boolean attempted = edu.rice.cs.drjava.model.junit.ConcJUnitUtils. +// showIncompatibleWantToRegenerateDialog(null, +// new Runnable() { public void run() { cm.signal(); } }, // yes +// new Runnable() { public void run() { cm.signal(); } }); // no +// while(!cm.attemptEnsureSignaled()); // wait for dialog to finish +// if (!attempted) { repeat = false; } +// } +// } +// catch(IOException ioe) { +// // we couldn't get the short file name (on Windows), disable "lucky" warnings +// DrJava.getConfig().setSetting(OptionConstants.CONCJUNIT_CHECKS_ENABLED, +// OptionConstants.ConcJUnitCheckChoices.NO_LUCKY); +// rtLocationConfigured = false; +// javax.swing.JOptionPane.showMessageDialog(null, +// "There was a problem with the selected file, and it was disabled:\n"+rtLocation, +// "Invalid ConcJUnit Runtime File", +// javax.swing.JOptionPane.ERROR_MESSAGE); +// } +// } +// } while (repeat); +// // end of the section that may loop +// // ------------------------------------------------------ if (_allowAssertions) { jvmArgs.add("-ea"); } int debugPort = _getDebugPort(); @@ -716,49 +721,49 @@ private void _doStartup() { JVMBuilder jvmb = new JVMBuilder(_startupClassPath).directory(dir).jvmArguments(jvmArgs); - // extend classpath if JUnit/ConcJUnit location specified - File junitLocation = DrJava.getConfig().getSetting(OptionConstants.JUNIT_LOCATION); - boolean junitLocationConfigured = - (edu.rice.cs.drjava.model.junit.ConcJUnitUtils.isValidJUnitFile(junitLocation) || - edu.rice.cs.drjava.model.junit.ConcJUnitUtils.isValidConcJUnitFile(junitLocation)); - if (DrJava.getConfig().getSetting(OptionConstants.JUNIT_LOCATION_ENABLED) && // enabled - !junitLocationConfigured && // not valid - (junitLocation != null) && // not null - (!FileOps.NULL_FILE.equals(junitLocation)) && // not NULL_FILE - (junitLocation.exists())) { // but exists - // invalid file, clear setting - DrJava.getConfig().setSetting(OptionConstants.JUNIT_LOCATION_ENABLED, false); - junitLocationConfigured = false; - } - ArrayList extendedClassPath = new ArrayList(); - if (DrJava.getConfig().getSetting(OptionConstants.JUNIT_LOCATION_ENABLED) && - junitLocationConfigured) { - extendedClassPath.add(junitLocation); - } - for(File f: jvmb.classPath()) { extendedClassPath.add(f); } - jvmb = jvmb.classPath(edu.rice.cs.plt.iter.IterUtil.asSizedIterable(extendedClassPath)); +// // extend classpath if JUnit/ConcJUnit location specified +// File junitLocation = DrJava.getConfig().getSetting(OptionConstants.JUNIT_LOCATION); +// boolean junitLocationConfigured = +// (edu.rice.cs.drjava.model.junit.ConcJUnitUtils.isValidJUnitFile(junitLocation) || +// edu.rice.cs.drjava.model.junit.ConcJUnitUtils.isValidConcJUnitFile(junitLocation)); +// if (DrJava.getConfig().getSetting(OptionConstants.JUNIT_LOCATION_ENABLED) && // enabled +// !junitLocationConfigured && // not valid +// (junitLocation != null) && // not null +// (!FileOps.NULL_FILE.equals(junitLocation)) && // not NULL_FILE +// (junitLocation.exists())) { // but exists +// // invalid file, clear setting +// DrJava.getConfig().setSetting(OptionConstants.JUNIT_LOCATION_ENABLED, false); +// junitLocationConfigured = false; +// } +// ArrayList extendedClassPath = new ArrayList(); +// if (DrJava.getConfig().getSetting(OptionConstants.JUNIT_LOCATION_ENABLED) && +// junitLocationConfigured) { +// extendedClassPath.add(junitLocation); +// } +// for(File f: jvmb.classPath()) { extendedClassPath.add(f); } +// jvmb = jvmb.classPath(edu.rice.cs.plt.iter.IterUtil.asSizedIterable(extendedClassPath)); - // add Java properties controlling ConcJUnit - Map props = jvmb.propertiesCopy(); +// // add Java properties controlling ConcJUnit +// Map props = jvmb.propertiesCopy(); - // settings are mutually exclusive - boolean all = DrJava.getConfig().getSetting(OptionConstants.CONCJUNIT_CHECKS_ENABLED). - equals(OptionConstants.ConcJUnitCheckChoices.ALL); - boolean noLucky = DrJava.getConfig().getSetting(OptionConstants.CONCJUNIT_CHECKS_ENABLED). - equals(OptionConstants.ConcJUnitCheckChoices.NO_LUCKY); - boolean none = DrJava.getConfig().getSetting(OptionConstants.CONCJUNIT_CHECKS_ENABLED). - equals(OptionConstants.ConcJUnitCheckChoices.NONE); - // "threads" is enabled as long as the setting isn't NONE - props.put("edu.rice.cs.cunit.concJUnit.check.threads.enabled", - new Boolean(!none).toString()); - // "join" is enabled for ALL and NO_LUCKY - props.put("edu.rice.cs.cunit.concJUnit.check.join.enabled", - new Boolean(all || noLucky).toString()); - // "lucky" is enabled only for ALL - props.put("edu.rice.cs.cunit.concJUnit.check.lucky.enabled", - new Boolean(all).toString()); +// // settings are mutually exclusive +// boolean all = DrJava.getConfig().getSetting(OptionConstants.CONCJUNIT_CHECKS_ENABLED). +// equals(OptionConstants.ConcJUnitCheckChoices.ALL); +// boolean noLucky = DrJava.getConfig().getSetting(OptionConstants.CONCJUNIT_CHECKS_ENABLED). +// equals(OptionConstants.ConcJUnitCheckChoices.NO_LUCKY); +// boolean none = DrJava.getConfig().getSetting(OptionConstants.CONCJUNIT_CHECKS_ENABLED). +// equals(OptionConstants.ConcJUnitCheckChoices.NONE); +// // "threads" is enabled as long as the setting isn't NONE +// props.put("edu.rice.cs.cunit.concJUnit.check.threads.enabled", +// new Boolean(!none).toString()); +// // "join" is enabled for ALL and NO_LUCKY +// props.put("edu.rice.cs.cunit.concJUnit.check.join.enabled", +// new Boolean(all || noLucky).toString()); +// // "lucky" is enabled only for ALL +// props.put("edu.rice.cs.cunit.concJUnit.check.lucky.enabled", +// new Boolean(all).toString()); - jvmb = jvmb.properties(props); +// jvmb = jvmb.properties(props); invokeSlave(jvmb); } diff --git a/drjava/src/edu/rice/cs/drjava/platform/DefaultPlatform.java b/drjava/src/edu/rice/cs/drjava/platform/DefaultPlatform.java index 767c9a6ba..235cf5653 100644 --- a/drjava/src/edu/rice/cs/drjava/platform/DefaultPlatform.java +++ b/drjava/src/edu/rice/cs/drjava/platform/DefaultPlatform.java @@ -210,15 +210,15 @@ public void setMnemonicAt(javax.swing.JTabbedPane obj, int tabIndex, int mnemoni /** @return true if file extensions can be registered and unregistered. */ public boolean canRegisterFileExtensions() { return false; } - /** Register .drjava and .djapp file extensions. + /** Register .drjava file extension. * @return true if registering succeeded */ public boolean registerDrJavaFileExtensions() { return false; } - /** Unregister .drjava and .djapp file extensions. + /** Unregister .drjava file extensions. * @return true if unregistering succeeded */ public boolean unregisterDrJavaFileExtensions() { return false; } - /** @return true if .drjava and .djapp file extensions are registered. */ + /** @return true if .drjava file extension is registered. */ public boolean areDrJavaFileExtensionsRegistered() { return false; } /** Register .java file extension. diff --git a/drjava/src/edu/rice/cs/drjava/platform/PlatformFactory.java b/drjava/src/edu/rice/cs/drjava/platform/PlatformFactory.java index 61da5fd01..2bdd1d35f 100644 --- a/drjava/src/edu/rice/cs/drjava/platform/PlatformFactory.java +++ b/drjava/src/edu/rice/cs/drjava/platform/PlatformFactory.java @@ -46,8 +46,10 @@ private static PlatformSupport getPlatformSupport() { // Get OS name string; we expect one of "windows xp", "mac os x", etc. String os = System.getProperty("os.name").toLowerCase(); + String java_version = System.getProperty("java.version").toLowerCase(); - if (os.startsWith("mac os x")) return MacPlatform.ONLY; + if (os.startsWith("mac os x") && java_version.startsWith("1.")) return MacPlatformJava8.ONLY; + else if (os.startsWith("mac os x")) return MacPlatform.ONLY; else if (os.startsWith("windows")) return WindowsPlatform.ONLY; else return DefaultPlatform.ONLY; } diff --git a/drjava/src/edu/rice/cs/drjava/platform/PlatformSupport.java b/drjava/src/edu/rice/cs/drjava/platform/PlatformSupport.java index 7293b8818..a945664b5 100644 --- a/drjava/src/edu/rice/cs/drjava/platform/PlatformSupport.java +++ b/drjava/src/edu/rice/cs/drjava/platform/PlatformSupport.java @@ -108,15 +108,15 @@ public interface PlatformSupport { /** @return true if file extensions can be registered and unregistered. */ public boolean canRegisterFileExtensions(); - /** Register .drjava and .djapp file extensions. + /** Register .drjava file extensions. * @return true if registering succeeded */ public boolean registerDrJavaFileExtensions(); - /** Unregister .drjava and .djapp file extensions. + /** Unregister .drjava file extensions. * @return true if unregistering succeeded */ public boolean unregisterDrJavaFileExtensions(); - /** @return true if .drjava and .djapp file extensions are registered. */ + /** @return true if .drjava file extensions are registered. */ public boolean areDrJavaFileExtensionsRegistered(); /** Register .java file extension. diff --git a/drjava/src/edu/rice/cs/drjava/project/ProjectProfile.java b/drjava/src/edu/rice/cs/drjava/project/ProjectProfile.java index f43272bd7..ef7641374 100644 --- a/drjava/src/edu/rice/cs/drjava/project/ProjectProfile.java +++ b/drjava/src/edu/rice/cs/drjava/project/ProjectProfile.java @@ -353,10 +353,10 @@ public void write(OutputStream os) throws IOException { xc.set(".timestamp", s, f, true); String pkg = df.getPackage(); xc.set(".package", (pkg != null)?pkg:"", f, true); - xc.set("select.from", String.valueOf((pSel != null)?pSel.first():0), f, true); - xc.set("select.to", String.valueOf((pSel != null)?pSel.second():0), f, true); - xc.set("scroll.column", String.valueOf((pScr != null)?pScr.first():0), f, true); - xc.set("scroll.row", String.valueOf((pScr != null)?pScr.second():0), f, true); + xc.set("select.from", String.valueOf((pSel != null) ? pSel.first() : (Integer) 0), f, true); + xc.set("select.to", String.valueOf((pSel != null) ? pSel.second() : (Integer) 0), f, true); + xc.set("scroll.column", String.valueOf((pScr != null) ? pScr.first() : (Integer) 0), f, true); + xc.set("scroll.row", String.valueOf((pScr != null) ? pScr.second() : (Integer) 0), f, true); if (df==active) xc.set(".active", "true", f, true); } } @@ -383,11 +383,11 @@ public void write(OutputStream os) throws IOException { xc.set(".name", path, f, true); xc.set(".timestamp", s, f, true); String pkg = df.getPackage(); - xc.set(".package", (pkg != null)?pkg:"", f, true); - xc.set("select.from", String.valueOf((pSel != null)?pSel.first():0), f, true); - xc.set("select.to", String.valueOf((pSel != null)?pSel.second():0), f, true); - xc.set("scroll.column", String.valueOf((pScr != null)?pScr.first():0), f, true); - xc.set("scroll.row", String.valueOf((pScr != null)?pScr.second():0), f, true); + xc.set(".package", (pkg != null) ? pkg:"", f, true); + xc.set("select.from", String.valueOf((pSel != null) ? pSel.first() : (Integer) 0), f, true); + xc.set("select.to", String.valueOf((pSel != null) ? pSel.second() : (Integer) 0), f, true); + xc.set("scroll.column", String.valueOf((pScr != null) ? pScr.first() : (Integer) 0), f, true); + xc.set("scroll.row", String.valueOf((pScr != null) ? pScr.second() : (Integer) 0), f, true); if (df==active) { xc.set(".active", "true", f, true); } } @@ -416,11 +416,11 @@ public void write(OutputStream os) throws IOException { xc.set(".name", path, f, true); xc.set(".timestamp", s, f, true); String pkg = df.getPackage(); - xc.set(".package", (pkg != null)?pkg:"", f, true); - xc.set("select.from", String.valueOf((pSel != null)?pSel.first():0), f, true); - xc.set("select.to", String.valueOf((pSel != null)?pSel.second():0), f, true); - xc.set("scroll.column", String.valueOf((pScr != null)?pScr.first():0), f, true); - xc.set("scroll.row", String.valueOf((pScr != null)?pScr.second():0), f, true); + xc.set(".package", (pkg != null) ? pkg : "", f, true); + xc.set("select.from", String.valueOf((pSel != null) ? pSel.first():(Integer) 0), f, true); + xc.set("select.to", String.valueOf((pSel != null) ? pSel.second():(Integer) 0), f, true); + xc.set("scroll.column", String.valueOf((pScr != null) ? pScr.first():(Integer) 0), f, true); + xc.set("scroll.row", String.valueOf((pScr != null) ? pScr.second():(Integer) 0), f, true); if (df==active) { xc.set(".active", "true", f, true); } } @@ -436,7 +436,7 @@ public void write(OutputStream os) throws IOException { xc.createNode("drjava/project/classpath"); if (!_classPathFiles.isEmpty()) { for(AbsRelFile cp: _classPathFiles) { - path = cp.keepAbsolute()?cp.getAbsolutePath():FileOps.stringMakeRelativeTo(cp, _projectRoot); + path = cp.keepAbsolute() ? cp.getAbsolutePath():FileOps.stringMakeRelativeTo(cp, _projectRoot); path = replace(path, File.separator, "/"); Node f = xc.createNode("drjava/project/classpath/file", null, false); xc.set(".name", path, f, true); diff --git a/drjava/src/edu/rice/cs/drjava/ui/EditExternalDialog.java b/drjava/src/edu/rice/cs/drjava/ui/EditExternalDialog.java index 4d044c6bb..079da853e 100644 --- a/drjava/src/edu/rice/cs/drjava/ui/EditExternalDialog.java +++ b/drjava/src/edu/rice/cs/drjava/ui/EditExternalDialog.java @@ -56,8 +56,6 @@ import edu.rice.cs.plt.lambda.Runnable1; import edu.rice.cs.plt.lambda.LambdaUtil; - - public class EditExternalDialog extends SwingFrame implements OptionConstants { private static final int FRAME_WIDTH = 503; private static final int FRAME_HEIGHT = 318; @@ -125,26 +123,26 @@ public String toString() { protected CompletionMonitor _editExternalDialogMonitor = new CompletionMonitor(); /** Filter for drjava external process files (.djapp) */ - private final FileFilter _extProcFilter = new javax.swing.filechooser.FileFilter() { - public boolean accept(File f) { - return f.isDirectory() || - f.getPath().endsWith(OptionConstants.EXTPROCESS_FILE_EXTENSION); - } - public String getDescription() { - return "DrJava External Process Files (*" + EXTPROCESS_FILE_EXTENSION + ")"; - } - }; - - /** Filter for drjava project files (.djapp only) */ - private final FileFilter _saveExtProcFilter = new javax.swing.filechooser.FileFilter() { - public boolean accept(File f) { - return f.isDirectory() || - f.getPath().endsWith(OptionConstants.EXTPROCESS_FILE_EXTENSION); - } - public String getDescription() { - return "DrJava External Process Files (*" + PROJECT_FILE_EXTENSION + ")"; - } - }; +// private final FileFilter _extProcFilter = new javax.swing.filechooser.FileFilter() { +// public boolean accept(File f) { +// return f.isDirectory() || +// f.getPath().endsWith(OptionConstants.EXTPROCESS_FILE_EXTENSION); +// } +// public String getDescription() { +// return "DrJava External Process Files (*" + EXTPROCESS_FILE_EXTENSION + ")"; +// } +// }; + +// /** Filter for drjava project files (.djapp only) */ +// private final FileFilter _saveExtProcFilter = new javax.swing.filechooser.FileFilter() { +// public boolean accept(File f) { +// return f.isDirectory() || +// f.getPath().endsWith(OptionConstants.EXTPROCESS_FILE_EXTENSION); +// } +// public String getDescription() { +// return "DrJava External Process Files (*" + PROJECT_FILE_EXTENSION + ")"; +// } +// }; /** For opening files. We have a persistent dialog to keep track of the last directory from which we opened. */ private JFileChooser _importChooser; @@ -297,7 +295,7 @@ public void setCurrentDirectory(File dir) { } }; _importChooser.setPreferredSize(new Dimension(650, 410)); - _importChooser.setFileFilter(_extProcFilter); +// _importChooser.setFileFilter(_extProcFilter); _importChooser.setMultiSelectionEnabled(false); _exportChooser = new JFileChooser() { @@ -308,10 +306,10 @@ public void setCurrentDirectory(File dir) { } }; _exportChooser.setPreferredSize(new Dimension(650, 410)); - _exportChooser.setFileFilter(_saveExtProcFilter); +// _exportChooser.setFileFilter(_saveExtProcFilter); } - /** Method that handels the OK button */ + /** Method that handles the OK button */ private void _ok() { _lastState = new FrameState(this); DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_COUNT, @@ -346,7 +344,7 @@ public void run() { }).start(); } - /** Method that handels the remove button */ + /** Method that handles the remove button */ private void _remove() { int count = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_COUNT); final int selectedIndex = _list.getSelectedIndex(); @@ -369,9 +367,9 @@ private void _remove() { v.remove(selectedIndex); DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_WORKDIRS,v); - v = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES); - v.remove(selectedIndex); - DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES,v); +// v = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES); +// v.remove(selectedIndex); +// DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES,v); --count; DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_COUNT, count); @@ -404,10 +402,10 @@ private void _up() { v.add(selectedIndex-1,s); DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_WORKDIRS,v); - v = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES); - s = v.remove(selectedIndex); - v.add(selectedIndex-1,s); - DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES,v); +// v = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES); +// s = v.remove(selectedIndex); +// v.add(selectedIndex-1,s); +// DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES,v); DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_COUNT, count); updateList(Math.max(0,selectedIndex-1)); @@ -439,10 +437,10 @@ private void _down() { v.add(selectedIndex+1,s); DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_WORKDIRS,v); - v = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES); - s = v.remove(selectedIndex); - v.add(selectedIndex+1,s); - DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES,v); +// v = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES); +// s = v.remove(selectedIndex); +// v.add(selectedIndex+1,s); +// DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES,v); DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_COUNT, count); updateList(Math.max(0,selectedIndex+1)); @@ -460,17 +458,17 @@ public void _import() { } case JFileChooser.APPROVE_OPTION: { - File[] chosen = _importChooser.getSelectedFiles(); - if (chosen == null) { - return; - } - // If this is a single-selection dialog, getSelectedFiles() will always - // return a zero-size array -- handle it differently. - if (chosen.length == 0) { - File f = _importChooser.getSelectedFile(); - MainFrame.openExtProcessFile(f); - updateList(DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_COUNT)-1); - } +// File[] chosen = _importChooser.getSelectedFiles(); +// if (chosen == null) { +// return; +// } +// // If this is a single-selection dialog, getSelectedFiles() will always +// // return a zero-size array -- handle it differently. +// if (chosen.length == 0) { +// File f = _importChooser.getSelectedFile(); +// MainFrame.openExtProcessFile(f); +// updateList(DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_COUNT)-1); +// } return; } @@ -505,9 +503,9 @@ public void _export() { // return a zero-size array -- handle it differently. if (chosen.length == 0) { File f = _exportChooser.getSelectedFile(); - if (!f.getName().endsWith(OptionConstants.EXTPROCESS_FILE_EXTENSION)) { - f = new File(f.getAbsolutePath()+OptionConstants.EXTPROCESS_FILE_EXTENSION); - } +// if (!f.getName().endsWith(OptionConstants.EXTPROCESS_FILE_EXTENSION)) { +// f = new File(f.getAbsolutePath()+OptionConstants.EXTPROCESS_FILE_EXTENSION); +// } //System.out.println("\tindex=" + _list.getSelectedIndex() + ", file=" + f); ExecuteExternalDialog.saveToFile(_list.getSelectedIndex(), f); } diff --git a/drjava/src/edu/rice/cs/drjava/ui/ErrorPanel.java b/drjava/src/edu/rice/cs/drjava/ui/ErrorPanel.java index 608b3259b..7c6f2b321 100644 --- a/drjava/src/edu/rice/cs/drjava/ui/ErrorPanel.java +++ b/drjava/src/edu/rice/cs/drjava/ui/ErrorPanel.java @@ -74,33 +74,33 @@ public abstract class ErrorPanel extends TabbedPanel implements OptionConstants /** The total number of errors in the list */ protected volatile int _numErrors; - protected volatile JCheckBox _showHighlightsCheckBox; + protected final JCheckBox _showHighlightsCheckBox; - protected volatile SingleDisplayModel _model; + protected final SingleDisplayModel _model; - private volatile JScrollPane _scroller; + private final JScrollPane _scroller; /** This contains the _scroller and the _errorNavPanel. */ - private volatile JPanel _leftPanel; + private final JPanel _leftPanel; /** This contains the label, showHighlightsCheckBox, and the customPanel. */ - private volatile JPanel _rightPanel; + private final JPanel _rightPanel; - private volatile JPanel _errorNavPanel; + private final JPanel _errorNavPanel; - private volatile JPanel _errorNavButtonsPanel; + private final JPanel _errorNavButtonsPanel; /** This JPanel contains each child panel's specific UI components. **/ - protected volatile JPanel customPanel; + protected final JPanel customPanel; - private volatile JButton _nextErrorButton; - private volatile JButton _prevErrorButton; + private final JButton _nextErrorButton; + private final JButton _prevErrorButton; /** _popupMenu and _popupMenuListener are either both null or both non-null. */ protected volatile JPopupMenu _popupMenu = null; protected volatile RightClickMouseAdapter _popupMenuListener = null; - /** Highlight painter for selected list items. */ + /** Highlight painter for selected list items. Not final because it is rebound in CompilerErrorColorOptionListener */ static volatile ReverseHighlighter.DrJavaHighlightPainter _listHighlightPainter = new ReverseHighlighter.DrJavaHighlightPainter(DrJava.getConfig().getSetting(COMPILER_ERROR_COLOR)); @@ -211,7 +211,7 @@ public void actionPerformed(ActionEvent e) { protected void setErrorListPane(final ErrorListPane elp) { if (_popupMenuListener!=null) { - if ((_scroller!=null) && + if ((_scroller!=null) && // unnecessary? (_scroller.getViewport()!=null) && (_scroller.getViewport().getView()!=null)) { _scroller.getViewport().getView().removeMouseListener(_popupMenuListener); @@ -960,7 +960,7 @@ protected void _popupAction(MouseEvent e) { } }; addMouseListener(_popupMenuListener); - if (_scroller!=null) { + if (_scroller!=null) { // test unnecessary? _scroller.addMouseListener(_popupMenuListener); if (_scroller.getViewport().getView()!=null) { _scroller.getViewport().getView().addMouseListener(_popupMenuListener); diff --git a/drjava/src/edu/rice/cs/drjava/ui/ExecuteExternalDialog.java b/drjava/src/edu/rice/cs/drjava/ui/ExecuteExternalDialog.java index 601ae1184..da2850d7b 100644 --- a/drjava/src/edu/rice/cs/drjava/ui/ExecuteExternalDialog.java +++ b/drjava/src/edu/rice/cs/drjava/ui/ExecuteExternalDialog.java @@ -148,8 +148,6 @@ public String toString() { DocumentListener _documentListener; /** Command line work directory document listener. */ DocumentListener _workDirDocumentListener; - /** Command line enclosing file document listener. */ - DocumentListener _enclosingFileDocumentListener; /** Directory chooser to open when clicking the "..." button. */ protected DirectoryChooser _dirChooser; @@ -210,7 +208,7 @@ public void setFrameState(String s) { } /** Create a dialog. - * @param mf the instance of mainframe to query into the project + * @param mf the instance of mainframe to query the external projec * @param editMode true if a saved external process is edited * @param editIndex index of the saved external processes to edit * @param cm completion monitor telling the calling dialog that we are done @@ -226,16 +224,13 @@ public ExecuteExternalDialog(MainFrame mf, boolean editMode, int editIndex, Comp _cm = cm; initComponents(); if (editMode) { - if (editIndex>=DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_COUNT)) { + if (editIndex >= DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_COUNT)) { throw new IllegalArgumentException("Trying to edit saved external process that does not exist"); } final String cmdline = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_CMDLINES).get(editIndex); final String workdir = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_WORKDIRS).get(editIndex); - final String enclosingFile = - DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES).get(editIndex); _commandLine.setText(cmdline); _commandWorkDirLine.setText(workdir); - _commandEnclosingFileLine.setText(enclosingFile); } initDone(); // call mandated by SwingFrame contract } @@ -243,9 +238,7 @@ public ExecuteExternalDialog(MainFrame mf, boolean editMode, int editIndex, Comp /** Create a dialog with the "Run" button. * @param mf the instance of mainframe to query into the project */ - public ExecuteExternalDialog(MainFrame mf) { - this(mf, false, -1, null); - } + public ExecuteExternalDialog(MainFrame mf) { this(mf, false, -1, null); } /** Build the dialog. */ private void initComponents() { @@ -253,7 +246,7 @@ private void initComponents() { _dirChooser.setDialogTitle("Select Work Directory"); _dirChooser.setApproveButtonText("Select"); _fileChooser = new FileChooser(null); - _fileChooser.setDialogTitle("Select Enclosing .djapp File"); +// _fileChooser.setDialogTitle("Select Enclosing .djapp File"); _fileChooser.setApproveButtonText("Select"); super.getContentPane().setLayout(new GridLayout(1,1)); @@ -482,45 +475,6 @@ public void keyTyped(KeyEvent e) { } gridbag.setConstraints(commandWorkDirLinePreviewSP, c); main.add(commandWorkDirLinePreviewSP); - // enclosing .djapp file - c.weightx = 0.0; - c.weighty = 0.0; - c.gridwidth = 1; - c.insets = labelInsets; - JLabel enclosingFileLabel = new JLabel("Enclosing .djapp file:"); - gridbag.setConstraints(enclosingFileLabel, c); - main.add(enclosingFileLabel); - - c.weightx = 1.0; - c.weighty = 8.0; - c.gridwidth = GridBagConstraints.RELATIVE; - c.insets = compInsets; - - _commandEnclosingFileLine = new JTextPane(); - // do not allow a newline - _commandEnclosingFileLine.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if (e.getKeyCode() == KeyEvent.VK_ENTER) e.consume(); - else if (e.getKeyCode() == KeyEvent.VK_TAB) { - e.consume(); - if (e.isShiftDown()) _commandWorkDirLine.requestFocus(); - else { - _insertCommandButton.setEnabled(false); - if (_editMode) { - _saveCommandButton.requestFocus(); - } - else _runCommandButton.requestFocus(); - } - } - } - public void keyReleased(KeyEvent e) { } - public void keyTyped(KeyEvent e) { } - }); - JScrollPane commandEnclosingFileLineSP = new JScrollPane(_commandEnclosingFileLine); - commandEnclosingFileLineSP.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); - gridbag.setConstraints(commandEnclosingFileLineSP, c); - main.add(commandEnclosingFileLineSP); - c.weightx = 0.0; c.weighty = 0.0; c.gridwidth = GridBagConstraints.REMAINDER; @@ -631,36 +585,6 @@ public void update(DocumentEvent e) { _commandWorkDirLine.setText("${drjava.working.dir}"); _workDirDocumentListener.changedUpdate(null); - // update the preview of the actual enclosing .djapp file post substitution - _enclosingFileDocumentListener = new DocumentListener() { - public void update(DocumentEvent e) { - assert EventQueue.isDispatchThread(); - try { - // preview - _commandEnclosingFileLineDoc.remove(0,_commandEnclosingFileLineDoc.getLength()); - String text = StringOps.replaceVariables(_commandEnclosingFileLine.getText(), _props, PropertyMaps.GET_LAZY); - _commandEnclosingFileLineDoc.insertString(0, StringOps.unescapeFileName(text), null); - - // command line - colorVariables(_commandEnclosingFileLine, - _props, - this, - _commandLineCmdAS, - _varCommandLineCmdStyle, - _varErrorCommandLineCmdStyle); - } - catch(BadLocationException ble) { - _commandLinePreview.setText("Error: " + ble); - } - } - public void changedUpdate(DocumentEvent e) { update(e); } - public void insertUpdate(DocumentEvent e) { update(e); } - public void removeUpdate(DocumentEvent e) { update(e); } - }; - _commandEnclosingFileLine.getDocument().addDocumentListener(_enclosingFileDocumentListener); - _commandEnclosingFileLine.setText(""); - _enclosingFileDocumentListener.changedUpdate(null); - _lastCommandFocus = _commandLine; // do not allow preview to have focus _commandLine.addFocusListener(new FocusAdapter() { @@ -814,19 +738,15 @@ private void _cancel() { } // public static edu.rice.cs.util.Log LOG = new edu.rice.cs.util.Log("process.txt", false); - /** Run a command and return an external process panel. * @param name name of the process * @param cmdline the command line to execute, before evaluation * @param workdir the work directory, before evaluation - * @param enclosingFile the enclosing .djapp JAR file, or "" if not enclosed * @param pm PropertyMaps used for substitution when replacing variables * @return ExternalProcessPanel that displays the output of the process */ - public ExternalProcessPanel runCommand(String name, String cmdline, String workdir, - String enclosingFile, PropertyMaps pm) { - ((MutableFileProperty)pm.getProperty("enclosing.djapp.file")).setFile(enclosingFile.length() > 0? - new File(enclosingFile):null); + public ExternalProcessPanel runCommand(String name, String cmdline, String workdir, PropertyMaps pm) { + ProcessCreator pc = new GeneralProcessCreator(cmdline, workdir.trim(), pm); String label = "External"; if (!name.equals("")) { label += ": " + name; } @@ -845,16 +765,13 @@ public ExternalProcessPanel runCommand(String name, String cmdline, String workd /** Execute the command line. */ private void _runCommand() { - _mainFrame.updateStatusField("Executing external process..."); - GeneralProcessCreator.LOG.log("_runCommand(): ${enclosing.djapp.file} = " + _commandEnclosingFileLine.getText()); _mainFrame.removeModalWindowAdapter(this); if (_commandLinePreview.getText().length() > 0) { try { _props = PropertyMaps.TEMPLATE.clone(); PropertyMaps pm = _props.clone(); - runCommand("", _commandLine.getText(), _commandWorkDirLine.getText(), - _commandEnclosingFileLine.getText().trim(), pm); + runCommand("", _commandLine.getText(), _commandWorkDirLine.getText(), pm); } catch(CloneNotSupportedException e) { throw new edu.rice.cs.util.UnexpectedException(e); } } @@ -879,8 +796,7 @@ private void _saveCommand() { if (_cm != null) { _cm.signal(); } return; } - editInMenu(_editIndex, name, _commandLine.getText(), _commandWorkDirLine.getText(), - _commandEnclosingFileLine.getText()); + editInMenu(_editIndex, name, _commandLine.getText(), _commandWorkDirLine.getText()); } else { int count = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_COUNT); @@ -894,7 +810,7 @@ private void _saveCommand() { if (_cm != null) { _cm.signal(); } return; } - addToMenu(name, _commandLine.getText(), _commandWorkDirLine.getText(), _commandEnclosingFileLine.getText()); + addToMenu(name, _commandLine.getText(), _commandWorkDirLine.getText()); } // Always apply and save settings @@ -907,18 +823,14 @@ private void _saveCommand() { * @param name process name * @param cmdline command line * @param workdir work directory - * @param enclosingFile the enclosing .djapp JAR file, or "" if not enclosed * @return number of processes in the menu */ - public static int addToMenu(String name, String cmdline, String workdir, String enclosingFile) { - GeneralProcessCreator.LOG.log("addToMenu(): enclosingFile = " + enclosingFile); + public static int addToMenu(String name, String cmdline, String workdir) { int count = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_COUNT); ++count; final Vector names = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_NAMES); final Vector cmdlines = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_CMDLINES); final Vector workdirs = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_WORKDIRS); - final Vector enclosingFiles = - DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES); - + names.add(name); DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_NAMES,names); @@ -927,10 +839,6 @@ public static int addToMenu(String name, String cmdline, String workdir, String workdirs.add(workdir); DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_WORKDIRS,workdirs); - - enclosingFiles.add(enclosingFile); - DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES,enclosingFiles); - DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_COUNT,count); return count; @@ -941,14 +849,11 @@ public static int addToMenu(String name, String cmdline, String workdir, String * @param name process name * @param cmdline command line * @param workdir work directory - * @param enclosingFile the enclosing .djapp JAR file, or "" if not enclosed */ - public static void editInMenu(int editIndex, String name, String cmdline, String workdir, String enclosingFile) { - GeneralProcessCreator.LOG.log("editInMenu(): enclosingFile = " + enclosingFile); + public static void editInMenu(int editIndex, String name, String cmdline, String workdir) { final Vector names = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_NAMES); final Vector cmdlines = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_CMDLINES); final Vector workdirs = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_WORKDIRS); - final Vector enclosingFiles = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES); names.set(editIndex,name); DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_NAMES,names); @@ -958,9 +863,6 @@ public static void editInMenu(int editIndex, String name, String cmdline, String workdirs.set(editIndex,workdir); DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_WORKDIRS,workdirs); - - enclosingFiles.set(editIndex,enclosingFile); - DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES,enclosingFiles); } /** Save process to file. @@ -970,15 +872,11 @@ public static void saveToFile(int index, File f) { final Vector names = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_NAMES); final Vector cmdlines = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_CMDLINES); final Vector workdirs = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_WORKDIRS); - final Vector enclosingFiles = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES); XMLConfig xc = new XMLConfig(); -// System.out.println("saveToFile(" + index + ", " + f + ")"); -// System.out.println("\t" + names.get(index)); xc.set("drjava/extprocess/name", names.get(index)); xc.set("drjava/extprocess/cmdline", cmdlines.get(index)); xc.set("drjava/extprocess/workdir", workdirs.get(index)); - xc.set("drjava/extprocess/enlcosingfile", enclosingFiles.get(index)); xc.save(f); } diff --git a/drjava/src/edu/rice/cs/drjava/ui/FindResultsPanel.java b/drjava/src/edu/rice/cs/drjava/ui/FindResultsPanel.java index 25226ac7f..999971f6c 100644 --- a/drjava/src/edu/rice/cs/drjava/ui/FindResultsPanel.java +++ b/drjava/src/edu/rice/cs/drjava/ui/FindResultsPanel.java @@ -107,7 +107,7 @@ public class FindResultsPanel extends RegionsTreePanel { * @param noComments whether the search ignored comments * @param noTestCases whether the search ignored test cases * @param doc weak reference to the document in which the search occurred (or started, if all documents were searched) - * @param findReplace the FindReplacePanel that created this FindResultsPanel + * @param findReplacePanel the FindReplacePanel that created this FindResultsPanel */ public FindResultsPanel(final MainFrame frame, final RegionManager regionManager, final MovingDocumentRegion region, final String title, final String searchString, diff --git a/drjava/src/edu/rice/cs/drjava/ui/GenerateCustomDrJavaJarFrame.java b/drjava/src/edu/rice/cs/drjava/ui/GenerateCustomDrJavaJarFrame.java index 0eac59ed7..406cc2cdb 100644 --- a/drjava/src/edu/rice/cs/drjava/ui/GenerateCustomDrJavaJarFrame.java +++ b/drjava/src/edu/rice/cs/drjava/ui/GenerateCustomDrJavaJarFrame.java @@ -65,16 +65,16 @@ public class GenerateCustomDrJavaJarFrame extends SwingFrame { private final JButton _generateButton; private final JButton _checkButton; private final JButton _closeButton; - private JPanel _mainPanel; + private final JPanel _mainPanel; /** The file with the current DrJava executable. */ private final File _drjavaFile = FileOps.getDrJavaFile(); - /** File selector for the jar output file. */ - private FileSelectorComponent _jarFileSelector; + /** File selector for the jar output file. Not final because it is rebound in _makeJarFileSelector(). */ + private volatile FileSelectorComponent _jarFileSelector; /** List with additional sources. */ - private VectorFileOptionComponent _sourcesList; + private volatile VectorFileOptionComponent _sourcesList; /** Constructs a frame to generate a custom drjava.jar. * @param mf reference to the main frame @@ -83,7 +83,7 @@ public GenerateCustomDrJavaJarFrame(MainFrame mf) { super("Generate Custom drjava.jar File"); _mainFrame = mf; - _mainPanel= new JPanel(); + _mainPanel = new JPanel(); Action generateAction = new AbstractAction("Generate") { public void actionPerformed(ActionEvent e) { generate(); } diff --git a/drjava/src/edu/rice/cs/drjava/ui/JUnitPanel.java b/drjava/src/edu/rice/cs/drjava/ui/JUnitPanel.java index 40ffb9ca5..01db9187f 100644 --- a/drjava/src/edu/rice/cs/drjava/ui/JUnitPanel.java +++ b/drjava/src/edu/rice/cs/drjava/ui/JUnitPanel.java @@ -35,6 +35,7 @@ import edu.rice.cs.util.UnexpectedException; import edu.rice.cs.util.swing.BorderlessScrollPane; import edu.rice.cs.util.swing.RightClickMouseAdapter; +import edu.rice.cs.util.swing.Utilities; import javax.swing.*; import javax.swing.border.EmptyBorder; @@ -47,7 +48,8 @@ import java.io.File; import java.util.HashMap; -/** The panel that displays all the testing errors. +/** The panel that displays all the testing errors. All non-trivial methods in this class other than constructors should + * only be called from the dispatch thread, except during set up of MainFrame. * @version $Id$ */ public class JUnitPanel extends ErrorPanel { @@ -80,12 +82,12 @@ private static final SimpleAttributeSet _getTestFailAttributes() { private static final String TEST_OUT_OF_SYNC = "The documents being tested have been modified and should be recompiled!\n"; - protected JUnitErrorListPane _errorListPane; + protected volatile JUnitErrorListPane _errorListPane; private final MainFrame _mainFrame; // only used in assert statements - private int _testCount; - private boolean _testsSuccessful; + private volatile int _testCount; + private volatile boolean _testsSuccessful; - private volatile JUnitProgressBar _progressBar; + private final JUnitProgressBar _progressBar; private Action _showStackTraceAction = new AbstractAction("Show Stack Trace") { public void actionPerformed(ActionEvent ae) { @@ -100,7 +102,7 @@ public void actionPerformed(ActionEvent ae) { /** The currently selected error. */ private volatile JUnitError _error = null; private volatile Window _stackFrame = null; - private volatile JTextArea _stackTextArea; + private volatile JTextArea _stackTextArea; // not final because it is rebound in _setupStackTraceFrame() private final JLabel _errorLabel = new JLabel(); private final JLabel _testLabel = new JLabel(); private final JLabel _fileLabel = new JLabel(); @@ -134,6 +136,7 @@ public JUnitPanel(SingleDisplayModel model, MainFrame frame) { * @param newSet Style containing new attributes to use. */ protected void _updateStyles(AttributeSet newSet) { + assert ! _mainFrame.isVisible() || EventQueue.isDispatchThread(); super._updateStyles(newSet); OUT_OF_SYNC_ATTRIBUTES.addAttributes(newSet); StyleConstants.setBold(OUT_OF_SYNC_ATTRIBUTES, true); // should always be bold @@ -143,6 +146,7 @@ protected void _updateStyles(AttributeSet newSet) { /** called when work begins */ public void setJUnitInProgress() { + assert ! _mainFrame.isVisible() || EventQueue.isDispatchThread(); _errorListPane.setJUnitInProgress(); } @@ -156,6 +160,7 @@ protected void _close() { /** Reset the errors to the current error information. */ public void reset() { + assert ! _mainFrame.isVisible() || EventQueue.isDispatchThread(); JUnitErrorModel junitErrorModel = getModel().getJUnitModel().getJUnitErrorModel(); boolean testsHaveRun = false; if (junitErrorModel != null) { @@ -168,9 +173,10 @@ public void reset() { } /** Resets the progress bar to start counting the given number of tests. - * @param numTests number of tests to be counted - */ + * @param numTests number of tests to be counted + */ public void progressReset(int numTests) { + assert ! _mainFrame.isVisible() || EventQueue.isDispatchThread(); _progressBar.reset(); _progressBar.start(numTests); _testsSuccessful = true; @@ -181,6 +187,7 @@ public void progressReset(int numTests) { * @param successful Whether the last test was successful or not. */ public void progressStep(boolean successful) { + assert ! _mainFrame.isVisible() || EventQueue.isDispatchThread(); _testCount++; _testsSuccessful &= successful; _progressBar.step(_testCount, _testsSuccessful); @@ -189,6 +196,7 @@ public void progressStep(boolean successful) { public void testStarted(String className, String testName) { } private void _displayStackTrace (JUnitError e) { + assert ! _mainFrame.isVisible() || EventQueue.isDispatchThread(); _errorLabel.setText((e.isWarning() ? "Error: " : "Failure: ") + e.message()); _fileLabel.setText("File: " + (new File(e.fileName())).getName()); @@ -242,10 +250,11 @@ private String _getClassFromName(String name) { else throw new IllegalArgumentException("Name does not contain any parens: " + name); } - /** Provides the ability to display the name of the test being run. + /** Provides the the name of the test being run to the JUnitPanel. * @param name the name of the test being run */ public void testStarted(String name) { + assert ! _mainFrame.isVisible() || EventQueue.isDispatchThread(); if (name.indexOf('(') < 0) return; String testName = _getTestFromName(name); @@ -253,51 +262,62 @@ public void testStarted(String name) { String fullName = className + "." + testName; if (fullName.equals(JUNIT_WARNING)) return; ErrorDocument doc = getErrorDocument(); - try { - int len = doc.getLength(); - // Insert the classname if it has changed - if (! className.equals(_runningTestName)) { - _runningTestName = className; - doc.insertString(len, " " + className + "\n", NORMAL_ATTRIBUTES); - len = doc.getLength(); + + // Converted this GUI operation to a Runnable and use invokeLater + Utilities.invokeLater(new Runnable() { + public void run() { + try { + int len = doc.getLength(); + // Insert the classname if it has changed + if (! className.equals(_runningTestName)) { + _runningTestName = className; + doc.insertString(len, " " + className + "\n", NORMAL_ATTRIBUTES); + len = doc.getLength(); + } + + // Insert the test name, remembering its position + doc.insertString(len, " ", NORMAL_ATTRIBUTES); + len = doc.getLength(); + doc.insertString(len, testName + "\n", NORMAL_ATTRIBUTES); + Position pos = doc.createPosition(len); + _runningTestNamePositions.put(fullName, pos); + setCaretPosition(len); + } + catch (BadLocationException ble) { + // Inserting at end, shouldn't happen + throw new UnexpectedException(ble); + } } - - // Insert the test name, remembering its position - doc.insertString(len, " ", NORMAL_ATTRIBUTES); - len = doc.getLength(); - doc.insertString(len, testName + "\n", NORMAL_ATTRIBUTES); - Position pos = doc.createPosition(len); - _runningTestNamePositions.put(fullName, pos); - setCaretPosition(len); - } - catch (BadLocationException ble) { - // Inserting at end, shouldn't happen - throw new UnexpectedException(ble); - } + }); } - /** Displays the results of a test that has finished. + /** Displays the results of a test that has finished in the JUnitPanel. * @param name the name of the test * @param wasSuccessful whether the test was successful * @param causedError whether the test caused an error */ public void testEnded(String name, boolean wasSuccessful, boolean causedError) { + assert ! _mainFrame.isVisible() || EventQueue.isDispatchThread(); if (name.indexOf('(')<0) return; String testName = _getTestFromName(name); String fullName = _getClassFromName(name) + "." + testName; if (fullName.equals(JUNIT_WARNING)) return; - + // TODO: convert this GUI operation to a Runnable and use invokeLater ErrorDocument doc = getErrorDocument(); - Position namePos = _runningTestNamePositions.get(fullName); - AttributeSet set; - if (! wasSuccessful || causedError) set = TEST_FAIL_ATTRIBUTES; - else set = TEST_PASS_ATTRIBUTES; - if (namePos != null) { - int index = namePos.getOffset(); - int length = testName.length(); - doc.setCharacterAttributes(index, length, set, false); - } + Utilities.invokeLater(new Runnable() { + public void run() { + Position namePos = _runningTestNamePositions.get(fullName); + AttributeSet set; + if (! wasSuccessful || causedError) set = TEST_FAIL_ATTRIBUTES; + else set = TEST_PASS_ATTRIBUTES; + if (namePos != null) { + int index = namePos.getOffset(); + int length = testName.length(); + doc.setCharacterAttributes(index, length, set, false); + } + } + }); } /** Puts the error pane into "junit in progress" state. Only runs in event thread. */ @@ -319,6 +339,7 @@ public void setJUnitInProgress() { /** Used to show that testing was unsuccessful. */ protected void _updateWithErrors() throws BadLocationException { + assert ! _mainFrame.isVisible() || EventQueue.isDispatchThread(); //DefaultStyledDocument doc = new DefaultStyledDocument(); ErrorDocument doc = getErrorDocument(); // _checkSync(doc); @@ -415,6 +436,7 @@ protected void _updateNoErrors(boolean haveTestsRun) throws BadLocationException private void _setupStackTraceFrame() { //DrJava.consoleOut().println("Stack Trace for Error: \n" + e.stackTrace()); + assert ! _mainFrame.isVisible() || EventQueue.isDispatchThread(); JDialog _dialog = new JDialog(_frame,"JUnit Error Stack Trace",false); _stackFrame = _dialog; _stackTextArea = new JTextArea(); @@ -453,6 +475,7 @@ public void actionPerformed(ActionEvent e) { * and enabling the _showStackTraceButton. */ public void selectItem(DJError error) { + assert ! _mainFrame.isVisible() || EventQueue.isDispatchThread(); super.selectItem(error); _error = (JUnitError) error; _showStackTraceButton.setEnabled(true); @@ -461,6 +484,7 @@ public void selectItem(DJError error) { /** Overrides _removeListHighlight in ErrorListPane to disable the _showStackTraceButton. */ protected void _removeListHighlight() { + assert ! _mainFrame.isVisible() || EventQueue.isDispatchThread(); super._removeListHighlight(); _showStackTraceButton.setEnabled(false); } @@ -497,6 +521,7 @@ public void mouseReleased(MouseEvent e) { * @return true iff the mouse click is over an error */ private boolean _selectError(MouseEvent e) { + assert ! _mainFrame.isVisible() || EventQueue.isDispatchThread(); //TODO: get rid of cast in the next line, if possible _error = (JUnitError)_errorAtPoint(e.getPoint()); @@ -513,7 +538,10 @@ private boolean _selectError(MouseEvent e) { /** Shows the popup menu for this mouse adapter. * @param e the MouseEvent correponding to this click */ - protected void _popupAction(MouseEvent e) { _popMenu.show(e.getComponent(), e.getX(), e.getY()); } + protected void _popupAction(MouseEvent e) { + assert ! _mainFrame.isVisible() || EventQueue.isDispatchThread(); + _popMenu.show(e.getComponent(), e.getX(), e.getY()); + } } public String getErrorDocumentTitle() { return "Javadoc Errors"; } } @@ -532,6 +560,7 @@ public JUnitProgressBar() { } private Color getStatusColor() { + assert EventQueue.isDispatchThread(); if (_hasError) { return Color.red; } @@ -541,17 +570,20 @@ private Color getStatusColor() { } public void reset() { + assert EventQueue.isDispatchThread(); _hasError = false; setForeground(getStatusColor()); setValue(0); } public void start(int total) { + assert EventQueue.isDispatchThread(); setMaximum(total); reset(); } public void step(int value, boolean successful) { + assert EventQueue.isDispatchThread(); setValue(value); if (!_hasError && !successful) { _hasError= true; diff --git a/drjava/src/edu/rice/cs/drjava/ui/MainFrame.java b/drjava/src/edu/rice/cs/drjava/ui/MainFrame.java index 42c455e54..e132cfeda 100644 --- a/drjava/src/edu/rice/cs/drjava/ui/MainFrame.java +++ b/drjava/src/edu/rice/cs/drjava/ui/MainFrame.java @@ -1879,49 +1879,54 @@ private void generateJavaAPISet() { final ProcessingDialog pd = new ProcessingDialog(this, "Java API Classes", "Loading, please wait.", false); if (! EventQueue.isDispatchThread()) { pd.setVisible(true); } - // generate list - String linkVersion = DrJava.getConfig().getSetting(JAVADOC_API_REF_VERSION); -// // the string that will be ADDED to the beginning of the link to form the full URL -// String base = ""; -// -// // the string that will be REMOVED from the beginning of the link to form the fully-qualified class name -// String stripPrefix = ""; + String suffix = "/allclasses-1.8.html"; + _javaAPISet.addAll(_generateJavaAPISet(suffix)); - // the HTML file name that contains all the links - String suffix = ""; - if (linkVersion.equals(JAVADOC_AUTO_TEXT)) { - // use the compiler's version of the Java API Javadoc - JavaVersion ver = _model.getCompilerModel().getActiveCompiler().version(); - if (ver == JavaVersion.JAVA_6) linkVersion = JAVADOC_1_6_TEXT; - else if (ver == JavaVersion.JAVA_7) linkVersion = JAVADOC_1_7_TEXT; - else if (ver == JavaVersion.JAVA_8) linkVersion = JAVADOC_1_8_TEXT; - else linkVersion = JAVADOC_1_8_TEXT; // default - } - if (linkVersion.equals(JAVADOC_1_6_TEXT)) { - // at one point, the links in the 1.6 Javadoc were absolute, and this is how we dealt with that - // base = ""; // links in 1.6 Javadoc are absolute, so nothing needs to be added to get an absolute URL - // // but we do need to strip the absolute part to get correct fully-qualified class names - // // and we take the default string here, not what the user entered, because the links in - // // our allclasses-1.6.html file go to the original Sun website. - // base = DrJava.getConfig().getSetting(JAVADOC_1_6_LINK) + "/"; - // stripPrefix = ""; // nothing needs to be stripped, links in 1.6 Javadoc are relative - suffix = "/allclasses-1.6.html"; - } - else if (linkVersion.equals(JAVADOC_1_7_TEXT)) { -// base = DrJava.getConfig().getSetting(JAVADOC_1_7_LINK) + "/"; -// stripPrefix = ""; // nothing needs to be stripped, links in 1.7 Javadoc are relative - suffix = "/allclasses-1.7.html"; - } - else if (linkVersion.equals(JAVADOC_1_8_TEXT)) { -// base = DrJava.getConfig().getSetting(JAVADOC_1_8_LINK) + "/"; -// stripPrefix = ""; // nothing needs to be stripped, links in 1.8 Javadoc are relative - suffix = "/allclasses-1.8.html"; - } - if (! suffix.equals("")) _javaAPISet.addAll(_generateJavaAPISet(suffix)); - else { - // no valid Javadoc URL - } + /* Legacy code supporting Java versions prior to Java 8 */ + // generate list +// String linkVersion = DrJava.getConfig().getSetting(JAVADOC_API_REF_VERSION); +// +//// // the string that will be ADDED to the beginning of the link to form the full URL +//// String base = ""; +//// +//// // the string that will be REMOVED from the beginning of the link to form the fully-qualified class name +//// String stripPrefix = ""; +// +// // the HTML file name that contains all the links +// String suffix = ""; +// if (linkVersion.equals(JAVADOC_AUTO_TEXT)) { +// // use the compiler's version of the Java API Javadoc +// JavaVersion ver = _model.getCompilerModel().getActiveCompiler().version(); +// if (ver == JavaVersion.JAVA_6) linkVersion = JAVADOC_1_6_TEXT; +// else if (ver == JavaVersion.JAVA_7) linkVersion = JAVADOC_1_7_TEXT; +// else if (ver == JavaVersion.JAVA_8) linkVersion = JAVADOC_1_8_TEXT; +// else linkVersion = JAVADOC_1_8_TEXT; // default +// } +// if (linkVersion.equals(JAVADOC_1_6_TEXT)) { +// // at one point, the links in the 1.6 Javadoc were absolute, and this is how we dealt with that +// // base = ""; // links in 1.6 Javadoc are absolute, so nothing needs to be added to get an absolute URL +// // // but we do need to strip the absolute part to get correct fully-qualified class names +// // // and we take the default string here, not what the user entered, because the links in +// // // our allclasses-1.6.html file go to the original Sun website. +// // base = DrJava.getConfig().getSetting(JAVADOC_1_6_LINK) + "/"; +// // stripPrefix = ""; // nothing needs to be stripped, links in 1.6 Javadoc are relative +// suffix = "/allclasses-1.6.html"; +// } +// else if (linkVersion.equals(JAVADOC_1_7_TEXT)) { +//// base = DrJava.getConfig().getSetting(JAVADOC_1_7_LINK) + "/"; +//// stripPrefix = ""; // nothing needs to be stripped, links in 1.7 Javadoc are relative +// suffix = "/allclasses-1.7.html"; +// } +// else if (linkVersion.equals(JAVADOC_1_8_TEXT)) { +//// base = DrJava.getConfig().getSetting(JAVADOC_1_8_LINK) + "/"; +//// stripPrefix = ""; // nothing needs to be stripped, links in 1.8 Javadoc are relative +// suffix = "/allclasses-1.8.html"; +// } +// if (! suffix.equals("")) _javaAPISet.addAll(_generateJavaAPISet(suffix)); +// else { +// // no valid Javadoc URL +// } // add JUnit Set junitAPIList = _generateJavaAPISet("/allclasses-concjunit4.7.html"); @@ -2329,7 +2334,7 @@ public void saveTo(OutputStream os) throws IOException { }; /** Resets the Interactions pane. */ - private final Action _resetInteractionsAction = new AbstractAction("Reset Interactions") { + private final Action _resetInteractionsAction = new AbstractAction("Reset Interactions and Clear Console") { public void actionPerformed(ActionEvent ae) { if (! DrJava.getConfig().getSetting(INTERACTIONS_RESET_PROMPT).booleanValue()) { _doResetInteractions(); @@ -2354,11 +2359,12 @@ public void actionPerformed(ActionEvent ae) { private void _doResetInteractions() { _tabbedPane.setSelectedIndex(INTERACTIONS_TAB); - updateStatusField("Resetting Interactions"); + updateStatusField("Resetting Interactions and Clearing Console"); // Lots of work, so use another thread _interactionsPane.discardUndoEdits(); new Thread(new Runnable() { public void run() { + _model.resetConsole(); _model.resetInteractions(_model.getWorkingDirectory(), true); _closeSystemInAction.setEnabled(true); } @@ -3894,7 +3900,7 @@ else if (DrJava.getConfig().getSetting(OptionConstants.FILE_EXT_REGISTRATION) public void run() { int rc; Object[] options = {"Yes", "No", "Always", "Never"}; - String text = "Do you want to associate .java, .drjava and .djapp files with DrJava?\n" + + String text = "Do you want to associate .java and .drjava files with DrJava?\n" + "Double-clicking on those files will open them in DrJava.\n\n" + "Select 'Always' to let DrJava do this automatically.\n"+ "Select 'Never' if you don't want to be asked again.\n\n"+ @@ -7007,17 +7013,17 @@ private JMenu _setUpToolsMenu(int mask, boolean updateKeyboardManager) { final int namesCount = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_NAMES).size(); final int cmdlinesCount = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_CMDLINES).size(); final int workdirsCount = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_WORKDIRS).size(); - final int enclosingFileCount = - DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES).size(); +// final int enclosingFileCount = +// DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES).size(); if ((savedCount!=namesCount) || (savedCount!=cmdlinesCount) || - (savedCount!=workdirsCount) || - (savedCount!=enclosingFileCount)) { + (savedCount!=workdirsCount) /* || + (savedCount!=enclosingFileCount)*/) { DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_COUNT, 0); DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_NAMES, new Vector()); DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_CMDLINES, new Vector()); DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_WORKDIRS, new Vector()); - DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES, new Vector()); +// DrJava.getConfig().setSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES, new Vector()); } OptionListener externalSavedCountListener = @@ -7031,22 +7037,22 @@ public void optionChanged(final OptionEvent oce) { final Vector names = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_NAMES); final Vector cmdlines = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_CMDLINES); final Vector workdirs = DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_WORKDIRS); - final Vector enclosingfiles = - DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES); +// final Vector enclosingfiles = +// DrJava.getConfig().getSetting(OptionConstants.EXTERNAL_SAVED_ENCLOSING_DJAPP_FILES); - extMenu.insert(new AbstractAction(names.get(i)) { - public void actionPerformed(ActionEvent ae) { - try { - PropertyMaps pm = PropertyMaps.TEMPLATE.clone(); - String s = enclosingfiles.get(i).trim(); - ((MutableFileProperty) pm.getProperty("enclosing.djapp.file")). - setFile(s.length() > 0 ? new File(s) : null); - _executeExternalDialog. - runCommand(names.get(i),cmdlines.get(i),workdirs.get(i),enclosingfiles.get(i),pm); - } - catch(CloneNotSupportedException e) { throw new UnexpectedException(e); } - } - },i+2); +// extMenu.insert(new AbstractAction(names.get(i)) { +// public void actionPerformed(ActionEvent ae) { +// try { +// PropertyMaps pm = PropertyMaps.TEMPLATE.clone(); +// String s = enclosingfiles.get(i).trim(); +// ((MutableFileProperty) pm.getProperty("enclosing.djapp.file")). +// setFile(s.length() > 0 ? new File(s) : null); +// _executeExternalDialog. +// runCommand(names.get(i),cmdlines.get(i),workdirs.get(i),enclosingfiles.get(i),pm); +// } +// catch(CloneNotSupportedException e) { throw new UnexpectedException(e); } +// } +// },i+2); } if (oce.value > 0) { extMenu.addSeparator(); } extMenu.add(_editExternalProcessesAction); @@ -9542,7 +9548,7 @@ public void junitSuiteStarted(final int numTests) { public void junitTestStarted(final String name) { assert EventQueue.isDispatchThread(); - _junitPanel.getErrorListPane().testStarted(name); /* this does nothing! */ + _junitPanel.getErrorListPane().testStarted(name); /* passes test name to errorListPane */ } public void junitTestEnded(final String name, final boolean succeeded, final boolean causedError) { @@ -10434,9 +10440,9 @@ public void drop(DropTargetDropEvent dropTargetDropEvent) { if (file.isFile() && (DrJavaFileUtils.isSourceFile(file) || file.getName().endsWith(".txt"))) { filteredFileList.add(file); } - else if (file.isFile() && file.getName().endsWith(OptionConstants.EXTPROCESS_FILE_EXTENSION)) { - openExtProcessFile(file); - } +// else if (file.isFile() && file.getName().endsWith(OptionConstants.EXTPROCESS_FILE_EXTENSION)) { +// openExtProcessFile(file); +// } } final File[] fileArray = filteredFileList.toArray(new File[filteredFileList.size()]); FileOpenSelector fs = new FileOpenSelector() { @@ -10459,48 +10465,48 @@ else if (file.isFile() && file.getName().endsWith(OptionConstants.EXTPROCESS_FIL } } - /** Open stand-alone external process file. - * @param file the file to be opened - */ - public static void openExtProcessFile(File file) { - try { - XMLConfig xc = new XMLConfig(file); - String name = xc.get("drjava/extprocess/name"); - ExecuteExternalDialog.addToMenu(name, xc.get("drjava/extprocess/cmdline"), - xc.get("drjava/extprocess/workdir"), ""); - JOptionPane.showMessageDialog(null, "The installation was successful for:\n"+name, - "Installation Successful", JOptionPane.INFORMATION_MESSAGE); - // We override the drjava/extprocess/enclosingfile and set it to the empty string "" - // because this external process did not come from a *.djapp file that was a JAR file. - } - catch(XMLConfigException xce) { - // this wasn't an XML file, try to treat it as a jar file - openExtProcessJarFile(file); - } - } +// /** Open stand-alone external process file. +// * @param file the file to be opened +// */ +// public static void openExtProcessFile(File file) { +// try { +// XMLConfig xc = new XMLConfig(file); +// String name = xc.get("drjava/extprocess/name"); +// ExecuteExternalDialog.addToMenu(name, xc.get("drjava/extprocess/cmdline"), +// xc.get("drjava/extprocess/workdir"), ""); +// JOptionPane.showMessageDialog(null, "The installation was successful for:\n"+name, +// "Installation Successful", JOptionPane.INFORMATION_MESSAGE); +// // We override the drjava/extprocess/enclosingfile and set it to the empty string "" +// // because this external process did not come from a *.djapp file that was a JAR file. +// } +// catch(XMLConfigException xce) { +// // this wasn't an XML file, try to treat it as a jar file +// openExtProcessJarFile(file); +// } +// } - /** Open external process file in a jar file. - * @param file the file to be opened - */ - public static void openExtProcessJarFile(File file) { - try { - JarFile jf = new JarFile(file); - JarEntry je = jf.getJarEntry(EXTPROCESS_FILE_NAME_INSIDE_JAR); - InputStream is = jf.getInputStream(je); - XMLConfig xc = new XMLConfig(is); - String name = xc.get("drjava/extprocess/name"); - ExecuteExternalDialog.addToMenu(name, xc.get("drjava/extprocess/cmdline"), - xc.get("drjava/extprocess/workdir"), file.getAbsolutePath()); - JOptionPane.showMessageDialog(null, "The installation was successful for:\n"+name, - "Installation Successful", JOptionPane.INFORMATION_MESSAGE); - // We override the drjava/extprocess/enclosingfile and set it to the file specified - // because this external process came from a *.djapp file that was a JAR file. - is.close(); - jf.close(); - } - catch(IOException ioe) { /* ignore drop */ } - catch(XMLConfigException xce) { /* ignore drop */ } - } +// /** Open external process file in a jar file. +// * @param file the file to be opened +// */ +// public static void openExtProcessJarFile(File file) { +// try { +// JarFile jf = new JarFile(file); +// JarEntry je = jf.getJarEntry(EXTPROCESS_FILE_NAME_INSIDE_JAR); +// InputStream is = jf.getInputStream(je); +// XMLConfig xc = new XMLConfig(is); +// String name = xc.get("drjava/extprocess/name"); +// ExecuteExternalDialog.addToMenu(name, xc.get("drjava/extprocess/cmdline"), +// xc.get("drjava/extprocess/workdir"), file.getAbsolutePath()); +// JOptionPane.showMessageDialog(null, "The installation was successful for:\n"+name, +// "Installation Successful", JOptionPane.INFORMATION_MESSAGE); +// // We override the drjava/extprocess/enclosingfile and set it to the file specified +// // because this external process came from a *.djapp file that was a JAR file. +// is.close(); +// jf.close(); +// } +// catch(IOException ioe) { /* ignore drop */ } +// catch(XMLConfigException xce) { /* ignore drop */ } +// } /** Convert a string with URIs to a list of files. * @param data string with URIs @@ -10528,10 +10534,10 @@ private static List textURIListToFileList(String data) { * @param lineNo line number to jump to, or -1 of not specified */ public void handleRemoteOpenFile(final File f, final int lineNo) { - if (f.getName().endsWith(OptionConstants.EXTPROCESS_FILE_EXTENSION)) { - openExtProcessFile(f); - } - else { +// if (f.getName().endsWith(OptionConstants.EXTPROCESS_FILE_EXTENSION)) { +// openExtProcessFile(f); +// } +// else { final FileOpenSelector openSelector = new FileOpenSelector() { public File[] getFiles() throws OperationCanceledException { return new File[] { f }; @@ -10558,7 +10564,7 @@ public void run() { } }); } - } +// } } /** Follow a file. */ diff --git a/drjava/src/edu/rice/cs/drjava/ui/NewJavaClassDialog.java b/drjava/src/edu/rice/cs/drjava/ui/NewJavaClassDialog.java index 4d32a5757..a92666965 100644 --- a/drjava/src/edu/rice/cs/drjava/ui/NewJavaClassDialog.java +++ b/drjava/src/edu/rice/cs/drjava/ui/NewJavaClassDialog.java @@ -67,7 +67,7 @@ public class NewJavaClassDialog extends SwingFrame { private final JButton _okButton; private final JButton _cancelButton; - private JPanel _mainPanel; + private final JPanel _mainPanel; private final JTextField _className = new JTextField(); private final JTextField _interfaces = new JTextField(); private final JTextField _superClass = new JTextField(); diff --git a/drjava/src/edu/rice/cs/drjava/ui/RegionsTreePanel.java b/drjava/src/edu/rice/cs/drjava/ui/RegionsTreePanel.java index 84dcd8a6a..140ad9719 100644 --- a/drjava/src/edu/rice/cs/drjava/ui/RegionsTreePanel.java +++ b/drjava/src/edu/rice/cs/drjava/ui/RegionsTreePanel.java @@ -30,13 +30,9 @@ import java.awt.*; import java.awt.event.*; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.SortedSet; -import java.util.NoSuchElementException; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; import javax.swing.*; import javax.swing.event.*; @@ -786,8 +782,15 @@ public void addRegion(final R r) { // } // else { @SuppressWarnings("unchecked") - Enumeration regionNodes = docNode.children(); - + Enumeration rawNodes = docNode.children(); + Iterator nodeIterator = StreamSupport.stream(Spliterators.spliteratorUnknownSize((Iterator) rawNodes, 0), false) + .map(node -> (DefaultMutableTreeNode) node) + .iterator(); + + Enumeration regionNodes = Collections.enumeration( + StreamSupport.stream(Spliterators.spliteratorUnknownSize(nodeIterator, 0), false) + .collect(Collectors.toList())); + // Create a new region node in this document node list, where regions are sorted by start offset. int startOffset = r.getStartOffset(); for (int index = 0; true ; index++) { // infinite loop incrementing index on each iteration diff --git a/drjava/src/edu/rice/cs/drjava/ui/config/ConfigFrame.java b/drjava/src/edu/rice/cs/drjava/ui/config/ConfigFrame.java index ea1781e78..ef989cfab 100644 --- a/drjava/src/edu/rice/cs/drjava/ui/config/ConfigFrame.java +++ b/drjava/src/edu/rice/cs/drjava/ui/config/ConfigFrame.java @@ -1081,26 +1081,26 @@ private void _setupJVMsPanel(ConfigPanel panel) { */ private void _setupFileTypesPanel(ConfigPanel panel) { if (PlatformFactory.ONLY.canRegisterFileExtensions()) { - addOptionComponent(panel, new LabelComponent("Assign DrJava project files and DrJava extensions
"+ - "(with the extensions .drjava and .djapp) to DrJava.
"+ + addOptionComponent(panel, new LabelComponent("Assign DrJava project files"+ + "(with the extension .drjava) to DrJava.
"+ "When double-clicking on a .drjava file, DrJava will open it.", this, true)); panel.addComponent(new ButtonComponent(new ActionListener() { public void actionPerformed(ActionEvent e) { if (PlatformFactory.ONLY.registerDrJavaFileExtensions()) { JOptionPane.showMessageDialog(ConfigFrame.this, - "Successfully set .drjava and .djapp file associations.", + "Successfully set .drjava file associations.", "Success", JOptionPane.INFORMATION_MESSAGE); } else { JOptionPane.showMessageDialog(ConfigFrame.this, - "Could not set .drjava and .djapp file associations.", + "Could not set .drjava file associations.", "File Types Error", JOptionPane.ERROR_MESSAGE); } } - }, "Associate .drjava and .djapp Files with DrJava", this, "This associates .drjava and .djapp files with DrJava.")); + }, "Associate .drjava Files with DrJava", this, "This associates .drjava files with DrJava.")); addOptionComponent(panel, new LabelComponent(" ", this, true)); @@ -1108,18 +1108,18 @@ public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) { if (PlatformFactory.ONLY.unregisterDrJavaFileExtensions()) { JOptionPane.showMessageDialog(ConfigFrame.this, - "Successfully removed .drjava and .djapp file associations.", + "Successfully removed .drjava file associations.", "Success", JOptionPane.INFORMATION_MESSAGE); } else { JOptionPane.showMessageDialog(ConfigFrame.this, - "Could not remove .drjava and .djapp file associations.", + "Could not remove .drjava file associations.", "File Types Error", JOptionPane.ERROR_MESSAGE); } } - }, "Remove .drjava and .djapp File Associations", this, "This removes the association of .drjava and .djapp files with DrJava.")); + }, "Remove .drjava file associations", this, "This removes the association of .drjava with DrJava.")); addOptionComponent(panel, new LabelComponent(" ", this, true)); addOptionComponent(panel, new LabelComponent(" ", this, true)); @@ -1353,8 +1353,8 @@ public boolean validateTextField() { addOptionComponent(panel, new LabelComponent(" ", this, true)); - boolean javaVersion7 = JavaVersion.CURRENT.supports(JavaVersion.JAVA_7); - if (!javaVersion7) { + boolean javaVersion8 = JavaVersion.CURRENT.supports(JavaVersion.JAVA_8); + if (!javaVersion8) { final ForcedChoiceOptionComponent concJUnitChecksEnabledComponent = newForcedChoiceOptionComponent(OptionConstants.CONCJUNIT_CHECKS_ENABLED); addOptionComponent(panel, concJUnitChecksEnabledComponent); diff --git a/javalanglevels/build.xml b/javalanglevels/build.xml index 9d2c0614c..93103f44c 100644 --- a/javalanglevels/build.xml +++ b/javalanglevels/build.xml @@ -55,7 +55,7 @@ - + + @@ -286,14 +287,7 @@ Testing Targets *************** --> - - - - - - - @@ -383,24 +377,14 @@ - - - - - - - + fork="yes" forkmode="perTest" maxmemory="2G" jvm="${test-jvm}" dir="${basedir}"> - + @@ -487,38 +471,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -562,7 +514,6 @@ - @@ -802,11 +753,6 @@ - - - - - diff --git a/javalanglevels/lib/asm-all-5.0.1.jar b/javalanglevels/lib/asm-all-5.0.1.jar deleted file mode 100644 index 59b27bf81..000000000 Binary files a/javalanglevels/lib/asm-all-5.0.1.jar and /dev/null differ diff --git a/javalanglevels/lib/buildlib/junit.jar b/javalanglevels/lib/buildlib/junit.jar old mode 100755 new mode 100644 index c8f711d05..3a7fc266c Binary files a/javalanglevels/lib/buildlib/junit.jar and b/javalanglevels/lib/buildlib/junit.jar differ diff --git a/javalanglevels/src/edu/rice/cs/javalanglevels/Augmentor.java b/javalanglevels/src/edu/rice/cs/javalanglevels/Augmentor.java index e449402a2..8fb14b838 100644 --- a/javalanglevels/src/edu/rice/cs/javalanglevels/Augmentor.java +++ b/javalanglevels/src/edu/rice/cs/javalanglevels/Augmentor.java @@ -1497,7 +1497,7 @@ private static LinkedList _getVariableAccessorListHelper(SymbolData VariableData vd = accessorMappings.get(i).getFirst(); MethodData md = accessorMappings.get(i).getSecond(); boolean canSeeMethod = - TypeChecker.checkAccess(new NullLiteral(SourceInfo.NONE), md.getMav(), md.getName(), + d.checkAccess(new NullLiteral(SourceInfo.NONE), md.getMav(), md.getName(), md.getSymbolData(), currClass, "method", false); //TODO: it is okay to throw Runtime exceptions or Errors) { if (canSeeMethod && (! md.hasModifier("static")) && md.getThrown().length == 0 && diff --git a/javalanglevels/src/edu/rice/cs/javalanglevels/ClassBodyTypeChecker.java b/javalanglevels/src/edu/rice/cs/javalanglevels/ClassBodyTypeChecker.java index 673260101..82d13a731 100644 --- a/javalanglevels/src/edu/rice/cs/javalanglevels/ClassBodyTypeChecker.java +++ b/javalanglevels/src/edu/rice/cs/javalanglevels/ClassBodyTypeChecker.java @@ -326,6 +326,7 @@ public TypeData forAbstractMethodDef(AbstractMethodDef that) { for (int i = 0; i < that.getThrows().length; i++) { throwsRes[i] = getSymbolData(that.getThrows()[i].getName(), _symbolData, that.getThrows()[i]); } + /** Commented out because it blows up simple IntList.dj visitor code */ // Ensure that this method doesn't override another method with a different return type. MethodData md = _symbolData.getMethod(that.getName().getText(), paramsRes); if (md == null) { @@ -634,43 +635,44 @@ intt, new Word(SourceInfo.NONE, "myMethod3"), new FormalParameter[] {param}, assertEquals("There should still be 2 errors", 2, errors.size()); } - public void testCheckDifferentReturnTypes() { - SymbolData superSd = new SymbolData("aiya"); - _sd1.setSuperClass(superSd); - MethodData md3 = new MethodData("methodName", - _publicMav, - new TypeParameter[0], - SymbolData.CHAR_TYPE, - new VariableData[0], - new String[0], - null, - null); - superSd.addMethod(md3); - MethodData md4 = new MethodData("methodName", - _publicMav, - new TypeParameter[0], - SymbolData.INT_TYPE, - new VariableData[0], - new String[0], - superSd, - null); - MethodDef mDef = new ConcreteMethodDef(SourceInfo.NONE, _publicMav, new TypeParameter[0], new PrimitiveType(SourceInfo.NONE, "int"), - new Word(SourceInfo.NONE, "methodName"), new FormalParameter[0], new ReferenceType[0], - new BracedBody(SourceInfo.NONE, new BodyItemI[] {new ValueReturnStatement(SourceInfo.NONE, new IntegerLiteral(SourceInfo.NONE, 76))})); - _sd1.addMethod(md4); - _cbbtc._symbolData = _sd1; - mDef.visit(_cbbtc); - assertEquals("There should be one error.", 1, errors.size()); - assertEquals("The error message should be correct", "methodName() in " + _sd1.getName() + " cannot override methodName() in aiya; attempting to use different return types", - errors.get(0).getFirst()); - mDef = new AbstractMethodDef(SourceInfo.NONE, _publicMav, new TypeParameter[0], new PrimitiveType(SourceInfo.NONE, "int"), - new Word(SourceInfo.NONE, "methodName"), new FormalParameter[0], new ReferenceType[0]); - - mDef.visit(_cbbtc); - assertEquals("There should be two errors.", 2, errors.size()); - assertEquals("The error message should be correct", "methodName() in " + _sd1.getName() + " cannot override methodName() in aiya; attempting to use different return types", - errors.get(1).getFirst()); - } + /* Commented out because this check breaks a very simply Functional Java example program: IntList.dj */ +// public void testCheckDifferentReturnTypes() { +// SymbolData superSd = new SymbolData("aiya"); +// _sd1.setSuperClass(superSd); +// MethodData md3 = new MethodData("methodName", +// _publicMav, +// new TypeParameter[0], +// SymbolData.CHAR_TYPE, +// new VariableData[0], +// new String[0], +// null, +// null); +// superSd.addMethod(md3); +// MethodData md4 = new MethodData("methodName", +// _publicMav, +// new TypeParameter[0], +// SymbolData.INT_TYPE, +// new VariableData[0], +// new String[0], +// superSd, +// null); +// MethodDef mDef = new ConcreteMethodDef(SourceInfo.NONE, _publicMav, new TypeParameter[0], new PrimitiveType(SourceInfo.NONE, "int"), +// new Word(SourceInfo.NONE, "methodName"), new FormalParameter[0], new ReferenceType[0], +// new BracedBody(SourceInfo.NONE, new BodyItemI[] {new ValueReturnStatement(SourceInfo.NONE, new IntegerLiteral(SourceInfo.NONE, 76))})); +// _sd1.addMethod(md4); +// _cbbtc._symbolData = _sd1; +// mDef.visit(_cbbtc); +// assertEquals("There should be one error.", 1, errors.size()); +// assertEquals("The error message should be correct", "methodName() in " + _sd1.getName() + " cannot override methodName() in aiya; attempting to use different return types", +// errors.get(0).getFirst()); +// mDef = new AbstractMethodDef(SourceInfo.NONE, _publicMav, new TypeParameter[0], new PrimitiveType(SourceInfo.NONE, "int"), +// new Word(SourceInfo.NONE, "methodName"), new FormalParameter[0], new ReferenceType[0]); +// +// mDef.visit(_cbbtc); +// assertEquals("There should be two errors.", 2, errors.size()); +// assertEquals("The error message should be correct", "methodName() in " + _sd1.getName() + " cannot override methodName() in aiya; attempting to use different return types", +// errors.get(1).getFirst()); +// } public void testForTypeOnly() { Type t = new PrimitiveType(SourceInfo.NONE, "double"); diff --git a/platform/build.xml b/platform/build.xml index a953faa43..0cabfe5c6 100644 --- a/platform/build.xml +++ b/platform/build.xml @@ -42,7 +42,9 @@ - + + + @@ -156,6 +158,9 @@ that is not possible, later versions are used. Note that if there are dependencies on later APIs, the DrJava application is responsible for ensuring that those classes are only loaded when the necessary APIs are available. --> + + @@ -237,13 +242,23 @@ - - + - - - + + + + + + + + + + + + @@ -279,7 +294,7 @@ source="${source-version}" target="${source-version}" bootclasspath="${runtime-jar}" sourcepath="" includeAntRuntime="no" executable="javac" fork="yes" memoryMaximumSize="512M" - debug="on" optimize="off" deprecation="on"> + verbose="true" debug="on" optimize="off" deprecation="on"> @@ -310,7 +325,62 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -434,6 +504,15 @@ + + + + + + + + @@ -583,6 +662,7 @@ + @@ -604,6 +684,7 @@ + @@ -631,6 +712,7 @@ + diff --git a/platform/classes/base-mac-java-8/edu/rice/cs/drjava/model/compiler/descriptors/SoyLatteDescriptor.class b/platform/classes/base-mac-java-8/edu/rice/cs/drjava/model/compiler/descriptors/SoyLatteDescriptor.class new file mode 100644 index 000000000..cf39d5bf9 Binary files /dev/null and b/platform/classes/base-mac-java-8/edu/rice/cs/drjava/model/compiler/descriptors/SoyLatteDescriptor.class differ diff --git a/platform/classes/base-mac-java-8/edu/rice/cs/drjava/platform/MacPlatformJava8$1.class b/platform/classes/base-mac-java-8/edu/rice/cs/drjava/platform/MacPlatformJava8$1.class new file mode 100644 index 000000000..3a5dce55e Binary files /dev/null and b/platform/classes/base-mac-java-8/edu/rice/cs/drjava/platform/MacPlatformJava8$1.class differ diff --git a/platform/classes/base-mac-java-8/edu/rice/cs/drjava/platform/MacPlatformJava8$2$1.class b/platform/classes/base-mac-java-8/edu/rice/cs/drjava/platform/MacPlatformJava8$2$1.class new file mode 100644 index 000000000..95554e7b6 Binary files /dev/null and b/platform/classes/base-mac-java-8/edu/rice/cs/drjava/platform/MacPlatformJava8$2$1.class differ diff --git a/platform/classes/base-mac-java-8/edu/rice/cs/drjava/platform/MacPlatformJava8$2.class b/platform/classes/base-mac-java-8/edu/rice/cs/drjava/platform/MacPlatformJava8$2.class new file mode 100644 index 000000000..7bac61ab9 Binary files /dev/null and b/platform/classes/base-mac-java-8/edu/rice/cs/drjava/platform/MacPlatformJava8$2.class differ diff --git a/platform/classes/base-mac-java-8/edu/rice/cs/drjava/platform/MacPlatformJava8.class b/platform/classes/base-mac-java-8/edu/rice/cs/drjava/platform/MacPlatformJava8.class new file mode 100644 index 000000000..dac52786a Binary files /dev/null and b/platform/classes/base-mac-java-8/edu/rice/cs/drjava/platform/MacPlatformJava8.class differ diff --git a/platform/classes/base-mac/edu/rice/cs/drjava/model/compiler/descriptors/SoyLatteDescriptor.class b/platform/classes/base-mac/edu/rice/cs/drjava/model/compiler/descriptors/SoyLatteDescriptor.class old mode 100755 new mode 100644 index 359fc2380..dc7a5ce38 Binary files a/platform/classes/base-mac/edu/rice/cs/drjava/model/compiler/descriptors/SoyLatteDescriptor.class and b/platform/classes/base-mac/edu/rice/cs/drjava/model/compiler/descriptors/SoyLatteDescriptor.class differ diff --git a/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform$1.class b/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform$1.class old mode 100755 new mode 100644 index 13706f8ec..b13aa3787 Binary files a/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform$1.class and b/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform$1.class differ diff --git a/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform$2$1.class b/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform$2$1.class deleted file mode 100755 index 0c48a7f0b..000000000 Binary files a/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform$2$1.class and /dev/null differ diff --git a/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform$2.class b/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform$2.class old mode 100755 new mode 100644 index d4cddbbdf..96d5b7fe6 Binary files a/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform$2.class and b/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform$2.class differ diff --git a/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform$3.class b/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform$3.class new file mode 100644 index 000000000..fdac42927 Binary files /dev/null and b/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform$3.class differ diff --git a/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform$4$1.class b/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform$4$1.class new file mode 100644 index 000000000..ab918f473 Binary files /dev/null and b/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform$4$1.class differ diff --git a/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform$4.class b/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform$4.class new file mode 100644 index 000000000..c3b496917 Binary files /dev/null and b/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform$4.class differ diff --git a/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform.class b/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform.class old mode 100755 new mode 100644 index cb101a5c8..b14972142 Binary files a/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform.class and b/platform/classes/base-mac/edu/rice/cs/drjava/platform/MacPlatform.class differ diff --git a/platform/classes/test-mac-java-8/edu/rice/cs/drjava/platform/MacJava8FactoryTest.class b/platform/classes/test-mac-java-8/edu/rice/cs/drjava/platform/MacJava8FactoryTest.class new file mode 100644 index 000000000..3ed1751be Binary files /dev/null and b/platform/classes/test-mac-java-8/edu/rice/cs/drjava/platform/MacJava8FactoryTest.class differ diff --git a/platform/classes/test-mac/edu/rice/cs/drjava/platform/MacFactoryTest.class b/platform/classes/test-mac/edu/rice/cs/drjava/platform/MacFactoryTest.class new file mode 100644 index 000000000..4caec762c Binary files /dev/null and b/platform/classes/test-mac/edu/rice/cs/drjava/platform/MacFactoryTest.class differ diff --git a/platform/platform-full.jar b/platform/platform-full.jar new file mode 100644 index 000000000..b3b04e9ff Binary files /dev/null and b/platform/platform-full.jar differ diff --git a/platform/src-mac-java-8/edu/rice/cs/drjava/model/compiler/descriptors/SoyLatteDescriptor.java b/platform/src-mac-java-8/edu/rice/cs/drjava/model/compiler/descriptors/SoyLatteDescriptor.java new file mode 100644 index 000000000..b4719aad8 --- /dev/null +++ b/platform/src-mac-java-8/edu/rice/cs/drjava/model/compiler/descriptors/SoyLatteDescriptor.java @@ -0,0 +1,154 @@ +/*BEGIN_COPYRIGHT_BLOCK + * + * Copyright (c) 2001-2010, JavaPLT group at Rice University (drjava@rice.edu) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This software is Open Source Initiative approved Open Source Software. + * Open Source Initative Approved is a trademark of the Open Source Initiative. + * + * This file is part of DrJava. Download the current version of this project + * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/ + * + * END_COPYRIGHT_BLOCK*/ + +package edu.rice.cs.drjava.model.compiler.descriptors; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Set; +import java.util.HashSet; +import java.util.Collections; +import java.util.jar.JarFile; +import edu.rice.cs.plt.reflect.JavaVersion; +import edu.rice.cs.plt.iter.IterUtil; +import edu.rice.cs.plt.io.IOUtil; +import edu.rice.cs.plt.lambda.LambdaUtil; +import edu.rice.cs.plt.lambda.Predicate; + +import edu.rice.cs.drjava.model.JDKDescriptor; + +/** The description of the SoyLatte JDK. */ +public class SoyLatteDescriptor extends JDKDescriptor { + /** Return the name of this JDK. + * @return name */ + public String getName() { + return "SoyLatte"; + } + + /** Packages to shadow when loading a new tools.jar. If we don't shadow these classes, we won't + * be able to load distinct versions for each tools.jar library. These should be verified whenever + * a new Java version is released. (We can't just shadow *everything* because some classes, at + * least in OS X's classes.jar, can only be loaded by the JVM.) + * + * @return set of packages that need to be shadowed + */ + public Set getToolsPackages() { + HashSet set = new HashSet(); + Collections.addAll(set, new String[] { + // Additional from 6 tools.jar: + "com.sun.codemodel", + "com.sun.istack.internal.tools", // other istack packages are in rt.jar + "com.sun.istack.internal.ws", + "com.sun.source", + "com.sun.xml.internal.dtdparser", // other xml.internal packages are in rt.jar + "com.sun.xml.internal.rngom", + "com.sun.xml.internal.xsom", + "org.relaxng", + "javax.lang.element" + }); + return set; + } + + /** Returns a list of directories that should be searched for tools.jar and classes.jar files. + * @return list of directories to search */ + public Iterable getSearchDirectories() { + if (System.getProperty("os.name").toLowerCase().indexOf("mac")<0) return IterUtil.empty(); // Mac only + Iterable roots = IterUtil.asIterable(new File[] { + new File("/usr/local/soylatte"), + new File("/usr/local") + }); + Predicate subdirFilter = LambdaUtil.or(IOUtil.regexCanonicalCaseFilePredicate("\\d+\\.\\d+\\.\\d+"), + IOUtil.regexCanonicalCaseFilePredicate("soylatte.*")); + Iterable dirs = IterUtil.empty(); + for(File d: roots) { + dirs = IterUtil.compose(dirs, IOUtil.attemptListFilesAsIterable(d, subdirFilter)); + } + return dirs; + } + + /** Returns a list of files that should be searched if they contain a compiler. + * @return list of files to search */ + public Iterable getSearchFiles() { + if (System.getProperty("os.name").toLowerCase().indexOf("mac")<0) return IterUtil.empty(); // Mac only + return IterUtil.asIterable(new File[] { + new File("/usr/local/soylatte/lib/classes.jar"), + new File("/usr/local/soylatte/lib/tools.jar") + }); + } + + /** True if this is a compound JDK and needs a fully featured JDK to operate. + * @return true if compound JDK (e.g. NextGen, Mint, Habanero). */ + public boolean isCompound() { return false; } + + /** Return true if the file (jar file or directory) contains the compiler. + * @return true if the file contains the compiler */ + public boolean containsCompiler(File f) { + if (System.getProperty("os.name").toLowerCase().indexOf("mac")<0) return false; // Mac only + return Util.exists(f, + "sun/tools/javac/Main.class", + "com/sun/tools/javac/main/JavaCompiler.class", + "com/sun/tools/javac/util/Context.class", + "com/sun/tools/javac/util/Name.class", + "com/sun/tools/javac/util/Options.class", + "com/sun/tools/javac/util/Position.class"); + } + + /** Return the class name of the compiler adapter. + * @return class name of compiler, or null if no compiler */ + public String getAdapterForCompiler() { return "edu.rice.cs.drjava.model.compiler.Javac160Compiler"; } + + /** Return the class name of the debugger adapter. + * @return class name of debugger, or null if no debugger */ + public String getAdapterForDebugger() { return null; } + + /** Return the minimum Java version required to use this JDK. + * @return minimum version */ + public JavaVersion getMinimumMajorVersion() { return JavaVersion.JAVA_6; } + + /** Return the list of additional files required to use the compiler. + * The compiler was found in the specified file. This method may have to search the user's hard drive, e.g. + * by looking relative to compiler.getParentFile(), by checking environment variables, or by looking in + * certain OS-specific directories. + * @param compiler location where the compiler was fund + * @return list of additional files that need to be available */ + public Iterable getAdditionalCompilerFiles(File compiler) throws FileNotFoundException { + File parentDir = compiler.getParentFile(); + return IterUtil.make(Util.oneOf(parentDir, "../jre/lib/rt.jar")); + } + + public String toString() { return getClass().getSimpleName()+" --> "+getAdapterForCompiler(); } +} diff --git a/platform/src-mac-java-8/edu/rice/cs/drjava/platform/MacJava8FactoryTest.java b/platform/src-mac-java-8/edu/rice/cs/drjava/platform/MacJava8FactoryTest.java new file mode 100644 index 000000000..07bd6cb11 --- /dev/null +++ b/platform/src-mac-java-8/edu/rice/cs/drjava/platform/MacJava8FactoryTest.java @@ -0,0 +1,58 @@ +/*BEGIN_COPYRIGHT_BLOCK + * + * Copyright (c) 2001-2010, JavaPLT group at Rice University (drjava@rice.edu) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This software is Open Source Initiative approved Open Source Software. + * Open Source Initative Approved is a trademark of the Open Source Initiative. + * + * This file is part of DrJava. Download the current version of this project + * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/ + * + * END_COPYRIGHT_BLOCK*/ + +package edu.rice.cs.drjava.platform; + +import junit.framework.*; + +/** + * A simple test class to verify that PlatformFactory has returned the appropriate + * PlatformSupport class. + */ +public class MacJava8FactoryTest extends TestCase { + /** + * Gets the PlatformSupport implementation for this platform from the + * PlatformFactory and verifies that it is an instance of the correct + * class. + */ + public void testFactory() { + PlatformSupport ps = PlatformFactory.ONLY; + String psClassName = ps.getClass().getName(); + assertEquals("PlatformFactory produced the appropriate PlatformSupport?", + "edu.rice.cs.drjava.platform.MacPlatformJava8", + psClassName); + } +} diff --git a/platform/src-mac-java-8/edu/rice/cs/drjava/platform/MacPlatformJava8.java b/platform/src-mac-java-8/edu/rice/cs/drjava/platform/MacPlatformJava8.java new file mode 100644 index 000000000..b5f511dd3 --- /dev/null +++ b/platform/src-mac-java-8/edu/rice/cs/drjava/platform/MacPlatformJava8.java @@ -0,0 +1,203 @@ +/*BEGIN_COPYRIGHT_BLOCK + * + * Copyright (c) 2001-2019, JavaPLT group at Rice University (drjava@rice.edu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This software is Open Source Initiative approved Open Source Software. Open Source Initative Approved is a trademark + * of the Open Source Initiative. + * + * This file is part of DrJava. Download the current version of this project from http://www.drjava.org/ or + * http://sourceforge.net/projects/drjava/ + * + * END_COPYRIGHT_BLOCK*/ + +package edu.rice.cs.drjava.platform; + +import java.net.URL; +import com.apple.eawt.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import javax.swing.*; + + +/** Platform-specific code shared by all Mac OS X platforms. */ + +class MacPlatformJava8 extends DefaultPlatform { + + /** Singleton instance. */ + public static MacPlatformJava8 ONLY = new MacPlatformJava8(); + + /** + * Private constructor for singleton pattern. + */ + protected MacPlatformJava8() {}; + + public boolean openURL(URL address) { + // First, try to delegate up. + if (super.openURL(address)) { + return true; + } + else { + try { + // OS X doesn't like how Java formats file URLs: + // "file:/Users/dir/file.html" isn't legal. + // Instead, we need to put another slash in the protocol: + // "file:///Users/dir/file.html" + String addressString = address.toString(); + if (addressString.startsWith("file:/")) { + String suffix = addressString.substring("file:/".length(), addressString.length()); + addressString = "file:///" + suffix; + } + + // If there is no command specified, or it won't work, try using "open". + //Process proc = + Runtime.getRuntime().exec(new String[] { "open", addressString }); + } + catch (Throwable t) { + // If there was any kind of problem, ignore it and report failure. + return false; + } + } + + // Otherwise, trust that it worked. + return true; + } + + /** + * Hook for performing general UI setup. Called before all other UI setup is done. + * The Mac JDK implementation sets a system property to use the screen menu bar. + */ + public void beforeUISetup() { + System.setProperty("apple.laf.useScreenMenuBar","true"); + + // needs to be done here, otherwise the event gets lost + ApplicationListener appListener = new ApplicationAdapter() { + public void handleOpenFile(ApplicationEvent event) { + if (event.getFilename()!=null) { + edu.rice.cs.drjava.DrJavaRoot.handleRemoteOpenFile(new java.io.File(event.getFilename()), -1); + event.setHandled(true); + } + } + }; + + // Register the ApplicationListener. + Application appl = new Application(); + appl.addApplicationListener(appListener); + } + + /** + * Hook for performing general UI setup. Called after all other UI setup is done. + * The Mac JDK implementation adds handlers for the application menu items. + * @param about the Action associated with openning the About dialog + * @param prefs the Action associated with openning the Preferences dialog + * @param quit the Action associated with quitting the DrJava application + */ + public void afterUISetup(final Action about, final Action prefs, final Action quit) { + ApplicationListener appListener = new ApplicationAdapter() { + public void handleAbout(ApplicationEvent e) { + about.actionPerformed(new ActionEvent(this, 0, "About DrJava")); + e.setHandled(true); + } + + public void handlePreferences(ApplicationEvent e) { + prefs.actionPerformed(new ActionEvent(this, 0, "Preferences...")); + e.setHandled(true); + } + + public void handleQuit(ApplicationEvent e) { + // Workaround for 2868805: show modal dialogs in a separate thread. + // This encapsulation is not necessary in 10.2, but will not break either. + final ApplicationEvent ae = e; + SwingUtilities.invokeLater(new Runnable() { + public void run() { + quit.actionPerformed(new ActionEvent(this, 0, "Quit DrJava")); + ae.setHandled(true); + } + }); + } + }; + + // Register the ApplicationListener. + Application appl = new Application(); + appl.setEnabledPreferencesMenu(true); + appl.addApplicationListener(appListener); + } + + /** + * Returns whether this is a Mac platform. + */ + public boolean isMacPlatform() { + return true; + } + + /** Set the keyboard mnemonic for the component in a way that is consistent with + * the current platform. On Mac OS, the Alt-? mnemonics are broken, so we do not + * set them. + * @param obj the component whose mnemonic should be set + * @param mnemonic the key code which represents the mnemonic + * @see javax.swing.AbstractButton#setMnemonic(int) + * @see java.awt.event.KeyEvent */ + public void setMnemonic(javax.swing.AbstractButton obj, int mnemonic) { + // on Mac OS, the Alt-? mnemonics are broken, so we do not set them + } + + /** Set the keyboard mnemonic for the component in a way that is consistent with + * the current platform. On Mac OS, the Alt-? mnemonics are broken, so we do not + * set them. + * @param obj the component whose mnemonic should be set + * @param mnemonic a char specifying the mnemonic value + * @see javax.swing.AbstractButton#setMnemonic(char) */ + public void setMnemonic(javax.swing.AbstractButton obj, char mnemonic) { + // on Mac OS, the Alt-? mnemonics are broken, so we do not set them + } + + /** Set the keyboard mnemonic for the component in a way that is consistent with + * the current platform. On Mac OS, the Alt-? mnemonics are broken, so we do not + * set them. + * @param obj the component whose mnemonic should be set + * @param mnemonic the key code which represents the mnemonic + * @see javax.swing.ButtonModel#setMnemonic(int) + * @see java.awt.event.KeyEvent */ + public void setMnemonic(javax.swing.ButtonModel obj, int mnemonic) { + // on Mac OS, the Alt-? mnemonics are broken, so we do not set them + } + + /** Set the keyboard mnemonic for the component in a way that is consistent with + * the current platform. On Mac OS, the Alt-? mnemonics are broken, so we do not + * set them. + * @param obj the component whose mnemonic should be set + * @param tabIndex the index of the tab that the mnemonic refers to + * @param mnemonic the key code which represents the mnemonic + * @see javax.swing.JTabbedPane#setMnemonic(int,int) + * @see java.awt.event.KeyEvent */ + public void setMnemonic(javax.swing.JTabbedPane obj, int tabIndex, int mnemonic) { + // on Mac OS, the Alt-? mnemonics are broken, so we do not set them + } + + /** Set the keyboard mnemonic for the component in a way that is consistent with + * the current platform. On Mac OS, the Alt-? mnemonics are broken, so we do not + * set them. + * @param obj the component whose mnemonic should be set + * @param mnemonic the key code which represents the mnemonic + * @see javax.swing.JTabbedPane#setMnemonic(int) + * @see java.awt.event.KeyEvent */ + public void setMnemonic(javax.swing.JTabbedPane obj, int mnemonic) { + // on Mac OS, the Alt-? mnemonics are broken, so we do not set them + } +} \ No newline at end of file diff --git a/platform/src-mac/edu/rice/cs/drjava/platform/MacPlatform.java b/platform/src-mac/edu/rice/cs/drjava/platform/MacPlatform.java index 479702c2e..61988803f 100644 --- a/platform/src-mac/edu/rice/cs/drjava/platform/MacPlatform.java +++ b/platform/src-mac/edu/rice/cs/drjava/platform/MacPlatform.java @@ -1,53 +1,63 @@ /*BEGIN_COPYRIGHT_BLOCK * - * Copyright (c) 2001-2019, JavaPLT group at Rice University (drjava@rice.edu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * Copyright (c) 2001-2010, JavaPLT group at Rice University (drjava@rice.edu) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This software is Open Source Initiative approved Open Source Software. + * Open Source Initative Approved is a trademark of the Open Source Initiative. + * + * This file is part of DrJava. Download the current version of this project + * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/ * - * This software is Open Source Initiative approved Open Source Software. Open Source Initative Approved is a trademark - * of the Open Source Initiative. - * - * This file is part of DrJava. Download the current version of this project from http://www.drjava.org/ or - * http://sourceforge.net/projects/drjava/ - * * END_COPYRIGHT_BLOCK*/ package edu.rice.cs.drjava.platform; +import java.awt.desktop.*; import java.net.URL; -import com.apple.eawt.*; +//import com.apple.eawt.*; import java.awt.*; import java.awt.event.ActionEvent; import javax.swing.*; -/** Platform-specific code shared by all Mac OS X platforms. */ - +/** + * Platform-specific code shared by all Mac OS X platforms. + */ class MacPlatform extends DefaultPlatform { - - /** Singleton instance. */ + /** + * Singleton instance. + */ public static MacPlatform ONLY = new MacPlatform(); - + /** * Private constructor for singleton pattern. */ protected MacPlatform() {}; - + public boolean openURL(URL address) { // First, try to delegate up. if (super.openURL(address)) { @@ -66,7 +76,7 @@ public boolean openURL(URL address) { } // If there is no command specified, or it won't work, try using "open". - //Process proc = + //Process proc = Runtime.getRuntime().exec(new String[] { "open", addressString }); } catch (Throwable t) { @@ -74,33 +84,45 @@ public boolean openURL(URL address) { return false; } } - + // Otherwise, trust that it worked. return true; } - + /** * Hook for performing general UI setup. Called before all other UI setup is done. * The Mac JDK implementation sets a system property to use the screen menu bar. */ public void beforeUISetup() { System.setProperty("apple.laf.useScreenMenuBar","true"); - + // needs to be done here, otherwise the event gets lost - ApplicationListener appListener = new ApplicationAdapter() { - public void handleOpenFile(ApplicationEvent event) { - if (event.getFilename()!=null) { - edu.rice.cs.drjava.DrJavaRoot.handleRemoteOpenFile(new java.io.File(event.getFilename()), -1); - event.setHandled(true); +// ApplicationListener appListener = new ApplicationAdapter() { +// public void handleOpenFile(ApplicationEvent event) { +// if (event.getFilename()!=null) { +// edu.rice.cs.drjava.DrJavaRoot.handleRemoteOpenFile(new java.io.File(event.getFilename()), -1); +// event.setHandled(true); +// } +// } +// }; +// +// // Register the ApplicationListener. +// Application appl = new Application(); +// appl.addApplicationListener(appListener); + + Desktop d = Desktop.getDesktop(); + d.setOpenFileHandler(new OpenFilesHandler() { + @Override + public void openFiles(OpenFilesEvent e) { + if (e.getSearchTerm()!= null) { + edu.rice.cs.drjava.DrJavaRoot.handleRemoteOpenFile(new java.io.File(e.getSearchTerm()), -1); } } - }; - - // Register the ApplicationListener. - Application appl = new Application(); - appl.addApplicationListener(appListener); + }); + + } - + /** * Hook for performing general UI setup. Called after all other UI setup is done. * The Mac JDK implementation adds handlers for the application menu items. @@ -108,95 +130,128 @@ public void handleOpenFile(ApplicationEvent event) { * @param prefs the Action associated with openning the Preferences dialog * @param quit the Action associated with quitting the DrJava application */ - public void afterUISetup(final Action about, final Action prefs, final Action quit) { - ApplicationListener appListener = new ApplicationAdapter() { - public void handleAbout(ApplicationEvent e) { + public void afterUISetup(final Action about, final Action prefs, final Action quit) { +// ApplicationListener appListener = new ApplicationAdapter() { +// public void handleAbout(ApplicationEvent e) { +// about.actionPerformed(new ActionEvent(this, 0, "About DrJava")); +// e.setHandled(true); +// } +// +// public void handlePreferences(ApplicationEvent e) { +// prefs.actionPerformed(new ActionEvent(this, 0, "Preferences...")); +// e.setHandled(true); +// } +// +// public void handleQuit(ApplicationEvent e) { +// // Workaround for 2868805: show modal dialogs in a separate thread. +// // This encapsulation is not necessary in 10.2, but will not break either. +// final ApplicationEvent ae = e; +// SwingUtilities.invokeLater(new Runnable() { +// public void run() { +// quit.actionPerformed(new ActionEvent(this, 0, "Quit DrJava")); +// ae.setHandled(true); +// } +// }); +// } +// }; +// +// // Register the ApplicationListener. +// Application appl = new Application(); +// appl.setEnabledPreferencesMenu(true); +// appl.addApplicationListener(appListener); + + Desktop d = Desktop.getDesktop(); + d.setAboutHandler(new AboutHandler() { + @Override + public void handleAbout(AboutEvent e) { about.actionPerformed(new ActionEvent(this, 0, "About DrJava")); - e.setHandled(true); } + }); - public void handlePreferences(ApplicationEvent e) { + d.setPreferencesHandler(new PreferencesHandler() { + @Override + public void handlePreferences(PreferencesEvent e) { prefs.actionPerformed(new ActionEvent(this, 0, "Preferences...")); - e.setHandled(true); } + }); + + d.setQuitHandler(new QuitHandler() { + @Override + public void handleQuitRequestWith(QuitEvent e, QuitResponse response) { - public void handleQuit(ApplicationEvent e) { - // Workaround for 2868805: show modal dialogs in a separate thread. - // This encapsulation is not necessary in 10.2, but will not break either. - final ApplicationEvent ae = e; + final QuitEvent ae = e; SwingUtilities.invokeLater(new Runnable() { public void run() { quit.actionPerformed(new ActionEvent(this, 0, "Quit DrJava")); - ae.setHandled(true); } }); + } - }; - - // Register the ApplicationListener. - Application appl = new Application(); - appl.setEnabledPreferencesMenu(true); - appl.addApplicationListener(appListener); + }); + + + } - + + /** * Returns whether this is a Mac platform. */ public boolean isMacPlatform() { return true; } - + /** Set the keyboard mnemonic for the component in a way that is consistent with - * the current platform. On Mac OS, the Alt-? mnemonics are broken, so we do not - * set them. - * @param obj the component whose mnemonic should be set - * @param mnemonic the key code which represents the mnemonic - * @see javax.swing.AbstractButton#setMnemonic(int) - * @see java.awt.event.KeyEvent */ + * the current platform. On Mac OS, the Alt-? mnemonics are broken, so we do not + * set them. + * @param obj the component whose mnemonic should be set + * @param mnemonic the key code which represents the mnemonic + * @see javax.swing.AbstractButton#setMnemonic(int) + * @see java.awt.event.KeyEvent */ public void setMnemonic(javax.swing.AbstractButton obj, int mnemonic) { // on Mac OS, the Alt-? mnemonics are broken, so we do not set them } /** Set the keyboard mnemonic for the component in a way that is consistent with - * the current platform. On Mac OS, the Alt-? mnemonics are broken, so we do not - * set them. - * @param obj the component whose mnemonic should be set - * @param mnemonic a char specifying the mnemonic value - * @see javax.swing.AbstractButton#setMnemonic(char) */ + * the current platform. On Mac OS, the Alt-? mnemonics are broken, so we do not + * set them. + * @param obj the component whose mnemonic should be set + * @param mnemonic a char specifying the mnemonic value + * @see javax.swing.AbstractButton#setMnemonic(char) */ public void setMnemonic(javax.swing.AbstractButton obj, char mnemonic) { // on Mac OS, the Alt-? mnemonics are broken, so we do not set them } /** Set the keyboard mnemonic for the component in a way that is consistent with - * the current platform. On Mac OS, the Alt-? mnemonics are broken, so we do not - * set them. - * @param obj the component whose mnemonic should be set - * @param mnemonic the key code which represents the mnemonic - * @see javax.swing.ButtonModel#setMnemonic(int) - * @see java.awt.event.KeyEvent */ + * the current platform. On Mac OS, the Alt-? mnemonics are broken, so we do not + * set them. + * @param obj the component whose mnemonic should be set + * @param mnemonic the key code which represents the mnemonic + * @see javax.swing.ButtonModel#setMnemonic(int) + * @see java.awt.event.KeyEvent */ public void setMnemonic(javax.swing.ButtonModel obj, int mnemonic) { // on Mac OS, the Alt-? mnemonics are broken, so we do not set them } /** Set the keyboard mnemonic for the component in a way that is consistent with - * the current platform. On Mac OS, the Alt-? mnemonics are broken, so we do not - * set them. - * @param obj the component whose mnemonic should be set - * @param tabIndex the index of the tab that the mnemonic refers to - * @param mnemonic the key code which represents the mnemonic - * @see javax.swing.JTabbedPane#setMnemonic(int,int) - * @see java.awt.event.KeyEvent */ + * the current platform. On Mac OS, the Alt-? mnemonics are broken, so we do not + * set them. + * @param obj the component whose mnemonic should be set + * @param tabIndex the index of the tab that the mnemonic refers to + * @param mnemonic the key code which represents the mnemonic + * @see javax.swing.JTabbedPane#setMnemonic(int,int) + * @see java.awt.event.KeyEvent */ public void setMnemonic(javax.swing.JTabbedPane obj, int tabIndex, int mnemonic) { // on Mac OS, the Alt-? mnemonics are broken, so we do not set them } /** Set the keyboard mnemonic for the component in a way that is consistent with - * the current platform. On Mac OS, the Alt-? mnemonics are broken, so we do not - * set them. - * @param obj the component whose mnemonic should be set - * @param mnemonic the key code which represents the mnemonic - * @see javax.swing.JTabbedPane#setMnemonic(int) - * @see java.awt.event.KeyEvent */ + * the current platform. On Mac OS, the Alt-? mnemonics are broken, so we do not + * set them. + * @param obj the component whose mnemonic should be set + * @param mnemonic the key code which represents the mnemonic + * @see javax.swing.JTabbedPane#setMnemonic(int) + * @see java.awt.event.KeyEvent */ public void setMnemonic(javax.swing.JTabbedPane obj, int mnemonic) { // on Mac OS, the Alt-? mnemonics are broken, so we do not set them } diff --git a/platform/src-openjdk6/edu/rice/cs/drjava/model/compiler/Javac160OpenJDKCompiler.java b/platform/src-openjdk6/edu/rice/cs/drjava/model/compiler/Javac160OpenJDKCompiler.java index bc336505f..b16f73447 100644 --- a/platform/src-openjdk6/edu/rice/cs/drjava/model/compiler/Javac160OpenJDKCompiler.java +++ b/platform/src-openjdk6/edu/rice/cs/drjava/model/compiler/Javac160OpenJDKCompiler.java @@ -57,12 +57,12 @@ import static edu.rice.cs.plt.debug.DebugUtil.debug; import static edu.rice.cs.plt.debug.DebugUtil.error; -/** - * An implementation of the CompilerInterface that supports compiling with - * OpenJDK 6.0. It is a Java 6 compiler, but uses the Java 5 interface. - * - * @version $Id$ - */ +/* Question (Corky): Is this adapter obsolete? */ +/** An implementation of the CompilerInterface (in DrJava) that supports compiling with + * OpenJDK 6.0. It is a Java 6 compiler, but uses the Java 5 interface from DrJava. + * + * @version $Id$ + */ public class Javac160OpenJDKCompiler extends JavacCompiler { public static final String COMPILER_CLASS_NAME = "com.sun.tools.javac.main.JavaCompiler";