Adds withIncludeSynthToNameHashing. Ref #2537

Provides a workaround flag `incOptions :=
incOptions.value.withIncludeSynthToNameHashing(true)` for name hashing
not including synthetic methods. This will not be enabled by default in
sbt 0.13. It can also enabled by passing `sbt.inc.include_synth=true`
to JVM.
This commit is contained in:
Eugene Yokota 2016-04-05 22:57:59 -04:00
parent 36293f7400
commit c75a386a82
10 changed files with 62 additions and 13 deletions

View File

@ -206,6 +206,7 @@ private final class AnalysisCallback(internalMap: File => Option[File], external
def usedName(sourceFile: File, name: String) = add(usedNames, sourceFile, name)
def nameHashing: Boolean = options.nameHashing
def includeSynthToNameHashing: Boolean = options.includeSynthToNameHashing
def get: Analysis = addUsedNames(addCompilation(addProductsAndDeps(Analysis.empty(nameHashing = nameHashing))))

View File

@ -80,7 +80,11 @@ final class IncOptions(
* Once Scala compiler sources are refactored to work well with name hashing algorithm this option will be
* deleted immediately.
*/
val antStyle: Boolean) extends Product with Serializable {
val antStyle: Boolean,
/**
* Include synthetic methods into the dependency tracking by name hashing.
*/
val includeSynthToNameHashing: Boolean) extends Product with Serializable {
/**
* Secondary constructor introduced to make IncOptions to be binary compatible with version that didn't have
@ -90,59 +94,72 @@ 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.antStyleDefault, IncOptions.includeSynthToNameHashingDefault)
}
def this(transitiveStep: Int, recompileAllFraction: Double, relationsDebug: Boolean, apiDebug: Boolean,
apiDiffContextSize: Int, apiDumpDirectory: Option[java.io.File], newClassfileManager: () => ClassfileManager,
recompileOnMacroDef: Boolean, nameHashing: Boolean, antStyle: Boolean) = {
this(transitiveStep, recompileAllFraction, relationsDebug, apiDebug,
apiDiffContextSize, apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing,
antStyle, IncOptions.includeSynthToNameHashingDefault)
}
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)
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle, includeSynthToNameHashing)
}
def withRecompileAllFraction(recompileAllFraction: Double): IncOptions = {
new IncOptions(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle)
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle, includeSynthToNameHashing)
}
def withRelationsDebug(relationsDebug: Boolean): IncOptions = {
new IncOptions(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle)
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle, includeSynthToNameHashing)
}
def withApiDebug(apiDebug: Boolean): IncOptions = {
new IncOptions(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle)
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle, includeSynthToNameHashing)
}
def withApiDiffContextSize(apiDiffContextSize: Int): IncOptions = {
new IncOptions(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle)
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle, includeSynthToNameHashing)
}
def withApiDumpDirectory(apiDumpDirectory: Option[File]): IncOptions = {
new IncOptions(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle)
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle, includeSynthToNameHashing)
}
def withNewClassfileManager(newClassfileManager: () => ClassfileManager): IncOptions = {
new IncOptions(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle)
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle, includeSynthToNameHashing)
}
def withRecompileOnMacroDef(recompileOnMacroDef: Boolean): IncOptions = {
new IncOptions(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle)
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle, includeSynthToNameHashing)
}
def withNameHashing(nameHashing: Boolean): IncOptions = {
new IncOptions(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle)
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle, includeSynthToNameHashing)
}
def withIncludeSynthToNameHashing(includeSynthToNameHashing: Boolean): IncOptions = {
new IncOptions(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle, includeSynthToNameHashing)
}
def withAntStyle(antStyle: Boolean): IncOptions = {
new IncOptions(transitiveStep, recompileAllFraction, relationsDebug, apiDebug, apiDiffContextSize,
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle)
apiDumpDirectory, newClassfileManager, recompileOnMacroDef, nameHashing, antStyle, includeSynthToNameHashing)
}
//- EXPANDED CASE CLASS METHOD BEGIN -//
@ -219,6 +236,8 @@ object IncOptions extends Serializable {
private val recompileOnMacroDefDefault: Boolean = true
private[sbt] val nameHashingDefault: Boolean = true
private val antStyleDefault: Boolean = false
// This should default to false
private[sbt] val includeSynthToNameHashingDefault = java.lang.Boolean.getBoolean("sbt.inc.include_synth")
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).

View File

@ -41,6 +41,8 @@ import scala.tools.nsc._
class ExtractUsedNames[GlobalType <: CallbackGlobal](val global: GlobalType) extends Compat {
import global._
@inline def debug(msg: => String) = if (settings.verbose.value) inform(msg)
def extract(unit: CompilationUnit): Set[String] = {
val tree = unit.body
val extractedByTreeWalk = extractByTreeWalk(tree)
@ -122,7 +124,7 @@ class ExtractUsedNames[GlobalType <: CallbackGlobal](val global: GlobalType) ext
}
(symbol != NoSymbol) &&
!symbol.isSynthetic &&
(callback.includeSynthToNameHashing || !symbol.isSynthetic) &&
!emptyName(symbol.name)
}
}

View File

@ -59,4 +59,8 @@ public interface AnalysisCallback
* Do not depend on it, please.
*/
boolean nameHashing();
/**
* Include synthetic methods into the dependency tracking by name hashing.
*/
boolean includeSynthToNameHashing();
}

View File

@ -0,0 +1,10 @@
[@eed3si9n]: https://github.com/eed3si9n
[@jsuereth]: https://github.com/jsuereth
[@dwijnand]: http://github.com/dwijnand
[@Duhemm]: http://github.com/Duhemm
[@gkossakowski]: https://github.com/gkossakowski
[2573]: https://github.com/sbt/sbt/issues/2537
### Bug fixes
- Provides a workaround flag `incOptions := incOptions.value.withIncludeSynthToNameHashing(true)` for name hashing not including synthetic methods. This will not be enabled by default in sbt 0.13. It can also enabled by passing `sbt.inc.include_synth=true` to JVM. [#2537][2573] by [@eed3si9h][@eed3si9h]

View File

@ -0,0 +1 @@
case class A(a: Int)

View File

@ -0,0 +1 @@
class B { def test(a: A) = a.copy() }

View File

@ -0,0 +1,5 @@
lazy val root = (project in file(".")).
settings(
scalaVersion := "2.11.7",
incOptions := incOptions.value.withIncludeSynthToNameHashing(true)
)

View File

@ -0,0 +1 @@
case class A(a: Int) { private def copy = ??? }

View File

@ -0,0 +1,5 @@
> compile
$ copy-file changes/A.scala A.scala
-> compile