Potential fix for var
keyword breaking linemappings with Loom
#5
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Obligatory disclaimer: I only looked at Mercury & Loom for the first time this week, and as such I am not confident that this change does not break other features. Thanks for your patience in review!
Version Details
Loom: 1.7-SNAPSHOT
Mercury: 0.4.1
Minecraft: 1.20.1
Yarn: 1.20.1+build.10
Loader: 0.15.10
Issue Explanation
We have a class in a project that always has linemapping issues - you can consistently "lose" breakpoints in IntelliJ 100% of the time by placing a breakpoint in any method within this class. The breakpoint is always consistently offset by a constant amount. I went on a goose chase yesterday to figure out why this was happening, and traced it to down to a quirk in Mercury with the
var
keyword.AFAIK: When Loom publishes or imports(?) projects, the
remapSourcesJar
task is used to map the project to Intermediary (and then re-map back to Yarn when you pull the library back into your project). This task uses Mercury under the hood to swap out identifiers based on the mappings set. I notice after some poking around that the import statements from the source code and output sources (that go through Mercury once or twice) do not match. There are 2 reproducible issues here:1. if you use
var
with a primitive type, Mercury will attempt to import the primitive type when producing remapped jar files. You can reproduce this easily by creating a new Fabric project and running theremapSourcesJar
task with code like this:If you check the output sources jar, you will find an additional import added to your class. This import will appear (and show as an error) in any projects that include your library as a dependency. Additionally, this import will shift all line-mapping down by 1, meaning you can no longer breakpoint anywhere in the class.
2. if you use
var
with a type that needs an import, and do not explicitly import the type, Mercury will inject the type in output sources jar. Every import added this way will shift your linemappings down by 1:(Left = fixed patch, Right = the same class, but every additional import was added by Mercury due to the presence of
var
keyword. Both of these library (non-vanilla) classes were piped throughremapSourcesJar
. The fixed patch is a 1:1 mirror of the original source code for the project.)Issue TL;DR
var
in this class breaks linemapping for the entire class (and thus all breakpoints)var foo = 5.0
(for any primitive type) will result in an import statement being added for the primitive (eg.import D;
) when runningremapSourcesJar
, which will offset linemappings once for every primitive type used in the class.var foo = MethodThatReturnsType.get()
without explicitly importing the type will result in an extra import being added by Mercury, which will also shift linemaps down by 1 (can no longer debug the class)Issue Fix
This issue is fixed by moving the
addImport
call within theisVar
check; it prevents imports from being forcibly added when thevar
keyword is used. As far as I can tell from testing, this has not caused any additional issues (and fixes the issues described above - our problematic 1,000 LOC class with 15var
implicitly imported types can now perfectly breakpoint at any method).