Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 37 additions & 25 deletions src/core/lombok/javac/CompilerMessageSuppressor.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2011-2021 The Project Lombok Authors.
* Copyright (C) 2011-2025 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand All @@ -24,7 +24,10 @@
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
Expand All @@ -36,7 +39,6 @@

import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.JCDiagnostic;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Log;

import lombok.permit.Permit;
Expand All @@ -53,9 +55,14 @@ public final class CompilerMessageSuppressor {
private static final Field deferDiagnosticsField, deferredDiagnosticsField, diagnosticHandlerField;
private static final ConcurrentMap<Class<?>, Field> handlerDeferredFields = new ConcurrentHashMap<Class<?>, Field>();
private static final Field NULL_FIELD;
private static final Class<?> DIAGNOSTIC_HANDLER;
private static final Class<?> DISCARD_DIAGNOSTIC_HANDLER;
private static final Method POP_DIAGNOSTIC_HANDLER;
private static final Constructor<?> DISCARD_DIAGNOSTIC_HANDLER_CONSTRUCTOR;
private Boolean dumpOnError, promptOnError;
private DiagnosticListener<?> contextDiagnosticListener, logDiagnosticListener;
private final Context context;
private Object diagnosticHandler;

private static final ThreadLocal<Queue<?>> queueCache = new ThreadLocal<Queue<?>>();

Expand Down Expand Up @@ -87,6 +94,11 @@ enum Writers {
diagnosticHandlerField = getDeclaredField(Log.class, "diagnosticHandler");

NULL_FIELD = getDeclaredField(JavacResolution.class, "NULL_FIELD");

DIAGNOSTIC_HANDLER = getClass("com.sun.tools.javac.util.Log$DiagnosticHandler");
DISCARD_DIAGNOSTIC_HANDLER = getClass("com.sun.tools.javac.util.Log$DiscardDiagnosticHandler");
POP_DIAGNOSTIC_HANDLER = DIAGNOSTIC_HANDLER != null ? Permit.permissiveGetMethod(Log.class, "popDiagnosticHandler", DIAGNOSTIC_HANDLER) : null;
DISCARD_DIAGNOSTIC_HANDLER_CONSTRUCTOR = DISCARD_DIAGNOSTIC_HANDLER != null ? Permit.permissiveGetConstructor(DISCARD_DIAGNOSTIC_HANDLER, Log.class) : null;
}

static Field getDeclaredField(Class<?> c, String fieldName) {
Expand All @@ -97,6 +109,14 @@ static Field getDeclaredField(Class<?> c, String fieldName) {
}
}

static Class<?> getClass(String name) {
try {
return Class.forName(name);
} catch (Throwable t) {
return null;
}
}

public CompilerMessageSuppressor(Context context) {
this.log = Log.instance(context);
this.context = context;
Expand All @@ -118,16 +138,6 @@ public void disableLoggers() {
}
} catch (Exception e) {}

if (diagnosticHandlerField != null) try {
Object handler = diagnosticHandlerField.get(log);
Field field = getDeferredField(handler);
if (field != null) {
queueCache.set((Queue<?>) field.get(handler));
Queue<?> empty = new LinkedList<Object>();
field.set(handler, empty);
}
} catch (Exception e) {}

if (dumpOnErrorField != null) try {
dumpOnError = (Boolean) dumpOnErrorField.get(log);
dumpOnErrorField.set(log, false);
Expand All @@ -145,6 +155,11 @@ public void disableLoggers() {
diagnosticListenerField.set(log, null);
} catch (Exception e) {
}

if (DISCARD_DIAGNOSTIC_HANDLER != null) try {
diagnosticHandler = Permit.newInstance(DISCARD_DIAGNOSTIC_HANDLER_CONSTRUCTOR, log);
} catch (Exception e) {
}
}

private static Field getDeferredField(Object handler) {
Expand Down Expand Up @@ -183,19 +198,15 @@ public void enableLoggers() {
logDiagnosticListener = null;
} catch (Exception e) {}

if (diagnosticHandlerField != null && queueCache.get() != null) try {
Object handler = diagnosticHandlerField.get(log);
Field field = getDeferredField(handler);
if (field != null) {
field.set(handler, queueCache.get());
queueCache.set(null);
}
} catch (Exception e) {}

if (deferDiagnosticsField != null && queueCache.get() != null) try {
deferredDiagnosticsField.set(log, queueCache.get());
queueCache.set(null);
} catch (Exception e) {}

if (diagnosticHandler != null) try {
Permit.invoke(POP_DIAGNOSTIC_HANDLER, log, diagnosticHandler);
} catch (Exception e) {}
diagnosticHandler = null;
}

public void removeAllBetween(JavaFileObject sourcefile, int startPos, int endPos) {
Expand All @@ -222,19 +233,20 @@ public void removeAllBetween(JavaFileObject sourcefile, int startPos, int endPos
if (field == null || receiver == null) return;

try {
ListBuffer<?> deferredDiagnostics = (ListBuffer<?>) field.get(receiver);
ListBuffer<Object> newDeferredDiagnostics = new ListBuffer<Object>();
Collection<?> deferredDiagnostics = (Collection<?>) field.get(receiver);
if (deferredDiagnostics.isEmpty()) return;
LinkedList<Object> newDeferredDiagnostics = new LinkedList<Object>();
for (Object diag_ : deferredDiagnostics) {
if (!(diag_ instanceof JCDiagnostic)) {
newDeferredDiagnostics.append(diag_);
newDeferredDiagnostics.add(diag_);
continue;
}
JCDiagnostic diag = (JCDiagnostic) diag_;
long here = diag.getStartPosition();
if (here >= startPos && here < endPos && diag.getSource() == sourcefile) {
// We eliminate it
} else {
newDeferredDiagnostics.append(diag);
newDeferredDiagnostics.add(diag);
}
}
field.set(receiver, newDeferredDiagnostics);
Expand Down
2 changes: 2 additions & 0 deletions src/core/lombok/javac/JavacAST.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Position;

/**
* Wraps around javac's internal AST view to add useful features as well as the ability to visit parents from children,
Expand Down Expand Up @@ -595,6 +596,7 @@ void printMessage(Diagnostic.Kind kind, String message, JavacNode node, Diagnost
}

public void removeFromDeferredDiagnostics(int startPos, int endPos) {
if (startPos == Position.NOPOS || endPos == Position.NOPOS) return;
JCCompilationUnit self = (JCCompilationUnit) top().get();
new CompilerMessageSuppressor(getContext()).removeAllBetween(self.sourcefile, startPos, endPos);
}
Expand Down
6 changes: 3 additions & 3 deletions src/core/lombok/javac/JavacResolution.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2011-2021 The Project Lombok Authors.
* Copyright (C) 2011-2025 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -416,7 +416,7 @@ private static Iterable<? extends Type> concat(final Type t, final Collection<?
}

private static int compare(Name a, Name b) {
return a.compareTo(b);
return a.toString().compareTo(b.toString());
}

private static boolean isLocalType(TypeSymbol symbol) {
Expand Down Expand Up @@ -469,7 +469,7 @@ private static JCExpression typeToJCTree0(Type type, JavacAST ast, boolean allow
winLevel = level;
continue;
}
if (compare(winner.tsym.getQualifiedName(), t.tsym.getQualifiedName()) < 0) winner = t;
if (compare(winner.tsym.getQualifiedName(), t.tsym.getQualifiedName()) > 0) winner = t;
}
if (winner == null) return createJavaLangObject(ast);
return typeToJCTree(winner, ast, allowCompound, allowVoid, allowCapture);
Expand Down
10 changes: 9 additions & 1 deletion src/utils/lombok/permit/Permit.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2021 The Project Lombok Authors.
* Copyright (C) 2018-2025 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -165,6 +165,14 @@ public static <T> Constructor<T> getConstructor(Class<T> c, Class<?>... paramete
return setAccessible(c.getDeclaredConstructor(parameterTypes));
}

public static <T> Constructor<T> permissiveGetConstructor(Class<T> c, Class<?>... parameterTypes) {
try {
return getConstructor(c, parameterTypes);
} catch (Exception ignore) {
return null;
}
}

private static Object reflectiveStaticFieldAccess(Class<?> c, String fName) {
try {
Field f = c.getDeclaredField(fName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import java.util.function.Function;

public class ExtensionMethodInLambda {
private static final Function<String, String> testStatic = s -> ExtensionMethodInLambda.Extensions.reverse(s);

public void testSimple() {
String test = "test";
test = ExtensionMethodInLambda.Extensions.map(test, s -> ExtensionMethodInLambda.Extensions.reverse(s));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ public static String trim(Integer integer) {
return "0";
}
}
private static final Function<String, String> testStatic = (<no type> s) -> ExtensionMethodInLambda.Extensions.reverse(s);
<clinit>() {
}
public ExtensionMethodInLambda() {
super();
}
Expand Down
2 changes: 2 additions & 0 deletions test/transform/resource/before/ExtensionMethodInLambda.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

@ExtensionMethod(value = ExtensionMethodInLambda.Extensions.class)
public class ExtensionMethodInLambda {
private static final Function<String, String> testStatic = s -> s.reverse();

public void testSimple() {
String test = "test";
test = test.map(s -> s.reverse());
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
19 cannot find symbol symbol: method invalid((s)->s.reverse()) location: variable test of type java.lang.String
21 cannot find symbol symbol: method invalid((s)->s.reverse()) location: variable test of type java.lang.String
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
6 Cannot use 'val' here because initializer expression does not have a representable type: Type cannot be resolved
7 Cannot use 'val' here because initializer expression does not have a representable type: Type cannot be resolved
8 Cannot use 'val' here because initializer expression does not have a representable type: Type cannot be resolved
9 Cannot use 'val' here because initializer expression does not have a representable type: Type cannot be resolved
10 Cannot use 'val' here because initializer expression does not have a representable type: Type cannot be resolved
11 Cannot use 'val' here because initializer expression does not have a representable type: Type cannot be resolved
12 Cannot use 'val' here because initializer expression does not have a representable type: Type cannot be resolved
Original file line number Diff line number Diff line change
@@ -1 +1 @@
19 The method invalid((<no type> s) -> {}) is undefined for the type String
21 The method invalid((<no type> s) -> {}) is undefined for the type String
Original file line number Diff line number Diff line change
@@ -1 +1 @@
17 cannot find symbol symbol: method invalid((s)->s.reverse()) location: variable test of type java.lang.String
19 cannot find symbol symbol: method invalid((s)->s.reverse()) location: variable test of type java.lang.String
Loading