[#3886] Fix previous commit: The scan for OSGI types is important, or ecj invocations will fail. Updated patcher to allow X AND (A OR B OR C) style witnessing.

This commit is contained in:
Reinier Zwitserloot committed 2025-05-23 04:01:16 +02:00
1 parent 6a3af0704d
commit b223db1818
3 files changed
+21 -20

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`.
@@ -332,8 +332,8 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
.requestExtra(StackRequest.PARAM1)
.transplant()
.build());
sm.addScriptIfWitness(new String [] {"org/eclipse/jdt/internal/compiler/parser/TerminalToken"}, ScriptBuilder.replaceMethodCall()
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"))
@@ -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,18 +792,19 @@ final class PatchFixesHider {
// If this fails, better to break some refactor scripts than to crash eclipse.
}
if (isGenerated) return -1;
Object res = -1;
// `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);
res = Permit.invoke(m, scanner, token, startOffset);
return (Integer) Permit.invoke(m, scanner, token, startOffset);
} catch (Exception e) {
e.printStackTrace();
// continue
// 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;
}
return (Integer) res;
}
public static int getTokenEndOffsetFixed(TokenScanner scanner, Object token, int startOffset, Object domNode) throws CoreException {
boolean isGenerated = false;
try {
@@ -811,18 +813,16 @@ final class PatchFixesHider {
// If this fails, better to break some refactor scripts than to crash eclipse.
}
if (isGenerated) return -1;
Object res = -1;
try {
// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/3303
Class<?> TERMINAL_TOKEN_CLASS = Class.forName("org.eclipse.jdt.internal.compiler.parser.TerminalToken");
Method m = Permit.getMethod(TokenScanner.class, "getTokenEndOffset", TERMINAL_TOKEN_CLASS, int.class);
res = Permit.invoke(m, scanner, token, startOffset);
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) {
e.printStackTrace();
// continue
// 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;
}
return (Integer) res;
}
public static IMethod[] removeGeneratedMethods(IMethod[] methods) throws Exception {