mirror of https://github.com/sbt/sbt.git
Merge pull request #2659 from dwijnand/log-recompile-on-macro-opt
Fixes #2654 Silence macro recompilation info message
This commit is contained in:
commit
9ea9abf98d
|
|
@ -84,7 +84,9 @@ final class IncOptions(
|
|||
/**
|
||||
* Include synthetic methods into the dependency tracking by name hashing.
|
||||
*/
|
||||
val includeSynthToNameHashing: Boolean) extends Product with Serializable {
|
||||
val includeSynthToNameHashing: Boolean,
|
||||
/** Determines whether to log information on file recompiled due to a transitive macro change */
|
||||
val logRecompileOnMacro: Boolean) extends Product with Serializable {
|
||||
|
||||
/**
|
||||
* Secondary constructor introduced to make IncOptions to be binary compatible with version that didn't have
|
||||
|
|
@ -94,7 +96,8 @@ final class IncOptions(
|
|||
apiDiffContextSize: Int, apiDumpDirectory: Option[java.io.File], newClassfileManager: () => ClassfileManager) = {
|
||||
this(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
|
||||
apiDumpDirectory, newClassfileManager, IncOptions.recompileOnMacroDefDefault, IncOptions.nameHashingDefault,
|
||||
IncOptions.antStyleDefault, IncOptions.includeSynthToNameHashingDefault)
|
||||
IncOptions.antStyleDefault, IncOptions.includeSynthToNameHashingDefault,
|
||||
IncOptions.logRecompileOnMacroDefault)
|
||||
}
|
||||
|
||||
def this(transitiveStep: Int, recompileAllFraction: Double, relationsDebug: Boolean, apiDebug: Boolean,
|
||||
|
|
@ -102,64 +105,81 @@ final class IncOptions(
|
|||
recompileOnMacroDef: Boolean, nameHashing: Boolean, antStyle: Boolean) = {
|
||||
this(transitiveStep, recompileAllFraction, relationsDebug, apiDebug,
|
||||
apiDiffContextSize, apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing,
|
||||
antStyle, IncOptions.includeSynthToNameHashingDefault)
|
||||
antStyle, IncOptions.includeSynthToNameHashingDefault, IncOptions.logRecompileOnMacroDefault)
|
||||
}
|
||||
|
||||
assert(!(antStyle && nameHashing), "Name hashing and Ant-style cannot be enabled at the same time.")
|
||||
|
||||
def withTransitiveStep(transitiveStep: Int): IncOptions = {
|
||||
new IncOptions(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle, includeSynthToNameHashing)
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle,
|
||||
includeSynthToNameHashing, logRecompileOnMacro)
|
||||
}
|
||||
|
||||
def withRecompileAllFraction(recompileAllFraction: Double): IncOptions = {
|
||||
new IncOptions(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle, includeSynthToNameHashing)
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle,
|
||||
includeSynthToNameHashing, logRecompileOnMacro)
|
||||
}
|
||||
|
||||
def withRelationsDebug(relationsDebug: Boolean): IncOptions = {
|
||||
new IncOptions(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle, includeSynthToNameHashing)
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle,
|
||||
includeSynthToNameHashing, logRecompileOnMacro)
|
||||
}
|
||||
|
||||
def withApiDebug(apiDebug: Boolean): IncOptions = {
|
||||
new IncOptions(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle, includeSynthToNameHashing)
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle,
|
||||
includeSynthToNameHashing, logRecompileOnMacro)
|
||||
}
|
||||
|
||||
def withApiDiffContextSize(apiDiffContextSize: Int): IncOptions = {
|
||||
new IncOptions(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle, includeSynthToNameHashing)
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle,
|
||||
includeSynthToNameHashing, logRecompileOnMacro)
|
||||
}
|
||||
|
||||
def withApiDumpDirectory(apiDumpDirectory: Option[File]): IncOptions = {
|
||||
new IncOptions(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle, includeSynthToNameHashing)
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle,
|
||||
includeSynthToNameHashing, logRecompileOnMacro)
|
||||
}
|
||||
|
||||
def withNewClassfileManager(newClassfileManager: () => ClassfileManager): IncOptions = {
|
||||
new IncOptions(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle, includeSynthToNameHashing)
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle,
|
||||
includeSynthToNameHashing, logRecompileOnMacro)
|
||||
}
|
||||
|
||||
def withRecompileOnMacroDef(recompileOnMacroDef: Boolean): IncOptions = {
|
||||
new IncOptions(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle, includeSynthToNameHashing)
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle,
|
||||
includeSynthToNameHashing, logRecompileOnMacro)
|
||||
}
|
||||
|
||||
def withNameHashing(nameHashing: Boolean): IncOptions = {
|
||||
new IncOptions(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle, includeSynthToNameHashing)
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle,
|
||||
includeSynthToNameHashing, logRecompileOnMacro)
|
||||
}
|
||||
|
||||
def withIncludeSynthToNameHashing(includeSynthToNameHashing: Boolean): IncOptions = {
|
||||
new IncOptions(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle, includeSynthToNameHashing)
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle,
|
||||
includeSynthToNameHashing, logRecompileOnMacro)
|
||||
}
|
||||
|
||||
def withAntStyle(antStyle: Boolean): IncOptions = {
|
||||
new IncOptions(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle, includeSynthToNameHashing)
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle,
|
||||
includeSynthToNameHashing, logRecompileOnMacro)
|
||||
}
|
||||
|
||||
def withLogRecompileOnMacro(logRecompileOnMacro: Boolean): IncOptions = {
|
||||
new IncOptions(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
|
||||
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle,
|
||||
includeSynthToNameHashing, logRecompileOnMacro)
|
||||
}
|
||||
|
||||
//- EXPANDED CASE CLASS METHOD BEGIN -//
|
||||
|
|
@ -238,6 +258,7 @@ object IncOptions extends Serializable {
|
|||
private val antStyleDefault: Boolean = false
|
||||
// This should default to false
|
||||
private[sbt] val includeSynthToNameHashingDefault = java.lang.Boolean.getBoolean("sbt.inc.include_synth")
|
||||
private[sbt] val logRecompileOnMacroDefault = true
|
||||
val Default = IncOptions(
|
||||
// 1. recompile changed sources
|
||||
// 2(3). recompile direct dependencies and transitive public inheritance dependencies of sources with API changes in 1(2).
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import java.io.File
|
|||
*/
|
||||
private final class IncrementalNameHashing(log: Logger, options: IncOptions) extends IncrementalCommon(log, options) {
|
||||
|
||||
private val memberRefInvalidator = new MemberRefInvalidator(log)
|
||||
private val memberRefInvalidator = new MemberRefInvalidator(log, options.logRecompileOnMacro)
|
||||
|
||||
// Package objects are fragile: if they inherit from an invalidated source, get "class file needed by package is missing" error
|
||||
// This might be too conservative: we probably only need package objects for packages of invalidated sources.
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ import xsbt.api.APIUtil
|
|||
* dependencies unconditionally. On the other hand, if api change is due to modified name hashes
|
||||
* of regular members then we'll invalidate sources that use those names.
|
||||
*/
|
||||
private[inc] class MemberRefInvalidator(log: Logger) {
|
||||
private[inc] class MemberRefInvalidator(log: Logger, logRecompileOnMacro: Boolean) {
|
||||
def get[T](memberRef: Relation[File, T], usedNames: Relation[File, String], apiChange: APIChange[_]): T => Set[File] = apiChange match {
|
||||
case _: APIChangeDueToMacroDefinition[_] =>
|
||||
new InvalidateDueToMacroDefinition(memberRef)
|
||||
|
|
@ -82,7 +82,7 @@ private[inc] class MemberRefInvalidator(log: Logger) {
|
|||
private class InvalidateDueToMacroDefinition[T](memberRef: Relation[File, T]) extends (T => Set[File]) {
|
||||
def apply(from: T): Set[File] = {
|
||||
val invalidated = memberRef.reverse(from)
|
||||
if (invalidated.nonEmpty) {
|
||||
if (invalidated.nonEmpty && logRecompileOnMacro) {
|
||||
log.info(s"Because $from contains a macro definition, the following dependencies are invalidated unconditionally:\n" +
|
||||
formatInvalidated(invalidated))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
### Improvements
|
||||
|
||||
- When `RecompileOnMacroDef` is enabled, sbt will now print out a info level log indicating that some sources are being recompiled because it's used from a source that contains a macro definition. [#2637][2637] by [@eed3si9n][@eed3si9n]
|
||||
- When `RecompileOnMacroDef` is enabled, sbt will now print out a info level log indicating that some sources are being recompiled because it's used from a source that contains a macro definition. Can be disabled with `incOptions := incOptions.value.withLogRecompileOnMacro(false)` [#2637][2637]/[#2659][2659] by [@eed3si9n][@eed3si9n]/[@dwijnand][@dwijnand]
|
||||
- Adds Windows script support and native file extensions on Unix platforms. [#2603][2603] by [@ekrich][@ekrich]
|
||||
- Improves loading time of large builds. [#2630][2630] by [@eed3si9n][@eed3si9n]
|
||||
- Adds the ability to call `dependsOn` for the current project inside a `.sbt` file. [#2653][2653] by [@anatolydwnld][@anatolydwnld]
|
||||
|
|
@ -56,6 +56,7 @@
|
|||
[2002]: https://github.com/sbt/sbt/issues/2002
|
||||
[1500]: https://github.com/sbt/sbt/issues/1500
|
||||
[2537]: https://github.com/sbt/sbt/issues/2537
|
||||
[2659]: https://github.com/sbt/sbt/pull/2659
|
||||
|
||||
[@eed3si9n]: https://github.com/eed3si9n
|
||||
[@jsuereth]: https://github.com/jsuereth
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
package p
|
||||
|
||||
object Client {
|
||||
def foo = Foo printTree (Foo printTree "foo")
|
||||
def bar = Bar printTree (Bar printTree "bar")
|
||||
def baz = Baz printTree (Baz printTree "baz")
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
dependsOn(macros)
|
||||
|
||||
scalaVersion in Global := "2.11.8"
|
||||
|
||||
val macros = project settings (libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value)
|
||||
|
||||
def expectedStringFor(l: String) =
|
||||
s"Because $l contains a macro definition, the following dependencies are invalidated unconditionally"
|
||||
|
||||
TaskKey[Unit]("checkPresent1") := check(expectedStringFor("p.Foo$"), expectPresent = true).value
|
||||
TaskKey[Unit]("checkMissing2") := check(expectedStringFor("p.Bar$"), expectPresent = false).value
|
||||
TaskKey[Unit]("checkPresent3") := check(expectedStringFor("p.Baz$"), expectPresent = true).value
|
||||
|
||||
def check(expectedString: String, expectPresent: Boolean) = Def task {
|
||||
val last = IO read (BuiltinCommands lastLogFile state.value).get
|
||||
val present = last contains expectedString
|
||||
if (expectPresent && !present) sys error "Expected there to be a log message for macro recompilation"
|
||||
if (!expectPresent && present) sys error "Expected there to NOT be a log message for macro recompilation"
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package p
|
||||
|
||||
import scala.language.experimental.macros
|
||||
import scala.reflect.macros._
|
||||
|
||||
object Bar {
|
||||
def printTree(arg: Any): Any = macro BarMacros.printTreeImpl
|
||||
}
|
||||
|
||||
class BarMacros(val c: blackbox.Context) {
|
||||
import c.universe._
|
||||
def printTreeImpl(arg: Tree): Tree = Literal(Constant("Bar1: " + arg))
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package p
|
||||
|
||||
import scala.language.experimental.macros
|
||||
import scala.reflect.macros._
|
||||
|
||||
object Baz {
|
||||
def printTree(arg: Any): Any = macro BazMacros.printTreeImpl
|
||||
}
|
||||
|
||||
class BazMacros(val c: blackbox.Context) {
|
||||
import c.universe._
|
||||
def printTreeImpl(arg: Tree): Tree = Literal(Constant("Baz1: " + arg))
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package p
|
||||
|
||||
import scala.language.experimental.macros
|
||||
import scala.reflect.macros._
|
||||
|
||||
object Foo {
|
||||
def printTree(arg: Any): Any = macro FooMacros.printTreeImpl
|
||||
}
|
||||
|
||||
class FooMacros(val c: blackbox.Context) {
|
||||
import c.universe._
|
||||
def printTreeImpl(arg: Tree): Tree = Literal(Constant("Foo1: " + arg))
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package p
|
||||
|
||||
import scala.language.experimental.macros
|
||||
import scala.reflect.macros._
|
||||
|
||||
object Bar {
|
||||
def printTree(arg: Any): Any = macro BarMacros.printTreeImpl
|
||||
}
|
||||
|
||||
class BarMacros(val c: blackbox.Context) {
|
||||
import c.universe._
|
||||
def printTreeImpl(arg: Tree): Tree = Literal(Constant("Bar2: " + arg))
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package p
|
||||
|
||||
import scala.language.experimental.macros
|
||||
import scala.reflect.macros._
|
||||
|
||||
object Baz {
|
||||
def printTree(arg: Any): Any = macro BazMacros.printTreeImpl
|
||||
}
|
||||
|
||||
class BazMacros(val c: blackbox.Context) {
|
||||
import c.universe._
|
||||
def printTreeImpl(arg: Tree): Tree = Literal(Constant("Baz2: " + arg))
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package p
|
||||
|
||||
import scala.language.experimental.macros
|
||||
import scala.reflect.macros._
|
||||
|
||||
object Foo {
|
||||
def printTree(arg: Any): Any = macro FooMacros.printTreeImpl
|
||||
}
|
||||
|
||||
class FooMacros(val c: blackbox.Context) {
|
||||
import c.universe._
|
||||
def printTreeImpl(arg: Tree): Tree = Literal(Constant("Foo2: " + arg))
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
> compile
|
||||
$ copy-file macros/changes/Foo.scala macros/Foo.scala
|
||||
> compile
|
||||
> checkPresent1
|
||||
|
||||
> set incOptions := incOptions.value.withLogRecompileOnMacro(false)
|
||||
|
||||
> compile
|
||||
$ copy-file macros/changes/Bar.scala macros/Bar.scala
|
||||
> compile
|
||||
> checkMissing2
|
||||
|
||||
> set incOptions := incOptions.value.withLogRecompileOnMacro(true)
|
||||
|
||||
> compile
|
||||
$ copy-file macros/changes/Baz.scala macros/Baz.scala
|
||||
> compile
|
||||
> checkPresent3
|
||||
Loading…
Reference in New Issue