summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md24
-rw-r--r--bincompat-backward.whitelist.conf12
-rw-r--r--bincompat-forward.whitelist.conf4
-rw-r--r--project/VersionUtil.scala69
-rw-r--r--project/plugins.sbt5
-rw-r--r--scripts/common9
-rwxr-xr-xscripts/jobs/integrate/bootstrap199
-rw-r--r--spec/04-basic-declarations-and-definitions.md9
-rw-r--r--spec/06-expressions.md4
-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/settings/ScalaVersion.scala2
-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/HashMap.scala12
-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/TreeInfo.scala1
-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/pos/t4237.scala15
-rw-r--r--test/files/run/t10171/Test.scala59
-rw-r--r--test/junit/scala/collection/mutable/HashMapTest.scala38
-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
-rwxr-xr-xtools/get-scala-commit-date22
-rw-r--r--tools/get-scala-commit-date.bat9
-rwxr-xr-xtools/get-scala-commit-sha22
-rw-r--r--tools/get-scala-commit-sha.bat9
39 files changed, 481 insertions, 312 deletions
diff --git a/README.md b/README.md
index 5d565a4418..6a9360947f 100644
--- a/README.md
+++ b/README.md
@@ -104,10 +104,13 @@ Core commands:
- `partest` runs partest tests (accepts options, try `partest --help`)
- `publishLocal` publishes a distribution locally (can be used as `scalaVersion` in
other sbt projects)
- - Optionally `set baseVersionSuffix := "abcd123-SNAPSHOT"`
+ - Optionally `set baseVersionSuffix := "-bin-abcd123-SNAPSHOT"`
where `abcd123` is the git hash of the revision being published. You can also
- use something custom like `"mypatch"`. This changes the version number from
- `2.12.0-SNAPSHOT` to something more stable (`2.12.0-abcd123-SNAPSHOT`).
+ use something custom like `"-bin-mypatch"`. This changes the version number from
+ `2.12.2-SNAPSHOT` to something more stable (`2.12.2-bin-abcd123-SNAPSHOT`).
+ - Note that the `-bin` string marks the version binary compatible. Using it in
+ sbt will cause the `scalaBinaryVersion` to be `2.12`. If the version is not
+ binary compatible, we recommend using `-pre`, e.g., `2.13.0-pre-abcd123-SNAPSHOT`.
- Optionally `set publishArtifact in (Compile, packageDoc) in ThisBuild := false`
to skip generating / publishing API docs (speeds up the process).
@@ -199,8 +202,9 @@ CI performs a full bootstrap. The first task, `validate-publish-core`, publishes
a build of your commit to the temporary repository
https://scala-ci.typesafe.com/artifactory/scala-pr-validation-snapshots.
Note that this build is not yet bootstrapped, its bytecode is built using the
-current `starr`. The version number is `2.12.0-abcd123-SNAPSHOT` where `abcd123`
-is the commit hash.
+current `starr`. The version number is `2.12.2-bin-abcd123-SNAPSHOT` where `abcd123`
+is the commit hash. For binary incompatible builds, the version number is
+`2.13.0-pre-abcd123-SNAPSHOT`.
You can use Scala builds in the validation repository locally by adding a resolver
and specifying the corresponding `scalaVersion`:
@@ -208,7 +212,7 @@ and specifying the corresponding `scalaVersion`:
```
$ sbt
> set resolvers += "pr" at "https://scala-ci.typesafe.com/artifactory/scala-pr-validation-snapshots/"
-> set scalaVersion := "2.12.0-abcd123-SNAPSHOT"
+> set scalaVersion := "2.12.2-bin-abcd123-SNAPSHOT"
> console
```
@@ -220,7 +224,7 @@ tested version during CI validation.
The Scala CI builds nightly download releases (including all modules) and publishes
them to the following locations:
- [2.12.x](http://www.scala-lang.org/files/archive/nightly/2.12.x/?C=M;O=D)
- - [2.11.x](http://www.scala-lang.org/files/archive/nightly/2.11.x/?C=M;O=A)
+ - [2.11.x](http://www.scala-lang.org/files/archive/nightly/2.11.x/?C=M;O=D)
The CI also publishes nightly API docs:
- [2.12.x](http://www.scala-lang.org/files/archive/nightly/2.12.x/api/?C=M;O=D)
@@ -228,10 +232,8 @@ The CI also publishes nightly API docs:
- [2.11.x](http://www.scala-lang.org/files/archive/nightly/2.11.x/api/?C=M;O=D)
- [symlink to the latest](http://www.scala-lang.org/files/archive/nightly/2.11.x/api/2.11.x/)
-Note that we currently don't publish nightly (or SNAPSHOT) builds in maven or ivy
-format to any repository. You can track progress on this front at
-[scala-jenkins-infra#133](https://github.com/scala/scala-jenkins-infra/issues/133)
-and [scala-dev#68](https://github.com/scala/scala-dev/issues/68).
+Using a nightly build in sbt is explained in
+[this answer on Stack Overflow](http://stackoverflow.com/questions/40622878)
## Scala CI Internals
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/project/VersionUtil.scala b/project/VersionUtil.scala
index ebc2488345..aacbc78329 100644
--- a/project/VersionUtil.scala
+++ b/project/VersionUtil.scala
@@ -2,8 +2,10 @@ package scala.build
import sbt._
import Keys._
-import java.util.Properties
+import java.util.{Date, Locale, Properties, TimeZone}
import java.io.{File, FileInputStream}
+import java.text.SimpleDateFormat
+
import scala.collection.JavaConverters._
import BuildSettings.autoImport._
@@ -51,19 +53,21 @@ object VersionUtil {
/** Compute the canonical, Maven and OSGi version number from `baseVersion` and `baseVersionSuffix`.
* Examples of the generated versions:
*
- * ("2.11.8", "SNAPSHOT" ) -> ("2.11.8-20151215-133023-7559aed", "2.11.8-SNAPSHOT", "2.11.8.v20151215-133023-7559aed")
- * ("2.11.8", "SHA-SNAPSHOT") -> ("2.11.8-20151215-133023-7559aed", "2.11.8-7559aed-SNAPSHOT", "2.11.8.v20151215-133023-7559aed")
- * ("2.11.8", "SHA-NIGHTLY" ) -> ("2.11.8-7559aed-nightly", "2.11.8-7559aed-nightly", "2.11.8.v20151215-133023-NIGHTLY-7559aed")
- * ("2.11.8", "" ) -> ("2.11.8", "2.11.8", "2.11.8.v20151215-133023-VFINAL-7559aed")
- * ("2.11.8", "M3" ) -> ("2.11.8-M3", "2.11.8-M3", "2.11.8.v20151215-133023-M3-7559aed")
- * ("2.11.8", "RC4" ) -> ("2.11.8-RC4", "2.11.8-RC4", "2.11.8.v20151215-133023-RC4-7559aed")
- * ("2.11.8-RC4", "SPLIT" ) -> ("2.11.8-RC4", "2.11.8-RC4", "2.11.8.v20151215-133023-RC4-7559aed")
+ * ("2.11.8", "SNAPSHOT" ) -> ("2.11.8-20151215-133023-7559aed", "2.11.8-bin-SNAPSHOT", "2.11.8.v20151215-133023-7559aed")
+ * ("2.11.8", "SHA-SNAPSHOT") -> ("2.11.8-20151215-133023-7559aed", "2.11.8-bin-7559aed-SNAPSHOT", "2.11.8.v20151215-133023-7559aed")
+ * ("2.11.8", "SHA" ) -> ("2.11.8-7559aed", "2.11.8-bin-7559aed", "2.11.8.v20151215-133023-7559aed")
+ * ("2.11.0", "SHA" ) -> ("2.11.0-7559aed", "2.11.0-pre-7559aed", "2.11.0.v20151215-133023-7559aed")
+ * ("2.11.8", "" ) -> ("2.11.8", "2.11.8", "2.11.8.v20151215-133023-VFINAL-7559aed")
+ * ("2.11.8", "M3" ) -> ("2.11.8-M3", "2.11.8-M3", "2.11.8.v20151215-133023-M3-7559aed")
+ * ("2.11.8", "RC4" ) -> ("2.11.8-RC4", "2.11.8-RC4", "2.11.8.v20151215-133023-RC4-7559aed")
+ * ("2.11.8-RC4", "SPLIT" ) -> ("2.11.8-RC4", "2.11.8-RC4", "2.11.8.v20151215-133023-RC4-7559aed")
*
* A `baseVersionSuffix` of "SNAPSHOT" is the default, which is used for local snapshot builds. The PR validation
- * job uses "SHA-SNAPSHOT". A proper version number for a nightly build can be computed with "SHA-nightly". An empty
+ * job uses "SHA-SNAPSHOT". A proper version number for an integration build can be computed with "SHA". An empty
* suffix is used for releases. All other suffix values are treated as RC / milestone builds. The special suffix
* value "SPLIT" is used to split the real suffix off from `baseVersion` instead and then apply the usual logic. */
private lazy val versionPropertiesImpl: Def.Initialize[Versions] = Def.setting {
+ val log = sLog.value
val (base, suffix) = {
val (b, s) = (baseVersion.value, baseVersionSuffix.value)
@@ -74,23 +78,44 @@ object VersionUtil {
} else (b, s)
}
- def executeTool(tool: String) = {
- val cmd =
- if (System.getProperty("os.name").toLowerCase.contains("windows"))
- s"cmd.exe /c tools\\$tool.bat -p"
- else s"tools/$tool"
- Process(cmd).lines.head
+ val (dateObj, sha) = {
+ try {
+ // Use JGit to get the commit date and SHA
+ import org.eclipse.jgit.storage.file.FileRepositoryBuilder
+ import org.eclipse.jgit.revwalk.RevWalk
+ val db = new FileRepositoryBuilder().findGitDir.build
+ val head = db.resolve("HEAD")
+ if(head eq null) {
+ log.info("No git HEAD commit found -- Using current date and 'unknown' SHA")
+ (new Date, "unknown")
+ } else {
+ val commit = new RevWalk(db).parseCommit(head)
+ (new Date(commit.getCommitTime.toLong * 1000L), commit.getName.substring(0, 7))
+ }
+ } catch { case ex: Exception =>
+ log.error("Could not determine commit date + SHA: "+ex)
+ log.trace(ex)
+ (new Date, "unknown")
+ }
+ }
+ val date = {
+ val df = new SimpleDateFormat("yyyyMMdd-HHmmss", Locale.ENGLISH)
+ df.setTimeZone(TimeZone.getTimeZone("UTC"))
+ df.format(dateObj)
}
- val date = executeTool("get-scala-commit-date")
- val sha = executeTool("get-scala-commit-sha").substring(0, 7)
+ val Patch = """\d+\.\d+\.(\d+)""".r
+ def cross = base match {
+ case Patch(p) if p.toInt > 0 => "bin"
+ case _ => "pre"
+ }
val (canonicalV, mavenSuffix, osgiV, release) = suffix match {
- case "SNAPSHOT" => (s"$base-$date-$sha", s"-SNAPSHOT", s"$base.v$date-$sha", false)
- case "SHA-SNAPSHOT" => (s"$base-$date-$sha", s"-$sha-SNAPSHOT", s"$base.v$date-$sha", false)
- case "SHA-NIGHTLY" => (s"$base-$sha-nightly", s"-$sha-nightly", s"$base.v$date-NIGHTLY-$sha", true)
- case "" => (s"$base", "", s"$base.v$date-VFINAL-$sha", true)
- case suffix => (s"$base-$suffix", s"-$suffix", s"$base.v$date-$suffix-$sha", true)
+ case "SNAPSHOT" => (s"$base-$date-$sha", s"-$cross-SNAPSHOT", s"$base.v$date-$sha", false)
+ case "SHA-SNAPSHOT" => (s"$base-$date-$sha", s"-$cross-$sha-SNAPSHOT", s"$base.v$date-$sha", false)
+ case "SHA" => (s"$base-$sha", s"-$cross-$sha", s"$base.v$date-$sha", false)
+ case "" => (s"$base", "", s"$base.v$date-VFINAL-$sha", true)
+ case suffix => (s"$base-$suffix", s"-$suffix", s"$base.v$date-$suffix-$sha", true)
}
Versions(canonicalV, base, mavenSuffix, osgiV, sha, date, release)
diff --git a/project/plugins.sbt b/project/plugins.sbt
index ca80c88a9e..58e2d6cdad 100644
--- a/project/plugins.sbt
+++ b/project/plugins.sbt
@@ -21,6 +21,11 @@ buildInfoPackage := "scalabuild"
libraryDependencies += "com.typesafe" %% "mima-reporter" % "0.1.13"
+libraryDependencies ++= Seq(
+ "org.eclipse.jgit" % "org.eclipse.jgit" % "4.6.0.201612231935-r",
+ "org.slf4j" % "slf4j-nop" % "1.7.23"
+)
+
concurrentRestrictions in Global := Seq(
Tags.limitAll(1) // workaround for https://github.com/sbt/sbt/issues/2970
)
diff --git a/scripts/common b/scripts/common
index cd9d874cf7..c68a80fd74 100644
--- a/scripts/common
+++ b/scripts/common
@@ -156,15 +156,16 @@ EOF
}
# Generate a repositories file with all allowed repositories in our build environment.
-# Takes one optional argument, the private repository URL.
+# Takes a variable number of additional repositories as argument.
# See http://www.scala-sbt.org/0.13/docs/Proxy-Repositories.html
function generateRepositoriesConfig() {
jcenterCacheUrl=${jcenterCacheUrl-"https://scala-ci.typesafe.com/artifactory/jcenter/"}
sbtRepositoryConfig="$scriptsDir/sbt-repositories-config"
echo > "$sbtRepositoryConfig" '[repositories]'
- if [ -n "$1" ]
- then
- echo >> "$sbtRepositoryConfig" " private-repo: $1"
+ if [[ $# -gt 0 ]]; then
+ for i in $(seq 1 $#); do
+ echo >> "$sbtRepositoryConfig" " script-repo-$i: ${!i}"
+ done
fi
cat >> "$sbtRepositoryConfig" << EOF
jcenter-cache: $jcenterCacheUrl
diff --git a/scripts/jobs/integrate/bootstrap b/scripts/jobs/integrate/bootstrap
index 71936abf71..a071f3c45f 100755
--- a/scripts/jobs/integrate/bootstrap
+++ b/scripts/jobs/integrate/bootstrap
@@ -3,16 +3,13 @@
# Script Overview
# - determine scala version
# - determine module versions
-# - build minimal core (aka locker) of Scala, use the determined version number, publish to private-repo
-# - build those modules where a binary compatible version doesn't exist, publish to private-repo
-# - build Scala using the previously built core and bootstrap modules, publish to private-repo (overwrites the minimal core version on private-repo)
-# - for releases (not nightlies)
+# - build minimal core (aka locker) of Scala, use the determined version number, publish to scala-release-temp
+# - build those modules where a binary compatible version doesn't exist, publish to scala-integration
+# - build Scala using the previously built core and bootstrap modules, publish to scala-integration
+# - for releases
# - stage Scala on sonatype
# - rebuild modules that needed a rebuild with this Scala build, and stage them on sonatype
-# - for nightlies
-# - force rebuild all modules and publish them locally (for testing purposes)
# - the Scala version is serialized to jenkins.properties, which is passed downstream to scala-release jobs
-# - this removes the need to tag scala/scala-dist (it's still encouraged for releases, but not a hard requirement)
# Specifying the Scala version:
@@ -21,21 +18,16 @@
# - Or have the current HEAD tagged as v$base$suffix
# - To prevent staging on sonatype (for testing), set publishToSonatype to anything but "yes"
# - Note: After building a release, the jenkins job provides an updated versions.properties file as artifact.
-# Put this file in the Scala repo and create a pull request, and also update the file build.number.
+# Put this file in the Scala repo and create a pull request, also update `baseVersion in Global` in build.sbt.
#
-# - Otherwise, a nightly release is built:
-# - version number is read from the build.number file, extended with -$sha-nightly
+# - Otherwise, an integration build is performed:
+# - version number is read from the build.sbt, extended with -[bin|pre]-$sha
-# Specifying module versions: there are two modes
-# - If moduleVersioning="versions.properties" (default): in this mode we use release versions for the modules.
-# - Module versions are read from the versions.properties file.
-# - Set <MODULE>_VER to override the default, e.g. XML_VER="1.0.4".
-# - The git revision is set to <MODULE>_REF="v$<MODULE>_VER". Make sure the tag exists (you can't override <MODULE>_REF).
-#
-# - Otherwise (moduleVersioning has some other value): in this mode we use nightly version numbers for modules.
-# - By default the script sets all <MODULE>_REF to "HEAD", override to build a specific revision.
-# - The <MODULE>_VER is set to a nightly version, for example "1.0.3-7-g14888a2-nightly" (you can't override <MODULE>_VER)
+# Specifying module versions. We use release versions for modules.
+# - Module versions are read from the versions.properties file.
+# - Set <MODULE>_VER to override the default, e.g. XML_VER="1.0.4".
+# - The git revision is set to <MODULE>_REF="v$<MODULE>_VER". Make sure the tag exists (you can't override <MODULE>_REF).
# Modules are automatically built if necessary.
@@ -56,7 +48,7 @@
# to be re-built using the 2.11.1 release, we could not use 2.11.0. We could also not release the modules
# after 2.11.1 was out, because that way the scala-library-all pom of 2.11.1 would depend on the old modules.
#
-# (*) https://github.com/sbt/sbt/blob/0.13.8/util/cross/src/main/input_sources/CrossVersionUtil.scala#L39
+# (*) https://github.com/sbt/sbt/blob/v0.13.13/util/cross/src/main/input_sources/CrossVersionUtil.scala#L41
# Binary incompatible changes in Modules: example with Scala 2.11 / 2.12 and scala-parser-combinators
@@ -82,8 +74,6 @@
# Note: private-repo used to be private-repo.typesafe.com. now we're running artifactory on scala-ci.typesafe.com/artifactory
-moduleVersioning=${moduleVersioning-"versions.properties"}
-
publishPrivateTask=${publishPrivateTask-"publish"}
publishSonatypeTaskCore=${publishSonatypeTaskCore-"publishSigned"}
publishSonatypeTaskModules=${publishSonatypeTaskModules-"publishSigned"}
@@ -108,10 +98,21 @@ mkdir -p $baseDir/ivy2
rm -rf $baseDir/resolutionScratch_
mkdir -p $baseDir/resolutionScratch_
-# repo used to publish "locker" scala to (to start the bootstrap)
-releaseTempRepoCred="private-repo"
+# repo for the starr and locker builds
releaseTempRepoUrl=${releaseTempRepoUrl-"https://scala-ci.typesafe.com/artifactory/scala-release-temp/"}
-generateRepositoriesConfig $releaseTempRepoUrl
+# repo for the modules and the quick build
+integrationRepoUrl=${integrationRepoUrl-"https://scala-ci.typesafe.com/artifactory/scala-integration/"}
+
+# the `releaseTempRepoUrl` needs to be in the repositories file to get starr when building quick and the modules.
+# `integrationRepoUrl` is there to find modules when building quick and other modules (e.g., partest requires xml).
+# the file is re-generated for running the stability test, this time with only `integrationRepoUrl`.
+generateRepositoriesConfig $releaseTempRepoUrl $integrationRepoUrl
+
+# ARGH trying to get this to work on multiple versions of sbt-extras...
+# the old version (on jenkins, and I don't want to upgrade for risk of breaking other builds) honors -sbt-dir
+# the new version of sbt-extras ignores sbt-dir, so we pass it in as -Dsbt.global.base
+# need to set sbt-dir to one that has the gpg.sbt plugin config
+sbtArgs="-ivy $baseDir/ivy2 -Dsbt.override.build.repos=true -Dsbt.repository.config=$sbtRepositoryConfig -Dsbt.global.base=$HOME/.sbt/0.13 -sbt-dir $HOME/.sbt/0.13"
##### git
gfxd() {
@@ -155,12 +156,7 @@ function st_stagingRepoClose() {
echo "{\"data\":{\"description\":\"$message\",\"stagedRepositoryIds\":[\"$repo\"]}}" | st_curl -X POST -d @- "$stApi/staging/bulk/close"
}
-
-# ARGH trying to get this to work on multiple versions of sbt-extras...
-# the old version (on jenkins, and I don't want to upgrade for risk of breaking other builds) honors -sbt-dir
-# the new version of sbt-extras ignores sbt-dir, so we pass it in as -Dsbt.global.base
-# need to set sbt-dir to one that has the gpg.sbt plugin config
-sbtArgs="-ivy $baseDir/ivy2 -Dsbt.override.build.repos=true -Dsbt.repository.config=$sbtRepositoryConfig -Dsbt.global.base=$HOME/.sbt/0.13 -sbt-dir $HOME/.sbt/0.13"
+#### sbt tools
sbtBuild() {
echo "### sbtBuild: "$SBT_CMD -no-colors $sbtArgs "${scalaVersionTasks[@]}" "${publishTasks[@]}" "$@"
@@ -184,15 +180,15 @@ sbtResolve() {
# then set the version to the right one and publish (which won't re-gen the docs).
# Also tried publish-local without docs using 'set publishArtifact in (Compile, packageDoc) := false' and republishing, no dice.
-# Each buildModule() function is invoked twice: first to build against locker and publish to private-repo, then
+# Each buildModule() function is invoked twice: first to build against locker and publish to artifactory, then
# to build against the release and publish to sonatype (or publish-local if publishToSonatype is not "yes").
-# In the second round, sbtResolve is always true: the module will be found in the private-repo!
+# In the second round, sbtResolve is always true: the module will be found in the artifactory!
# Therefore, if MODULE_BUILT is "yes" (in the second round), we know that we need to build (and publish) the
# module again.
#
-# Note: we tried an alternative solution in which sbtResolve would not look at private-repo, but that fails. For example,
+# Note: we tried an alternative solution in which sbtResolve would not look at artifactory, but that fails. For example,
# scala-xml depends on scala-library, so sbt tries to find the scala-library of the version that we are currently building,
-# which exists only in private-repo.
+# which exists only in artifactory.
docTask() {
if [[ "$STARR_REF" != "" && "$1" != "yes" ]]; then
@@ -226,7 +222,7 @@ buildPartest() {
fi
}
-# should only be called with publishTasks publishing to private-repo
+# should only be called with publishTasks publishing to artifactory
buildScalaCheck(){
if [ "$SCALACHECK_BUILT" != "yes" ] && [ "$forceRebuild" != "yes" ] && ( sbtResolve "org.scalacheck" "scalacheck" $SCALACHECK_VER )
then echo "Found scalacheck $SCALACHECK_VER; not building."
@@ -238,9 +234,9 @@ buildScalaCheck(){
fi
}
-# build modules, using ${buildTasks[@]} (except for ScalaCheck, which is hard-coded to publish to private-repo)
+# build modules, using ${buildTasks[@]} (except for ScalaCheck, which is hard-coded to publish to artifactory)
buildModules() {
- publishTasks=('set credentials += Credentials(Path.userHome / ".credentials-private-repo")' "set every publishTo := Some(\"private-repo\" at \"$releaseTempRepoUrl\")")
+ publishTasks=('set credentials += Credentials(Path.userHome / ".credentials-private-repo")' "set every publishTo := Some(\"publish-repo\" at \"$integrationRepoUrl\")")
buildTasks=($publishPrivateTask)
buildXML
# buildScalaCheck
@@ -267,20 +263,19 @@ scalaVerToBinary() {
local patch="$(echo $2 | sed -e "s#$RE#\3#")"
# The binary version is majMin (e.g. "2.12") if
- # - there's no suffix : 2.12.0, 2.12.1
- # - the suffix starts with "-bin": 2.12.0-bin-M1
- # - the patch version is > 0 : 2.12.1-M1, 1.12.3-RC2, 2.12.1-sha-nightly, 2.12.2-SNAPSHOT
+ # - there's no suffix : 2.12.0, 2.12.1
+ # - the suffix starts with "-bin" : 2.12.1-bin-sha, 2.12.1-bin-sha-custom, 2.12.1-bin-SNAPSHOT
+ # - the suffix is \w+ and patch version is > 0: 2.12.1-M1, 2.12.1-RC2 (also 2.12.1-sha, 2.12.1-SNAPSHOT, which we don't use)
#
- # Otherwise, the binary version is the full version: 2.12.0-M1, 2.12.0-RC2, 2.12.0-sha-nightly, 2.12.0-SNAPSHOT
+ # Otherwise, the binary version is the full version: 2.12.0-M1, 2.12.0-RC2, 2.12.0-pre-sha, 2.12.0-pre-SNAPSHOT
+ # (also 2.12.0-sha, 2.12.0-SNAPSHOT, which we don't use)
#
- # Adapted from sbt: https://github.com/sbt/sbt/blob/0.13.8/util/cross/src/main/input_sources/CrossVersionUtil.scala#L39
+ # Adapted from sbt: https://github.com/sbt/sbt/blob/v0.13.13/util/cross/src/main/input_sources/CrossVersionUtil.scala#L42
#
- # Note: during the pre-release cycle of a major release (e.g. before 2.12.0), the SCALA_BINARY_VER of nightly / SNAPSHOT
- # versions is the full version, e.g. 2.12.0-sha-nightly, so modules are always re-built. This is in line with what sbt
- # does: for example, with scalaVersion := "2.12.0-SNAPSHOT", sbt will resolve scala-xml as scala-xml_2.12.0-SNAPSHOT.
- # Once the 2.12.0 release is out, the binary version is 2.12 for all versions (e.g. for 2.12.1-sha-nightly).
+ # During the pre-release cycle of a major release (e.g. before 2.12.0), the SCALA_BINARY_VER of integration / SNAPSHOT
+ # versions is the full version, e.g. 2.12.0-pre-sha, so modules are always re-built.
- if [[ "$3" == "" || "${3:0:4}" == "-bin" || "$patch" != "0" ]]; then
+ if [[ "$3" == "" || "${3:0:4}" == "-bin" || ("$patch" != "0" && "$3" =~ ^-[a-zA-Z0-9_]+$) ]]; then
echo "$majMin"
else
echo "$1"
@@ -291,7 +286,7 @@ determineScalaVersion() {
cd $WORKSPACE
parseScalaProperties "versions.properties"
- # each of the branches below defines the following vars: SCALA_VER_BASE, SCALA_VER_SUFFIX, SCALADOC_SOURCE_LINKS_VER, publishToSonatype
+ # each of the branches below defines the following vars: SCALA_VER_BASE, SCALA_VER_SUFFIX, publishToSonatype
if [ -z "$SCALA_VER_BASE" ]; then
echo "No SCALA_VER_BASE specified."
@@ -299,12 +294,11 @@ determineScalaVersion() {
if [ -z "$scalaTag" ]
then
- echo "No tag found, building nightly snapshot."
- $SBT_CMD $sbtArgs 'set baseVersionSuffix in Global := "SHA-NIGHTLY"' generateBuildCharacterPropertiesFile
+ echo "No tag found, running an integration build."
+ $SBT_CMD $sbtArgs 'set baseVersionSuffix in Global := "SHA"' generateBuildCharacterPropertiesFile
parseScalaProperties "buildcharacter.properties"
SCALA_VER_BASE="$maven_version_base"
SCALA_VER_SUFFIX="$maven_version_suffix"
- SCALADOC_SOURCE_LINKS_VER=$(git rev-parse HEAD)
# TODO: publish nightly snapshot using this script - currently it's a separate jenkins job still running at EPFL.
publishToSonatype="no"
@@ -314,7 +308,6 @@ determineScalaVersion() {
local RE='v*\([0-9]*\)[.]\([0-9]*\)[.]\([0-9]*\)\([0-9A-Za-z-]*\)' # don't change this to make it more accurate, it's not worth it
SCALA_VER_BASE="$(echo $scalaTag | sed -e "s#$RE#\1.\2.\3#")"
SCALA_VER_SUFFIX="$(echo $scalaTag | sed -e "s#$RE#\4#")"
- SCALADOC_SOURCE_LINKS_VER=$scalaTag
if [ "$SCALA_VER_BASE" == "$scalaTag" ]; then
echo "Could not parse version $scalaTag"
@@ -324,8 +317,6 @@ determineScalaVersion() {
fi
else
publishToSonatype=${publishToSonatype-"yes"} # unless forced previously, publish
- # if version base/suffix are provided, we assume a corresponding tag exists for the scaladoc source links
- SCALADOC_SOURCE_LINKS_VER="v$SCALA_VER_BASE$SCALA_VER_SUFFIX"
fi
SCALA_VER="$SCALA_VER_BASE$SCALA_VER_SUFFIX"
@@ -339,39 +330,16 @@ determineScalaVersion() {
echo "Building Scala $SCALA_VER."
}
-deriveVersion() {
- update $1 $2 $3 &> /dev/null
- echo "$(git describe --tag --match=v* | cut -dv -f2)-nightly"
-}
-
-deriveVersionAnyTag() {
- update $1 $2 $3 &> /dev/null
- echo "$(git describe --tag | cut -dv -f2)-nightly"
-}
-
-# determineScalaVersion must have been called
+# determineScalaVersion must have been called (versions.properties is parsed to env vars)
deriveModuleVersions() {
- if [ "$moduleVersioning" == "versions.properties" ]; then
- # use versions.properties as defaults when no version specified on the command line
- XML_VER=${XML_VER-$scala_xml_version_number}
- PARTEST_VER=${PARTEST_VER-$partest_version_number}
- SCALACHECK_VER=${SCALACHECK_VER-$scalacheck_version_number}
-
- XML_REF="v$XML_VER"
- PARTEST_REF="v$PARTEST_VER"
- SCALACHECK_REF="$SCALACHECK_VER" # no `v` in their tags
- else
- # use HEAD as default when no revision is specified on the command line
- XML_REF=${XML_REF-"HEAD"}
- PARTEST_REF=${PARTEST_REF-"HEAD"}
- SCALACHECK_REF=${SCALACHECK_REF-"HEAD"}
-
- XML_VER=$(deriveVersion scala scala-xml "$XML_REF")
- PARTEST_VER=$(deriveVersion scala scala-partest "$PARTEST_REF")
- SCALACHECK_VER=$(deriveVersionAnyTag rickynils scalacheck "$SCALACHECK_REF")
- fi
+ XML_VER=${XML_VER-$scala_xml_version_number}
+ PARTEST_VER=${PARTEST_VER-$partest_version_number}
+ SCALACHECK_VER=${SCALACHECK_VER-$scalacheck_version_number}
+
+ XML_REF="v$XML_VER"
+ PARTEST_REF="v$PARTEST_VER"
+ SCALACHECK_REF="$SCALACHECK_VER" # no `v` in their tags
- echo "Module versions (versioning strategy: $moduleVersioning):"
echo "PARTEST = $PARTEST_VER at $PARTEST_REF"
# echo "SCALACHECK = $SCALACHECK_VER at $SCALACHECK_REF"
echo "XML = $XML_VER at $XML_REF"
@@ -385,30 +353,39 @@ createNetrcFile() {
grep 'password=' $1 | sed 's/password=\(.*\)/password \1/' >> $netrcFile
}
+# deletes existing artifacts (core and modules) matching the $SCALA_VER from the repository passed as argument
removeExistingBuilds() {
- createNetrcFile "$HOME/.credentials-private-repo"
- local netrcFile="$HOME/.credentials-private-repo-netrc"
-
- local storageApiUrl=`echo $releaseTempRepoUrl | sed 's/\(scala-release-temp\)/api\/storage\/\1/'`
- local scalaLangModules=`curl -s $storageApiUrl/org/scala-lang | jq -r '.children | .[] | "org/scala-lang" + .uri' | grep -v actors-migration`
-
- for module in $scalaLangModules; do
- local artifacts=`curl -s $storageApiUrl/$module | jq -r ".children | .[] | select(.uri | endswith(\"$SCALA_VER\")) | .uri"`
- for artifact in $artifacts; do
- echo "Deleting $releaseTempRepoUrl$module$artifact"
- curl -s --netrc-file $netrcFile -X DELETE $releaseTempRepoUrl$module$artifact
+ local repoUrl=$1
+ local repoPrefix="https://scala-ci.typesafe.com/artifactory/"
+ if [[ $repoUrl == "$repoPrefix"* ]]; then
+ local repoId=${1#$repoPrefix}
+ local storageApiUrl="${repoPrefix}api/storage/$repoId"
+
+ createNetrcFile "$HOME/.credentials-private-repo"
+ local netrcFile="$HOME/.credentials-private-repo-netrc"
+
+ # "module" is not a scala module (like scala-xml), but an artifact of a boostrap build. the variable
+ # contains: "org/scala-lang/modules", "org/scala-lang/scala-compiler", "org/scala-lang/scala-library", ...
+ local scalaLangModules=`curl -s $storageApiUrl/org/scala-lang | jq -r '.children | .[] | "org/scala-lang" + .uri' | grep -v actors-migration`
+
+ for module in $scalaLangModules; do
+ local artifacts=`curl -s $storageApiUrl/$module | jq -r ".children | .[] | select(.uri | endswith(\"$SCALA_VER\")) | .uri"`
+ for artifact in $artifacts; do
+ echo "Deleting $repoUrl$module$artifact"
+ curl -s --netrc-file $netrcFile -X DELETE $repoUrl$module$artifact
+ done
done
- done
+ else
+ echo "Unknown repo, not deleting anything: $repoUrl"
+ fi
}
constructUpdatedModuleVersions() {
updatedModuleVersions=()
- # force the new module versions for building the core. these may be different from the values in versions.properties,
- # either because the variables (XML_VER) were provided, or because we're building the modules from HEAD.
- # in the common case, the values are the same as in versions.properties.
+ # force the new module versions for building the core. these may be different from the values in versions.properties
+ # if the variables (XML_VER) were provided. in the common case, the values are the same as in versions.properties.
updatedModuleVersions=("${updatedModuleVersions[@]}" "-Dscala-xml.version.number=$XML_VER")
-
updatedModuleVersions=("${updatedModuleVersions[@]}" "-Dpartest.version.number=$PARTEST_VER")
# updatedModuleVersions=("${updatedModuleVersions[@]}" "-Dscalacheck.version.number=$SCALACHECK_VER")
@@ -418,7 +395,7 @@ constructUpdatedModuleVersions() {
if [ ! -z "$SCALA_BINARY_VER" ]; then updatedModuleVersions=("${updatedModuleVersions[@]}" "-Dscala.binary.version=$SCALA_BINARY_VER"); fi
}
-# build locker (scala + modules) and quick, publishing everything to private-repo
+# build locker (scala + modules) and quick, publishing everything to artifactory
bootstrap() {
echo "### Bootstrapping"
@@ -429,7 +406,7 @@ bootstrap() {
echo "### Building STARR"
STARR_DIR=./scala-starr
- STARR_VER_SUFFIX="-$(git rev-parse --short $STARR_REF)-nightly"
+ STARR_VER_SUFFIX="-$(git rev-parse --short $STARR_REF)-starr"
STARR_VER=$SCALA_VER_BASE$STARR_VER_SUFFIX
rm -rf "$STARR_DIR"
(
@@ -472,8 +449,6 @@ bootstrap() {
# Rebuild Scala with these modules so that all binary versions are consistent.
# Update versions.properties to new modules.
# Sanity check: make sure the Scala test suite passes / docs can be generated with these modules.
- # don't skip locker (-Dlocker.skip=1), or stability will fail
- # overwrite "locker" version of scala at private-repo with bootstrapped version
cd $baseDir
rm -rf build/
@@ -481,7 +456,7 @@ bootstrap() {
--warn \
-Dstarr.version=$SCALA_VER \
${updatedModuleVersions[@]} \
- "setupBootstrapQuick $releaseTempRepoUrl $SCALA_VER" \
+ "setupBootstrapQuick $integrationRepoUrl $SCALA_VER" \
$clean \
$sbtBuildTask \
dist/mkQuick \
@@ -506,7 +481,7 @@ testStability() {
--warn \
-Dstarr.version=$SCALA_VER \
${updatedModuleVersions[@]} \
- "setupBootstrapQuick $releaseTempRepoUrl $SCALA_VER" \
+ "setupBootstrapQuick $integrationRepoUrl $SCALA_VER" \
$clean \
dist/mkQuick
mv build/quick build/strap
@@ -526,7 +501,7 @@ publishSonatype() {
--warn \
-Dstarr.version=$SCALA_VER \
${updatedModuleVersions[@]} \
- "setupBootstrapPublish $releaseTempRepoUrl $SCALA_VER" \
+ "setupBootstrapPublish $integrationRepoUrl $SCALA_VER" \
$publishSonatypeTaskCore
echo "### Publishing modules to sonatype"
@@ -554,10 +529,14 @@ determineScalaVersion
deriveModuleVersions
-removeExistingBuilds
+removeExistingBuilds $integrationRepoUrl
+removeExistingBuilds $releaseTempRepoUrl
bootstrap
+# for stability testing and sonatype publishing, use artifacts in `integrationRepoUrl`
+generateRepositoriesConfig $integrationRepoUrl
+
if [ "$testStability" == "yes" ]
then testStability
fi
diff --git a/spec/04-basic-declarations-and-definitions.md b/spec/04-basic-declarations-and-definitions.md
index 53b34dedc5..c4d3425fff 100644
--- a/spec/04-basic-declarations-and-definitions.md
+++ b/spec/04-basic-declarations-and-definitions.md
@@ -669,6 +669,15 @@ def f(a: Int = 0)(b: Int = a + 1) = b // OK
f(10)() // returns 11 (not 1)
```
+If an [implicit argument](07-implicits.html#implicit-parameters)
+is not found by implicit search, it may be supplied using a default argument.
+
+```scala
+implicit val i: Int = 2
+def f(implicit x: Int, s: String = "hi") = s * x
+f // "hihi"
+```
+
### By-Name Parameters
```ebnf
diff --git a/spec/06-expressions.md b/spec/06-expressions.md
index 48cff1725a..581170c5f9 100644
--- a/spec/06-expressions.md
+++ b/spec/06-expressions.md
@@ -320,7 +320,7 @@ would not typecheck.
### Named and Default Arguments
-If an application might uses named arguments $p = e$ or default
+If an application is to use named arguments $p = e$ or default
arguments, the following conditions must hold.
- For every named argument $p_i = e_i$ which appears left of a positional argument
@@ -330,7 +330,7 @@ arguments, the following conditions must hold.
argument defines a parameter which is already specified by a
positional argument.
- Every formal parameter $p_j:T_j$ which is not specified by either a positional
- or a named argument has a default argument.
+ or named argument has a default argument.
If the application uses named or default
arguments the following transformation is applied to convert it into
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/settings/ScalaVersion.scala b/src/compiler/scala/tools/nsc/settings/ScalaVersion.scala
index 0b051ef89d..c38de753c8 100644
--- a/src/compiler/scala/tools/nsc/settings/ScalaVersion.scala
+++ b/src/compiler/scala/tools/nsc/settings/ScalaVersion.scala
@@ -127,7 +127,7 @@ abstract class ScalaBuild extends Ordered[ScalaBuild] {
def unparse: String
}
/**
- * A development, test, nightly, snapshot or other "unofficial" build
+ * A development, test, integration, snapshot or other "unofficial" build
*/
case class Development(id: String) extends ScalaBuild {
def unparse = s"-${id}"
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/HashMap.scala b/src/library/scala/collection/mutable/HashMap.scala
index 11ff1f0893..de61ebb796 100644
--- a/src/library/scala/collection/mutable/HashMap.scala
+++ b/src/library/scala/collection/mutable/HashMap.scala
@@ -73,10 +73,18 @@ extends AbstractMap[A, B]
}
override def getOrElseUpdate(key: A, defaultValue: => B): B = {
- val i = index(elemHashCode(key))
+ val hash = elemHashCode(key)
+ val i = index(hash)
val entry = findEntry(key, i)
if (entry != null) entry.value
- else addEntry(createNewEntry(key, defaultValue), i)
+ else {
+ val table0 = table
+ val default = defaultValue
+ // Avoid recomputing index if the `defaultValue()` hasn't triggered
+ // a table resize.
+ val newEntryIndex = if (table0 eq table) i else index(hash)
+ addEntry(createNewEntry(key, default), newEntryIndex)
+ }
}
/* inlined HashTable.findEntry0 to preserve its visibility */
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/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 1aef30819a..933afbea2b 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -274,6 +274,7 @@ abstract class TreeInfo {
def mayBeVarGetter(sym: Symbol): Boolean = sym.info match {
case NullaryMethodType(_) => sym.owner.isClass && !sym.isStable
case PolyType(_, NullaryMethodType(_)) => sym.owner.isClass && !sym.isStable
+ case PolyType(_, mt @ MethodType(_, _))=> mt.isImplicit && sym.owner.isClass && !sym.isStable
case mt @ MethodType(_, _) => mt.isImplicit && sym.owner.isClass && !sym.isStable
case _ => false
}
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/pos/t4237.scala b/test/files/pos/t4237.scala
index fcf6eb8bf1..3f605607b2 100644
--- a/test/files/pos/t4237.scala
+++ b/test/files/pos/t4237.scala
@@ -2,5 +2,16 @@ class A {
(new { def field = 0; def field_=(i: Int) = () }).field = 5 // compiles as expected
(new { def field(implicit i: Int) = 0; def field_=(i: Int) = () }).field = 5 // compiles even with implicit params on getter
(new { def field = 0; def field_=[T](i: Int) = () }).field = 5 // compiles with type param on setter
- (new { def field[T] = 0; def field_=(i: Int) = () }).field = 5 // DOESN'T COMPILE
-} \ No newline at end of file
+ (new { def field[T] = 0; def field_=(i: Int) = () }).field = 5 // DIDN'T COMPILE
+
+ class Imp
+ implicit val imp: Imp = new Imp
+ implicit val implicitList: List[Int] = null
+
+ // compiles even with implicit params on setter
+ (new { def field(implicit i: Int) = 0; def field_=(i: Int)(implicit j: Imp) = () }).field = 5
+ (new { def field(implicit i: Int) = 0; def field_=[T <: Imp](i: Int)(implicit j: T) = () }).field = 5
+ // was reassignment to val
+ (new { def field[T](implicit ts: List[T]) = 0; def field_=[T](i: Int)(implicit ts: List[T]) = () }).field = 5
+ (new { def field[T](implicit ts: List[T]) = 0; def field_=[T](i: T)(implicit ts: List[T]) = () }).field = 5
+}
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/junit/scala/collection/mutable/HashMapTest.scala b/test/junit/scala/collection/mutable/HashMapTest.scala
new file mode 100644
index 0000000000..cc1979a920
--- /dev/null
+++ b/test/junit/scala/collection/mutable/HashMapTest.scala
@@ -0,0 +1,38 @@
+package scala.collection
+package mutable
+
+import org.junit.Assert._
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(classOf[JUnit4])
+class HashMapTest {
+
+ @Test
+ def getOrElseUpdate_mutationInCallback() {
+ val hm = new mutable.HashMap[String, String]()
+ // add enough elements to resize the hash table in the callback
+ def add() = 1 to 100000 foreach (i => hm(i.toString) = "callback")
+ hm.getOrElseUpdate("0", {
+ add()
+ ""
+ })
+ assertEquals(Some(""), hm.get("0"))
+ }
+
+ @Test
+ def getOrElseUpdate_evalOnce(): Unit = {
+ var i = 0
+ val hm = new mutable.HashMap[Int, Int]()
+ hm.getOrElseUpdate(0, {i += 1; i})
+ assertEquals(1, hm(0))
+ }
+
+ @Test
+ def getOrElseUpdate_noEval(): Unit = {
+ val hm = new mutable.HashMap[Int, Int]()
+ hm.put(0, 0)
+ hm.getOrElseUpdate(0, throw new AssertionError())
+ }
+}
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)
}
}
diff --git a/tools/get-scala-commit-date b/tools/get-scala-commit-date
deleted file mode 100755
index 6511ed98ca..0000000000
--- a/tools/get-scala-commit-date
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env bash
-#
-# Usage: get-scala-commit-date [dir]
-# Figures out current commit date of a git clone.
-# If no dir is given, current working dir is used.
-#
-# Example build version string:
-# 20120312
-#
-
-[[ $# -eq 0 ]] || cd "$1"
-
-if git rev-parse --is-inside-work-tree > /dev/null 2>&1; then
- lastcommitdate=$(git log --format="%ci" HEAD | head -n 1 | cut -d ' ' -f 1)
- lastcommithours=$(git log --format="%ci" HEAD | head -n 1 | cut -d ' ' -f 2)
-else
- lastcommitdate=$(date +%Y-%m-%d)
- lastcommithours=$(date +%H:%M:%S)
-fi
-
-# 20120324
-echo "${lastcommitdate//-/}-${lastcommithours//:/}"
diff --git a/tools/get-scala-commit-date.bat b/tools/get-scala-commit-date.bat
deleted file mode 100644
index 735a80b927..0000000000
--- a/tools/get-scala-commit-date.bat
+++ /dev/null
@@ -1,9 +0,0 @@
-@echo off
-for %%X in (bash.exe) do (set FOUND=%%~$PATH:X)
-if defined FOUND (
- bash "%~dp0\get-scala-commit-date" 2>NUL
-) else (
- rem echo this script does not work with cmd.exe. please, install bash
- echo unknown
- exit 1
-)
diff --git a/tools/get-scala-commit-sha b/tools/get-scala-commit-sha
deleted file mode 100755
index 18289c7ca8..0000000000
--- a/tools/get-scala-commit-sha
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env bash
-#
-# Usage: get-scala-commit-sha [dir]
-# Figures out current commit sha of a git clone.
-# If no dir is given, current working dir is used.
-#
-# Example build version string:
-# 6f1c486d0ba
-#
-
-[[ $# -eq 0 ]] || cd "$1"
-
-if git rev-parse --is-inside-work-tree > /dev/null 2>&1; then
- # printf %016s is not portable for 0-padding, has to be a digit.
- # so we're stuck disassembling it.
- hash=$(git log -1 --format="%H" HEAD)
- hash=${hash#g}
- hash=${hash:0:10}
-else
- hash="unknown"
-fi
-echo "$hash"
diff --git a/tools/get-scala-commit-sha.bat b/tools/get-scala-commit-sha.bat
deleted file mode 100644
index 6559a19120..0000000000
--- a/tools/get-scala-commit-sha.bat
+++ /dev/null
@@ -1,9 +0,0 @@
-@echo off
-for %%X in (bash.exe) do (set FOUND=%%~$PATH:X)
-if defined FOUND (
- bash "%~dp0\get-scala-commit-sha" 2>NUL
-) else (
- rem echo this script does not work with cmd.exe. please, install bash
- echo unknown
- exit 1
-)