summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala6
-rw-r--r--src/compiler/scala/tools/nsc/interactive/CompilerControl.scala16
-rw-r--r--src/compiler/scala/tools/nsc/interactive/REPL.scala46
-rw-r--r--src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala61
-rw-r--r--src/compiler/scala/tools/nsc/scratchpad/CommentOutputStream.scala18
-rw-r--r--src/compiler/scala/tools/nsc/scratchpad/CommentWriter.scala42
-rw-r--r--src/compiler/scala/tools/nsc/scratchpad/SourceInserter.scala89
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala10
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala11
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala49
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala22
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala40
-rw-r--r--src/library/scala/StringContext.scala8
-rw-r--r--src/library/scala/collection/parallel/ParIterableLike.scala2
-rw-r--r--src/library/scala/concurrent/util/Duration.scala506
-rw-r--r--src/library/scala/deprecatedInheritance.scala22
-rw-r--r--src/library/scala/deprecatedOverriding.scala21
-rw-r--r--src/library/scala/math/BigDecimal.scala1
-rw-r--r--src/library/scala/math/BigInt.scala1
-rw-r--r--src/library/scala/reflect/ClassTag.scala64
-rw-r--r--src/library/scala/reflect/Manifest.scala19
-rw-r--r--src/library/scala/runtime/ScalaRunTime.scala29
-rw-r--r--src/library/scala/runtime/WorksheetSupport.scala6
-rw-r--r--src/library/scala/util/Try.scala63
-rw-r--r--src/partest/scala/tools/partest/nest/RunnerManager.scala4
-rw-r--r--src/reflect/scala/reflect/api/Symbols.scala12
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala3
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala60
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala25
-rw-r--r--test/files/jvm/duration-java.check362
-rw-r--r--test/files/jvm/duration-java/Test.java38
-rw-r--r--test/files/neg/override.check2
-rwxr-xr-xtest/files/neg/override.scala2
-rw-r--r--test/files/neg/t5031.check6
-rw-r--r--test/files/neg/t5031b.check5
-rw-r--r--test/files/neg/t5031b/a.scala3
-rw-r--r--test/files/neg/t5031b/b.scala3
-rw-r--r--test/files/neg/t6162-inheritance.check10
-rw-r--r--test/files/neg/t6162-inheritance.flags1
-rw-r--r--test/files/neg/t6162-inheritance.scala19
-rw-r--r--test/files/neg/t6162-overriding.check7
-rw-r--r--test/files/neg/t6162-overriding.flags1
-rw-r--r--test/files/neg/t6162-overriding.scala17
-rw-r--r--test/files/neg/t6258.check16
-rw-r--r--test/files/neg/t6258.scala25
-rw-r--r--test/files/neg/t6276.check13
-rw-r--r--test/files/neg/t6276.flags1
-rw-r--r--test/files/neg/t6276.scala29
-rw-r--r--test/files/neg/t6335.check9
-rw-r--r--test/files/neg/t6335.scala7
-rw-r--r--test/files/pos/t6274.scala13
-rw-r--r--test/files/pos/t6278-synth-def.scala30
-rw-r--r--test/files/pos/t6335.scala25
-rw-r--r--test/files/presentation/recursive-ask.check4
-rw-r--r--test/files/presentation/recursive-ask/RecursiveAsk.scala20
-rw-r--r--test/files/run/classtags_core.check30
-rw-r--r--test/files/run/classtags_multi.check10
-rw-r--r--test/files/run/getClassTest-valueClass.check2
-rw-r--r--test/files/run/getClassTest-valueClass.scala10
-rw-r--r--test/files/run/interop_classtags_are_classmanifests.check6
-rw-r--r--test/files/run/macro-expand-tparams-implicit.check2
-rw-r--r--test/files/run/macro-expand-tparams-prefix-a.check2
-rw-r--r--test/files/run/macro-expand-tparams-prefix-b.check2
-rw-r--r--test/files/run/macro-expand-tparams-prefix-c1.check2
-rw-r--r--test/files/run/macro-expand-tparams-prefix-c2.check2
-rw-r--r--test/files/run/macro-undetparams-macroitself.check2
-rw-r--r--test/files/run/t5064.check25
-rw-r--r--test/files/run/t5064.scala23
-rw-r--r--test/files/run/t5881.check4
-rw-r--r--test/files/run/t6246.check90
-rw-r--r--test/files/run/t6246.scala26
-rw-r--r--test/files/run/t6318_derived.check3
-rw-r--r--test/files/run/t6318_derived.scala15
-rw-r--r--test/files/run/t6318_primitives.check36
-rw-r--r--test/files/run/t6318_primitives.scala71
-rw-r--r--test/files/run/t6327.check4
-rw-r--r--test/files/run/t6327.scala22
-rw-r--r--test/files/run/t6333.scala29
-rw-r--r--test/files/run/valueclasses-classtag-basic.check2
-rw-r--r--test/files/run/valueclasses-classtag-existential.check2
-rw-r--r--test/files/run/valueclasses-classtag-generic.check2
-rw-r--r--test/files/run/virtpatmat_typetag.check20
85 files changed, 1603 insertions, 779 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 085ce82025..bd5c9b2f68 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -48,12 +48,12 @@ trait Trees extends reflect.internal.Trees { self: Global =>
override def isType = definition.isType
}
- /** Array selection <qualifier> . <name> only used during erasure */
+ /** Array selection `<qualifier> . <name>` only used during erasure */
case class SelectFromArray(qualifier: Tree, name: Name, erasure: Type)
extends RefTree with TermTree
- /** Derived value class injection (equivalent to: new C(arg) after easure); only used during erasure
- * The class C is stored as the symbol of the tree node.
+ /** Derived value class injection (equivalent to: `new C(arg)` after erasure); only used during erasure.
+ * The class `C` is stored as a tree attachment.
*/
case class InjectDerivedValue(arg: Tree)
extends SymTree
diff --git a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
index 6acd6d2382..3de2359ce3 100644
--- a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
+++ b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
@@ -257,12 +257,18 @@ trait CompilerControl { self: Global =>
*/
def askForResponse[A](op: () => A): Response[A] = {
val r = new Response[A]
- val ir = scheduler askDoQuickly op
- ir onComplete {
- case Left(result) => r set result
- case Right(exc) => r raise exc
+ if (self.onCompilerThread) {
+ try { r set op() }
+ catch { case exc: Throwable => r raise exc }
+ r
+ } else {
+ val ir = scheduler askDoQuickly op
+ ir onComplete {
+ case Left(result) => r set result
+ case Right(exc) => r raise exc
+ }
+ r
}
- r
}
def onCompilerThread = Thread.currentThread == compileRunner
diff --git a/src/compiler/scala/tools/nsc/interactive/REPL.scala b/src/compiler/scala/tools/nsc/interactive/REPL.scala
index 2d93c77ca4..afac5828e5 100644
--- a/src/compiler/scala/tools/nsc/interactive/REPL.scala
+++ b/src/compiler/scala/tools/nsc/interactive/REPL.scala
@@ -133,50 +133,6 @@ object REPL {
iSourceName
}
- /** Compile instrumented source file
- * @param iSourceName The name of the instrumented source file
- * @param arguments Further argumenrs to pass to the compiler
- * @return Optionallu, if no -d option is given, the virtual directory
- * contained the generated bytecode classes
- def compileInstrumented(iSourceName: String, arguments: List[String]): Option[AbstractFile] = {
- println("compiling "+iSourceName)
- val command = new CompilerCommand(iSourceName :: arguments, reporter.error(scala.reflect.internal.util.NoPosition, _))
- val virtualDirectoryOpt =
- if (arguments contains "-d")
- None
- else {
- val vdir = new VirtualDirectory("(memory)", None)
- command.settings.outputDirs setSingleOutput vdir
- Some(vdir)
- }
- val compiler = new scala.tools.nsc.Global(command.settings, reporter)
- val run = new compiler.Run()
- println("compiling: "+command.files)
- run compile command.files
- virtualDirectoryOpt
- }
-
- /** Run instrumented bytecode file
- * @param vdir Optionally, the virtual directory containing the generated bytecode classes
- * @param iFullName The full name of the generated object
- * @param stripped The contents original source file without any right hand column comments.
- * @return The generated file content containing original source in the left column
- * and outputs in the right column
- */
- def runInstrumented(vdirOpt: Option[AbstractFile], iFullName: String, stripped: Array[Char]): Array[Char] = {
- val defaultClassLoader = getClass.getClassLoader
- val classLoader = vdirOpt match {
- case Some(vdir) => new AbstractFileClassLoader(vdir, defaultClassLoader)
- case None => defaultClassLoader
- }
- println("running "+iFullName)
- val si = new SourceInserter(stripped)
- Executor.execute(iFullName, si, classLoader)
- println("done")
- si.currentContents
- }
- */
-
/** The method for implementing worksheet functionality.
* @param arguments a file name, followed by optional command line arguments that are passed
* to the compiler that processes the instrumented source.
@@ -191,7 +147,7 @@ object REPL {
// strip right hand side comment column and any trailing spaces from all lines
val strippedContents = SourceInserter.stripRight(source.content)
val strippedSource = new BatchSourceFile(source.file, strippedContents)
- println("stripped source = "+strippedSource)
+ println("stripped source = "+strippedSource+":"+strippedContents.mkString)
comp.askReload(List(strippedSource), reloadResult)
comp.askInstrumented(strippedSource, line, instrumentedResult)
using(instrumentedResult) {
diff --git a/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala b/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala
index 2aed99657e..0080cfd753 100644
--- a/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala
+++ b/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala
@@ -4,6 +4,7 @@ package interactive
import scala.reflect.internal.util.{SourceFile, BatchSourceFile, RangePosition}
import collection.mutable.ArrayBuffer
import reflect.internal.Chars.{isLineBreakChar, isWhitespace}
+import ast.parser.Tokens._
trait ScratchPadMaker { self: Global =>
@@ -11,7 +12,7 @@ trait ScratchPadMaker { self: Global =>
private case class Patch(offset: Int, text: String)
- private class Patcher(contents: Array[Char], endOffset: Int) extends Traverser {
+ private class Patcher(contents: Array[Char], lex: LexicalStructure, endOffset: Int) extends Traverser {
var objectName: String = ""
private val patches = new ArrayBuffer[Patch]
@@ -24,9 +25,13 @@ trait ScratchPadMaker { self: Global =>
"res$"+resNum
}
- private def nameType(name: String, tpe: Type): String = name+": "+tpe
+ private def nameType(name: String, tpe: Type): String = {
+ // if name ends in symbol character, add a space to separate it from the following ':'
+ val pad = if (Character.isLetter(name.last) || Character.isDigit(name.last)) "" else " "
+ name+pad+": "+tpe
+ }
- private def nameType(sym: Symbol): String = nameType(sym.name.toString, sym.tpe)
+ private def nameType(sym: Symbol): String = nameType(sym.name.decoded, sym.tpe)
private def literal(str: String) = "\"\"\""+str+"\"\"\""
@@ -42,19 +47,19 @@ trait ScratchPadMaker { self: Global =>
/** The position where to insert an instrumentation statement in front of giuven statement.
* This is at the latest `stat.pos.start`. But in order not to mess with column numbers
- * in position we try to insert it at the end of the preceding line instead.
- * To be safe, this can be done only if there's only whitespace between that position and
- * statement's start position.
+ * in position we try to insert it at the end of the previous token instead.
+ * Furthermore, `(' tokens have to be skipped because they do not show up
+ * in statement range positions.
*/
- private def instrumentPos(stat: Tree): Int = {
- var start = stat.pos.start
- while (start > 0 && isWhitespace(contents(start - 1))) start -= 1
- if (start > 0 && isLineBreakChar(contents(start - 1))) start -= 1
- start
+ private def instrumentPos(start: Int): Int = {
+ val (prevToken, prevStart, prevEnd) = lex.locate(start - 1)
+ if (prevStart >= start) start
+ else if (prevToken == LPAREN) instrumentPos(prevStart)
+ else prevEnd
}
private def addSkip(stat: Tree): Unit = {
- val ipos = instrumentPos(stat)
+ val ipos = instrumentPos(stat.pos.start)
if (stat.pos.start > skipped) applyPendingPatches(ipos)
if (stat.pos.start >= endOffset)
patches += Patch(ipos, ";$stop()")
@@ -98,7 +103,8 @@ trait ScratchPadMaker { self: Global =>
} else {
val resName = nextRes()
val dispResName = resName filter ('$' != _)
- patches += Patch(stat.pos.start, "val " + resName + " = ")
+ val offset = instrumentPos(stat.pos.start)
+ patches += Patch(offset, "val " + resName + " = ")
addSandbox(stat)
toPrint += resultString(nameType(dispResName, stat.tpe), resName)
}
@@ -146,6 +152,33 @@ trait ScratchPadMaker { self: Global =>
}
}
+ class LexicalStructure(source: SourceFile) {
+ val token = new ArrayBuffer[Int]
+ val startOffset = new ArrayBuffer[Int]
+ val endOffset = new ArrayBuffer[Int]
+ private val scanner = new syntaxAnalyzer.UnitScanner(new CompilationUnit(source))
+ scanner.init()
+ while (scanner.token != EOF) {
+ startOffset += scanner.offset
+ token += scanner.token
+ scanner.nextToken
+ endOffset += scanner.lastOffset
+ }
+
+ /** @return token that starts before or at offset, its startOffset, its endOffset
+ */
+ def locate(offset: Int): (Int, Int, Int) = {
+ var lo = 0
+ var hi = token.length - 1
+ while (lo < hi) {
+ val mid = (lo + hi + 1) / 2
+ if (startOffset(mid) <= offset) lo = mid
+ else hi = mid - 1
+ }
+ (token(lo), startOffset(lo), endOffset(lo))
+ }
+ }
+
/** Compute an instrumented version of a sourcefile.
* @param source The given sourcefile.
* @param line The line up to which results should be printed, -1 = whole document.
@@ -158,7 +191,7 @@ trait ScratchPadMaker { self: Global =>
protected def instrument(source: SourceFile, line: Int): (String, Array[Char]) = {
val tree = typedTree(source, true)
val endOffset = if (line < 0) source.length else source.lineToOffset(line + 1)
- val patcher = new Patcher(source.content, endOffset)
+ val patcher = new Patcher(source.content, new LexicalStructure(source), endOffset)
patcher.traverse(tree)
(patcher.objectName, patcher.result)
}
diff --git a/src/compiler/scala/tools/nsc/scratchpad/CommentOutputStream.scala b/src/compiler/scala/tools/nsc/scratchpad/CommentOutputStream.scala
deleted file mode 100644
index 92ccd79df9..0000000000
--- a/src/compiler/scala/tools/nsc/scratchpad/CommentOutputStream.scala
+++ /dev/null
@@ -1,18 +0,0 @@
-package scala.tools.nsc.scratchpad
-
-import java.io.OutputStream
-
-class CommentOutputStream(out: CommentWriter, encoding: String = "") extends OutputStream {
-
- override def write(bs: Array[Byte]) =
- out.write(if (encoding.isEmpty) new String(bs) else new String(bs, encoding))
-
- override def write(bs: Array[Byte], off: Int, len: Int) =
- out.write(if (encoding.isEmpty) new String(bs, off, len) else new String(bs, off, len, encoding))
-
- override def write(ch: Int) =
- write(Array(ch.toByte))
-
- override def close() = out.close()
- override def flush() = out.flush()
-} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/scratchpad/CommentWriter.scala b/src/compiler/scala/tools/nsc/scratchpad/CommentWriter.scala
deleted file mode 100644
index eb8880e437..0000000000
--- a/src/compiler/scala/tools/nsc/scratchpad/CommentWriter.scala
+++ /dev/null
@@ -1,42 +0,0 @@
-package scala.tools.nsc.scratchpad
-
-import java.io.Writer
-import reflect.internal.Chars._
-
-
-class CommentWriter(underlying: SourceInserter, startCol: Int = 40, endCol: Int = 152) extends Writer {
-
- private def rightCol(marker: String) = {
- while (underlying.column < startCol) underlying.write(' ')
- underlying.write(marker)
- }
-
- private var lastWasNL = false
-
- private def writeChar(ch: Char) = {
- if (underlying.column >= endCol) {
- underlying.write('\n'); rightCol("//| ")
- }
- if (underlying.column < startCol) rightCol("//> ")
- underlying.write(ch)
- lastWasNL = isLineBreakChar(ch)
- }
-
- override def write(chs: Array[Char], off: Int, len: Int) = {
- for (i <- off until off + len) writeChar(chs(i))
- flush()
- }
-
- def skip(len: Int) {
- if (lastWasNL) {
- underlying.backspace()
- lastWasNL = false
- }
- underlying.skip(len)
- if (underlying.column >= startCol) underlying.write('\n')
- }
-
- override def close() = underlying.close()
- override def flush() = underlying.flush()
-}
-
diff --git a/src/compiler/scala/tools/nsc/scratchpad/SourceInserter.scala b/src/compiler/scala/tools/nsc/scratchpad/SourceInserter.scala
index 42a35dc642..1c4fad5511 100644
--- a/src/compiler/scala/tools/nsc/scratchpad/SourceInserter.scala
+++ b/src/compiler/scala/tools/nsc/scratchpad/SourceInserter.scala
@@ -21,92 +21,3 @@ object SourceInserter {
(prefixes mkString "\n").toArray
}
}
-class SourceInserter(contents: Array[Char], start: Int = 0, tabInc: Int = 8) extends Writer {
-
- private var buf = contents
- private var offset = start
- private var hilen = contents.length
-
- def length = offset + hilen
-
- private def currentColumn: Int = {
- var i = offset
- while (i > 0 && !isLineBreakChar(buf(i - 1))) i -= 1
- var col = 0
- while (i < offset) {
- col = if (buf(i) == '\t') (col + tabInc) / tabInc * tabInc else col + 1
- i += 1
- }
- col
- }
-
- private var col = currentColumn
-
- def column = synchronized { col }
-
- private def addCapacity(n: Int) = {
- val newlength = length + n
- while (newlength > buf.length) {
- val buf1 = Array.ofDim[Char](buf.length * 2)
- Array.copy(buf, 0, buf1, 0, offset)
- Array.copy(buf, buf.length - hilen, buf1, buf1.length - hilen, hilen)
- buf = buf1
- }
- }
-
- private def insertChar(ch: Char) = {
-// Console.err.print("["+ch+"]")
- buf(offset) = ch
- offset += 1
- ch match {
- case LF => col = 0
- case '\t' => col = (col + tabInc) / tabInc * tabInc
- case _ => col += 1
- }
- }
-
- override def write(ch: Int) = synchronized {
- addCapacity(1)
- insertChar(ch.toChar)
- }
-
- override def write(chs: Array[Char], off: Int, len: Int) = synchronized {
- addCapacity(len)
- for (i <- off until off + len) insertChar(chs(i))
- }
-
- override def close() {
- }
-
- override def flush() {
- // signal buffer change
- }
-
- def currentContents = synchronized {
- if (length == buf.length) buf
- else {
- val res = Array.ofDim[Char](length)
- Array.copy(buf, 0, res, 0, offset)
- Array.copy(buf, buf.length - hilen, res, offset, hilen)
- res
- }
- }
-
- def backspace() = synchronized {
- offset -= 1
- if (offset > 0 && buf(offset) == LF && buf(offset - 1) == CR) offset -=1
- }
-
- def currentChar = synchronized {
- buf(buf.length - hilen)
- }
-
- def skip(len: Int) = synchronized {
- for (i <- 0 until len) {
- val ch = currentChar
- hilen -= 1
- insertChar(ch)
- }
- }
-}
-
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index d97fbf5daa..4b0a6ab44a 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -326,7 +326,7 @@ abstract class Erasure extends AddInterfaces
}
// Methods on Any/Object which we rewrite here while we still know what
// is a primitive and what arrived boxed.
- private lazy val interceptedMethods = Set[Symbol](Any_##, Object_##, Any_getClass) ++ (
+ private lazy val interceptedMethods = Set[Symbol](Any_##, Object_##, Any_getClass, AnyVal_getClass) ++ (
// Each value class has its own getClass for ultra-precise class object typing.
ScalaValueClasses map (_.tpe member nme.getClass_)
)
@@ -1069,9 +1069,11 @@ abstract class Erasure extends AddInterfaces
case _ =>
global.typer.typed(gen.mkRuntimeCall(nme.hash_, List(qual)))
}
- } else if (isPrimitiveValueClass(qual.tpe.typeSymbol)) {
+ } else if (isPrimitiveValueClass(qual.tpe.typeSymbol)) {
// Rewrite 5.getClass to ScalaRunTime.anyValClass(5)
global.typer.typed(gen.mkRuntimeCall(nme.anyValClass, List(qual, typer.resolveClassTag(tree.pos, qual.tpe.widen))))
+ } else if (fn.symbol == AnyVal_getClass) {
+ tree setSymbol Object_getClass
} else {
tree
}
@@ -1079,8 +1081,8 @@ abstract class Erasure extends AddInterfaces
case New(tpt) if name == nme.CONSTRUCTOR && tpt.tpe.typeSymbol.isDerivedValueClass =>
// println("inject derived: "+arg+" "+tpt.tpe)
val List(arg) = args
- InjectDerivedValue(arg) addAttachment //@@@ setSymbol tpt.tpe.typeSymbol
- new TypeRefAttachment(tree.tpe.asInstanceOf[TypeRef])
+ val attachment = new TypeRefAttachment(tree.tpe.asInstanceOf[TypeRef])
+ InjectDerivedValue(arg) addAttachment attachment
case _ =>
preEraseNormalApply(tree)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala b/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala
index 9e175fa516..b04a736fd3 100644
--- a/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala
@@ -47,7 +47,7 @@ trait EtaExpansion { self: Analyzer =>
* tree is already attributed
* </p>
*/
- def etaExpand(unit : CompilationUnit, tree: Tree): Tree = {
+ def etaExpand(unit : CompilationUnit, tree: Tree, typer: Typer): Tree = {
val tpe = tree.tpe
var cnt = 0 // for NoPosition
def freshName() = {
@@ -69,7 +69,11 @@ trait EtaExpansion { self: Analyzer =>
val vname: Name = freshName()
// Problem with ticket #2351 here
defs += atPos(tree.pos) {
- val rhs = if (byName) Function(List(), tree) else tree
+ val rhs = if (byName) {
+ val res = typer.typed(Function(List(), tree))
+ new ChangeOwnerTraverser(typer.context.owner, res.symbol) traverse tree // SI-6274
+ res
+ } else tree
ValDef(Modifiers(SYNTHETIC), vname.toTermName, TypeTree(), rhs)
}
atPos(tree.pos.focus) {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 1b3602fca2..803fb2857e 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -923,10 +923,13 @@ trait Infer {
/** Is sym1 (or its companion class in case it is a module) a subclass of
* sym2 (or its companion class in case it is a module)?
*/
- def isProperSubClassOrObject(sym1: Symbol, sym2: Symbol): Boolean =
- sym1 != sym2 && sym1 != NoSymbol && (sym1 isSubClass sym2) ||
- sym1.isModuleClass && isProperSubClassOrObject(sym1.linkedClassOfClass, sym2) ||
- sym2.isModuleClass && isProperSubClassOrObject(sym1, sym2.linkedClassOfClass)
+ def isProperSubClassOrObject(sym1: Symbol, sym2: Symbol): Boolean = (
+ (sym1 != sym2) && (sym1 != NoSymbol) && (
+ (sym1 isSubClass sym2)
+ || (sym1.isModuleClass && isProperSubClassOrObject(sym1.linkedClassOfClass, sym2))
+ || (sym2.isModuleClass && isProperSubClassOrObject(sym1, sym2.linkedClassOfClass))
+ )
+ )
/** is symbol `sym1` defined in a proper subclass of symbol `sym2`?
*/
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index 01e773e528..59935677a8 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -630,7 +630,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
macroDef.owner)
} else
targ.tpe
- if (tpe.isConcrete) context.TypeTag(tpe) else context.AbsTypeTag(tpe)
+ context.AbsTypeTag(tpe)
})
macroTraceVerbose("tags: ")(tags)
diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
index 4f597f97c9..83740f1658 100644
--- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -369,7 +369,7 @@ trait MethodSynthesis {
}
/** A synthetic method which performs the implicit conversion implied by
- * the declaration of an implicit class. Yet to be written.
+ * the declaration of an implicit class.
*/
case class ImplicitClassWrapper(tree: ClassDef) extends DerivedFromClassDef {
def completer(sym: Symbol): Type = ??? // not needed
@@ -377,7 +377,7 @@ trait MethodSynthesis {
def derivedSym: Symbol = {
// Only methods will do! Don't want to pick up any stray
// companion objects of the same name.
- val result = enclClass.info decl name suchThat (_.isMethod)
+ val result = enclClass.info decl name suchThat (x => x.isMethod && x.isSynthetic)
assert(result != NoSymbol, "not found: "+name+" in "+enclClass+" "+enclClass.info.decls)
result
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index adced9d8c9..62f01b8afa 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -359,10 +359,39 @@ trait Namers extends MethodSynthesis {
}
}
+ /** Given a ClassDef or ModuleDef, verifies there isn't a companion which
+ * has been defined in a separate file.
+ */
+ private def validateCompanionDefs(tree: ImplDef) {
+ val sym = tree.symbol
+ if (sym eq NoSymbol) return
+
+ val ctx = if (context.owner.isPackageObjectClass) context.outer else context
+ val module = if (sym.isModule) sym else ctx.scope lookup tree.name.toTermName
+ val clazz = if (sym.isClass) sym else ctx.scope lookup tree.name.toTypeName
+ val fails = (
+ module.isModule
+ && clazz.isClass
+ && !module.isSynthetic
+ && !clazz.isSynthetic
+ && (clazz.sourceFile ne null)
+ && (module.sourceFile ne null)
+ && !(module isCoDefinedWith clazz)
+ )
+ if (fails) {
+ context.unit.error(tree.pos, (
+ s"Companions '$clazz' and '$module' must be defined in same file:\n"
+ + s" Found in ${clazz.sourceFile.canonicalPath} and ${module.sourceFile.canonicalPath}")
+ )
+ }
+ }
+
def enterModuleDef(tree: ModuleDef) = {
val sym = enterModuleSymbol(tree)
sym.moduleClass setInfo namerOf(sym).moduleClassTypeCompleter(tree)
sym setInfo completerOf(tree)
+ validateCompanionDefs(tree)
+ sym
}
/** Enter a module symbol. The tree parameter can be either
@@ -635,6 +664,7 @@ trait Namers extends MethodSynthesis {
}
else context.unit.error(tree.pos, "implicit classes must accept exactly one primary constructor parameter")
}
+ validateCompanionDefs(tree)
}
// this logic is needed in case typer was interrupted half
@@ -699,7 +729,7 @@ trait Namers extends MethodSynthesis {
// }
}
- def moduleClassTypeCompleter(tree: Tree) = {
+ def moduleClassTypeCompleter(tree: ModuleDef) = {
mkTypeCompleter(tree) { sym =>
val moduleSymbol = tree.symbol
assert(moduleSymbol.moduleClass == sym, moduleSymbol.moduleClass)
@@ -1545,18 +1575,11 @@ trait Namers extends MethodSynthesis {
* call this method?
*/
def companionSymbolOf(original: Symbol, ctx: Context): Symbol = {
- try {
- original.companionSymbol orElse {
- ctx.lookup(original.name.companionName, original.owner).suchThat(sym =>
- (original.isTerm || sym.hasModuleFlag) &&
- (sym isCoDefinedWith original)
- )
- }
- }
- catch {
- case e: InvalidCompanions =>
- ctx.unit.error(original.pos, e.getMessage)
- NoSymbol
+ original.companionSymbol orElse {
+ ctx.lookup(original.name.companionName, original.owner).suchThat(sym =>
+ (original.isTerm || sym.hasModuleFlag) &&
+ (sym isCoDefinedWith original)
+ )
}
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 166bb2d18c..f1f2794a95 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -430,6 +430,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
overrideError("cannot override a macro")
} else {
checkOverrideTypes()
+ checkOverrideDeprecated()
if (settings.warnNullaryOverride.value) {
if (other.paramss.isEmpty && !member.paramss.isEmpty) {
unit.warning(member.pos, "non-nullary method overrides nullary method")
@@ -508,6 +509,14 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
}
}
}
+
+ def checkOverrideDeprecated() {
+ if (other.hasDeprecatedOverridingAnnotation) {
+ val suffix = other.deprecatedOverridingMessage map (": " + _) getOrElse ""
+ val msg = s"overriding ${other.fullLocationString} is deprecated$suffix"
+ unit.deprecationWarning(member.pos, msg)
+ }
+ }
}
val opc = new overridingPairs.Cursor(clazz)
@@ -1197,6 +1206,18 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
case _ =>
}
+ // SI-6276 warn for `def foo = foo` or `val bar: X = bar`, which come up more frequently than you might think.
+ def checkInfiniteLoop(valOrDef: ValOrDefDef) {
+ val trivialInifiniteLoop = (
+ !valOrDef.isErroneous
+ && !valOrDef.symbol.isValueParameter
+ && valOrDef.symbol.paramss.isEmpty
+ && valOrDef.rhs.hasSymbolWhich(_.accessedOrSelf == valOrDef.symbol)
+ )
+ if (trivialInifiniteLoop)
+ unit.warning(valOrDef.rhs.pos, s"${valOrDef.symbol.fullLocationString} does nothing other than call itself recursively")
+ }
+
// Transformation ------------------------------------------------------------
/* Convert a reference to a case factory of type `tpe` to a new of the class it produces. */
@@ -1640,6 +1661,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
case ValDef(_, _, _, _) | DefDef(_, _, _, _, _, _) =>
checkDeprecatedOvers(tree)
+ checkInfiniteLoop(tree.asInstanceOf[ValOrDefDef])
if (settings.warnNullaryUnit.value)
checkNullaryMethodReturnType(sym)
if (settings.warnInaccessible.value) {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 1845776c2d..d48f5a4145 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -579,7 +579,7 @@ trait Typers extends Modes with Adaptations with Tags {
// to notice exhaustiveness and to generate good code when
// List extractors are mixed with :: patterns. See Test5 in lists.scala.
def dealias(sym: Symbol) =
- (atPos(tree.pos) {gen.mkAttributedRef(sym)}, sym.owner.thisType)
+ (atPos(tree.pos.makeTransparent) {gen.mkAttributedRef(sym)} setPos tree.pos, sym.owner.thisType)
sym.name match {
case nme.List => return dealias(ListModule)
case nme.Seq => return dealias(SeqModule)
@@ -886,7 +886,7 @@ trait Typers extends Modes with Adaptations with Tags {
if (!meth.isConstructor && !meth.isTermMacro && isFunctionType(pt)) { // (4.2)
debuglog("eta-expanding " + tree + ":" + tree.tpe + " to " + pt)
checkParamsConvertible(tree, tree.tpe)
- val tree0 = etaExpand(context.unit, tree)
+ val tree0 = etaExpand(context.unit, tree, this)
// println("eta "+tree+" ---> "+tree0+":"+tree0.tpe+" undet: "+context.undetparams+ " mode: "+Integer.toHexString(mode))
if (context.undetparams.nonEmpty) {
@@ -1057,7 +1057,7 @@ trait Typers extends Modes with Adaptations with Tags {
case other =>
other
}
- typed(atPos(tree.pos)(Select(qual, nme.apply)), mode, pt)
+ typed(atPos(tree.pos)(Select(qual setPos tree.pos.makeTransparent, nme.apply)), mode, pt)
}
// begin adapt
@@ -1577,6 +1577,12 @@ trait Typers extends Modes with Adaptations with Tags {
if (psym.isFinal)
pending += ParentFinalInheritanceError(parent, psym)
+ if (psym.hasDeprecatedInheritanceAnnotation) {
+ val suffix = psym.deprecatedInheritanceMessage map (": " + _) getOrElse ""
+ val msg = s"inheritance from ${psym.fullLocationString} is deprecated$suffix"
+ unit.deprecationWarning(parent.pos, msg)
+ }
+
if (psym.isSealed && !phase.erasedTypes)
if (context.unit.source.file == psym.sourceFile)
psym addChild context.owner
@@ -2395,7 +2401,7 @@ trait Typers extends Modes with Adaptations with Tags {
else targs.init
def mkParams(methodSym: Symbol, formals: List[Type] = deriveFormals) =
- if (formals.isEmpty) { MissingParameterTypeAnonMatchError(tree, pt); Nil }
+ if (formals.isEmpty || !formals.forall(isFullyDefined)) { MissingParameterTypeAnonMatchError(tree, pt); Nil }
else methodSym newSyntheticValueParams formals
def mkSel(params: List[Symbol]) =
@@ -2743,12 +2749,18 @@ trait Typers extends Modes with Adaptations with Tags {
// this code by associating defaults and companion objects
// with the original tree instead of the new symbol.
def matches(stat: Tree, synt: Tree) = (stat, synt) match {
+ // synt is default arg for stat
case (DefDef(_, statName, _, _, _, _), DefDef(mods, syntName, _, _, _, _)) =>
mods.hasDefaultFlag && syntName.toString.startsWith(statName.toString)
+ // synt is companion module
case (ClassDef(_, className, _, _), ModuleDef(_, moduleName, _)) =>
className.toTermName == moduleName
+ // synt is implicit def for implicit class (#6278)
+ case (ClassDef(cmods, cname, _, _), DefDef(dmods, dname, _, _, _, _)) =>
+ cmods.isImplicit && dmods.isImplicit && cname.toTermName == dname
+
case _ => false
}
@@ -3811,18 +3823,23 @@ trait Typers extends Modes with Adaptations with Tags {
* - simplest solution: have two method calls
*
*/
- def mkInvoke(cxTree: Tree, tree: Tree, qual: Tree, name: Name): Option[Tree] =
+ def mkInvoke(cxTree: Tree, tree: Tree, qual: Tree, name: Name): Option[Tree] = {
+ debuglog(s"mkInvoke($cxTree, $tree, $qual, $name)")
acceptsApplyDynamicWithType(qual, name) map { tp =>
// tp eq NoType => can call xxxDynamic, but not passing any type args (unless specified explicitly by the user)
// in scala-virtualized, when not NoType, tp is passed as type argument (for selection on a staged Struct)
- // strip off type application -- we're not doing much with outer, so don't bother preserving cxTree's attributes etc
- val (outer, explicitTargs) = cxTree match {
- case TypeApply(fun, targs) => (fun, targs)
- case Apply(TypeApply(fun, targs), args) => (Apply(fun, args), targs)
- case t => (t, Nil)
+ // strip off type application -- we're not doing much with outer,
+ // so don't bother preserving cxTree's attributes etc
+ val cxTree1 = cxTree match {
+ case t: ValOrDefDef => t.rhs
+ case t => t
+ }
+ val (outer, explicitTargs) = cxTree1 match {
+ case TypeApply(fun, targs) => (fun, targs)
+ case Apply(TypeApply(fun, targs), args) => (Apply(fun, args), targs)
+ case t => (t, Nil)
}
-
@inline def hasNamedArg(as: List[Tree]) = as.collectFirst{case AssignOrNamedArg(lhs, rhs) =>}.nonEmpty
// note: context.tree includes at most one Apply node
@@ -3847,6 +3864,7 @@ trait Typers extends Modes with Adaptations with Tags {
atPos(qual.pos)(Apply(tappSel, List(Literal(Constant(name.decode)))))
}
+ }
}
@inline final def deindentTyping() = context.typingIndentLevel -= 2
diff --git a/src/library/scala/StringContext.scala b/src/library/scala/StringContext.scala
index 723d95a499..453f29d9e6 100644
--- a/src/library/scala/StringContext.scala
+++ b/src/library/scala/StringContext.scala
@@ -19,7 +19,7 @@ case class StringContext(parts: String*) {
import StringContext._
- /** Checks that the given arguments `args` number one less than the number
+ /** Checks that the length of the given argument `args` is one less than the number
* of `parts` supplied to the enclosing `StringContext`.
* @param `args` The arguments to be checked.
* @throws An `IllegalArgumentException` if this is not the case.
@@ -37,7 +37,7 @@ case class StringContext(parts: String*) {
* @throws An `IllegalArgumentException`
* if the number of `parts` in the enclosing `StringContext` does not exceed
* the number of arguments `arg` by exactly 1.
- * @throws A `StringContext.InvalidEscapeException` if if a `parts` string contains a backslash (`\`) character
+ * @throws A `StringContext.InvalidEscapeException` if a `parts` string contains a backslash (`\`) character
* that does not start a valid escape sequence.
*/
def s(args: Any*): String = standardInterpolator(treatEscapes, args)
@@ -51,7 +51,7 @@ case class StringContext(parts: String*) {
* @throws An `IllegalArgumentException`
* if the number of `parts` in the enclosing `StringContext` does not exceed
* the number of arguments `arg` by exactly 1.
- * @throws A `StringContext.InvalidEscapeException` if if a `parts` string contains a backslash (`\`) character
+ * @throws A `StringContext.InvalidEscapeException` if a `parts` string contains a backslash (`\`) character
* that does not start a valid escape sequence.
*/
def raw(args: Any*): String = standardInterpolator(identity, args)
@@ -102,7 +102,7 @@ case class StringContext(parts: String*) {
object StringContext {
- /** An exception that is thrown if a string contains a backslash (`\`) character that
+ /** An exception that is thrown if a string contains a backslash (`\`) character
* that does not start a valid escape sequence.
* @param str The offending string
* @param idx The index of the offending backslash character in `str`.
diff --git a/src/library/scala/collection/parallel/ParIterableLike.scala b/src/library/scala/collection/parallel/ParIterableLike.scala
index 26877a32b1..ef693ab7ca 100644
--- a/src/library/scala/collection/parallel/ParIterableLike.scala
+++ b/src/library/scala/collection/parallel/ParIterableLike.scala
@@ -453,7 +453,7 @@ self: ParIterableLike[T, Repr, Sequential] =>
def reduceRightOption[U >: T](op: (T, U) => U): Option[U] = seq.reduceRightOption(op)
- /** Applies a function `f` to all the elements of $coll in a sequential order.
+ /** Applies a function `f` to all the elements of $coll in a undefined order.
*
* @tparam U the result type of the function applied to each element, which is always discarded
* @param f function applied to each element
diff --git a/src/library/scala/concurrent/util/Duration.scala b/src/library/scala/concurrent/util/Duration.scala
index bab664727e..bf0f3006f1 100644
--- a/src/library/scala/concurrent/util/Duration.scala
+++ b/src/library/scala/concurrent/util/Duration.scala
@@ -26,76 +26,68 @@ object Deadline {
def now: Deadline = Deadline(Duration(System.nanoTime, NANOSECONDS))
}
+// TODO: "Inf", "PlusInf", "MinusInf", where did these names come from?
+// TODO: Duration.create(n, DAYS) == Duration(Long.MaxValue, NANOSECONDS) forall (n: Double) >= 106752d
object Duration {
implicit def timeLeft(implicit d: Deadline): Duration = d.timeLeft
- def apply(length: Long, unit: TimeUnit): FiniteDuration = new FiniteDuration(length, unit)
def apply(length: Double, unit: TimeUnit): FiniteDuration = fromNanos(unit.toNanos(1) * length)
- def apply(length: Long, unit: String): FiniteDuration = new FiniteDuration(length, Duration.timeUnit(unit))
+ def apply(length: Long, unit: TimeUnit): FiniteDuration = new FiniteDuration(length, unit)
+ def apply(length: Long, unit: String): FiniteDuration = new FiniteDuration(length, Duration.timeUnit(unit))
/**
- * Construct a Duration by parsing a String. In case of a format error, a
- * RuntimeException is thrown. See `unapply(String)` for more information.
- */
- def apply(s: String): Duration = unapply(s) getOrElse sys.error("format error " + s)
-
- private val RE = ("""^\s*([\+|-]?\d+(?:\.\d+)?)\s*""" + // length part
- "(?:" + // units are distinguished in separate match groups
- "(d|day|days)|" +
- "(h|hour|hours)|" +
- "(min|minute|minutes)|" +
- "(s|sec|second|seconds)|" +
- "(ms|milli|millis|millisecond|milliseconds)|" +
- "(µs|micro|micros|microsecond|microseconds)|" +
- "(ns|nano|nanos|nanosecond|nanoseconds)" +
- """)\s*$""").r // close the non-capturing group
- private val REinf = """^\s*(?:\+|Plus)?Inf\s*$""".r
- private val REminf = """^\s*(?:-|Minus)Inf\s*""".r
-
- /**
- * Deconstruct a Duration into `Long` length and [[java.util.concurrent.TimeUnit]] if it is a
- * [[scala.util.concurrent.FiniteDuration]].
- *
- * @param d Duration to be deconstructed.
+ * Parse String into Duration. Format is `"<length><unit>"`, where
+ * whitespace is allowed before, between and after the parts. Infinities are
+ * designated by `"Inf"`, `"PlusInf"`, `"+Inf"` and `"-Inf"` or `"MinusInf"`.
+ * Throws exception if format is not parseable.
*/
- def unapply(d: Duration): Option[(Long, TimeUnit)] = {
- if (d.finite_?) {
- Some((d.length, d.unit))
- } else {
- None
+ def apply(s: String): Duration = {
+ val s1: String = s filterNot (_.isWhitespace)
+ s1 match {
+ case "Inf" | "PlusInf" | "+Inf" => Inf
+ case "MinusInf" | "-Inf" => MinusInf
+ case _ =>
+ val unitName = s1.reverse takeWhile (_.isLetter) reverse;
+ def length = JDouble.parseDouble(s1 dropRight unitName.length)
+ timeUnit get unitName match {
+ case Some(unit) => Duration(length, unit)
+ case _ => sys.error("format error " + s)
+ }
}
}
- /**
- * Parse String, return None if no match. Format is `"<length><unit>"`, where
- * whitespace is allowed before, between and after the parts. Infinities are
- * designated by `"Inf"`, `"PlusInf"`, `"+Inf"` and `"-Inf"` or `"MinusInf"`.
- */
- def unapply(s: String): Option[Duration] = s match {
- case RE(length, d, h, m, s, ms, mus, ns) ⇒
- if (d ne null)
- Some(Duration(JDouble.parseDouble(length), DAYS))
- else if (h ne null)
- Some(Duration(JDouble.parseDouble(length), HOURS))
- else if (m ne null)
- Some(Duration(JDouble.parseDouble(length), MINUTES))
- else if (s ne null)
- Some(Duration(JDouble.parseDouble(length), SECONDS))
- else if (ms ne null)
- Some(Duration(JDouble.parseDouble(length), MILLISECONDS))
- else if (mus ne null)
- Some(Duration(JDouble.parseDouble(length), MICROSECONDS))
- else if (ns ne null)
- Some(Duration(JDouble.parseDouble(length), NANOSECONDS))
- else
- sys.error("made some error in regex (should not be possible)")
- case REinf() ⇒ Some(Inf)
- case REminf() ⇒ Some(MinusInf)
- case _ ⇒ None
+ // "ms milli millisecond" -> List("ms", "milli", "millis", "millisecond", "milliseconds")
+ private def words(s: String) = (s.trim split "\\s+").toList
+ private def expandLabels(labels: String): List[String] = {
+ val hd :: rest = words(labels)
+ hd :: rest.flatMap(s => List(s, s + "s"))
}
+ private val timeUnitLabels = List(
+ DAYS -> "d day",
+ HOURS -> "h hour",
+ MINUTES -> "min minute",
+ SECONDS -> "s sec second",
+ MILLISECONDS -> "ms milli millisecond",
+ MICROSECONDS -> "µs micro microsecond",
+ NANOSECONDS -> "ns nano nanosecond"
+ )
+
+ // TimeUnit => standard label
+ protected[util] val timeUnitName: Map[TimeUnit, String] =
+ timeUnitLabels.toMap mapValues (s => words(s).last) toMap
+
+ // Label => TimeUnit
+ protected[util] val timeUnit: Map[String, TimeUnit] =
+ timeUnitLabels flatMap { case (unit, names) => expandLabels(names) map (_ -> unit) } toMap
+
+ def unapply(s: String): Option[(Long, TimeUnit)] =
+ ( try Some(apply(s)) catch { case _: RuntimeException => None } ) flatMap unapply
+
+ def unapply(d: Duration): Option[(Long, TimeUnit)] =
+ if (d.isFinite) Some((d.length, d.unit)) else None
def fromNanos(nanos: Double): FiniteDuration =
- fromNanos((nanos + 0.5).asInstanceOf[Long])
+ fromNanos((nanos + 0.5).toLong)
def fromNanos(nanos: Long): FiniteDuration = {
if (nanos % 86400000000000L == 0) {
@@ -118,72 +110,62 @@ object Duration {
/**
* Parse TimeUnit from string representation.
*/
- protected[util] def timeUnit(unit: String): TimeUnit = unit.toLowerCase match {
- case "d" | "day" | "days" => DAYS
- case "h" | "hour" | "hours" => HOURS
- case "min" | "minute" | "minutes" => MINUTES
- case "s" | "sec" | "second" | "seconds" => SECONDS
- case "ms" | "milli" | "millis" | "millisecond" | "milliseconds" => MILLISECONDS
- case "µs" | "micro" | "micros" | "microsecond" | "microseconds" => MICROSECONDS
- case "ns" | "nano" | "nanos" | "nanosecond" | "nanoseconds" => NANOSECONDS
- }
val Zero: FiniteDuration = new FiniteDuration(0, NANOSECONDS)
- val Undefined: Duration = new Duration with Infinite {
+
+ object Undefined extends Infinite {
+ private def fail(what: String) = throw new IllegalArgumentException(s"cannot $what Undefined duration")
+
override def toString = "Duration.Undefined"
- override def equals(other: Any) = other.asInstanceOf[AnyRef] eq this
- override def +(other: Duration): Duration = throw new IllegalArgumentException("cannot add Undefined duration")
- override def -(other: Duration): Duration = throw new IllegalArgumentException("cannot subtract Undefined duration")
- override def *(factor: Double): Duration = throw new IllegalArgumentException("cannot multiply Undefined duration")
- override def /(factor: Double): Duration = throw new IllegalArgumentException("cannot divide Undefined duration")
- override def /(other: Duration): Double = throw new IllegalArgumentException("cannot divide Undefined duration")
- def compare(other: Duration) = throw new IllegalArgumentException("cannot compare Undefined duration")
- def unary_- : Duration = throw new IllegalArgumentException("cannot negate Undefined duration")
+ override def equals(other: Any) = this eq other.asInstanceOf[AnyRef]
+ override def +(other: Duration): Duration = fail("add")
+ override def -(other: Duration): Duration = fail("subtract")
+ override def *(factor: Double): Duration = fail("multiply")
+ override def /(factor: Double): Duration = fail("divide")
+ override def /(other: Duration): Double = fail("divide")
+ def compare(other: Duration) = fail("compare")
+ def unary_- : Duration = fail("negate")
}
- trait Infinite {
- this: Duration =>
-
- def +(other: Duration): Duration =
- other match {
- case _: this.type => this
- case _: Infinite => throw new IllegalArgumentException("illegal addition of infinities")
- case _ => this
- }
+ sealed abstract class Infinite extends Duration {
+ def +(other: Duration): Duration = other match {
+ case x: Infinite if x ne this => throw new IllegalArgumentException("illegal addition of infinities")
+ case _ => this
+ }
+ // Is this really intended to throw if the argument is "this" but otherwise return this?
def -(other: Duration): Duration =
- other match {
- case _: this.type => throw new IllegalArgumentException("illegal subtraction of infinities")
- case _ => this
- }
+ if (other ne this) this
+ else throw new IllegalArgumentException("illegal subtraction of infinities")
+
def *(factor: Double): Duration = this
def /(factor: Double): Duration = this
- def /(other: Duration): Double =
- other match {
- case _: Infinite => throw new IllegalArgumentException("illegal division of infinities")
- // maybe questionable but pragmatic: Inf / 0 => Inf
- case x => Double.PositiveInfinity * (if ((this > Zero) ^ (other >= Zero)) -1 else 1)
- }
-
- def finite_? = false
-
- def length: Long = throw new IllegalArgumentException("length not allowed on infinite Durations")
- def unit: TimeUnit = throw new IllegalArgumentException("unit not allowed on infinite Durations")
- def toNanos: Long = throw new IllegalArgumentException("toNanos not allowed on infinite Durations")
- def toMicros: Long = throw new IllegalArgumentException("toMicros not allowed on infinite Durations")
- def toMillis: Long = throw new IllegalArgumentException("toMillis not allowed on infinite Durations")
- def toSeconds: Long = throw new IllegalArgumentException("toSeconds not allowed on infinite Durations")
- def toMinutes: Long = throw new IllegalArgumentException("toMinutes not allowed on infinite Durations")
- def toHours: Long = throw new IllegalArgumentException("toHours not allowed on infinite Durations")
- def toDays: Long = throw new IllegalArgumentException("toDays not allowed on infinite Durations")
- def toUnit(unit: TimeUnit): Double = throw new IllegalArgumentException("toUnit not allowed on infinite Durations")
+ def /(other: Duration): Double = other match {
+ case _: Infinite => throw new IllegalArgumentException("illegal division of infinities")
+ // maybe questionable but pragmatic: Inf / 0 => Inf
+ case x => Double.PositiveInfinity * (if ((this > Zero) ^ (other >= Zero)) -1 else 1)
+ }
+
+ final def isFinite() = false
+ private def fail(what: String) = throw new IllegalArgumentException(s"$what not allowed on infinite Durations")
+ def length: Long = fail("length")
+ def toNanos: Long = fail("toNanos")
+ def toMicros: Long = fail("toMicros")
+ def toMillis: Long = fail("toMillis")
+ def toSeconds: Long = fail("toSeconds")
+ def toMinutes: Long = fail("toMinutes")
+ def toHours: Long = fail("toHours")
+ def toDays: Long = fail("toDays")
+
+ def unit: TimeUnit = fail("unit")
+ def toUnit(unit: TimeUnit): Double = fail("toUnit")
}
/**
* Infinite duration: greater than any other and not equal to any other,
* including itself.
*/
- val Inf: Duration = new Duration with Infinite {
+ val Inf: Infinite = new Infinite {
override def toString = "Duration.Inf"
def compare(other: Duration) = if (other eq this) 0 else 1
def unary_- : Duration = MinusInf
@@ -193,17 +175,17 @@ object Duration {
* Infinite negative duration: lesser than any other and not equal to any other,
* including itself.
*/
- val MinusInf: Duration = new Duration with Infinite {
+ val MinusInf: Infinite = new Infinite {
override def toString = "Duration.MinusInf"
def compare(other: Duration) = if (other eq this) 0 else -1
def unary_- : Duration = Inf
}
// Java Factories
- def create(length: Long, unit: TimeUnit): FiniteDuration = apply(length, unit)
+ def create(length: Long, unit: TimeUnit): FiniteDuration = apply(length, unit)
def create(length: Double, unit: TimeUnit): FiniteDuration = apply(length, unit)
- def create(length: Long, unit: String): FiniteDuration = apply(length, unit)
- def parse(s: String): Duration = unapply(s).get
+ def create(length: Long, unit: String): FiniteDuration = apply(length, unit)
+ def create(s: String): Duration = apply(s)
implicit object DurationIsOrdered extends Ordering[Duration] {
def compare(a: Duration, b: Duration) = a compare b
@@ -261,23 +243,22 @@ abstract class Duration extends Serializable with Ordered[Duration] {
def /(factor: Double): Duration
def /(other: Duration): Double
def unary_- : Duration
- def finite_? : Boolean
+ def isFinite(): Boolean
def min(other: Duration): Duration = if (this < other) this else other
def max(other: Duration): Duration = if (this > other) this else other
def fromNow: Deadline = Deadline.now + this
// Java API
- def lt(other: Duration) = this < other
- def lteq(other: Duration) = this <= other
- def gt(other: Duration) = this > other
- def gteq(other: Duration) = this >= other
- def plus(other: Duration) = this + other
+ def div(factor: Double) = this / factor
+ def div(other: Duration) = this / other
+ def gt(other: Duration) = this > other
+ def gteq(other: Duration) = this >= other
+ def lt(other: Duration) = this < other
+ def lteq(other: Duration) = this <= other
def minus(other: Duration) = this - other
- def mul(factor: Double) = this * factor
- def div(factor: Double) = this / factor
- def div(other: Duration) = this / other
- def neg() = -this
- def isFinite() = finite_?
+ def mul(factor: Double) = this * factor
+ def neg() = -this
+ def plus(other: Duration) = this + other
}
object FiniteDuration {
@@ -286,252 +267,121 @@ object FiniteDuration {
}
def apply(length: Long, unit: TimeUnit) = new FiniteDuration(length, unit)
-
- def apply(length: Long, unit: String) = new FiniteDuration(length, Duration.timeUnit(unit))
-
+ def apply(length: Long, unit: String) = new FiniteDuration(length, Duration.timeUnit(unit))
}
class FiniteDuration(val length: Long, val unit: TimeUnit) extends Duration {
import Duration._
- def toNanos = unit.toNanos(length)
- def toMicros = unit.toMicros(length)
- def toMillis = unit.toMillis(length)
+ def toNanos = unit.toNanos(length)
+ def toMicros = unit.toMicros(length)
+ def toMillis = unit.toMillis(length)
def toSeconds = unit.toSeconds(length)
def toMinutes = unit.toMinutes(length)
- def toHours = unit.toHours(length)
- def toDays = unit.toDays(length)
+ def toHours = unit.toHours(length)
+ def toDays = unit.toDays(length)
def toUnit(u: TimeUnit) = toNanos.toDouble / NANOSECONDS.convert(1, u)
- override def toString = this match {
- case Duration(1, DAYS) => "1 day"
- case Duration(x, DAYS) => x + " days"
- case Duration(1, HOURS) => "1 hour"
- case Duration(x, HOURS) => x + " hours"
- case Duration(1, MINUTES) => "1 minute"
- case Duration(x, MINUTES) => x + " minutes"
- case Duration(1, SECONDS) => "1 second"
- case Duration(x, SECONDS) => x + " seconds"
- case Duration(1, MILLISECONDS) => "1 millisecond"
- case Duration(x, MILLISECONDS) => x + " milliseconds"
- case Duration(1, MICROSECONDS) => "1 microsecond"
- case Duration(x, MICROSECONDS) => x + " microseconds"
- case Duration(1, NANOSECONDS) => "1 nanosecond"
- case Duration(x, NANOSECONDS) => x + " nanoseconds"
- }
-
- def compare(other: Duration) =
- if (other.finite_?) {
- val me = toNanos
- val o = other.toNanos
- if (me > o) 1 else if (me < o) -1 else 0
- } else -other.compare(this)
+ private def unitString = timeUnitName(unit) + ( if (length == 1) "" else "s" )
+ override def toString = "" + length + " " + unitString
- def +(other: Duration) = {
- if (!other.finite_?) {
- other
- } else {
- val nanos = toNanos + other.asInstanceOf[FiniteDuration].toNanos
- fromNanos(nanos)
- }
+ def compare(other: Duration) = other match {
+ case x: FiniteDuration => toNanos compare x.toNanos
+ case _ => -(other compare this)
}
-
- def -(other: Duration) = {
- if (!other.finite_?) {
- other
- } else {
- val nanos = toNanos - other.asInstanceOf[FiniteDuration].toNanos
- fromNanos(nanos)
- }
+ def +(other: Duration) = other match {
+ case x: FiniteDuration => fromNanos(toNanos + x.toNanos)
+ case _ => other
+ }
+ def -(other: Duration) = other match {
+ case x: FiniteDuration => fromNanos(toNanos - x.toNanos)
+ case _ => other
}
def *(factor: Double) = fromNanos(toNanos.toDouble * factor)
def /(factor: Double) = fromNanos(toNanos.toDouble / factor)
- def /(other: Duration) = if (other.finite_?) toNanos.toDouble / other.toNanos else 0
+ def /(other: Duration) = if (other.isFinite) toNanos.toDouble / other.toNanos else 0
def unary_- = Duration(-length, unit)
- def finite_? = true
-
- override def equals(other: Any) =
- other.isInstanceOf[FiniteDuration] &&
- toNanos == other.asInstanceOf[FiniteDuration].toNanos
+ final def isFinite() = true
- override def hashCode = toNanos.asInstanceOf[Int]
+ override def equals(other: Any) = other match {
+ case x: FiniteDuration => toNanos == x.toNanos
+ case _ => super.equals(other)
+ }
+ override def hashCode = toNanos.toInt
}
-class DurationInt(n: Int) {
+trait DurationConversions extends Any {
import duration.Classifier
+ protected def durationIn(unit: TimeUnit): FiniteDuration
- def nanoseconds = Duration(n, NANOSECONDS)
- def nanos = Duration(n, NANOSECONDS)
- def nanosecond = Duration(n, NANOSECONDS)
- def nano = Duration(n, NANOSECONDS)
+ def nanoseconds = durationIn(NANOSECONDS)
+ def nanos = nanoseconds
+ def nanosecond = nanoseconds
+ def nano = nanoseconds
- def microseconds = Duration(n, MICROSECONDS)
- def micros = Duration(n, MICROSECONDS)
- def microsecond = Duration(n, MICROSECONDS)
- def micro = Duration(n, MICROSECONDS)
+ def microseconds = durationIn(MICROSECONDS)
+ def micros = microseconds
+ def microsecond = microseconds
+ def micro = microseconds
- def milliseconds = Duration(n, MILLISECONDS)
- def millis = Duration(n, MILLISECONDS)
- def millisecond = Duration(n, MILLISECONDS)
- def milli = Duration(n, MILLISECONDS)
+ def milliseconds = durationIn(MILLISECONDS)
+ def millis = milliseconds
+ def millisecond = milliseconds
+ def milli = milliseconds
- def seconds = Duration(n, SECONDS)
- def second = Duration(n, SECONDS)
+ def seconds = durationIn(SECONDS)
+ def second = seconds
- def minutes = Duration(n, MINUTES)
- def minute = Duration(n, MINUTES)
+ def minutes = durationIn(MINUTES)
+ def minute = minutes
- def hours = Duration(n, HOURS)
- def hour = Duration(n, HOURS)
+ def hours = durationIn(HOURS)
+ def hour = hours
- def days = Duration(n, DAYS)
- def day = Duration(n, DAYS)
+ def days = durationIn(DAYS)
+ def day = days
- def nanoseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, NANOSECONDS))
- def nanos[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, NANOSECONDS))
- def nanosecond[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, NANOSECONDS))
- def nano[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, NANOSECONDS))
+ def nanoseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(nanoseconds)
+ def nanos[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = nanoseconds(c)
+ def nanosecond[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = nanoseconds(c)
+ def nano[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = nanoseconds(c)
- def microseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MICROSECONDS))
- def micros[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MICROSECONDS))
- def microsecond[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MICROSECONDS))
- def micro[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MICROSECONDS))
+ def microseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(microseconds)
+ def micros[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = microseconds(c)
+ def microsecond[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = microseconds(c)
+ def micro[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = microseconds(c)
- def milliseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MILLISECONDS))
- def millis[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MILLISECONDS))
- def millisecond[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MILLISECONDS))
- def milli[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MILLISECONDS))
+ def milliseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(milliseconds)
+ def millis[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = milliseconds(c)
+ def millisecond[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = milliseconds(c)
+ def milli[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = milliseconds(c)
- def seconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, SECONDS))
- def second[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, SECONDS))
+ def seconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(seconds)
+ def second[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = seconds(c)
- def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MINUTES))
- def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MINUTES))
+ def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(minutes)
+ def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = minutes(c)
- def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, HOURS))
- def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, HOURS))
+ def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(hours)
+ def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = hours(c)
- def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, DAYS))
- def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, DAYS))
+ def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(days)
+ def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = days(c)
}
-class DurationLong(n: Long) {
- import duration.Classifier
-
- def nanoseconds = Duration(n, NANOSECONDS)
- def nanos = Duration(n, NANOSECONDS)
- def nanosecond = Duration(n, NANOSECONDS)
- def nano = Duration(n, NANOSECONDS)
-
- def microseconds = Duration(n, MICROSECONDS)
- def micros = Duration(n, MICROSECONDS)
- def microsecond = Duration(n, MICROSECONDS)
- def micro = Duration(n, MICROSECONDS)
-
- def milliseconds = Duration(n, MILLISECONDS)
- def millis = Duration(n, MILLISECONDS)
- def millisecond = Duration(n, MILLISECONDS)
- def milli = Duration(n, MILLISECONDS)
-
- def seconds = Duration(n, SECONDS)
- def second = Duration(n, SECONDS)
-
- def minutes = Duration(n, MINUTES)
- def minute = Duration(n, MINUTES)
-
- def hours = Duration(n, HOURS)
- def hour = Duration(n, HOURS)
-
- def days = Duration(n, DAYS)
- def day = Duration(n, DAYS)
-
- def nanoseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, NANOSECONDS))
- def nanos[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, NANOSECONDS))
- def nanosecond[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, NANOSECONDS))
- def nano[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, NANOSECONDS))
-
- def microseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MICROSECONDS))
- def micros[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MICROSECONDS))
- def microsecond[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MICROSECONDS))
- def micro[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MICROSECONDS))
-
- def milliseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MILLISECONDS))
- def millis[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MILLISECONDS))
- def millisecond[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MILLISECONDS))
- def milli[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MILLISECONDS))
-
- def seconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, SECONDS))
- def second[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, SECONDS))
-
- def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MINUTES))
- def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MINUTES))
-
- def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, HOURS))
- def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, HOURS))
-
- def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, DAYS))
- def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, DAYS))
+final class DurationInt(val n: Int) extends AnyVal with DurationConversions {
+ override protected def durationIn(unit: TimeUnit): FiniteDuration = Duration(n, unit)
}
-class DurationDouble(d: Double) {
- import duration.Classifier
-
- def nanoseconds = Duration(d, NANOSECONDS)
- def nanos = Duration(d, NANOSECONDS)
- def nanosecond = Duration(d, NANOSECONDS)
- def nano = Duration(d, NANOSECONDS)
-
- def microseconds = Duration(d, MICROSECONDS)
- def micros = Duration(d, MICROSECONDS)
- def microsecond = Duration(d, MICROSECONDS)
- def micro = Duration(d, MICROSECONDS)
-
- def milliseconds = Duration(d, MILLISECONDS)
- def millis = Duration(d, MILLISECONDS)
- def millisecond = Duration(d, MILLISECONDS)
- def milli = Duration(d, MILLISECONDS)
-
- def seconds = Duration(d, SECONDS)
- def second = Duration(d, SECONDS)
-
- def minutes = Duration(d, MINUTES)
- def minute = Duration(d, MINUTES)
-
- def hours = Duration(d, HOURS)
- def hour = Duration(d, HOURS)
-
- def days = Duration(d, DAYS)
- def day = Duration(d, DAYS)
-
- def nanoseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, NANOSECONDS))
- def nanos[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, NANOSECONDS))
- def nanosecond[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, NANOSECONDS))
- def nano[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, NANOSECONDS))
-
- def microseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, MICROSECONDS))
- def micros[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, MICROSECONDS))
- def microsecond[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, MICROSECONDS))
- def micro[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, MICROSECONDS))
-
- def milliseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, MILLISECONDS))
- def millis[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, MILLISECONDS))
- def millisecond[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, MILLISECONDS))
- def milli[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, MILLISECONDS))
-
- def seconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, SECONDS))
- def second[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, SECONDS))
-
- def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, MINUTES))
- def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, MINUTES))
-
- def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, HOURS))
- def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, HOURS))
+final class DurationLong(val n: Long) extends AnyVal with DurationConversions {
+ override protected def durationIn(unit: TimeUnit): FiniteDuration = Duration(n, unit)
+}
- def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, DAYS))
- def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, DAYS))
+final class DurationDouble(val d: Double) extends AnyVal with DurationConversions {
+ override protected def durationIn(unit: TimeUnit): FiniteDuration = Duration(d, unit)
}
diff --git a/src/library/scala/deprecatedInheritance.scala b/src/library/scala/deprecatedInheritance.scala
new file mode 100644
index 0000000000..ca1b586223
--- /dev/null
+++ b/src/library/scala/deprecatedInheritance.scala
@@ -0,0 +1,22 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2012, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala
+
+/** An annotation that designates that inheriting from a class is deprecated.
+ *
+ * This is usually done to warn about a non-final class being made final in a future version.
+ * Sub-classing such a class then generates a warning.
+ *
+ * @param message the message to print during compilation if the class was sub-classed
+ * @param since a string identifying the first version in which inheritance was deprecated
+ * @since 2.10
+ * @see [[scala.deprecatedOverriding]]
+ */
+private[scala] // for now, this needs to be generalized to communicate other modifier deltas
+class deprecatedInheritance(message: String = "", since: String = "") extends annotation.StaticAnnotation
diff --git a/src/library/scala/deprecatedOverriding.scala b/src/library/scala/deprecatedOverriding.scala
new file mode 100644
index 0000000000..566cb59431
--- /dev/null
+++ b/src/library/scala/deprecatedOverriding.scala
@@ -0,0 +1,21 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2012, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala
+
+/** An annotation that designates that overriding a member is deprecated.
+ *
+ * Overriding such a member in a sub-class then generates a warning.
+ *
+ * @param message the message to print during compilation if the member was overridden
+ * @param since a string identifying the first version in which overriding was deprecated
+ * @since 2.10
+ * @see [[scala.deprecatedInheritance]]
+ */
+private[scala] // for the same reasons as deprecatedInheritance
+class deprecatedOverriding(message: String = "", since: String = "") extends annotation.StaticAnnotation
diff --git a/src/library/scala/math/BigDecimal.scala b/src/library/scala/math/BigDecimal.scala
index 8669b2e2e8..a475d663f4 100644
--- a/src/library/scala/math/BigDecimal.scala
+++ b/src/library/scala/math/BigDecimal.scala
@@ -159,6 +159,7 @@ object BigDecimal {
* @author Stephane Micheloud
* @version 1.0
*/
+@deprecatedInheritance("This class will me made final.", "2.10.0")
class BigDecimal(
val bigDecimal: BigDec,
val mc: MathContext)
diff --git a/src/library/scala/math/BigInt.scala b/src/library/scala/math/BigInt.scala
index 09e8ae2026..e354117e14 100644
--- a/src/library/scala/math/BigInt.scala
+++ b/src/library/scala/math/BigInt.scala
@@ -114,6 +114,7 @@ object BigInt {
* @author Martin Odersky
* @version 1.0, 15/07/2003
*/
+@deprecatedInheritance("This class will me made final.", "2.10.0")
class BigInt(val bigInteger: BigInteger) extends ScalaNumber with ScalaNumericConversions with Serializable {
/** Returns the hash code for this BigInt. */
override def hashCode(): Int =
diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala
index 5255c44f10..e42c89d21f 100644
--- a/src/library/scala/reflect/ClassTag.scala
+++ b/src/library/scala/reflect/ClassTag.scala
@@ -2,7 +2,7 @@ package scala.reflect
import java.lang.{ Class => jClass }
import language.{implicitConversions, existentials}
-import scala.runtime.ScalaRunTime.arrayClass
+import scala.runtime.ScalaRunTime.{ arrayClass, arrayElementClass }
/** A `ClassTag[T]` wraps a runtime class, which can be accessed via the `runtimeClass` method.
*
@@ -54,35 +54,59 @@ trait ClassTag[T] extends ClassManifestDeprecatedApis[T] with Equals with Serial
* `SomeExtractor(...)` is turned into `ct(SomeExtractor(...))` if `T` in `SomeExtractor.unapply(x: T)`
* is uncheckable, but we have an instance of `ClassTag[T]`.
*/
- def unapply(x: Any): Option[T] = if (x != null && runtimeClass.isAssignableFrom(x.getClass)) Some(x.asInstanceOf[T]) else None
+ def unapply(x: Any): Option[T] = unapply_impl(x)
+ def unapply(x: Byte): Option[T] = unapply_impl(x)
+ def unapply(x: Short): Option[T] = unapply_impl(x)
+ def unapply(x: Char): Option[T] = unapply_impl(x)
+ def unapply(x: Int): Option[T] = unapply_impl(x)
+ def unapply(x: Long): Option[T] = unapply_impl(x)
+ def unapply(x: Float): Option[T] = unapply_impl(x)
+ def unapply(x: Double): Option[T] = unapply_impl(x)
+ def unapply(x: Boolean): Option[T] = unapply_impl(x)
+ def unapply(x: Unit): Option[T] = unapply_impl(x)
+
+ private def unapply_impl[U: ClassTag](x: U): Option[T] =
+ if (x == null) None
+ else {
+ val staticClass = classTag[U].runtimeClass
+ val dynamicClass = x.getClass
+ val effectiveClass = if (staticClass.isPrimitive) staticClass else dynamicClass
+ val conforms = runtimeClass.isAssignableFrom(effectiveClass)
+ if (conforms) Some(x.asInstanceOf[T]) else None
+ }
/** case class accessories */
override def canEqual(x: Any) = x.isInstanceOf[ClassTag[_]]
override def equals(x: Any) = x.isInstanceOf[ClassTag[_]] && this.runtimeClass == x.asInstanceOf[ClassTag[_]].runtimeClass
override def hashCode = scala.runtime.ScalaRunTime.hash(runtimeClass)
- override def toString = "ClassTag[" + runtimeClass + "]"
+ override def toString = {
+ def prettyprint(clazz: jClass[_]): String =
+ if (clazz.isArray) s"Array[${prettyprint(arrayElementClass(clazz))}]" else
+ clazz.getName
+ prettyprint(runtimeClass)
+ }
}
object ClassTag {
+ private val ObjectTYPE = classOf[java.lang.Object]
private val NothingTYPE = classOf[scala.runtime.Nothing$]
private val NullTYPE = classOf[scala.runtime.Null$]
- private val ObjectTYPE = classOf[java.lang.Object]
- val Byte : ClassTag[scala.Byte] = new ClassTag[scala.Byte]{ def runtimeClass = java.lang.Byte.TYPE; private def readResolve() = ClassTag.Byte }
- val Short : ClassTag[scala.Short] = new ClassTag[scala.Short]{ def runtimeClass = java.lang.Short.TYPE; private def readResolve() = ClassTag.Short }
- val Char : ClassTag[scala.Char] = new ClassTag[scala.Char]{ def runtimeClass = java.lang.Character.TYPE; private def readResolve() = ClassTag.Char }
- val Int : ClassTag[scala.Int] = new ClassTag[scala.Int]{ def runtimeClass = java.lang.Integer.TYPE; private def readResolve() = ClassTag.Int }
- val Long : ClassTag[scala.Long] = new ClassTag[scala.Long]{ def runtimeClass = java.lang.Long.TYPE; private def readResolve() = ClassTag.Long }
- val Float : ClassTag[scala.Float] = new ClassTag[scala.Float]{ def runtimeClass = java.lang.Float.TYPE; private def readResolve() = ClassTag.Float }
- val Double : ClassTag[scala.Double] = new ClassTag[scala.Double]{ def runtimeClass = java.lang.Double.TYPE; private def readResolve() = ClassTag.Double }
- val Boolean : ClassTag[scala.Boolean] = new ClassTag[scala.Boolean]{ def runtimeClass = java.lang.Boolean.TYPE; private def readResolve() = ClassTag.Boolean }
- val Unit : ClassTag[scala.Unit] = new ClassTag[scala.Unit]{ def runtimeClass = java.lang.Void.TYPE; private def readResolve() = ClassTag.Unit }
- val Any : ClassTag[scala.Any] = new ClassTag[scala.Any]{ def runtimeClass = ObjectTYPE; private def readResolve() = ClassTag.Any }
- val Object : ClassTag[java.lang.Object] = new ClassTag[java.lang.Object]{ def runtimeClass = ObjectTYPE; private def readResolve() = ClassTag.Object }
- val AnyVal : ClassTag[scala.AnyVal] = ClassTag.Object.asInstanceOf[ClassTag[scala.AnyVal]]
- val AnyRef : ClassTag[scala.AnyRef] = ClassTag.Object.asInstanceOf[ClassTag[scala.AnyRef]]
- val Nothing : ClassTag[scala.Nothing] = new ClassTag[scala.Nothing]{ def runtimeClass = NothingTYPE; private def readResolve() = ClassTag.Nothing }
- val Null : ClassTag[scala.Null] = new ClassTag[scala.Null]{ def runtimeClass = NullTYPE; private def readResolve() = ClassTag.Null }
+ val Byte : ClassTag[scala.Byte] = Manifest.Byte
+ val Short : ClassTag[scala.Short] = Manifest.Short
+ val Char : ClassTag[scala.Char] = Manifest.Char
+ val Int : ClassTag[scala.Int] = Manifest.Int
+ val Long : ClassTag[scala.Long] = Manifest.Long
+ val Float : ClassTag[scala.Float] = Manifest.Float
+ val Double : ClassTag[scala.Double] = Manifest.Double
+ val Boolean : ClassTag[scala.Boolean] = Manifest.Boolean
+ val Unit : ClassTag[scala.Unit] = Manifest.Unit
+ val Any : ClassTag[scala.Any] = Manifest.Any
+ val Object : ClassTag[java.lang.Object] = Manifest.Object
+ val AnyVal : ClassTag[scala.AnyVal] = Manifest.AnyVal
+ val AnyRef : ClassTag[scala.AnyRef] = Manifest.AnyRef
+ val Nothing : ClassTag[scala.Nothing] = Manifest.Nothing
+ val Null : ClassTag[scala.Null] = Manifest.Null
def apply[T](runtimeClass1: jClass[_]): ClassTag[T] =
runtimeClass1 match {
@@ -96,6 +120,8 @@ object ClassTag {
case java.lang.Boolean.TYPE => ClassTag.Boolean.asInstanceOf[ClassTag[T]]
case java.lang.Void.TYPE => ClassTag.Unit.asInstanceOf[ClassTag[T]]
case ObjectTYPE => ClassTag.Object.asInstanceOf[ClassTag[T]]
+ case NothingTYPE => ClassTag.Nothing.asInstanceOf[ClassTag[T]]
+ case NullTYPE => ClassTag.Null.asInstanceOf[ClassTag[T]]
case _ => new ClassTag[T]{ def runtimeClass = runtimeClass1 }
}
diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala
index 9347f5b6bb..f2a23f4372 100644
--- a/src/library/scala/reflect/Manifest.scala
+++ b/src/library/scala/reflect/Manifest.scala
@@ -155,28 +155,34 @@ object ManifestFactory {
private def readResolve(): Any = Manifest.Unit
}
- val Any: Manifest[scala.Any] = new PhantomManifest[scala.Any]("Any") {
+ private val ObjectTYPE = classOf[java.lang.Object]
+ private val NothingTYPE = classOf[scala.runtime.Nothing$]
+ private val NullTYPE = classOf[scala.runtime.Null$]
+
+ val Any: Manifest[scala.Any] = new PhantomManifest[scala.Any](ObjectTYPE, "Any") {
override def <:<(that: ClassManifest[_]): Boolean = (that eq this)
private def readResolve(): Any = Manifest.Any
}
- val Object: Manifest[java.lang.Object] = new PhantomManifest[java.lang.Object]("Object") {
+ val Object: Manifest[java.lang.Object] = new PhantomManifest[java.lang.Object](ObjectTYPE, "Object") {
override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any)
private def readResolve(): Any = Manifest.Object
}
- val AnyVal: Manifest[scala.AnyVal] = new PhantomManifest[scala.AnyVal]("AnyVal") {
+ val AnyRef: Manifest[scala.AnyRef] = Object.asInstanceOf[Manifest[scala.AnyRef]]
+
+ val AnyVal: Manifest[scala.AnyVal] = new PhantomManifest[scala.AnyVal](ObjectTYPE, "AnyVal") {
override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any)
private def readResolve(): Any = Manifest.AnyVal
}
- val Null: Manifest[scala.Null] = new PhantomManifest[scala.Null]("Null") {
+ val Null: Manifest[scala.Null] = new PhantomManifest[scala.Null](NullTYPE, "Null") {
override def <:<(that: ClassManifest[_]): Boolean =
(that ne null) && (that ne Nothing) && !(that <:< AnyVal)
private def readResolve(): Any = Manifest.Null
}
- val Nothing: Manifest[scala.Nothing] = new PhantomManifest[scala.Nothing]("Nothing") {
+ val Nothing: Manifest[scala.Nothing] = new PhantomManifest[scala.Nothing](NothingTYPE, "Nothing") {
override def <:<(that: ClassManifest[_]): Boolean = (that ne null)
private def readResolve(): Any = Manifest.Nothing
}
@@ -211,7 +217,8 @@ object ManifestFactory {
def classType[T](prefix: Manifest[_], clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] =
new ClassTypeManifest[T](Some(prefix), clazz, args.toList)
- private abstract class PhantomManifest[T](override val toString: String) extends ClassTypeManifest[T](None, classOf[java.lang.Object], Nil) {
+ private abstract class PhantomManifest[T](_runtimeClass: Predef.Class[_],
+ override val toString: String) extends ClassTypeManifest[T](None, _runtimeClass, Nil) {
override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
override val hashCode = System.identityHashCode(this)
}
diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala
index e5f5e9dc5d..a8635151ff 100644
--- a/src/library/scala/runtime/ScalaRunTime.scala
+++ b/src/library/scala/runtime/ScalaRunTime.scala
@@ -167,35 +167,6 @@ object ScalaRunTime {
def checkInitialized[T <: AnyRef](x: T): T =
if (x == null) throw new UninitializedError else x
- abstract class Try[+A] {
- def Catch[B >: A](handler: PartialFunction[Throwable, B]): B
- def Finally(fin: => Unit): A
- }
-
- def Try[A](block: => A): Try[A] = new Try[A] with Runnable {
- private var result: A = _
- private var exception: Throwable =
- try { run() ; null }
- catch {
- case e: ControlThrowable => throw e // don't catch non-local returns etc
- case e: Throwable => e
- }
-
- def run() { result = block }
-
- def Catch[B >: A](handler: PartialFunction[Throwable, B]): B =
- if (exception == null) result
- else if (handler isDefinedAt exception) handler(exception)
- else throw exception
-
- def Finally(fin: => Unit): A = {
- fin
-
- if (exception == null) result
- else throw exception
- }
- }
-
def _toString(x: Product): String =
x.productIterator.mkString(x.productPrefix + "(", ",", ")")
diff --git a/src/library/scala/runtime/WorksheetSupport.scala b/src/library/scala/runtime/WorksheetSupport.scala
index 6f2a4d382d..a003bba034 100644
--- a/src/library/scala/runtime/WorksheetSupport.scala
+++ b/src/library/scala/runtime/WorksheetSupport.scala
@@ -40,9 +40,9 @@ object WorksheetSupport {
write((currentOffset+" ").getBytes)
}
out.write(c)
- col =
+ col =
if (c == '\n') -1
- else if (c == '\t') (col / tabInc) * tabInc + tabInc
+ else if (c == '\t') (col / tabInc) * tabInc + tabInc
else col + 1
if (col >= width) writeOne('\n')
}
@@ -86,7 +86,7 @@ object WorksheetSupport {
def $stop() = throw new StopException
- def $show(x: Any): String = stringOf(x, scala.Int.MaxValue)
+ def $show(x: Any): String = stringOf(x)
}
class StopException extends Exception
diff --git a/src/library/scala/util/Try.scala b/src/library/scala/util/Try.scala
index f381a18b0c..7afbfcdd66 100644
--- a/src/library/scala/util/Try.scala
+++ b/src/library/scala/util/Try.scala
@@ -52,6 +52,8 @@ import language.implicitConversions
* ''Note'': only non-fatal exceptions are caught by the combinators on `Try` (see [[scala.util.control.NonFatal]]).
* Serious system errors, on the other hand, will be thrown.
*
+ * ''Note:'': all Try combinators will catch exceptions and return failure unless otherwise specified in the documentation.
+ *
* `Try` comes to the Scala standard library after years of use as an integral part of Twitter's stack.
*
* @author based on Twitter's original implementation in com.twitter.util.
@@ -68,12 +70,19 @@ sealed abstract class Try[+T] {
def isSuccess: Boolean
/** Returns the value from this `Success` or the given `default` argument if this is a `Failure`.
+ *
+ * ''Note:'': This will throw an exception if it is not a success and default throws an exception.
*/
- def getOrElse[U >: T](default: => U) = if (isSuccess) get else default
+ def getOrElse[U >: T](default: => U): U =
+ if (isSuccess) get else default
/** Returns this `Try` if it's a `Success` or the given `default` argument if this is a `Failure`.
*/
- def orElse[U >: T](default: => Try[U]) = if (isSuccess) this else default
+ def orElse[U >: T](default: => Try[U]): Try[U] =
+ try if (isSuccess) this else default
+ catch {
+ case NonFatal(e) => Failure(e)
+ }
/** Returns the value from this `Success` or throws the exception if this is a `Failure`.
*/
@@ -81,6 +90,8 @@ sealed abstract class Try[+T] {
/**
* Applies the given function `f` if this is a `Success`, otherwise returns `Unit` if this is a `Failure`.
+ *
+ * ''Note:'' If `f` throws, then this method may throw an exception.
*/
def foreach[U](f: T => U): Unit
@@ -114,7 +125,7 @@ sealed abstract class Try[+T] {
/**
* Returns `None` if this is a `Failure` or a `Some` containing the value if this is a `Success`.
*/
- def toOption = if (isSuccess) Some(get) else None
+ def toOption: Option[T] = if (isSuccess) Some(get) else None
/**
* Transforms a nested `Try`, ie, a `Try` of type `Try[Try[T]]`,
@@ -131,20 +142,25 @@ sealed abstract class Try[+T] {
/** Completes this `Try` by applying the function `f` to this if this is of type `Failure`, or conversely, by applying
* `s` if this is a `Success`.
*/
- def transform[U](s: T => Try[U], f: Throwable => Try[U]): Try[U] = this match {
- case Success(v) => s(v)
- case Failure(e) => f(e)
- }
+ def transform[U](s: T => Try[U], f: Throwable => Try[U]): Try[U] =
+ try this match {
+ case Success(v) => s(v)
+ case Failure(e) => f(e)
+ } catch {
+ case NonFatal(e) => Failure(e)
+ }
}
object Try {
-
- def apply[T](r: => T): Try[T] = {
- try { Success(r) } catch {
+ /** Constructs a `Try` using the by-name parameter. This
+ * method will ensure any non-fatal exception is caught and a
+ * `Failure` object is returned.
+ */
+ def apply[T](r: => T): Try[T] =
+ try Success(r) catch {
case NonFatal(e) => Failure(e)
}
- }
}
@@ -152,24 +168,25 @@ final case class Failure[+T](val exception: Throwable) extends Try[T] {
def isFailure: Boolean = true
def isSuccess: Boolean = false
def recoverWith[U >: T](f: PartialFunction[Throwable, Try[U]]): Try[U] =
- if (f.isDefinedAt(exception)) f(exception) else this
+ try {
+ if (f isDefinedAt exception) f(exception) else this
+ } catch {
+ case NonFatal(e) => Failure(e)
+ }
def get: T = throw exception
- def flatMap[U](f: T => Try[U]): Try[U] = Failure[U](exception)
- def flatten[U](implicit ev: T <:< Try[U]): Try[U] = Failure[U](exception)
- def foreach[U](f: T => U): Unit = {}
- def map[U](f: T => U): Try[U] = Failure[U](exception)
+ def flatMap[U](f: T => Try[U]): Try[U] = this.asInstanceOf[Try[U]]
+ def flatten[U](implicit ev: T <:< Try[U]): Try[U] = this.asInstanceOf[Try[U]]
+ def foreach[U](f: T => U): Unit = ()
+ def map[U](f: T => U): Try[U] = this.asInstanceOf[Try[U]]
def filter(p: T => Boolean): Try[T] = this
- def recover[U >: T](rescueException: PartialFunction[Throwable, U]): Try[U] = {
+ def recover[U >: T](rescueException: PartialFunction[Throwable, U]): Try[U] =
try {
- if (rescueException.isDefinedAt(exception)) {
+ if (rescueException isDefinedAt exception) {
Try(rescueException(exception))
- } else {
- this
- }
+ } else this
} catch {
case NonFatal(e) => Failure(e)
}
- }
def failed: Try[Throwable] = Success(exception)
}
@@ -177,7 +194,7 @@ final case class Failure[+T](val exception: Throwable) extends Try[T] {
final case class Success[+T](value: T) extends Try[T] {
def isFailure: Boolean = false
def isSuccess: Boolean = true
- def recoverWith[U >: T](f: PartialFunction[Throwable, Try[U]]): Try[U] = Success(value)
+ def recoverWith[U >: T](f: PartialFunction[Throwable, Try[U]]): Try[U] = this
def get = value
def flatMap[U](f: T => Try[U]): Try[U] =
try f(value)
diff --git a/src/partest/scala/tools/partest/nest/RunnerManager.scala b/src/partest/scala/tools/partest/nest/RunnerManager.scala
index 20d61d0831..376e0e9bdb 100644
--- a/src/partest/scala/tools/partest/nest/RunnerManager.scala
+++ b/src/partest/scala/tools/partest/nest/RunnerManager.scala
@@ -312,8 +312,8 @@ class RunnerManager(kind: String, val fileManager: FileManager, params: TestRunP
val testFiles = dir.listFiles.toList filter isJavaOrScala
def isInGroup(f: File, num: Int) = SFile(f).stripExtension endsWith ("_" + num)
- val groups = (0 to 9).toList map (num => testFiles filter (f => isInGroup(f, num)))
- val noGroupSuffix = testFiles filterNot (groups.flatten contains)
+ val groups = (0 to 9).toList map (num => (testFiles filter (f => isInGroup(f, num))).sorted)
+ val noGroupSuffix = (testFiles filterNot (groups.flatten contains)).sorted
noGroupSuffix :: groups filterNot (_.isEmpty)
}
diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala
index d167099979..1fbbc0c0a4 100644
--- a/src/reflect/scala/reflect/api/Symbols.scala
+++ b/src/reflect/scala/reflect/api/Symbols.scala
@@ -140,18 +140,6 @@ trait Symbols extends base.Symbols { self: Universe =>
*/
def isErroneous : Boolean
- /** Can this symbol be loaded by a reflective mirror?
- *
- * Scalac relies on `ScalaSignature' annotation to retain symbols across compilation runs.
- * Such annotations (also called "pickles") are applied on top-level classes and include information
- * about all symbols reachable from the annotee. However, local symbols (e.g. classes or definitions local to a block)
- * are typically unreachable and information about them gets lost.
- *
- * This method is useful for macro writers who wish to save certain ASTs to be used at runtime.
- * With `isLocatable' it's possible to check whether a tree can be retained as is, or it needs special treatment.
- */
- def isLocatable: Boolean
-
/** Is this symbol static (i.e. with no outer instance)?
* Q: When exactly is a sym marked as STATIC?
* A: If it's a member of a toplevel object, or of an object contained in a toplevel object, or any number of levels deep.
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index c21ebfe997..15b74058b7 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -277,6 +277,7 @@ trait Definitions extends api.StandardDefinitions {
anyval
}).asInstanceOf[ClassSymbol]
lazy val AnyValTpe = definitions.AnyValClass.toTypeConstructor
+ def AnyVal_getClass = getMemberMethod(AnyValClass, nme.getClass_)
// bottom types
lazy val RuntimeNothingClass = getClassByName(fulltpnme.RuntimeNothing)
@@ -940,6 +941,8 @@ trait Definitions extends api.StandardDefinitions {
lazy val CloneableAttr = requiredClass[scala.annotation.cloneable]
lazy val DeprecatedAttr = requiredClass[scala.deprecated]
lazy val DeprecatedNameAttr = requiredClass[scala.deprecatedName]
+ lazy val DeprecatedInheritanceAttr = requiredClass[scala.deprecatedInheritance]
+ lazy val DeprecatedOverridingAttr = requiredClass[scala.deprecatedOverriding]
lazy val NativeAttr = requiredClass[scala.native]
lazy val RemoteAttr = requiredClass[scala.remote]
lazy val ScalaInlineClass = requiredClass[scala.inline]
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 3548657c04..a1c774c545 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -697,6 +697,18 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def deprecationMessage = getAnnotation(DeprecatedAttr) flatMap (_ stringArg 0)
def deprecationVersion = getAnnotation(DeprecatedAttr) flatMap (_ stringArg 1)
def deprecatedParamName = getAnnotation(DeprecatedNameAttr) flatMap (_ symbolArg 0)
+ def hasDeprecatedInheritanceAnnotation
+ = hasAnnotation(DeprecatedInheritanceAttr)
+ def deprecatedInheritanceMessage
+ = getAnnotation(DeprecatedInheritanceAttr) flatMap (_ stringArg 0)
+ def deprecatedInheritanceVersion
+ = getAnnotation(DeprecatedInheritanceAttr) flatMap (_ stringArg 1)
+ def hasDeprecatedOverridingAnnotation
+ = hasAnnotation(DeprecatedOverridingAttr)
+ def deprecatedOverridingMessage
+ = getAnnotation(DeprecatedOverridingAttr) flatMap (_ stringArg 0)
+ def deprecatedOverridingVersion
+ = getAnnotation(DeprecatedOverridingAttr) flatMap (_ stringArg 1)
// !!! when annotation arguments are not literal strings, but any sort of
// assembly of strings, there is a fair chance they will turn up here not as
@@ -853,7 +865,16 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isInitialized: Boolean =
validTo != NoPeriod
- /** Determines whether this symbol can be loaded by subsequent reflective compilation */
+ /** Can this symbol be loaded by a reflective mirror?
+ *
+ * Scalac relies on `ScalaSignature' annotation to retain symbols across compilation runs.
+ * Such annotations (also called "pickles") are applied on top-level classes and include information
+ * about all symbols reachable from the annotee. However, local symbols (e.g. classes or definitions local to a block)
+ * are typically unreachable and information about them gets lost.
+ *
+ * This method is useful for macro writers who wish to save certain ASTs to be used at runtime.
+ * With `isLocatable' it's possible to check whether a tree can be retained as is, or it needs special treatment.
+ */
final def isLocatable: Boolean = {
if (this == NoSymbol) return false
if (isRoot || isRootPackage) return true
@@ -1790,26 +1811,16 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
} else owner.enclosingTopLevelClass
/** Is this symbol defined in the same scope and compilation unit as `that` symbol? */
- def isCoDefinedWith(that: Symbol) = {
- (this.rawInfo ne NoType) &&
- (this.effectiveOwner == that.effectiveOwner) && {
- !this.effectiveOwner.isPackageClass ||
- (this.sourceFile eq null) ||
- (that.sourceFile eq null) ||
- (this.sourceFile == that.sourceFile) || {
- // recognize companion object in separate file and fail, else compilation
- // appears to succeed but highly opaque errors come later: see bug #1286
- if (this.sourceFile.path != that.sourceFile.path) {
- // The cheaper check can be wrong: do the expensive normalization
- // before failing.
- if (this.sourceFile.canonicalPath != that.sourceFile.canonicalPath)
- throw InvalidCompanions(this, that)
- }
-
- false
- }
- }
- }
+ def isCoDefinedWith(that: Symbol) = (
+ (this.rawInfo ne NoType)
+ && (this.effectiveOwner == that.effectiveOwner)
+ && ( !this.effectiveOwner.isPackageClass
+ || (this.sourceFile eq null)
+ || (that.sourceFile eq null)
+ || (this.sourceFile.path == that.sourceFile.path) // Cheap possibly wrong check, then expensive normalization
+ || (this.sourceFile.canonicalPath == that.sourceFile.canonicalPath)
+ )
+ )
/** The internal representation of classes and objects:
*
@@ -3202,13 +3213,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
if (settings.debug.value) printStackTrace()
}
- case class InvalidCompanions(sym1: Symbol, sym2: Symbol) extends Throwable({
- "Companions '" + sym1 + "' and '" + sym2 + "' must be defined in same file:\n" +
- " Found in " + sym1.sourceFile.canonicalPath + " and " + sym2.sourceFile.canonicalPath
- }) {
- override def toString = getMessage
- }
-
/** A class for type histories */
private sealed case class TypeHistory(var validFrom: Period, info: Type, prev: TypeHistory) {
assert((prev eq null) || phaseId(validFrom) > phaseId(prev.validFrom), this)
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index c266e26895..df44cf234e 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -317,25 +317,6 @@ trait Types extends api.Types { self: SymbolTable =>
def substituteSymbols(from: List[Symbol], to: List[Symbol]): Type = substSym(from, to)
def substituteTypes(from: List[Symbol], to: List[Type]): Type = subst(from, to)
- def isConcrete = {
- def notConcreteSym(sym: Symbol) =
- sym.isAbstractType && !sym.isExistential
-
- def notConcreteTpe(tpe: Type): Boolean = tpe match {
- case ThisType(_) => false
- case SuperType(_, _) => false
- case SingleType(pre, sym) => notConcreteSym(sym)
- case ConstantType(_) => false
- case TypeRef(_, sym, args) => notConcreteSym(sym) || (args exists notConcreteTpe)
- case RefinedType(_, _) => false
- case ExistentialType(_, _) => false
- case AnnotatedType(_, tp, _) => notConcreteTpe(tp)
- case _ => true
- }
-
- !notConcreteTpe(this)
- }
-
// the only thingies that we want to splice are: 1) type parameters, 2) abstract type members
// the thingies that we don't want to splice are: 1) concrete types (obviously), 2) existential skolems
def isSpliceable = {
@@ -3473,9 +3454,9 @@ trait Types extends api.Types { self: SymbolTable =>
}
/** A temporary type representing the erasure of a user-defined value type.
- * Created during phase reasure, eliminated again in posterasure.
- * @param sym The value class symbol
- * @param underlying The underlying type before erasure
+ * Created during phase erasure, eliminated again in posterasure.
+ *
+ * @param original The underlying type before erasure
*/
abstract case class ErasedValueType(original: TypeRef) extends UniqueType {
override def safeToString = "ErasedValueType("+original+")"
diff --git a/test/files/jvm/duration-java.check b/test/files/jvm/duration-java.check
new file mode 100644
index 0000000000..7ae257dcc0
--- /dev/null
+++ b/test/files/jvm/duration-java.check
@@ -0,0 +1,362 @@
+ 0.0 nanoseconds => 0 days
+ 1.0 nanoseconds => 1 nanosecond
+ 7.0 nanoseconds => 7 nanoseconds
+ 10.0 nanoseconds => 10 nanoseconds
+ 12.0 nanoseconds => 12 nanoseconds
+ 24.0 nanoseconds => 24 nanoseconds
+ 30.0 nanoseconds => 30 nanoseconds
+ 49.0 nanoseconds => 49 nanoseconds
+ 60.0 nanoseconds => 60 nanoseconds
+ 70.0 nanoseconds => 70 nanoseconds
+ 84.0 nanoseconds => 84 nanoseconds
+ 100.0 nanoseconds => 100 nanoseconds
+ 120.0 nanoseconds => 120 nanoseconds
+ 144.0 nanoseconds => 144 nanoseconds
+ 168.0 nanoseconds => 168 nanoseconds
+ 210.0 nanoseconds => 210 nanoseconds
+ 240.0 nanoseconds => 240 nanoseconds
+ 288.0 nanoseconds => 288 nanoseconds
+ 300.0 nanoseconds => 300 nanoseconds
+ 360.0 nanoseconds => 360 nanoseconds
+ 420.0 nanoseconds => 420 nanoseconds
+ 576.0 nanoseconds => 576 nanoseconds
+ 600.0 nanoseconds => 600 nanoseconds
+ 700.0 nanoseconds => 700 nanoseconds
+ 720.0 nanoseconds => 720 nanoseconds
+ 900.0 nanoseconds => 900 nanoseconds
+ 1000.0 nanoseconds => 1 microsecond
+ 1200.0 nanoseconds => 1200 nanoseconds
+ 1440.0 nanoseconds => 1440 nanoseconds
+ 1800.0 nanoseconds => 1800 nanoseconds
+ 2400.0 nanoseconds => 2400 nanoseconds
+ 3000.0 nanoseconds => 3 microseconds
+ 3600.0 nanoseconds => 3600 nanoseconds
+ 6000.0 nanoseconds => 6 microseconds
+ 7000.0 nanoseconds => 7 microseconds
+ 10000.0 nanoseconds => 10 microseconds
+ 12000.0 nanoseconds => 12 microseconds
+ 24000.0 nanoseconds => 24 microseconds
+ 30000.0 nanoseconds => 30 microseconds
+ 60000.0 nanoseconds => 60 microseconds
+ 100000.0 nanoseconds => 100 microseconds
+ 1000000.0 nanoseconds => 1 millisecond
+ 7000000.0 nanoseconds => 7 milliseconds
+ 1.0E7 nanoseconds => 10 milliseconds
+ 1.2E7 nanoseconds => 12 milliseconds
+ 2.4E7 nanoseconds => 24 milliseconds
+ 3.0E7 nanoseconds => 30 milliseconds
+ 6.0E7 nanoseconds => 60 milliseconds
+ 1.0E8 nanoseconds => 100 milliseconds
+ 1.0E9 nanoseconds => 1 second
+ 1.0E12 nanoseconds => 1000 seconds
+ 0.0 microseconds => 0 days
+ 1.0 microseconds => 1 microsecond
+ 7.0 microseconds => 7 microseconds
+ 10.0 microseconds => 10 microseconds
+ 12.0 microseconds => 12 microseconds
+ 24.0 microseconds => 24 microseconds
+ 30.0 microseconds => 30 microseconds
+ 49.0 microseconds => 49 microseconds
+ 60.0 microseconds => 60 microseconds
+ 70.0 microseconds => 70 microseconds
+ 84.0 microseconds => 84 microseconds
+ 100.0 microseconds => 100 microseconds
+ 120.0 microseconds => 120 microseconds
+ 144.0 microseconds => 144 microseconds
+ 168.0 microseconds => 168 microseconds
+ 210.0 microseconds => 210 microseconds
+ 240.0 microseconds => 240 microseconds
+ 288.0 microseconds => 288 microseconds
+ 300.0 microseconds => 300 microseconds
+ 360.0 microseconds => 360 microseconds
+ 420.0 microseconds => 420 microseconds
+ 576.0 microseconds => 576 microseconds
+ 600.0 microseconds => 600 microseconds
+ 700.0 microseconds => 700 microseconds
+ 720.0 microseconds => 720 microseconds
+ 900.0 microseconds => 900 microseconds
+ 1000.0 microseconds => 1 millisecond
+ 1200.0 microseconds => 1200 microseconds
+ 1440.0 microseconds => 1440 microseconds
+ 1800.0 microseconds => 1800 microseconds
+ 2400.0 microseconds => 2400 microseconds
+ 3000.0 microseconds => 3 milliseconds
+ 3600.0 microseconds => 3600 microseconds
+ 6000.0 microseconds => 6 milliseconds
+ 7000.0 microseconds => 7 milliseconds
+ 10000.0 microseconds => 10 milliseconds
+ 12000.0 microseconds => 12 milliseconds
+ 24000.0 microseconds => 24 milliseconds
+ 30000.0 microseconds => 30 milliseconds
+ 60000.0 microseconds => 60 milliseconds
+ 100000.0 microseconds => 100 milliseconds
+ 1000000.0 microseconds => 1 second
+ 7000000.0 microseconds => 7 seconds
+ 1.0E7 microseconds => 10 seconds
+ 1.2E7 microseconds => 12 seconds
+ 2.4E7 microseconds => 24 seconds
+ 3.0E7 microseconds => 30 seconds
+ 6.0E7 microseconds => 1 minute
+ 1.0E8 microseconds => 100 seconds
+ 1.0E9 microseconds => 1000 seconds
+ 1.0E12 microseconds => 1000000 seconds
+ 0.0 milliseconds => 0 days
+ 1.0 milliseconds => 1 millisecond
+ 7.0 milliseconds => 7 milliseconds
+ 10.0 milliseconds => 10 milliseconds
+ 12.0 milliseconds => 12 milliseconds
+ 24.0 milliseconds => 24 milliseconds
+ 30.0 milliseconds => 30 milliseconds
+ 49.0 milliseconds => 49 milliseconds
+ 60.0 milliseconds => 60 milliseconds
+ 70.0 milliseconds => 70 milliseconds
+ 84.0 milliseconds => 84 milliseconds
+ 100.0 milliseconds => 100 milliseconds
+ 120.0 milliseconds => 120 milliseconds
+ 144.0 milliseconds => 144 milliseconds
+ 168.0 milliseconds => 168 milliseconds
+ 210.0 milliseconds => 210 milliseconds
+ 240.0 milliseconds => 240 milliseconds
+ 288.0 milliseconds => 288 milliseconds
+ 300.0 milliseconds => 300 milliseconds
+ 360.0 milliseconds => 360 milliseconds
+ 420.0 milliseconds => 420 milliseconds
+ 576.0 milliseconds => 576 milliseconds
+ 600.0 milliseconds => 600 milliseconds
+ 700.0 milliseconds => 700 milliseconds
+ 720.0 milliseconds => 720 milliseconds
+ 900.0 milliseconds => 900 milliseconds
+ 1000.0 milliseconds => 1 second
+ 1200.0 milliseconds => 1200 milliseconds
+ 1440.0 milliseconds => 1440 milliseconds
+ 1800.0 milliseconds => 1800 milliseconds
+ 2400.0 milliseconds => 2400 milliseconds
+ 3000.0 milliseconds => 3 seconds
+ 3600.0 milliseconds => 3600 milliseconds
+ 6000.0 milliseconds => 6 seconds
+ 7000.0 milliseconds => 7 seconds
+ 10000.0 milliseconds => 10 seconds
+ 12000.0 milliseconds => 12 seconds
+ 24000.0 milliseconds => 24 seconds
+ 30000.0 milliseconds => 30 seconds
+ 60000.0 milliseconds => 1 minute
+ 100000.0 milliseconds => 100 seconds
+ 1000000.0 milliseconds => 1000 seconds
+ 7000000.0 milliseconds => 7000 seconds
+ 1.0E7 milliseconds => 10000 seconds
+ 1.2E7 milliseconds => 200 minutes
+ 2.4E7 milliseconds => 400 minutes
+ 3.0E7 milliseconds => 500 minutes
+ 6.0E7 milliseconds => 1000 minutes
+ 1.0E8 milliseconds => 100000 seconds
+ 1.0E9 milliseconds => 1000000 seconds
+ 1.0E12 milliseconds => 1000000000 seconds
+ 0.0 seconds => 0 days
+ 1.0 seconds => 1 second
+ 7.0 seconds => 7 seconds
+ 10.0 seconds => 10 seconds
+ 12.0 seconds => 12 seconds
+ 24.0 seconds => 24 seconds
+ 30.0 seconds => 30 seconds
+ 49.0 seconds => 49 seconds
+ 60.0 seconds => 1 minute
+ 70.0 seconds => 70 seconds
+ 84.0 seconds => 84 seconds
+ 100.0 seconds => 100 seconds
+ 120.0 seconds => 2 minutes
+ 144.0 seconds => 144 seconds
+ 168.0 seconds => 168 seconds
+ 210.0 seconds => 210 seconds
+ 240.0 seconds => 4 minutes
+ 288.0 seconds => 288 seconds
+ 300.0 seconds => 5 minutes
+ 360.0 seconds => 6 minutes
+ 420.0 seconds => 7 minutes
+ 576.0 seconds => 576 seconds
+ 600.0 seconds => 10 minutes
+ 700.0 seconds => 700 seconds
+ 720.0 seconds => 12 minutes
+ 900.0 seconds => 15 minutes
+ 1000.0 seconds => 1000 seconds
+ 1200.0 seconds => 20 minutes
+ 1440.0 seconds => 24 minutes
+ 1800.0 seconds => 30 minutes
+ 2400.0 seconds => 40 minutes
+ 3000.0 seconds => 50 minutes
+ 3600.0 seconds => 1 hour
+ 6000.0 seconds => 100 minutes
+ 7000.0 seconds => 7000 seconds
+ 10000.0 seconds => 10000 seconds
+ 12000.0 seconds => 200 minutes
+ 24000.0 seconds => 400 minutes
+ 30000.0 seconds => 500 minutes
+ 60000.0 seconds => 1000 minutes
+ 100000.0 seconds => 100000 seconds
+ 1000000.0 seconds => 1000000 seconds
+ 7000000.0 seconds => 7000000 seconds
+ 1.0E7 seconds => 10000000 seconds
+ 1.2E7 seconds => 200000 minutes
+ 2.4E7 seconds => 400000 minutes
+ 3.0E7 seconds => 500000 minutes
+ 6.0E7 seconds => 1000000 minutes
+ 1.0E8 seconds => 100000000 seconds
+ 1.0E9 seconds => 1000000000 seconds
+ 1.0E12 seconds => 9223372036854775807 nanoseconds
+ 0.0 minutes => 0 days
+ 1.0 minutes => 1 minute
+ 7.0 minutes => 7 minutes
+ 10.0 minutes => 10 minutes
+ 12.0 minutes => 12 minutes
+ 24.0 minutes => 24 minutes
+ 30.0 minutes => 30 minutes
+ 49.0 minutes => 49 minutes
+ 60.0 minutes => 1 hour
+ 70.0 minutes => 70 minutes
+ 84.0 minutes => 84 minutes
+ 100.0 minutes => 100 minutes
+ 120.0 minutes => 2 hours
+ 144.0 minutes => 144 minutes
+ 168.0 minutes => 168 minutes
+ 210.0 minutes => 210 minutes
+ 240.0 minutes => 4 hours
+ 288.0 minutes => 288 minutes
+ 300.0 minutes => 5 hours
+ 360.0 minutes => 6 hours
+ 420.0 minutes => 7 hours
+ 576.0 minutes => 576 minutes
+ 600.0 minutes => 10 hours
+ 700.0 minutes => 700 minutes
+ 720.0 minutes => 12 hours
+ 900.0 minutes => 15 hours
+ 1000.0 minutes => 1000 minutes
+ 1200.0 minutes => 20 hours
+ 1440.0 minutes => 1 day
+ 1800.0 minutes => 30 hours
+ 2400.0 minutes => 40 hours
+ 3000.0 minutes => 50 hours
+ 3600.0 minutes => 60 hours
+ 6000.0 minutes => 100 hours
+ 7000.0 minutes => 7000 minutes
+ 10000.0 minutes => 10000 minutes
+ 12000.0 minutes => 200 hours
+ 24000.0 minutes => 400 hours
+ 30000.0 minutes => 500 hours
+ 60000.0 minutes => 1000 hours
+ 100000.0 minutes => 100000 minutes
+ 1000000.0 minutes => 1000000 minutes
+ 7000000.0 minutes => 7000000 minutes
+ 1.0E7 minutes => 10000000 minutes
+ 1.2E7 minutes => 200000 hours
+ 2.4E7 minutes => 400000 hours
+ 3.0E7 minutes => 500000 hours
+ 6.0E7 minutes => 1000000 hours
+ 1.0E8 minutes => 100000000 minutes
+ 1.0E9 minutes => 9223372036854775807 nanoseconds
+ 1.0E12 minutes => 9223372036854775807 nanoseconds
+ 0.0 hours => 0 days
+ 1.0 hours => 1 hour
+ 7.0 hours => 7 hours
+ 10.0 hours => 10 hours
+ 12.0 hours => 12 hours
+ 24.0 hours => 1 day
+ 30.0 hours => 30 hours
+ 49.0 hours => 49 hours
+ 60.0 hours => 60 hours
+ 70.0 hours => 70 hours
+ 84.0 hours => 84 hours
+ 100.0 hours => 100 hours
+ 120.0 hours => 5 days
+ 144.0 hours => 6 days
+ 168.0 hours => 7 days
+ 210.0 hours => 210 hours
+ 240.0 hours => 10 days
+ 288.0 hours => 12 days
+ 300.0 hours => 300 hours
+ 360.0 hours => 15 days
+ 420.0 hours => 420 hours
+ 576.0 hours => 24 days
+ 600.0 hours => 25 days
+ 700.0 hours => 700 hours
+ 720.0 hours => 30 days
+ 900.0 hours => 900 hours
+ 1000.0 hours => 1000 hours
+ 1200.0 hours => 50 days
+ 1440.0 hours => 60 days
+ 1800.0 hours => 75 days
+ 2400.0 hours => 100 days
+ 3000.0 hours => 125 days
+ 3600.0 hours => 150 days
+ 6000.0 hours => 250 days
+ 7000.0 hours => 7000 hours
+ 10000.0 hours => 10000 hours
+ 12000.0 hours => 500 days
+ 24000.0 hours => 1000 days
+ 30000.0 hours => 1250 days
+ 60000.0 hours => 2500 days
+ 100000.0 hours => 100000 hours
+ 1000000.0 hours => 1000000 hours
+ 7000000.0 hours => 9223372036854775807 nanoseconds
+ 1.0E7 hours => 9223372036854775807 nanoseconds
+ 1.2E7 hours => 9223372036854775807 nanoseconds
+ 2.4E7 hours => 9223372036854775807 nanoseconds
+ 3.0E7 hours => 9223372036854775807 nanoseconds
+ 6.0E7 hours => 9223372036854775807 nanoseconds
+ 1.0E8 hours => 9223372036854775807 nanoseconds
+ 1.0E9 hours => 9223372036854775807 nanoseconds
+ 1.0E12 hours => 9223372036854775807 nanoseconds
+ 0.0 days => 0 days
+ 1.0 days => 1 day
+ 7.0 days => 7 days
+ 10.0 days => 10 days
+ 12.0 days => 12 days
+ 24.0 days => 24 days
+ 30.0 days => 30 days
+ 49.0 days => 49 days
+ 60.0 days => 60 days
+ 70.0 days => 70 days
+ 84.0 days => 84 days
+ 100.0 days => 100 days
+ 120.0 days => 120 days
+ 144.0 days => 144 days
+ 168.0 days => 168 days
+ 210.0 days => 210 days
+ 240.0 days => 240 days
+ 288.0 days => 288 days
+ 300.0 days => 300 days
+ 360.0 days => 360 days
+ 420.0 days => 420 days
+ 576.0 days => 576 days
+ 600.0 days => 600 days
+ 700.0 days => 700 days
+ 720.0 days => 720 days
+ 900.0 days => 900 days
+ 1000.0 days => 1000 days
+ 1200.0 days => 1200 days
+ 1440.0 days => 1440 days
+ 1800.0 days => 1800 days
+ 2400.0 days => 2400 days
+ 3000.0 days => 3000 days
+ 3600.0 days => 3600 days
+ 6000.0 days => 6000 days
+ 7000.0 days => 7000 days
+ 10000.0 days => 10000 days
+ 12000.0 days => 12000 days
+ 24000.0 days => 24000 days
+ 30000.0 days => 30000 days
+ 60000.0 days => 60000 days
+ 100000.0 days => 100000 days
+ 1000000.0 days => 9223372036854775807 nanoseconds
+ 7000000.0 days => 9223372036854775807 nanoseconds
+ 1.0E7 days => 9223372036854775807 nanoseconds
+ 1.2E7 days => 9223372036854775807 nanoseconds
+ 2.4E7 days => 9223372036854775807 nanoseconds
+ 3.0E7 days => 9223372036854775807 nanoseconds
+ 6.0E7 days => 9223372036854775807 nanoseconds
+ 1.0E8 days => 9223372036854775807 nanoseconds
+ 1.0E9 days => 9223372036854775807 nanoseconds
+ 1.0E12 days => 9223372036854775807 nanoseconds
+ Inf => Duration.Inf
+ -Inf => Duration.MinusInf
+ +Inf => Duration.Inf
+ PlusInf => Duration.Inf
+ MinusInf => Duration.MinusInf
diff --git a/test/files/jvm/duration-java/Test.java b/test/files/jvm/duration-java/Test.java
new file mode 100644
index 0000000000..02feb522b8
--- /dev/null
+++ b/test/files/jvm/duration-java/Test.java
@@ -0,0 +1,38 @@
+import scala.concurrent.util.Duration;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import static java.util.concurrent.TimeUnit.*;
+
+public class Test {
+ public static List<Double> inputs = Arrays.asList(0d, 1d, 7d, 10d, 12d, 24d, 30d, 60d, 100d, 1000d, 1e6);
+ public static List<Double> makeNumbers() {
+ ArrayList<Double> xs = new ArrayList<Double>();
+ for (Double n1: inputs) {
+ for (Double n2: inputs) {
+ Double n = n1 * n2;
+ if (!xs.contains(n))
+ xs.add(n);
+ }
+ }
+ Double[] arr = xs.toArray(new Double[0]);
+ Arrays.sort(arr);
+ return Arrays.asList(arr);
+ }
+
+ public static void p(Object x) {
+ System.out.println(x);
+ }
+ public static void main(String[] args) {
+ for (TimeUnit t : TimeUnit.values()) {
+ for (Double n: makeNumbers()) {
+ String s = "" + n + " " + t.toString().toLowerCase();
+ Duration d = Duration.create(n, t);
+ p(String.format("%25s => %s", s, d));
+ }
+ }
+ for (String s: Arrays.asList("Inf", "-Inf", "+Inf", "PlusInf", "MinusInf")) {
+ Duration d = Duration.create(s);
+ p(String.format("%25s => %s", s, d));
+ }
+ }
+}
diff --git a/test/files/neg/override.check b/test/files/neg/override.check
index fc152cb3b1..8be98bf4d0 100644
--- a/test/files/neg/override.check
+++ b/test/files/neg/override.check
@@ -1,5 +1,5 @@
override.scala:9: error: overriding type T in trait A with bounds >: Int <: Int;
type T in trait B with bounds >: String <: String has incompatible type
- lazy val x : A with B = x
+ lazy val x : A with B = {println(""); x}
^
one error found
diff --git a/test/files/neg/override.scala b/test/files/neg/override.scala
index 3e589b52e3..7975516061 100755
--- a/test/files/neg/override.scala
+++ b/test/files/neg/override.scala
@@ -6,7 +6,7 @@ trait X {
trait Y extends X {
trait B { type T >: String <: String }
- lazy val x : A with B = x
+ lazy val x : A with B = {println(""); x}
n = "foo"
}
diff --git a/test/files/neg/t5031.check b/test/files/neg/t5031.check
index 8983d8daf9..2f1090c321 100644
--- a/test/files/neg/t5031.check
+++ b/test/files/neg/t5031.check
@@ -1,5 +1,5 @@
-Id.scala:3: error: Companions 'class Test' and 'object Test' must be defined in same file:
+package.scala:2: error: Companions 'class Test' and 'object Test' must be defined in same file:
Found in t5031/package.scala and t5031/Id.scala
-object Test
- ^
+ class Test
+ ^
one error found
diff --git a/test/files/neg/t5031b.check b/test/files/neg/t5031b.check
new file mode 100644
index 0000000000..3bc2284a4d
--- /dev/null
+++ b/test/files/neg/t5031b.check
@@ -0,0 +1,5 @@
+b.scala:3: error: Companions 'class Bippy' and 'object Bippy' must be defined in same file:
+ Found in t5031b/a.scala and t5031b/b.scala
+object Bippy
+ ^
+one error found
diff --git a/test/files/neg/t5031b/a.scala b/test/files/neg/t5031b/a.scala
new file mode 100644
index 0000000000..0ab9aa9769
--- /dev/null
+++ b/test/files/neg/t5031b/a.scala
@@ -0,0 +1,3 @@
+package foo
+
+class Bippy
diff --git a/test/files/neg/t5031b/b.scala b/test/files/neg/t5031b/b.scala
new file mode 100644
index 0000000000..bdef237af5
--- /dev/null
+++ b/test/files/neg/t5031b/b.scala
@@ -0,0 +1,3 @@
+package foo
+
+object Bippy
diff --git a/test/files/neg/t6162-inheritance.check b/test/files/neg/t6162-inheritance.check
new file mode 100644
index 0000000000..a7d3cc3238
--- /dev/null
+++ b/test/files/neg/t6162-inheritance.check
@@ -0,0 +1,10 @@
+t6162-inheritance.scala:6: error: inheritance from class Foo in package t6126 is deprecated: `Foo` will be made final in a future version.
+class SubFoo extends Foo
+ ^
+t6162-inheritance.scala:11: error: inheritance from trait T in package t6126 is deprecated
+object SubT extends T
+ ^
+t6162-inheritance.scala:17: error: inheritance from trait S in package t6126 is deprecated
+ new S {
+ ^
+three errors found
diff --git a/test/files/neg/t6162-inheritance.flags b/test/files/neg/t6162-inheritance.flags
new file mode 100644
index 0000000000..65faf53579
--- /dev/null
+++ b/test/files/neg/t6162-inheritance.flags
@@ -0,0 +1 @@
+-Xfatal-warnings -deprecation \ No newline at end of file
diff --git a/test/files/neg/t6162-inheritance.scala b/test/files/neg/t6162-inheritance.scala
new file mode 100644
index 0000000000..7b47b9285a
--- /dev/null
+++ b/test/files/neg/t6162-inheritance.scala
@@ -0,0 +1,19 @@
+package scala.t6126
+
+@deprecatedInheritance("`Foo` will be made final in a future version.", "2.10.0")
+class Foo
+
+class SubFoo extends Foo
+
+@deprecatedInheritance()
+trait T
+
+object SubT extends T
+
+@deprecatedInheritance()
+trait S
+
+object O {
+ new S {
+ }
+}
diff --git a/test/files/neg/t6162-overriding.check b/test/files/neg/t6162-overriding.check
new file mode 100644
index 0000000000..e774888d36
--- /dev/null
+++ b/test/files/neg/t6162-overriding.check
@@ -0,0 +1,7 @@
+t6162-overriding.scala:14: error: overriding method bar in class Bar is deprecated: `bar` will be made private in a future version.
+ override def bar = 43
+ ^
+t6162-overriding.scala:15: error: overriding method baz in class Bar is deprecated
+ override def baz = 43
+ ^
+two errors found
diff --git a/test/files/neg/t6162-overriding.flags b/test/files/neg/t6162-overriding.flags
new file mode 100644
index 0000000000..65faf53579
--- /dev/null
+++ b/test/files/neg/t6162-overriding.flags
@@ -0,0 +1 @@
+-Xfatal-warnings -deprecation \ No newline at end of file
diff --git a/test/files/neg/t6162-overriding.scala b/test/files/neg/t6162-overriding.scala
new file mode 100644
index 0000000000..4cab0c2dee
--- /dev/null
+++ b/test/files/neg/t6162-overriding.scala
@@ -0,0 +1,17 @@
+package scala.t6162
+
+class Bar {
+ @deprecatedOverriding("`bar` will be made private in a future version.", "2.10.0")
+ def bar = 42
+
+ @deprecatedOverriding()
+ def baz = 42
+
+ def baz(a: Any) = 0
+}
+
+class SubBar extends Bar {
+ override def bar = 43
+ override def baz = 43
+ override def baz(a: Any) = 43 // okay
+}
diff --git a/test/files/neg/t6258.check b/test/files/neg/t6258.check
new file mode 100644
index 0000000000..73363d8280
--- /dev/null
+++ b/test/files/neg/t6258.check
@@ -0,0 +1,16 @@
+t6258.scala:2: error: missing parameter type for expanded function
+The argument types of an anonymous function must be fully known. (SLS 8.5)
+Expected type was: PartialFunction[?, Int]
+ val f : PartialFunction[_, Int] = { case a : Int => a } // undefined param
+ ^
+t6258.scala:5: error: missing parameter type for expanded function
+The argument types of an anonymous function must be fully known. (SLS 8.5)
+Expected type was: PartialFunction[?,Int]
+ foo { case a : Int => a } // undefined param
+ ^
+t6258.scala:22: error: missing parameter type for expanded function
+The argument types of an anonymous function must be fully known. (SLS 8.5)
+Expected type was: PartialFunction[?,Any]
+ bar[M[Any]] (foo { // undefined param
+ ^
+three errors found
diff --git a/test/files/neg/t6258.scala b/test/files/neg/t6258.scala
new file mode 100644
index 0000000000..5046a4750a
--- /dev/null
+++ b/test/files/neg/t6258.scala
@@ -0,0 +1,25 @@
+object Test {
+ val f : PartialFunction[_, Int] = { case a : Int => a } // undefined param
+
+ def foo[A](pf: PartialFunction[A, Int]) {};
+ foo { case a : Int => a } // undefined param
+
+ val g : PartialFunction[Int, _] = { case a : Int => a } // okay
+}
+
+
+// Another variation, seen in the wild with Specs2.
+class X {
+ trait Matcher[-T]
+
+ def bar[T](m: Matcher[T]) = null
+ def bar[T](i: Int) = null
+
+ def foo[T](p: PartialFunction[T, Any]): Matcher[T] = null
+
+ case class M[X](a: X)
+
+ bar[M[Any]] (foo { // undefined param
+ case M(_) => null
+ })
+}
diff --git a/test/files/neg/t6276.check b/test/files/neg/t6276.check
new file mode 100644
index 0000000000..8bd92cf293
--- /dev/null
+++ b/test/files/neg/t6276.check
@@ -0,0 +1,13 @@
+t6276.scala:4: error: method a does nothing other than call itself recursively
+ def a: Any = a // warn
+ ^
+t6276.scala:5: error: value b does nothing other than call itself recursively
+ val b: Any = b // warn
+ ^
+t6276.scala:10: error: method a does nothing other than call itself recursively
+ def a: Any = a // warn
+ ^
+t6276.scala:19: error: method a does nothing other than call itself recursively
+ def a = a // warn
+ ^
+four errors found
diff --git a/test/files/neg/t6276.flags b/test/files/neg/t6276.flags
new file mode 100644
index 0000000000..85d8eb2ba2
--- /dev/null
+++ b/test/files/neg/t6276.flags
@@ -0,0 +1 @@
+-Xfatal-warnings
diff --git a/test/files/neg/t6276.scala b/test/files/neg/t6276.scala
new file mode 100644
index 0000000000..8333618964
--- /dev/null
+++ b/test/files/neg/t6276.scala
@@ -0,0 +1,29 @@
+object Test {
+ def foo(a: Int, b: Int, c: Int) {
+ new {
+ def a: Any = a // warn
+ val b: Any = b // warn
+ }
+
+ def method {
+ // method local
+ def a: Any = a // warn
+ }
+
+ trait T {
+ def a: Any
+ }
+
+ new T {
+ // inherited return type
+ def a = a // warn
+ }
+
+ // no warnings below
+ new {
+ def a: Any = {println(""); a}
+ val b: Any = {println(""); b}
+ def c(i: Int): Any = c(i - 0)
+ }
+ }
+}
diff --git a/test/files/neg/t6335.check b/test/files/neg/t6335.check
new file mode 100644
index 0000000000..1727a05eb2
--- /dev/null
+++ b/test/files/neg/t6335.check
@@ -0,0 +1,9 @@
+t6335.scala:6: error: method Z is defined twice
+ conflicting symbols both originated in file 't6335.scala'
+ implicit class Z[A](val i: A) { def zz = i }
+ ^
+t6335.scala:3: error: method X is defined twice
+ conflicting symbols both originated in file 't6335.scala'
+ implicit class X(val x: Int) { def xx = x }
+ ^
+two errors found
diff --git a/test/files/neg/t6335.scala b/test/files/neg/t6335.scala
new file mode 100644
index 0000000000..5c41e81ef5
--- /dev/null
+++ b/test/files/neg/t6335.scala
@@ -0,0 +1,7 @@
+object ImplicitClass {
+ def X(i: Int) {}
+ implicit class X(val x: Int) { def xx = x }
+
+ def Z[A](i: A) {}
+ implicit class Z[A](val i: A) { def zz = i }
+} \ No newline at end of file
diff --git a/test/files/pos/t6274.scala b/test/files/pos/t6274.scala
new file mode 100644
index 0000000000..cf769fc72d
--- /dev/null
+++ b/test/files/pos/t6274.scala
@@ -0,0 +1,13 @@
+trait Crash {
+
+ def foo(i: => Int) (j: Int): Int
+
+ def t = {
+ // var count = 0
+ foo {
+ var count = 0
+ count
+ } _
+ }
+
+}
diff --git a/test/files/pos/t6278-synth-def.scala b/test/files/pos/t6278-synth-def.scala
new file mode 100644
index 0000000000..b8b660fbe3
--- /dev/null
+++ b/test/files/pos/t6278-synth-def.scala
@@ -0,0 +1,30 @@
+
+package t6278
+
+import language.implicitConversions
+
+object test {
+ def ok() {
+ class Foo(val i: Int) {
+ def foo[A](body: =>A): A = body
+ }
+ implicit def toFoo(i: Int): Foo = new Foo(i)
+
+ val k = 1
+ k foo println("k?")
+ val j = 2
+ }
+ def nope() {
+ implicit class Foo(val i: Int) {
+ def foo[A](body: =>A): A = body
+ }
+
+ val k = 1
+ k foo println("k?")
+ //lazy
+ val j = 2
+ }
+ def main(args: Array[String]) {
+ ok(); nope()
+ }
+}
diff --git a/test/files/pos/t6335.scala b/test/files/pos/t6335.scala
new file mode 100644
index 0000000000..50e34092d1
--- /dev/null
+++ b/test/files/pos/t6335.scala
@@ -0,0 +1,25 @@
+object E extends Z {
+ def X = 3
+ implicit class X(val i: Int) {
+ def xx = i
+ }
+
+ def Y(a: Any) = 0
+ object Y
+ implicit class Y(val i: String) { def yy = i }
+
+ implicit class Z(val i: Boolean) { def zz = i }
+}
+
+trait Z {
+ def Z = 0
+}
+
+object Test {
+ import E._
+ 0.xx
+
+ "".yy
+
+ true.zz
+}
diff --git a/test/files/presentation/recursive-ask.check b/test/files/presentation/recursive-ask.check
new file mode 100644
index 0000000000..357d2cf879
--- /dev/null
+++ b/test/files/presentation/recursive-ask.check
@@ -0,0 +1,4 @@
+[ outer] askForResponse
+[nested] askForResponse
+passed
+done
diff --git a/test/files/presentation/recursive-ask/RecursiveAsk.scala b/test/files/presentation/recursive-ask/RecursiveAsk.scala
new file mode 100644
index 0000000000..b0e29b3fd3
--- /dev/null
+++ b/test/files/presentation/recursive-ask/RecursiveAsk.scala
@@ -0,0 +1,20 @@
+import scala.tools.nsc.interactive.tests._
+
+object Test extends InteractiveTest {
+ override def execute(): Unit = recursiveAskForResponse()
+
+ def recursiveAskForResponse() {
+ val res0 = compiler.askForResponse( () => {
+ println("[ outer] askForResponse")
+ val res = compiler.askForResponse( () => { println("[nested] askForResponse") })
+ println (res.get(5000) match {
+ case Some(_) => "passed"
+ case None => "timeout"
+ })
+ })
+
+ res0.get
+
+ println("done")
+ }
+}
diff --git a/test/files/run/classtags_core.check b/test/files/run/classtags_core.check
index 6519db2178..5a9b41fd6d 100644
--- a/test/files/run/classtags_core.check
+++ b/test/files/run/classtags_core.check
@@ -1,30 +1,30 @@
true
-ClassTag[byte]
+Byte
true
-ClassTag[short]
+Short
true
-ClassTag[char]
+Char
true
-ClassTag[int]
+Int
true
-ClassTag[long]
+Long
true
-ClassTag[float]
+Float
true
-ClassTag[double]
+Double
true
-ClassTag[boolean]
+Boolean
true
-ClassTag[void]
+Unit
true
-ClassTag[class java.lang.Object]
+Any
true
-ClassTag[class java.lang.Object]
+AnyVal
true
-ClassTag[class java.lang.Object]
+Object
true
-ClassTag[class java.lang.Object]
+Object
true
-ClassTag[class scala.runtime.Null$]
+Null
true
-ClassTag[class scala.runtime.Nothing$]
+Nothing
diff --git a/test/files/run/classtags_multi.check b/test/files/run/classtags_multi.check
index 3a7f16c3a0..68cee4841d 100644
--- a/test/files/run/classtags_multi.check
+++ b/test/files/run/classtags_multi.check
@@ -1,5 +1,5 @@
-ClassTag[int]
-ClassTag[class [I]
-ClassTag[class [[I]
-ClassTag[class [[[I]
-ClassTag[class [[[[I]
+Int
+Array[int]
+Array[Array[int]]
+Array[Array[Array[int]]]
+Array[Array[Array[Array[int]]]]
diff --git a/test/files/run/getClassTest-valueClass.check b/test/files/run/getClassTest-valueClass.check
new file mode 100644
index 0000000000..7608d92b4e
--- /dev/null
+++ b/test/files/run/getClassTest-valueClass.check
@@ -0,0 +1,2 @@
+int
+class V
diff --git a/test/files/run/getClassTest-valueClass.scala b/test/files/run/getClassTest-valueClass.scala
new file mode 100644
index 0000000000..05a116dfff
--- /dev/null
+++ b/test/files/run/getClassTest-valueClass.scala
@@ -0,0 +1,10 @@
+class V(val x: Int) extends AnyVal
+
+object Test {
+ def main(args: Array[String]) = {
+ val v = new V(2)
+ val s: Any = 2
+ println(2.getClass)
+ println(v.getClass)
+ }
+}
diff --git a/test/files/run/interop_classtags_are_classmanifests.check b/test/files/run/interop_classtags_are_classmanifests.check
index 7a0a829af2..c07ed0e657 100644
--- a/test/files/run/interop_classtags_are_classmanifests.check
+++ b/test/files/run/interop_classtags_are_classmanifests.check
@@ -1,3 +1,3 @@
-ClassTag[int]
-ClassTag[class java.lang.String]
-ClassTag[class [I]
+Int
+java.lang.String
+Array[int]
diff --git a/test/files/run/macro-expand-tparams-implicit.check b/test/files/run/macro-expand-tparams-implicit.check
index 80c6b826ba..1c1a785706 100644
--- a/test/files/run/macro-expand-tparams-implicit.check
+++ b/test/files/run/macro-expand-tparams-implicit.check
@@ -1,2 +1,2 @@
TypeTag[Int]
-TypeTag[String]
+AbsTypeTag[String]
diff --git a/test/files/run/macro-expand-tparams-prefix-a.check b/test/files/run/macro-expand-tparams-prefix-a.check
index 6c23b47d64..6a7f9c5f52 100644
--- a/test/files/run/macro-expand-tparams-prefix-a.check
+++ b/test/files/run/macro-expand-tparams-prefix-a.check
@@ -1,4 +1,4 @@
TypeTag[Int]
TypeTag[Int]
-TypeTag[String]
+AbsTypeTag[String]
TypeTag[Boolean]
diff --git a/test/files/run/macro-expand-tparams-prefix-b.check b/test/files/run/macro-expand-tparams-prefix-b.check
index 67dabff11e..daae32bd0a 100644
--- a/test/files/run/macro-expand-tparams-prefix-b.check
+++ b/test/files/run/macro-expand-tparams-prefix-b.check
@@ -1,2 +1,2 @@
TypeTag[Boolean] TypeTag[Int]
-TypeTag[Boolean] TypeTag[String]
+TypeTag[Boolean] AbsTypeTag[String]
diff --git a/test/files/run/macro-expand-tparams-prefix-c1.check b/test/files/run/macro-expand-tparams-prefix-c1.check
index 8d1c4e3416..5356b3e6d1 100644
--- a/test/files/run/macro-expand-tparams-prefix-c1.check
+++ b/test/files/run/macro-expand-tparams-prefix-c1.check
@@ -1,3 +1,3 @@
TypeTag[Int]
-TypeTag[String]
+AbsTypeTag[String]
TypeTag[Boolean]
diff --git a/test/files/run/macro-expand-tparams-prefix-c2.check b/test/files/run/macro-expand-tparams-prefix-c2.check
index 8d1c4e3416..5356b3e6d1 100644
--- a/test/files/run/macro-expand-tparams-prefix-c2.check
+++ b/test/files/run/macro-expand-tparams-prefix-c2.check
@@ -1,3 +1,3 @@
TypeTag[Int]
-TypeTag[String]
+AbsTypeTag[String]
TypeTag[Boolean]
diff --git a/test/files/run/macro-undetparams-macroitself.check b/test/files/run/macro-undetparams-macroitself.check
index 80c6b826ba..1c1a785706 100644
--- a/test/files/run/macro-undetparams-macroitself.check
+++ b/test/files/run/macro-undetparams-macroitself.check
@@ -1,2 +1,2 @@
TypeTag[Int]
-TypeTag[String]
+AbsTypeTag[String]
diff --git a/test/files/run/t5064.check b/test/files/run/t5064.check
new file mode 100644
index 0000000000..077006abd9
--- /dev/null
+++ b/test/files/run/t5064.check
@@ -0,0 +1,25 @@
+[12] T5064.super.<init>()
+[12] T5064.super.<init>
+[12] this
+[16:23] immutable.this.List.apply(scala.this.Predef.wrapIntArray(Array[Int]{1}))
+[16:20] immutable.this.List.apply
+<16:20> immutable.this.List
+<16:20> immutable.this
+[16:23] scala.this.Predef.wrapIntArray(Array[Int]{1})
+[20] scala.this.Predef.wrapIntArray
+[20] scala.this.Predef
+[20] scala.this
+[26:32] collection.this.Seq.apply(scala.this.Predef.wrapIntArray(Array[Int]{1}))
+[26:29] collection.this.Seq.apply
+<26:29> collection.this.Seq
+<26:29> collection.this
+[26:32] scala.this.Predef.wrapIntArray(Array[Int]{1})
+[29] scala.this.Predef.wrapIntArray
+[29] scala.this.Predef
+[29] scala.this
+[35:39] immutable.this.List
+<35:39> immutable.this
+[42:45] collection.this.Seq
+<42:45> collection.this
+[48:51] immutable.this.Nil
+<48:51> immutable.this
diff --git a/test/files/run/t5064.scala b/test/files/run/t5064.scala
new file mode 100644
index 0000000000..35f0951765
--- /dev/null
+++ b/test/files/run/t5064.scala
@@ -0,0 +1,23 @@
+import scala.tools.partest._
+
+object Test extends CompilerTest {
+ import global._
+ override def extraSettings = super.extraSettings + " -Yrangepos"
+ override def sources = List(
+ """|class T5064 {
+ | List(1)
+ | Seq(1)
+ | List
+ | Seq
+ | Nil
+ |}""".stripMargin
+ )
+ def check(source: String, unit: CompilationUnit) {
+ for (ClassDef(_, _, _, Template(_, _, stats)) <- unit.body ; stat <- stats ; t <- stat) {
+ t match {
+ case _: Select | _: Apply | _: This => println("%-15s %s".format(t.pos.show, t))
+ case _ =>
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/test/files/run/t5881.check b/test/files/run/t5881.check
index 477fb935a8..8e596e9323 100644
--- a/test/files/run/t5881.check
+++ b/test/files/run/t5881.check
@@ -1,2 +1,2 @@
-ClassTag[class scala.collection.immutable.List]
-ClassTag[class scala.collection.immutable.List]
+scala.collection.immutable.List
+scala.collection.immutable.List
diff --git a/test/files/run/t6246.check b/test/files/run/t6246.check
new file mode 100644
index 0000000000..9532185ead
--- /dev/null
+++ b/test/files/run/t6246.check
@@ -0,0 +1,90 @@
+runtimeClass = byte, toString = Byte
+true
+true
+true
+false
+true
+false
+false
+false
+false
+runtimeClass = short, toString = Short
+true
+true
+true
+false
+true
+false
+false
+false
+false
+runtimeClass = char, toString = Char
+true
+true
+true
+false
+true
+false
+false
+false
+false
+runtimeClass = int, toString = Int
+true
+true
+true
+false
+true
+false
+false
+false
+false
+runtimeClass = long, toString = Long
+true
+true
+true
+false
+true
+false
+false
+false
+false
+runtimeClass = float, toString = Float
+true
+true
+true
+false
+true
+false
+false
+false
+false
+runtimeClass = double, toString = Double
+true
+true
+true
+false
+true
+false
+false
+false
+false
+runtimeClass = void, toString = Unit
+true
+true
+true
+false
+true
+false
+false
+false
+false
+runtimeClass = boolean, toString = Boolean
+true
+true
+true
+false
+true
+false
+false
+false
+false \ No newline at end of file
diff --git a/test/files/run/t6246.scala b/test/files/run/t6246.scala
new file mode 100644
index 0000000000..28765e1adf
--- /dev/null
+++ b/test/files/run/t6246.scala
@@ -0,0 +1,26 @@
+import scala.reflect.{ClassTag, classTag}
+
+object Test extends App {
+ def testValueClass(tag: ClassTag[_]) {
+ println(s"runtimeClass = ${tag.runtimeClass}, toString = ${tag.toString}")
+ println(tag <:< tag)
+ println(tag <:< ClassTag.AnyVal)
+ println(tag <:< ClassTag.Any)
+ println(tag <:< ClassTag.Nothing)
+ println(ClassTag.Nothing <:< tag)
+ println(tag <:< ClassTag.Null)
+ println(ClassTag.Null <:< tag)
+ println(tag <:< ClassTag.Object)
+ println(ClassTag.Object <:< tag)
+ }
+
+ testValueClass(ClassTag.Byte)
+ testValueClass(ClassTag.Short)
+ testValueClass(ClassTag.Char)
+ testValueClass(ClassTag.Int)
+ testValueClass(ClassTag.Long)
+ testValueClass(ClassTag.Float)
+ testValueClass(ClassTag.Double)
+ testValueClass(ClassTag.Unit)
+ testValueClass(ClassTag.Boolean)
+} \ No newline at end of file
diff --git a/test/files/run/t6318_derived.check b/test/files/run/t6318_derived.check
new file mode 100644
index 0000000000..ad43b6579b
--- /dev/null
+++ b/test/files/run/t6318_derived.check
@@ -0,0 +1,3 @@
+Some(X)
+true
+Some(X)
diff --git a/test/files/run/t6318_derived.scala b/test/files/run/t6318_derived.scala
new file mode 100644
index 0000000000..ccdc18daee
--- /dev/null
+++ b/test/files/run/t6318_derived.scala
@@ -0,0 +1,15 @@
+import scala.reflect.{ClassTag, classTag}
+
+object Test extends App {
+ def test[T: ClassTag](x: T) {
+ println(classTag[T].runtimeClass.isAssignableFrom(x.getClass))
+ println(classTag[T].unapply(x))
+ }
+
+ class X(val x: Int) extends AnyVal { override def toString = "X" }
+ val x = new X(1)
+ // the commented line crashes because of SI-6326
+ //println(classTag[X].runtimeClass.isAssignableFrom(x.getClass))
+ println(classTag[X].unapply(x))
+ test(x)
+} \ No newline at end of file
diff --git a/test/files/run/t6318_primitives.check b/test/files/run/t6318_primitives.check
new file mode 100644
index 0000000000..bb474c3bdc
--- /dev/null
+++ b/test/files/run/t6318_primitives.check
@@ -0,0 +1,36 @@
+true
+Some(1)
+false
+None
+true
+Some(1)
+false
+None
+true
+Some()
+false
+None
+true
+Some(1)
+false
+None
+true
+Some(1)
+false
+None
+true
+Some(1.0)
+false
+None
+true
+Some(1.0)
+false
+None
+true
+Some(true)
+false
+None
+true
+Some(())
+false
+None
diff --git a/test/files/run/t6318_primitives.scala b/test/files/run/t6318_primitives.scala
new file mode 100644
index 0000000000..30f27120b3
--- /dev/null
+++ b/test/files/run/t6318_primitives.scala
@@ -0,0 +1,71 @@
+import scala.reflect.{ClassTag, classTag}
+
+object Test extends App {
+ def test[T: ClassTag](x: T) {
+ println(classTag[T].runtimeClass.isAssignableFrom(x.getClass))
+ println(classTag[T].unapply(x))
+ }
+
+ {
+ val x = 1.toByte
+ println(ClassTag.Byte.runtimeClass.isAssignableFrom(x.getClass))
+ println(ClassTag.Byte.unapply(x))
+ test(x)
+ }
+
+ {
+ val x = 1.toShort
+ println(ClassTag.Short.runtimeClass.isAssignableFrom(x.getClass))
+ println(ClassTag.Short.unapply(x))
+ test(x)
+ }
+
+ {
+ val x = 1.toChar
+ println(ClassTag.Char.runtimeClass.isAssignableFrom(x.getClass))
+ println(ClassTag.Char.unapply(x))
+ test(x)
+ }
+
+ {
+ val x = 1.toInt
+ println(ClassTag.Int.runtimeClass.isAssignableFrom(x.getClass))
+ println(ClassTag.Int.unapply(x))
+ test(x)
+ }
+
+ {
+ val x = 1.toLong
+ println(ClassTag.Long.runtimeClass.isAssignableFrom(x.getClass))
+ println(ClassTag.Long.unapply(x))
+ test(x)
+ }
+
+ {
+ val x = 1.toFloat
+ println(ClassTag.Float.runtimeClass.isAssignableFrom(x.getClass))
+ println(ClassTag.Float.unapply(x))
+ test(x)
+ }
+
+ {
+ val x = 1.toDouble
+ println(ClassTag.Double.runtimeClass.isAssignableFrom(x.getClass))
+ println(ClassTag.Double.unapply(x))
+ test(x)
+ }
+
+ {
+ val x = true
+ println(ClassTag.Boolean.runtimeClass.isAssignableFrom(x.getClass))
+ println(ClassTag.Boolean.unapply(x))
+ test(x)
+ }
+
+ {
+ val x = ()
+ println(ClassTag.Unit.runtimeClass.isAssignableFrom(x.getClass))
+ println(ClassTag.Unit.unapply(x))
+ test(x)
+ }
+} \ No newline at end of file
diff --git a/test/files/run/t6327.check b/test/files/run/t6327.check
new file mode 100644
index 0000000000..f7bacac931
--- /dev/null
+++ b/test/files/run/t6327.check
@@ -0,0 +1,4 @@
+A
+A
+A
+A
diff --git a/test/files/run/t6327.scala b/test/files/run/t6327.scala
new file mode 100644
index 0000000000..7683101f14
--- /dev/null
+++ b/test/files/run/t6327.scala
@@ -0,0 +1,22 @@
+import language._
+
+object Test extends App {
+
+ case class R[+T](s: String) { def x() = println(s) }
+
+ // Implicits in contention; StringR is nested to avoid ambiguity
+ object R { implicit val StringR = R[String]("A") }
+ implicit val Default = R[Any]("B")
+
+ class B() extends Dynamic {
+ def selectDynamic[T](f: String)(implicit r: R[T]): Unit = r.x()
+ }
+
+ val b = new B()
+
+ // These should all produce the same output, but they don't
+ b.selectDynamic[String]("baz")
+ b.baz[String]
+ val c = b.selectDynamic[String]("baz")
+ val d = b.baz[String]
+}
diff --git a/test/files/run/t6333.scala b/test/files/run/t6333.scala
new file mode 100644
index 0000000000..266d95ce69
--- /dev/null
+++ b/test/files/run/t6333.scala
@@ -0,0 +1,29 @@
+object Test extends App {
+ import util.Try
+
+ val a = "apple"
+ def fail: String = throw new Exception("Fail!")
+ def argh: Try[String] = throw new Exception("Argh!")
+
+ // No throw tests
+ def tryMethods(expr: => String): Unit = {
+ Try(expr) orElse argh
+ Try(expr).transform(_ => argh, _ => argh)
+ Try(expr).recoverWith { case e if (a == fail) => Try(a) }
+ Try(expr).recoverWith { case _ => argh }
+ Try(expr).getOrElse(a)
+ // TODO - Fail getOrElse?
+ Try(expr) orElse argh
+ Try(expr) orElse Try(a)
+ Try(expr) map (_ => fail)
+ Try(expr) map (_ => a)
+ Try(expr) flatMap (_ => argh)
+ Try(expr) flatMap (_ => Try(a))
+ Try(expr) filter (_ => throw new Exception("O NOES"))
+ Try(expr) filter (_ => true)
+ Try(expr) recover { case _ => fail }
+ Try(expr).failed
+ }
+ tryMethods(a)
+ tryMethods(fail)
+}
diff --git a/test/files/run/valueclasses-classtag-basic.check b/test/files/run/valueclasses-classtag-basic.check
index 0c13986b32..554c75e074 100644
--- a/test/files/run/valueclasses-classtag-basic.check
+++ b/test/files/run/valueclasses-classtag-basic.check
@@ -1 +1 @@
-ClassTag[class Foo]
+Foo
diff --git a/test/files/run/valueclasses-classtag-existential.check b/test/files/run/valueclasses-classtag-existential.check
index 95e94e7aee..15ac02630f 100644
--- a/test/files/run/valueclasses-classtag-existential.check
+++ b/test/files/run/valueclasses-classtag-existential.check
@@ -1 +1 @@
-ClassTag[class java.lang.Object]
+Object
diff --git a/test/files/run/valueclasses-classtag-generic.check b/test/files/run/valueclasses-classtag-generic.check
index 0c13986b32..554c75e074 100644
--- a/test/files/run/valueclasses-classtag-generic.check
+++ b/test/files/run/valueclasses-classtag-generic.check
@@ -1 +1 @@
-ClassTag[class Foo]
+Foo
diff --git a/test/files/run/virtpatmat_typetag.check b/test/files/run/virtpatmat_typetag.check
index f9800b84d0..eaa9f3361f 100644
--- a/test/files/run/virtpatmat_typetag.check
+++ b/test/files/run/virtpatmat_typetag.check
@@ -1,10 +1,10 @@
-1 is not a ClassTag[int]; it's a class java.lang.Integer
-1 is a ClassTag[class java.lang.Integer]
-1 is not a ClassTag[class java.lang.String]; it's a class java.lang.Integer
-true is a ClassTag[class java.lang.Object]
-woele is a ClassTag[class java.lang.String]
-1 is not a ClassTag[int]; it's a class java.lang.Integer
-1 is a ClassTag[class java.lang.Integer]
-1 is not a ClassTag[class java.lang.String]; it's a class java.lang.Integer
-true is a ClassTag[class java.lang.Object]
-woele is a ClassTag[class java.lang.String]
+1 is not a Int; it's a class java.lang.Integer
+1 is a java.lang.Integer
+1 is not a java.lang.String; it's a class java.lang.Integer
+true is a Any
+woele is a java.lang.String
+1 is not a Int; it's a class java.lang.Integer
+1 is a java.lang.Integer
+1 is not a java.lang.String; it's a class java.lang.Integer
+true is a Any
+woele is a java.lang.String