The previous logic was wrong and included all members of traits in their
API hash, which degraded the performance of the incremental compiler.
This commit changes this logic so that only the non-public members of
traits are included into their API hash.
Fixes#2436
It's not clear what the distinction between compiler-project and
source-dependencies scripted tests is so let's stick to the one that has
the biggest number of tests for incremental compiler.
The test shows that name hashing optimization is broken for members
defined in traits. The problem is that modification of a member of a trait
triggers change of a hash of trait's name.
The behavior covered by this test regressed in
40ebc82531
The bug is tracked in #2436.
Add a new field in `Source` that indicates whether this `Source`
represents a package object. This field is used in the incrmental
compiler to perform recompilation of package objects rather than relying
on the file name being `package.scala`.
Mark pending test `source-dependencies/package-object-name` as passing.
The convention says to place package objects in files named
`package.scala`, but this is not enforced by the scala specification.
The incremental compiler currently offers special treatment for files
whose name is `package.scala`, but it should rather care about whether a
file defines a package object or not.
This test fails because it defines a package object in a file whose name
is not `package.scala`.
It's not clear what the distinction between compiler-project and
source-dependencies scripted tests is so let's stick to the one that has
the biggest number of tests for incremental compiler.
The test shows that name hashing optimization is broken for members
defined in traits. The problem is that modification of a member of a trait
triggers change of a hash of trait's name.
The behavior covered by this test regressed in
40ebc82531
The bug is tracked in #2436.
Modify `invalidatedPackageObjects` to look for package objects that
transitively inherit from an invalidated class instead of just inheriting
directly. This is the correct behavior that should have been implemented
in the first place. The bug comes from a subtle copy&paste mistake. The old
implementation used `publicInherited` relation and new one looks identical
but uses `inheritance` relation. The difference is that `publicInherited`
was a relation that was expanded transitively along inheritance chain but
`inheritance` is not. We have to perform the transitive walk in
`IncrementalNameHashing.invalidatedPackageObjects` implementation.
Mark `pkg-self` test as passing.
Fixes#2326
To aid debugging, modify Relations.toString to include `inheritance` in
addition to already printed `memberRef` relation.
Modify it for both name hashing and old implementation.
The previous version of `pkg-self` covered scenario where a package object
inherited directly from a class that is being modified and recompiled in
subsequent steps. The #2326 shows that name hashing fails to handle
a package object that inherits indirectly from a modified class. In that
case, name hashing fails to invalidate the source file that defines the
package object.
This commit expands `pkg-self` with a class B that inherits from modified
class `A` and makes package object inherit from B. We mark that test as
pending to show that this indeed trigger the bug in name hashing.
If a method's type contains a non-primitive value class then it has two
signatures: one before erasure and one after erasure. Before this
commit, we checked if this was the case using `isAnyValSubtype`, but
this is too crude since primitive value classes are also subtypes of
`AnyVal` but do not change signature after erasure.
This commit replaces `isAnyValSubtype` by `isDerivedValueClass` which
excludes primitive value classes.
In practice, for an empty class, this reduces the size of the output of
`DefaultShowAPI` from 65 lines to 25 lines.
Before:
https://gist.github.com/smarter/cf1d6fe58efda88d6ee6#file-old-api
After:
https://gist.github.com/smarter/cf1d6fe58efda88d6ee6#file-new-api
Before this commit, we did not do the invalidation for methods with
multiple parameter list, the comment above `hasValueClassAsReturnType`
said:
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.
But this is wrong: a method with signature:
def foo(a: A)(b: B): C
is erased to:
def foo(a: A, b: B): C
and not, as the comment in the code suggest, to:
def foo(a: A): B => C
so we do need to inspect the final result type of methods, because they
can be value classes that will be erased to their underlying value.
We are hiding a bug fix on global setting that was not importing auto
imports because fixing this via sbt/sbt#2399 breaks the source
compatibility: sbt/sbt#2415
I've split out the relevant portion of the scripted test into
global-settings, and marked it pending.
This addresses 0.13.10 regression, which currently warns users about
Maven incompatibility on a private configuration. This adds a config
class so the build user can control the level of the warning as well as
the target configuration to be monitored.
By default, we are only going to look at `Compile` and `Runtime`.
Previously, the autoimports for globally defined plugins were not
imported for global configuration files, although they were imported for
project configuration files.
This patch causes an additional plugin discovery phase to happen during
global config evaluation, so that auto-plugins can be detected and their
imports subsequently included.
Tested manually:
$ grep 'version.*:=' build.sbt
version := "0.13.10-SNAPSHOT",
$ git archive --prefix=sbt-0.13.10-SNAPSHOT/ -o ~/Desktop/sbt-0.13.10-SNAPSHOT.tgz HEAD
$ cd ~/Desktop
$ ls
sbt-0.13.10-SNAPSHOT.tgz
$ tar xfz sbt-0.13.10-SNAPSHOT.tgz
$ cd sbt-0.13.10-SNAPSHOT/
$ sbt info
[info] Loading global plugins from /Users/dnw/.dotfiles/.sbt/0.13/plugins
[info] Loading project definition from /Users/dnw/Desktop/sbt-0.13.10-SNAPSHOT/project
[info] Updating {file:/Users/dnw/Desktop/sbt-0.13.10-SNAPSHOT/project/}sbt-0-13-10-snapshot-build...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[warn] There may be incompatibilities among your library dependencies.
[warn] Here are some of the libraries that were evicted:
[warn] * com.typesafe.sbt:sbt-site:0.8.1 -> 0.8.2
[warn] Run 'evicted' to see detailed eviction warnings
[info] Compiling 12 Scala sources to /Users/dnw/Desktop/sbt-0.13.10-SNAPSHOT/project/target/scala-2.10/sbt-0.13/classes...
[info] This is sbt 0.13.9
[info] The current project is {file:/Users/dnw/Desktop/sbt-0.13.10-SNAPSHOT/}sbtRoot 0.13.10-SNAPSHOT
[info] The current project is built against Scala 2.10.6
[info] Available Plugins: sbt.plugins.IvyPlugin, sbt.plugins.JvmPlugin, sbt.plugins.CorePlugin...
[info] sbt, sbt plugins, and build definitions are using Scala 2.10.5
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
)
This is a fixup of 0f616294c4.
That commit assumed that dealiasing is being done for types referred in
self type. It was changed to not do that but the test wasn't updated.
Unfortunately, that mistake slipped by during PR review because unit tests
of compileInterface were not ran (see #2358).