Skip to content

Commit eecb3b7

Browse files
Merge commit '0bd25506d'
2 parents 89bf0ce + 0bd2550 commit eecb3b7

File tree

2 files changed

+32
-10
lines changed

2 files changed

+32
-10
lines changed

frontend/src/main/scala/bloop/engine/caches/SourceGeneratorCache.scala

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,25 @@ import bloop.logging.Logger
99
import bloop.task.Task
1010

1111
final class SourceGeneratorCache private (
12-
cache: ConcurrentHashMap[SourceGenerator, SourceGenerator.Run]
12+
cache: ConcurrentHashMap[SourceGenerator, Task[SourceGenerator.Run]]
1313
) {
1414
def update(
1515
sourceGenerator: SourceGenerator,
1616
logger: Logger,
1717
opts: CommonOptions
1818
): Task[List[AbsolutePath]] = {
19-
val previous = getStateFor(sourceGenerator)
20-
sourceGenerator.update(previous, logger, opts).map {
21-
case SourceGenerator.NoRun => Nil
22-
case SourceGenerator.PreviousRun(_, outputs) => outputs.keys.toList.sortBy(_.syntax)
23-
}
24-
}
25-
26-
private def getStateFor(sourceGenerator: SourceGenerator): SourceGenerator.Run = {
27-
Option(cache.get(sourceGenerator)).getOrElse(SourceGenerator.NoRun)
19+
cache
20+
.compute(
21+
sourceGenerator,
22+
{ (_, prev) =>
23+
val previous = Option(prev).getOrElse(Task.now(SourceGenerator.NoRun))
24+
previous.flatMap(sourceGenerator.update(_, logger, opts)).memoize
25+
}
26+
)
27+
.map {
28+
case SourceGenerator.NoRun => Nil
29+
case SourceGenerator.PreviousRun(_, outputs) => outputs.keys.toList.sortBy(_.syntax)
30+
}
2831
}
2932
}
3033

frontend/src/test/scala/bloop/SourceGeneratorSpec.scala

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,25 @@ object SourceGeneratorSpec extends bloop.testing.BaseSuite {
209209
}
210210
}
211211

212+
test("source generator is not re-run when nothing has changed") {
213+
singleProjectWithSourceGenerator("glob:*.in" :: Nil) { (workspace, project, state) =>
214+
val generatorOutput = project.config.sourceGenerators
215+
.flatMap(_.headOption)
216+
.map(p => AbsolutePath(p.outputDirectory))
217+
writeFile(workspace.resolve("hello.in"), "hello")
218+
writeFile(project.srcFor("test.scala", exists = false), assertNInputs(n = 1))
219+
val compiledState1 = state.compile(project)
220+
val origHash = sourceHashFor("NameLengths_1.scala", project, compiledState1)
221+
assertExitStatus(compiledState1, ExitStatus.Ok)
222+
223+
val compiledState2 = compiledState1.compile(project)
224+
assertExitStatus(compiledState2, ExitStatus.Ok)
225+
226+
val newHash = sourceHashFor("NameLengths_1.scala", project, compiledState2)
227+
assertEquals(origHash, newHash)
228+
}
229+
}
230+
212231
private def assertNInputs(n: Int): String =
213232
s"""class Foo {
214233
| val length = generated.NameLengths.args_${n}

0 commit comments

Comments
 (0)