Skip to content
This repository was archived by the owner on Sep 1, 2020. It is now read-only.

Commit 4e95083

Browse files
authored
Merge pull request scala#5242 from szeiger/wip/merge-2.11-to-2.12-june-19
Merge 2.11 to 2.12 [ci: last-only]
2 parents 79e7334 + 2d85fe4 commit 4e95083

File tree

19 files changed

+408
-91
lines changed

19 files changed

+408
-91
lines changed

build.sbt

+129-53
Large diffs are not rendered by default.

project/BuildSettings.scala

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import sbt._
2+
3+
/** This object defines keys that should be visible with an unqualified name in all .sbt files and the command line */
4+
object BuildSettings extends AutoPlugin {
5+
object autoImport {
6+
lazy val antStyle = settingKey[Boolean]("Use ant-style incremental builds instead of name-hashing")
7+
lazy val baseVersion = settingKey[String]("The base version number from which all others are derived")
8+
lazy val baseVersionSuffix = settingKey[String]("Identifies the kind of version to build")
9+
lazy val mimaReferenceVersion = settingKey[Option[String]]("Scala version number to run MiMa against")
10+
}
11+
}

project/MiMa.scala

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// It would be nice to use sbt-mima-plugin here, but the plugin is missing
2+
// at least two features we need:
3+
// * ability to run MiMa twice, swapping `curr` and `prev`, to detect
4+
// both forwards and backwards incompatibilities (possibly fixed as of
5+
// https://github.com/typesafehub/migration-manager/commit/2844ffa48b6d2255aa64bd687703aec21dadd55e)
6+
// * ability to pass a filter file (https://github.com/typesafehub/migration-manager/issues/102)
7+
// So we invoke the MiMa CLI directly; it's also what the Ant build did.
8+
9+
import sbt._
10+
import sbt.Keys._
11+
import BuildSettings.autoImport._
12+
13+
object MiMa {
14+
lazy val mima =
15+
taskKey[Unit]("run Migration Manager to detect binary incompatibilities")
16+
17+
lazy val settings =
18+
Seq(
19+
mima := {
20+
val log = streams.value.log
21+
mimaReferenceVersion.value.fold {
22+
log.info(s"No reference version defined - skipping binary compatibility checks")
23+
} { refVersion =>
24+
def runOnce(prev: java.io.File, curr: java.io.File, isForward: Boolean): Unit = {
25+
val direction = if (isForward) "forward" else "backward"
26+
log.info(s"Checking $direction binary compatibility")
27+
log.debug(s"prev = $prev, curr = $curr")
28+
runMima(
29+
prev = if (isForward) curr else prev,
30+
curr = if (isForward) prev else curr,
31+
// TODO: it would be nicer if each subproject had its own whitelist, but for now
32+
// for compatibility with how Ant did things, there's just one at the root.
33+
// once Ant is gone we'd be free to split it up.
34+
filter = (baseDirectory in ThisBuild).value / s"bincompat-$direction.whitelist.conf",
35+
log)
36+
}
37+
val artifact =
38+
getPreviousArtifact(
39+
"org.scala-lang" % s"${name.value}" % refVersion,
40+
ivySbt.value, streams.value)
41+
for (isForward <- Seq(false, true))
42+
runOnce(artifact, (packageBin in Compile).value, isForward)
43+
}
44+
}
45+
)
46+
47+
def runMima(prev: java.io.File, curr: java.io.File, filter: java.io.File, log: Logger): Unit = {
48+
val args = Array(
49+
"--prev", prev.getAbsolutePath,
50+
"--curr", curr.getAbsolutePath,
51+
"--filters", filter.getAbsolutePath,
52+
"--generate-filters"
53+
)
54+
val exitCode = TrapExit(com.typesafe.tools.mima.cli.Main.main(args), log)
55+
if (exitCode != 0)
56+
throw new RuntimeException(s"MiMa failed with exit code $exitCode")
57+
}
58+
59+
// cribbed from https://github.com/typesafehub/migration-manager/blob/master/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala
60+
def getPreviousArtifact(m: ModuleID, ivy: IvySbt, s: TaskStreams): File = {
61+
val moduleSettings = InlineConfiguration(
62+
"dummy" % "test" % "version",
63+
ModuleInfo("dummy-test-project-for-resolving"),
64+
dependencies = Seq(m))
65+
val module = new ivy.Module(moduleSettings)
66+
val report = Deprecated.Inner.ivyUpdate(ivy)(module, s)
67+
val optFile = (for {
68+
config <- report.configurations
69+
module <- config.modules
70+
(artifact, file) <- module.artifacts
71+
// TODO - Hardcode this?
72+
if artifact.name == m.name
73+
} yield file).headOption
74+
optFile getOrElse sys.error("Could not resolve previous artifact: " + m)
75+
}
76+
77+
}
78+
79+
// use the SI-7934 workaround to silence a deprecation warning on an sbt API
80+
// we have no choice but to call. on the lack of any suitable alternative,
81+
// see https://gitter.im/sbt/sbt-dev?at=5616e2681b0e279854bd74a4 :
82+
// "it's my intention to eventually come up with a public API" says Eugene Y
83+
object Deprecated {
84+
@deprecated("", "") class Inner {
85+
def ivyUpdate(ivy: IvySbt)(module: ivy.Module, s: TaskStreams) =
86+
IvyActions.update(
87+
module,
88+
new UpdateConfiguration(
89+
retrieve = None,
90+
missingOk = false,
91+
logging = UpdateLogging.DownloadOnly),
92+
s.log)
93+
}
94+
object Inner extends Inner
95+
}

project/Osgi.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ object Osgi {
2828
"Bundle-Name" -> bundleName.value,
2929
"Bundle-SymbolicName" -> bundleSymbolicName.value,
3030
"ver" -> v,
31-
"Export-Package" -> ("*;version=${ver}"),
32-
"Import-Package" -> ("scala.*;version=\"${range;[==,=+);${ver}}\",*"),
31+
"Export-Package" -> "*;version=${ver};-split-package:=merge-first",
32+
"Import-Package" -> "scala.*;version=\"${range;[==,=+);${ver}}\",*",
3333
"Bundle-Version" -> v,
3434
"Bundle-RequiredExecutionEnvironment" -> "JavaSE-1.8",
3535
"-eclipse" -> "false"

project/Quiet.scala

-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,4 @@ object Quiet {
2828
case x => x
2929
}
3030
}
31-
32-
def silenceIvyUpdateInfoLogging = logLevel in update := Level.Warn
3331
}

project/ScalaTool.scala

+6-6
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ case class ScalaTool(mainClass: String,
2727
} else classpath.mkString(":").replace('\\', '/').replaceAll(varRegex, """\${$1}""")
2828

2929
val variables = Map(
30-
("@@" -> "@"), // for backwards compatibility
31-
("@class@" -> mainClass),
32-
("@properties@" -> (properties map { case (k, v) => s"""-D$k="$v""""} mkString " ")),
33-
("@javaflags@" -> javaOpts),
34-
("@toolflags@" -> toolFlags),
35-
("@classpath@" -> platformClasspath)
30+
"@@" -> "@", // for backwards compatibility
31+
"@class@" -> mainClass,
32+
"@properties@" -> (properties map { case (k, v) => s"""-D$k="$v""""} mkString " "),
33+
"@javaflags@" -> javaOpts,
34+
"@toolflags@" -> toolFlags,
35+
"@classpath@" -> platformClasspath
3636
)
3737

3838
val (from, to) = variables.unzip

project/ScriptCommands.scala

+18-4
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,33 @@
11
import sbt._
22
import Keys._
3-
import complete.DefaultParsers._
3+
import BuildSettings.autoImport._
44

55
/** Custom commands for use by the Jenkins scripts. This keeps the surface area and call syntax small. */
66
object ScriptCommands {
7-
def all = Seq(setupPublishCore)
7+
def all = Seq(setupPublishCore, setupValidateTest)
88

99
/** Set up the environment for `validate/publish-core`. The argument is the Artifactory snapshot repository URL. */
1010
def setupPublishCore = Command.single("setupPublishCore") { case (state, url) =>
1111
Project.extract(state).append(Seq(
12-
VersionUtil.baseVersionSuffix in Global := "SHA-SNAPSHOT",
12+
baseVersionSuffix in Global := "SHA-SNAPSHOT",
1313
// Append build.timestamp to Artifactory URL to get consistent build numbers (see https://github.com/sbt/sbt/issues/2088):
1414
publishTo in Global := Some("scala-pr" at url.replaceAll("/$", "") + ";build.timestamp=" + System.currentTimeMillis),
1515
publishArtifact in (Compile, packageDoc) in ThisBuild := false,
16-
scalacOptions in Compile in ThisBuild += "-optimise"
16+
scalacOptions in Compile in ThisBuild += "-Yopt:l:classpath",
17+
logLevel in ThisBuild := Level.Info,
18+
logLevel in update in ThisBuild := Level.Warn
1719
), state)
1820
}
21+
22+
/** Set up the environment for `validate/test`. The argument is the Artifactory snapshot repository URL. */
23+
def setupValidateTest = Command.single("setupValidateTest") { case (state, url) =>
24+
//TODO When ant is gone, pass starr version as an argument to this command instead of using version.properties
25+
Project.extract(state).append(Seq(
26+
resolvers in Global += "scala-pr" at url,
27+
scalacOptions in Compile in ThisBuild += "-opt:l:classpath",
28+
testOptions in IntegrationTest in LocalProject("test") ++= Seq(Tests.Argument("--show-log"), Tests.Argument("--show-diff")),
29+
logLevel in ThisBuild := Level.Info,
30+
logLevel in update in ThisBuild := Level.Warn
31+
), state)
32+
}
1933
}

project/VersionUtil.scala

+31-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import sbt._
22
import Keys._
33
import java.util.Properties
4-
import java.io.FileInputStream
4+
import java.io.{File, FileInputStream}
55
import scala.collection.JavaConverters._
6+
import BuildSettings.autoImport._
67

78
object VersionUtil {
8-
lazy val baseVersion = settingKey[String]("The base version number from which all others are derived")
9-
lazy val baseVersionSuffix = settingKey[String]("Identifies the kind of version to build")
109
lazy val copyrightString = settingKey[String]("Copyright string.")
1110
lazy val versionProperties = settingKey[Versions]("Version properties.")
1211
lazy val generateVersionPropertiesFile = taskKey[File]("Generating version properties file.")
@@ -123,4 +122,33 @@ object VersionUtil {
123122
/** Get a subproject version number from `versionProps` */
124123
def versionNumber(name: String): String =
125124
versionProps(s"$name.version.number")
125+
126+
/** Build a dependency to a Scala module with the given group and artifact ID */
127+
def scalaDep(group: String, artifact: String, versionProp: String = null, scope: String = null, compatibility: String = "binary") = {
128+
val vp = if(versionProp eq null) artifact else versionProp
129+
val m = group % (artifact + "_" + versionProps(s"scala.$compatibility.version")) % versionNumber(vp)
130+
val m2 = if(scope eq null) m else m % scope
131+
// exclusion of the scala-library transitive dependency avoids eviction warnings during `update`:
132+
m2.exclude("org.scala-lang", "*")
133+
}
134+
135+
private def bootstrapOrganization(path: String) =
136+
"org.scala-lang.scala-sha-bootstrap." + path.replace('/', '.')
137+
138+
/** Build a dependency to a JAR file in the bootstrap repository */
139+
def bootstrapDep(baseDir: File, path: String, libName: String): ModuleID = {
140+
val sha = IO.read(baseDir / path / s"$libName.jar.desired.sha1").split(' ')(0)
141+
bootstrapOrganization(path) % libName % sha from
142+
s"https://dl.bintray.com/typesafe/scala-sha-bootstrap/org/scala-lang/bootstrap/$sha/$path/$libName.jar"
143+
}
144+
145+
/** Copy a boostrap dependency JAR that is on the classpath to a file */
146+
def copyBootstrapJar(cp: Seq[Attributed[File]], baseDir: File, path: String, libName: String): Unit = {
147+
val org = bootstrapOrganization(path)
148+
val resolved = cp.find { a =>
149+
val mod = a.get(moduleID.key)
150+
mod.map(_.organization) == Some(org) && mod.map(_.name) == Some(libName)
151+
}.map(_.data).get
152+
IO.copyFile(resolved, baseDir / path / s"$libName.jar")
153+
}
126154
}

project/plugins.sbt

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
scalacOptions ++= Seq("-unchecked", "-feature", /*"-deprecation",*/
2+
"-Xlint" /*, "-Xfatal-warnings"*/)
3+
14
libraryDependencies += "org.apache.commons" % "commons-lang3" % "3.3.2"
25

36
libraryDependencies += "org.pantsbuild" % "jarjar" % "1.6.3"
@@ -15,3 +18,5 @@ buildClasspath := (externalDependencyClasspath in Compile).value.map(_.data).mkS
1518
buildInfoKeys := Seq[BuildInfoKey](buildClasspath)
1619

1720
buildInfoPackage := "scalabuild"
21+
22+
libraryDependencies += "com.typesafe" %% "mima-reporter" % "0.1.8"

scripts/jobs/validate/publish-core

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ case $prDryRun in
1616
;;
1717
*)
1818
echo ">>> Getting Scala version number."
19-
$SBT_CMD "setupPublishCore $prRepoUrl" generateBuildCharacterPropertiesFile
19+
$SBT_CMD --warn "setupPublishCore $prRepoUrl" generateBuildCharacterPropertiesFile
2020
parseScalaProperties buildcharacter.properties # produce maven_version_number
2121

2222
echo ">>> Checking availability of Scala ${maven_version_number} in $prRepoUrl."
@@ -27,7 +27,7 @@ case $prDryRun in
2727
if $libraryAvailable && $reflectAvailable && $compilerAvailable; then
2828
echo "Scala core already built!"
2929
else
30-
$SBT_CMD "setupPublishCore $prRepoUrl" $antBuildArgs publish
30+
$SBT_CMD --warn "setupPublishCore $prRepoUrl" publish
3131
fi
3232

3333
mv buildcharacter.properties jenkins.properties # parsed by the jenkins job

scripts/jobs/validate/test

+27-8
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,36 @@
1-
#!/bin/bash -e
1+
#!/bin/bash -e -v -x
2+
3+
baseDir=${WORKSPACE-`pwd`}
4+
scriptsDir="$baseDir/scripts"
5+
. $scriptsDir/common
26

37
case $prDryRun in
8+
49
yep)
510
echo "DRY RUN"
611
;;
12+
713
*)
8-
./pull-binary-libs.sh
914

1015
# build quick using STARR built upstream, as specified by scalaVersion
11-
# (in that sense it's locker, since it was built with starr by that upstream job)
12-
ant -Dstarr.version=$scalaVersion \
13-
-Dscalac.args.optimise=-opt:l:classpath \
14-
-Dlocker.skip=1 -Dextra.repo.url=$prRepoUrl \
15-
$testExtraArgs ${testTarget-test.core docs.done}
16+
# (in that sense it's locker, since it was built with starr by that upstream job);
17+
# and run JUnit tests, partest, OSGi tests, MiMa and scaladoc
18+
$SBT_CMD \
19+
-Dstarr.version=$scalaVersion \
20+
--warn \
21+
"setupValidateTest $prRepoUrl" \
22+
$testExtraArgs \
23+
"test" \
24+
"partest run pos neg jvm" \
25+
"partest res scalap specialized scalacheck" \
26+
"partest instrumented presentation" \
27+
"partest --srcpath scaladoc" \
28+
osgiTestFelix/test \
29+
osgiTestEclipse/test \
30+
library/mima \
31+
reflect/mima \
32+
doc
33+
1634
;;
17-
esac
35+
36+
esac

src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ abstract class TreeBuilder {
107107
def makeCatchFromExpr(catchExpr: Tree): CaseDef = {
108108
val binder = freshTermName()
109109
val pat = Bind(binder, Typed(Ident(nme.WILDCARD), Ident(tpnme.Throwable)))
110-
val catchDef = ValDef(Modifiers(ARTIFACT), freshTermName("catchExpr"), TypeTree(), catchExpr)
110+
val catchDef = ValDef(Modifiers(ARTIFACT), freshTermName("catchExpr$"), TypeTree(), catchExpr)
111111
val catchFn = Ident(catchDef.name)
112112
val body = atPos(catchExpr.pos.makeTransparent)(Block(
113113
List(catchDef),

src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala

+16-2
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,22 @@ trait MemberLookup extends base.MemberLookupBase {
4444
/* Get package object which has associatedFile ne null */
4545
sym.info.member(newTermName("package"))
4646
else sym
47-
Option(sym1.associatedFile) flatMap (_.underlyingSource) flatMap { src =>
48-
val path = src.canonicalPath
47+
def classpathEntryFor(s: Symbol): Option[String] = {
48+
Option(s.associatedFile).flatMap(_.underlyingSource).map { src =>
49+
val path = src.canonicalPath
50+
if(path.endsWith(".class")) { // Individual class file -> Classpath entry is root dir
51+
var nesting = s.ownerChain.count(_.hasPackageFlag)
52+
if(nesting > 0) {
53+
val p = 0.until(nesting).foldLeft(src) {
54+
case (null, _) => null
55+
case (f, _) => f.container
56+
}
57+
if(p eq null) path else p.canonicalPath
58+
} else path
59+
} else path // JAR file (and fallback option)
60+
}
61+
}
62+
classpathEntryFor(sym1) flatMap { path =>
4963
settings.extUrlMapping get path map { url =>
5064
LinkToExternal(name, url + "#" + name)
5165
}

test/files/pos/t9245.scala

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
/*
3+
Was:
4+
test/files/pos/t9245.scala:5: error: recursive value catchExpr1 needs type
5+
try {} catch catchExpr1
6+
^
7+
8+
Now:
9+
def catchExpr1: PartialFunction[Throwable,Any] = scala.this.Predef.???;
10+
def test: Any = try {
11+
()
12+
} catch {
13+
case (x$1 @ (_: Throwable)) => {
14+
<artifact> val catchExpr$1: PartialFunction[Throwable,Any] = Test.this.catchExpr1;
15+
if (catchExpr$1.isDefinedAt(x$1))
16+
catchExpr$1.apply(x$1)
17+
else
18+
throw x$1
19+
}
20+
}
21+
*/
22+
trait Test {
23+
def catchExpr1: PartialFunction[Throwable, Any] = ???
24+
def test = {
25+
try {} catch catchExpr1
26+
}
27+
}

test/osgi/src/logback.xml

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<configuration>
2+
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
3+
<encoder>
4+
<pattern>*** \(%logger{30}\)%green(%X{debugId}) %msg%n</pattern>
5+
</encoder>
6+
</appender>
7+
<root level="${log.root:-warn}">
8+
<appender-ref ref="STDOUT" />
9+
</root>
10+
</configuration>

test/scaladoc/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.log
2+
*.obj/

0 commit comments

Comments
 (0)