summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Cunei <antonio.cunei@epfl.ch>2010-04-12 16:37:39 +0000
committerAntonio Cunei <antonio.cunei@epfl.ch>2010-04-12 16:37:39 +0000
commitd61d2c93d788fdf01ad2497b9c6bb69ab9d6a397 (patch)
tree99fb5dd5a796f4701067e49cf74992335a9126e9
parentf31eaf606f2f1f524621dacd280abfccb9110f59 (diff)
downloadscala-d61d2c93d788fdf01ad2497b9c6bb69ab9d6a397.tar.gz
scala-d61d2c93d788fdf01ad2497b9c6bb69ab9d6a397.tar.bz2
scala-d61d2c93d788fdf01ad2497b9c6bb69ab9d6a397.zip
Merged revisions 21467,21471-21482,21486-21487 ...
Merged revisions 21467,21471-21482,21486-21487 via svnmerge from https://lampsvn.epfl.ch/svn-repos/scala/scala/trunk ........ r21467 | plocinic | 2010-04-12 10:09:26 +0200 (Mon, 12 Apr 2010) | 1 line Closes #2757. No review. ........ r21471 | odersky | 2010-04-12 13:52:39 +0200 (Mon, 12 Apr 2010) | 1 line Closes #3224. Review by retronym. ........ r21472 | odersky | 2010-04-12 13:53:05 +0200 (Mon, 12 Apr 2010) | 1 line Cosmetic renamings. No review. ........ r21473 | phaller | 2010-04-12 13:59:29 +0200 (Mon, 12 Apr 2010) | 1 line actors.UncaughtException stores most recent sender. Default output for unhandled exceptions can be disabled using actors.Debug. Review by plocinic. ........ r21474 | phaller | 2010-04-12 14:00:10 +0200 (Mon, 12 Apr 2010) | 1 line Improved deprecation warnings in actors package object. No review. ........ r21475 | phaller | 2010-04-12 14:02:51 +0200 (Mon, 12 Apr 2010) | 1 line Another test for see #2017. No review. ........ r21476 | phaller | 2010-04-12 15:25:57 +0200 (Mon, 12 Apr 2010) | 1 line Attempting to unblock partest by handling AssertionErrors. No review. ........ r21477 | dubochet | 2010-04-12 15:29:05 +0200 (Mon, 12 Apr 2010) | 1 line [scaladoc] meta-documentation (attributes, definition classes, etc.) is available for members that do not have a comment. No review. ........ r21478 | dubochet | 2010-04-12 16:16:01 +0200 (Mon, 12 Apr 2010) | 1 line [scaladoc] Dangerous HTML (that can break Scaladoc) is stripped out of comments and replaced by corresponding wiki syntax when possible. No review. ........ r21479 | dubochet | 2010-04-12 16:29:47 +0200 (Mon, 12 Apr 2010) | 1 line [scaladoc] Not all 23 AbstractFunction classes are listed in the left list. No review. ........ r21480 | dubochet | 2010-04-12 16:38:16 +0200 (Mon, 12 Apr 2010) | 1 line [scaladoc] More mitigation code for dangerous HTML tags. No review. ........ r21481 | malayeri | 2010-04-12 16:52:39 +0200 (Mon, 12 Apr 2010) | 1 line Move constructors to beginning of scaladoc html page; show implicit modifier in main list. Review by dubochet. ........ r21482 | rytz | 2010-04-12 17:12:56 +0200 (Mon, 12 Apr 2010) | 1 line fixed LOAD_MODULE for companions of primitive types. fixes .net build. review by dragos. ........ r21486 | odersky | 2010-04-12 17:26:20 +0200 (Mon, 12 Apr 2010) | 1 line changed testfile, to satisfy new diff algo (which should be reverted IMO). review by extempore. ........ r21487 | extempore | 2010-04-12 18:11:36 +0200 (Mon, 12 Apr 2010) | 1 line Some modifications to partest to improve output. Review by phaller. ........
-rw-r--r--src/actors/scala/actors/ActorTask.scala11
-rw-r--r--src/actors/scala/actors/Debug.scala31
-rw-r--r--src/actors/scala/actors/ReactorTask.scala9
-rw-r--r--src/actors/scala/actors/UncaughtException.scala3
-rw-r--r--src/actors/scala/actors/package.scala8
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala37
-rw-r--r--src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala1
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/page/Index.scala14
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/page/Template.scala262
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css10
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/Entity.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala6
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala24
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala15
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala6
-rw-r--r--src/library/scala/native.scala22
-rw-r--r--src/partest/scala/tools/partest/Actions.scala2
-rw-r--r--src/partest/scala/tools/partest/Compilable.scala7
-rw-r--r--src/partest/scala/tools/partest/Dispatcher.scala19
-rw-r--r--src/partest/scala/tools/partest/Results.scala20
-rw-r--r--src/partest/scala/tools/partest/io/Logging.scala5
-rw-r--r--test/files/jvm/actor-uncaught-exception2.check2
-rw-r--r--test/files/jvm/actor-uncaught-exception2.scala48
-rw-r--r--test/files/neg/t3224.check6
-rwxr-xr-xtest/files/neg/t3224.scala30
26 files changed, 386 insertions, 220 deletions
diff --git a/src/actors/scala/actors/ActorTask.scala b/src/actors/scala/actors/ActorTask.scala
index bceea06072..2fa24f93af 100644
--- a/src/actors/scala/actors/ActorTask.scala
+++ b/src/actors/scala/actors/ActorTask.scala
@@ -30,9 +30,18 @@ private[actors] class ActorTask(actor: Actor,
}
protected override def terminateExecution(e: Exception) {
+ val senderInfo = try { Some(actor.sender) } catch {
+ case _: Exception => None
+ }
+ val uncaught = new UncaughtException(actor,
+ if (msg != null) Some(msg) else None,
+ senderInfo,
+ currentThread,
+ e)
+
actor.synchronized {
if (!actor.links.isEmpty)
- actor.exitLinked(e)
+ actor exitLinked uncaught
}
}
diff --git a/src/actors/scala/actors/Debug.scala b/src/actors/scala/actors/Debug.scala
index bad19b8aeb..f28156fc9a 100644
--- a/src/actors/scala/actors/Debug.scala
+++ b/src/actors/scala/actors/Debug.scala
@@ -11,22 +11,28 @@
package scala.actors
/**
+ * Provides methods for generating debugging output.
+ *
* @author Philipp Haller
*/
-object Debug {
+object Debug extends Logger("") {}
+
+private[actors] class Logger(tag: String) {
private var lev = 2
def level = lev
def level_= (lev: Int) = { this.lev = lev }
+ private val tagString = if (tag == "") "" else " ["+tag+"]"
+
def info(s: String) =
- if (lev > 2) System.out.println("Info: " + s)
+ if (lev > 2) System.out.println("Info" + tagString + ": " + s)
def warning(s: String) =
- if (lev > 1) System.err.println("Warning: " + s)
+ if (lev > 1) System.err.println("Warning" + tagString + ": " + s)
def error(s: String) =
- if (lev > 0) System.err.println("Error: " + s)
+ if (lev > 0) System.err.println("Error" + tagString + ": " + s)
def doInfo(b: => Unit) =
if (lev > 2) b
@@ -38,18 +44,5 @@ object Debug {
if (lev > 0) b
}
-class Debug(tag: String) {
- private var lev = 2
-
- def level = lev
- def level_= (lev: Int) = { this.lev = lev }
-
- def info(s: String) =
- if (lev > 2) System.out.println(tag + " (info): " + s)
-
- def warning(s: String) =
- if (lev > 1) System.err.println(tag + " (warn): " + s)
-
- def error(s: String) =
- if (lev > 0) System.err.println(tag + " (erro): " + s)
-}
+@deprecated("this class is going to be removed in a future release")
+class Debug(tag: String) extends Logger(tag) {}
diff --git a/src/actors/scala/actors/ReactorTask.scala b/src/actors/scala/actors/ReactorTask.scala
index ac809f04ff..3f9ebb6fa7 100644
--- a/src/actors/scala/actors/ReactorTask.scala
+++ b/src/actors/scala/actors/ReactorTask.scala
@@ -53,12 +53,13 @@ private[actors] class ReactorTask[Msg >: Null](var reactor: Reactor[Msg],
// print message on default error stream
val msgException = "Uncaught exception in "+reactor+"\n"
val msgMessage = if (msg != null) "Message: "+msg+"\n" else ""
- Console.err.print(msgException + msgMessage)
- e.printStackTrace()
+ Debug.doWarning {
+ Console.err.print(msgException + msgMessage)
+ e.printStackTrace()
+ }
- val uncaught = new UncaughtException(reactor, if (msg != null) Some(msg) else None, currentThread, e)
+ terminateExecution(e)
reactor.terminated()
- terminateExecution(uncaught)
} finally {
suspendExecution()
this.reactor = null
diff --git a/src/actors/scala/actors/UncaughtException.scala b/src/actors/scala/actors/UncaughtException.scala
index 30043465a1..54c28f66cf 100644
--- a/src/actors/scala/actors/UncaughtException.scala
+++ b/src/actors/scala/actors/UncaughtException.scala
@@ -21,11 +21,12 @@ package scala.actors
*/
class UncaughtException[Msg >: Null](val actor: Reactor[Msg],
val message: Option[Msg],
+ val sender: Option[OutputChannel[Any]],
val thread: Thread,
cause: Exception)
extends Exception(cause) {
override def toString() =
- "UncaughtException("+actor+","+message+","+cause+")"
+ "UncaughtException("+actor+","+message+","+sender+","+cause+")"
}
diff --git a/src/actors/scala/actors/package.scala b/src/actors/scala/actors/package.scala
index 98170b83dd..66ba05b1dd 100644
--- a/src/actors/scala/actors/package.scala
+++ b/src/actors/scala/actors/package.scala
@@ -5,19 +5,19 @@ package object actors {
// type of Reactors tracked by termination detector
private[actors] type TrackedReactor = Reactor[A] forSome { type A >: Null }
- @deprecated("use scala.actors.scheduler.ForkJoinScheduler instead")
+ @deprecated("use scheduler.ForkJoinScheduler instead")
type FJTaskScheduler2 = scala.actors.scheduler.ForkJoinScheduler
- @deprecated("use scala.actors.scheduler.ForkJoinScheduler instead")
+ @deprecated("use scheduler.ForkJoinScheduler instead")
type TickedScheduler = scala.actors.scheduler.ForkJoinScheduler
- @deprecated("use scala.actors.scheduler.ForkJoinScheduler instead")
+ @deprecated("use scheduler.ForkJoinScheduler instead")
type WorkerThreadScheduler = scala.actors.scheduler.ForkJoinScheduler
@deprecated("this class is going to be removed in a future release")
type WorkerThread = java.lang.Thread
- @deprecated("use scala.actors.scheduler.SingleThreadedScheduler instead")
+ @deprecated("use scheduler.SingleThreadedScheduler instead")
type SingleThreadedScheduler = scala.actors.scheduler.SingleThreadedScheduler
// This used to do a blind cast and throw a CCE after the package
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index a3b81862e6..b357dff25a 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -784,7 +784,7 @@ abstract class GenICode extends SubComponent {
if (settings.debug.value)
log("LOAD_MODULE from 'This': " + tree.symbol);
assert(!tree.symbol.isPackageClass, "Cannot use package as value: " + tree)
- ctx.bb.emit(LOAD_MODULE(tree.symbol), tree.pos)
+ genLoadModule(ctx, tree.symbol, tree.pos)
generatedType = REFERENCE(tree.symbol)
} else {
ctx.bb.emit(THIS(ctx.clazz.symbol), tree.pos)
@@ -803,21 +803,18 @@ abstract class GenICode extends SubComponent {
log("LOAD_MODULE from Select(<emptypackage>): " + tree.symbol);
}
assert(!tree.symbol.isPackageClass, "Cannot use package as value: " + tree)
- ctx.bb.emit(LOAD_MODULE(tree.symbol), tree.pos)
+ genLoadModule(ctx, tree.symbol, tree.pos)
ctx
case Select(qualifier, selector) =>
- var sym = tree.symbol
+ val sym = tree.symbol
generatedType = toTypeKind(sym.info)
if (sym.isModule) {
if (settings.debug.value)
- log("LOAD_MODULE from Select(qualifier, selector): " + sym);
+ log("LOAD_MODULE from Select(qualifier, selector): " + sym)
assert(!tree.symbol.isPackageClass, "Cannot use package as value: " + tree)
- if (definitions.primitiveCompanions(sym))
- ctx.bb.emit(LOAD_MODULE(definitions.getModule("scala.runtime." + sym.name)))
- else
- ctx.bb.emit(LOAD_MODULE(sym), tree.pos);
+ genLoadModule(ctx, sym, tree.pos)
ctx
} else if (sym.isStaticMember) {
ctx.bb.emit(LOAD_FIELD(sym, true), tree.pos)
@@ -829,21 +826,22 @@ abstract class GenICode extends SubComponent {
}
case Ident(name) =>
- if (!tree.symbol.isPackage) {
- if (tree.symbol.isModule) {
+ val sym = tree.symbol
+ if (!sym.isPackage) {
+ if (sym.isModule) {
if (settings.debug.value)
- log("LOAD_MODULE from Ident(name): " + tree.symbol);
- assert(!tree.symbol.isPackageClass, "Cannot use package as value: " + tree)
- ctx.bb.emit(LOAD_MODULE(tree.symbol), tree.pos)
- generatedType = toTypeKind(tree.symbol.info)
+ log("LOAD_MODULE from Ident(name): " + sym)
+ assert(!sym.isPackageClass, "Cannot use package as value: " + tree)
+ genLoadModule(ctx, sym, tree.pos)
+ generatedType = toTypeKind(sym.info)
} else {
try {
- val Some(l) = ctx.method.lookupLocal(tree.symbol)
+ val Some(l) = ctx.method.lookupLocal(sym)
ctx.bb.emit(LOAD_LOCAL(l), tree.pos)
generatedType = l.kind
} catch {
case ex: MatchError =>
- abort("symbol " + tree.symbol + " does not exist in " + ctx.method)
+ abort("symbol " + sym + " does not exist in " + ctx.method)
}
}
}
@@ -1037,6 +1035,13 @@ abstract class GenICode extends SubComponent {
ctx1
}
+ private def genLoadModule(ctx: Context, sym: Symbol, pos: Position) {
+ if (definitions.primitiveCompanions(sym))
+ ctx.bb.emit(LOAD_MODULE(definitions.getModule("scala.runtime." + sym.name)), pos)
+ else
+ ctx.bb.emit(LOAD_MODULE(sym), pos)
+ }
+
def genConversion(from: TypeKind, to: TypeKind, ctx: Context, cast: Boolean) = {
if (cast)
ctx.bb.emit(CALL_PRIMITIVE(Conversion(from, to)))
diff --git a/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala b/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala
index c84e608bb7..4c7b1977bb 100644
--- a/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala
+++ b/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala
@@ -143,6 +143,7 @@ trait DependencyAnalysis extends SubComponent with Files {
}
}
+ dependencies.reset(source)
for (d <- unit.depends; if (d.sourceFile != null)){
dependencies.depends(source, d.sourceFile);
}
diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Index.scala b/src/compiler/scala/tools/nsc/doc/html/page/Index.scala
index 7bbd8ef821..8f1d537c43 100644
--- a/src/compiler/scala/tools/nsc/doc/html/page/Index.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/page/Index.scala
@@ -43,10 +43,16 @@ class Index(universe: Universe) extends HtmlPage {
<div class="pack" id="tpl">{
def isExcluded(dtpl: DocTemplateEntity) = {
val qname = dtpl.qualifiedName
- (qname.startsWith("scala.Tuple") || qname.startsWith("scala.Product") || qname.startsWith("scala.Function")) &&
- !(qname=="scala.Function1" || qname=="scala.Function2" || qname=="scala.Function" ||
- qname=="scala.Product1" || qname=="scala.Product2" || qname=="scala.Product" ||
- qname=="scala.Tuple1" || qname=="scala.Tuple2")
+ ( ( qname.startsWith("scala.Tuple") || qname.startsWith("scala.Product") ||
+ qname.startsWith("scala.Function") || qname.startsWith("scala.runtime.AbstractFunction")
+ ) && !(
+ qname == "scala.Tuple1" || qname == "scala.Tuple2" ||
+ qname == "scala.Product" || qname == "scala.Product1" || qname == "scala.Product2" ||
+ qname == "scala.Function" || qname == "scala.Function1" || qname == "scala.Function2" ||
+ qname == "scala.runtime.AbstractFunction0" || qname == "scala.runtime.AbstractFunction1" ||
+ qname == "scala.runtime.AbstractFunction2"
+ )
+ )
}
def packageElem(pack: model.Package): NodeSeq = {
<xml:group>
diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
index 4a6a9de032..d90e3d2f64 100644
--- a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
@@ -71,6 +71,13 @@ class Template(tpl: DocTemplateEntity) extends HtmlPage {
</div>
</div>
+ { if (constructors.isEmpty) NodeSeq.Empty else
+ <div id="constructors" class="members">
+ <h3>Instance constructors</h3>
+ <ol>{ constructors map (memberToHtml(_)) }</ol>
+ </div>
+ }
+
{ if (typeMembers.isEmpty) NodeSeq.Empty else
<div id="types" class="members">
<h3>Type Members</h3>
@@ -85,13 +92,6 @@ class Template(tpl: DocTemplateEntity) extends HtmlPage {
</div>
}
- { if (constructors.isEmpty) NodeSeq.Empty else
- <div id="constructors" class="members">
- <h3>Instance constructors</h3>
- <ol>{ constructors map (memberToHtml(_)) }</ol>
- </div>
- }
-
</div>
<div id="tooltip" ></div>
@@ -114,146 +114,162 @@ class Template(tpl: DocTemplateEntity) extends HtmlPage {
}
mbr match {
case dte: DocTemplateEntity if isSelf =>
- <div id="comment" class="fullcomment">{ memberToFullCommentHtml(mbr, isSelf) }</div>
+ // comment of class itself
+ <div id="comment" class="fullcomment">{ memberToCommentBodyHtml(mbr, isSelf = true) }</div>
case dte: DocTemplateEntity if mbr.comment.isDefined =>
+ // comment of inner, documented class (only short comment, full comment is on the class' own page)
<p class="comment cmt">{ inlineToHtml(mbr.comment.get.short) }</p>
- case _ if mbr.comment.isDefined =>
- <p class="shortcomment cmt">{ useCaseCommentHtml }{ inlineToHtml(mbr.comment.get.short) }</p>
- <div class="fullcomment">{ useCaseCommentHtml }{ memberToFullCommentHtml(mbr, isSelf) }</div>
- case _ => useCaseCommentHtml
+ case _ =>
+ // comment of non-class member or non-documentented inner class
+ val commentBody = memberToCommentBodyHtml(mbr, isSelf = false)
+ if (commentBody.isEmpty)
+ NodeSeq.Empty
+ else {
+ <xml:group>
+ { if (mbr.comment.isEmpty) NodeSeq.Empty else {
+ <p class="shortcomment cmt">{ useCaseCommentHtml }{ inlineToHtml(mbr.comment.get.short) }</p>
+ }
+ }
+ <div class="fullcomment">{ useCaseCommentHtml }{ memberToCommentBodyHtml(mbr, isSelf) }</div>
+ </xml:group>
+ }
}
}
- def memberToFullCommentHtml(mbr: MemberEntity, isSelf: Boolean): NodeSeq =
- <xml:group>
- { if (mbr.comment.isEmpty) NodeSeq.Empty else
- <div class="comment cmt">{ commentToHtml(mbr.comment) }</div>
+ def memberToCommentBodyHtml(mbr: MemberEntity, isSelf: Boolean): NodeSeq =
+ NodeSeq.Empty ++
+ { if (mbr.comment.isEmpty) NodeSeq.Empty else
+ <div class="comment cmt">{ commentToHtml(mbr.comment) }</div>
+ } ++
+ { val prs: List[ParameterEntity] = mbr match {
+ case cls: Class if cls.isCaseClass =>
+ cls.typeParams ::: (cls.primaryConstructor map (_.valueParams.flatten)).toList.flatten
+ case trt: Trait => trt.typeParams
+ case dfe: Def => dfe.typeParams ::: dfe.valueParams.flatten
+ case ctr: Constructor => ctr.valueParams.flatten
+ case _ => Nil
}
- { val prs: List[ParameterEntity] = mbr match {
- case cls: Class if cls.isCaseClass =>
- cls.typeParams ::: (cls.primaryConstructor map (_.valueParams.flatten)).toList.flatten
- case trt: Trait => trt.typeParams
- case dfe: Def => dfe.typeParams ::: dfe.valueParams.flatten
- case ctr: Constructor => ctr.valueParams.flatten
- case _ => Nil
- }
- def mbrCmt = mbr.comment.get
- def paramCommentToHtml(prs: List[ParameterEntity]): NodeSeq = prs match {
- case Nil =>
- NodeSeq.Empty
- case (tp: TypeParam) :: rest =>
- val paramEntry: NodeSeq = {
- <dt class="tparam">{ tp.name }</dt><dd class="cmt">{ bodyToHtml(mbrCmt.typeParams(tp.name)) }</dd>
- }
- paramEntry ++ paramCommentToHtml(rest)
- case (vp: ValueParam) :: rest =>
- val paramEntry: NodeSeq = {
- <dt class="param">{ vp.name }</dt><dd class="cmt">{ bodyToHtml(mbrCmt.valueParams(vp.name)) }</dd>
- }
- paramEntry ++ paramCommentToHtml(rest)
- }
- if (mbr.comment.isEmpty) NodeSeq.Empty
- else {
- val cmtedPrs = prs filter {
- case tp: TypeParam => mbrCmt.typeParams isDefinedAt tp.name
- case vp: ValueParam => mbrCmt.valueParams isDefinedAt vp.name
+ def mbrCmt = mbr.comment.get
+ def paramCommentToHtml(prs: List[ParameterEntity]): NodeSeq = prs match {
+ case Nil =>
+ NodeSeq.Empty
+ case (tp: TypeParam) :: rest =>
+ val paramEntry: NodeSeq = {
+ <dt class="tparam">{ tp.name }</dt><dd class="cmt">{ bodyToHtml(mbrCmt.typeParams(tp.name)) }</dd>
}
- if (cmtedPrs.isEmpty && mbrCmt.result.isEmpty) NodeSeq.Empty
- else
- <dl class="paramcmts block">{
- paramCommentToHtml(cmtedPrs) ++ (
- mbrCmt.result match {
- case None => NodeSeq.Empty
- case Some(cmt) =>
- <dt>returns</dt><dd class="cmt">{ bodyToHtml(cmt) }</dd>
- })
- }</dl>
+ paramEntry ++ paramCommentToHtml(rest)
+ case (vp: ValueParam) :: rest =>
+ val paramEntry: NodeSeq = {
+ <dt class="param">{ vp.name }</dt><dd class="cmt">{ bodyToHtml(mbrCmt.valueParams(vp.name)) }</dd>
+ }
+ paramEntry ++ paramCommentToHtml(rest)
+ }
+ if (mbr.comment.isEmpty) NodeSeq.Empty
+ else {
+ val cmtedPrs = prs filter {
+ case tp: TypeParam => mbrCmt.typeParams isDefinedAt tp.name
+ case vp: ValueParam => mbrCmt.valueParams isDefinedAt vp.name
}
+ if (cmtedPrs.isEmpty && mbrCmt.result.isEmpty) NodeSeq.Empty
+ else
+ <dl class="paramcmts block">{
+ paramCommentToHtml(cmtedPrs) ++ (
+ mbrCmt.result match {
+ case None => NodeSeq.Empty
+ case Some(cmt) =>
+ <dt>returns</dt><dd class="cmt">{ bodyToHtml(cmt) }</dd>
+ })
+ }</dl>
}
- { val fvs: List[comment.Paragraph] = visibility(mbr).toList ::: mbr.flags
- if (fvs.isEmpty) NodeSeq.Empty else
+ } ++
+ { val fvs: List[comment.Paragraph] = visibility(mbr).toList ::: mbr.flags
+ if (fvs.isEmpty) NodeSeq.Empty else
+ <div class="block">
+ attributes: { fvs map { fv => { inlineToHtml(fv.text) ++ xml.Text(" ") } } }
+ </div>
+ } ++
+ { tpl.companion match {
+ case Some(companion) if isSelf =>
<div class="block">
- attributes: { fvs map { fv => { inlineToHtml(fv.text) ++ xml.Text(" ") } } }
+ go to: <a href={relativeLinkTo(companion)}>companion</a>
</div>
+ case _ =>
+ NodeSeq.Empty
}
- { tpl.companion match {
- case Some(companion) if isSelf =>
- <div class="block">
- Go to: <a href={relativeLinkTo(companion)}>companion</a>
- </div>
- case _ =>
- NodeSeq.Empty
- }
+ } ++
+ { val inDefTpls = mbr.inDefinitionTemplates
+ if (inDefTpls.tail.isEmpty && (inDefTpls.head == mbr.inTemplate)) NodeSeq.Empty else {
+ <div class="block">
+ definition classes: { templatesToHtml(inDefTpls, xml.Text(" → ")) }
+ </div>
}
- { val inDefTpls = mbr.inDefinitionTemplates
- if (inDefTpls.tail.isEmpty && (inDefTpls.head == mbr.inTemplate)) NodeSeq.Empty else {
+ } ++
+ { mbr match {
+ case dtpl: DocTemplateEntity if (isSelf && !dtpl.subClasses.isEmpty) =>
<div class="block">
- definition classes: { templatesToHtml(inDefTpls, xml.Text(" → ")) }
+ known subclasses: { templatesToHtml(dtpl.subClasses, xml.Text(", ")) }
</div>
- }
+ case _ => NodeSeq.Empty
}
- { mbr match {
- case dtpl: DocTemplateEntity if (isSelf && !dtpl.subClasses.isEmpty) =>
- <div class="block">
- known subclasses: { templatesToHtml(dtpl.subClasses, xml.Text(", ")) }
- </div>
- case _ => NodeSeq.Empty
- }
- }
- { mbr match {
- case dtpl: DocTemplateEntity if (isSelf && dtpl.sourceUrl.isDefined) =>
- val sourceUrl = tpl.sourceUrl.get
- <div class="block">
- source: { <a href={ sourceUrl.toString }>{ Text(new java.io.File(sourceUrl.getPath).getName) }</a> }
- </div>
- case _ => NodeSeq.Empty
- }
+ } ++
+ { mbr match {
+ case dtpl: DocTemplateEntity if (isSelf && dtpl.sourceUrl.isDefined) =>
+ val sourceUrl = tpl.sourceUrl.get
+ <div class="block">
+ source: { <a href={ sourceUrl.toString }>{ Text(new java.io.File(sourceUrl.getPath).getName) }</a> }
+ </div>
+ case _ => NodeSeq.Empty
}
- { if(mbr.deprecation.isEmpty) NodeSeq.Empty else
- <div class="block"><ol>deprecated:
- { <li>{ bodyToHtml(mbr.deprecation.get) }</li> }
- </ol></div>
+ } ++
+ { if (mbr.deprecation.isEmpty) NodeSeq.Empty else
+ <div class="block"><ol>deprecated:
+ { <li>{ bodyToHtml(mbr.deprecation.get) }</li> }
+ </ol></div>
+ } ++
+ { mbr.comment match {
+ case Some(comment) =>
+ <xml:group>
+ { if(!comment.version.isEmpty)
+ <div class="block"><ol>version
+ { for(body <- comment.version.toList) yield <li>{bodyToHtml(body)}</li> }
+ </ol></div>
+ else NodeSeq.Empty
+ }
+ { if(!comment.since.isEmpty)
+ <div class="block"><ol>since
+ { for(body <- comment.since.toList) yield <li>{bodyToHtml(body)}</li> }
+ </ol></div>
+ else NodeSeq.Empty
+ }
+ { if(!comment.see.isEmpty)
+ <div class="block"><ol>see also:
+ { val seeXml:List[scala.xml.NodeSeq]=(for(see <- comment.see ) yield <li>{bodyToHtml(see)}</li> )
+ seeXml.reduceLeft(_ ++ Text(", ") ++ _)
+ }
+ </ol></div>
+ else NodeSeq.Empty
+ }
+ { if(!comment.authors.isEmpty)
+ <div class="block"><ol>authors:
+ { val authorsXml:List[scala.xml.NodeSeq]=(for(author <- comment.authors ) yield <li>{bodyToHtml(author)}</li> )
+ authorsXml.reduceLeft(_ ++ Text(", ") ++ _)
+ }
+ </ol></div>
+ else NodeSeq.Empty
+ }
+ </xml:group>
+ case None => NodeSeq.Empty
}
- { for(comment <- mbr.comment.toList) yield {
- <xml:group>
- { if(!comment.version.isEmpty)
- <div class="block"><ol>version
- { for(body <- comment.version.toList) yield <li>{bodyToHtml(body)}</li> }
- </ol></div>
- else NodeSeq.Empty
- }
- { if(!comment.since.isEmpty)
- <div class="block"><ol>since
- { for(body <- comment.since.toList) yield <li>{bodyToHtml(body)}</li> }
- </ol></div>
- else NodeSeq.Empty
- }
- { if(!comment.see.isEmpty)
- <div class="block"><ol>see also:
- { val seeXml:List[scala.xml.NodeSeq]=(for(see <- comment.see ) yield <li>{bodyToHtml(see)}</li> )
- seeXml.reduceLeft(_ ++ Text(", ") ++ _)
- }
- </ol></div>
- else NodeSeq.Empty
- }
- { if(!comment.authors.isEmpty)
- <div class="block"><ol>authors:
- { val authorsXml:List[scala.xml.NodeSeq]=(for(author <- comment.authors ) yield <li>{bodyToHtml(author)}</li> )
- authorsXml.reduceLeft(_ ++ Text(", ") ++ _)
- }
- </ol></div>
- else NodeSeq.Empty
- }
- </xml:group>
- }}
- </xml:group>
+ }
def kindToString(mbr: MemberEntity): String = mbr match {
case tpl: DocTemplateEntity =>
if (tpl.isPackage) "package" else if (tpl.isClass) "class" else if (tpl.isTrait) "trait" else "object"
case ctor: Constructor => "new"
case tme: MemberEntity =>
- if (tme.isDef) "def" else if (tme.isVal) "val" else if (tme.isVar) "var" else "type"
+ val attr: String = if (tme.isImplicit) "implicit " else ""
+ val kind = if (tme.isDef) "def" else if (tme.isVal) "val" else if (tme.isVar) "var" else "type"
+ attr + kind
}
def boundsToHtml(hi: Option[TypeEntity], lo: Option[TypeEntity], hasLinks: Boolean): NodeSeq = {
diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css b/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css
index a23c8b6402..5c8822b1c1 100644
--- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css
+++ b/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css
@@ -123,12 +123,12 @@ div.members > ol > li {
text-align: right;
float: left;
display: inline-block;
- width: 72px;
+ width: 7em;
}
.signature .symbol {
display: inline;
- padding-left: 8px;
+ padding-left: 0.7em;
}
.signature .name {
@@ -219,12 +219,12 @@ div.members > ol > li {
p.comment {
display: block;
- margin-left: 80px;
+ margin-left: 7.7em;
}
p.shortcomment {
display: block;
- margin-left: 80px;
+ margin-left: 7.7em;
cursor: help;
}
@@ -234,7 +234,7 @@ div.fullcomment {
}
#template div.fullcomment {
- margin: 6px 0 6px 80px;
+ margin: 6px 0 6px 7.7em;
}
div.fullcomment .block {
diff --git a/src/compiler/scala/tools/nsc/doc/model/Entity.scala b/src/compiler/scala/tools/nsc/doc/model/Entity.scala
index 7aa2c234ea..678702c7f1 100644
--- a/src/compiler/scala/tools/nsc/doc/model/Entity.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/Entity.scala
@@ -49,6 +49,7 @@ trait MemberEntity extends Entity {
def isDef: Boolean
def isVal: Boolean
def isVar: Boolean
+ def isImplicit: Boolean
def isConstructor: Boolean
def isAliasType: Boolean
def isAbstractType: Boolean
@@ -63,6 +64,7 @@ trait DocTemplateEntity extends TemplateEntity with MemberEntity {
def sourceUrl: Option[java.net.URL]
def typeParams: List[TypeParam]
def parentType: Option[TypeEntity]
+ def parentTemplates: List[TemplateEntity]
def linearization: List[TemplateEntity]
def subClasses: List[DocTemplateEntity]
def members: List[MemberEntity]
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
index 64dfbfb160..9641bc9045 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
@@ -52,6 +52,10 @@ class ModelFactory(val global: Global, val settings: doc.Settings) extends Comme
def inTemplate = inTpl
def toRoot: List[EntityImpl] = this :: inTpl.toRoot
def qualifiedName = name
+ override def equals(that: Any) = that match {
+ case that: EntityImpl => this.sym == that.sym
+ case _ => false
+ }
}
/** Provides a default implementation for instances of the `WeakTemplateEntity` type. It must be instantiated as a
@@ -121,6 +125,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) extends Comme
def isDef = false
def isVal = false
def isVar = false
+ def isImplicit = sym.isImplicit
def isConstructor = false
def isAliasType = false
def isAbstractType = false
@@ -154,6 +159,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) extends Comme
else None
}
def typeParams = if (sym.isClass) sym.typeParams map (makeTypeParam(_, this)) else Nil
+ def parentTemplates = sym.info.parents map { x: Type => makeTemplate(x.typeSymbol) }
def parentType =
if (sym.isPackage) None else
Some(makeType(RefinedType(sym.tpe.parents filter (_ != ScalaObjectClass.tpe), EmptyScope)))
diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
index 0aff68ab02..dba538046a 100644
--- a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
@@ -45,8 +45,8 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
}
}
- protected val endOfText = '\u0003'
- protected val endOfLine = '\u000A'
+ protected val endOfText = '\u0003'
+ protected val endOfLine = '\u000A'
/** Something that should not have happened, happened, and Scaladoc should exit. */
protected def oops(msg: String): Nothing =
@@ -56,6 +56,22 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
protected val CleanCommentLine =
new Regex("""(?:\s*\*\s?)?(.*)""")
+ /** Dangerous HTML tags that should be replaced by something safer, such as wiki syntax, or that should be dropped. */
+ protected val DangerousHtml =
+ new Regex("""<(/?(?:p|div|pre|ol|ul|li|h[1-6]|code))[^>]*>""")
+
+ /** Maps a dangerous HTML tag to a safe wiki replacement, or an empty string if it cannot be salvaged. */
+ protected def htmlReplacement(mtch: Regex.Match): String = mtch.matched match {
+ case "p" | "div" => "\n\n"
+ case "h1" | "h2" | "h3" | "h4" | "h5" | "h6" => "\n= "
+ case "/h1" | "/h2" | "/h3" | "/h4" | "/h5" | "/h6" => " =\n"
+ case "pre" => "{{{"
+ case "/pre" => "}}}"
+ case "code" | "/code" => "`"
+ case "li" => "\n - "
+ case _ => ""
+ }
+
/** A Scaladoc tag not linked to a symbol. Returns the name of the tag, and the rest of the line. */
protected val SimpleTag =
new Regex("""\s*@(\S+)\s+(.*)""")
@@ -99,7 +115,9 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
tl
}
}
- comment.trim.stripPrefix("/*").stripSuffix("*/").lines.toList map (cleanLine(_))
+ val strippedComment = comment.trim.stripPrefix("/*").stripSuffix("*/")
+ val safeComment = DangerousHtml.replaceAllIn(strippedComment, { htmlReplacement(_) })
+ safeComment.lines.toList map (cleanLine(_))
}
/** Parses a comment (in the form of a list of lines) to a Comment instance, recursively on lines. To do so, it
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index c0b54cb4f0..c8d3308077 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -802,6 +802,14 @@ trait Infer {
(argtpes1, argPos, namesOK)
}
+ /** don't do a () to (()) conversion for methods whose second parameter
+ * is a varargs. This is a fairly kludgey way to address #3224.
+ * We'll probably find a better way to do this by identifying
+ * tupled and n-ary methods, but thiws is something for a future major revision.
+ */
+ def isUnitForVarArgs(args: List[AnyRef], params: List[Symbol]): Boolean =
+ args.length == 0 && params.length == 2 && isVarArgs(params)
+
/** Is there an instantiation of free type variables <code>undetparams</code>
* such that function type <code>ftpe</code> is applicable to
* <code>argtpes</code> and its result conform to <code>pt</code>?
@@ -833,14 +841,15 @@ trait Infer {
def tryTupleApply: Boolean = {
// if 1 formal, 1 argtpe (a tuple), otherwise unmodified argtpes0
- val tupleArgTpe = actualTypes(argtpes0 map {
+ val tupleArgTpes = actualTypes(argtpes0 map {
// no assignment is treated as named argument here
case NamedType(name, tp) => UnitClass.tpe
case tp => tp
}, formals.length)
- argtpes0.length != tupleArgTpe.length &&
- isApplicable(undetparams, ftpe, tupleArgTpe, pt)
+ argtpes0.length != tupleArgTpes.length &&
+ !isUnitForVarArgs(argtpes0, params) &&
+ isApplicable(undetparams, ftpe, tupleArgTpes, pt)
}
def typesCompatible(argtpes: List[Type]) = {
val restpe = ftpe.resultType(argtpes)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 284b12e501..3fe937f241 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2327,12 +2327,14 @@ trait Typers { self: Analyzer =>
// if 1 formal, 1 arg (a tuple), otherwise unmodified args
val tupleArgs = actualArgs(tree.pos.makeTransparent, args, formals.length)
- if (tupleArgs.length != args.length) {
+ if (tupleArgs.length != args.length && !isUnitForVarArgs(args, params)) {
// expected one argument, but got 0 or >1 ==> try applying to tuple
// the inner "doTypedApply" does "extractUndetparams" => restore when it fails
val savedUndetparams = context.undetparams
silent(_.doTypedApply(tree, fun, tupleArgs, mode, pt)) match {
- case t: Tree => Some(t)
+ case t: Tree =>
+// println("tuple conversion to "+t+" for "+mt)//DEBUG
+ Some(t)
case ex =>
context.undetparams = savedUndetparams
None
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index a60721f0ca..5ba52f5f06 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -134,9 +134,9 @@ trait Unapplies extends ast.TreeDSL
/** The module corresponding to a case class; without any member definitions
*/
def caseModuleDef(cdef: ClassDef): ModuleDef = {
- def inheritFromFun1 = !(cdef.mods hasFlag ABSTRACT) && cdef.tparams.isEmpty && constrParamss(cdef).length == 1
- def createFun1 = gen.scalaFunctionConstr(constrParamss(cdef).head map (_.tpt), toIdent(cdef))
- def parents = if (inheritFromFun1) List(createFun1) else Nil
+ def inheritFromFun = !(cdef.mods hasFlag ABSTRACT) && cdef.tparams.isEmpty && constrParamss(cdef).length == 1
+ def createFun = gen.scalaFunctionConstr(constrParamss(cdef).head map (_.tpt), toIdent(cdef))
+ def parents = if (inheritFromFun) List(createFun) else Nil
companionModuleDef(cdef, parents ::: List(gen.scalaScalaObjectConstr))
}
diff --git a/src/library/scala/native.scala b/src/library/scala/native.scala
index fbacf43b72..8aeffe1632 100644
--- a/src/library/scala/native.scala
+++ b/src/library/scala/native.scala
@@ -11,16 +11,14 @@
package scala
-/**
- * Marker for native methods.
- * <p>
- * <code>@native def f(x: Int, y: List[Long]): String = ..</code>
- * </p>
- * <p>
- * Method body is not generated if method is marked with <code>@native</code>,
- * but it is type checked when present.
- * </p>
- *
- * @since 2.6
- */
+/** Marker for native methods.
+ *
+ * {{{
+ * @native def f(x: Int, y: List[Long]): String = ...
+ * }}}
+ *
+ * Method body is not generated if method is marked with `@native`,
+ * but it is type checked when present.
+ *
+ * @since 2.6 */
class native extends StaticAnnotation {}
diff --git a/src/partest/scala/tools/partest/Actions.scala b/src/partest/scala/tools/partest/Actions.scala
index 48b80cface..15351db2a7 100644
--- a/src/partest/scala/tools/partest/Actions.scala
+++ b/src/partest/scala/tools/partest/Actions.scala
@@ -54,7 +54,7 @@ trait Actions {
proc = Process.exec(toArgs(cmd), execEnv, execCwd.orNull, true)
proc.slurp()
}
- proc.waitFor() == 0
+ proc != null && (proc.waitFor() == 0)
}
result getOrElse {
warning("Process never terminated: '%s'" format cmd)
diff --git a/src/partest/scala/tools/partest/Compilable.scala b/src/partest/scala/tools/partest/Compilable.scala
index c11532f278..d7365c1620 100644
--- a/src/partest/scala/tools/partest/Compilable.scala
+++ b/src/partest/scala/tools/partest/Compilable.scala
@@ -81,7 +81,10 @@ trait PartestCompilation {
class PartestGlobal(settings: Settings, val creporter: ConsoleReporter) extends Global(settings, creporter) {
def partestCompile(files: List[String], printSummary: Boolean): Boolean = {
try { new Run compile files }
- catch { case FatalError(msg) => creporter.error(null, "fatal error: " + msg) }
+ catch {
+ case FatalError(msg) => creporter.error(null, "fatal error: " + msg)
+ case ae: AssertionError => creporter.error(null, ""+ae)
+ }
if (printSummary)
creporter.printSummary
@@ -102,4 +105,4 @@ trait PartestCompilation {
(new PartestGlobal(command.settings, reporter), command.files)
}
}
-} \ No newline at end of file
+}
diff --git a/src/partest/scala/tools/partest/Dispatcher.scala b/src/partest/scala/tools/partest/Dispatcher.scala
index 2c7d9d6a2f..2a9d99ab60 100644
--- a/src/partest/scala/tools/partest/Dispatcher.scala
+++ b/src/partest/scala/tools/partest/Dispatcher.scala
@@ -31,14 +31,14 @@ trait Dispatcher {
val groups = selected groupBy (_.category)
val count = selected.size
- if (count == 0) return CombinedTestResults(0, 0, 0)
+ if (count == 0) return CombinedTestResults(0, 0, 0, Nil)
else if (count == allTests.size) verbose("Running all %d tests." format count)
else verbose("Running %d/%d tests: %s".format(count, allTests.size, toStringTrunc(selected map (_.label) mkString ", ")))
allCategories collect { case x if groups contains x => runCategory(x, groups(x)) } reduceLeft (_ ++ _)
}
- private def parallelizeTests(tests: List[TestEntity]): immutable.Map[TestEntity, Int] = {
+ private def parallelizeTests(tests: List[TestEntity]): immutable.Map[TestEntity, TestResult] = {
// propagate verbosity
if (isDebug) scala.actors.Debug.level = 3
@@ -63,9 +63,9 @@ trait Dispatcher {
case ResultsOfRun(resultMap) => resultMap
case TIMEOUT =>
warning("Worker %d timed out." format w.workerNum)
- immutable.Map[TestEntity, Int]()
// mark all the worker's tests as having timed out - should be hard to miss
- groups(w.workerNum) map (_ -> 2) toMap
+ // immutable.Map[TestEntity, TestResult]()
+ groups(w.workerNum) map (x => (x -> new Timeout(x))) toMap
}
}) reduceLeft (_ ++ _)
}
@@ -75,9 +75,10 @@ trait Dispatcher {
normal("%s (%s tests in %s)\n".format(category.startMessage, tests.size, category))
val (milliSeconds, resultMap) = timed2(parallelizeTests(tests))
- val (passed, failed) = resultsToStatistics(resultMap)
+ val (passed, failed) = resultsToStatistics(resultMap mapValues (_.state))
+ val failures = resultMap.values filterNot (_.passed) toList
- CombinedTestResults(passed, failed, milliSeconds)
+ CombinedTestResults(passed, failed, milliSeconds, failures)
}
/** A Worker is given a bundle of tests and runs them all sequentially.
@@ -92,8 +93,8 @@ trait Dispatcher {
/** Runs the tests. Passes the result Map to onCompletion when done.
*/
- private def runTests(tests: List[TestEntity])(onCompletion: immutable.Map[TestEntity, Int] => Unit) {
- var results = new immutable.HashMap[TestEntity, Int] // maps tests to results
+ private def runTests(tests: List[TestEntity])(onCompletion: immutable.Map[TestEntity, TestResult] => Unit) {
+ var results = new immutable.HashMap[TestEntity, TestResult] // maps tests to results
val numberOfTests = tests.size
val testIterator = tests.iterator
def processed = results.size
@@ -122,7 +123,7 @@ trait Dispatcher {
return warning("Received duplicate result for %s: was %s, now %s".format(test, results(test), state))
// increment the counter for this result state
- results += (test -> state)
+ results += (test -> result)
// show on screen
if (isDryRun) normal("\n") // blank line between dry run traces
diff --git a/src/partest/scala/tools/partest/Results.scala b/src/partest/scala/tools/partest/Results.scala
index 4e0c446788..8078e7bf85 100644
--- a/src/partest/scala/tools/partest/Results.scala
+++ b/src/partest/scala/tools/partest/Results.scala
@@ -16,7 +16,7 @@ trait Results {
/** The response from a Worker who has been given TestsToRun.
*/
- case class ResultsOfRun(results: immutable.Map[TestEntity, Int])
+ case class ResultsOfRun(results: immutable.Map[TestEntity, TestResult])
/** The result of a single test. (0: OK, 1: FAILED, 2: TIMEOUT)
*/
@@ -39,7 +39,7 @@ trait Results {
case _ => false
}
override def hashCode = entity.hashCode
- override def toString = "%s (%s)".format(entity, if (passed) "passed" else "failed")
+ override def toString = "%s [%s]".format(entity, description)
}
class Success(val entity: TestEntity) extends TestResult(0, " OK ") {
@@ -58,6 +58,7 @@ trait Results {
if (isShowLog || isTrace)
normal(toStringTrunc(entity.failureMessage(), 1600))
}
+ override def toString = List(super.toString, toStringTrunc(entity.failureMessage(), 400)) mkString "\n"
}
class Timeout(val entity: TestEntity) extends TestResult(2, "TIME OUT") {
def colorize(s: String) = markFailure(s)
@@ -84,7 +85,8 @@ trait Results {
case class CombinedTestResults(
passed: Int,
failed: Int,
- elapsedMilliseconds: Long
+ elapsedMilliseconds: Long,
+ failures: List[TestResult]
) {
// housekeeping
val elapsedSecs = elapsedMilliseconds / 1000
@@ -100,14 +102,20 @@ trait Results {
def ++(x: CombinedTestResults) = CombinedTestResults(
passed + x.passed,
failed + x.failed,
- elapsedMilliseconds + x.elapsedMilliseconds
+ elapsedMilliseconds + x.elapsedMilliseconds,
+ failures ::: x.failures
)
- def elapsedString = "%02d:%02d:%02d".format(elapsedHrs, dispMins, dispSecs)
+ def elapsedString = "%02d:%02d:%02d".format(elapsedHrs, dispMins, dispSecs)
+ def failuresString = {
+ if (failures.isEmpty) ""
+ else "Summary of failures:" :: failures mkString ("\n", "\n", "")
+ }
+
override def toString =
if (total == 0) "There were no tests to run."
else if (isDryRun) "%d tests would be run." format total
- else if (hasFailures) "%d of %d tests failed (elapsed time: %s)".format(failed, total, elapsedString)
+ else if (hasFailures) "%d of %d tests failed (elapsed time: %s)".format(failed, total, elapsedString) + failuresString
else "All %d tests were successful (elapsed time: %s)".format(total, elapsedString)
}
} \ No newline at end of file
diff --git a/src/partest/scala/tools/partest/io/Logging.scala b/src/partest/scala/tools/partest/io/Logging.scala
index 3d1b0fa0b4..3667faaf3d 100644
--- a/src/partest/scala/tools/partest/io/Logging.scala
+++ b/src/partest/scala/tools/partest/io/Logging.scala
@@ -75,8 +75,9 @@ trait Logging {
def loggingResult(body: => String) =
try returning(true)(_ => logFile writeAll body)
catch {
- case x: ControlThrowable => throw x
- case x: Throwable => logException(x)
+ case x: ControlThrowable => throw x
+ case x: InterruptedException => normal(this + " received interrupt, failing.\n") ; false
+ case x: Throwable => logException(x)
}
def throwableToString(x: Throwable): String = {
diff --git a/test/files/jvm/actor-uncaught-exception2.check b/test/files/jvm/actor-uncaught-exception2.check
new file mode 100644
index 0000000000..870a5d32f9
--- /dev/null
+++ b/test/files/jvm/actor-uncaught-exception2.check
@@ -0,0 +1,2 @@
+UncaughtException(StartError,None,None,MyException: I don't want to run!)
+UncaughtException(MessageError,Some('ping),Some(Supervisor),MyException: No message for me!)
diff --git a/test/files/jvm/actor-uncaught-exception2.scala b/test/files/jvm/actor-uncaught-exception2.scala
new file mode 100644
index 0000000000..973cfb370a
--- /dev/null
+++ b/test/files/jvm/actor-uncaught-exception2.scala
@@ -0,0 +1,48 @@
+import scala.actors.{Actor, Exit, Debug}
+
+class MyException(msg: String) extends Exception(msg) {
+ override def fillInStackTrace() = this
+}
+
+object Test {
+
+ case object StartError extends Actor {
+ def act() {
+ throw new MyException("I don't want to run!")
+ }
+ }
+
+ case object MessageError extends Actor {
+ def act() {
+ react {
+ case _ => throw new MyException("No message for me!")
+ }
+ }
+ }
+
+ case object Supervisor extends Actor {
+ def act() {
+ trapExit = true
+ link(StartError)
+ link(MessageError)
+ StartError.start()
+ MessageError.start()
+
+ Actor.loop {
+ react {
+ case Exit(actor, reason) =>
+ println(reason)
+ if (actor == StartError)
+ MessageError ! 'ping
+ else
+ exit()
+ }
+ }
+ }
+ }
+
+ def main(args: Array[String]) {
+ Debug.level = 1 // decrease level so that it does not print warnings
+ Supervisor.start()
+ }
+}
diff --git a/test/files/neg/t3224.check b/test/files/neg/t3224.check
new file mode 100644
index 0000000000..29304c567a
--- /dev/null
+++ b/test/files/neg/t3224.check
@@ -0,0 +1,6 @@
+t3224.scala:29: error: polymorphic expression cannot be instantiated to expected type;
+ found : [T]Array[T]
+ required: List[?]
+ println(Texts textL Array()); println(Texts textL Array(1)); println(Texts textL Array(1, 1))
+ ^
+one error found
diff --git a/test/files/neg/t3224.scala b/test/files/neg/t3224.scala
new file mode 100755
index 0000000000..0e24baf28a
--- /dev/null
+++ b/test/files/neg/t3224.scala
@@ -0,0 +1,30 @@
+object Texts{
+ def textL[T](list: List[T]) = {
+ list match{
+ case List() => "Empty"
+ case List(_) => "One"
+ case List(_*) => "Many"
+ }
+ }
+
+ def textA[T](array: Array[T]) = {
+ array match{
+ case Array() => "Empty"
+ case Array(_) => "One"
+ case Array(_*) => "Many"
+ }
+ }
+}
+
+object Test extends Application {
+
+ implicit def array2list[T](array: Array[T]) = {
+ println(array.toList.size)
+ array.toList
+ }
+
+
+ println(Texts textL List()); println(Texts textL List(1)); println(Texts textL List(1, 1));
+
+ println(Texts textL Array()); println(Texts textL Array(1)); println(Texts textL Array(1, 1))
+}