summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-11-13 01:56:10 +0000
committerPaul Phillips <paulp@improving.org>2011-11-13 01:56:10 +0000
commitb6a300f3ac965285583ed39348ad43abb6df019e (patch)
tree9e919340b1ab94d9b849ca1d49b7437924404bf1
parentea5aac152dab47e7e4aa37224a0b8a609b6d9a0c (diff)
downloadscala-b6a300f3ac965285583ed39348ad43abb6df019e.tar.gz
scala-b6a300f3ac965285583ed39348ad43abb6df019e.tar.bz2
scala-b6a300f3ac965285583ed39348ad43abb6df019e.zip
Working on the runners.
Removed assumption that bash is in /bin. Removed --posix option to bash. Modernized shell constructs: $() instead of ``, [[ ]] instead of [ ]. Added -debug option for all runners which will show you the exact java command line being run before running it. Added -usebootcp to complement -nobootcp, and made regular classpath the default on cygwin. Quoted more things to give us a fighting chance against spaces and parens in paths. I took the waste-half-a-day step of installing vmware fusion so I could install windows so I could install cygwin so I could install scala under cygwin so I could see if it still worked. Seems to. We still desperately need some way of testing not only everything I'm attempting to address in this pile of patches but everything which is most likely now regressing. :javap now sort of works on windows (not for repl-defined classes as yet) if JAVA_HOME is set such that I can find tools.jar. Closes SI-4959. (Risks breaking and) references SI-2092. References SI-622 since that shouldn't be hard to get working.
-rw-r--r--src/compiler/scala/reflect/internal/ClassfileConstants.scala5
-rw-r--r--src/compiler/scala/tools/ant/templates/tool-unix.tmpl128
-rw-r--r--src/compiler/scala/tools/nsc/Properties.scala5
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ILoop.scala17
-rw-r--r--src/partest/scala/tools/partest/nest/Worker.scala40
5 files changed, 122 insertions, 73 deletions
diff --git a/src/compiler/scala/reflect/internal/ClassfileConstants.scala b/src/compiler/scala/reflect/internal/ClassfileConstants.scala
index 3eb6c55848..136350ebbb 100644
--- a/src/compiler/scala/reflect/internal/ClassfileConstants.scala
+++ b/src/compiler/scala/reflect/internal/ClassfileConstants.scala
@@ -32,6 +32,11 @@ object ClassfileConstants {
*
* All interface methods must have their `ACC_ABSTRACT` and
* `ACC_PUBLIC` flags set.
+ *
+ * Note for future reference: see this thread on ACC_SUPER and
+ * how its enforcement differs on the android vm.
+ * https://groups.google.com/forum/?hl=en#!topic/jvm-languages/jVhzvq8-ZIk
+ *
*/ // Class Field Method
final val JAVA_ACC_PUBLIC = 0x0001 // X X X
final val JAVA_ACC_PRIVATE = 0x0002 // X X
diff --git a/src/compiler/scala/tools/ant/templates/tool-unix.tmpl b/src/compiler/scala/tools/ant/templates/tool-unix.tmpl
index 72d6ba1bab..4275ef7ba1 100644
--- a/src/compiler/scala/tools/ant/templates/tool-unix.tmpl
+++ b/src/compiler/scala/tools/ant/templates/tool-unix.tmpl
@@ -1,4 +1,4 @@
-#!/bin/bash --posix
+#!/usr/bin/env bash
#
##############################################################################
# Copyright 2002-2011, LAMP/EPFL
@@ -8,6 +8,17 @@
# PARTICULAR PURPOSE.
##############################################################################
+findScalaHome () {
+ # see #2092
+ local SOURCE="${BASH_SOURCE[0]}"
+ while [ -h "$SOURCE" ] ; do SOURCE="$(readlink "$SOURCE")"; done
+ ( cd -P "$( dirname "$SOURCE" )"/.. && pwd )
+}
+execCommand () {
+ [[ -n $SCALA_RUNNER_DEBUG ]] && echo "" && for arg in "$@@"; do echo "$arg"; done && echo "";
+ "$@@"
+}
+
# Not sure what the right default is here: trying nonzero.
scala_exit_status=127
saved_stty=""
@@ -15,7 +26,8 @@ saved_stty=""
# restore stty settings (echo in particular)
function restoreSttySettings() {
if [[ -n $SCALA_RUNNER_DEBUG ]]; then
- echo "restoring stty: $saved_stty"
+ echo "restoring stty:"
+ echo "$saved_stty"
fi
stty $saved_stty
@@ -23,10 +35,8 @@ function restoreSttySettings() {
}
function onExit() {
- if [[ "$saved_stty" != "" ]]; then
- restoreSttySettings
- exit $scala_exit_status
- fi
+ [[ "$saved_stty" != "" ]] && restoreSttySettings
+ exit $scala_exit_status
}
# to reenable echo if we are interrupted before completing.
@@ -39,69 +49,60 @@ if [[ ! $? ]]; then
saved_stty=""
fi
if [[ -n $SCALA_RUNNER_DEBUG ]]; then
- echo "saved stty: $saved_stty"
+ echo "saved stty:"
+ echo "$saved_stty"
fi
-cygwin=false;
-case "`uname`" in
- CYGWIN*) cygwin=true ;;
-esac
+unset cygwin
+if uname | grep -q ^CYGWIN; then
+ cygwin="$(uname)"
+fi
# Finding the root folder for this Scala distribution
-SOURCE=$0;
-SCRIPT=`basename "$SOURCE"`;
-while [ -h "$SOURCE" ]; do
- SCRIPT=`basename "$SOURCE"`;
- LOOKUP=`ls -ld "$SOURCE"`;
- TARGET=`expr "$LOOKUP" : '.*-> \(.*\)$'`;
- if expr "${TARGET:-.}/" : '/.*/$' > /dev/null; then
- SOURCE=${TARGET:-.};
- else
- SOURCE=`dirname "$SOURCE"`/${TARGET:-.};
- fi;
-done;
+SCALA_HOME="$(findScalaHome)"
+SEP=":"
-# see #2092
-SCALA_HOME=`dirname "$SOURCE"`
-SCALA_HOME=`cd "$SCALA_HOME"; pwd -P`
-SCALA_HOME=`cd "$SCALA_HOME"/..; pwd`
+# Possible additional command line options
+CYGWIN_OPT=""
+EMACS_OPT=""
+[[ -n "$EMACS" ]] && EMACS_OPT="-Denv.emacs=$EMACS"
# Remove spaces from SCALA_HOME on windows
-if $cygwin; then
- SCALA_HOME=`cygpath --windows --short-name "$SCALA_HOME"`
- SCALA_HOME=`cygpath --unix "$SCALA_HOME"`
+if [[ -n "$cygwin" ]]; then
+ SCALA_HOME="$(shome="$(cygpath --windows --short-name "$SCALA_HOME")" ; cygpath --unix "$shome")"
+# elif uname |grep -q ^MINGW; then
+# SEP=";"
fi
# Constructing the extension classpath
TOOL_CLASSPATH="@classpath@"
-if [ -z "$TOOL_CLASSPATH" ] ; then
+if [[ -z "$TOOL_CLASSPATH" ]]; then
for ext in "$SCALA_HOME"/lib/* ; do
- if [ -z "$TOOL_CLASSPATH" ] ; then
+ if [[ -z "$TOOL_CLASSPATH" ]]; then
TOOL_CLASSPATH="$ext"
else
- TOOL_CLASSPATH="$TOOL_CLASSPATH:$ext"
+ TOOL_CLASSPATH="${TOOL_CLASSPATH}${SEP}${ext}"
fi
done
fi
-CYGWIN_JLINE_TERMINAL=
-if $cygwin; then
- if [ "$OS" = "Windows_NT" ] && cygpath -m .>/dev/null 2>/dev/null ; then
+if [[ -n "$cygwin" ]]; then
+ if [[ "$OS" = "Windows_NT" ]] && cygpath -m .>/dev/null 2>/dev/null ; then
format=mixed
else
format=windows
fi
- SCALA_HOME=`cygpath --$format "$SCALA_HOME"`
- TOOL_CLASSPATH=`cygpath --path --$format "$TOOL_CLASSPATH"`
+ SCALA_HOME="$(cygpath --$format "$SCALA_HOME")"
+ TOOL_CLASSPATH="$(cygpath --path --$format "$TOOL_CLASSPATH")"
case "$TERM" in
rxvt* | xterm*)
stty -icanon min 1 -echo
- CYGWIN_JLINE_TERMINAL="-Djline.terminal=scala.tools.jline.UnixTerminal"
+ CYGWIN_OPT="-Djline.terminal=scala.tools.jline.UnixTerminal"
;;
esac
fi
-[ -n "$JAVA_OPTS" ] || JAVA_OPTS="@javaflags@"
+[[ -n "$JAVA_OPTS" ]] || JAVA_OPTS="@javaflags@"
# break out -D and -J options and add them to JAVA_OPTS as well
# so they reach the underlying JVM in time to do some good. The
@@ -109,11 +110,21 @@ fi
declare -a java_args
declare -a scala_args
-# default to the boot classpath for speed.
-CPSELECT="-Xbootclasspath/a:"
-USEJAVACP=false
+# default to the boot classpath for speed, except on cygwin/mingw.
+unset usebootcp
+if [[ -z $cygwin ]]; then
+ usebootcp="true"
+fi
+
+classpathArgs () {
+ if [[ -n $usebootcp ]]; then
+ echo "-Xbootclasspath/a:$TOOL_CLASSPATH"
+ else
+ echo "-classpath $TOOL_CLASSPATH"
+ fi
+}
-while [ $# -gt 0 ]; do
+while [[ $# -gt 0 ]]; do
case "$1" in
-D*)
# pass to scala as well: otherwise we lose it sometimes when we
@@ -130,12 +141,19 @@ while [ $# -gt 0 ]; do
shift
;;
-toolcp)
- TOOL_CLASSPATH="$TOOL_CLASSPATH:$2"
+ TOOL_CLASSPATH="${TOOL_CLASSPATH}${SEP}${2}"
shift 2
;;
-nobootcp)
- CPSELECT="-classpath "
- USEJAVACP=true
+ unset usebootcp
+ shift
+ ;;
+ -usebootcp)
+ usebootcp="true"
+ shift
+ ;;
+ -debug)
+ SCALA_RUNNER_DEBUG=1
shift
;;
*)
@@ -148,18 +166,22 @@ done
# reset "$@@" to the remaining args
set -- "${scala_args[@@]}"
-if [ -z "$JAVACMD" -a -n "$JAVA_HOME" -a -x "$JAVA_HOME/bin/java" ]; then
+if [[ -z "$JAVACMD" && -n "$JAVA_HOME" && -x "$JAVA_HOME/bin/java" ]]; then
JAVACMD="$JAVA_HOME/bin/java"
fi
-"${JAVACMD:=java}" \
+# note that variables which may intentionally be empty must not
+# be quoted: otherwise an empty string will appear as a command line
+# argument, and java will think that is the program to run.
+execCommand \
+ "${JAVACMD:=java}" \
$JAVA_OPTS \
"${java_args[@@]}" \
- ${CPSELECT}${TOOL_CLASSPATH} \
- -Dscala.usejavacp="$USEJAVACP" \
+ $(classpathArgs) \
-Dscala.home="$SCALA_HOME" \
- -Denv.emacs="$EMACS" \
- $CYGWIN_JLINE_TERMINAL \
+ -Dscala.usejavacp=true \
+ $EMACS_OPT \
+ $CYGWIN_OPT \
@properties@ @class@ @toolflags@ "$@@"
# record the exit status lest it be overwritten:
diff --git a/src/compiler/scala/tools/nsc/Properties.scala b/src/compiler/scala/tools/nsc/Properties.scala
index c83ccfeef1..d33be5bca0 100644
--- a/src/compiler/scala/tools/nsc/Properties.scala
+++ b/src/compiler/scala/tools/nsc/Properties.scala
@@ -22,4 +22,9 @@ object Properties extends scala.util.PropertiesTrait {
// derived values
def isEmacsShell = propOrEmpty("env.emacs") != ""
def fileEndings = fileEndingString.split("""\|""").toList
+
+ // System property java.home is the JRE root.
+ // Environment variable JAVA_HOME is (supposed to be) the jdk root.
+ // We need the latter to find javac, tools.jar, etc.
+ def jdkHome = envOrElse("JAVA_HOME", javaHome)
}
diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
index ce74b2a8c3..391d5ab8ee 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
@@ -17,9 +17,10 @@ import scala.collection.mutable.ListBuffer
import scala.concurrent.ops
import util.{ ClassPath, Exceptional, stringFromWriter, stringFromStream }
import interpreter._
-import io.{ File, Sources }
+import io.{ File, Sources, Directory }
import scala.reflect.NameTransformer._
-import util.ScalaClassLoader._
+import util.ScalaClassLoader
+import ScalaClassLoader._
import scala.tools.util._
/** The Scala interactive shell. It provides a read-eval-print loop
@@ -374,7 +375,17 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
}
}
- protected def newJavap() = new JavapClass(intp.classLoader, new IMain.ReplStrippingWriter(intp)) {
+ private def addToolsJarToLoader() = {
+ val javaHome = Directory(sys.env("JAVA_HOME"))
+ val tools = javaHome / "lib" / "tools.jar"
+ if (tools.isFile) {
+ echo("Found tools.jar, adding for use by javap.")
+ ScalaClassLoader.fromURLs(Seq(tools.toURL), intp.classLoader)
+ }
+ else intp.classLoader
+ }
+
+ protected def newJavap() = new JavapClass(addToolsJarToLoader(), new IMain.ReplStrippingWriter(intp)) {
override def tryClass(path: String): Array[Byte] = {
val hd :: rest = path split '.' toList;
// If there are dots in the name, the first segment is the
diff --git a/src/partest/scala/tools/partest/nest/Worker.scala b/src/partest/scala/tools/partest/nest/Worker.scala
index 711e3f0935..5403e1954f 100644
--- a/src/partest/scala/tools/partest/nest/Worker.scala
+++ b/src/partest/scala/tools/partest/nest/Worker.scala
@@ -12,6 +12,7 @@ import java.io._
import java.net.URL
import java.util.{ Timer, TimerTask }
+import scala.tools.nsc.Properties.{ jdkHome, javaHome, propOrElse }
import scala.util.Properties.{ isWin }
import scala.tools.nsc.{ Settings, CompilerCommand, Global }
import scala.tools.nsc.io.{ AbstractFile, PlainFile, Path, Directory, File => SFile }
@@ -105,14 +106,9 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
val scalaCheckFileManager = new ScalaCheckFileManager(fileManager)
var reporter: ConsoleReporter = _
- val timer = new Timer
-
- val javacCmd = if ((fileManager.JAVAC_CMD.indexOf("${env.JAVA_HOME}") != -1) ||
- fileManager.JAVAC_CMD.equals("/bin/javac") ||
- fileManager.JAVAC_CMD.equals("\\bin\\javac")) "javac"
- else
- fileManager.JAVAC_CMD
-
+ val timer = new Timer
+ val javaCmd = propOrElse("partest.javacmd", Path(javaHome) / "bin" / "java" path)
+ val javacCmd = propOrElse("partest.javac_cmd", Path(jdkHome) / "bin" / "javac" path)
def cancelTimerTask() = if (currentTimerTask != null) currentTimerTask.cancel()
def updateTimerTask(body: => Unit) = {
@@ -272,15 +268,16 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
def javac(outDir: File, files: List[File], output: File): Boolean = {
// compile using command-line javac compiler
- val cmd = "%s -d %s -classpath %s %s".format(
+ val args = Seq(
javacCmd,
+ "-d",
outDir.getAbsolutePath,
- join(outDir.toString, CLASSPATH),
- files mkString " "
- )
+ "-classpath",
+ join(outDir.toString, CLASSPATH)
+ ) ++ files.map("" + _)
- try runCommand(cmd, output)
- catch exHandler(output, "javac command '" + cmd + "' failed:\n")
+ try runCommand(args, output)
+ catch exHandler(output, "javac command failed:\n" + args.map(" " + _ + "\n").mkString + "\n")
}
/** Runs command redirecting standard out and
@@ -290,7 +287,15 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
NestUI.verbose("running command:\n"+command)
(command #> outFile !) == 0
}
+ def runCommand(args: Seq[String], outFile: File): Boolean = {
+ NestUI.verbose("running command:\n"+args.map(" " + _ + "\n").mkString)
+ (Process(args) #> outFile !) == 0
+ }
+ private def q(s: String) = {
+ val quot = "\""
+ if ((s == "") || (s.head == '"')) s else quot + s + quot
+ }
def execTest(outDir: File, logFile: File, classpathPrefix: String = ""): Boolean = {
// check whether there is a ".javaopts" file
val argsFile = new File(logFile.getParentFile, fileBase + ".javaopts")
@@ -325,7 +330,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
"-Dpartest.cwd="+outDir.getParent,
"-Dpartest.test-path="+testFullPath,
"-Dpartest.testname="+fileBase,
- "-Djavacmd="+JAVACMD,
+ "-Djavacmd="+javaCmd,
"-Djavaccmd="+javacCmd,
"-Duser.language=en -Duser.country=US"
) ++ extras
@@ -333,10 +338,11 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
val classpath = if (classpathPrefix != "") join(classpathPrefix, CLASSPATH) else CLASSPATH
val cmd = (
List(
- JAVACMD,
+ javaCmd,
JAVA_OPTS,
argString,
- "-classpath " + join(outDir.toString, classpath)
+ "-classpath",
+ join(outDir.toString, classpath)
) ++ propertyOptions ++ List(
"scala.tools.nsc.MainGenericRunner",
"-usejavacp",