diff options
author | Paul Phillips <paulp@improving.org> | 2012-09-05 00:48:41 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-09-05 00:48:41 -0700 |
commit | 4f9851d1fdbad7c5584931935e138b16d20ac478 (patch) | |
tree | 7b7e9816a5edd7bcd1c9da6ed7abc78272e4a791 | |
parent | c24be0eaa2d1c65d9cf8922f0917e77bd1d03707 (diff) | |
parent | 5d6ba0c99ba010594bd434948b54e6c5dd1f7cf1 (diff) | |
download | scala-4f9851d1fdbad7c5584931935e138b16d20ac478.tar.gz scala-4f9851d1fdbad7c5584931935e138b16d20ac478.tar.bz2 scala-4f9851d1fdbad7c5584931935e138b16d20ac478.zip |
Merge pull request #1256 from paulp/merge-210
Merge 210
90 files changed, 1406 insertions, 943 deletions
diff --git a/project/Build.scala b/project/Build.scala index 58d322108b..d8468032ef 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -215,7 +215,7 @@ object ScalaBuild extends Build with Layers with Packaging with Testing { lazy val scalacheck = Project("scalacheck", file(".")) settings(compilerDependentProjectSettings:_*) dependsOn(actors % "provided") lazy val partestSettings = compilerDependentProjectSettings :+ externalDeps - lazy val partest = Project("partest", file(".")) settings(partestSettings:_*) dependsOn(actors,forkjoin,scalap) + lazy val partest = Project("partest", file(".")) settings(partestSettings:_*) dependsOn(actors,forkjoin,scalap,asm) lazy val scalapSettings = compilerDependentProjectSettings ++ Seq( name := "scalap", exportJars := true diff --git a/project/Partest.scala b/project/Partest.scala index bbc160a41d..fbb0a2a980 100644 --- a/project/Partest.scala +++ b/project/Partest.scala @@ -58,8 +58,8 @@ object partest { val results = runner run Array(testArgs ++ extraArgs ++ extras: _*) asScala // TODO - save results val failures = results collect { - case (path, 1) => path + " [FAILED]" - case (path, 2) => path + " [TIMEOUT]" + case (path, "FAIL") => path + " [FAILED]" + case (path, "TIMEOUT") => path + " [TIMEOUT]" } if (failures.isEmpty) @@ -115,7 +115,7 @@ object partest { } } - def partestRunnerTask(classpath: ScopedTask[Classpath], javacOptions: SettingKey[Seq[String]]): Project.Initialize[Task[PartestRunner]] = + def partestRunnerTask(classpath: ScopedTask[Classpath], javacOptions: TaskKey[Seq[String]]): Project.Initialize[Task[PartestRunner]] = (classpath, javacOptions) map ((cp, opts) => new PartestRunner(Build.data(cp), opts mkString " ")) } @@ -128,11 +128,11 @@ class PartestRunner(classpath: Seq[File], javaOpts: String) { (c,m) } lazy val classPathArgs = Seq("-cp", classpath.map(_.getAbsoluteFile).mkString(java.io.File.pathSeparator)) - def run(args: Array[String]): java.util.Map[String,Int] = try { + def run(args: Array[String]): java.util.Map[String,String] = try { // TODO - undo this settings after running. Also globals are bad. System.setProperty("partest.java_opts", javaOpts) val allArgs = (classPathArgs ++ args).toArray - mainMethod.invoke(null, allArgs).asInstanceOf[java.util.Map[String,Int]] + mainMethod.invoke(null, allArgs).asInstanceOf[java.util.Map[String,String]] } catch { case e => //error("Could not run Partest: " + e) diff --git a/project/plugins.sbt b/project/plugins.sbt index b49ece7527..fdf37e31a6 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -4,6 +4,6 @@ resolvers += Resolver.url("scalasbt", new URL("http://scalasbt.artifactoryonline resolvers += "jgit-repo" at "http://download.eclipse.org/jgit/maven" -libraryDependencies += "net.databinder" %% "dispatch-http" % "0.8.6" +libraryDependencies += "net.databinder" % "dispatch-http_2.9.1" % "0.8.6" diff --git a/project/project/Build.scala b/project/project/Build.scala index bd1250fc39..902e8b0fb3 100644 --- a/project/project/Build.scala +++ b/project/project/Build.scala @@ -2,6 +2,6 @@ import sbt._ object PluginDef extends Build { override def projects = Seq(root) lazy val root = Project("plugins", file(".")) dependsOn(proguard, git) - lazy val proguard = uri("git://github.com/jsuereth/xsbt-proguard-plugin.git#sbt-0.11") + lazy val proguard = uri("git://github.com/jsuereth/xsbt-proguard-plugin.git#sbt-0.12") lazy val git = uri("git://github.com/sbt/sbt-git-plugin.git#scala-build") } diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 486058ec33..187cba8410 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -73,11 +73,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) def this(settings: Settings) = this(settings, new ConsoleReporter(settings)) - // fulfilling requirements - // Renamed AbstractFile to AbstractFileType for backward compatibility: - // it is difficult for sbt to work around the ambiguity errors which result. - type AbstractFileType = scala.tools.nsc.io.AbstractFile - def mkAttributedQualifier(tpe: Type, termSym: Symbol): Tree = gen.mkAttributedQualifier(tpe, termSym) def picklerPhase: Phase = if (currentRun.isDefined) currentRun.picklerPhase else NoPhase diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index e883f3bc42..fb27033097 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -754,8 +754,12 @@ trait Scanners extends ScannersCommon { } else { val isUnclosedLiteral = !isUnicodeEscape && (ch == SU || (!multiLine && (ch == CR || ch == LF))) if (isUnclosedLiteral) { - syntaxError(if (!multiLine) "unclosed string literal" else "unclosed multi-line string literal") - } else { + if (multiLine) + incompleteInputError("unclosed multi-line string literal") + else + syntaxError("unclosed string literal") + } + else { putChar(ch) nextRawChar() getStringPart(multiLine) diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index 49f3781372..142aacfdf7 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -121,10 +121,13 @@ abstract class GenICode extends SubComponent { m.native = m.symbol.hasAnnotation(definitions.NativeAttr) if (!m.isAbstractMethod && !m.native) { - if (m.symbol.isAccessor && m.symbol.accessed.hasStaticAnnotation) { + val staticfield = if (m.symbol.isAccessor && m.symbol.accessed.hasStaticAnnotation) { + val compClass = m.symbol.owner.companionClass + compClass.info.findMember(m.symbol.accessed.name, NoFlags, NoFlags, false) + } else NoSymbol + if (staticfield != NoSymbol) { // in companion object accessors to @static fields, we access the static field directly val hostClass = m.symbol.owner.companionClass - val staticfield = hostClass.info.findMember(m.symbol.accessed.name, NoFlags, NoFlags, false) if (m.symbol.isGetter) { ctx1.bb.emit(LOAD_FIELD(staticfield, true) setHostClass hostClass, tree.pos) 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/interpreter/ExprTyper.scala b/src/compiler/scala/tools/nsc/interpreter/ExprTyper.scala index 54094ad425..4a8ee6549f 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ExprTyper.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ExprTyper.scala @@ -37,7 +37,7 @@ trait ExprTyper { } /** Parse a line into a sequence of trees. Returns None if the input is incomplete. */ - def parse(line: String): Option[List[Tree]] = { + def parse(line: String): Option[List[Tree]] = debugging(s"""parse("$line")""") { var isIncomplete = false reporter.withIncompleteHandler((_, _) => isIncomplete = true) { val trees = codeParser.stmts(line) 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/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index 1aa170a07e..3630cb3dbe 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -562,6 +562,10 @@ abstract class CleanUp extends Transform with ast.TreeDSL { else tree } + case DefDef(mods, name, tps, vps, tp, rhs) if tree.symbol.hasStaticAnnotation => + reporter.error(tree.pos, "The @static annotation is not allowed on method definitions.") + super.transform(tree) + case ValDef(mods, name, tpt, rhs) if tree.symbol.hasStaticAnnotation => def transformStaticValDef = { log("moving @static valdef field: " + name + ", in: " + tree.symbol.owner) @@ -604,7 +608,8 @@ abstract class CleanUp extends Transform with ast.TreeDSL { } // create a static field in the companion class for this @static field - val stfieldSym = linkedClass.newVariable(newTermName(name), tree.pos, STATIC | SYNTHETIC | FINAL) setInfo sym.tpe + val stfieldSym = linkedClass.newValue(newTermName(name), tree.pos, STATIC | SYNTHETIC | FINAL) setInfo sym.tpe + if (sym.isMutable) stfieldSym.setFlag(MUTABLE) stfieldSym.addAnnotation(StaticClass) val names = classNames.getOrElseUpdate(linkedClass, linkedClass.info.decls.collect { @@ -780,7 +785,8 @@ abstract class CleanUp extends Transform with ast.TreeDSL { staticSym <- clazz.info.decls if staticSym.hasStaticAnnotation } staticSym match { - case stfieldSym if stfieldSym.isVariable => + case stfieldSym if (stfieldSym.isValue && !stfieldSym.isMethod) || stfieldSym.isVariable => + log(stfieldSym + " is value: " + stfieldSym.isValue) val valdef = staticBodies((clazz, stfieldSym)) val ValDef(_, _, _, rhs) = valdef val fixedrhs = rhs.changeOwner((valdef.symbol, clazz.info.decl(nme.CONSTRUCTOR))) diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala index 21ed10dfdf..4132661298 100644 --- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala +++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala @@ -111,7 +111,8 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { } def extensionMethInfo(extensionMeth: Symbol, origInfo: Type, clazz: Symbol): Type = { - var newTypeParams = cloneSymbolsAtOwner(clazz.typeParams, extensionMeth) + // No variance for method type parameters + var newTypeParams = cloneSymbolsAtOwner(clazz.typeParams, extensionMeth) map (_ resetFlag COVARIANT | CONTRAVARIANT) val thisParamType = appliedType(clazz.typeConstructor, newTypeParams map (_.tpeHK)) val thisParam = extensionMeth.newValueParameter(nme.SELF, extensionMeth.pos) setInfo thisParamType def transform(clonedType: Type): Type = clonedType match { diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index 0e6d141d3a..6b69184d0a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -85,10 +85,33 @@ trait ContextErrors { def typeErrorMsg(found: Type, req: Type, possiblyMissingArgs: Boolean) = { def missingArgsMsg = if (possiblyMissingArgs) "\n possible cause: missing arguments for method or constructor" else "" + "type mismatch" + foundReqMsg(found, req) + missingArgsMsg } } + def notAnyRefMessage(found: Type): String = { + val tp = found.widen + def name = tp.typeSymbol.nameString + def parents = tp.parents filterNot isTrivialTopType + def onlyAny = tp.parents forall (_.typeSymbol == AnyClass) + def parents_s = ( if (parents.isEmpty) tp.parents else parents ) mkString ", " + def what = ( + if (tp.typeSymbol.isAbstractType) { + val descr = if (onlyAny) "unbounded" else "bounded only by " + parents_s + s"$name is $descr, which means AnyRef is not a known parent" + } + else if (tp.typeSymbol.isAnonOrRefinementClass) + s"the parents of this type ($parents_s) extend Any, not AnyRef" + else + s"$name extends Any, not AnyRef" + ) + if (isPrimitiveValueType(found)) "" else "\n" + + s"""|Note that $what. + |Such types can participate in value classes, but instances + |cannot appear in singleton types or in reference comparisons.""".stripMargin + } + import ErrorUtils._ trait TyperContextErrors { @@ -293,12 +316,17 @@ trait ContextErrors { else "" ) - companion + semicolon + val notAnyRef = ( + if (ObjectClass.info.member(name).exists) notAnyRefMessage(target) + else "" + ) + companion + notAnyRef + semicolon } + def targetStr = targetKindString + target.directObjectString withAddendum(qual.pos)( - if (name == nme.CONSTRUCTOR) target + " does not have a constructor" - else nameString + " is not a member of " + targetKindString + target.directObjectString + addendum - ) + if (name == nme.CONSTRUCTOR) s"$target does not have a constructor" + else s"$nameString is not a member of $targetStr$addendum" + ) } issueNormalTypeError(sel, errMsg) // the error has to be set for the copied tree, otherwise @@ -1092,44 +1120,42 @@ trait ContextErrors { pre1: String, pre2: String, trailer: String) (isView: Boolean, pt: Type, tree: Tree)(implicit context0: Context) = { if (!info1.tpe.isErroneous && !info2.tpe.isErroneous) { - val coreMsg = - pre1+" "+info1.sym.fullLocationString+" of type "+info1.tpe+"\n "+ - pre2+" "+info2.sym.fullLocationString+" of type "+info2.tpe+"\n "+ - trailer - val errMsg = - if (isView) { - val found = pt.typeArgs(0) - val req = pt.typeArgs(1) - def defaultExplanation = - "Note that implicit conversions are not applicable because they are ambiguous:\n "+ - coreMsg+"are possible conversion functions from "+ found+" to "+req - - def explanation = { - val sym = found.typeSymbol - // Explain some common situations a bit more clearly. - if (AnyRefClass.tpe <:< req) { - if (sym == AnyClass || sym == UnitClass) { - "Note: " + sym.name + " is not implicitly converted to AnyRef. You can safely\n" + - "pattern match `x: AnyRef` or cast `x.asInstanceOf[AnyRef]` to do so." - } - else boxedClass get sym match { - case Some(boxed) => - "Note: an implicit exists from " + sym.fullName + " => " + boxed.fullName + ", but\n" + - "methods inherited from Object are rendered ambiguous. This is to avoid\n" + - "a blanket implicit which would convert any " + sym.fullName + " to any AnyRef.\n" + - "You may wish to use a type ascription: `x: " + boxed.fullName + "`." - case _ => - defaultExplanation - } - } - else defaultExplanation - } - - typeErrorMsg(found, req, infer.isPossiblyMissingArgs(found, req)) + "\n" + explanation - } else { - "ambiguous implicit values:\n "+coreMsg + "match expected type "+pt + def coreMsg = + s"""| $pre1 ${info1.sym.fullLocationString} of type ${info1.tpe} + | $pre2 ${info2.sym.fullLocationString} of type ${info2.tpe} + | $trailer""".stripMargin + def viewMsg = { + val found :: req :: _ = pt.typeArgs + def explanation = { + val sym = found.typeSymbol + // Explain some common situations a bit more clearly. Some other + // failures which have nothing to do with implicit conversions + // per se, but which manifest as implicit conversion conflicts + // involving Any, are further explained from foundReqMsg. + if (AnyRefClass.tpe <:< req) ( + if (sym == AnyClass || sym == UnitClass) ( + s"""|Note: ${sym.name} is not implicitly converted to AnyRef. You can safely + |pattern match `x: AnyRef` or cast `x.asInstanceOf[AnyRef]` to do so.""".stripMargin + ) + else boxedClass get sym map (boxed => + s"""|Note: an implicit exists from ${sym.fullName} => ${boxed.fullName}, but + |methods inherited from Object are rendered ambiguous. This is to avoid + |a blanket implicit which would convert any ${sym.fullName} to any AnyRef. + |You may wish to use a type ascription: `x: ${boxed.fullName}`.""".stripMargin + ) getOrElse "" + ) + else + s"""|Note that implicit conversions are not applicable because they are ambiguous: + |${coreMsg}are possible conversion functions from $found to $req""".stripMargin } - context.issueAmbiguousError(AmbiguousTypeError(tree, tree.pos, errMsg)) + typeErrorMsg(found, req, infer.isPossiblyMissingArgs(found, req)) + ( + if (explanation == "") "" else "\n" + explanation + ) + } + context.issueAmbiguousError(AmbiguousTypeError(tree, tree.pos, + if (isView) viewMsg + else s"ambiguous implicit values:\n${coreMsg}match expected type $pt") + ) } } 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 fadf9b8acc..96dcbb5b80 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -279,7 +279,16 @@ trait Infer { def issue(err: AbsTypeError): Unit = context.issue(err) - def isPossiblyMissingArgs(found: Type, req: Type) = (found.resultApprox ne found) && isWeaklyCompatible(found.resultApprox, req) + def isPossiblyMissingArgs(found: Type, req: Type) = ( + false + /** However it is that this condition is expected to imply + * "is possibly missing args", it is too weak. It is + * better to say nothing than to offer misleading guesses. + + (found.resultApprox ne found) + && isWeaklyCompatible(found.resultApprox, req) + */ + ) def explainTypes(tp1: Type, tp2: Type) = withDisambiguation(List(), tp1, tp2)(global.explainTypes(tp1, tp2)) diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala index f0dca64a00..f8a5c401df 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala @@ -252,6 +252,13 @@ trait TypeDiagnostics { } "" // no elaborable variance situation found } + + // For found/required errors where AnyRef would have sufficed: + // explain in greater detail. + def explainAnyVsAnyRef(found: Type, req: Type): String = { + if (AnyRefClass.tpe <:< req) notAnyRefMessage(found) else "" + } + // TODO - figure out how to avoid doing any work at all // when the message will never be seen. I though context.reportErrors // being false would do that, but if I return "<suppressed>" under @@ -261,7 +268,10 @@ trait TypeDiagnostics { ";\n found : " + found.toLongString + existentialContext(found) + explainAlias(found) + "\n required: " + req + existentialContext(req) + explainAlias(req) ) - withDisambiguation(Nil, found, req)(baseMessage) + explainVariance(found, req) + ( withDisambiguation(Nil, found, req)(baseMessage) + + explainVariance(found, req) + + explainAnyVsAnyRef(found, req) + ) } case class TypeDiag(tp: Type, sym: Symbol) extends Ordered[TypeDiag] { diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index d234de2315..87937519fc 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -233,10 +233,11 @@ trait Typers extends Modes with Adaptations with Tags { * @param tree ... * @return ... */ - def checkStable(tree: Tree): Tree = + def checkStable(tree: Tree): Tree = ( if (treeInfo.isExprSafeToInline(tree)) tree else if (tree.isErrorTyped) tree else UnstableTreeError(tree) + ) /** Would tree be a stable (i.e. a pure expression) if the type * of its symbol was not volatile? @@ -578,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) @@ -885,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) { @@ -1056,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 @@ -2528,7 +2529,7 @@ trait Typers extends Modes with Adaptations with Tags { * @param pt ... * @return ... */ - def typedFunction(fun: Function, mode: Int, pt: Type): Tree = { + private def typedFunction(fun: Function, mode: Int, pt: Type): Tree = { val numVparams = fun.vparams.length if (numVparams > definitions.MaxFunctionArity) return MaxFunctionArityError(fun) @@ -5221,7 +5222,10 @@ trait Typers extends Modes with Adaptations with Tags { def typedSingletonTypeTree(tree: SingletonTypeTree) = { val ref1 = checkStable( - typed(tree.ref, EXPRmode | QUALmode | (mode & TYPEPATmode), AnyRefClass.tpe)) + context.withImplicitsDisabled( + typed(tree.ref, EXPRmode | QUALmode | (mode & TYPEPATmode), AnyRefClass.tpe) + ) + ) tree setType ref1.tpe.resultType } @@ -5254,149 +5258,60 @@ trait Typers extends Modes with Adaptations with Tags { // whatever type to tree; we just have to survive until a real error message is issued. tree setType AnyClass.tpe } + def typedFunction(fun: Function) = { + if (fun.symbol == NoSymbol) + fun.symbol = context.owner.newAnonymousFunctionValue(fun.pos) + + typerWithLocalContext(context.makeNewScope(fun, fun.symbol))(_.typedFunction(fun, mode, pt)) + } // begin typed1 //if (settings.debug.value && tree.isDef) log("typing definition of "+sym);//DEBUG - tree match { - case tree: Ident => - typedIdentOrWildcard(tree) - - case tree: Select => - typedSelectOrSuperCall(tree) - - case tree: Apply => - typedApply(tree) - - case tree: TypeTree => - typedTypeTree(tree) - - case tree: Literal => - typedLiteral(tree) - - case tree: This => - typedThis(tree) - - case tree: ValDef => - typedValDef(tree) - - case tree: DefDef => - // flag default getters for constructors. An actual flag would be nice. See SI-5543. - //val flag = ddef.mods.hasDefaultFlag && ddef.mods.hasFlag(PRESUPER) - defDefTyper(tree).typedDefDef(tree) - - case tree: Block => - typerWithLocalContext(context.makeNewScope(tree, context.owner)){ - _.typedBlock(tree, mode, pt) - } - - case tree: If => - typedIf(tree) - - case tree: TypeApply => - typedTypeApply(tree) - - case tree: AppliedTypeTree => - typedAppliedTypeTree(tree) - - case tree: Bind => - typedBind(tree) - - case tree: Function => - if (tree.symbol == NoSymbol) - tree.symbol = context.owner.newAnonymousFunctionValue(tree.pos) - typerWithLocalContext(context.makeNewScope(tree, tree.symbol))(_.typedFunction(tree, mode, pt)) - - case tree: Match => - typedVirtualizedMatch(tree) - - case tree: New => - typedNew(tree) - - case Assign(lhs, rhs) => - typedAssign(lhs, rhs) - - case AssignOrNamedArg(lhs, rhs) => // called by NamesDefaults in silent typecheck - typedAssign(lhs, rhs) - - case tree: Super => - typedSuper(tree) - - case tree: TypeBoundsTree => - typedTypeBoundsTree(tree) - - case tree: Typed => - typedTyped(tree) - - case tree: ClassDef => - newTyper(context.makeNewScope(tree, sym)).typedClassDef(tree) - - case tree: ModuleDef => - newTyper(context.makeNewScope(tree, sym.moduleClass)).typedModuleDef(tree) - - case tree: TypeDef => - typedTypeDef(tree) - - case tree: LabelDef => - labelTyper(tree).typedLabelDef(tree) - - case tree: PackageDef => - typedPackageDef(tree) - - case tree: DocDef => - typedDocDef(tree) - - case tree: Annotated => - typedAnnotated(tree) - - case tree: SingletonTypeTree => - typedSingletonTypeTree(tree) - - case tree: SelectFromTypeTree => - typedSelectFromTypeTree(tree) - - case tree: CompoundTypeTree => - typedCompoundTypeTree(tree) - - case tree: ExistentialTypeTree => - typedExistentialTypeTree(tree) - - case tree: Return => - typedReturn(tree) - - case tree: Try => - typedTry(tree) - - case tree: Throw => - typedThrow(tree) - - case tree: Alternative => - typedAlternative(tree) - - case tree: Star => - typedStar(tree) - - case tree: UnApply => - typedUnApply(tree) - - case tree: ArrayValue => - typedArrayValue(tree) - - case tree: ApplyDynamic => - typedApplyDynamic(tree) - - case tree: ReferenceToBoxed => - typedReferenceToBoxed(tree) - - case tree: TypeTreeWithDeferredRefCheck => - tree // TODO: should we re-type the wrapped tree? then we need to change TypeTreeWithDeferredRefCheck's representation to include the wrapped tree explicitly (instead of in its closure) - - case tree: Import => - assert(forInteractive, "!forInteractive") // should not happen in normal circumstances. - tree setType tree.symbol.tpe - - case _ => - abort("unexpected tree: " + tree.getClass + "\n" + tree)//debug + case tree: Ident => typedIdentOrWildcard(tree) + case tree: Select => typedSelectOrSuperCall(tree) + case tree: Apply => typedApply(tree) + case tree: TypeTree => typedTypeTree(tree) + case tree: Literal => typedLiteral(tree) + case tree: This => typedThis(tree) + case tree: ValDef => typedValDef(tree) + case tree: DefDef => defDefTyper(tree).typedDefDef(tree) + case tree: Block => typerWithLocalContext(context.makeNewScope(tree, context.owner))(_.typedBlock(tree, mode, pt)) + case tree: If => typedIf(tree) + case tree: TypeApply => typedTypeApply(tree) + case tree: AppliedTypeTree => typedAppliedTypeTree(tree) + case tree: Bind => typedBind(tree) + case tree: Function => typedFunction(tree) + case tree: Match => typedVirtualizedMatch(tree) + case tree: New => typedNew(tree) + case tree: Assign => typedAssign(tree.lhs, tree.rhs) + case tree: AssignOrNamedArg => typedAssign(tree.lhs, tree.rhs) // called by NamesDefaults in silent typecheck + case tree: Super => typedSuper(tree) + case tree: TypeBoundsTree => typedTypeBoundsTree(tree) + case tree: Typed => typedTyped(tree) + case tree: ClassDef => newTyper(context.makeNewScope(tree, sym)).typedClassDef(tree) + case tree: ModuleDef => newTyper(context.makeNewScope(tree, sym.moduleClass)).typedModuleDef(tree) + case tree: TypeDef => typedTypeDef(tree) + case tree: LabelDef => labelTyper(tree).typedLabelDef(tree) + case tree: PackageDef => typedPackageDef(tree) + case tree: DocDef => typedDocDef(tree) + case tree: Annotated => typedAnnotated(tree) + case tree: SingletonTypeTree => typedSingletonTypeTree(tree) + case tree: SelectFromTypeTree => typedSelectFromTypeTree(tree) + case tree: CompoundTypeTree => typedCompoundTypeTree(tree) + case tree: ExistentialTypeTree => typedExistentialTypeTree(tree) + case tree: Return => typedReturn(tree) + case tree: Try => typedTry(tree) + case tree: Throw => typedThrow(tree) + case tree: Alternative => typedAlternative(tree) + case tree: Star => typedStar(tree) + case tree: UnApply => typedUnApply(tree) + case tree: ArrayValue => typedArrayValue(tree) + case tree: ApplyDynamic => typedApplyDynamic(tree) + case tree: ReferenceToBoxed => typedReferenceToBoxed(tree) + case tree: TypeTreeWithDeferredRefCheck => tree // TODO: retype the wrapped tree? TTWDRC would have to change to hold the wrapped tree (not a closure) + case tree: Import => assert(forInteractive, "!forInteractive") ; tree setType tree.symbol.tpe // should not happen in normal circumstances. + case _ => abort(s"unexpected tree: ${tree.getClass}\n$tree") } } diff --git a/src/compiler/scala/tools/reflect/ToolBox.scala b/src/compiler/scala/tools/reflect/ToolBox.scala index 2505c1afb7..85e2b6543f 100644 --- a/src/compiler/scala/tools/reflect/ToolBox.scala +++ b/src/compiler/scala/tools/reflect/ToolBox.scala @@ -12,7 +12,7 @@ trait ToolBox[U <: Universe] { /** Underlying mirror of a ToolBox */ - val mirror: MirrorOf[u.type] + val mirror: u.Mirror /** Front end of the toolbox. * diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala index 8cc5a4e531..b658491294 100644 --- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala +++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala @@ -26,7 +26,9 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => private class ToolBoxImpl(val frontEnd: FrontEnd, val options: String) extends ToolBox[U] { toolBoxSelf => val u: factorySelf.u.type = factorySelf.u - val mirror: u.Mirror = factorySelf.mirror + + lazy val classLoader = new AbstractFileClassLoader(virtualDirectory, factorySelf.mirror.classLoader) + lazy val mirror: u.Mirror = u.runtimeMirror(classLoader) class ToolBoxGlobal(settings: scala.tools.nsc.Settings, reporter: Reporter) extends ReflectGlobal(settings, reporter, toolBoxSelf.classLoader) { @@ -327,7 +329,6 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => lazy val importer = compiler.mkImporter(u) lazy val exporter = importer.reverse - lazy val classLoader = new AbstractFileClassLoader(virtualDirectory, mirror.classLoader) def typeCheck(tree: u.Tree, expectedType: u.Type, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree = { if (compiler.settings.verbose.value) println("importing "+tree+", expectedType = "+expectedType) diff --git a/src/library/scala/Dynamic.scala b/src/library/scala/Dynamic.scala index faf834d310..3bcb2f1c90 100644 --- a/src/library/scala/Dynamic.scala +++ b/src/library/scala/Dynamic.scala @@ -9,11 +9,11 @@ package scala /** A marker trait that enables dynamic invocations. Instances `x` of this - * trait allow method invocations `x.meth(args)` for arbitrary method - * names `meth` and argument lists `args` as well as field accesses + * trait allow method invocations `x.meth(args)` for arbitrary method + * names `meth` and argument lists `args` as well as field accesses * `x.field` for arbitrary field names `field`. * - * If a call is not natively supported by `x` (i.e. if type checking + * If a call is not natively supported by `x` (i.e. if type checking * fails), it is rewritten according to the following rules: * * {{{ @@ -23,12 +23,12 @@ package scala * foo.field ~~> foo.selectDynamic("field") * foo.varia = 10 ~~> foo.updateDynamic("varia")(10) * foo.arr(10) = 13 ~~> foo.selectDynamic("arr").update(10, 13) - * foo.arr(10) ~~> foo.applyDynamics("arr")(10) + * foo.arr(10) ~~> foo.applyDynamic("arr")(10) * }}} * * As of Scala 2.10, defining direct or indirect subclasses of this trait * is only possible if the language feature `dynamics` is enabled. */ -trait Dynamic +trait Dynamic extends Any diff --git a/src/library/scala/StringContext.scala b/src/library/scala/StringContext.scala index 855f63907e..678ab30168 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 5d8610a7b7..388e3f193f 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/io/BytePickle.scala b/src/library/scala/io/BytePickle.scala index 3bb5ea9c2b..a199986141 100644 --- a/src/library/scala/io/BytePickle.scala +++ b/src/library/scala/io/BytePickle.scala @@ -19,6 +19,7 @@ import scala.collection.mutable * @author Philipp Haller * @version 1.1 */ +@deprecated("This class will be removed.", "2.10.0") object BytePickle { abstract class SPU[T] { def appP(a: T, state: PicklerState): PicklerState diff --git a/src/library/scala/io/Position.scala b/src/library/scala/io/Position.scala index 5d1e695add..0d0d0d7648 100644 --- a/src/library/scala/io/Position.scala +++ b/src/library/scala/io/Position.scala @@ -32,6 +32,7 @@ package scala.io * }}} * @author Burak Emir (translated from work by Matthias Zenger and others) */ +@deprecated("This class will be removed.", "2.10.0") abstract class Position { /** Definable behavior for overflow conditions. */ diff --git a/src/library/scala/io/UTF8Codec.scala b/src/library/scala/io/UTF8Codec.scala index df0a36ef21..aa6cccf1d1 100644 --- a/src/library/scala/io/UTF8Codec.scala +++ b/src/library/scala/io/UTF8Codec.scala @@ -13,6 +13,7 @@ package scala.io * @author Martin Odersky * @version 1.0, 04/10/2004 */ +@deprecated("This class will be removed.", "2.10.0") object UTF8Codec { final val UNI_REPLACEMENT_CHAR: Int = 0x0000FFFD final val UNI_REPLACEMENT_BYTES = Array[Byte](-17, -65, -67) diff --git a/src/library/scala/language.scala b/src/library/scala/language.scala index df2eb0b910..dfe27f8857 100644 --- a/src/library/scala/language.scala +++ b/src/library/scala/language.scala @@ -17,7 +17,7 @@ object language { * of programs. Furthermore, dynamic member selection often relies on reflection, * which is not available on all platforms. */ - implicit lazy val dynamics: dynamics = ??? + implicit lazy val dynamics: dynamics = languageFeature.dynamics /** Only where enabled, postfix operator notation `(expr op)` will be allowed. * @@ -26,7 +26,7 @@ object language { * _Why control it?_ Postfix operators interact poorly with semicolon inference. * Most programmers avoid them for this reason. */ - implicit lazy val postfixOps: postfixOps = ??? + implicit lazy val postfixOps: postfixOps = languageFeature.postfixOps /** Only where enabled, accesses to members of structural types that need * reflection are supported. Reminder: A structural type is a type of the form @@ -42,7 +42,7 @@ object language { * such as ProGuard have problems dealing with it. Even where reflection is available, * reflective dispatch can lead to surprising performance degradations. */ - implicit lazy val reflectiveCalls: reflectiveCalls = ??? + implicit lazy val reflectiveCalls: reflectiveCalls = languageFeature.reflectiveCalls /** Only where enabled, definitions of implicit conversions are allowed. An * implicit conversion is an implicit value of unary function type `A => B`, @@ -65,7 +65,7 @@ object language { * most situations using implicit parameters leads to a better design than * implicit conversions. */ - implicit lazy val implicitConversions: implicitConversions = ??? + implicit lazy val implicitConversions: implicitConversions = languageFeature.implicitConversions /** Only where this flag is enabled, higher-kinded types can be written. * @@ -86,7 +86,7 @@ object language { * enabling also serves as a warning that code involving higher-kinded types * might have to be slightly revised in the future. */ - implicit lazy val higherKinds: higherKinds = ??? + implicit lazy val higherKinds: higherKinds = languageFeature.higherKinds /** Only where enabled, existential types that cannot be expressed as wildcard * types can be written and are allowed in inferred types of values or return @@ -102,7 +102,7 @@ object language { * is generally perceived not to be a good idea. Also, complicated existential types * might be no longer supported in a future simplification of the language. */ - implicit lazy val existentials: existentials = ??? + implicit lazy val existentials: existentials = languageFeature.existentials object experimental { @@ -119,6 +119,6 @@ object language { * _Why control it?_ For their very power, macros can lead to code that is hard * to debug and understand. */ - implicit lazy val macros: macros = ??? + implicit lazy val macros: macros = languageFeature.experimental.macros } } diff --git a/src/library/scala/languageFeature.scala b/src/library/scala/languageFeature.scala index c32f1eb724..39540b4f49 100644 --- a/src/library/scala/languageFeature.scala +++ b/src/library/scala/languageFeature.scala @@ -6,25 +6,32 @@ object languageFeature { @meta.languageFeature("extension of type scala.Dynamic", enableRequired = true) sealed trait dynamics + object dynamics extends dynamics @meta.languageFeature("postfix operator #", enableRequired = false) sealed trait postfixOps + object postfixOps extends postfixOps @meta.languageFeature("reflective access of structural type member #", enableRequired = false) sealed trait reflectiveCalls + object reflectiveCalls extends reflectiveCalls @meta.languageFeature("implicit conversion #", enableRequired = false) sealed trait implicitConversions + object implicitConversions extends implicitConversions @meta.languageFeature("higher-kinded type", enableRequired = false) sealed trait higherKinds + object higherKinds extends higherKinds @meta.languageFeature("#, which cannot be expressed by wildcards, ", enableRequired = false) sealed trait existentials + object existentials extends existentials object experimental { @meta.languageFeature("macro definition", enableRequired = true) sealed trait macros + object macros extends macros } } 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/testing/Benchmark.scala b/src/library/scala/testing/Benchmark.scala index 9acae34d4e..9c07fcab4f 100644 --- a/src/library/scala/testing/Benchmark.scala +++ b/src/library/scala/testing/Benchmark.scala @@ -33,6 +33,7 @@ import compat.Platform * * @author Iulian Dragos, Burak Emir */ +@deprecated("This class will be removed.", "2.10.0") trait Benchmark { /** this method should be implemented by the concrete benchmark. diff --git a/src/library/scala/testing/Show.scala b/src/library/scala/testing/Show.scala index 5ab46b8985..da1868c7f6 100644 --- a/src/library/scala/testing/Show.scala +++ b/src/library/scala/testing/Show.scala @@ -25,6 +25,7 @@ package scala.testing * where `<result>` is the result of evaluating the call. * */ +@deprecated("This class will be removed.", "2.10.0") trait Show { /** An implicit definition that adds an apply method to Symbol which forwards to `test`. diff --git a/src/library/scala/util/logging/ConsoleLogger.scala b/src/library/scala/util/logging/ConsoleLogger.scala index 58284797b4..1d9a4deb62 100644 --- a/src/library/scala/util/logging/ConsoleLogger.scala +++ b/src/library/scala/util/logging/ConsoleLogger.scala @@ -17,6 +17,7 @@ package scala.util.logging * @author Burak Emir * @version 1.0 */ +@deprecated("This class will be removed.", "2.10.0") trait ConsoleLogger extends Logged { /** logs argument to Console using [[scala.Console.println]] diff --git a/src/library/scala/util/logging/Logged.scala b/src/library/scala/util/logging/Logged.scala index d23b38c569..1476c8bf08 100644 --- a/src/library/scala/util/logging/Logged.scala +++ b/src/library/scala/util/logging/Logged.scala @@ -22,6 +22,7 @@ package scala.util.logging * }}} * and the logging is sent to the [[scala.util.logging.ConsoleLogger]] object. */ +@deprecated("This class will be removed.", "2.10.0") trait Logged { /** This method should log the message given as argument somewhere * as a side-effect. diff --git a/src/partest/scala/tools/partest/nest/SBTRunner.scala b/src/partest/scala/tools/partest/nest/SBTRunner.scala index 266153d9d3..6fa31492f3 100644 --- a/src/partest/scala/tools/partest/nest/SBTRunner.scala +++ b/src/partest/scala/tools/partest/nest/SBTRunner.scala @@ -34,7 +34,7 @@ object SBTRunner extends DirectRunner { scalacOptions: Seq[String] = Seq(), justFailedTests: Boolean = false) - def mainReflect(args: Array[String]): java.util.Map[String, TestState] = { + def mainReflect(args: Array[String]): java.util.Map[String, String] = { setProp("partest.debug", "true") val Argument = new scala.util.matching.Regex("-(.*)") @@ -73,9 +73,13 @@ object SBTRunner extends DirectRunner { (for { (testType, files) <- runs (path, result) <- reflectiveRunTestsForFiles(files,testType).asScala - } yield (path, result)).seq.asJava + } yield (path, fixResult(result))).seq.asJava + } + def fixResult(result: TestState): String = result match { + case TestState.Ok => "OK" + case TestState.Fail => "FAIL" + case TestState.Timeout => "TIMEOUT" } - def main(args: Array[String]): Unit = { val failures = ( for ((path, result) <- mainReflect(args).asScala ; if result != TestState.Ok) yield diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala index b17377795b..d167099979 100644 --- a/src/reflect/scala/reflect/api/Symbols.scala +++ b/src/reflect/scala/reflect/api/Symbols.scala @@ -15,9 +15,10 @@ trait Symbols extends base.Symbols { self: Universe => /** The API of symbols */ trait SymbolApi extends SymbolBase { this: Symbol => - /** The position of this symbol + /** Source file if this symbol is created during this compilation run, + * or a class file if this symbol is loaded from a *.class or *.jar. */ - def pos: Position + def associatedFile: scala.tools.nsc.io.AbstractFile /** A list of annotations attached to this Symbol. */ @@ -182,6 +183,10 @@ trait Symbols extends base.Symbols { self: Universe => */ def isSpecialized: Boolean + /** Is this symbol defined by Java? + */ + def isJava: Boolean + /******************* helpers *******************/ /** ... @@ -204,16 +209,16 @@ trait Symbols extends base.Symbols { self: Universe => /** The API of term symbols */ trait TermSymbolApi extends SymbolApi with TermSymbolBase { this: TermSymbol => - /** Does this symbol represent a value, i.e. not a module and not a method? + /** Is this symbol introduced as `val`? */ - def isValue: Boolean + def isVal: Boolean /** Does this symbol denote a stable value? */ def isStable: Boolean - /** Does this symbol represent a mutable value? + /** Is this symbol introduced as `var`? */ - def isVariable: Boolean + def isVar: Boolean /** Does this symbol represent a getter or a setter? */ @@ -320,6 +325,9 @@ trait Symbols extends base.Symbols { self: Universe => */ def isConstructor: Boolean + /** Does this symbol denote the primary constructor of its enclosing class? */ + def isPrimaryConstructor: Boolean + /** For a polymorphic method, its type parameters, the empty list for all other methods */ def typeParams: List[Symbol] @@ -378,6 +386,22 @@ trait Symbols extends base.Symbols { self: Universe => */ def isSealed: Boolean + /** If this is a sealed class, its known direct subclasses. + * Otherwise, the empty set. + */ + def knownDirectSubclasses: Set[Symbol] + + /** The list of all base classes of this type (including its own typeSymbol) + * in reverse linearization order, starting with the class itself and ending + * in class Any. + */ + def baseClasses: List[Symbol] + + /** The module corresponding to this module class, + * or NoSymbol if this symbol is not a module class. + */ + def module: Symbol + /** If this symbol is a class or trait, its self type, otherwise the type * of the symbol itself. */ diff --git a/src/reflect/scala/reflect/internal/AbstractFileApi.scala b/src/reflect/scala/reflect/internal/AbstractFileApi.scala deleted file mode 100644 index 9f37f4536f..0000000000 --- a/src/reflect/scala/reflect/internal/AbstractFileApi.scala +++ /dev/null @@ -1,7 +0,0 @@ -package scala.reflect -package internal - -trait AbstractFileApi { - def path: String - def canonicalPath: String -} diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 3da7997f6d..9fddd1bb7f 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -218,6 +218,32 @@ trait Definitions extends api.StandardDefinitions { case _ => null } + /** Fully initialize the symbol, type, or scope. + */ + def fullyInitializeSymbol(sym: Symbol): Symbol = { + sym.initialize + fullyInitializeType(sym.info) + fullyInitializeType(sym.tpe) + sym + } + def fullyInitializeType(tp: Type): Type = { + tp.typeParams foreach fullyInitializeSymbol + tp.paramss.flatten foreach fullyInitializeSymbol + tp + } + def fullyInitializeScope(scope: Scope): Scope = { + scope.sorted foreach fullyInitializeSymbol + scope + } + /** Is this type equivalent to Any, AnyVal, or AnyRef? */ + def isTrivialTopType(tp: Type) = ( + tp =:= AnyClass.tpe + || tp =:= AnyValClass.tpe + || tp =:= AnyRefClass.tpe + ) + /** Does this type have a parent which is none of Any, AnyVal, or AnyRef? */ + def hasNonTrivialParent(tp: Type) = tp.parents exists (t => !isTrivialTopType(tp)) + private def fixupAsAnyTrait(tpe: Type): Type = tpe match { case ClassInfoType(parents, decls, clazz) => if (parents.head.typeSymbol == AnyClass) tpe @@ -386,7 +412,7 @@ trait Definitions extends api.StandardDefinitions { def isRepeated(param: Symbol) = isRepeatedParamType(param.tpe) def isCastSymbol(sym: Symbol) = sym == Any_asInstanceOf || sym == Object_asInstanceOf - def isJavaVarArgsMethod(m: Symbol) = m.isMethod && isJavaVarArgs(m.info.params) + def isJavaVarArgsMethod(m: Symbol) = m.isMethod && isJavaVarArgs(m.info.params) def isJavaVarArgs(params: Seq[Symbol]) = params.nonEmpty && isJavaRepeatedParamType(params.last.tpe) def isScalaVarArgs(params: Seq[Symbol]) = params.nonEmpty && isScalaRepeatedParamType(params.last.tpe) def isVarArgsList(params: Seq[Symbol]) = params.nonEmpty && isRepeatedParamType(params.last.tpe) diff --git a/src/reflect/scala/reflect/internal/Required.scala b/src/reflect/scala/reflect/internal/Required.scala index abbe8fbfb7..842491d56d 100644 --- a/src/reflect/scala/reflect/internal/Required.scala +++ b/src/reflect/scala/reflect/internal/Required.scala @@ -5,8 +5,6 @@ import settings.MutableSettings trait Required { self: SymbolTable => - type AbstractFileType >: Null <: AbstractFileApi - def picklerPhase: Phase def settings: MutableSettings diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 70de86a453..2a8249ebe7 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -12,6 +12,7 @@ import util.Statistics import Flags._ import base.Attachments import scala.annotation.tailrec +import scala.tools.nsc.io.AbstractFile trait Symbols extends api.Symbols { self: SymbolTable => import definitions._ @@ -67,12 +68,18 @@ trait Symbols extends api.Symbols { self: SymbolTable => def isParamWithDefault: Boolean = this.hasDefault def isByNameParam: Boolean = this.isValueParameter && (this hasFlag BYNAMEPARAM) def isImplementationArtifact: Boolean = (this hasFlag BRIDGE) || (this hasFlag VBRIDGE) || (this hasFlag ARTIFACT) + def isJava: Boolean = this hasFlag JAVA + def isVal: Boolean = isTerm && !isModule && !isMethod && !isMutable + def isVar: Boolean = isTerm && !isModule && !isMethod && isMutable def newNestedSymbol(name: Name, pos: Position, newFlags: Long, isClass: Boolean): Symbol = name match { case n: TermName => newTermSymbol(n, pos, newFlags) case n: TypeName => if (isClass) newClassSymbol(n, pos, newFlags) else newNonClassSymbol(n, pos, newFlags) } + def knownDirectSubclasses = children + def baseClasses = info.baseClasses + def module = sourceModule def thisPrefix: Type = thisType def selfType: Type = typeOfThis def typeSignature: Type = info @@ -516,6 +523,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => def isTypeParameterOrSkolem = false def isTypeSkolem = false def isTypeMacro = false + def isInvariant = !isCovariant && !isContravariant /** Qualities of Terms, always false for TypeSymbols. */ @@ -2070,21 +2078,21 @@ trait Symbols extends api.Symbols { self: SymbolTable => * of sourceFile (which is expected at least in the IDE only to * return actual source code.) So sourceFile has classfiles filtered out. */ - private def sourceFileOnly(file: AbstractFileType): AbstractFileType = + private def sourceFileOnly(file: AbstractFile): AbstractFile = if ((file eq null) || (file.path endsWith ".class")) null else file - private def binaryFileOnly(file: AbstractFileType): AbstractFileType = + private def binaryFileOnly(file: AbstractFile): AbstractFile = if ((file eq null) || !(file.path endsWith ".class")) null else file - final def binaryFile: AbstractFileType = binaryFileOnly(associatedFile) - final def sourceFile: AbstractFileType = sourceFileOnly(associatedFile) + final def binaryFile: AbstractFile = binaryFileOnly(associatedFile) + final def sourceFile: AbstractFile = sourceFileOnly(associatedFile) /** Overridden in ModuleSymbols to delegate to the module class. */ - def associatedFile: AbstractFileType = enclosingTopLevelClass.associatedFile - def associatedFile_=(f: AbstractFileType) { abort("associatedFile_= inapplicable for " + this) } + def associatedFile: AbstractFile = enclosingTopLevelClass.associatedFile + def associatedFile_=(f: AbstractFile) { abort("associatedFile_= inapplicable for " + this) } @deprecated("Use associatedFile_= instead", "2.10.0") - def sourceFile_=(f: AbstractFileType): Unit = associatedFile_=(f) + def sourceFile_=(f: AbstractFile): Unit = associatedFile_=(f) /** If this is a sealed class, its known direct subclasses. * Otherwise, the empty set. @@ -2438,7 +2446,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => private var flatname: TermName = null override def associatedFile = moduleClass.associatedFile - override def associatedFile_=(f: AbstractFileType) { moduleClass.associatedFile = f } + override def associatedFile_=(f: AbstractFile) { moduleClass.associatedFile = f } override def moduleClass = referenced override def companionClass = @@ -2733,9 +2741,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => extends TypeSymbol(initOwner, initPos, initName) with ClassSymbolApi { type TypeOfClonedSymbol = ClassSymbol - private[this] var flatname: TypeName = _ - private[this] var _associatedFile: AbstractFileType = _ - private[this] var thissym: Symbol = this + private[this] var flatname: TypeName = _ + private[this] var _associatedFile: AbstractFile = _ + private[this] var thissym: Symbol = this private[this] var thisTypeCache: Type = _ private[this] var thisTypePeriod = NoPeriod @@ -2833,7 +2841,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => } override def associatedFile = if (owner.isPackageClass) _associatedFile else super.associatedFile - override def associatedFile_=(f: AbstractFileType) { _associatedFile = f } + override def associatedFile_=(f: AbstractFile) { _associatedFile = f } override def reset(completer: Type): this.type = { super.reset(completer) diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 9ca480155e..1d566e3202 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -1010,7 +1010,11 @@ trait Types extends api.Types { self: SymbolTable => def toLongString = { val str = toString if (str == "type") widen.toString - else if ((str endsWith ".type") && !typeSymbol.isModuleClass) str + " (with underlying type " + widen + ")" + else if ((str endsWith ".type") && !typeSymbol.isModuleClass) + widen match { + case RefinedType(_, _) => "" + widen + case _ => s"$str (with underlying type $widen)" + } else str } @@ -1632,7 +1636,7 @@ trait Types extends api.Types { self: SymbolTable => override def safeToString: String = parentsString(parents) + ( (if (settings.debug.value || parents.isEmpty || (decls.elems ne null)) - decls.mkString("{", "; ", "}") else "") + fullyInitializeScope(decls).mkString("{", "; ", "}") else "") ) } @@ -1819,7 +1823,6 @@ trait Types extends api.Types { self: SymbolTable => false })) } - override def kind = "RefinedType" } @@ -2005,9 +2008,11 @@ trait Types extends api.Types { self: SymbolTable => /** A nicely formatted string with newlines and such. */ def formattedToString: String = - parents.mkString("\n with ") + - (if (settings.debug.value || parents.isEmpty || (decls.elems ne null)) - decls.mkString(" {\n ", "\n ", "\n}") else "") + parents.mkString("\n with ") + ( + if (settings.debug.value || parents.isEmpty || (decls.elems ne null)) + fullyInitializeScope(decls).mkString(" {\n ", "\n ", "\n}") + else "" + ) } object ClassInfoType extends ClassInfoTypeExtractor @@ -2466,7 +2471,7 @@ trait Types extends api.Types { self: SymbolTable => def refinementString = ( if (sym.isStructuralRefinement) ( - decls filter (sym => sym.isPossibleInRefinement && sym.isPublic) + fullyInitializeScope(decls) filter (sym => sym.isPossibleInRefinement && sym.isPublic) map (_.defString) mkString("{", "; ", "}") ) @@ -3712,10 +3717,15 @@ trait Types extends api.Types { self: SymbolTable => * may or may not be poly? (It filched the standard "canonical creator" name.) */ object GenPolyType { - def apply(tparams: List[Symbol], tpe: Type): Type = ( + def apply(tparams: List[Symbol], tpe: Type): Type = { + tpe match { + case MethodType(_, _) => + assert(tparams forall (_.isInvariant), "Trying to create a method with variant type parameters: " + ((tparams, tpe))) + case _ => + } if (tparams.nonEmpty) typeFun(tparams, tpe) else tpe // it's okay to be forgiving here - ) + } def unapply(tpe: Type): Option[(List[Symbol], Type)] = tpe match { case PolyType(tparams, restpe) => Some((tparams, restpe)) case _ => Some((Nil, tpe)) diff --git a/src/reflect/scala/reflect/macros/Universe.scala b/src/reflect/scala/reflect/macros/Universe.scala index 8d9711dedd..06428ee3fc 100644 --- a/src/reflect/scala/reflect/macros/Universe.scala +++ b/src/reflect/scala/reflect/macros/Universe.scala @@ -24,6 +24,12 @@ abstract class Universe extends scala.reflect.api.Universe { */ trait SymbolContextApi extends SymbolApi with AttachableApi { self: Symbol => + def deSkolemize: Symbol + + /** The position of this symbol + */ + def pos: Position + def setTypeSignature(tpe: Type): Symbol def setAnnotations(annots: AnnotationInfo*): Symbol diff --git a/src/reflect/scala/reflect/runtime/AbstractFile.scala b/src/reflect/scala/reflect/runtime/AbstractFile.scala deleted file mode 100644 index 0f88af1b0a..0000000000 --- a/src/reflect/scala/reflect/runtime/AbstractFile.scala +++ /dev/null @@ -1,7 +0,0 @@ -package scala.reflect -package runtime - -class AbstractFile(val jfile: java.io.File) extends internal.AbstractFileApi { - def path: String = jfile.getPath() - def canonicalPath: String = jfile.getCanonicalPath() -} diff --git a/src/reflect/scala/reflect/runtime/JavaUniverse.scala b/src/reflect/scala/reflect/runtime/JavaUniverse.scala index 629df76178..77d65a7db2 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverse.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverse.scala @@ -8,8 +8,6 @@ import internal.{SomePhase, NoPhase, Phase, TreeGen} */ class JavaUniverse extends internal.SymbolTable with ReflectSetup with runtime.SymbolTable { self => - type AbstractFileType = AbstractFile - def picklerPhase = SomePhase lazy val settings = new Settings diff --git a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala index e87c6b339b..0125fa2c53 100644 --- a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala +++ b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala @@ -49,7 +49,7 @@ object ReflectionUtils { case cl: java.net.URLClassLoader => (cl.getURLs mkString ",") case cl if cl != null && isAbstractFileClassLoader(cl.getClass) => - cl.asInstanceOf[{val root: scala.reflect.internal.AbstractFileApi}].root.canonicalPath + cl.asInstanceOf[{val root: scala.tools.nsc.io.AbstractFile}].root.canonicalPath case null => inferBootClasspath case _ => diff --git a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala index 12db7a7bf9..40346cad79 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala @@ -1,7 +1,7 @@ package scala.reflect package runtime -import internal.Flags.DEFERRED +import scala.tools.nsc.io.AbstractFile trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable => @@ -123,7 +123,7 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable => trait SynchronizedClassSymbol extends ClassSymbol with SynchronizedTypeSymbol { override def associatedFile = synchronized { super.associatedFile } - override def associatedFile_=(f: AbstractFileType) = synchronized { super.associatedFile_=(f) } + override def associatedFile_=(f: AbstractFile) = synchronized { super.associatedFile_=(f) } override def thisSym: Symbol = synchronized { super.thisSym } override def thisType: Type = synchronized { super.thisType } override def typeOfThis: Type = synchronized { super.typeOfThis } diff --git a/src/reflect/scala/tools/nsc/io/AbstractFile.scala b/src/reflect/scala/tools/nsc/io/AbstractFile.scala index 8d55b708b1..018a017c6d 100644 --- a/src/reflect/scala/tools/nsc/io/AbstractFile.scala +++ b/src/reflect/scala/tools/nsc/io/AbstractFile.scala @@ -82,7 +82,7 @@ object AbstractFile { * <code>global.settings.encoding.value</code>. * </p> */ -abstract class AbstractFile extends reflect.internal.AbstractFileApi with Iterable[AbstractFile] { +abstract class AbstractFile extends Iterable[AbstractFile] { /** Returns the name of this abstract file. */ def name: String diff --git a/test/files/buildmanager/t2650_3/t2650_3.check b/test/files/buildmanager/t2650_3/t2650_3.check index c109800d9c..5c6326d59f 100644 --- a/test/files/buildmanager/t2650_3/t2650_3.check +++ b/test/files/buildmanager/t2650_3/t2650_3.check @@ -10,6 +10,5 @@ B.scala:2: error: type mismatch; found : a.T (which expands to) Long required: Int - possible cause: missing arguments for method or constructor def x(a: A): Int = a.x ^ diff --git a/test/files/buildmanager/t2650_4/t2650_4.check b/test/files/buildmanager/t2650_4/t2650_4.check index 89536776bd..a4aeaddfbb 100644 --- a/test/files/buildmanager/t2650_4/t2650_4.check +++ b/test/files/buildmanager/t2650_4/t2650_4.check @@ -10,6 +10,5 @@ B.scala:2: error: type mismatch; found : a.T2 (which expands to) Long required: Int - possible cause: missing arguments for method or constructor def x(a: A): Int = a.x ^ 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/any-vs-anyref.check b/test/files/neg/any-vs-anyref.check new file mode 100644 index 0000000000..63c4853130 --- /dev/null +++ b/test/files/neg/any-vs-anyref.check @@ -0,0 +1,64 @@ +any-vs-anyref.scala:6: error: type mismatch; + found : a.type (with underlying type A) + required: AnyRef +Note that A is bounded only by Equals, which means AnyRef is not a known parent. +Such types can participate in value classes, but instances +cannot appear in singleton types or in reference comparisons. + def foo1[A <: Product](a: A) = { type X = a.type } + ^ +any-vs-anyref.scala:7: error: type mismatch; + found : a.type (with underlying type A) + required: AnyRef +Note that A is bounded only by Product, Quux, which means AnyRef is not a known parent. +Such types can participate in value classes, but instances +cannot appear in singleton types or in reference comparisons. + def foo2[A <: Product with Quux](a: A) = { type X = a.type } + ^ +any-vs-anyref.scala:8: error: type mismatch; + found : a.type (with underlying type Product) + required: AnyRef +Note that Product extends Any, not AnyRef. +Such types can participate in value classes, but instances +cannot appear in singleton types or in reference comparisons. + def foo3(a: Product) = { type X = a.type } + ^ +any-vs-anyref.scala:9: error: type mismatch; + found : Product with Quux + required: AnyRef +Note that the parents of this type (Product, Quux) extend Any, not AnyRef. +Such types can participate in value classes, but instances +cannot appear in singleton types or in reference comparisons. + def foo4(a: Product with Quux) = { type X = a.type } + ^ +any-vs-anyref.scala:10: error: value eq is not a member of Quux with Product +Note that the parents of this type (Quux, Product) extend Any, not AnyRef. +Such types can participate in value classes, but instances +cannot appear in singleton types or in reference comparisons. + def foo5(x: Quux with Product) = (x eq "abc") && ("abc" eq x) + ^ +any-vs-anyref.scala:11: error: value eq is not a member of Quux with Product{def f: Int} +Note that the parents of this type (Quux, Product) extend Any, not AnyRef. +Such types can participate in value classes, but instances +cannot appear in singleton types or in reference comparisons. + def foo6(x: Quux with Product { def f: Int }) = (x eq "abc") && ("abc" eq x) + ^ +any-vs-anyref.scala:12: error: type mismatch; + found : Quux with Product{def eq(other: String): Boolean} + required: AnyRef +Note that the parents of this type (Quux, Product) extend Any, not AnyRef. +Such types can participate in value classes, but instances +cannot appear in singleton types or in reference comparisons. + def foo7(x: Quux with Product { def eq(other: String): Boolean }) = (x eq "abc") && ("abc" eq x) + ^ +any-vs-anyref.scala:22: error: value eq is not a member of Bippy +Note that Bippy extends Any, not AnyRef. +Such types can participate in value classes, but instances +cannot appear in singleton types or in reference comparisons. + def bad1(x: Bippy, y: Bippy) = x eq y + ^ +any-vs-anyref.scala:27: error: type mismatch; + found : Quux{def g(x: String): String} + required: Quux{def g(x: Int): Int} + f(new Quux { def g(x: String) = x }) + ^ +9 errors found diff --git a/test/files/neg/any-vs-anyref.scala b/test/files/neg/any-vs-anyref.scala new file mode 100644 index 0000000000..8d237fbaec --- /dev/null +++ b/test/files/neg/any-vs-anyref.scala @@ -0,0 +1,29 @@ +trait Quux extends Any +trait QuuxRef extends AnyRef +final class Bippy(val x: Any) extends AnyVal with Quux + +object Foo { + def foo1[A <: Product](a: A) = { type X = a.type } + def foo2[A <: Product with Quux](a: A) = { type X = a.type } + def foo3(a: Product) = { type X = a.type } + def foo4(a: Product with Quux) = { type X = a.type } + def foo5(x: Quux with Product) = (x eq "abc") && ("abc" eq x) + def foo6(x: Quux with Product { def f: Int }) = (x eq "abc") && ("abc" eq x) + def foo7(x: Quux with Product { def eq(other: String): Boolean }) = (x eq "abc") && ("abc" eq x) + + def ok1[A <: QuuxRef](a: A) = { type X = a.type } + def ok2[A <: Product with QuuxRef](a: A) = { type X = a.type } + def ok3(a: QuuxRef) = { type X = a.type } + def ok4(a: Product with QuuxRef) = { type X = a.type } + def ok5(x: QuuxRef with Product) = (x eq "abc") && ("abc" eq x) + def ok6(x: QuuxRef with Product { def f: Int }) = (x eq "abc") && ("abc" eq x) + def ok7(x: QuuxRef { def eq(other: String): Boolean }) = (x eq "abc") && ("abc" eq x) + + def bad1(x: Bippy, y: Bippy) = x eq y +} + +object Bar { + def f(x: Quux { def g(x: Int): Int }): Int = x g 5 + f(new Quux { def g(x: String) = x }) + f(new Quux { def g(x: Int) = x }) +} diff --git a/test/files/neg/not-possible-cause.check b/test/files/neg/not-possible-cause.check new file mode 100644 index 0000000000..5c09fa1545 --- /dev/null +++ b/test/files/neg/not-possible-cause.check @@ -0,0 +1,9 @@ +not-possible-cause.scala:2: error: type mismatch; + found : a.type (with underlying type A) + required: AnyRef +Note that A is bounded only by Equals, which means AnyRef is not a known parent. +Such types can participate in value classes, but instances +cannot appear in singleton types or in reference comparisons. + def foo[A <: Product](a: A) { type X = a.type } + ^ +one error found diff --git a/test/files/neg/not-possible-cause.scala b/test/files/neg/not-possible-cause.scala new file mode 100644 index 0000000000..83ec24dec8 --- /dev/null +++ b/test/files/neg/not-possible-cause.scala @@ -0,0 +1,3 @@ +object Foo { + def foo[A <: Product](a: A) { type X = a.type } +} diff --git a/test/files/neg/static-annot.check b/test/files/neg/static-annot.check index 66efebdcee..c98e7d9658 100644 --- a/test/files/neg/static-annot.check +++ b/test/files/neg/static-annot.check @@ -13,7 +13,10 @@ static-annot.scala:38: error: The @static annotation is only allowed on public m static-annot.scala:39: error: The @static annotation is not allowed on lazy members. @static lazy val bam = 3 ^ +static-annot.scala:52: error: The @static annotation is not allowed on method definitions. + @static def x = 42 + ^ static-annot.scala:14: error: Only members of top-level objects and their nested objects can be annotated with @static. @static val blah = 2 ^ -6 errors found
\ No newline at end of file +7 errors found diff --git a/test/files/neg/t3614.check b/test/files/neg/t3614.check index 5fdb5cbf1f..0f9c83aa0d 100644 --- a/test/files/neg/t3614.check +++ b/test/files/neg/t3614.check @@ -1,4 +1,4 @@ -t3614.scala:2: error: class type required but AnyRef{def a: <?>} found +t3614.scala:2: error: class type required but AnyRef{def a: Int} found def v = new ({ def a=0 }) ^ -one error found
\ No newline at end of file +one error found diff --git a/test/files/neg/t4581.check b/test/files/neg/t4581.check new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/files/neg/t4581.check diff --git a/test/files/neg/t4581/static-declaration_1.scala b/test/files/neg/t4581/static-declaration_1.scala new file mode 100644 index 0000000000..f9a66b29c1 --- /dev/null +++ b/test/files/neg/t4581/static-declaration_1.scala @@ -0,0 +1,14 @@ + + + + + +object Constants { + import scala.annotation.static + @static val Const: Int = 0 // should generate a static final field + @static final val FinalConst: Int = 0 // ditto + @static var MutableField: Int = 0 // should not be final +} + + + diff --git a/test/files/neg/t4581/static_2.java b/test/files/neg/t4581/static_2.java new file mode 100644 index 0000000000..2fd5bf1d82 --- /dev/null +++ b/test/files/neg/t4581/static_2.java @@ -0,0 +1,15 @@ + + + + +public class static_2 { + public static void main(String[] args) { + Constants.Const = 17; + Constants.FinalConst = 99; + Constants.MutableField = 199; + } +} + + + + diff --git a/test/files/neg/t5510.check b/test/files/neg/t5510.check index 60da3bed40..04220e79bb 100644 --- a/test/files/neg/t5510.check +++ b/test/files/neg/t5510.check @@ -13,7 +13,7 @@ t5510.scala:5: error: unclosed string literal t5510.scala:6: error: unclosed multi-line string literal val s5 = ""s""" $s1 $s2 s" ^ -t5510.scala:7: error: '}' expected but eof found. +t5510.scala:7: error: unclosed multi-line string literal } ^ 6 errors found diff --git a/test/files/neg/t6263.check b/test/files/neg/t6263.check new file mode 100644 index 0000000000..9e9c7c615b --- /dev/null +++ b/test/files/neg/t6263.check @@ -0,0 +1,9 @@ +t6263.scala:5: error: type mismatch; + found : A.this.c.type (with underlying type C) + required: AnyRef +Note that C extends Any, not AnyRef. +Such types can participate in value classes, but instances +cannot appear in singleton types or in reference comparisons. + type t = c.type + ^ +one error found diff --git a/test/files/neg/t6263.scala b/test/files/neg/t6263.scala new file mode 100644 index 0000000000..6575185b5c --- /dev/null +++ b/test/files/neg/t6263.scala @@ -0,0 +1,6 @@ +class C(val a: Any) extends AnyVal +class A { + implicit def c2AnyRef(c: C): AnyRef = new {} + val c = new C(0) + type t = c.type +} diff --git a/test/files/neg/t900.check b/test/files/neg/t900.check index ff5304a135..6fe26a31ac 100644 --- a/test/files/neg/t900.check +++ b/test/files/neg/t900.check @@ -1,6 +1,9 @@ t900.scala:4: error: type mismatch; found : Foo.this.x.type (with underlying type Foo.this.bar) required: AnyRef +Note that bar is unbounded, which means AnyRef is not a known parent. +Such types can participate in value classes, but instances +cannot appear in singleton types or in reference comparisons. def break(): x.type ^ one error found diff --git a/test/files/pos/t6034.scala b/test/files/pos/t6034.scala new file mode 100644 index 0000000000..3558d7ff0b --- /dev/null +++ b/test/files/pos/t6034.scala @@ -0,0 +1 @@ +final class OptPlus[+A](val x: A) extends AnyVal { } 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/t6294.scala b/test/files/pos/t6294.scala new file mode 100644 index 0000000000..c6d39a9cc8 --- /dev/null +++ b/test/files/pos/t6294.scala @@ -0,0 +1,14 @@ + + + +object A { + @annotation.static final val x = 123 +} + + +object B { + println(A.x) +} + + + 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/dynamic-anyval.check b/test/files/run/dynamic-anyval.check new file mode 100644 index 0000000000..dee7bef8e8 --- /dev/null +++ b/test/files/run/dynamic-anyval.check @@ -0,0 +1,4 @@ +().dingo(bippy, 5) +List(1, 2, 3).dingo(bippy, 5) +().dingo(bippy, 5) +List(1, 2, 3).dingo(bippy, 5) diff --git a/test/files/run/dynamic-anyval.scala b/test/files/run/dynamic-anyval.scala new file mode 100644 index 0000000000..605503d377 --- /dev/null +++ b/test/files/run/dynamic-anyval.scala @@ -0,0 +1,22 @@ +import scala.language.dynamics + +object Test { + implicit class DynamicValue[T](val value: T) extends AnyVal with Dynamic { + def applyDynamic(name: String)(args: Any*) = println(s"""$this.$name(${args mkString ", "})""") + override def toString = "" + value + } + implicit class DynamicValue2[T](val value: T) extends Dynamic { + def applyDynamic(name: String)(args: Any*) = println(s"""$this.$name(${args mkString ", "})""") + override def toString = "" + value + } + + def f[T](x: DynamicValue[T]) = x.dingo("bippy", 5) + def g[T](x: DynamicValue2[T]) = x.dingo("bippy", 5) + + def main(args: Array[String]): Unit = { + f(()) + f(List(1, 2, 3)) + g(()) + g(List(1, 2, 3)) + } +} diff --git a/test/files/run/reflection-equality.check b/test/files/run/reflection-equality.check index be531fbbd3..17c1f6dd70 100644 --- a/test/files/run/reflection-equality.check +++ b/test/files/run/reflection-equality.check @@ -1,53 +1,53 @@ -Type in expressions to have them evaluated.
-Type :help for more information.
-
-scala>
-
-scala> class X {
- def methodIntIntInt(x: Int, y: Int) = x+y
-}
-defined class X
-
-scala>
-
-scala> import scala.reflect.runtime.universe._
-import scala.reflect.runtime.universe._
-
-scala> import scala.reflect.runtime.{ currentMirror => cm }
-import scala.reflect.runtime.{currentMirror=>cm}
-
-scala> def im: InstanceMirror = cm.reflect(new X)
-im: reflect.runtime.universe.InstanceMirror
-
-scala> val cs: ClassSymbol = im.symbol
-cs: reflect.runtime.universe.ClassSymbol = class X
-
-scala> val ts: Type = cs.typeSignature
-ts: reflect.runtime.universe.Type =
-java.lang.Object {
- def <init>: <?>
- def methodIntIntInt: <?>
-}
-
-scala> val ms: MethodSymbol = ts.declaration(newTermName("methodIntIntInt")).asMethod
-ms: reflect.runtime.universe.MethodSymbol = method methodIntIntInt
-
-scala> val MethodType( _, t1 ) = ms.typeSignature
-t1: reflect.runtime.universe.Type = scala.Int
-
-scala> val t2 = typeOf[scala.Int]
-t2: reflect.runtime.universe.Type = Int
-
-scala> t1 == t2
-res0: Boolean = false
-
-scala> t1 =:= t2
-res1: Boolean = true
-
-scala> t1 <:< t2
-res2: Boolean = true
-
-scala> t2 <:< t1
-res3: Boolean = true
-
-scala>
+Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> class X { + def methodIntIntInt(x: Int, y: Int) = x+y +} +defined class X + +scala> + +scala> import scala.reflect.runtime.universe._ +import scala.reflect.runtime.universe._ + +scala> import scala.reflect.runtime.{ currentMirror => cm } +import scala.reflect.runtime.{currentMirror=>cm} + +scala> def im: InstanceMirror = cm.reflect(new X) +im: reflect.runtime.universe.InstanceMirror + +scala> val cs: ClassSymbol = im.symbol +cs: reflect.runtime.universe.ClassSymbol = class X + +scala> val ts: Type = cs.typeSignature +ts: reflect.runtime.universe.Type = +java.lang.Object { + def <init>(): X + def methodIntIntInt(x: scala.Int,y: scala.Int): scala.Int +} + +scala> val ms: MethodSymbol = ts.declaration(newTermName("methodIntIntInt")).asMethod +ms: reflect.runtime.universe.MethodSymbol = method methodIntIntInt + +scala> val MethodType( _, t1 ) = ms.typeSignature +t1: reflect.runtime.universe.Type = scala.Int + +scala> val t2 = typeOf[scala.Int] +t2: reflect.runtime.universe.Type = Int + +scala> t1 == t2 +res0: Boolean = false + +scala> t1 =:= t2 +res1: Boolean = true + +scala> t1 <:< t2 +res2: Boolean = true + +scala> t2 <:< t1 +res3: Boolean = true + +scala> diff --git a/test/files/run/reflection-fieldmirror-accessorsareokay.scala b/test/files/run/reflection-fieldmirror-accessorsareokay.scala index 9590cbe811..16354025f3 100644 --- a/test/files/run/reflection-fieldmirror-accessorsareokay.scala +++ b/test/files/run/reflection-fieldmirror-accessorsareokay.scala @@ -14,7 +14,7 @@ object Test extends App { def test(f: Symbol) = { try { val fm: FieldMirror = im.reflectField(f.asTerm) - println(fm.symbol.isVariable) + println(fm.symbol.isVar) println(fm.get) fm.set(2) println(fm.get) diff --git a/test/files/run/reflection-fieldmirror-nmelocalsuffixstring.scala b/test/files/run/reflection-fieldmirror-nmelocalsuffixstring.scala index 5cfe583ed5..2b4a9bb55e 100644 --- a/test/files/run/reflection-fieldmirror-nmelocalsuffixstring.scala +++ b/test/files/run/reflection-fieldmirror-nmelocalsuffixstring.scala @@ -12,5 +12,5 @@ object Test extends App { val cs = im.symbol val f = cs.typeSignature.declaration(newTermName("x" + nme.LOCAL_SUFFIX_STRING)).asTerm val fm: FieldMirror = im.reflectField(f) - println(fm.symbol.isVariable) + println(fm.symbol.isVar) } diff --git a/test/files/run/reflection-fieldmirror-privatethis.scala b/test/files/run/reflection-fieldmirror-privatethis.scala index 7aa179958d..ab838dbb1b 100644 --- a/test/files/run/reflection-fieldmirror-privatethis.scala +++ b/test/files/run/reflection-fieldmirror-privatethis.scala @@ -12,7 +12,7 @@ object Test extends App { val cs = im.symbol val f = cs.typeSignature.declaration(newTermName("x")).asTerm val fm: FieldMirror = im.reflectField(f) - println(fm.symbol.isVariable) + println(fm.symbol.isVar) println(fm.get) fm.set(2) println(fm.get) diff --git a/test/files/run/reflection-fieldsymbol-navigation.scala b/test/files/run/reflection-fieldsymbol-navigation.scala index da4612a564..4448724988 100644 --- a/test/files/run/reflection-fieldsymbol-navigation.scala +++ b/test/files/run/reflection-fieldsymbol-navigation.scala @@ -7,9 +7,9 @@ class C { object Test extends App { val x = typeOf[C].member(newTermName("x")).asTerm println(x) - println(x.isVariable) + println(x.isVar) println(x.accessed) - println(x.accessed.asTerm.isVariable) + println(x.accessed.asTerm.isVar) println(x.getter) println(x.setter) }
\ No newline at end of file diff --git a/test/files/run/static-annot-repl.check b/test/files/run/static-annot-repl.check index d1029a9809..3a1532b823 100644 --- a/test/files/run/static-annot-repl.check +++ b/test/files/run/static-annot-repl.check @@ -13,7 +13,9 @@ scala> @static val x2 = 43 x2: Int = 43 scala> @static def x3 = 44 -x3: Int +<console>:8: error: The @static annotation is not allowed on method definitions. + @static def x3 = 44 + ^ scala> x1 res0: Int = 42 @@ -22,11 +24,15 @@ scala> x2 res1: Int = 43 scala> x3 -res2: Int = 44 +<console>:9: error: not found: value x3 + x3 + ^ scala> class Test { @static def x = 42 } -defined class Test +<console>:9: error: The @static annotation is not allowed on method definitions. + @static def x = 42 + ^ scala>
\ No newline at end of file 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/t5256a.check b/test/files/run/t5256a.check index 518663b3da..7e60139db3 100644 --- a/test/files/run/t5256a.check +++ b/test/files/run/t5256a.check @@ -1,6 +1,6 @@ -class A
-A
+class A +A Object { - def <init>: <?> - def foo: <?> -}
+ def <init>(): A + def foo: Nothing +} diff --git a/test/files/run/t5256b.check b/test/files/run/t5256b.check index d6015f2743..a80df6eb30 100644 --- a/test/files/run/t5256b.check +++ b/test/files/run/t5256b.check @@ -1,6 +1,6 @@ -class A
-Test.A
+class A +Test.A Object { - def <init>: <?> - def foo: <?> -}
+ def <init>(): Test.A + def foo: Nothing +} diff --git a/test/files/run/t5256d.check b/test/files/run/t5256d.check index dd32c05a93..9742ae572e 100644 --- a/test/files/run/t5256d.check +++ b/test/files/run/t5256d.check @@ -1,32 +1,32 @@ -Type in expressions to have them evaluated.
-Type :help for more information.
-
-scala>
-
-scala> import scala.reflect.runtime.universe._
-import scala.reflect.runtime.universe._
-
-scala> import scala.reflect.runtime.{currentMirror => cm}
-import scala.reflect.runtime.{currentMirror=>cm}
-
-scala> class A { def foo = ??? }
-defined class A
-
-scala> val c = cm.classSymbol(classOf[A])
-c: reflect.runtime.universe.ClassSymbol = class A
-
-scala> println(c)
-class A
-
-scala> println(c.fullName)
-$line8.$read.$iw.$iw.$iw.$iw.A
-
-scala> println(c.typeSignature)
-java.lang.Object {
- def <init>: <?>
- def foo: <?>
-}
-
-scala>
-
-scala>
+Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> import scala.reflect.runtime.universe._ +import scala.reflect.runtime.universe._ + +scala> import scala.reflect.runtime.{currentMirror => cm} +import scala.reflect.runtime.{currentMirror=>cm} + +scala> class A { def foo = ??? } +defined class A + +scala> val c = cm.classSymbol(classOf[A]) +c: reflect.runtime.universe.ClassSymbol = class A + +scala> println(c) +class A + +scala> println(c.fullName) +$line8.$read.$iw.$iw.$iw.$iw.A + +scala> println(c.typeSignature) +java.lang.Object { + def <init>(): A + def foo: scala.Nothing +} + +scala> + +scala> diff --git a/test/files/run/t5256e.check b/test/files/run/t5256e.check index 6c6de90acc..011115720c 100644 --- a/test/files/run/t5256e.check +++ b/test/files/run/t5256e.check @@ -1,6 +1,6 @@ class A Test.C.A Object { - def <init>: <?> - def foo: <?> + def <init>(): C.this.A + def foo: Nothing } diff --git a/test/files/run/t5256f.check b/test/files/run/t5256f.check index c840793fd5..e0fec85596 100644 --- a/test/files/run/t5256f.check +++ b/test/files/run/t5256f.check @@ -1,12 +1,12 @@ class A1 Test.A1 Object { - def <init>: <?> - def foo: <?> + def <init>(): Test.A1 + def foo: Nothing } class A2 Test.A2 Object { - def <init>: <?> - def foo: <?> + def <init>(): Test.this.A2 + def foo: Nothing } diff --git a/test/files/run/t6273.check b/test/files/run/t6273.check new file mode 100644 index 0000000000..c1c18daac2 --- /dev/null +++ b/test/files/run/t6273.check @@ -0,0 +1,19 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> val y = 55 +y: Int = 55 + +scala> val x = s""" + y = $y +""" +x: String = +" + y = 55 +" + +scala> + +scala> diff --git a/test/files/run/t6273.scala b/test/files/run/t6273.scala new file mode 100644 index 0000000000..ed0fd452e0 --- /dev/null +++ b/test/files/run/t6273.scala @@ -0,0 +1,11 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + def tq = "\"\"\"" + def code = s""" +val y = 55 +val x = s$tq + y = $$y +$tq + """ +} diff --git a/test/files/run/t6290.scala b/test/files/run/t6290.scala new file mode 100644 index 0000000000..9d05db0d18 --- /dev/null +++ b/test/files/run/t6290.scala @@ -0,0 +1,4 @@ +object Test { + implicit val foo = language.dynamics + def main(args: Array[String]): Unit = () +} |