summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@typesafe.com>2016-04-01 14:05:31 +0200
committerLukas Rytz <lukas.rytz@typesafe.com>2016-04-01 14:05:31 +0200
commit19dac8212090f81ffd18bad6d7cc929fbff9bec8 (patch)
tree37943111ae925d9fdd092073a336cff3f6a38e98
parentad361859546aaa84349714c0a5890492fec38939 (diff)
parent6181525f60588228ce99ab3ef2593ecfcfd35066 (diff)
downloadscala-19dac8212090f81ffd18bad6d7cc929fbff9bec8.tar.gz
scala-19dac8212090f81ffd18bad6d7cc929fbff9bec8.tar.bz2
scala-19dac8212090f81ffd18bad6d7cc929fbff9bec8.zip
Merge pull request #5068 from retronym/topic/jdk8ism2v2.12.0-M4
Accomodate and exploit new library, lang features JDK 8
-rw-r--r--src/compiler/scala/reflect/macros/runtime/MacroRuntimes.scala14
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaParsers.scala5
-rw-r--r--src/library/scala/collection/generic/BitOperations.scala23
-rw-r--r--src/library/scala/collection/parallel/Tasks.scala11
-rw-r--r--src/library/scala/compat/Platform.scala3
-rw-r--r--src/library/scala/math/Ordering.scala22
-rw-r--r--src/library/scala/runtime/BoxesRunTime.java6
-rw-r--r--src/library/scala/sys/process/BasicIO.scala2
-rw-r--r--src/library/scala/util/Properties.scala2
-rw-r--r--src/library/scala/util/control/NoStackTrace.scala2
-rw-r--r--src/reflect/scala/reflect/internal/SymbolTable.scala28
-rw-r--r--src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala4
-rw-r--r--test/files/pos/java-type-annotations/NotNull.java6
-rw-r--r--test/files/pos/java-type-annotations/Test.java4
-rw-r--r--test/files/run/t5375.check1
-rw-r--r--test/files/run/t5375.scala16
16 files changed, 82 insertions, 67 deletions
diff --git a/src/compiler/scala/reflect/macros/runtime/MacroRuntimes.scala b/src/compiler/scala/reflect/macros/runtime/MacroRuntimes.scala
index 5fd9c0db34..d4b8175d28 100644
--- a/src/compiler/scala/reflect/macros/runtime/MacroRuntimes.scala
+++ b/src/compiler/scala/reflect/macros/runtime/MacroRuntimes.scala
@@ -1,8 +1,12 @@
package scala.reflect.macros
package runtime
+import java.net.URLClassLoader
+
import scala.reflect.internal.Flags._
+import scala.reflect.internal.util.ScalaClassLoader
import scala.reflect.runtime.ReflectionUtils
+import scala.reflect.internal.util.AbstractFileClassLoader
trait MacroRuntimes extends JavaReflectionRuntimes {
self: scala.tools.nsc.typechecker.Analyzer =>
@@ -44,7 +48,15 @@ trait MacroRuntimes extends JavaReflectionRuntimes {
* which compiles implementations into a virtual directory (very much like REPL does) and then conjures
* a classloader mapped to that virtual directory.
*/
- lazy val defaultMacroClassloader: ClassLoader = findMacroClassLoader()
+ private lazy val defaultMacroClassloaderCache = {
+ def attemptClose(loader: ClassLoader): Unit = loader match {
+ case u: URLClassLoader => debuglog("Closing macro runtime classloader"); u.close()
+ case afcl: AbstractFileClassLoader => attemptClose(afcl.getParent)
+ case _ => ???
+ }
+ perRunCaches.newGeneric(findMacroClassLoader, attemptClose _)
+ }
+ def defaultMacroClassloader: ClassLoader = defaultMacroClassloaderCache()
/** Abstracts away resolution of macro runtimes.
*/
diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
index 8cdc5944e8..cc851b6330 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
@@ -264,7 +264,8 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
}
}
- def typ(): Tree =
+ def typ(): Tree = {
+ annotations()
optArrayBrackets {
if (in.token == FINAL) in.nextToken()
if (in.token == IDENTIFIER) {
@@ -287,6 +288,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
basicType()
}
}
+ }
def typeArgs(t: Tree): Tree = {
val wildcards = new ListBuffer[TypeDef]
@@ -404,6 +406,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
def typeParam(): TypeDef =
atPos(in.currentPos) {
+ annotations()
val name = identForType()
val hi = if (in.token == EXTENDS) { in.nextToken() ; bound() } else EmptyTree
TypeDef(Modifiers(Flags.JAVA | Flags.DEFERRED | Flags.PARAM), name, Nil, TypeBoundsTree(EmptyTree, hi))
diff --git a/src/library/scala/collection/generic/BitOperations.scala b/src/library/scala/collection/generic/BitOperations.scala
index d430ece2f5..2f460eee1f 100644
--- a/src/library/scala/collection/generic/BitOperations.scala
+++ b/src/library/scala/collection/generic/BitOperations.scala
@@ -26,16 +26,7 @@ private[collection] object BitOperations {
def complement(i: Int) = (-1) ^ i
def bits(num: Int) = 31 to 0 by -1 map (i => (num >>> i & 1) != 0)
def bitString(num: Int, sep: String = "") = bits(num) map (b => if (b) "1" else "0") mkString sep
-
- def highestOneBit(j: Int) = {
- var i = j
- i |= (i >> 1)
- i |= (i >> 2)
- i |= (i >> 4)
- i |= (i >> 8)
- i |= (i >> 16)
- i - (i >>> 1)
- }
+ def highestOneBit(j: Int) = java.lang.Integer.highestOneBit(j)
}
object Int extends Int
@@ -49,17 +40,7 @@ private[collection] object BitOperations {
def complement(i: Long) = (-1L) ^ i
def bits(num: Long) = 63L to 0L by -1L map (i => (num >>> i & 1L) != 0L)
def bitString(num: Long, sep: String = "") = bits(num) map (b => if (b) "1" else "0") mkString sep
-
- def highestOneBit(j: Long) = {
- var i = j
- i |= (i >> 1)
- i |= (i >> 2)
- i |= (i >> 4)
- i |= (i >> 8)
- i |= (i >> 16)
- i |= (i >> 32)
- i - (i >>> 1)
- }
+ def highestOneBit(j: Long) = java.lang.Long.highestOneBit(j)
}
object Long extends Long
}
diff --git a/src/library/scala/collection/parallel/Tasks.scala b/src/library/scala/collection/parallel/Tasks.scala
index c9a75752df..2a4e40dd16 100644
--- a/src/library/scala/collection/parallel/Tasks.scala
+++ b/src/library/scala/collection/parallel/Tasks.scala
@@ -66,13 +66,10 @@ trait Task[R, +Tp] {
}
private[parallel] def mergeThrowables(that: Task[_, _]) {
- // TODO: As soon as we target Java >= 7, use Throwable#addSuppressed
- // to pass additional Throwables to the caller, e. g.
- // if (this.throwable != null && that.throwable != null)
- // this.throwable.addSuppressed(that.throwable)
- // For now, we just use whatever Throwable comes across “first”.
- if (this.throwable == null && that.throwable != null)
- this.throwable = that.throwable
+ if (this.throwable != null && that.throwable != null)
+ this.throwable.addSuppressed(that.throwable)
+ else if (this.throwable == null && that.throwable != null)
+ this.throwable = that.throwable
}
// override in concrete task implementations to signal abort to other tasks
diff --git a/src/library/scala/compat/Platform.scala b/src/library/scala/compat/Platform.scala
index 42dfcbfdde..f3745bc189 100644
--- a/src/library/scala/compat/Platform.scala
+++ b/src/library/scala/compat/Platform.scala
@@ -105,8 +105,7 @@ object Platform {
/** The default line separator.
*
* On the JVM, this is equivalent to calling the method:
- * `System.getProperty("line.separator")`
- * with a default value of "\n".
+ * `java.lang.System.lineSeparator`
*/
val EOL = scala.util.Properties.lineSeparator
diff --git a/src/library/scala/math/Ordering.scala b/src/library/scala/math/Ordering.scala
index 827cccc77e..37096d5ed0 100644
--- a/src/library/scala/math/Ordering.scala
+++ b/src/library/scala/math/Ordering.scala
@@ -224,42 +224,32 @@ object Ordering extends LowPriorityOrderingImplicits {
implicit object Unit extends UnitOrdering
trait BooleanOrdering extends Ordering[Boolean] {
- def compare(x: Boolean, y: Boolean) = (x, y) match {
- case (false, true) => -1
- case (true, false) => 1
- case _ => 0
- }
+ def compare(x: Boolean, y: Boolean) = java.lang.Boolean.compare(x, y)
}
implicit object Boolean extends BooleanOrdering
trait ByteOrdering extends Ordering[Byte] {
- def compare(x: Byte, y: Byte) = x.toInt - y.toInt
+ def compare(x: Byte, y: Byte) = java.lang.Byte.compare(x, y)
}
implicit object Byte extends ByteOrdering
trait CharOrdering extends Ordering[Char] {
- def compare(x: Char, y: Char) = x.toInt - y.toInt
+ def compare(x: Char, y: Char) = java.lang.Character.compare(x, y)
}
implicit object Char extends CharOrdering
trait ShortOrdering extends Ordering[Short] {
- def compare(x: Short, y: Short) = x.toInt - y.toInt
+ def compare(x: Short, y: Short) = java.lang.Short.compare(x, y)
}
implicit object Short extends ShortOrdering
trait IntOrdering extends Ordering[Int] {
- def compare(x: Int, y: Int) =
- if (x < y) -1
- else if (x == y) 0
- else 1
+ def compare(x: Int, y: Int) = java.lang.Integer.compare(x, y)
}
implicit object Int extends IntOrdering
trait LongOrdering extends Ordering[Long] {
- def compare(x: Long, y: Long) =
- if (x < y) -1
- else if (x == y) 0
- else 1
+ def compare(x: Long, y: Long) = java.lang.Long.compare(x, y)
}
implicit object Long extends LongOrdering
diff --git a/src/library/scala/runtime/BoxesRunTime.java b/src/library/scala/runtime/BoxesRunTime.java
index 96e0f23f3d..9ae118f43f 100644
--- a/src/library/scala/runtime/BoxesRunTime.java
+++ b/src/library/scala/runtime/BoxesRunTime.java
@@ -236,10 +236,10 @@ public final class BoxesRunTime
if (iv == dv) return iv;
long lv = n.longValue();
- if (lv == dv) return java.lang.Long.valueOf(lv).hashCode();
+ if (lv == dv) return java.lang.Long.hashCode(lv);
float fv = n.floatValue();
- if (fv == dv) return java.lang.Float.valueOf(fv).hashCode();
+ if (fv == dv) return java.lang.Float.hashCode(fv);
else return n.hashCode();
}
public static int hashFromFloat(java.lang.Float n) {
@@ -248,7 +248,7 @@ public final class BoxesRunTime
if (iv == fv) return iv;
long lv = n.longValue();
- if (lv == fv) return java.lang.Long.valueOf(lv).hashCode();
+ if (lv == fv) return java.lang.Long.hashCode(lv);
else return n.hashCode();
}
public static int hashFromNumber(java.lang.Number n) {
diff --git a/src/library/scala/sys/process/BasicIO.scala b/src/library/scala/sys/process/BasicIO.scala
index 640f7e68c2..b39ae77c62 100644
--- a/src/library/scala/sys/process/BasicIO.scala
+++ b/src/library/scala/sys/process/BasicIO.scala
@@ -33,7 +33,7 @@ object BasicIO {
final val BufferSize = 8192
/** Used to separate lines in the `processFully` function that takes `Appendable`. */
- final val Newline = props("line.separator")
+ final val Newline = System.lineSeparator
private[process] final class Streamed[T](
val process: T => Unit,
diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala
index 583f1539d1..a176748cd6 100644
--- a/src/library/scala/util/Properties.scala
+++ b/src/library/scala/util/Properties.scala
@@ -120,7 +120,7 @@ private[scala] trait PropertiesTrait {
/** The default end of line character.
*/
- def lineSeparator = propOrElse("line.separator", "\n")
+ def lineSeparator = System.lineSeparator()
/* Various well-known properties. */
def javaClassPath = propOrEmpty("java.class.path")
diff --git a/src/library/scala/util/control/NoStackTrace.scala b/src/library/scala/util/control/NoStackTrace.scala
index 3c42944af1..3647af4ac3 100644
--- a/src/library/scala/util/control/NoStackTrace.scala
+++ b/src/library/scala/util/control/NoStackTrace.scala
@@ -14,6 +14,8 @@ package util.control
* on a global basis via a system property wrapper in
* [[scala.sys.SystemProperties]].
*
+ * @note Since JDK 1.7, a similar effect can be achieved with `class Ex extends Throwable(..., writableStackTrace = false)`
+ *
* @author Paul Phillips
* @since 2.8
*/
diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala
index 88a94ab530..6d988479af 100644
--- a/src/reflect/scala/reflect/internal/SymbolTable.scala
+++ b/src/reflect/scala/reflect/internal/SymbolTable.scala
@@ -375,20 +375,30 @@ abstract class SymbolTable extends macros.Universe
def newWeakSet[K <: AnyRef]() = recordCache(new WeakHashSet[K]())
def newAnyRefMap[K <: AnyRef, V]() = recordCache(mutable.AnyRefMap[K, V]())
- def newGeneric[T](f: => T): () => T = {
+ /**
+ * Register a cache specified by a factory function and (optionally) a cleanup function.
+ *
+ * @return A function that will return cached value, or create a fresh value when a new run is started.
+ */
+ def newGeneric[T](f: => T, cleanup: T => Unit = (x: Any) => ()): () => T = {
val NoCached: T = null.asInstanceOf[T]
var cached: T = NoCached
var cachedRunId = NoRunId
- recordCache(new Clearable {
- def clear(): Unit = cached = NoCached
- })
- () => {
- if (currentRunId != cachedRunId || cached == NoCached) {
- cached = f
- cachedRunId = currentRunId
+ val clearable = new Clearable with (() => T) {
+ def clear(): Unit = {
+ if (cached != NoCached)
+ cleanup(cached)
+ cached = NoCached
+ }
+ def apply(): T = {
+ if (currentRunId != cachedRunId || cached == NoCached) {
+ cached = f
+ cachedRunId = currentRunId
+ }
+ cached
}
- cached
}
+ recordCache(clearable)
}
}
diff --git a/src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala b/src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala
index cc5be92489..f3db2017be 100644
--- a/src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala
+++ b/src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala
@@ -139,6 +139,10 @@ object ScalaClassLoader {
classloaderURLs :+= url
super.addURL(url)
}
+ override def close(): Unit = {
+ super.close()
+ classloaderURLs = null
+ }
}
def fromURLs(urls: Seq[URL], parent: ClassLoader = null): URLClassLoader =
diff --git a/test/files/pos/java-type-annotations/NotNull.java b/test/files/pos/java-type-annotations/NotNull.java
new file mode 100644
index 0000000000..2716fe1a99
--- /dev/null
+++ b/test/files/pos/java-type-annotations/NotNull.java
@@ -0,0 +1,6 @@
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+public @interface NotNull {
+}
diff --git a/test/files/pos/java-type-annotations/Test.java b/test/files/pos/java-type-annotations/Test.java
new file mode 100644
index 0000000000..d6bda1dedb
--- /dev/null
+++ b/test/files/pos/java-type-annotations/Test.java
@@ -0,0 +1,4 @@
+public class Test {
+ static class C<@NotNull T> {};
+ @NotNull String foo() { return ""; }
+}
diff --git a/test/files/run/t5375.check b/test/files/run/t5375.check
index b1a57eeeec..e69de29bb2 100644
--- a/test/files/run/t5375.check
+++ b/test/files/run/t5375.check
@@ -1 +0,0 @@
-Runtime exception
diff --git a/test/files/run/t5375.scala b/test/files/run/t5375.scala
index 826ecd841e..2028b6f05d 100644
--- a/test/files/run/t5375.scala
+++ b/test/files/run/t5375.scala
@@ -1,8 +1,16 @@
object Test extends App {
val foos = (1 to 1000).toSeq
- try
- foos.par.map(i => if (i % 37 == 0) sys.error("i div 37") else i)
- catch {
- case ex: RuntimeException => println("Runtime exception")
+ try {
+ foos.par.map(i => if (i % 37 == 0) throw new MultipleOf37Exception(i) else i)
+ assert(false)
+ } catch {
+ case ex: MultipleOf37Exception =>
+ assert(ex.getSuppressed.size > 0)
+ assert(ex.getSuppressed.forall(_.isInstanceOf[MultipleOf37Exception]))
+ assert(ex.i == 37)
+ assert(ex.getSuppressed.map(_.asInstanceOf[MultipleOf37Exception].i).toList == List(74, 148, 259, 518))
+ case _: Throwable =>
+ assert(false)
}
+ class MultipleOf37Exception(val i: Int) extends RuntimeException
}