Skip to content

Commit

Permalink
Merge pull request #2101 from dotty-staging/upgrade/sbt0.13.14
Browse files Browse the repository at this point in the history
Upgrade to sbt 0.13.14-RC2, switch to build.sbt
  • Loading branch information
smarter committed Mar 24, 2017
2 parents 5fd7a95 + 70c072a commit 90eb9d2
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 54 deletions.
19 changes: 19 additions & 0 deletions build.sbt
@@ -0,0 +1,19 @@
val dotty = Build.dotty
val `dotty-bootstrapped` = Build.`dotty-bootstrapped`
val `dotty-interfaces` = Build.`dotty-interfaces`
val `dotty-doc` = Build.`dotty-doc`
val `dotty-bot` = Build.`dotty-bot`
val `dotty-compiler` = Build.`dotty-compiler`
val `dotty-compiler-bootstrapped` = Build.`dotty-compiler-bootstrapped`
val `dotty-bin-tests` = Build.`dotty-bin-tests`
val `dotty-library` = Build.`dotty-library`
val `dotty-library-bootstrapped` = Build.`dotty-library-bootstrapped`
val `dotty-sbt-bridge` = Build.`dotty-sbt-bridge`
val sjsSandbox = Build.sjsSandbox
val `dotty-bench` = Build.`dotty-bench`
val `scala-library` = Build.`scala-library`
val `scala-compiler` = Build.`scala-compiler`
val `scala-reflect` = Build.`scala-reflect`
val scalap = Build.scalap

inThisBuild(Build.thisBuildSettings)
58 changes: 30 additions & 28 deletions project/Build.scala
Expand Up @@ -10,7 +10,7 @@ import org.scalajs.sbtplugin.ScalaJSPlugin
import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport._
import sbt.Package.ManifestAttributes

object DottyBuild extends Build {
object Build {

val scalacVersion = "2.11.5" // Do not rename, this is grepped in bin/common.

Expand Down Expand Up @@ -59,26 +59,25 @@ object DottyBuild extends Build {
// Shorthand for compiling a docs site
lazy val dottydoc = inputKey[Unit]("run dottydoc")

override def settings: Seq[Setting[_]] = {
super.settings ++ Seq(
scalaVersion in Global := scalacVersion,
version in Global := dottyVersion,
organization in Global := dottyOrganization,
organizationName in Global := "LAMP/EPFL",
organizationHomepage in Global := Some(url("http://lamp.epfl.ch")),
homepage in Global := Some(url("https://github.com/lampepfl/dotty")),

// scalac options
scalacOptions in Global ++= Seq(
"-feature",
"-deprecation",
"-encoding", "UTF8",
"-language:existentials,higherKinds,implicitConversions"
),

javacOptions in Global ++= Seq("-Xlint:unchecked", "-Xlint:deprecation")
)
}
// Used in build.sbt
val thisBuildSettings = Seq(
scalaVersion in Global := scalacVersion,
version in Global := dottyVersion,
organization in Global := dottyOrganization,
organizationName in Global := "LAMP/EPFL",
organizationHomepage in Global := Some(url("http://lamp.epfl.ch")),
homepage in Global := Some(url("https://github.com/lampepfl/dotty")),

// scalac options
scalacOptions in Global ++= Seq(
"-feature",
"-deprecation",
"-encoding", "UTF8",
"-language:existentials,higherKinds,implicitConversions"
),

javacOptions in Global ++= Seq("-Xlint:unchecked", "-Xlint:deprecation")
)

/** Enforce 2.11.5. Do not let it be upgraded by dependencies. */
private val overrideScalaVersionSetting =
Expand Down Expand Up @@ -124,7 +123,7 @@ object DottyBuild extends Build {
lazy val dotty = project.in(file(".")).
// FIXME: we do not aggregate `bin` because its tests delete jars, thus breaking other tests
aggregate(`dotty-interfaces`, `dotty-library`, `dotty-compiler`, `dotty-doc`, dottySbtBridgeRef,
`scala-library`, `scala-compiler`, `scala-reflect`, `scalap`).
`scala-library`, `scala-compiler`, `scala-reflect`, scalap).
dependsOn(`dotty-compiler`).
dependsOn(`dotty-library`).
settings(
Expand Down Expand Up @@ -281,8 +280,11 @@ object DottyBuild extends Build {
libraryDependencies ++= partestDeps.value,
libraryDependencies ++= Seq("org.scala-lang.modules" %% "scala-xml" % "1.0.1",
"org.scala-lang.modules" %% "scala-partest" % "1.0.11" % "test",
"com.novocode" % "junit-interface" % "0.11" % "test",
"com.typesafe.sbt" % "sbt-interface" % sbtVersion.value),
"com.novocode" % "junit-interface" % "0.11" % "test"),

resolvers += Resolver.typesafeIvyRepo("releases"), // For org.scala-sbt:interface
libraryDependencies += "org.scala-sbt" % "interface" % sbtVersion.value,

// enable improved incremental compilation algorithm
incOptions := incOptions.value.withNameHashing(true),

Expand Down Expand Up @@ -428,7 +430,7 @@ object DottyBuild extends Build {
// FIXME: should go away when xml literal parsing is removed
path.contains("scala-xml") ||
// needed for the xsbti interface
path.contains("sbt-interface")
path.contains("org.scala-sbt/interface/")
} yield "-Xbootclasspath/p:" + path

val ci_build = // propagate if this is a ci build
Expand Down Expand Up @@ -552,9 +554,9 @@ object DottyBuild extends Build {
},
publishLocal := (publishLocal.dependsOn(cleanSbtBridge)).value,
description := "sbt compiler bridge for Dotty",
resolvers += Resolver.typesafeIvyRepo("releases"),
resolvers += Resolver.typesafeIvyRepo("releases"), // For org.scala-sbt stuff
libraryDependencies ++= Seq(
"com.typesafe.sbt" % "sbt-interface" % sbtVersion.value,
"org.scala-sbt" % "interface" % sbtVersion.value,
"org.scala-sbt" % "api" % sbtVersion.value % "test",
"org.specs2" %% "specs2" % "2.3.11" % "test"
),
Expand Down Expand Up @@ -725,7 +727,7 @@ object DottyInjectedPlugin extends AutoPlugin {
libraryDependencies := Seq("org.scala-lang" % "scala-reflect" % scalaVersion.value)
).
settings(publishing)
lazy val `scalap` = project.
lazy val scalap = project.
settings(
crossPaths := false,
libraryDependencies := Seq("org.scala-lang" % "scalap" % scalaVersion.value)
Expand Down
2 changes: 1 addition & 1 deletion project/build.properties
@@ -1 +1 @@
sbt.version=0.13.11
sbt.version=0.13.14-RC2
8 changes: 3 additions & 5 deletions project/plugins.sbt
Expand Up @@ -3,10 +3,8 @@
// e.g. addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.1.0")

// Scala IDE project file generator
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "4.0.0")
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "5.1.0")

addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "0.8.0")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.14")

addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.8")

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.3")
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.4")
80 changes: 76 additions & 4 deletions sbt-bridge/test/xsbt/ExtractAPISpecification.scala
Expand Up @@ -2,9 +2,8 @@
package xsbt

import org.junit.runner.RunWith
import xsbti.api.ClassLike
import xsbti.api.Def
import xsbt.api.ShowAPI
import xsbti.api._
import xsbt.api.DefaultShowAPI
import org.specs2.mutable.Specification
import org.specs2.runner.JUnitRunner

Expand All @@ -17,7 +16,7 @@ class ExtractAPISpecification extends Specification {

def stableExistentialNames: Boolean = {
def compileAndGetFooMethodApi(src: String): Def = {
val compilerForTesting = new ScalaCompilerForUnitTesting
val compilerForTesting = new ScalaCompilerForUnitTesting(nameHashing = false)
val sourceApi = compilerForTesting.extractApiFromSrc(src)
val FooApi = sourceApi.definitions().find(_.name() == "Foo").get.asInstanceOf[ClassLike]
val fooMethodApi = FooApi.structure().declared().find(_.name == "foo").get
Expand All @@ -38,8 +37,81 @@ class ExtractAPISpecification extends Specification {
|
}""".stripMargin
val fooMethodApi2 = compileAndGetFooMethodApi(src2)

fooMethodApi1 == fooMethodApi2
// Fails because xsbt.api is compiled with Scala 2.10
// SameAPI.apply(fooMethodApi1, fooMethodApi2)
}

/**
* Checks if representation of the inherited Namer class (with a declared self variable) in Global.Foo
* is stable between compiling from source and unpickling. We compare extracted APIs of Global when Global
* is compiled together with Namers or Namers is compiled first and then Global refers
* to Namers by unpickling types from class files.
*
* See https://github.com/sbt/sbt/issues/2504
*/
"Self variable and no self type" in {
def selectNamer(api: SourceAPI): ClassLike = {
def selectClass(defs: Iterable[Definition], name: String): ClassLike = defs.collectFirst {
case cls: ClassLike if cls.name == name => cls
}.get
val global = selectClass(api.definitions, "Global")
val foo = selectClass(global.structure.declared, "Global.Foo")
selectClass(foo.structure.inherited, "Namers.Namer")
}
val src1 =
"""|class Namers {
| class Namer { thisNamer => }
|}
|""".stripMargin
val src2 =
"""|class Global {
| class Foo extends Namers
|}
|""".stripMargin
val compilerForTesting = new ScalaCompilerForUnitTesting(nameHashing = false)
val apis = compilerForTesting.extractApisFromSrcs(reuseCompilerInstance = false)(List(src1, src2), List(src2))
val _ :: src2Api1 :: src2Api2 :: Nil = apis.toList
val namerApi1 = selectNamer(src2Api1)
val namerApi2 = selectNamer(src2Api2)

DefaultShowAPI(namerApi1) == DefaultShowAPI(namerApi2)
// Fails because xsbt.api is compiled with Scala 2.10
// SameAPI(namerApi1, namerApi2)
}

/**
* Checks if self type is properly extracted in various cases of declaring a self type
* with our without a self variable.
*/
"Self type" in {
def collectFirstClass(defs: Array[Definition]): ClassLike = defs.collectFirst {
case c: ClassLike => c
}.get
val srcX = "trait X"
val srcY = "trait Y"
val srcC1 = "class C1 { this: C1 => }"
val srcC2 = "class C2 { thisC: C2 => }"
val srcC3 = "class C3 { this: X => }"
val srcC4 = "class C4 { thisC: X => }"
val srcC5 = "class C5 extends AnyRef with X with Y { self: X with Y => }"
val srcC6 = "class C6 extends AnyRef with X { self: X with Y => }"
// val srcC7 = "class C7 { _ => }" // DOTTY: Syntax not supported
val srcC8 = "class C8 { self => }"
val compilerForTesting = new ScalaCompilerForUnitTesting(nameHashing = false)
val apis = compilerForTesting.extractApisFromSrcs(reuseCompilerInstance = true)(
List(srcX, srcY, srcC1, srcC2, srcC3, srcC4, srcC5, srcC6, srcC8)
).map(x => collectFirstClass(x.definitions))
val emptyType = new EmptyType
def hasSelfType(c: ClassLike): Boolean =
c.selfType != emptyType
val (withSelfType, withoutSelfType) = apis.partition(hasSelfType)
// DOTTY: In the scalac ExtractAPI phase, the self-type is only
// extracted if it differs from the type of the class for stability
// reasons. This isn't necessary in dotty because we always pickle
// the self type.
withSelfType.map(_.name).toSet === Set("C1", "C2", "C3", "C4", "C5", "C6", "C8")
withoutSelfType.map(_.name).toSet === Set("X", "Y")
}
}
39 changes: 39 additions & 0 deletions sbt-bridge/test/xsbt/ExtractUsedNamesSpecification.scala
Expand Up @@ -75,6 +75,7 @@ class ExtractUsedNamesSpecification extends Specification {
|}""".stripMargin
val compilerForTesting = new ScalaCompilerForUnitTesting(nameHashing = true)
val usedNames = compilerForTesting.extractUsedNamesFromSrc(srcA, srcB)

// DOTTY TODO: "Int" is not actually used, but we collect it because
// it's the inferred return type so it appears in a TypeTree
// We could avoid this by checking if the untyped tree has a return type
Expand All @@ -84,6 +85,44 @@ class ExtractUsedNamesSpecification extends Specification {
usedNames === expectedNames
}

"extract names in the types of trees" in {
val src1 = """|class X0
|class X1 extends X0
|class Y
|class A {
| type T >: X1 <: X0
|}
|class M
|class N
|class P0
|class P1 extends P0
|object B {
| type S = Y
| val lista: List[A] = ???
| val at: A#T = ???
| val as: S = ???
| def foo(m: M): N = ???
| def bar[Param >: P1 <: P0](p: Param): Param = ???
|}""".stripMargin
val src2 = """|object Test {
| val x = B.lista
| val y = B.at
| val z = B.as
| B.foo(???)
| B.bar(???)
|}""".stripMargin
val compilerForTesting = new ScalaCompilerForUnitTesting(nameHashing = true)
val usedNames = compilerForTesting.extractUsedNamesFromSrc(src1, src2)
val expectedNames = standardNames ++ Set("Test", "Test$", "B", "B$",
"Predef", "Predef$", "$qmark$qmark$qmark", "Nothing",
"lista", "List", "A",
"at", "T", "X1", "X0",
"as", "S", "Y",
"foo", "M", "N",
"bar", "P1", "P0")
usedNames === expectedNames
}

// test for https://github.com/gkossakowski/sbt/issues/3
"used names from the same compilation unit" in {
val src = "class A { def foo: Int = 0; def bar: Int = foo }"
Expand Down

0 comments on commit 90eb9d2

Please sign in to comment.