From 0bc115a9afda920aa7bb6745e841c785f478da6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Wawrzyk?= Date: Fri, 8 Jun 2018 09:53:10 +0200 Subject: [PATCH 01/11] Only show changed lines in diff --- .../main/scala/sbt/internal/inc/APIDiff.scala | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/internal/zinc-core/src/main/scala/sbt/internal/inc/APIDiff.scala b/internal/zinc-core/src/main/scala/sbt/internal/inc/APIDiff.scala index 1cefb899e4..9bd1fbf79d 100644 --- a/internal/zinc-core/src/main/scala/sbt/internal/inc/APIDiff.scala +++ b/internal/zinc-core/src/main/scala/sbt/internal/inc/APIDiff.scala @@ -144,8 +144,9 @@ private[inc] class APIDiff { val lastTokens = splitTokens(lastCode, Nil).toArray val diff = hirschberg(lastTokens, tokens) + val cleanDiff = dropNonChangedLines(diff) - diff.collect { + cleanDiff.collect { case Unmodified(str) => str case Inserted(str) => ADDITION_COLOR + str + ANSI_DEFAULT case Modified(old, str) if printDiffDel => @@ -155,6 +156,24 @@ private[inc] class APIDiff { }.mkString } + private def dropNonChangedLines(patches: Array[Patch]): Seq[Patch] = { + def recur(patches: List[Patch], result: List[List[Patch]]): List[List[Patch]] = { + if (patches.isEmpty) result.reverse + else { + val (line, rest) = patches.span { + case Modified(_, "\n") | Deleted("\n") | Inserted("\n") | Unmodified("\n") => false + case _ => true + } + val hasChanges = line.exists { + case _: Modified | _: Deleted | _: Inserted => true + case _: Unmodified => false + } + recur(rest.drop(1), if (hasChanges) (line ++ rest.take(1)) :: result else result) + } + } + recur(patches.toList, Nil).flatten + } + private sealed trait Patch private case class Unmodified(str: String) extends Patch private case class Modified(original: String, str: String) extends Patch From 1fd25b761130d204815919656ad5ce2017064ba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Wawrzyk?= Date: Fri, 8 Jun 2018 10:56:07 +0200 Subject: [PATCH 02/11] Add colors for inv sections --- .../scala/sbt/internal/inc/IncrementalCommon.scala | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalCommon.scala b/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalCommon.scala index 4e70ff987a..388c968cd2 100644 --- a/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalCommon.scala +++ b/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalCommon.scala @@ -111,18 +111,23 @@ private[inc] abstract class IncrementalCommon(val log: sbt.util.Logger, options: val invalidatedSources = classes.flatMap(previous.relations.definesClass) ++ modifiedSrcs val invalidatedSourcesForCompilation = expand(invalidatedSources, allSources) val pruned = Incremental.prune(invalidatedSourcesForCompilation, previous, classfileManager) - debug("********* Pruned: \n" + pruned.relations + "\n*********") + debugSection("Pruned")(pruned.relations) val fresh = doCompile(invalidatedSourcesForCompilation, binaryChanges) // For javac as class files are added to classfileManager as they are generated, so // this step is redundant. For scalac this is still necessary. TODO: do the same for scalac. classfileManager.generated(fresh.relations.allProducts.toArray) - debug("********* Fresh: \n" + fresh.relations + "\n*********") + debugSection("Fresh")(fresh.relations) val merged = pruned ++ fresh //.copy(relations = pruned.relations ++ fresh.relations, apis = pruned.apis ++ fresh.apis) - debug("********* Merged: \n" + merged.relations + "\n*********") + debugSection("Merged")(merged.relations) (merged, invalidatedSourcesForCompilation) } + private[this] def debugSection(header: String)(content: => Any): Unit = { + import Console._ + debug(s"$CYAN************* $header:$RESET\n$content\n$CYAN************* (end of $header)$RESET") + } + private[this] def emptyChanges: DependencyChanges = new DependencyChanges { val modifiedBinaries = new Array[File](0) val modifiedClasses = new Array[String](0) From 39ce062e2461b1526f88a16465ffc2bccb19d661 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Wawrzyk?= Date: Fri, 8 Jun 2018 10:59:55 +0200 Subject: [PATCH 03/11] Improve to string of UsedName --- .../src/main/scala/sbt/internal/inc/UsedName.scala | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/internal/zinc-core/src/main/scala/sbt/internal/inc/UsedName.scala b/internal/zinc-core/src/main/scala/sbt/internal/inc/UsedName.scala index 7c20c54efa..db85f3515c 100644 --- a/internal/zinc-core/src/main/scala/sbt/internal/inc/UsedName.scala +++ b/internal/zinc-core/src/main/scala/sbt/internal/inc/UsedName.scala @@ -11,7 +11,13 @@ import java.util import xsbti.UseScope -case class UsedName private (name: String, scopes: util.EnumSet[UseScope]) +case class UsedName private (name: String, scopes: util.EnumSet[UseScope]) { + + override def toString: String = { + val formattedScopes = if (scopes == UsedName.DefaultScope) "" else " " + scopes + name + formattedScopes + } +} object UsedName { @@ -25,4 +31,7 @@ object UsedName { private def escapeControlChars(name: String) = { name.replaceAllLiterally("\n", "\u26680A") } + + private val DefaultScope = java.util.EnumSet.of(UseScope.Default) + } From 1b6df7277b80f5467ff2eb788681026d4bc5868d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Wawrzyk?= Date: Fri, 8 Jun 2018 11:12:58 +0200 Subject: [PATCH 04/11] Implement vertical alignment for relations --- .../scala/sbt/internal/inc/Relations.scala | 50 ++++++++++++------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/internal/zinc-core/src/main/scala/sbt/internal/inc/Relations.scala b/internal/zinc-core/src/main/scala/sbt/internal/inc/Relations.scala index 588c4a2a46..29f01f13b5 100644 --- a/internal/zinc-core/src/main/scala/sbt/internal/inc/Relations.scala +++ b/internal/zinc-core/src/main/scala/sbt/internal/inc/Relations.scala @@ -509,12 +509,20 @@ private abstract class MRelationsCommon( /** Making large Relations a little readable. */ private val userDir = sys.props("user.dir").stripSuffix("/") + "/" private def nocwd(s: String) = s stripPrefix userDir - private def line_s(kv: (Any, Any)) = - " " + nocwd("" + kv._1) + " -> " + nocwd("" + kv._2) + "\n" - protected def relation_s(r: Relation[_, _]) = ( + private def formatAsLines(kvs: Seq[(Any, Any)], indentation: String): Seq[String] = { + val stringified = kvs.map { case (k, v) => nocwd(k.toString) -> nocwd(v.toString) } + val longestKey = stringified.map(_._1.length).max + stringified.map { + case (k, v) => + indentation + " " + k.padTo(longestKey, ' ') + " -> " + v + "\n" + } + } + protected def relation_s(r: Relation[_, _], indentation: String): String = { if (r.forwardMap.isEmpty) "Relation [ ]" - else (r.all.toSeq.map(line_s).sorted) mkString ("Relation [\n", "", "]") - ) + else + formatAsLines(r.all.toSeq, indentation).sorted.mkString("Relation [\n", "", indentation + "]") + } + protected def relation_s(r: Relation[_, _]): String = relation_s(r, " ") } /** @@ -663,22 +671,26 @@ private class MRelationsNameHashing( (srcProd :: libraryDep :: libraryClassName :: memberRef :: inheritance :: classes :: Nil).hashCode override def toString: String = { - val internalDepsStr = (internalDependencies.dependencies map { - case (k, vs) => k + " " + relation_s(vs) - }).mkString("\n ", "\n ", "") - val externalDepsStr = (externalDependencies.dependencies map { - case (k, vs) => k + " " + relation_s(vs) - }).mkString("\n ", "\n ", "") + def color(s: String) = Console.YELLOW + s + Console.RESET + def nestedRelation(deps: Map[_, Relation[_, _]]): String = { + if (deps.isEmpty) "Relation [ ]" + else { + val indentation = " " + deps + .map { case (k, vs) => color(k.toString) + ": " + relation_s(vs, indentation) } + .mkString("\n" + indentation, "\n" + indentation, "") + } + } s""" |Relations (with name hashing enabled): - | products: ${relation_s(srcProd)} - | library deps: ${relation_s(libraryDep)} - | library class names: ${relation_s(libraryClassName)} - | internalDependencies: $internalDepsStr - | externalDependencies: $externalDepsStr - | class names: ${relation_s(classes)} - | used names: ${relation_s(names)} - | product class names: ${relation_s(productClassName)} + | ${color("products")}: ${relation_s(srcProd)} + | ${color("library dependencies")}: ${relation_s(libraryDep)} + | ${color("library class names")}: ${relation_s(libraryClassName)} + | ${color("internal dependencies")}: ${nestedRelation(internalDependencies.dependencies)} + | ${color("external dependencies")}: ${nestedRelation(externalDependencies.dependencies)} + | ${color("class names")}: ${relation_s(classes)} + | ${color("used names")}: ${relation_s(names)} + | ${color("product class names")}: ${relation_s(productClassName)} """.trim.stripMargin } } From bd711366ed70cccb4a134d5d1773a4821d93f1ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Wawrzyk?= Date: Fri, 8 Jun 2018 12:43:08 +0200 Subject: [PATCH 05/11] Add separators for compilation cycles --- .../scala/sbt/internal/inc/Incremental.scala | 2 +- .../sbt/internal/inc/IncrementalCommon.scala | 24 ++++++++++++------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/internal/zinc-core/src/main/scala/sbt/internal/inc/Incremental.scala b/internal/zinc-core/src/main/scala/sbt/internal/inc/Incremental.scala index f07ae95c18..3dbd5ceafe 100644 --- a/internal/zinc-core/src/main/scala/sbt/internal/inc/Incremental.scala +++ b/internal/zinc-core/src/main/scala/sbt/internal/inc/Incremental.scala @@ -76,7 +76,7 @@ object Incremental { else incremental.log.debug( "All initially invalidated classes: " + initialInvClasses + "\n" + - "All initially invalidated sources:" + initialInvSources + "\n") + "All initially invalidated sources: " + initialInvSources + "\n") val analysis = manageClassfiles(options) { classfileManager => incremental.cycle(initialInvClasses, initialInvSources, diff --git a/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalCommon.scala b/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalCommon.scala index 388c968cd2..0c116100a2 100644 --- a/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalCommon.scala +++ b/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalCommon.scala @@ -47,6 +47,7 @@ private[inc] abstract class IncrementalCommon(val log: sbt.util.Logger, options: if (invalidatedRaw.isEmpty && modifiedSrcs.isEmpty) previous else { + debugOuterSection(s"Recompilation cycle #$cycleNum") val invalidatedPackageObjects = this.invalidatedPackageObjects(invalidatedRaw, previous.relations, previous.apis) if (invalidatedPackageObjects.nonEmpty) @@ -111,23 +112,18 @@ private[inc] abstract class IncrementalCommon(val log: sbt.util.Logger, options: val invalidatedSources = classes.flatMap(previous.relations.definesClass) ++ modifiedSrcs val invalidatedSourcesForCompilation = expand(invalidatedSources, allSources) val pruned = Incremental.prune(invalidatedSourcesForCompilation, previous, classfileManager) - debugSection("Pruned")(pruned.relations) + debugInnerSection("Pruned")(pruned.relations) val fresh = doCompile(invalidatedSourcesForCompilation, binaryChanges) // For javac as class files are added to classfileManager as they are generated, so // this step is redundant. For scalac this is still necessary. TODO: do the same for scalac. classfileManager.generated(fresh.relations.allProducts.toArray) - debugSection("Fresh")(fresh.relations) + debugInnerSection("Fresh")(fresh.relations) val merged = pruned ++ fresh //.copy(relations = pruned.relations ++ fresh.relations, apis = pruned.apis ++ fresh.apis) - debugSection("Merged")(merged.relations) + debugInnerSection("Merged")(merged.relations) (merged, invalidatedSourcesForCompilation) } - private[this] def debugSection(header: String)(content: => Any): Unit = { - import Console._ - debug(s"$CYAN************* $header:$RESET\n$content\n$CYAN************* (end of $header)$RESET") - } - private[this] def emptyChanges: DependencyChanges = new DependencyChanges { val modifiedBinaries = new Array[File](0) val modifiedClasses = new Array[String](0) @@ -338,6 +334,7 @@ private[inc] abstract class IncrementalCommon(val log: sbt.util.Logger, options: val allInvalidatedClasses = invalidatedClasses ++ byExtSrcDep val allInvalidatedSourcefiles = addedSrcs ++ modifiedSrcs ++ byProduct ++ byBinaryDep + debugOuterSection(s"Initial invalidation") if (previous.allSources.isEmpty) log.debug("Full compilation, no sources in previous analysis.") else if (allInvalidatedClasses.isEmpty && allInvalidatedSourcefiles.isEmpty) @@ -506,4 +503,15 @@ private[inc] abstract class IncrementalCommon(val log: sbt.util.Logger, options: } xs.toSet } + + private[this] def debugOuterSection(header: String): Unit = { + import Console._ + log.debug(s"$GREEN*************************** $header$RESET") + } + + private[this] def debugInnerSection(header: String)(content: => Any): Unit = { + import Console._ + debug(s"$CYAN************* $header:$RESET\n$content\n$CYAN************* (end of $header)$RESET") + } + } From b6ac1397bc95620568bfd2d3baaad0617e0a2c1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Wawrzyk?= Date: Thu, 16 Aug 2018 13:21:22 +0200 Subject: [PATCH 06/11] Revert "Only show changed lines in diff" This reverts commit 0bc115a9afda920aa7bb6745e841c785f478da6a. --- .../main/scala/sbt/internal/inc/APIDiff.scala | 21 +------------------ 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/internal/zinc-core/src/main/scala/sbt/internal/inc/APIDiff.scala b/internal/zinc-core/src/main/scala/sbt/internal/inc/APIDiff.scala index 9bd1fbf79d..1cefb899e4 100644 --- a/internal/zinc-core/src/main/scala/sbt/internal/inc/APIDiff.scala +++ b/internal/zinc-core/src/main/scala/sbt/internal/inc/APIDiff.scala @@ -144,9 +144,8 @@ private[inc] class APIDiff { val lastTokens = splitTokens(lastCode, Nil).toArray val diff = hirschberg(lastTokens, tokens) - val cleanDiff = dropNonChangedLines(diff) - cleanDiff.collect { + diff.collect { case Unmodified(str) => str case Inserted(str) => ADDITION_COLOR + str + ANSI_DEFAULT case Modified(old, str) if printDiffDel => @@ -156,24 +155,6 @@ private[inc] class APIDiff { }.mkString } - private def dropNonChangedLines(patches: Array[Patch]): Seq[Patch] = { - def recur(patches: List[Patch], result: List[List[Patch]]): List[List[Patch]] = { - if (patches.isEmpty) result.reverse - else { - val (line, rest) = patches.span { - case Modified(_, "\n") | Deleted("\n") | Inserted("\n") | Unmodified("\n") => false - case _ => true - } - val hasChanges = line.exists { - case _: Modified | _: Deleted | _: Inserted => true - case _: Unmodified => false - } - recur(rest.drop(1), if (hasChanges) (line ++ rest.take(1)) :: result else result) - } - } - recur(patches.toList, Nil).flatten - } - private sealed trait Patch private case class Unmodified(str: String) extends Patch private case class Modified(original: String, str: String) extends Patch From 94d5c32d8d353d414998481945133050a311e0ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Wawrzyk?= Date: Thu, 16 Aug 2018 13:25:35 +0200 Subject: [PATCH 07/11] Avoid logging both Fresh and Merged if they are equal --- .../main/scala/sbt/internal/inc/IncrementalCommon.scala | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalCommon.scala b/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalCommon.scala index 0c116100a2..a53fda59e4 100644 --- a/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalCommon.scala +++ b/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalCommon.scala @@ -118,9 +118,14 @@ private[inc] abstract class IncrementalCommon(val log: sbt.util.Logger, options: // For javac as class files are added to classfileManager as they are generated, so // this step is redundant. For scalac this is still necessary. TODO: do the same for scalac. classfileManager.generated(fresh.relations.allProducts.toArray) - debugInnerSection("Fresh")(fresh.relations) val merged = pruned ++ fresh //.copy(relations = pruned.relations ++ fresh.relations, apis = pruned.apis ++ fresh.apis) - debugInnerSection("Merged")(merged.relations) + + if (fresh.relations == merged.relations) { + debugInnerSection("Fresh [== Merged]")(fresh.relations) + } else { + debugInnerSection("Fresh")(fresh.relations) + debugInnerSection("Merged")(merged.relations) + } (merged, invalidatedSourcesForCompilation) } From ab1d662db590d9c39934b68ba599e907da6d7078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Wawrzyk?= Date: Thu, 16 Aug 2018 13:48:09 +0200 Subject: [PATCH 08/11] Drop the word "Relation" from the output --- .../src/main/scala/sbt/internal/inc/IncrementalCommon.scala | 2 +- .../src/main/scala/sbt/internal/inc/Relations.scala | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalCommon.scala b/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalCommon.scala index a53fda59e4..0c8b71af8a 100644 --- a/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalCommon.scala +++ b/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalCommon.scala @@ -285,7 +285,7 @@ private[inc] abstract class IncrementalCommon(val log: sbt.util.Logger, options: val inv: Set[String] = propagated ++ dups val newlyInvalidated = (inv -- recompiledClasses) ++ dups log.debug( - "All newly invalidated classes after taking into account (previously) recompiled classes:" + newlyInvalidated) + "All newly invalidated classes after taking into account (previously) recompiled classes: " + newlyInvalidated) if (newlyInvalidated.isEmpty) Set.empty else inv } diff --git a/internal/zinc-core/src/main/scala/sbt/internal/inc/Relations.scala b/internal/zinc-core/src/main/scala/sbt/internal/inc/Relations.scala index 29f01f13b5..35c9f6e817 100644 --- a/internal/zinc-core/src/main/scala/sbt/internal/inc/Relations.scala +++ b/internal/zinc-core/src/main/scala/sbt/internal/inc/Relations.scala @@ -518,9 +518,9 @@ private abstract class MRelationsCommon( } } protected def relation_s(r: Relation[_, _], indentation: String): String = { - if (r.forwardMap.isEmpty) "Relation [ ]" + if (r.forwardMap.isEmpty) "[]" else - formatAsLines(r.all.toSeq, indentation).sorted.mkString("Relation [\n", "", indentation + "]") + formatAsLines(r.all.toSeq, indentation).sorted.mkString("[\n", "", indentation + "]") } protected def relation_s(r: Relation[_, _]): String = relation_s(r, " ") } @@ -673,7 +673,7 @@ private class MRelationsNameHashing( override def toString: String = { def color(s: String) = Console.YELLOW + s + Console.RESET def nestedRelation(deps: Map[_, Relation[_, _]]): String = { - if (deps.isEmpty) "Relation [ ]" + if (deps.isEmpty) "[]" else { val indentation = " " deps From c6ddaa4d57d350f27eabe328cfff1cdb1295a180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Wawrzyk?= Date: Fri, 17 Aug 2018 09:31:32 +0200 Subject: [PATCH 09/11] ModifiedNames(changes = A, B) => ModifiedNames(A, B) --- .../zinc-core/src/main/scala/sbt/internal/inc/Changes.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/zinc-core/src/main/scala/sbt/internal/inc/Changes.scala b/internal/zinc-core/src/main/scala/sbt/internal/inc/Changes.scala index 77d07a989a..5042285ba2 100644 --- a/internal/zinc-core/src/main/scala/sbt/internal/inc/Changes.scala +++ b/internal/zinc-core/src/main/scala/sbt/internal/inc/Changes.scala @@ -73,7 +73,7 @@ final case class ModifiedNames(names: Set[UsedName]) { usedName.scopes.asScala.exists(scope => lookupMap.contains(usedName.name -> scope)) override def toString: String = - s"ModifiedNames(changes = ${names.mkString(", ")})" + s"ModifiedNames(${names.mkString(", ")})" } object ModifiedNames { def compareTwoNameHashes(a: Array[NameHash], b: Array[NameHash]): ModifiedNames = { From 430604235424b7eb22c2199ad4534fe6872c791a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Wawrzyk?= Date: Fri, 17 Aug 2018 09:33:30 +0200 Subject: [PATCH 10/11] Colors for initial invalidation --- .../sbt/internal/inc/IncrementalCommon.scala | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalCommon.scala b/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalCommon.scala index 0c8b71af8a..2d749bb65f 100644 --- a/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalCommon.scala +++ b/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalCommon.scala @@ -121,7 +121,7 @@ private[inc] abstract class IncrementalCommon(val log: sbt.util.Logger, options: val merged = pruned ++ fresh //.copy(relations = pruned.relations ++ fresh.relations, apis = pruned.apis ++ fresh.apis) if (fresh.relations == merged.relations) { - debugInnerSection("Fresh [== Merged]")(fresh.relations) + debugInnerSection("Fresh == Merged")(fresh.relations) } else { debugInnerSection("Fresh")(fresh.relations) debugInnerSection("Merged")(merged.relations) @@ -344,21 +344,37 @@ private[inc] abstract class IncrementalCommon(val log: sbt.util.Logger, options: log.debug("Full compilation, no sources in previous analysis.") else if (allInvalidatedClasses.isEmpty && allInvalidatedSourcefiles.isEmpty) log.debug("No changes") - else + else { + def color(s: String) = Console.YELLOW + s + Console.RESET log.debug( - "\nInitial source changes: \n\tremoved:" + removedSrcs + "\n\tadded: " + addedSrcs + "\n\tmodified: " + modifiedSrcs + - "\nInvalidated products: " + changes.removedProducts + - "\nExternal API changes: " + changes.external + - "\nModified binary dependencies: " + changes.binaryDeps + - "\nInitial directly invalidated classes: " + invalidatedClasses + - "\n\nSources indirectly invalidated by:" + - "\n\tproduct: " + byProduct + - "\n\tbinary dep: " + byBinaryDep + - "\n\texternal source: " + byExtSrcDep + s""" + |${color("Initial source changes")}: + | ${color("removed")}: ${showSet(removedSrcs, baseIndent = " ")} + | ${color("added")}: ${showSet(addedSrcs, baseIndent = " ")} + | ${color("modified")}: ${showSet(modifiedSrcs, baseIndent = " ")} + |${color("Invalidated products")}: ${showSet(changes.removedProducts)} + |${color("External API changes")}: ${changes.external} + |${color("Modified binary dependencies")}: ${changes.binaryDeps} + |${color("Initial directly invalidated classes")}: $invalidatedClasses + | + |${color("Sources indirectly invalidated by")}: + | ${color("product")}: ${showSet(byProduct, baseIndent = " ")} + | ${color("binary dep")}: ${showSet(byBinaryDep, baseIndent = " ")} + | ${color("external source")}: ${showSet(byExtSrcDep, baseIndent = " ")}""".stripMargin ) + } (allInvalidatedClasses, allInvalidatedSourcefiles) } + + private def showSet[A](s: Set[A], baseIndent: String = ""): String = { + if (s.isEmpty) { + "[]" + } else { + s.map(baseIndent + " " + _.toString).mkString("[\n", ",\n", "\n" + baseIndent + "]") + } + } + private[this] def checkAbsolute(addedSources: List[File]): Unit = if (addedSources.nonEmpty) { addedSources.filterNot(_.isAbsolute) match { From 7d72fa6a2a1c46c8a0c6acd58bb61ec6ebf72928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Wawrzyk?= Date: Fri, 17 Aug 2018 09:34:50 +0200 Subject: [PATCH 11/11] invalidate by external improvements --- .../internal/inc/IncrementalNameHashing.scala | 27 +++++++++---------- .../internal/inc/MemberRefInvalidator.scala | 10 +++---- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalNameHashing.scala b/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalNameHashing.scala index 4d2b621c91..a88c921714 100644 --- a/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalNameHashing.scala +++ b/internal/zinc-core/src/main/scala/sbt/internal/inc/IncrementalNameHashing.scala @@ -68,7 +68,7 @@ private final class IncrementalNameHashing(log: sbt.util.Logger, options: IncOpt externalAPIChange: APIChange, isScalaClass: String => Boolean): Set[String] = { val modifiedBinaryClassName = externalAPIChange.modifiedClass - val invalidationReason = memberRefInvalidator.invalidationReason(externalAPIChange) + val invalidationReason = memberRefInvalidator.invalidationReason(externalAPIChange).capitalize log.debug( s"$invalidationReason\nAll member reference dependencies will be considered within this context.") // Propagate inheritance dependencies transitively. @@ -136,20 +136,17 @@ private final class IncrementalNameHashing(log: sbt.util.Logger, options: IncOpt def debugMessage: String = { if (all.isEmpty) s"Change $change does not affect any class." else { - val byTransitiveInheritance = - if (transitiveInheritance.nonEmpty) s"by transitive inheritance: $transitiveInheritance" - else "" - val byLocalInheritance = - if (localInheritance.nonEmpty) s"by local inheritance: $localInheritance" else "" - val byMemberRef = - if (memberRef.nonEmpty) s"by member reference: $memberRef" else "" - - s"""Change $change invalidates ${all.size} classes due to ${memberRefInvalidator - .invalidationReason(change)} - |\t> $byTransitiveInheritance - |\t> $byLocalInheritance - |\t> $byMemberRef - """.stripMargin + def by(reason: String, classes: Set[String]) = { + if (classes.isEmpty) "" + else { + s"\tby $reason: ${classes.mkString(", ")}\n" + } + } + + s"${all.size} classes were invalidated due to ${memberRefInvalidator.invalidationReason(change)}\n" + + by("transitive inheritance", transitiveInheritance) + + by("local inheritance", localInheritance) + + by("member reference", memberRef) } } diff --git a/internal/zinc-core/src/main/scala/sbt/internal/inc/MemberRefInvalidator.scala b/internal/zinc-core/src/main/scala/sbt/internal/inc/MemberRefInvalidator.scala index 172777f4de..affd019ac8 100644 --- a/internal/zinc-core/src/main/scala/sbt/internal/inc/MemberRefInvalidator.scala +++ b/internal/zinc-core/src/main/scala/sbt/internal/inc/MemberRefInvalidator.scala @@ -67,17 +67,15 @@ private[inc] class MemberRefInvalidator(log: Logger, logRecompileOnMacro: Boolea def invalidationReason(apiChange: APIChange): String = apiChange match { case TraitPrivateMembersModified(modifiedClass) => - s"The private signature of trait ${modifiedClass} changed." + s"the private signature of trait $modifiedClass changed." case APIChangeDueToMacroDefinition(modifiedSrcFile) => - s"The $modifiedSrcFile source file declares a macro." + s"the $modifiedSrcFile source file declares a macro." case NamesChange(modifiedClass, modifiedNames) => modifiedNames.in(UseScope.Implicit) match { case changedImplicits if changedImplicits.isEmpty => - s"""|The $modifiedClass has the following regular definitions changed: - |\t${modifiedNames.names.mkString(", ")}.""".stripMargin + s"the $modifiedClass has the following regular definitions changed: ${modifiedNames.names}" case changedImplicits => - s"""|The $modifiedClass has the following implicit definitions changed: - |\t${changedImplicits.mkString(", ")}.""".stripMargin + s"""the $modifiedClass has the following implicit definitions changed: $changedImplicits""".stripMargin } }