diff options
20 files changed, 200 insertions, 90 deletions
diff --git a/src/compiler/scala/reflect/reify/phases/Reshape.scala b/src/compiler/scala/reflect/reify/phases/Reshape.scala index 7578def687..b6f27f71ce 100644 --- a/src/compiler/scala/reflect/reify/phases/Reshape.scala +++ b/src/compiler/scala/reflect/reify/phases/Reshape.scala @@ -256,7 +256,7 @@ trait Reshape { val flags1 = (flags0 & GetterFlags) & ~(STABLE | ACCESSOR | METHOD) val mods1 = Modifiers(flags1, privateWithin0, annotations0) setPositions mods0.positions val mods2 = toPreTyperModifiers(mods1, ddef.symbol) - ValDef(mods2, name1.toTermName, tpt0, extractRhs(rhs0)) + ValDef(mods2, name1, tpt0, extractRhs(rhs0)) } private def trimAccessors(deff: Tree, stats: List[Tree]): List[Tree] = { diff --git a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala index b17de9b9d5..66ed0c8fae 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala @@ -187,7 +187,7 @@ trait TreeDSL { def vparamss: List[List[ValDef]] type ResultTreeType = DefDef - def mkTree(rhs: Tree): DefDef = DefDef(mods, name, tparams, vparamss, tpt, rhs) + def mkTree(rhs: Tree): DefDef = DefDef(mods, name.toTermName, tparams, vparamss, tpt, rhs) } class DefSymStart(val sym: Symbol) extends SymVODDStart with DefCreator { diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index eb924a811b..d0b0c09d59 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -2542,7 +2542,7 @@ self => } expr() } - DefDef(newmods, name, tparams, vparamss, restype, rhs) + DefDef(newmods, name.toTermName, tparams, vparamss, restype, rhs) } signalParseProgress(result.pos) result diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala index 2a799acbc7..239ecb4f8a 100644 --- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala @@ -510,7 +510,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners { if (inInterface) mods1 |= Flags.DEFERRED List { atPos(pos) { - DefDef(mods1, name, tparams, List(vparams), rtpt, body) + DefDef(mods1, name.toTermName, tparams, List(vparams), rtpt, body) } } } else { diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 0f65b11e9b..ee687e56b0 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -706,7 +706,8 @@ abstract class Erasure extends AddInterfaces // } typed(untyped) } - } else tree + } else qual1 + case Apply(TypeApply(sel @ Select(qual, name), List(targ)), List()) if tree.symbol == Any_isInstanceOf => targ.tpe match { diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala index c01694960c..b11368acdf 100644 --- a/src/library/scala/collection/immutable/List.scala +++ b/src/library/scala/collection/immutable/List.scala @@ -161,6 +161,8 @@ sealed abstract class List[+A] extends AbstractSeq[A] * @inheritdoc */ @inline final def mapConserve[B >: A <: AnyRef](f: A => B): List[B] = { + // Note to developers: there exists a duplication between this function and `reflect.internal.util.Collections#map2Conserve`. + // If any successful optimization attempts or other changes are made, please rehash them there too. @tailrec def loop(mapped: ListBuffer[B], unchanged: List[A], pending: List[A]): List[B] = if (pending.isEmpty) { diff --git a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala index 332131ca3a..3e28d4e4ad 100644 --- a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala +++ b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala @@ -138,7 +138,7 @@ class ConsoleRunner(argstr: String) extends { val rerunTests = if (isRerun) TestKinds.failedTests else Nil def miscTests = partestTests ++ individualTests ++ greppedTests ++ rerunTests - val givenKinds = standardKinds filter parsed.isSet + val givenKinds = standardKinds filter (parsed isSet "--" + _) val kinds = ( if (optAll) standardKinds else if (givenKinds.nonEmpty) givenKinds @@ -197,7 +197,7 @@ class ConsoleRunner(argstr: String) extends { val num = paths.size val ss = if (num == 1) "" else "s" comment(s"starting $num test$ss in $kind") - val results = runTestsForFiles(paths map (_.jfile), kind) + val results = runTestsForFiles(paths map (_.jfile.getAbsoluteFile), kind) val (passed, failed) = results partition (_.isOk) passedTests ++= passed diff --git a/src/partest/scala/tools/partest/nest/FileManager.scala b/src/partest/scala/tools/partest/nest/FileManager.scala index 7bfa8c6e77..208418047c 100644 --- a/src/partest/scala/tools/partest/nest/FileManager.scala +++ b/src/partest/scala/tools/partest/nest/FileManager.scala @@ -148,7 +148,7 @@ trait FileManager extends FileUtil { val srcpath = Path(srcdir.path) val pd = (srcpath / plugxml).toFile if (pd.exists) pd copyTo (pout / plugxml) - pout + pout.toAbsolute } else Path(p) def absolutize(path: String) = pathOrCwd(path) match { case x if x.isAbsolute => x.path diff --git a/src/partest/scala/tools/partest/nest/Runner.scala b/src/partest/scala/tools/partest/nest/Runner.scala index d7d87bdcf5..1d41095fce 100644 --- a/src/partest/scala/tools/partest/nest/Runner.scala +++ b/src/partest/scala/tools/partest/nest/Runner.scala @@ -270,60 +270,54 @@ class Runner(val testFile: File, fileManager: FileManager, val testRunParams: Te false } - /** Filter the diff for conditional blocks. + /** Filter the check file for conditional blocks. * The check file can contain lines of the form: * `#partest java7` * where the line contains a conventional flag name. - * In the diff output, these lines have the form: - * `> #partest java7` - * Blocks which don't apply are filtered out, - * and what remains is the desired diff. - * Line edit commands such as `0a1,6` don't count - * as diff, so return a nonempty diff only if - * material diff output was seen. - * Filtering the diff output (instead of every check - * file) means that we only post-process a test that - * might be failing, in the normal case. + * If the flag tests true, succeeding lines are retained + * (removed on false) until the next #partest flag. + * A missing flag evaluates the same as true. */ - def diffilter(d: String) = { + def filteredCheck: Seq[String] = { import scala.util.Properties.{javaVersion, isAvian} - val prefix = "#partest" - val margin = "> " - val leader = margin + prefix // use lines in block so labeled? Default to sorry, Charlie. - def retainOn(f: String) = { + def retainOn(expr: String) = { + val f = expr.trim + def flagWasSet(f: String) = fileManager.SCALAC_OPTS contains f val (invert, token) = if (f startsWith "!") (true, f drop 1) else (false, f) - val cond = token match { + val cond = token.trim match { case "java7" => javaVersion startsWith "1.7" case "java6" => javaVersion startsWith "1.6" case "avian" => isAvian case "true" => true - case _ => false + case "-optimise" | "-optimize" + => flagWasSet("-optimise") || flagWasSet("-optimize") + case flag if flag startsWith "-" + => flagWasSet(flag) + case rest => rest.isEmpty } if (invert) !cond else cond } - if (d contains prefix) { - val sb = new StringBuilder - var retain = true // use the current line - var material = false // saw a line of diff - for (line <- d.lines) - if (line startsWith leader) { - val rest = (line stripPrefix leader).trim - retain = retainOn(rest) - } else if (retain) { - if (line startsWith margin) material = true - sb ++= line - sb ++= EOL - } - if (material) sb.toString else "" - } else d + val prefix = "#partest" + val b = new ListBuffer[String]() + var on = true + for (line <- file2String(checkFile).lines) { + if (line startsWith prefix) { + on = retainOn(line stripPrefix prefix) + } else if (on) { + b += line + } + } + b.toList } - def currentDiff = ( - if (checkFile.canRead) diffilter(compareFiles(logFile, checkFile)) - else compareContents(augmentString(file2String(logFile)).lines.toList, Nil) - ) + def currentDiff = { + val logged = augmentString(file2String(logFile)).lines.toList + val (other, othername) = + if (checkFile.canRead) (filteredCheck, checkFile.getName) else (Nil, "empty") + compareContents(logged, other, logFile.getName, othername) + } val gitRunner = List("/usr/local/bin/git", "/usr/bin/git") map (f => new java.io.File(f)) find (_.canRead) val gitDiffOptions = "--ignore-space-at-eol --no-index " + propOrEmpty("partest.git_diff_options") @@ -721,6 +715,9 @@ class Runner(val testFile: File, fileManager: FileManager, val testRunParams: Te } def run(): TestState = { + // javac runner, for one, would merely append to an existing log file, so just delete it before we start + logFile.delete() + if (kind == "neg" || (kind endsWith "-neg")) runNegTest() else kind match { case "pos" => runTestCommon(true) @@ -786,7 +783,7 @@ trait DirectRunner { //val parentClassLoader = ScalaClassLoader fromURLs (List(scalaCheck.toURL), getClass().getClassLoader) val pool = Executors newFixedThreadPool numThreads val manager = new RunnerManager(kind, fileManager, TestRunParams(parentClassLoader)) - val futures = kindFiles map (f => pool submit callable(manager runTest f)) + val futures = kindFiles map (f => pool submit callable(manager runTest f.getAbsoluteFile)) pool.shutdown() Try (pool.awaitTermination(waitTime) { diff --git a/src/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala index f7a6a68946..443f34ccae 100644 --- a/src/reflect/scala/reflect/api/Trees.scala +++ b/src/reflect/scala/reflect/api/Trees.scala @@ -572,8 +572,8 @@ trait Trees { self: Universe => * @group Extractors */ abstract class DefDefExtractor { - def apply(mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef - def unapply(defDef: DefDef): Option[(Modifiers, Name, List[TypeDef], List[List[ValDef]], Tree, Tree)] + def apply(mods: Modifiers, name: TermName, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef + def unapply(defDef: DefDef): Option[(Modifiers, TermName, List[TypeDef], List[List[ValDef]], Tree, Tree)] } /** The API that all def defs support @@ -584,7 +584,7 @@ trait Trees { self: Universe => def mods: Modifiers /** @inheritdoc */ - def name: Name + def name: TermName /** The type parameters of the method. */ def tparams: List[TypeDef] diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index ceb3b383d7..df1ba1e2ea 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -312,7 +312,7 @@ trait Trees extends api.Trees { self: SymbolTable => case class ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree) extends ValOrDefDef with ValDefApi object ValDef extends ValDefExtractor - case class DefDef(mods: Modifiers, name: Name, tparams: List[TypeDef], + case class DefDef(mods: Modifiers, name: TermName, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) extends ValOrDefDef with DefDefApi object DefDef extends DefDefExtractor diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 11527d88ca..71f46fedb7 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -80,7 +80,8 @@ trait Types with tpe.CommonOwners with tpe.GlbLubs with tpe.TypeMaps - with tpe.TypeConstraints { self: SymbolTable => + with tpe.TypeConstraints + with util.Collections { self: SymbolTable => import definitions._ import TypesStats._ @@ -4317,18 +4318,6 @@ trait Types } } - /** like map2, but returns list `xs` itself - instead of a copy - if function - * `f` maps all elements to themselves. - */ - def map2Conserve[A <: AnyRef, B](xs: List[A], ys: List[B])(f: (A, B) => A): List[A] = - if (xs.isEmpty || ys.isEmpty) xs - else { - val x1 = f(xs.head, ys.head) - val xs1 = map2Conserve(xs.tail, ys.tail)(f) - if ((x1 eq xs.head) && (xs1 eq xs.tail)) xs - else x1 :: xs1 - } - /** Do type arguments `targs` conform to formal parameters `tparams`? */ def isWithinBounds(pre: Type, owner: Symbol, tparams: List[Symbol], targs: List[Type]): Boolean = { diff --git a/src/reflect/scala/reflect/internal/util/Collections.scala b/src/reflect/scala/reflect/internal/util/Collections.scala index e127d577e1..59af819dad 100644 --- a/src/reflect/scala/reflect/internal/util/Collections.scala +++ b/src/reflect/scala/reflect/internal/util/Collections.scala @@ -53,6 +53,42 @@ trait Collections { } lb.toList } + + /** like map2, but returns list `xs` itself - instead of a copy - if function + * `f` maps all elements to themselves. + */ + final def map2Conserve[A <: AnyRef, B](xs: List[A], ys: List[B])(f: (A, B) => A): List[A] = { + // Note to developers: there exists a duplication between this function and `List#mapConserve`. + // If any successful optimization attempts or other changes are made, please rehash them there too. + @tailrec + def loop(mapped: ListBuffer[A], unchanged: List[A], pending0: List[A], pending1: List[B]): List[A] = { + if (pending0.isEmpty || pending1.isEmpty) { + if (mapped eq null) unchanged + else mapped.prependToList(unchanged) + } else { + val head00 = pending0.head + val head01 = pending1.head + val head1 = f(head00, head01) + + if ((head1 eq head00.asInstanceOf[AnyRef])) { + loop(mapped, unchanged, pending0.tail, pending1.tail) + } else { + val b = if (mapped eq null) new ListBuffer[A] else mapped + var xc = unchanged + while ((xc ne pending0) && (xc ne pending1)) { + b += xc.head + xc = xc.tail + } + b += head1 + val tail0 = pending0.tail + val tail1 = pending1.tail + loop(b, tail0, tail0, tail1) + } + } + } + loop(null, xs, xs, ys) + } + final def map3[A, B, C, D](xs1: List[A], xs2: List[B], xs3: List[C])(f: (A, B, C) => D): List[D] = { if (xs1.isEmpty || xs2.isEmpty || xs3.isEmpty) Nil else f(xs1.head, xs2.head, xs3.head) :: map3(xs1.tail, xs2.tail, xs3.tail)(f) diff --git a/test/files/pos/erasure-nsquared.scala b/test/files/pos/erasure-nsquared.scala new file mode 100644 index 0000000000..b0e30ade58 --- /dev/null +++ b/test/files/pos/erasure-nsquared.scala @@ -0,0 +1,35 @@ +trait BigCast { + def bar(x: Int): AnyRef = ( + null + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + ) +} diff --git a/test/files/run/repl-javap-app.check b/test/files/run/repl-javap-app.check index db1f09b977..490860585c 100644 --- a/test/files/run/repl-javap-app.check +++ b/test/files/run/repl-javap-app.check @@ -6,14 +6,13 @@ scala> :javap -app MyApp$ public final void delayedEndpoint$MyApp$1(); Code: Stack=2, Locals=1, Args_size=1 - 0: getstatic #61; //Field scala/Console$.MODULE$:Lscala/Console$; - 3: ldc #63; //String Hello, delayed world. - 5: invokevirtual #67; //Method scala/Console$.println:(Ljava/lang/Object;)V - 8: return + 0: getstatic #61; //Field scala/Console$.MODULE$:Lscala/Console$; + 3: ldc #63; //String Hello, delayed world. + 5: invokevirtual #67; //Method scala/Console$.println:(Ljava/lang/Object;)V + 8: return LocalVariableTable: Start Length Slot Name Signature 0 9 0 this LMyApp$; -} scala> #partest !java6 diff --git a/test/files/run/stream_length.check b/test/files/run/stream_length.check index d1068f3247..e4350aa741 100644 --- a/test/files/run/stream_length.check +++ b/test/files/run/stream_length.check @@ -1,6 +1,5 @@ #partest !avian Length: 970299 - #partest avian !!!TEST SKIPPED!!! See SI-7600 for further information. diff --git a/test/files/run/tailcalls.check b/test/files/run/tailcalls.check index 10384ac46e..ab54d528ab 100644 --- a/test/files/run/tailcalls.check +++ b/test/files/run/tailcalls.check @@ -52,7 +52,6 @@ test TailCall.b2 was successful test FancyTailCalls.tcTryLocal was successful test FancyTailCalls.differentInstance was successful test PolyObject.tramp was successful - #partest avian test Object .f was successful test Final .f was successful @@ -106,4 +105,4 @@ test TailCall.b1 was successful test TailCall.b2 was successful test FancyTailCalls.tcTryLocal was successful test FancyTailCalls.differentInstance was successful -test PolyObject.tramp was successful
\ No newline at end of file +test PolyObject.tramp was successful diff --git a/test/files/scalacheck/CheckCollections.scala b/test/files/scalacheck/CheckCollections.scala new file mode 100644 index 0000000000..108040b900 --- /dev/null +++ b/test/files/scalacheck/CheckCollections.scala @@ -0,0 +1,59 @@ +import org.scalacheck.{ ConsoleReporter, Properties } +import org.scalacheck.Prop._ + +import scala.reflect.internal.util.Collections._ + +object Test extends Properties("reflect.internal.util.Collections") { + def map2ConserveOld[A <: AnyRef, B](xs: List[A], ys: List[B])(f: (A, B) => A): List[A] = + if (xs.isEmpty || ys.isEmpty) xs + else { + val x1 = f(xs.head, ys.head) + val xs1 = map2Conserve(xs.tail, ys.tail)(f) + if ((x1 eq xs.head) && (xs1 eq xs.tail)) xs + else x1 :: xs1 + } + + val testfun: (String, Int) => String = { case(x, y) => + x.toLowerCase + y.toString + } + val testid: (String, Int) => String = { case (x, y) => x } + + val prop1_map2Conserve = forAll { (xs: List[String], ys: List[Int]) => + val res = map2Conserve(xs, ys)(testid) + res eq xs + } + + val prop2_map2Conserve = forAll { (xs: List[String], ys: List[Int]) => + map2Conserve(xs, ys)(testid) == map2ConserveOld(xs, ys)(testid) && + map2Conserve(xs, ys)(testfun) == map2ConserveOld(xs, ys)(testfun) + } + + def checkStackOverflow() { + var xs: List[String] = Nil + var ys: List[Int] = Nil + for (i <- 0 until 250000) { + xs = "X" :: xs + ys = 1 :: ys + } + map2Conserve(xs, ys){ case(x, y) => x.toLowerCase + y.toString } + } + + + val tests = List( + ("map2Conserve(identity)", prop1_map2Conserve), + ("map2Conserve == old impl", prop2_map2Conserve) + ) + + checkStackOverflow() + + for { + (label, prop) <- tests + } property(label) = prop + + import org.scalacheck.{ Test => STest } + + def runTests() = + STest.checkProperties( + STest.Params(testCallback = ConsoleReporter(0)), this) + +} diff --git a/test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala b/test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala index 03f8aa58d3..23b6a5fbdb 100644 --- a/test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala +++ b/test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala @@ -91,7 +91,7 @@ trait ArbitraryTreesAndNames { yield CompoundTypeTree(templ) def genDefDef(size: Int) = - for(mods <- genModifiers; name <- genName; + for(mods <- genModifiers; name <- genTermName; tpt <- genTree(size -1); rhs <- genTree(size - 1); tparams <- smallList(size, genTypeDef(size - 1)); vparamss <- smallList(size, smallList(size, genValDef(size - 1)))) diff --git a/test/partest b/test/partest index 0259cdb791..b74e04a208 100755 --- a/test/partest +++ b/test/partest @@ -1,6 +1,5 @@ #!/usr/bin/env bash # - ############################################################################## # Scala test runner 2.10.0 ############################################################################## @@ -11,6 +10,17 @@ # PARTICULAR PURPOSE. ############################################################################## +findScalaHome () { + # see SI-2092 and SI-5792 + local source="${BASH_SOURCE[0]}" + while [ -h "$source" ] ; do + local linked="$(readlink "$source")" + local dir="$( cd -P $(dirname "$source") && cd -P $(dirname "$linked") && pwd )" + source="$dir/$(basename "$linked")" + done + ( ( cd -P "$(dirname "$source")/.." > /dev/null ) && pwd ) +} + # Use tput to detect color-capable terminal. term_colors=$(tput colors 2>/dev/null) if [[ $? == 0 ]] && [[ $term_colors -gt 2 ]]; then @@ -29,23 +39,7 @@ case "`uname`" in esac # 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; - -# see #2092 -SCALA_HOME=`dirname "$SOURCE"` -SCALA_HOME=`cd "$SCALA_HOME"; pwd -P` -SCALA_HOME=`cd "$SCALA_HOME"/..; pwd` +SCALA_HOME="$(findScalaHome)" if $cygwin; then SCALA_HOME=`cygpath --windows --short-name "$SCALA_HOME"` |