Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect @Delegate on record components #3831

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
16 changes: 11 additions & 5 deletions src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2024 The Project Lombok Authors.
* Copyright (C) 2009-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 @@ -2736,10 +2736,8 @@ public static boolean isClassEnumOrRecord(EclipseNode typeNode) {
* Returns {@code true} if the provided node is a record declaration (so, not an annotation definition, interface, enum, or plain class).
*/
public static boolean isRecord(EclipseNode typeNode) {
TypeDeclaration typeDecl = null;
if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get();
int modifiers = typeDecl == null ? 0 : typeDecl.modifiers;
return (modifiers & AccRecord) != 0;
ASTNode node = typeNode.get();
return node instanceof TypeDeclaration && isRecord((TypeDeclaration) node);
}

/**
Expand Down Expand Up @@ -2773,6 +2771,14 @@ public static boolean isStaticAllowed(EclipseNode typeNode) {
return typeNode.isStatic() || typeNode.up() == null || typeNode.up().getKind() == Kind.COMPILATION_UNIT || isRecord(typeNode);
}

/**
* Returns {@code true} if the provided type declaration is a record declaration (so, not an annotation definition, interface, enum, or plain class).
*/
public static boolean isRecord(TypeDeclaration typeDecl) {
int modifiers = typeDecl == null ? 0 : typeDecl.modifiers;
return (modifiers & AccRecord) != 0;
}

public static AbstractVariableDeclaration[] getRecordComponents(TypeDeclaration typeDeclaration) {
if (typeDeclaration == null || (typeDeclaration.modifiers & AccRecord) == 0) return null;
try {
Expand Down
17 changes: 13 additions & 4 deletions src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2010-2024 The Project Lombok Authors.
* Copyright (C) 2010-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 @@ -48,13 +48,13 @@
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.FieldReference;
import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
Expand Down Expand Up @@ -129,7 +129,8 @@ private static String nameOfScope(ClassScope scope) {
}

private static boolean hasDelegateMarkedFieldsOrMethods(TypeDeclaration decl) {
if (decl.fields != null) for (FieldDeclaration field : decl.fields) {
AbstractVariableDeclaration[] fields = getFieldsOrRecordComponents(decl);
if (fields != null) for (AbstractVariableDeclaration field : fields) {
if (field.annotations == null) continue;
for (Annotation ann : field.annotations) {
if (isDelegate(ann, decl)) return true;
Expand Down Expand Up @@ -224,11 +225,19 @@ public static void markHandled(Annotation annotation) {
Annotation_applied.set(annotation, true);
}

private static AbstractVariableDeclaration[] getFieldsOrRecordComponents(TypeDeclaration decl) {
if (isRecord(decl)) return getRecordComponents(decl);
return decl.fields;
}

private static void fillMethodBindingsForFields(CompilationUnitDeclaration cud, ClassScope scope, List<BindingTuple> methodsToDelegate) {
TypeDeclaration decl = scope.referenceContext;
if (decl == null) return;

if (decl.fields != null) for (FieldDeclaration field : decl.fields) {
AbstractVariableDeclaration[] fields = getFieldsOrRecordComponents(decl);
if (fields == null) return;

for (AbstractVariableDeclaration field : fields) {
if (field.annotations == null) continue;
for (Annotation ann : field.annotations) {
if (!isDelegate(ann, decl)) continue;
Expand Down
8 changes: 8 additions & 0 deletions test/transform/resource/after-delombok/DelegateOnRecord.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// version 14:
record DelegateOnRecord(Runnable runnable) {
@java.lang.SuppressWarnings("all")
@lombok.Generated
public void run() {
this.runnable.run();
}
}
8 changes: 8 additions & 0 deletions test/transform/resource/after-ecj/DelegateOnRecord.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// version 14:
import lombok.experimental.Delegate;
record DelegateOnRecord(Runnable runnable) {
/* Implicit */ private final Runnable runnable;
public @java.lang.SuppressWarnings("all") @lombok.Generated void run() {
this.runnable.run();
}
}
6 changes: 6 additions & 0 deletions test/transform/resource/before/DelegateOnRecord.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//platform !eclipse: Requires a 'full' eclipse with intialized workspace, and we don't (yet) have that set up properly in the test run.
//version 14:
import lombok.experimental.Delegate;

record DelegateOnRecord(@Delegate Runnable runnable) {
}
Loading