summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bincompat-backward.whitelist.conf12
-rw-r--r--bincompat-forward.whitelist.conf4
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala5
-rw-r--r--src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala7
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala66
-rw-r--r--src/library/scala/collection/mutable/FlatHashTable.scala4
-rw-r--r--src/library/scala/collection/mutable/HashTable.scala15
-rw-r--r--src/library/scala/collection/mutable/OpenHashMap.scala4
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala27
-rw-r--r--src/reflect/scala/reflect/internal/pickling/UnPickler.scala2
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/Page.scala27
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/page/Entity.scala10
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala2
-rw-r--r--test/files/neg/no-predef.check8
-rw-r--r--test/files/neg/t2102.check4
-rw-r--r--test/files/neg/type-diagnostics.check4
-rw-r--r--test/files/run/t10171/Test.scala59
-rw-r--r--test/scaladoc/run/inlineToStr-strips-unwanted-text.check1
-rw-r--r--test/scaladoc/run/inlineToStr-strips-unwanted-text.scala58
-rw-r--r--test/scaladoc/run/shortDescription-annotation.scala19
23 files changed, 248 insertions, 96 deletions
diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf
index 9ea78a2977..3d4e40a00d 100644
--- a/bincompat-backward.whitelist.conf
+++ b/bincompat-backward.whitelist.conf
@@ -22,6 +22,18 @@ filter {
problemName=DirectMissingMethodProblem
},
{
+ matchName="scala.collection.mutable.OpenHashMap.nextPositivePowerOfTwo"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.HashTable.nextPositivePowerOfTwo"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.HashTable.powerOfTwo"
+ problemName=DirectMissingMethodProblem
+ },
+ {
matchName="scala.reflect.runtime.JavaMirrors#JavaMirror.unpickleClass"
problemName=IncompatibleMethTypeProblem
},
diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf
index fdd0f0fa22..94b2a57b25 100644
--- a/bincompat-forward.whitelist.conf
+++ b/bincompat-forward.whitelist.conf
@@ -22,6 +22,10 @@ filter {
problemName=DirectMissingMethodProblem
},
{
+ matchName="scala.collection.mutable.HashTable.nextPositivePowerOfTwo"
+ problemName=DirectMissingMethodProblem
+ }
+ {
matchName="scala.reflect.runtime.Settings.Yvirtpatmat"
problemName=DirectMissingMethodProblem
},
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index c1b0733895..819887f959 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -953,10 +953,11 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
definitions.isDefinitionsInitialized
&& rootMirror.isMirrorInitialized
)
- override def isPastTyper = (
+ override def isPastTyper = isPast(currentRun.typerPhase)
+ def isPast(phase: Phase) = (
(curRun ne null)
&& isGlobalInitialized // defense against init order issues
- && (globalPhase.id > currentRun.typerPhase.id)
+ && (globalPhase.id > phase.id)
)
// TODO - trim these to the absolute minimum.
diff --git a/src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala b/src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala
index dfd5b07a3b..c18f220d95 100644
--- a/src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala
+++ b/src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala
@@ -446,9 +446,10 @@ abstract class ScalaPrimitives {
inform(s"Unknown primitive method $cls.$method")
else alts foreach (s =>
addPrimitive(s,
- s.info.paramTypes match {
- case tp :: _ if code == ADD && tp =:= StringTpe => CONCAT
- case _ => code
+ if (code != ADD) code
+ else exitingTyper(s.info).paramTypes match {
+ case tp :: _ if tp =:= StringTpe => CONCAT
+ case _ => code
}
)
)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index 503f64a44f..7a3b8d2ab6 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -62,7 +62,7 @@ trait Contexts { self: Analyzer =>
def warnUnusedImports(unit: CompilationUnit) = if (!unit.isJava) {
for (imps <- allImportInfos.remove(unit)) {
- for (imp <- imps.reverse.distinct) {
+ for (imp <- imps.distinct.reverse) {
val used = allUsedSelectors(imp)
imp.tree.selectors filterNot (s => isMaskImport(s) || used(s)) foreach { sel =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
index 990edcd86d..50743a922a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
@@ -112,7 +112,7 @@ abstract class TreeCheckers extends Analyzer {
else if (prevTrees exists (t => (t eq tree) || (t.symbol == sym)))
()
else {
- val s1 = (prevTrees map wholetreestr).sorted.distinct
+ val s1 = (prevTrees map wholetreestr).distinct.sorted
val s2 = wholetreestr(tree)
if (s1 contains s2) ()
else movedMsgs += ("\n** %s moved:\n** Previously:\n%s\n** Currently:\n%s".format(ownerstr(sym), s1 mkString ", ", s2))
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
index b66dbf21c0..36b9a65334 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
@@ -11,6 +11,7 @@ import scala.collection.mutable.ListBuffer
import scala.util.control.Exception.ultimately
import symtab.Flags._
import PartialFunction._
+import scala.annotation.tailrec
/** An interface to enable higher configurability of diagnostic messages
* regarding type errors. This is barely a beginning as error messages are
@@ -274,19 +275,54 @@ trait TypeDiagnostics {
if (AnyRefTpe <:< req) notAnyRefMessage(found) else ""
}
+ def finalOwners(tpe: Type): Boolean = (tpe.prefix == NoPrefix) || recursivelyFinal(tpe)
+
+ @tailrec
+ final def recursivelyFinal(tpe: Type): Boolean = {
+ val prefix = tpe.prefix
+ if (prefix != NoPrefix) {
+ if (prefix.typeSymbol.isFinal) {
+ recursivelyFinal(prefix)
+ } else {
+ false
+ }
+ } else {
+ true
+ }
+ }
+
// 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
// that condition, I see it.
def foundReqMsg(found: Type, req: Type): String = {
- def baseMessage = (
- ";\n found : " + found.toLongString + existentialContext(found) + explainAlias(found) +
- "\n required: " + req + existentialContext(req) + explainAlias(req)
- )
- ( withDisambiguation(Nil, found, req)(baseMessage)
- + explainVariance(found, req)
- + explainAnyVsAnyRef(found, req)
- )
+ val foundWiden = found.widen
+ val reqWiden = req.widen
+ val sameNamesDifferentPrefixes =
+ foundWiden.typeSymbol.name == reqWiden.typeSymbol.name &&
+ foundWiden.prefix.typeSymbol != reqWiden.prefix.typeSymbol
+ val easilyMistakable =
+ sameNamesDifferentPrefixes &&
+ !req.typeSymbol.isConstant &&
+ finalOwners(foundWiden) && finalOwners(reqWiden) &&
+ !found.typeSymbol.isTypeParameterOrSkolem && !req.typeSymbol.isTypeParameterOrSkolem
+
+ if (easilyMistakable) {
+ val longestNameLength = foundWiden.nameAndArgsString.length max reqWiden.nameAndArgsString.length
+ val paddedFoundName = foundWiden.nameAndArgsString.padTo(longestNameLength, ' ')
+ val paddedReqName = reqWiden.nameAndArgsString.padTo(longestNameLength, ' ')
+ ";\n found : " + (paddedFoundName + s" (in ${found.prefix.typeSymbol.fullNameString}) ") + explainAlias(found) +
+ "\n required: " + (paddedReqName + s" (in ${req.prefix.typeSymbol.fullNameString}) ") + explainAlias(req)
+ } else {
+ def baseMessage = {
+ ";\n found : " + found.toLongString + existentialContext(found) + explainAlias(found) +
+ "\n required: " + req + existentialContext(req) + explainAlias(req)
+ }
+ (withDisambiguation(Nil, found, req)(baseMessage)
+ + explainVariance(found, req)
+ + explainAnyVsAnyRef(found, req)
+ )
+ }
}
def typePatternAdvice(sym: Symbol, ptSym: Symbol) = {
@@ -315,14 +351,6 @@ trait TypeDiagnostics {
def restoreName() = sym.name = savedName
def modifyName(f: String => String) = sym setName newTypeName(f(sym.name.toString))
- /** Prepend java.lang, scala., or Predef. if this type originated
- * in one of those.
- */
- def qualifyDefaultNamespaces() = {
- val intersect = Set(trueOwner, aliasOwner) intersect UnqualifiedOwners
- if (intersect.nonEmpty && tp.typeSymbolDirect.name == tp.typeSymbol.name) preQualify()
- }
-
// functions to manipulate the name
def preQualify() = modifyName(trueOwner.fullName + "." + _)
def postQualify() = if (!(postQualifiedWith contains trueOwner)) { postQualifiedWith ::= trueOwner; modifyName(_ + "(in " + trueOwner + ")") }
@@ -414,12 +442,6 @@ trait TypeDiagnostics {
if (td1 string_== td2)
tds foreach (_.nameQualify())
- // If they have the same simple name, and either of them is in the
- // scala package or predef, qualify with scala so it is not confusing why
- // e.g. java.util.Iterator and Iterator are different types.
- if (td1 name_== td2)
- tds foreach (_.qualifyDefaultNamespaces())
-
// If they still print identically:
// a) If they are type parameters with different owners, append (in <owner>)
// b) Failing that, the best we can do is append "(some other)" to the latter.
diff --git a/src/library/scala/collection/mutable/FlatHashTable.scala b/src/library/scala/collection/mutable/FlatHashTable.scala
index 8c4115b1dd..0d8799282f 100644
--- a/src/library/scala/collection/mutable/FlatHashTable.scala
+++ b/src/library/scala/collection/mutable/FlatHashTable.scala
@@ -47,9 +47,7 @@ trait FlatHashTable[A] extends FlatHashTable.HashUtils[A] {
@transient protected var seedvalue: Int = tableSizeSeed
- import HashTable.powerOfTwo
-
- protected def capacity(expectedSize: Int) = if (expectedSize == 0) 1 else powerOfTwo(expectedSize)
+ protected def capacity(expectedSize: Int) = HashTable.nextPositivePowerOfTwo(expectedSize)
/** The initial size of the hash table.
*/
diff --git a/src/library/scala/collection/mutable/HashTable.scala b/src/library/scala/collection/mutable/HashTable.scala
index 445217ebef..01ec1defad 100644
--- a/src/library/scala/collection/mutable/HashTable.scala
+++ b/src/library/scala/collection/mutable/HashTable.scala
@@ -12,7 +12,7 @@ package scala
package collection
package mutable
-import java.lang.Integer.rotateRight
+import java.lang.Integer.{numberOfLeadingZeros, rotateRight}
import scala.util.hashing.byteswap32
/** This class can be used to construct data structures that are based
@@ -405,7 +405,7 @@ private[collection] object HashTable {
private[collection] final def sizeForThreshold(_loadFactor: Int, thr: Int) = ((thr.toLong * loadFactorDenum) / _loadFactor).toInt
- private[collection] final def capacity(expectedSize: Int) = if (expectedSize == 0) 1 else powerOfTwo(expectedSize)
+ private[collection] final def capacity(expectedSize: Int) = nextPositivePowerOfTwo(expectedSize)
trait HashUtils[KeyType] {
protected final def sizeMapBucketBitSize = 5
@@ -433,16 +433,7 @@ private[collection] object HashTable {
/**
* Returns a power of two >= `target`.
*/
- private[collection] def powerOfTwo(target: Int): Int = {
- /* See http://bits.stephan-brumme.com/roundUpToNextPowerOfTwo.html */
- var c = target - 1
- c |= c >>> 1
- c |= c >>> 2
- c |= c >>> 4
- c |= c >>> 8
- c |= c >>> 16
- c + 1
- }
+ private[collection] def nextPositivePowerOfTwo(target: Int): Int = 1 << -numberOfLeadingZeros(target - 1)
class Contents[A, Entry >: Null <: HashEntry[A, Entry]](
val loadFactor: Int,
diff --git a/src/library/scala/collection/mutable/OpenHashMap.scala b/src/library/scala/collection/mutable/OpenHashMap.scala
index ca08f475ce..b2e9ee27b9 100644
--- a/src/library/scala/collection/mutable/OpenHashMap.scala
+++ b/src/library/scala/collection/mutable/OpenHashMap.scala
@@ -31,8 +31,6 @@ object OpenHashMap {
final private class OpenEntry[Key, Value](var key: Key,
var hash: Int,
var value: Option[Value])
-
- private[mutable] def nextPositivePowerOfTwo(i : Int) = 1 << (32 - Integer.numberOfLeadingZeros(i - 1))
}
/** A mutable hash map based on an open hashing scheme. The precise scheme is
@@ -67,7 +65,7 @@ extends AbstractMap[Key, Value]
override def empty: OpenHashMap[Key, Value] = OpenHashMap.empty[Key, Value]
- private[this] val actualInitialSize = OpenHashMap.nextPositivePowerOfTwo(initialSize)
+ private[this] val actualInitialSize = HashTable.nextPositivePowerOfTwo(initialSize)
private var mask = actualInitialSize - 1
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 890a5796e9..9d71136fc5 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -809,7 +809,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isDerivedValueClass =
isClass && !hasFlag(PACKAGE | TRAIT) &&
- info.firstParent.typeSymbol == AnyValClass && !isPrimitiveValueClass
+ !phase.erasedTypes && info.firstParent.typeSymbol == AnyValClass && !isPrimitiveValueClass
final def isMethodWithExtension =
isMethod && owner.isDerivedValueClass && !isParamAccessor && !isConstructor && !hasFlag(SUPERACCESSOR) && !isMacro && !isSpecialized
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index b46f071717..dc12ef9352 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -967,6 +967,8 @@ trait Types
*/
def directObjectString = safeToString
+ def nameAndArgsString = typeSymbol.name.toString
+
/** A test whether a type contains any unification type variables.
* Overridden with custom logic except where trivially true.
*/
@@ -2321,6 +2323,8 @@ trait Types
private def preString = if (needsPreString) pre.prefixString else ""
private def argsString = if (args.isEmpty) "" else args.mkString("[", ",", "]")
+ override def nameAndArgsString = typeSymbol.name.toString + argsString
+
private def refinementDecls = fullyInitializeScope(decls) filter (sym => sym.isPossibleInRefinement && sym.isPublic)
private def refinementString = (
if (sym.isStructuralRefinement)
@@ -2728,6 +2732,19 @@ trait Types
arg.toString
}
+ override def nameAndArgsString: String = underlying match {
+ case TypeRef(_, sym, args) if !settings.debug && isRepresentableWithWildcards =>
+ sym.name + wildcardArgsString(quantified.toSet, args).mkString("[", ",", "]")
+ case TypeRef(_, sym, args) =>
+ sym.name + args.mkString("[", ",", "]") + existentialClauses
+ case _ => underlying.typeSymbol.name + existentialClauses
+ }
+
+ private def existentialClauses = {
+ val str = quantified map (_.existentialToString) mkString (" forSome { ", "; ", " }")
+ if (settings.explaintypes) "(" + str + ")" else str
+ }
+
/** An existential can only be printed with wildcards if:
* - the underlying type is a typeref
* - every quantified variable appears at most once as a type argument and
@@ -2746,7 +2763,7 @@ trait Types
tpe.typeSymbol.isRefinementClass && (tpe.parents exists isQuantified)
}
val (wildcardArgs, otherArgs) = args partition (arg => qset contains arg.typeSymbol)
- wildcardArgs.distinct == wildcardArgs &&
+ wildcardArgs.toSet.size == wildcardArgs.size &&
!(otherArgs exists (arg => isQuantified(arg))) &&
!(wildcardArgs exists (arg => isQuantified(arg.typeSymbol.info.bounds))) &&
!(qset contains sym) &&
@@ -2756,17 +2773,13 @@ trait Types
}
override def safeToString: String = {
- def clauses = {
- val str = quantified map (_.existentialToString) mkString (" forSome { ", "; ", " }")
- if (settings.explaintypes) "(" + str + ")" else str
- }
underlying match {
case TypeRef(pre, sym, args) if !settings.debug && isRepresentableWithWildcards =>
"" + TypeRef(pre, sym, Nil) + wildcardArgsString(quantified.toSet, args).mkString("[", ", ", "]")
case MethodType(_, _) | NullaryMethodType(_) | PolyType(_, _) =>
- "(" + underlying + ")" + clauses
+ "(" + underlying + ")" + existentialClauses
case _ =>
- "" + underlying + clauses
+ "" + underlying + existentialClauses
}
}
diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
index 08ccac8069..b4152c9b8c 100644
--- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
@@ -377,7 +377,7 @@ abstract class UnPickler {
def readThisType(): Type = {
val sym = readSymbolRef() match {
- case stub: StubSymbol => stub.setFlag(PACKAGE)
+ case stub: StubSymbol => stub.setFlag(PACKAGE | MODULE)
case sym => sym
}
ThisType(sym)
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/Page.scala b/src/scaladoc/scala/tools/nsc/doc/html/Page.scala
index c720c4939f..a84f77919d 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/Page.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/html/Page.scala
@@ -7,7 +7,7 @@ package scala
package tools.nsc.doc.html
import scala.tools.nsc.doc.model._
-import scala.tools.nsc.doc.base.comment
+import scala.tools.nsc.doc.base.comment._
import java.io.{FileOutputStream, File}
import scala.reflect.NameTransformer
import java.nio.channels.Channels
@@ -106,16 +106,21 @@ abstract class Page {
case dtpl: DocTemplateEntity => dtpl.companion.isDefined
case _ => false
}
+}
- protected def inlineToStr(inl: comment.Inline): String = inl match {
- case comment.Chain(items) => items flatMap (inlineToStr(_)) mkString ""
- case comment.Italic(in) => inlineToStr(in)
- case comment.Bold(in) => inlineToStr(in)
- case comment.Underline(in) => inlineToStr(in)
- case comment.Monospace(in) => inlineToStr(in)
- case comment.Text(text) => text
- case comment.Summary(in) => inlineToStr(in)
- case comment.EntityLink(comment.Text(text), _) => text
- case _ => inl.toString
+object Page {
+ def inlineToStr(inl: Inline): String = inl match {
+ case Chain(items) => items flatMap (inlineToStr(_)) mkString ""
+ case Italic(in) => inlineToStr(in)
+ case Bold(in) => inlineToStr(in)
+ case Underline(in) => inlineToStr(in)
+ case Superscript(in) => inlineToStr(in)
+ case Subscript(in) => inlineToStr(in)
+ case Link(raw, title) => inlineToStr(title)
+ case Monospace(in) => inlineToStr(in)
+ case Text(text) => text
+ case Summary(in) => inlineToStr(in)
+ case HtmlTag(tag) => "<[^>]*>".r.replaceAllIn(tag, "")
+ case EntityLink(in, _) => inlineToStr(in)
}
}
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/Entity.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/Entity.scala
index 54bf42bbd5..fb2bf5049f 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/page/Entity.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/html/page/Entity.scala
@@ -90,13 +90,13 @@ trait EntityPage extends HtmlPage {
mbr match {
case dtpl: DocTemplateEntity =>
dtpl.companion.fold(<span class="separator"></span>) { c: DocTemplateEntity =>
- <a class="object" href={relativeLinkTo(c)} title={c.comment.fold("")(com => inlineToStr(com.short))}></a>
+ <a class="object" href={relativeLinkTo(c)} title={c.comment.fold("")(com => Page.inlineToStr(com.short))}></a>
}
case _ => <span class="separator"></span>
}
}
- <a class={mbr.kind} href={relativeLinkTo(mbr)} title={mbr.comment.fold("")(com => inlineToStr(com.short))}></a>
- <a href={relativeLinkTo(mbr)} title={mbr.comment.fold("")(com => inlineToStr(com.short))}>
+ <a class={mbr.kind} href={relativeLinkTo(mbr)} title={mbr.comment.fold("")(com => Page.inlineToStr(com.short))}></a>
+ <a href={relativeLinkTo(mbr)} title={mbr.comment.fold("")(com => Page.inlineToStr(com.short))}>
{mbr.name}
</a>
</li>
@@ -897,7 +897,7 @@ trait EntityPage extends HtmlPage {
}
}
if (!nameLink.isEmpty)
- <a title={mbr.comment.fold("")(c => inlineToStr(c.short))} href={nameLink}>
+ <a title={mbr.comment.fold("")(c => Page.inlineToStr(c.short))} href={nameLink}>
{nameHtml}
</a>
else nameHtml
@@ -1065,7 +1065,7 @@ trait EntityPage extends HtmlPage {
body.blocks flatMap (blockToStr(_)) mkString ""
private def blockToStr(block: comment.Block): String = block match {
- case comment.Paragraph(in) => inlineToStr(in)
+ case comment.Paragraph(in) => Page.inlineToStr(in)
case _ => block.toString
}
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala
index 8f58a7b845..28304e76c7 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala
@@ -87,7 +87,7 @@ class IndexScript(universe: doc.Universe) extends Page {
/** Gets the short description i.e. the first sentence of the docstring */
def shortDesc(mbr: MemberEntity): String = mbr.comment.fold("") { c =>
- inlineToStr(c.short).replaceAll("\n", "")
+ Page.inlineToStr(c.short).replaceAll("\n", "")
}
/** Returns the json representation of the supplied members */
diff --git a/test/files/neg/no-predef.check b/test/files/neg/no-predef.check
index a63d8c5ba5..f5c2e82fe1 100644
--- a/test/files/neg/no-predef.check
+++ b/test/files/neg/no-predef.check
@@ -1,11 +1,11 @@
no-predef.scala:2: error: type mismatch;
- found : scala.Long(5L)
- required: java.lang.Long
+ found : Long (in scala)
+ required: Long (in java.lang)
def f1 = 5L: java.lang.Long
^
no-predef.scala:3: error: type mismatch;
- found : java.lang.Long
- required: scala.Long
+ found : Long (in java.lang)
+ required: Long (in scala)
def f2 = new java.lang.Long(5) : Long
^
no-predef.scala:4: error: value map is not a member of String
diff --git a/test/files/neg/t2102.check b/test/files/neg/t2102.check
index b4f91a5319..6f70839d22 100644
--- a/test/files/neg/t2102.check
+++ b/test/files/neg/t2102.check
@@ -1,6 +1,6 @@
t2102.scala:2: error: type mismatch;
- found : java.util.Iterator[Int]
- required: scala.collection.Iterator[_]
+ found : Iterator[Int] (in java.util)
+ required: Iterator[_] (in scala.collection)
val x: Iterator[_] = new java.util.ArrayList[Int]().iterator
^
one error found
diff --git a/test/files/neg/type-diagnostics.check b/test/files/neg/type-diagnostics.check
index c5e6dec3f8..fd327bcb66 100644
--- a/test/files/neg/type-diagnostics.check
+++ b/test/files/neg/type-diagnostics.check
@@ -1,6 +1,6 @@
type-diagnostics.scala:4: error: type mismatch;
- found : scala.collection.Set[String]
- required: scala.collection.immutable.Set[String]
+ found : Set[String] (in scala.collection)
+ required: Set[String] (in scala.collection.immutable)
def f = Calculator("Hello", binding.keySet: collection.Set[String])
^
type-diagnostics.scala:13: error: type mismatch;
diff --git a/test/files/run/t10171/Test.scala b/test/files/run/t10171/Test.scala
new file mode 100644
index 0000000000..37a2cfc67f
--- /dev/null
+++ b/test/files/run/t10171/Test.scala
@@ -0,0 +1,59 @@
+import scala.tools.partest._
+import java.io.File
+
+object Test extends StoreReporterDirectTest {
+ def code = ???
+
+ def compileCode(code: String) = {
+ val classpath = List(sys.props("partest.lib"), testOutput.path) mkString sys.props("path.separator")
+ compileString(newCompiler("-cp", classpath, "-d", testOutput.path))(code)
+ }
+
+ def library = """
+package a {
+ package b {
+ class C { class D }
+ }
+}
+package z {
+ class Base {
+ type S = String
+ def foo(s: S): a.b.C#D = null
+ }
+ class Sub extends Base {
+ def sub = "sub"
+ }
+}
+ """
+
+ def client = """
+ class Client { new z.Sub().sub }
+ """
+
+ def deleteClass(s: String) = {
+ val f = new File(testOutput.path, s + ".class")
+ assert(f.exists)
+ f.delete()
+ }
+
+ def deletePackage(s: String) = {
+ val f = new File(testOutput.path, s)
+ assert(f.exists)
+ f.delete()
+ }
+
+ def assertNoErrors(): Unit = {
+ assert(storeReporter.infos.isEmpty, storeReporter.infos.mkString("\n"))
+ storeReporter.reset()
+ }
+ def show(): Unit = {
+ compileCode(library)
+ assertNoErrors()
+ deleteClass("a/b/C$D")
+ deleteClass("a/b/C")
+ deletePackage("a/b")
+ compileCode(client)
+ assertNoErrors()
+ }
+}
+
diff --git a/test/scaladoc/run/inlineToStr-strips-unwanted-text.check b/test/scaladoc/run/inlineToStr-strips-unwanted-text.check
new file mode 100644
index 0000000000..619c56180b
--- /dev/null
+++ b/test/scaladoc/run/inlineToStr-strips-unwanted-text.check
@@ -0,0 +1 @@
+Done.
diff --git a/test/scaladoc/run/inlineToStr-strips-unwanted-text.scala b/test/scaladoc/run/inlineToStr-strips-unwanted-text.scala
new file mode 100644
index 0000000000..8faaf1b93d
--- /dev/null
+++ b/test/scaladoc/run/inlineToStr-strips-unwanted-text.scala
@@ -0,0 +1,58 @@
+import scala.tools.nsc.doc.html.Page
+import scala.tools.nsc.doc.model._
+import scala.tools.partest.ScaladocModelTest
+
+object Test extends ScaladocModelTest {
+
+ override def code = """
+ /** This comment contains ^superscript^ */
+ class Foo {
+ /** This comment contains ,,subscript,, */
+ def bar = ???
+
+ /** This comment contains a link [[https://scala.epfl.ch/]] */
+ def baz = ???
+
+ /** This comment contains an <strong>html tag</strong> */
+ def qux = ???
+
+ /** This comment contains a<br> single html tag */
+ def quux = ???
+
+ /** This comment contains nested <strong>html<br> tags</strong> */
+ def quuz = ???
+
+ /** This comment contains a [[corge ,,link with a subscript title,,]] */
+ def corge = ???
+ }
+ """
+ def scaladocSettings = ""
+
+ def testModel(root: Package) = {
+ import scala.tools.nsc.doc.base.comment._
+ import access._
+
+ val foo = root._class("Foo")
+
+ val fooStr = Page.inlineToStr(foo.comment.get.short)
+ assert(fooStr == "This comment contains superscript", fooStr)
+
+ val barStr = Page.inlineToStr(foo._method("bar").comment.get.short)
+ assert(barStr == "This comment contains subscript", barStr)
+
+ val bazStr = Page.inlineToStr(foo._method("baz").comment.get.short)
+ assert(bazStr == "This comment contains a link https://scala.epfl.ch/", bazStr)
+
+ val quxStr = Page.inlineToStr(foo._method("qux").comment.get.short)
+ assert(quxStr == "This comment contains an html tag", quxStr)
+
+ val quuxStr = Page.inlineToStr(foo._method("quux").comment.get.short)
+ assert(quuxStr == "This comment contains a single html tag", quuxStr)
+
+ val quuzStr = Page.inlineToStr(foo._method("quuz").comment.get.short)
+ assert(quuzStr == "This comment contains nested html tags", quuzStr)
+
+ val corgeStr = Page.inlineToStr(foo._method("corge").comment.get.short)
+ assert(corgeStr == "This comment contains a link with a subscript title", corgeStr)
+ }
+}
diff --git a/test/scaladoc/run/shortDescription-annotation.scala b/test/scaladoc/run/shortDescription-annotation.scala
index 0e2950f4f9..4f9a891133 100644
--- a/test/scaladoc/run/shortDescription-annotation.scala
+++ b/test/scaladoc/run/shortDescription-annotation.scala
@@ -1,3 +1,4 @@
+import scala.tools.nsc.doc.html.Page
import scala.tools.nsc.doc.model._
import scala.tools.partest.ScaladocModelTest
@@ -26,30 +27,18 @@ object Test extends ScaladocModelTest {
import scala.tools.nsc.doc.base.comment._
import access._
- def inlineToStr(inl: Inline): String = inl match {
- case Chain(items) => items flatMap (inlineToStr(_)) mkString ""
- case Italic(in) => inlineToStr(in)
- case Bold(in) => inlineToStr(in)
- case Underline(in) => inlineToStr(in)
- case Monospace(in) => inlineToStr(in)
- case Text(text) => text
- case Summary(in) => inlineToStr(in)
- case EntityLink(Text(text), _) => text
- case _ => inl.toString
- }
-
val foo = rootPackage._package("a")._class("Foo")
// Assert that the class has the correct short description
- val classDesc = inlineToStr(foo.comment.get.short)
+ val classDesc = Page.inlineToStr(foo.comment.get.short)
assert(classDesc == "This one should appear", classDesc)
// Assert that the `foo` method has the correct short description
- val fooDesc = inlineToStr(foo._method("foo").comment.get.short)
+ val fooDesc = Page.inlineToStr(foo._method("foo").comment.get.short)
assert(fooDesc == "This comment should appear", fooDesc)
// Assert that the `goo` method has the correct short description
- val gooDesc = inlineToStr(foo._method("goo").comment.get.short)
+ val gooDesc = Page.inlineToStr(foo._method("goo").comment.get.short)
assert(gooDesc == "This comment should appear", gooDesc)
}
}