From c75a386a82ad279ee1e76d458cf5fc1242c57c57 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 5 Apr 2016 22:57:59 -0400 Subject: [PATCH] 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. --- .../inc/src/main/scala/sbt/inc/Compile.scala | 1 + .../src/main/scala/sbt/inc/IncOptions.scala | 43 +++++++++++++------ .../main/scala/xsbt/ExtractUsedNames.scala | 4 +- .../src/main/java/xsbti/AnalysisCallback.java | 4 ++ notes/0.13.12/include_synth.markdown | 10 +++++ .../naha-synthetic/A.scala | 1 + .../naha-synthetic/B.scala | 1 + .../naha-synthetic/build.sbt | 5 +++ .../naha-synthetic/changes/A.scala | 1 + .../source-dependencies/naha-synthetic/test | 5 +++ 10 files changed, 62 insertions(+), 13 deletions(-) create mode 100644 notes/0.13.12/include_synth.markdown create mode 100644 sbt/src/sbt-test/source-dependencies/naha-synthetic/A.scala create mode 100644 sbt/src/sbt-test/source-dependencies/naha-synthetic/B.scala create mode 100644 sbt/src/sbt-test/source-dependencies/naha-synthetic/build.sbt create mode 100644 sbt/src/sbt-test/source-dependencies/naha-synthetic/changes/A.scala create mode 100644 sbt/src/sbt-test/source-dependencies/naha-synthetic/test diff --git a/compile/inc/src/main/scala/sbt/inc/Compile.scala b/compile/inc/src/main/scala/sbt/inc/Compile.scala index a5da65860..40a11e286 100644 --- a/compile/inc/src/main/scala/sbt/inc/Compile.scala +++ b/compile/inc/src/main/scala/sbt/inc/Compile.scala @@ -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)))) diff --git a/compile/inc/src/main/scala/sbt/inc/IncOptions.scala b/compile/inc/src/main/scala/sbt/inc/IncOptions.scala index b38fed952..17b65d65f 100644 --- a/compile/inc/src/main/scala/sbt/inc/IncOptions.scala +++ b/compile/inc/src/main/scala/sbt/inc/IncOptions.scala @@ -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). diff --git a/compile/interface/src/main/scala/xsbt/ExtractUsedNames.scala b/compile/interface/src/main/scala/xsbt/ExtractUsedNames.scala index 56f67f3e8..281131736 100644 --- a/compile/interface/src/main/scala/xsbt/ExtractUsedNames.scala +++ b/compile/interface/src/main/scala/xsbt/ExtractUsedNames.scala @@ -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) } } diff --git a/interface/src/main/java/xsbti/AnalysisCallback.java b/interface/src/main/java/xsbti/AnalysisCallback.java index a51628f15..9a342fdf1 100644 --- a/interface/src/main/java/xsbti/AnalysisCallback.java +++ b/interface/src/main/java/xsbti/AnalysisCallback.java @@ -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(); } \ No newline at end of file diff --git a/notes/0.13.12/include_synth.markdown b/notes/0.13.12/include_synth.markdown new file mode 100644 index 000000000..0348f2b03 --- /dev/null +++ b/notes/0.13.12/include_synth.markdown @@ -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] diff --git a/sbt/src/sbt-test/source-dependencies/naha-synthetic/A.scala b/sbt/src/sbt-test/source-dependencies/naha-synthetic/A.scala new file mode 100644 index 000000000..acafe2da1 --- /dev/null +++ b/sbt/src/sbt-test/source-dependencies/naha-synthetic/A.scala @@ -0,0 +1 @@ +case class A(a: Int) diff --git a/sbt/src/sbt-test/source-dependencies/naha-synthetic/B.scala b/sbt/src/sbt-test/source-dependencies/naha-synthetic/B.scala new file mode 100644 index 000000000..2c4519ab3 --- /dev/null +++ b/sbt/src/sbt-test/source-dependencies/naha-synthetic/B.scala @@ -0,0 +1 @@ +class B { def test(a: A) = a.copy() } diff --git a/sbt/src/sbt-test/source-dependencies/naha-synthetic/build.sbt b/sbt/src/sbt-test/source-dependencies/naha-synthetic/build.sbt new file mode 100644 index 000000000..cd5970b1c --- /dev/null +++ b/sbt/src/sbt-test/source-dependencies/naha-synthetic/build.sbt @@ -0,0 +1,5 @@ +lazy val root = (project in file(".")). + settings( + scalaVersion := "2.11.7", + incOptions := incOptions.value.withIncludeSynthToNameHashing(true) + ) diff --git a/sbt/src/sbt-test/source-dependencies/naha-synthetic/changes/A.scala b/sbt/src/sbt-test/source-dependencies/naha-synthetic/changes/A.scala new file mode 100644 index 000000000..57eb90cee --- /dev/null +++ b/sbt/src/sbt-test/source-dependencies/naha-synthetic/changes/A.scala @@ -0,0 +1 @@ +case class A(a: Int) { private def copy = ??? } diff --git a/sbt/src/sbt-test/source-dependencies/naha-synthetic/test b/sbt/src/sbt-test/source-dependencies/naha-synthetic/test new file mode 100644 index 000000000..4896f0dcc --- /dev/null +++ b/sbt/src/sbt-test/source-dependencies/naha-synthetic/test @@ -0,0 +1,5 @@ +> compile + +$ copy-file changes/A.scala A.scala + +-> compile