Skip to content

Commit

Permalink
Merge pull request #548 from lukaszwawrzyk/ignore-scalac-options
Browse files Browse the repository at this point in the history
Add option to Ignore scalac options change
  • Loading branch information
dwijnand authored Jun 7, 2018
2 parents ec23cbc + 54eca16 commit ae02d7e
Show file tree
Hide file tree
Showing 13 changed files with 184 additions and 30 deletions.

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions internal/compiler-interface/src/main/contraband/incremental.json
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,13 @@
"default": "xsbti.compile.IncOptions.defaultExternal()",
"doc": "External hooks that allows clients e.g. IDEs to interacts with compilation internals",
"since": "0.1.0"
},
{
"name": "ignoredScalacOptions",
"type": "String[]",
"default": "xsbti.compile.IncOptions.defaultIgnoredScalacOptions()",
"doc": "Array of regexes that will be used to determine if scalac options should be ignored if they change",
"since": "1.3.0"
}
],
"extra": [
Expand Down Expand Up @@ -232,6 +239,9 @@
"public static ExternalHooks defaultExternal() {",
" return new DefaultExternalHooks(java.util.Optional.empty(), java.util.Optional.empty());",
"}",
"public static String[] defaultIgnoredScalacOptions() {",
" return new String[0];",
"}",
"public static boolean defaultLogRecompileOnMacro() {",
" return true;",
"}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public class IncOptionsUtil {
public static final String USE_OPTIMIZED_SEALED = "useOptimizedSealed";
public static final String LOG_RECOMPILE_ON_MACRO = "logRecompileOnMacro";
public static final String CLASSFILE_MANAGER_TYPE_KEY = "classfileManagerType";
public static final String IGNORED_SCALAC_OPTIONS_KEY = "ignoredScalacOptions";
public static final String TRANSACTIONAL_MANAGER_TYPE = "transactionalManagerType";
public static final String TRANSACTIONAL_MANAGER_BASE_DIRECTORY = "transactionalManagerBaseDirectory";
public static final String DELETE_IMMEDIATELY_MANAGER_TYPE = "deleteImmediatelyManagerType";
Expand Down Expand Up @@ -139,6 +140,11 @@ public static IncOptions fromStringMap(Map<String, String> values, Logger logger
base = base.withUseOptimizedSealed(Boolean.parseBoolean(values.get(USE_OPTIMIZED_SEALED)));
}

if (values.containsKey(IGNORED_SCALAC_OPTIONS_KEY)) {
logger.debug(f0("IGNORED_SCALAC_OPTIONS_KEY value was read."));
base = base.withIgnoredScalacOptions(values.get(IGNORED_SCALAC_OPTIONS_KEY).split(" +"));
}

return base;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,14 @@ object MiniSetupUtil {
/* *********************************************************************** */

/* Define first because `Equiv[CompileOrder.value]` dominates `Equiv[MiniSetup]`. */
implicit def equivCompileSetup(
implicit def equivCompileSetup(equivOpts: Equiv[MiniOptions])(
implicit equivOutput: Equiv[APIOutput],
equivOpts: Equiv[MiniOptions],
equivComp: Equiv[String]
): Equiv[MiniSetup] = {
new Equiv[MiniSetup] {
def equiv(a: MiniSetup, b: MiniSetup) = {
/* Hard-code these to use the `Equiv` defined in this class. For
* some reason, `Equiv[Nothing]` or an equivalent is getting injected
* into here now, and it's borking all our results. This fixes it. */
def sameOutput = MiniSetupUtil.equivOutput.equiv(a.output, b.output)
def sameOptions = MiniSetupUtil.equivOpts.equiv(a.options, b.options)
def sameOutput = equivOutput.equiv(a.output, b.output)
def sameOptions = equivOpts.equiv(a.options, b.options)
def sameCompiler = equivComp.equiv(a.compilerVersion, b.compilerVersion)
def sameOrder = a.order == b.order
def sameExtra = equivPairs.equiv(a.extra, b.extra)
Expand Down Expand Up @@ -107,10 +103,13 @@ object MiniSetupUtil {
}
}

implicit val equivOpts: Equiv[MiniOptions] = {
// for compatibility
val equivOpts: Equiv[MiniOptions] = equivOpts0(Equiv.fromFunction(_ sameElements _))

def equivOpts0(equivScalacOpts: Equiv[Array[String]]): Equiv[MiniOptions] = {
new Equiv[MiniOptions] {
def equiv(a: MiniOptions, b: MiniOptions) = {
(a.scalacOptions sameElements b.scalacOptions) &&
equivScalacOpts.equiv(a.scalacOptions, b.scalacOptions) &&
(a.javacOptions sameElements b.javacOptions)
}
}
Expand All @@ -127,4 +126,25 @@ object MiniSetupUtil {
def equiv(a: CompileOrder, b: CompileOrder) = a == b
}
}

def equivScalacOptions(ignoredRegexes: Array[String]): Equiv[Array[String]] = {
def groupWithParams(opts: Array[String]): Set[String] = {
def isParam(s: String) = !s.startsWith("-")
def recur(opts: List[String], res: Set[String]): Set[String] = opts match {
case opt :: param :: rest if isParam(param) => recur(rest, res + s"$opt $param")
case opt :: rest => recur(rest, res + opt)
case Nil => res
}
recur(opts.toList, Set.empty)
}
val ignoreRegex = ignoredRegexes.mkString("|").r
def dropIgnored(opts: Set[String]): Set[String] =
opts.filterNot(ignoreRegex.pattern.matcher(_).matches)

new Equiv[Array[String]] {
override def equiv(opts1: Array[String], opts2: Array[String]): Boolean = {
dropIgnored(groupWithParams(opts1)) == dropIgnored(groupWithParams(opts2))
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package sbt.internal.inc

import MiniSetupUtil._

class MiniSetupUtilSpec extends UnitSpec {

it should "detect options change" in {
val equiv = equivScalacOptions(ignoredRegexes = Array())

val before = Array("-deprecation")
val after = Array[String]()

equiv.equiv(before, after) shouldBe false
}

it should "ignore options list different by specfied options (exact)" in {
val equiv = equivScalacOptions(ignoredRegexes = Array("-Xprint:typer", "-Xfatal-warnings"))

val before = Array("-Xprint:typer", "-deprecation")
val after = Array("-Xfatal-warnings", "-deprecation")

equiv.equiv(before, after) shouldBe true
}

it should "use regex to ignore options" in {
val equiv = equivScalacOptions(ignoredRegexes = Array("-Xprint:.*"))

val before = Array("-Xprint:typer")
val after = Array("-Xprint:typer", "-Xprint:refcheck", "-Xprint:parse")

equiv.equiv(before, after) shouldBe true
}

it should "combine options with their parameters with space for analysis" in {
val equiv = equivScalacOptions(ignoredRegexes = Array("-opt .*"))

val before = Array("-opt", "abc")
val after = Array("-opt", "def")

equiv.equiv(before, after) shouldBe true
}

it should "detect change for options with parameters" in {
val equiv = equivScalacOptions(ignoredRegexes = Array("-opt a.*"))

val before = Array("-opt", "abc")
val after = Array("-opt", "def")

equiv.equiv(before, after) shouldBe false
}

it should "ignore reordering of options" in {
val equiv = equivScalacOptions(ignoredRegexes = Array())

val before = Array("-a", "1", "-b", "2", "-c")
val after = Array("-b", "2", "-c", "-a", "1")

equiv.equiv(before, after) shouldBe true
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import sbt.util.InterfaceUtil
import xsbti._
import xsbti.compile.CompileOrder.Mixed
import xsbti.compile.{ ClasspathOptions => XClasspathOptions, JavaTools => XJavaTools, _ }
import sbt.internal.inc.MiniSetupUtil._

class IncrementalCompilerImpl extends IncrementalCompiler {

Expand Down Expand Up @@ -262,8 +263,9 @@ class IncrementalCompilerImpl extends IncrementalCompiler {
else {
val (analysis, changed) = compileInternal(
MixedAnalyzingCompiler(config)(logger),
MiniSetupUtil.equivCompileSetup,
MiniSetupUtil.equivPairs,
equivCompileSetup(
equivOpts0(equivScalacOptions(incrementalOptions.ignoredScalacOptions))),
equivPairs,
logger
)
CompileResult.of(analysis, config.currentSetup, changed)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
class A
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
class B
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
class C
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class A {
val a = 1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ignoredScalacOptions = -Xfatal-warnings
scalac.options = -deprecation -Xprint:typer
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ignoredScalacOptions = -Xfatal-warnings
scalac.options = -Xfatal-warnings -Xprint:typer -deprecation
7 changes: 7 additions & 0 deletions zinc/src/sbt-test/source-dependencies/scalac-options/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
> compile

$ copy-file changes/A.scala A.scala
$ copy-file changes/incOptions.properties incOptions.properties

> compile
> checkRecompilations 1 A

0 comments on commit ae02d7e

Please sign in to comment.