Merge branch 'TokenScanner'

This commit is contained in:
Reinier Zwitserloot committed 2025-05-23 04:01:27 +02:00
commit 99c230640e
3 files changed
+42 -3

No files matched your search

+1
View File
@@ -2,6 +2,7 @@ Lombok Changelog
----------------
### v1.18.39 "Edgy Guinea Pig"
* BUGFIX: Recent versions of eclipse (or the eclipse-based java lang server for VSCode) caused `java.lang.IllegalArgumentException: Document does not match the AST`. [Issue #3886](https://github.com/projectlombok/lombok/issues/3886).
* FEATURE: `@Jacksonized @Accessors(fluent=true)` automatically creates the relevant annotations such that Jackson correctly identifies fluent accessors.
* IMPROBABLE BREAKING CHANGE: From versions 1.18.16 to 1.18.38, lombok automatically copies certain Jackson annotations (e.g., `@JsonProperty`) from fields to the corresponding accessors (getters/setters). However, it turned out to be harmful in certain situations. Thus, Lombok does not automatically copy those annotations any more. You can restore the old behavior using the [config key](https://projectlombok.org/features/configuration) `lombok.copyJacksonAnnotationsToAccessors = true`.
@@ -333,6 +333,13 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
.transplant()
.build());
sm.addScriptIfComplexWitness(new String[][] {OSGI_TYPES, new String[] {"org/eclipse/jdt/internal/compiler/parser/TerminalToken"}}, ScriptBuilder.replaceMethodCall()
.target(new MethodTarget("org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer", "visit"))
.methodToReplace(new Hook("org.eclipse.jdt.internal.core.dom.rewrite.TokenScanner", "getTokenEndOffset", "int", "org.eclipse.jdt.internal.compiler.parser.TerminalToken", "int"))
.replacementMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "getTokenEndOffsetFixed", "int", "org.eclipse.jdt.internal.core.dom.rewrite.TokenScanner", "java.lang.Object", "int", "java.lang.Object"))
.requestExtra(StackRequest.PARAM1)
.transplant()
.build());
}
private static void patchPostCompileHookEclipse(ScriptManager sm) {
@@ -483,7 +483,7 @@ final class PatchFixesHider {
}
return result;
}
public static boolean isGenerated(org.eclipse.jdt.internal.compiler.ast.ASTNode node) {
boolean result = false;
try {
@@ -493,7 +493,7 @@ final class PatchFixesHider {
}
return result;
}
public static boolean isGenerated(org.eclipse.jdt.core.IMember member) {
boolean result = false;
try {
@@ -783,6 +783,7 @@ final class PatchFixesHider {
return newChildren.toArray(new RewriteEvent[0]);
}
// Eclipse changed a method. Older versions have `getTokenOffset(int, int)` whereas newer ones have `getTokenOffset(TerminalToken, int)`. See https://github.com/eclipse-jdt/eclipse.jdt.core/issues/3303
public static int getTokenEndOffsetFixed(TokenScanner scanner, int token, int startOffset, Object domNode) throws CoreException {
boolean isGenerated = false;
try {
@@ -791,7 +792,37 @@ final class PatchFixesHider {
// If this fails, better to break some refactor scripts than to crash eclipse.
}
if (isGenerated) return -1;
return scanner.getTokenEndOffset(token, startOffset);
// `scanner.getTokenEndOffset(int, int)` is public so we can just call it directly, except it might not exist (in more recent versions of eclipse).
// Ordinarily that means you just write a private static class and shove the code in there to avoid classloader errors, but we're in PatchFixes and we need to be careful about that sort of thing.
try {
Method m = Permit.getMethod(TokenScanner.class, "getTokenEndOffset", int.class, int.class);
return (Integer) Permit.invoke(m, scanner, token, startOffset);
} catch (Exception e) {
// This is bizarre; we replaced a call to this exact method which strongly suggests it should be there. It's not going to be a nice experience in eclipse to 'break' token offsets,
// but breaking token offsets is less dire than just hard crashing the entire editor with an exception.
return -1;
}
}
public static int getTokenEndOffsetFixed(TokenScanner scanner, Object token, int startOffset, Object domNode) throws CoreException {
boolean isGenerated = false;
try {
isGenerated = (Boolean) domNode.getClass().getField("$isGenerated").get(domNode);
} catch (Exception e) {
// If this fails, better to break some refactor scripts than to crash eclipse.
}
if (isGenerated) return -1;
try {
Class<?> terminalTokenClass = Class.forName("org.eclipse.jdt.internal.compiler.parser.TerminalToken");
Method m = Permit.getMethod(TokenScanner.class, "getTokenEndOffset", terminalTokenClass, int.class);
return (Integer) Permit.invoke(m, scanner, token, startOffset);
} catch (Exception e) {
// This is bizarre; we replaced a call to this exact method which strongly suggests it should be there. It's not going to be a nice experience in eclipse to 'break' token offsets,
// but breaking token offsets is less dire than just hard crashing the entire editor with an exception.
return -1;
}
}
public static IMethod[] removeGeneratedMethods(IMethod[] methods) throws Exception {