metals
metals copied to clipboard
Find reference triggers project recompilation under certain conditions
Describe the bug
This is quite a complex issue, my apologies for a lengthy description. I am not submitting it as multiple issues because they are problematic only when combined.
Consider a simple project with two scala modules:
val moduleA = project
.in(file("moduleA"))
.settings(
scalaVersion := "3.3.3"
)
val moduleB = project
.in(file("moduleB"))
.settings(
scalaVersion := "3.3.3",
)
val root = project.in(file(".")).aggregate(moduleA, moduleB)
Let's assume that there is a method definition in module A
:
object Person{
def fromList(list: List[Any])={
println(list)
}
}
And some code that doesn't compile in module B
.
If we call find references on Person.fromList
we will see in the logs that a compilation request was issued for module B:
2024.04.25 19:31:20 INFO compiling moduleb (1 scala source and 1 java source)
2024.04.25 19:31:20 INFO time: compiled moduleB in 31ms
Apr 25, 2024 7:31:21 PM org.eclipse.lsp4j.jsonrpc.RemoteEndpoint handleCancellation
WARNING: Unmatched cancel notification for request id 204
Issue 1
I believe that this is incorrect as there is no dependency between module B
and module A
so there is no need to recompile it for the find reference request.
Issue 2
If we keep calling "find refenrences" metals will keep asking for a recompilation. Luckily, thanks to the incremental compilation this is usually fast.
Issue 3
Let's add following java code into module B
:
src/main/java/com/example/Service.java
:
package com.example;
import java.util.List;
public class Service {
void create(List<Object> args) {
var second = (java.util.Optional<String>) args.get(2);
System.out.println(second);
}
}
There is an unchecked cast in here.
Let's now remove the invalid scala code from this module and turn on fatal warnings together with linting for unchecked casts in the module B
:
val moduleB = project
.in(file("moduleB"))
.settings(
scalaVersion := "3.3.3",
scalacOptions ++= Seq(
"-Xfatal-warnings"
),
javacOptions ++= Seq(
"-Xlint:unchecked"
)
)
The interesting thing is that the project compiles now from both sbt and bloop. It reports the detected unchecked cast in sbt as a warning:
[warn] /home/kghost/workspace/demos/moduleB/src/main/java/com/example/Service.java:8:1: unchecked cast
[warn] required: java.util.Optional<java.lang.String>
[warn] found: java.lang.Object
[warn] args.get(2)
(call clean compile from metals before moving forward)
However in metals this is reported as an error:
[Trace - 07:51:31 PM] Sending notification 'textDocument/publishDiagnostics'
Params: {
"uri": "file:///home/kghost/workspace/demos/moduleB/src/main/java/com/example/Service.java",
"diagnostics": [
{
"range": {
"start": {
"line": 7,
"character": 52
},
"end": {
"line": 7,
"character": 52
}
},
"severity": 1,
"source": "bloop",
"message": " [unchecked] unchecked cast",
"data": {
"actions": []
}
}
]
}
If we now try to call find references on fromList
metals will issue compilation request for module B and it will also do it on every subsequent invocation. This is probably due to module B
being recognized as "broken".
If we now compile the project with bloop: bloop compile root
it will compile fine (as mentioned previously) but from now on, metals won't issue recompile request for module B
when calling find references on fromList
.
Calling metals "clean compile" brings us back to the previous state.
This might not seem as a big deal, but at work we have a project with several sbt modules, one of them with more than a couple of thousands java classes, unchecked casts and fatal warnings enabled.
Calling find references in one module that is not connected with anything else cause recompilation of several other modules including the big one and is freezing my laptop. Every single time.
Full project to reproduce the behavior can be found here
Bloop version: 1.5.17
Expected behavior
First of all, I would expect "find references" not to trigger compilation of modules that aren't related.
Second, I would expect broken module not to be recompiled over and over again if nothing changed there.
And last, handling of fatal warnings + "-Xlint:unchecked"
from java should be consistent among all tools. I am not sure which is the correct way.
Operating system
Linux
Editor/Extension
Nvim (nvim-metals)
Version of Metals
1.3.0
Extra context or search terms
java fatal-warnings lint-unchecked