diff --git a/build.sbt b/build.sbt index c1682d13e..448656eb2 100644 --- a/build.sbt +++ b/build.sbt @@ -7,7 +7,7 @@ import Sxr.sxr // but can be shared across the multi projects. def buildLevelSettings: Seq[Setting[_]] = inThisBuild(Seq( organization := "org.scala-sbt", - version := "0.13.10-SNAPSHOT", + version := "0.13.11-SNAPSHOT", bintrayOrganization := Some(if (publishStatus.value == "releases") "typesafe" else "sbt"), bintrayRepository := s"ivy-${publishStatus.value}", bintrayPackage := "sbt", diff --git a/compile/api/src/main/scala/sbt/ClassToAPI.scala b/compile/api/src/main/scala/sbt/ClassToAPI.scala index 9589865ec..1eb91f44b 100644 --- a/compile/api/src/main/scala/sbt/ClassToAPI.scala +++ b/compile/api/src/main/scala/sbt/ClassToAPI.scala @@ -261,7 +261,7 @@ object ClassToAPI { def modifiers(i: Int): api.Modifiers = { import Modifier.{ isAbstract, isFinal } - new api.Modifiers(isAbstract(i), false, isFinal(i), false, false, false, false) + new api.Modifiers(isAbstract(i), false, isFinal(i), false, false, false, false, false) } def access(i: Int, pkg: Option[String]): api.Access = { diff --git a/compile/api/src/main/scala/xsbt/api/APIUtil.scala b/compile/api/src/main/scala/xsbt/api/APIUtil.scala index 9a6dddfdd..643f4ee32 100644 --- a/compile/api/src/main/scala/xsbt/api/APIUtil.scala +++ b/compile/api/src/main/scala/xsbt/api/APIUtil.scala @@ -12,7 +12,7 @@ object APIUtil { } val byteToModifiers = (b: Byte) => { def x(bit: Int) = (b & (1 << bit)) != 0 - new Modifiers(x(0), x(1), x(2), x(3), x(4), x(5), x(6)) + new Modifiers(x(0), x(1), x(2), x(3), x(4), x(5), x(6), x(7)) } def isScalaSourceName(name: String): Boolean = name.endsWith(".scala") diff --git a/compile/api/src/main/scala/xsbt/api/HashAPI.scala b/compile/api/src/main/scala/xsbt/api/HashAPI.scala index 6ed4054e0..f600d5416 100644 --- a/compile/api/src/main/scala/xsbt/api/HashAPI.scala +++ b/compile/api/src/main/scala/xsbt/api/HashAPI.scala @@ -139,16 +139,37 @@ final class HashAPI(includePrivate: Boolean, includeParamNames: Boolean, include { hash = startHash(0) hashSymmetric(s.packages, hashPackage) - hashDefinitions(s.definitions, true) + hashDefinitions(s.definitions, topLevel = true, isTrait = false) finalizeHash } def hashPackage(p: Package) = hashString(p.name) + @deprecated("Use the overload that indicates if the enclosing definition is a trait.", "0.14") def hashDefinitions(ds: Seq[Definition], topLevel: Boolean): Unit = + hashDefinitions(ds, topLevel, isTrait = false) + + def hashDefinitions(ds: Seq[Definition], topLevel: Boolean, isTrait: Boolean): Unit = { + def isPublic(d: Definition): Boolean = d.access match { case _: xsbti.api.Public => true; case _ => false } + def isTraitBreaker(d: Definition): Boolean = d match { + // Vars and vals in traits introduce getters, setters and fields in the implementing classes. + // See test `source-dependencies/trait-private-var + case _: FieldLike => true + // Objects in traits introduce fields in the implementing classes. + // See test `source-dependencies/trait-private-object` + case cl: ClassLike => cl.definitionType == DefinitionType.Module + // super calls introduce accessors that are not part of the public API + case d: Def => d.modifiers.isSuperAccessor + case _ => false + } + val includedPrivateDefinitions = + if (!includePrivate && !topLevel && isTrait) { + ds filter (x => isTraitBreaker(x) && !isPublic(x)) + } else Seq.empty + val defs = SameAPI.filterDefinitions(ds, topLevel, includePrivate) - hashSymmetric(defs, hashDefinition) + hashSymmetric(includedPrivateDefinitions ++ defs, hashDefinition) } /** @@ -356,9 +377,9 @@ final class HashAPI(includePrivate: Boolean, includeParamNames: Boolean, include def hashStructure0(structure: Structure, includeDefinitions: Boolean, isTrait: Boolean = false): Unit = { extend(StructureHash) hashTypes(structure.parents, includeDefinitions) - if (includeDefinitions || isTrait) { - hashDefinitions(structure.declared, isTrait) - hashDefinitions(structure.inherited, isTrait) + if (includeDefinitions) { + hashDefinitions(structure.declared, topLevel = false, isTrait) + hashDefinitions(structure.inherited, topLevel = false, isTrait) } } def hashParameters(parameters: Seq[TypeParameter], base: Type): Unit = diff --git a/compile/api/src/test/scala/xsbt/api/NameHashingSpecification.scala b/compile/api/src/test/scala/xsbt/api/NameHashingSpecification.scala index 4849838b2..1ec910058 100644 --- a/compile/api/src/test/scala/xsbt/api/NameHashingSpecification.scala +++ b/compile/api/src/test/scala/xsbt/api/NameHashingSpecification.scala @@ -165,20 +165,39 @@ class NameHashingSpecification extends Specification { } /** - * Checks that private members are included in the hash of the public API of traits. - * Including the private members of traits is required because classes that implement a trait - * have to define the private members of the trait. Therefore, if a private member of a trait is added, - * modified or removed we need to recompile the classes that implement this trait. + * Checks that private vars are included in the hash of the public API of traits. + * Including the private vars of traits is required because classes that implement a trait + * have to define getters and setters for these vars. * For instance, if trait Foo is initially defined as: - * trait Foo { private val x = new A } + * trait Foo { private var x = new A } * changing it to - * trait Foo { private val x = new B } + * trait Foo { private var x = new B } * requires us to recompile all implementors of trait Foo, because scalac generates setters and getters - * for the private fields of trait Foo in its implementor. If the clients of trait Foo are not recompiled, + * for the private vars of trait Foo in its implementor. If the clients of trait Foo are not recompiled, * we get abstract method errors at runtime, because the types expected by the setter (for instance) does not * match. */ - "private members in traits" in { + "private var in traits are included in API hash" in { + /* trait Foo { private var x } */ + val fooTrait1 = + simpleTrait("Foo", + simpleStructure(new Var(emptyType, "x", privateAccess, defaultModifiers, Array.empty)), + publicAccess) + + /* trait Foo */ + val fooTrait2 = + simpleTrait("Foo", + simpleStructure(), + publicAccess) + + val api1 = new SourceAPI(Array.empty, Array(fooTrait1)) + val api2 = new SourceAPI(Array.empty, Array(fooTrait2)) + + HashAPI(api1) !== HashAPI(api2) + + } + + "private vals in traits are included in API hash" in { /* trait Foo { private val x } */ val fooTrait1 = simpleTrait("Foo", @@ -198,15 +217,97 @@ class NameHashingSpecification extends Specification { } + "private objects in traits are included in API hash" in { + /* trait Foo { private object x } */ + val fooTrait1 = + simpleTrait("Foo", + simpleStructure( + new ClassLike(DefinitionType.Module, lzy(emptyType), lzy(simpleStructure()), Array.empty, Array.empty, "x", privateAccess, defaultModifiers, Array.empty)), + publicAccess) + + /* trait Foo */ + val fooTrait2 = + simpleTrait("Foo", + simpleStructure(), + publicAccess) + + val api1 = new SourceAPI(Array.empty, Array(fooTrait1)) + val api2 = new SourceAPI(Array.empty, Array(fooTrait2)) + + HashAPI(api1) !== HashAPI(api2) + + } + + "private non-synthetic def in traits are not included in API hash" in { + /* trait Foo { private def x } */ + val fooTrait1 = + simpleTrait("Foo", + simpleStructure(new Def(Array.empty, emptyType, Array.empty, "x", privateAccess, defaultModifiers, Array.empty)), + publicAccess) + + /* trait Foo */ + val fooTrait2 = + simpleTrait("Foo", + simpleStructure(), + publicAccess) + + val api1 = new SourceAPI(Array.empty, Array(fooTrait1)) + val api2 = new SourceAPI(Array.empty, Array(fooTrait2)) + + HashAPI(api1) === HashAPI(api2) + + } + + "private synthetic def in traits are included in API hash" in { + /* trait Foo { private def x } */ + val modifiers = new xsbti.api.Modifiers(false, false, false, false, false, false, false, true) + val fooTrait1 = + simpleTrait("Foo", + simpleStructure(new Def(Array.empty, emptyType, Array.empty, "x", privateAccess, modifiers, Array.empty)), + publicAccess) + + /* trait Foo */ + val fooTrait2 = + simpleTrait("Foo", + simpleStructure(), + publicAccess) + + val api1 = new SourceAPI(Array.empty, Array(fooTrait1)) + val api2 = new SourceAPI(Array.empty, Array(fooTrait2)) + + HashAPI(api1) !== HashAPI(api2) + + } + + "private types in traits are included not in API hash" in { + /* trait Foo { private type x } */ + val fooTrait1 = + simpleTrait("Foo", + simpleStructure(new TypeAlias(emptyType, Array.empty, "x", privateAccess, defaultModifiers, Array.empty)), + publicAccess) + + /* trait Foo */ + val fooTrait2 = + simpleTrait("Foo", + simpleStructure(), + publicAccess) + + val api1 = new SourceAPI(Array.empty, Array(fooTrait1)) + val api2 = new SourceAPI(Array.empty, Array(fooTrait2)) + + HashAPI(api1) === HashAPI(api2) + + } + /** - * Checks that private members in non-top-level traits are included as well. + * Checks that private vars in non-top-level traits are included as well. */ - "private members in nested traits" in { - /* class A { trait Foo { private val x } } */ + "private variables in nested traits are include in the API hash" in { + /* class A { trait Foo { private var x } } */ val classA1 = simpleClass("A", simpleTrait("Foo", - simpleStructure(new Val(emptyType, "x", privateAccess, defaultModifiers, Array.empty)), + simpleStructure(new Var(emptyType, "x", privateAccess, defaultModifiers, Array.empty)), publicAccess)) /* class A { trait Foo } */ @@ -226,12 +327,12 @@ class NameHashingSpecification extends Specification { /** * Checks that private traits are NOT included in the hash. */ - "private traits" in { - /* class Foo { private trait T { private val x } } */ + "private inner traits are not included in the API hash" in { + /* class Foo { private trait T { private var x } } */ val classFoo1 = simpleClass("Foo", simpleTrait("T", - simpleStructure(new Val(emptyType, "x", privateAccess, defaultModifiers, Array.empty)), + simpleStructure(new Var(emptyType, "x", privateAccess, defaultModifiers, Array.empty)), privateAccess)) /** class Foo { private trait T } */ @@ -256,10 +357,10 @@ class NameHashingSpecification extends Specification { * Checks that private members are NOT included in the hash of the public API of classes. */ "private members in classes are not included in the api hash" in { - /* class Foo { private val x } */ + /* class Foo { private var x } */ val classFoo1 = simpleClass("Foo", - simpleStructure(new Val(emptyType, "x", privateAccess, defaultModifiers, Array.empty))) + simpleStructure(new Var(emptyType, "x", privateAccess, defaultModifiers, Array.empty))) /* class Foo */ val classFoo2 = @@ -274,9 +375,9 @@ class NameHashingSpecification extends Specification { } /** - * Checks that private members do NOT contribute to name hashes. - * Test for https://github.com/sbt/sbt/issues/2324 - */ + * Checks that private members do NOT contribute to name hashes. + * Test for https://github.com/sbt/sbt/issues/2324 + */ "private members in classes do not contribute to name hashes" in { /* class Foo { private val x } */ val classFoo = @@ -336,6 +437,6 @@ class NameHashingSpecification extends Specification { private val strTpe = new Projection(emptyType, "String") private val publicAccess = new Public private val privateAccess = new Private(new Unqualified) - private val defaultModifiers = new Modifiers(false, false, false, false, false, false, false) + private val defaultModifiers = new Modifiers(false, false, false, false, false, false, false, false) } diff --git a/compile/inc/src/test/scala/sbt/inc/TestCaseGenerators.scala b/compile/inc/src/test/scala/sbt/inc/TestCaseGenerators.scala index 92571984d..1c628666b 100644 --- a/compile/inc/src/test/scala/sbt/inc/TestCaseGenerators.scala +++ b/compile/inc/src/test/scala/sbt/inc/TestCaseGenerators.scala @@ -76,7 +76,7 @@ object TestCaseGenerators { private[this] def makeDefinition(name: String): Definition = new ClassLike(DefinitionType.ClassDef, lzy(new EmptyType()), lzy(new Structure(lzy(Array()), lzy(Array()), lzy(Array()))), Array(), Array(), - name, new Public(), new Modifiers(false, false, false, false, false, false, false), Array()) + name, new Public(), new Modifiers(false, false, false, false, false, false, false, false), Array()) private[this] def lzy[T <: AnyRef](x: T) = SafeLazy.strict(x) diff --git a/compile/integration/src/main/scala/sbt/compiler/MixedAnalyzingCompiler.scala b/compile/integration/src/main/scala/sbt/compiler/MixedAnalyzingCompiler.scala index 4081ca473..546345805 100644 --- a/compile/integration/src/main/scala/sbt/compiler/MixedAnalyzingCompiler.scala +++ b/compile/integration/src/main/scala/sbt/compiler/MixedAnalyzingCompiler.scala @@ -37,7 +37,7 @@ final class MixedAnalyzingCompiler( */ def compile(include: Set[File], changes: DependencyChanges, callback: AnalysisCallback): Unit = { val outputDirs = outputDirectories(output) - outputDirs foreach (IO.createDirectory) + outputDirs foreach (d => if (!d.getPath.endsWith(".jar")) IO.createDirectory(d)) val incSrc = sources.filter(include) val (javaSrcs, scalaSrcs) = incSrc partition javaOnly logInputs(log, javaSrcs.size, scalaSrcs.size, outputDirs) diff --git a/compile/interface/src/main/scala/xsbt/Compat.scala b/compile/interface/src/main/scala/xsbt/Compat.scala index 9f9fb247c..a4859275d 100644 --- a/compile/interface/src/main/scala/xsbt/Compat.scala +++ b/compile/interface/src/main/scala/xsbt/Compat.scala @@ -107,8 +107,8 @@ abstract class Compat { } lazy val AnyValClass = global.rootMirror.getClassIfDefined("scala.AnyVal") - def isAnyValSubtype(sym: Symbol): Boolean = sym.isNonBottomSubClass(AnyValClass) - + def isDerivedValueClass(sym: Symbol): Boolean = + sym.isNonBottomSubClass(AnyValClass) && !definitions.ScalaValueClasses.contains(sym) } object MacroExpansionOf { diff --git a/compile/interface/src/main/scala/xsbt/ExtractAPI.scala b/compile/interface/src/main/scala/xsbt/ExtractAPI.scala index 31389218b..07336d31b 100644 --- a/compile/interface/src/main/scala/xsbt/ExtractAPI.scala +++ b/compile/interface/src/main/scala/xsbt/ExtractAPI.scala @@ -205,23 +205,17 @@ class ExtractAPI[GlobalType <: CallbackGlobal](val global: GlobalType, val hasValueClassAsParameter: Boolean = { import MirrorHelper._ - s.asMethod.paramss.flatten map (_.info) exists (t => isAnyValSubtype(t.typeSymbol)) + s.asMethod.paramss.flatten map (_.info) exists (t => isDerivedValueClass(t.typeSymbol)) } - // Note: We only inspect the "outermost type" (i.e. no recursion) because we don't need to - // inspect after erasure a function that would, for instance, return a function that returns - // a subtype of AnyVal. - val hasValueClassAsReturnType: Boolean = { - val tpe = viewer(in).memberInfo(s) - tpe match { - case PolyType(_, base) => isAnyValSubtype(base.typeSymbol) - case MethodType(_, resultType) => isAnyValSubtype(resultType.typeSymbol) - case Nullary(resultType) => isAnyValSubtype(resultType.typeSymbol) - case resultType => isAnyValSubtype(resultType.typeSymbol) - } + def hasValueClassAsReturnType(tpe: Type): Boolean = tpe match { + case PolyType(_, base) => hasValueClassAsReturnType(base) + case MethodType(_, resultType) => hasValueClassAsReturnType(resultType) + case Nullary(resultType) => hasValueClassAsReturnType(resultType) + case resultType => isDerivedValueClass(resultType.typeSymbol) } - val inspectPostErasure = hasValueClassAsParameter || hasValueClassAsReturnType + val inspectPostErasure = hasValueClassAsParameter || hasValueClassAsReturnType(viewer(in).memberInfo(s)) def build(t: Type, typeParams: Array[xsbti.api.TypeParameter], valueParameters: List[xsbti.api.ParameterList]): List[xsbti.api.Def] = { @@ -444,7 +438,7 @@ class ExtractAPI[GlobalType <: CallbackGlobal](val global: GlobalType, val absOver = s.hasFlag(ABSOVERRIDE) val abs = s.hasFlag(ABSTRACT) || s.hasFlag(DEFERRED) || absOver val over = s.hasFlag(OVERRIDE) || absOver - new xsbti.api.Modifiers(abs, over, s.isFinal, s.hasFlag(SEALED), isImplicit(s), s.hasFlag(LAZY), hasMacro(s)) + new xsbti.api.Modifiers(abs, over, s.isFinal, s.hasFlag(SEALED), isImplicit(s), s.hasFlag(LAZY), hasMacro(s), s.hasFlag(SUPERACCESSOR)) } private def isImplicit(s: Symbol) = s.hasFlag(Flags.IMPLICIT) diff --git a/interface/src/main/java/xsbti/api/Modifiers.java b/interface/src/main/java/xsbti/api/Modifiers.java index 5e103c7ec..c91c3ec28 100644 --- a/interface/src/main/java/xsbti/api/Modifiers.java +++ b/interface/src/main/java/xsbti/api/Modifiers.java @@ -9,13 +9,14 @@ public final class Modifiers implements java.io.Serializable private static final int ImplicitBit = 4; private static final int LazyBit = 5; private static final int MacroBit = 6; + private static final int SuperAccessorBit = 7; private static int flag(boolean set, int bit) { return set ? (1 << bit) : 0; } - public Modifiers(boolean isAbstract, boolean isOverride, boolean isFinal, boolean isSealed, boolean isImplicit, boolean isLazy, boolean isMacro) + public Modifiers(boolean isAbstract, boolean isOverride, boolean isFinal, boolean isSealed, boolean isImplicit, boolean isLazy, boolean isMacro, boolean isSuperAccessor) { this.flags = (byte)( flag(isAbstract, AbstractBit) | @@ -24,7 +25,8 @@ public final class Modifiers implements java.io.Serializable flag(isSealed, SealedBit) | flag(isImplicit, ImplicitBit) | flag(isLazy, LazyBit) | - flag(isMacro, MacroBit) + flag(isMacro, MacroBit) | + flag(isSuperAccessor, SuperAccessorBit) ); } @@ -68,6 +70,10 @@ public final class Modifiers implements java.io.Serializable { return flag(MacroBit); } + public final boolean isSuperAccessor() + { + return flag(SuperAccessorBit); + } public boolean equals(Object o) { return (o instanceof Modifiers) && flags == ((Modifiers)o).flags; @@ -78,6 +84,6 @@ public final class Modifiers implements java.io.Serializable } public String toString() { - return "Modifiers(" + "isAbstract: " + isAbstract() + ", " + "isOverride: " + isOverride() + ", " + "isFinal: " + isFinal() + ", " + "isSealed: " + isSealed() + ", " + "isImplicit: " + isImplicit() + ", " + "isLazy: " + isLazy() + ", " + "isMacro: " + isMacro()+ ")"; + return "Modifiers(" + "isAbstract: " + isAbstract() + ", " + "isOverride: " + isOverride() + ", " + "isFinal: " + isFinal() + ", " + "isSealed: " + isSealed() + ", " + "isImplicit: " + isImplicit() + ", " + "isLazy: " + isLazy() + ", " + "isMacro: " + isMacro()+ ", isSuperAccessor:" + isSuperAccessor() + ")"; } } diff --git a/main/src/main/scala/sbt/ConsoleProject.scala b/main/src/main/scala/sbt/ConsoleProject.scala index a484d4e8f..3d66cf552 100644 --- a/main/src/main/scala/sbt/ConsoleProject.scala +++ b/main/src/main/scala/sbt/ConsoleProject.scala @@ -11,7 +11,13 @@ object ConsoleProject { val cpImports = new Imports(extracted, state) val bindings = ("currentState" -> state) :: ("extracted" -> extracted) :: ("cpHelpers" -> cpImports) :: Nil val unit = extracted.currentUnit - val compiler = Compiler.compilers(ClasspathOptions.repl)(state.configuration, log).scalac + val (_, ivyConf) = extracted.runTask(Keys.ivyConfiguration, state) + val scalaInstance = { + val scalaProvider = state.configuration.provider.scalaProvider + ScalaInstance(scalaProvider.version, scalaProvider.launcher) + } + val sourcesModule = extracted.get(Keys.scalaCompilerBridgeSource) + val compiler = Compiler.scalaCompiler(scalaInstance, ClasspathOptions.repl, ivyConf, sourcesModule)(state.configuration, log) val imports = BuildUtil.getImports(unit.unit) ++ BuildUtil.importAll(bindings.map(_._1)) val importString = imports.mkString("", ";\n", ";\n\n") val initCommands = importString + extra diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index ac4a2c513..ae6e93823 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -1036,8 +1036,7 @@ object Classpaths { internalDependencyClasspath <<= internalDependencies, unmanagedClasspath <<= unmanagedDependencies, managedClasspath := managedJars(classpathConfiguration.value, classpathTypes.value, update.value), - exportedProducts <<= exportProductsTask, - exportedProductsAlways <<= trackedExportedProducts(TrackLevel.TrackAlways), + exportedProducts <<= trackedExportedProducts(TrackLevel.TrackAlways), exportedProductsIfMissing <<= trackedExportedProducts(TrackLevel.TrackIfMissing), exportedProductsNoTracking <<= trackedExportedProducts(TrackLevel.NoTracking), unmanagedJars := findUnmanagedJars(configuration.value, unmanagedBase.value, includeFilter in unmanagedJars value, excludeFilter in unmanagedJars value) @@ -1148,10 +1147,14 @@ object Classpaths { overrideBuildResolvers <<= appConfiguration(isOverrideRepositories), externalResolvers <<= (externalResolvers.task.?, resolvers, appResolvers, useJCenter) { case (Some(delegated), Seq(), _, _) => delegated - case (_, rs, Some(ars), uj) => task { ars ++ Resolver.reorganizeAppResolvers(rs, uj, true) } - case (_, rs, _, uj) => task { Resolver.withDefaultResolvers(rs, uj) } + case (_, rs, Some(ars), uj) => task { ars ++ rs } + case (_, rs, _, uj) => task { Resolver.withDefaultResolvers(rs, uj, true) } + }, + appResolvers := { + val ac = appConfiguration.value + val uj = useJCenter.value + appRepositories(ac) map { ars => Resolver.reorganizeAppResolvers(ars, uj, true) } }, - appResolvers <<= appConfiguration apply appRepositories, bootResolvers <<= appConfiguration map bootRepositories, fullResolvers <<= (projectResolver, externalResolvers, sbtPlugin, sbtResolver, bootResolvers, overrideBuildResolvers) map { (proj, rs, isPlugin, sbtr, boot, overrideFlag) => boot match { @@ -1623,6 +1626,7 @@ object Classpaths { } } + @deprecated("This is no longer used.", "0.13.10") def exportProductsTask: Initialize[Task[Classpath]] = Def.task { val art = (artifact in packageBin).value val module = projectID.value @@ -1742,7 +1746,7 @@ object Classpaths { track match { case TrackLevel.NoTracking => getClasspath(exportedProductsNoTracking, dep, conf, data) case TrackLevel.TrackIfMissing => getClasspath(exportedProductsIfMissing, dep, conf, data) - case TrackLevel.TrackAlways => getClasspath(exportedProductsAlways, dep, conf, data) + case TrackLevel.TrackAlways => getClasspath(exportedProducts, dep, conf, data) } private[sbt] def unmanagedLibs0(dep: ResolvedReference, conf: String, data: Settings[Scope], track: TrackLevel): Task[Classpath] = unmanagedLibs(dep, conf, data) diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index 14b3b8d0f..566d8ed49 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -234,7 +234,6 @@ object Keys { val productDirectories = TaskKey[Seq[File]]("product-directories", "Base directories of build products.", CTask) val exportJars = SettingKey[Boolean]("export-jars", "Determines whether the exported classpath for this project contains classes (false) or a packaged jar (true).", BSetting) val exportedProducts = TaskKey[Classpath]("exported-products", "Build products that go on the exported classpath.", CTask) - val exportedProductsAlways = TaskKey[Classpath]("exported-products-always", "Build products that go on the exported classpath for other projects.", CTask) val exportedProductsIfMissing = TaskKey[Classpath]("exported-products-if-missing", "Build products that go on the exported classpath if missing.", CTask) val exportedProductsNoTracking = TaskKey[Classpath]("exported-products-no-tracking", "Just the exported classpath without triggering the compilation.", CTask) val unmanagedClasspath = TaskKey[Classpath]("unmanaged-classpath", "Classpath entries (deep) that are manually managed.", BPlusTask) diff --git a/main/src/main/scala/sbt/Load.scala b/main/src/main/scala/sbt/Load.scala index e5d8a5113..ecd04cf07 100755 --- a/main/src/main/scala/sbt/Load.scala +++ b/main/src/main/scala/sbt/Load.scala @@ -71,12 +71,19 @@ object Load { if (files.isEmpty || base == globalBase) const(Nil) else buildGlobalSettings(globalBase, files, config) config.copy(injectSettings = config.injectSettings.copy(projectLoaded = compiled)) } + // We are hiding a bug fix on global setting that was not importing auto imports. + // Because fixing this via https://github.com/sbt/sbt/pull/2399 + // breaks the source compatibility: https://github.com/sbt/sbt/issues/2415 + @deprecated("Remove this when we can break source compatibility.", "0.13.10") + private[sbt] def useAutoImportInGlobal = sys.props.get("sbt.global.autoimport") map { _.toLowerCase == "true" } getOrElse false def buildGlobalSettings(base: File, files: Seq[File], config: sbt.LoadBuildConfiguration): ClassLoader => Seq[Setting[_]] = { val eval = mkEval(data(config.globalPluginClasspath), base, defaultEvalOptions) val imports = BuildUtil.baseImports ++ - config.detectedGlobalPlugins.imports + (// when we can beak the source compat, remove this if and use config.detectedGlobalPlugins.imports + if (useAutoImportInGlobal) config.detectedGlobalPlugins.imports + else BuildUtil.importAllRoot(config.globalPluginNames)) loader => { val loaded = EvaluateConfigurations(eval, files, imports)(loader) diff --git a/notes/0.13.10/consider-signatures-after-erasure.md b/notes/0.13.10/consider-signatures-after-erasure.md deleted file mode 100644 index f511a5aba..000000000 --- a/notes/0.13.10/consider-signatures-after-erasure.md +++ /dev/null @@ -1,12 +0,0 @@ - - [@Duhemm]: http://github.com/Duhemm - [1171]: https://github.com/sbt/sbt/issues/1171 - [2261]: https://github.com/sbt/sbt/pull/2261 - -### Fixes with compatibility implications - -### Improvements -- Register signatures of method before and after erasure if they involve value classes [#2261][2261] by [@Duhemm][@Duhemm] - -### Bug fixes -- Incremental compiler misses change to value class, and results to NoSuchMethodError at runtime [#1171][1171] \ No newline at end of file diff --git a/notes/0.13.10/dotty-awareness.md b/notes/0.13.10/dotty-awareness.md deleted file mode 100644 index 5660f9bcd..000000000 --- a/notes/0.13.10/dotty-awareness.md +++ /dev/null @@ -1,16 +0,0 @@ - - [Dotty]: https://github.com/lampepfl/dotty - [@smarter]: https://github.com/smarter - -### Fixes with compatibility implications - -### Improvements - -- sbt is now aware of [Dotty][Dotty], it will assume - that Dotty is used when `scalaVersion` starts with `0.`, the sbt - compiler-bridge does not support Dotty but a separate compiler-bridge is being - developed at https://github.com/smarter/dotty-bridge and an example project - that uses it is available at https://github.com/smarter/dotty-example-project - by [@smarter][@smarter]. - -### Bug fixes diff --git a/notes/0.13.10/drop-sealed-from-Append-typeclasses.markdown b/notes/0.13.10/drop-sealed-from-Append-typeclasses.markdown deleted file mode 100644 index 6ad216120..000000000 --- a/notes/0.13.10/drop-sealed-from-Append-typeclasses.markdown +++ /dev/null @@ -1,10 +0,0 @@ - - [1171]: https://github.com/sbt/sbt/issues/1171 - [2322]: https://github.com/sbt/sbt/pull/2322 - -### Fixes with compatibility implications - -### Improvements -- Drops `sealed` from the typeclasses in Append. [#2322][] by [@dwijnand][] - -### Bug fixes diff --git a/notes/0.13.10/internal-tracking.md b/notes/0.13.10/internal-tracking.md deleted file mode 100644 index eacdd2dec..000000000 --- a/notes/0.13.10/internal-tracking.md +++ /dev/null @@ -1,32 +0,0 @@ - - [@eed3si9n]: https://github.com/eed3si9n - [2266]: https://github.com/sbt/sbt/issues/2266 - [2354]: https://github.com/sbt/sbt/pull/2354 - -### Improvements - -- Adds `trackInternalDependencies` and `exportToInternal` keys. See below. - -### Inter-project dependency tracking - -sbt 0.13.10 adds `trackInternalDependencies` and `exportToInternal` settings. These can be used to control whether to trigger compilation of a dependent subprojects when you call `compile`. Both keys will take one of three values: `TrackLevel.NoTracking`, `TrackLevel.TrackIfMissing`, and `TrackLevel.TrackAlways`. By default they are both set to `TrackLevel.TrackAlways`. - -When `trackInternalDependencies` is set to `TrackLevel.TrackIfMissing`, sbt will no longer try to compile internal (inter-project) dependencies automatically, unless there are no `*.class` files (or JAR file when `exportJars` is `true`) in the output directory. When the setting is set to `TrackLevel.NoTracking`, the compilation of internal dependencies will be skipped. Note that the classpath will still be appended, and dependency graph will still show them as dependencies. The motivation is to save the I/O overhead of checking for the changes on a build with many subprojects during development. Here's how to set all subprojects to `TrackIfMissing`. - - lazy val root = (project in file(".")). - aggregate(....). - settings( - inThisBuild(Seq( - trackInternalDependencies := TrackLevel.TrackIfMissing, - exportJars := true - )) - ) - -The `exportToInternal` setting allows the dependee subprojects to opt out of the internal tracking, which might be useful if you want to track most subprojects except for a few. The intersection of the `trackInternalDependencies` and `exportToInternal` settings will be used to determine the actual track level. Here's an example to opt-out one project: - - lazy val dontTrackMe = (project in file("dontTrackMe")). - settings( - exportToInternal := TrackLevel.NoTracking - ) - -[#2266][2266]/[#2354][2354] by [@eed3si9n][@eed3si9n] diff --git a/notes/0.13.10.markdown b/notes/0.13.11.markdown similarity index 64% rename from notes/0.13.10.markdown rename to notes/0.13.11.markdown index b42df40fa..3b9d369a8 100644 --- a/notes/0.13.10.markdown +++ b/notes/0.13.11.markdown @@ -13,99 +13,124 @@ [@DavidPerezIngeniero]: https://github.com/DavidPerezIngeniero [@romanowski]: https://github.com/romanowski [@timcharper]: https://github.com/timcharper - [2302]: https://github.com/sbt/sbt/issues/2302 - [2303]: https://github.com/sbt/sbt/pull/2303 + [@smarter]: https://github.com/smarter + [@retronym]: https://github.com/retronym + + [Dotty]: https://github.com/lampepfl/dotty + [JLine2]: https://github.com/jline/jline2 + + [14]: https://github.com/sbt/ivy/pull/14 + [17]: https://github.com/sbt/ivy/pull/17 + [18]: https://github.com/sbt/ivy/pull/18 + + [1171]: https://github.com/sbt/sbt/issues/1171 + [1514]: https://github.com/sbt/sbt/issues/1514 + [1616]: https://github.com/sbt/sbt/issues/1616 + [1681]: https://github.com/sbt/sbt/issues/1681 + [1750]: https://github.com/sbt/sbt/issues/1750 + [1827]: https://github.com/sbt/sbt/issues/1827 + [1933]: https://github.com/sbt/sbt/issues/1933 [1967]: https://github.com/sbt/sbt/issues/1967 - [2085]: https://github.com/sbt/sbt/pull/2085 + [1968]: https://github.com/sbt/sbt/issues/1968 + [2041]: https://github.com/sbt/sbt/issues/2041 [2071]: https://github.com/sbt/sbt/issues/2071 + [2085]: https://github.com/sbt/sbt/pull/2085 + [2087]: https://github.com/sbt/sbt/issues/2087 [2091]: https://github.com/sbt/sbt/pull/2091 [2092]: https://github.com/sbt/sbt/pull/2092 - [2095]: https://github.com/sbt/sbt/pull/2095 [2094]: https://github.com/sbt/sbt/pull/2094 - [2112]: https://github.com/sbt/sbt/pull/2112 - [2108]: https://github.com/sbt/sbt/pull/2108 - [2106]: https://github.com/sbt/sbt/pull/2106 - [2041]: https://github.com/sbt/sbt/issues/2041 - [2087]: https://github.com/sbt/sbt/issues/2087 + [2095]: https://github.com/sbt/sbt/pull/2095 [2103]: https://github.com/sbt/sbt/pull/2103 + [2106]: https://github.com/sbt/sbt/pull/2106 [2107]: https://github.com/sbt/sbt/issues/2107 + [2108]: https://github.com/sbt/sbt/pull/2108 + [2109]: https://github.com/sbt/sbt/issues/2109 + [2112]: https://github.com/sbt/sbt/pull/2112 [2114]: https://github.com/sbt/sbt/pull/2114 [2117]: https://github.com/sbt/sbt/pull/2117 - [2109]: https://github.com/sbt/sbt/issues/2109 - [2127]: https://github.com/sbt/sbt/pull/2127 - [14]: https://github.com/sbt/ivy/pull/14 [2118]: https://github.com/sbt/sbt/issues/2118 + [2120]: https://github.com/sbt/sbt/issues/2120 + [2127]: https://github.com/sbt/sbt/pull/2127 [2137]: https://github.com/sbt/sbt/pull/2137 [2139]: https://github.com/sbt/sbt/pull/2139 [2142]: https://github.com/sbt/sbt/pull/2142 - [2155]: https://github.com/sbt/sbt/issues/2155 - [2160]: https://github.com/sbt/sbt/pull/2160 - [2158]: https://github.com/sbt/sbt/pull/2158 - [1681]: https://github.com/sbt/sbt/issues/1681 - [2173]: https://github.com/sbt/sbt/pull/2173 - [JLine2]: https://github.com/jline/jline2 [2151]: https://github.com/sbt/sbt/pull/2151 - [1750]: https://github.com/sbt/sbt/issues/1750 - [17]: https://github.com/sbt/ivy/pull/17 + [2155]: https://github.com/sbt/sbt/issues/2155 + [2158]: https://github.com/sbt/sbt/pull/2158 + [2160]: https://github.com/sbt/sbt/pull/2160 [2163]: https://github.com/sbt/sbt/pull/2163 - [18]: https://github.com/sbt/ivy/pull/18 + [2172]: https://github.com/sbt/sbt/pull/2172 + [2173]: https://github.com/sbt/sbt/pull/2173 [2186]: https://github.com/sbt/sbt/pull/2186 - [2197]: https://github.com/sbt/sbt/pull/2197 [2192]: https://github.com/sbt/sbt/pull/2192 + [2197]: https://github.com/sbt/sbt/pull/2197 [2201]: https://github.com/sbt/sbt/pull/2201 [2214]: https://github.com/sbt/sbt/pull/2214 - [1933]: https://github.com/sbt/sbt/issues/1933 - [2258]: https://github.com/sbt/sbt/pull/2258 - [2228]: https://github.com/sbt/sbt/issues/2228 - [2271]: https://github.com/sbt/sbt/pull/2271 - [2285]: https://github.com/sbt/sbt/pull/2285 - [2256]: https://github.com/sbt/sbt/issues/2256 - [2272]: https://github.com/sbt/sbt/pull/2272 - [1968]: https://github.com/sbt/sbt/issues/1968 - [2264]: https://github.com/sbt/sbt/issues/2264 - [2172]: https://github.com/sbt/sbt/pull/2172 [2217]: https://github.com/sbt/sbt/issues/2217 + [2228]: https://github.com/sbt/sbt/issues/2228 + [2256]: https://github.com/sbt/sbt/issues/2256 + [2258]: https://github.com/sbt/sbt/pull/2258 + [2261]: https://github.com/sbt/sbt/pull/2261 + [2264]: https://github.com/sbt/sbt/issues/2264 + [2266]: https://github.com/sbt/sbt/issues/2266 + [2271]: https://github.com/sbt/sbt/pull/2271 + [2272]: https://github.com/sbt/sbt/pull/2272 + [2285]: https://github.com/sbt/sbt/pull/2285 + [2302]: https://github.com/sbt/sbt/issues/2302 + [2303]: https://github.com/sbt/sbt/pull/2303 + [2311]: https://github.com/sbt/sbt/pull/2311 + [2313]: https://github.com/sbt/sbt/pull/2313 + [2322]: https://github.com/sbt/sbt/pull/2322 [2324]: https://github.com/sbt/sbt/issues/2324 [2325]: https://github.com/sbt/sbt/pull/2325 [2336]: https://github.com/sbt/sbt/issues/2336 - [1514]: https://github.com/sbt/sbt/issues/1514 - [1616]: https://github.com/sbt/sbt/issues/1616 - [2313]: https://github.com/sbt/sbt/pull/2313 [2343]: https://github.com/sbt/sbt/pull/2343 - [2120]: https://github.com/sbt/sbt/issues/2120 + [2344]: https://github.com/sbt/sbt/pull/2344 + [2354]: https://github.com/sbt/sbt/pull/2354 [2399]: https://github.com/sbt/sbt/pull/2399 + [2453]: https://github.com/sbt/sbt/pull/2453 + [2467]: https://github.com/sbt/sbt/pull/2467 + [101]: https://github.com/sbt/sbt-launcher-package/pull/101 + [105]: https://github.com/sbt/sbt-launcher-package/pull/105 ### Fixes with compatibility implications -- sbt 0.13.10 adds a new setting `useJCenter`, which is set to `false` by default. When set to `true`, JCenter will be placed as the first external resolver to find library dependencies. [#2217][2217] by [@eed3si9n][@eed3si9n] +- JCenter is now opt-in. A new setting `useJCenter` can be set to `true` to re-include it, as the first external resolver to find library dependencies. [#2217][2217]/[#2467][2467] by [@eed3si9n][@eed3si9n] - Adds `withInterProjectFirst` to the update option, which is enabled by default. When set to `true`, `inter-project` resolver will be prioritized above all resolvers and Ivy cache. [#1827][1827] by [@eed3si9n][@eed3si9n] - Fixes update option's `withLatestSnapshots` so it handles modules without an artifact. This flag will be enabled by default. [#1514][1514]/[#1616][1616]/[#2313][2313] by [@eed3si9n][@eed3si9n] -- sbt will no longer pass `-J` options to the local Java compiler. [#1968][1968]/[#2272][2272] by [@Duhemm][@Duhemm] +- No longer passes `-J` options to the local Java compiler. [#1968][1968]/[#2272][2272] by [@Duhemm][@Duhemm] +- Fixes auto imports for auto plugins in global configuration files. Because this is *not* source compatible with 0.13.x, the fix is enabled only when `sbt.global.autoimport` flag is `true`. [#2120][2120]/[#2399][2399] by [@timcharper][@timcharper] ### Improvements +- Adds configurable compiler bridge. See below. +- Adds initial support for [Dotty][Dotty]. See below +- Adds settings for granular inter-project dependency tracking. See below. - Scala version used by the build is updated to 2.10.6. [#2311][2311] by [@eed3si9n][@eed3si9n] - If `publishMavenStyle` is `true`, `update` task warns when it sees intransitive dependencies, which do not translate to Maven. [#2127][2127] by [@jsuereth][@jsuereth] - Adds `Def.settings`, which facilitates mixing settings with seq of settings. See below. -- Adds configurable compiler bridge. See below. -- sbt Serialization is updated to 0.1.2. [2117][#2117] by [@dwijnand][@dwijnand] +- sbt Serialization is updated to 0.1.2. [#2117][2117] by [@dwijnand][@dwijnand] - Hides the stack trace on compilation error in build definition. [#2071][2071]/[#2091][2091] by [@Duhemm][@Duhemm] - Makes the dummy `Logger.Null` public. [#2094][2094] by [@pdalpra][@pdalpra] - Uses diagnostic classes to get lines contents in local Java compiler. [#2108][2108]/[#2201][2201] by [@fkorotkov][@fkorotkov] -- Logs javaOptions used when forking. [#2087][2087]/[#2103][2103] by [@pdalpra][@pdalpra] +- Adds logging of javaOptions. [#2087][2087]/[#2103][2103] by [@pdalpra][@pdalpra] - Warns when javaOptions are defined but fork is set to false. [#2041][2041]/[#2103][2103] by [@pdalpra][@pdalpra] - Adds an `Append.Sequence` instance for `List` to allow `+=`/`++=` on `developers` setting. [#2107][2107]/[#2114][2114] by [@pdalpra][@pdalpra] -- Fixes warnings, and other clean ups. [#2112][2112]/[#2137][2137]/[#2139][2139]/[#2142][2142] by [@pdalpra][@pdalpra] +- Drops `sealed` from the typeclasses in `Append`. [#2322][2322] by [@dwijnand][@dwijnand] +- Fixes compilation warnings in sbt's codebase, and other clean ups. [#2112][2112]/[#2137][2137]/[#2139][2139]/[#2142][2142] by [@pdalpra][@pdalpra] - Adds `localIfFile` to `MavenRepository`, to force artifacts to be copied to the cache. [#2172][2172] by [@dwijnand][@dwijnand] - Adds `Resolver.bintrayIvyRepo(owner, repo)`. [#2285][2285] by [@dwijnand][@dwijnand] - Non-static annotation changes are no longer tracked by the incremental compiler. [#2343][2343] by [@romanowski][@romanowski] - Reduces the memory usage of API info extraction in the incremental compiler. [#2343][2343] by [@adriaanm][@adriaanm] +- Memory-related options can now be overridden individually via the `-J` options. [sbt/sbt-launcher-package#105][105] ### Bug fixes - Fixes the false positive of inconsistent duplicate warnings. [#1933][1933]/[#2258][2258] by [@Duhemm][@Duhemm] +- Fixes task scheduling performance on large builds by skipping checks in `sbt.Execute`. [#2302][2302]/[#2303][2303] by [@jrudolph][@jrudolph] +- Fixes changes in value classes by registering signatures of method before and after erasure. [#1171][1171]/[#2261][2261] by [@Duhemm][@Duhemm] - Updated Ivy to merge IVY-1526 fix. [sbt/ivy#14][14]/[#2118][2118] by [@jsuereth][@jsuereth] - Fixes `updateClassifiers` downloading updated snapshot sources and docs. [#1750][1750]/[sbt/ivy#17][17]/[#2163][2163]/[sbt/ivy#18][18]/[#2186][2186] by [@dwijnand][@dwijnand] @@ -127,11 +152,50 @@ - Adds more robustness to `tasks` and `settings` command. [#2192][2192] by [@DavidPerezIngeniero][@DavidPerezIngeniero] - Fixes Java compilation inconsistencies between sbt and `javac` by always failing if the local Java compiler reported errors. [#2228][2228]/[#2271][2271] by [@Duhemm][@Duhemm] - Fixes `JavaErrorParser` to parse non-compile-errors [#2256][2256]/[#2272][2272] by [@Duhemm][@Duhemm] -- Fixes task scheduling performance on large builds by skipping checks in `sbt.Execute`. [#2302][2302]/[#2303][2303] by [@jrudolph][@jrudolph] - Fixes launcher configuration to add `sbt-ivy-snapshots` repository to resolve nightly builds. [@eed3si9n][@eed3si9n] - Fixes performance issues during tree traversal in the incremental compiler. [#2343][2343] by [@adriaanm][@adriaanm] - Fixes the tracking of self types and F-bounded existential types in the incremental compiler. [#2343][2343] by [@adriaanm][@adriaanm] -- Fixes autoImports for AutoPlugins for global configuration files. [#2120][2120]/[#2399][2399] by [@timcharper][@timcharper] +- Avoid CCE when scalac internally uses `compileLate`. [#2453][2453] by [@retronym][@retronym] +- Fixes the memory-related options overriding `SBT_OPTS`. [sbt/sbt-launcher-package#101][101] by [@eed3si9n][@eed3si9n] + +### Configurable Scala compiler bridge + +sbt 0.13.11 adds `scalaCompilerBridgeSource` setting to specify the compiler brigde source. This allows different implementation of the bridge for Scala versions, and also allows future versions of Scala compiler implementation to diverge. The source module will be retrieved using library management configured by `bootIvyConfiguration` task. + +[#2106][2106]/[#2197][2197]/[#2336][2336] by [@Duhemm][@Duhemm] + +### Dotty awareness + +sbt 0.13.11 will assume that Dotty is used when `scalaVersion` starts with `0.`. +The built-in compiler bridge in sbt does not support Dotty, +but a separate compiler bridge is being developed at [smarter/dotty-bridge](https://github.com/smarter/dotty-bridge) and +an example project that uses it is available at [smarter/dotty-example-project](https://github.com/smarter/dotty-example-project). + +[#2344][2344] by [@smarter][@smarter] + +### Inter-project dependency tracking + +sbt 0.13.11 adds `trackInternalDependencies` and `exportToInternal` settings. These can be used to control whether to trigger compilation of a dependent subprojects when you call `compile`. Both keys will take one of three values: `TrackLevel.NoTracking`, `TrackLevel.TrackIfMissing`, and `TrackLevel.TrackAlways`. By default they are both set to `TrackLevel.TrackAlways`. + +When `trackInternalDependencies` is set to `TrackLevel.TrackIfMissing`, sbt will no longer try to compile internal (inter-project) dependencies automatically, unless there are no `*.class` files (or JAR file when `exportJars` is `true`) in the output directory. When the setting is set to `TrackLevel.NoTracking`, the compilation of internal dependencies will be skipped. Note that the classpath will still be appended, and dependency graph will still show them as dependencies. The motivation is to save the I/O overhead of checking for the changes on a build with many subprojects during development. Here's how to set all subprojects to `TrackIfMissing`. + + lazy val root = (project in file(".")). + aggregate(....). + settings( + inThisBuild(Seq( + trackInternalDependencies := TrackLevel.TrackIfMissing, + exportJars := true + )) + ) + +The `exportToInternal` setting allows the dependee subprojects to opt out of the internal tracking, which might be useful if you want to track most subprojects except for a few. The intersection of the `trackInternalDependencies` and `exportToInternal` settings will be used to determine the actual track level. Here's an example to opt-out one project: + + lazy val dontTrackMe = (project in file("dontTrackMe")). + settings( + exportToInternal := TrackLevel.NoTracking + ) + +[#2266][2266]/[#2354][2354] by [@eed3si9n][@eed3si9n] ### Def.settings @@ -143,9 +207,3 @@ Using `Def.settings` it is now possible to nicely define settings as such: ) [#2151][2151] by [@dwijnand][@dwijnand] - -### Configurable Scala compiler bridge - -sbt 0.13.10 adds `scalaCompilerBridgeSource` setting to specify the compiler brigde source. This allows different implementation of the bridge for Scala versions, and also allows future versions of Scala compiler implementation to diverge. The source module will be retrieved using library management configured by `bootIvyConfiguration` task. - -[#2106][2106]/[#2197][2197]/[#2336][2336] by [@Duhemm][@Duhemm] diff --git a/sbt/src/sbt-test/dependency-management/default-resolvers/test b/sbt/src/sbt-test/dependency-management/default-resolvers/test index 2513e8edf..0d310c9f5 100644 --- a/sbt/src/sbt-test/dependency-management/default-resolvers/test +++ b/sbt/src/sbt-test/dependency-management/default-resolvers/test @@ -3,3 +3,9 @@ > set useJCenter := true > check2 + +> reload + +> set resolvers += Resolver.jcenterRepo + +> check2 diff --git a/sbt/src/sbt-test/project/global-plugin/global/plugins/A.scala b/sbt/src/sbt-test/project/global-plugin/global/plugins/A.scala index bbf9fc243..b75a623b5 100644 --- a/sbt/src/sbt-test/project/global-plugin/global/plugins/A.scala +++ b/sbt/src/sbt-test/project/global-plugin/global/plugins/A.scala @@ -1,15 +1,5 @@ package test -import sbt._ - object Global { val x = 3 } - -object GlobalAutoPlugin extends AutoPlugin { - - object autoImport { - lazy val globalAutoPluginSetting = settingKey[String]("A top level setting declared in a plugin.") - } - -} diff --git a/sbt/src/sbt-test/project/global-settings/global/plugins/A.scala b/sbt/src/sbt-test/project/global-settings/global/plugins/A.scala new file mode 100644 index 000000000..ee7171f10 --- /dev/null +++ b/sbt/src/sbt-test/project/global-settings/global/plugins/A.scala @@ -0,0 +1,11 @@ +package test + +import sbt._ + +object GlobalAutoPlugin extends AutoPlugin { + + object autoImport { + lazy val globalAutoPluginSetting = settingKey[String]("A top level setting declared in a plugin.") + } + +} diff --git a/sbt/src/sbt-test/project/global-plugin/global/plugins/B.scala b/sbt/src/sbt-test/project/global-settings/global/plugins/B.scala similarity index 100% rename from sbt/src/sbt-test/project/global-plugin/global/plugins/B.scala rename to sbt/src/sbt-test/project/global-settings/global/plugins/B.scala diff --git a/sbt/src/sbt-test/project/global-plugin/global/useGlobalAutoPlugin.sbt b/sbt/src/sbt-test/project/global-settings/global/useGlobalAutoPlugin.sbt similarity index 100% rename from sbt/src/sbt-test/project/global-plugin/global/useGlobalAutoPlugin.sbt rename to sbt/src/sbt-test/project/global-settings/global/useGlobalAutoPlugin.sbt diff --git a/sbt/src/sbt-test/project/global-plugin/global/useGlobalLegacyPlugin.sbt b/sbt/src/sbt-test/project/global-settings/global/useGlobalLegacyPlugin.sbt similarity index 100% rename from sbt/src/sbt-test/project/global-plugin/global/useGlobalLegacyPlugin.sbt rename to sbt/src/sbt-test/project/global-settings/global/useGlobalLegacyPlugin.sbt diff --git a/sbt/src/sbt-test/project/global-settings/pending b/sbt/src/sbt-test/project/global-settings/pending new file mode 100644 index 000000000..1b6bd3c6f --- /dev/null +++ b/sbt/src/sbt-test/project/global-settings/pending @@ -0,0 +1,3 @@ +# This test is marked pending because sbt.globalsettingfix flag is off by default +# See https://github.com/sbt/sbt/issues/2415 +> name diff --git a/sbt/src/sbt-test/source-dependencies/trait-member-modified/test b/sbt/src/sbt-test/source-dependencies/trait-member-modified/test new file mode 100644 index 000000000..f8f7cb076 --- /dev/null +++ b/sbt/src/sbt-test/source-dependencies/trait-member-modified/test @@ -0,0 +1,9 @@ +# Test if adding a member to a trait affects classes that refer to that trait +# by a member reference +> compile +# add `foo` method to `A` +$ copy-file changes/A1.scala src/main/scala/A.scala +# only A.scala should be recompiled +> compile +# check if there are only two compile iterations performed +> check-compilations diff --git a/sbt/src/sbt-test/source-dependencies/trait-private-object/A.scala b/sbt/src/sbt-test/source-dependencies/trait-private-object/A.scala new file mode 100644 index 000000000..cbcda3176 --- /dev/null +++ b/sbt/src/sbt-test/source-dependencies/trait-private-object/A.scala @@ -0,0 +1,3 @@ +trait A { + val foo = 0 +} \ No newline at end of file diff --git a/sbt/src/sbt-test/source-dependencies/trait-private-object/B.scala b/sbt/src/sbt-test/source-dependencies/trait-private-object/B.scala new file mode 100644 index 000000000..5da0f8a71 --- /dev/null +++ b/sbt/src/sbt-test/source-dependencies/trait-private-object/B.scala @@ -0,0 +1,5 @@ +object B extends A { + def main(args: Array[String]): Unit = { + println(foo) + } +} diff --git a/sbt/src/sbt-test/source-dependencies/trait-private-object/changes/A.scala b/sbt/src/sbt-test/source-dependencies/trait-private-object/changes/A.scala new file mode 100644 index 000000000..b5600153b --- /dev/null +++ b/sbt/src/sbt-test/source-dependencies/trait-private-object/changes/A.scala @@ -0,0 +1,4 @@ +trait A { + val foo = 0 + X.a + private object X { val a = 1 } +} \ No newline at end of file diff --git a/sbt/src/sbt-test/source-dependencies/trait-private-object/test b/sbt/src/sbt-test/source-dependencies/trait-private-object/test new file mode 100644 index 000000000..5aab7a143 --- /dev/null +++ b/sbt/src/sbt-test/source-dependencies/trait-private-object/test @@ -0,0 +1,5 @@ +> run + +$ copy-file changes/A.scala A.scala + +> run \ No newline at end of file diff --git a/sbt/src/sbt-test/source-dependencies/trait-private-var/A.scala b/sbt/src/sbt-test/source-dependencies/trait-private-var/changes/A0.scala similarity index 100% rename from sbt/src/sbt-test/source-dependencies/trait-private-var/A.scala rename to sbt/src/sbt-test/source-dependencies/trait-private-var/changes/A0.scala diff --git a/sbt/src/sbt-test/source-dependencies/trait-private-var/changes/A.scala b/sbt/src/sbt-test/source-dependencies/trait-private-var/changes/A1.scala similarity index 100% rename from sbt/src/sbt-test/source-dependencies/trait-private-var/changes/A.scala rename to sbt/src/sbt-test/source-dependencies/trait-private-var/changes/A1.scala diff --git a/sbt/src/sbt-test/source-dependencies/trait-private-var/changes/A2.scala b/sbt/src/sbt-test/source-dependencies/trait-private-var/changes/A2.scala new file mode 100644 index 000000000..60641457d --- /dev/null +++ b/sbt/src/sbt-test/source-dependencies/trait-private-var/changes/A2.scala @@ -0,0 +1,5 @@ +trait A { + private val foo = 12 + // we need to access foo to trigger AbstractMethodError + def bar: Int = foo +} diff --git a/sbt/src/sbt-test/source-dependencies/trait-private-var/test b/sbt/src/sbt-test/source-dependencies/trait-private-var/test index d928246a9..c120697d8 100644 --- a/sbt/src/sbt-test/source-dependencies/trait-private-var/test +++ b/sbt/src/sbt-test/source-dependencies/trait-private-var/test @@ -1,14 +1,28 @@ +$ copy-file changes/A0.scala A.scala + # compile and run for the first time to verify that everything works > run # introduce private var and refer to it in a trait that we inherit from # there'll be pair of getters and setters generated for private var that # has to be implemented by a class (where you can declare corresponding field) -$ copy-file changes/A.scala A.scala +$ copy-file changes/A1.scala A.scala -# this fails with AbstractMethodError because getters and setters for -# a private var are not generated because introduction of a private var -# does not trigger recompilation of B -# B is not recompiled because incremental compiler tracks only public -# interace (members visible from outside of given trait/class) +# If the introduction of a private var did not trigger the recompilation of B, +# then this will fail with AbstractMethodError because the getters and setters +# for the private var have not been generated. +> run + +# Try again with a private val +> clean + +$ copy-file changes/A0.scala A.scala + +# compile and run a clean project to verify that everything works +> run + +# introduce a private val in the trait +$ copy-file changes/A2.scala A.scala + +# Verify that B has been recompiled and that everything runs fine. > run diff --git a/sbt/src/sbt-test/source-dependencies/value-class/changes/B2.scala b/sbt/src/sbt-test/source-dependencies/value-class/changes/B2.scala new file mode 100644 index 000000000..fe1136389 --- /dev/null +++ b/sbt/src/sbt-test/source-dependencies/value-class/changes/B2.scala @@ -0,0 +1,3 @@ +class B { + def bar(dummy: String)(dummy2: String): A = new A(0) +} diff --git a/sbt/src/sbt-test/source-dependencies/value-class/changes/C2.scala b/sbt/src/sbt-test/source-dependencies/value-class/changes/C2.scala new file mode 100644 index 000000000..17b70f957 --- /dev/null +++ b/sbt/src/sbt-test/source-dependencies/value-class/changes/C2.scala @@ -0,0 +1,3 @@ +object C extends App { + println(new B().bar("")("").x) +} diff --git a/sbt/src/sbt-test/source-dependencies/value-class/test b/sbt/src/sbt-test/source-dependencies/value-class/test index f78acb2d8..268274bf6 100644 --- a/sbt/src/sbt-test/source-dependencies/value-class/test +++ b/sbt/src/sbt-test/source-dependencies/value-class/test @@ -1,3 +1,4 @@ +## Case 1: value class as parameter of method $ copy-file changes/A0.scala src/main/scala/A.scala $ copy-file changes/B0.scala src/main/scala/B.scala $ copy-file changes/C0.scala src/main/scala/C.scala @@ -13,6 +14,8 @@ $ copy-file changes/A1.scala src/main/scala/A.scala # This means that we have invalidated C.scala, as expected! -> compile + +## Case 2: value class as return type of method with no parameter lists $ copy-file changes/A0.scala src/main/scala/A.scala $ copy-file changes/B1.scala src/main/scala/B.scala $ copy-file changes/C1.scala src/main/scala/C.scala @@ -28,3 +31,20 @@ $ copy-file changes/A1.scala src/main/scala/A.scala # because A is now a value class. > run + +## Case 3: value class as return type of method with multiple parameter lists +$ copy-file changes/A0.scala src/main/scala/A.scala +$ copy-file changes/B2.scala src/main/scala/B.scala +$ copy-file changes/C2.scala src/main/scala/C.scala + +# A is a normal class. B.bar takes two dummy arguments and returns an instance of A. C calls B.bar("")(""). +> compile +> run + +# Make A a value class. +$ copy-file changes/A1.scala src/main/scala/A.scala + +# The code compiles. It will run iff C is recompiled because the signature of B.bar has changed, +# because A is now a value class. +> run + diff --git a/src/main/conscript/sbt/launchconfig b/src/main/conscript/sbt/launchconfig index 033dc550b..eafdc7534 100644 --- a/src/main/conscript/sbt/launchconfig +++ b/src/main/conscript/sbt/launchconfig @@ -4,7 +4,7 @@ [app] org: ${sbt.organization-org.scala-sbt} name: sbt - version: ${sbt.version-read(sbt.version)[0.13.9]} + version: ${sbt.version-read(sbt.version)[0.13.11]} class: sbt.xMain components: xsbti,extra cross-versioned: ${sbt.cross.versioned-false} diff --git a/src/main/conscript/scalas/launchconfig b/src/main/conscript/scalas/launchconfig index 0d0d5664c..02d28dd3f 100644 --- a/src/main/conscript/scalas/launchconfig +++ b/src/main/conscript/scalas/launchconfig @@ -4,7 +4,7 @@ [app] org: ${sbt.organization-org.scala-sbt} name: sbt - version: ${sbt.version-read(sbt.version)[0.13.9]} + version: ${sbt.version-read(sbt.version)[0.13.11]} class: sbt.ScriptMain components: xsbti,extra cross-versioned: ${sbt.cross.versioned-false} diff --git a/src/main/conscript/screpl/launchconfig b/src/main/conscript/screpl/launchconfig index afa5eb125..f3a2907c4 100644 --- a/src/main/conscript/screpl/launchconfig +++ b/src/main/conscript/screpl/launchconfig @@ -4,7 +4,7 @@ [app] org: ${sbt.organization-org.scala-sbt} name: sbt - version: ${sbt.version-read(sbt.version)[0.13.9]} + version: ${sbt.version-read(sbt.version)[0.13.11]} class: sbt.ConsoleMain components: xsbti,extra cross-versioned: ${sbt.cross.versioned-false}