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

Handle field initializer in diet mode #3578

Merged
merged 2 commits into from
Jan 12, 2024
Merged
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
39 changes: 38 additions & 1 deletion src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2022 The Project Lombok Authors.
* Copyright (C) 2009-2024 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 @@ -2972,4 +2972,41 @@ public static void copyJavadocFromParam(EclipseNode from, MethodDeclaration to,
setDocComment(cud, type, to, newJavadoc);
} catch (Exception ignore) {}
}

/**
* Returns the method node containing the given annotation, or {@code null} if the given annotation node is not on a method or argument.
*/
public static EclipseNode getAnnotatedMethod(EclipseNode node) {
if (node == null || node.getKind() != Kind.ANNOTATION) return null;

EclipseNode result = node.up();
if (result.getKind() == Kind.ARGUMENT) {
result = node.up();
}
if (result.getKind() != Kind.METHOD) {
result = null;
}
return result;
}

/**
* Returns {@code true} if the given method node body was parsed.
*/
public static boolean hasParsedBody(EclipseNode method) {
if (method == null || method.getKind() != Kind.METHOD) return false;

boolean isCompleteParse = method.getAst().isCompleteParse();
if (isCompleteParse) return true;

AbstractMethodDeclaration methodDecl = (AbstractMethodDeclaration) method.get();
if (methodDecl.statements != null) return true;

// If the method is part of a field initializer it was parsed
EclipseNode parent = method.up();
while (parent != null) {
if (parent.getKind() == Kind.FIELD) return true;
parent = parent.up();
}
return false;
}
}
18 changes: 14 additions & 4 deletions src/core/lombok/eclipse/handlers/HandleLocked.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2023 The Project Lombok Authors.
* Copyright (C) 2021-2024 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 @@ -21,15 +21,19 @@
*/
package lombok.eclipse.handlers;

import static lombok.eclipse.EcjAugments.ASTNode_handled;
import static lombok.eclipse.handlers.EclipseHandlerUtil.*;

import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;

import lombok.Locked;
import lombok.core.AnnotationValues;
import lombok.core.HandlerPriority;
import lombok.eclipse.DeferUntilPostDiet;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
import lombok.Locked;
import lombok.spi.Provides;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;

/**
* Handles the {@code lombok.Locked} annotation for eclipse.
Expand All @@ -52,5 +56,11 @@ public class HandleLocked extends EclipseAnnotationHandler<Locked> {
@Override public void preHandle(AnnotationValues<Locked> annotation, Annotation source, EclipseNode annotationNode) {
String annotationValue = annotation.getInstance().value();
HandleLockedUtil.preHandle(annotationValue, LOCK_TYPE_CLASS, LOCK_IMPL_CLASS, annotationNode);

if (hasParsedBody(getAnnotatedMethod(annotationNode))) {
// This method has a body in diet mode, so we have to handle it now.
handle(annotation, source, annotationNode);
ASTNode_handled.set(source, true);
}
}
}
18 changes: 14 additions & 4 deletions src/core/lombok/eclipse/handlers/HandleLockedRead.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2023 The Project Lombok Authors.
* Copyright (C) 2021-2024 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 @@ -21,15 +21,19 @@
*/
package lombok.eclipse.handlers;

import static lombok.eclipse.EcjAugments.ASTNode_handled;
import static lombok.eclipse.handlers.EclipseHandlerUtil.*;

import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;

import lombok.Locked;
import lombok.core.AnnotationValues;
import lombok.core.HandlerPriority;
import lombok.eclipse.DeferUntilPostDiet;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
import lombok.Locked;
import lombok.spi.Provides;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;

/**
* Handles the {@code lombok.Locked.Read} annotation for eclipse.
Expand All @@ -53,5 +57,11 @@ public class HandleLockedRead extends EclipseAnnotationHandler<Locked.Read> {
@Override public void preHandle(AnnotationValues<Locked.Read> annotation, Annotation source, EclipseNode annotationNode) {
String annotationValue = annotation.getInstance().value();
HandleLockedUtil.preHandle(annotationValue, LOCK_TYPE_CLASS, LOCK_IMPL_CLASS, annotationNode);

if (hasParsedBody(getAnnotatedMethod(annotationNode))) {
// This method has a body in diet mode, so we have to handle it now.
handle(annotation, source, annotationNode);
ASTNode_handled.set(source, true);
}
}
}
18 changes: 14 additions & 4 deletions src/core/lombok/eclipse/handlers/HandleLockedWrite.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2023 The Project Lombok Authors.
* Copyright (C) 2021-2024 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 @@ -21,15 +21,19 @@
*/
package lombok.eclipse.handlers;

import static lombok.eclipse.EcjAugments.ASTNode_handled;
import static lombok.eclipse.handlers.EclipseHandlerUtil.*;

import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;

import lombok.Locked;
import lombok.core.AnnotationValues;
import lombok.core.HandlerPriority;
import lombok.eclipse.DeferUntilPostDiet;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
import lombok.Locked;
import lombok.spi.Provides;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;

/**
* Handles the {@code lombok.Locked.Write} annotation for eclipse.
Expand All @@ -53,5 +57,11 @@ public class HandleLockedWrite extends EclipseAnnotationHandler<Locked.Write> {
@Override public void preHandle(AnnotationValues<Locked.Write> annotation, Annotation source, EclipseNode annotationNode) {
String annotationValue = annotation.getInstance().value();
HandleLockedUtil.preHandle(annotationValue, LOCK_TYPE_CLASS, LOCK_IMPL_CLASS, annotationNode);

if (hasParsedBody(getAnnotatedMethod(annotationNode))) {
// This method has a body in diet mode, so we have to handle it now.
handle(annotation, source, annotationNode);
ASTNode_handled.set(source, true);
}
}
}
30 changes: 20 additions & 10 deletions src/core/lombok/eclipse/handlers/HandleSneakyThrows.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2021 The Project Lombok Authors.
* Copyright (C) 2009-2024 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 @@ -22,22 +22,14 @@
package lombok.eclipse.handlers;

import static lombok.core.handlers.HandlerUtil.*;
import static lombok.eclipse.EcjAugments.ASTNode_handled;
import static lombok.eclipse.handlers.EclipseHandlerUtil.*;

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import lombok.ConfigurationKeys;
import lombok.SneakyThrows;
import lombok.core.AnnotationValues;
import lombok.core.HandlerPriority;
import lombok.eclipse.DeferUntilPostDiet;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
import lombok.spi.Provides;

import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
Expand All @@ -58,6 +50,15 @@
import org.eclipse.jdt.internal.compiler.ast.TryStatement;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;

import lombok.ConfigurationKeys;
import lombok.SneakyThrows;
import lombok.core.AnnotationValues;
import lombok.core.HandlerPriority;
import lombok.eclipse.DeferUntilPostDiet;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
import lombok.spi.Provides;

/**
* Handles the {@code lombok.HandleSneakyThrows} annotation for eclipse.
*/
Expand All @@ -76,6 +77,15 @@ private static class DeclaredException {
}
}

@Override
public void preHandle(AnnotationValues<SneakyThrows> annotation, Annotation ast, EclipseNode annotationNode) {
if (hasParsedBody(getAnnotatedMethod(annotationNode))) {
// This method has a body in diet mode, so we have to handle it now.
handle(annotation, ast, annotationNode);
ASTNode_handled.set(ast, true);
}
}

@Override public void handle(AnnotationValues<SneakyThrows> annotation, Annotation source, EclipseNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.SNEAKY_THROWS_FLAG_USAGE, "@SneakyThrows");

Expand Down
9 changes: 8 additions & 1 deletion src/core/lombok/eclipse/handlers/HandleSynchronized.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2021 The Project Lombok Authors.
* Copyright (C) 2009-2024 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 @@ -22,6 +22,7 @@
package lombok.eclipse.handlers;

import static lombok.core.handlers.HandlerUtil.*;
import static lombok.eclipse.EcjAugments.ASTNode_handled;
import static lombok.eclipse.handlers.EclipseHandlerUtil.*;

import java.lang.reflect.Modifier;
Expand Down Expand Up @@ -70,6 +71,12 @@ public class HandleSynchronized extends EclipseAnnotationHandler<Synchronized> {
if (method.isAbstract()) return;

createLockField(annotation, annotationNode, new boolean[] {method.isStatic()}, false);

if (hasParsedBody(getAnnotatedMethod(annotationNode))) {
// This method has a body in diet mode, so we have to handle it now.
handle(annotation, source, annotationNode);
ASTNode_handled.set(source, true);
}
}

public char[] createLockField(AnnotationValues<Synchronized> annotation, EclipseNode annotationNode, boolean[] isStatic, boolean reportErrors) {
Expand Down
35 changes: 23 additions & 12 deletions test/core/src/lombok/AbstractRunTests.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2018 The Project Lombok Authors.
* Copyright (C) 2009-2024 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 @@ -29,14 +29,12 @@
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;

import org.junit.Assert;

Expand Down Expand Up @@ -83,28 +81,38 @@ public final FileTester createTester(final DirectoryRunner.TestParams params, fi
return new FileTester() {
@Override public void runTest() throws Throwable {
if (directiveFailure_ != null) throw directiveFailure_;
LinkedHashSet<CompilerMessage> messages = new LinkedHashSet<CompilerMessage>();
StringWriter writer = new StringWriter();

LombokConfiguration.overrideConfigurationResolverFactory(new ConfigurationResolverFactory() {
@Override public ConfigurationResolver createResolver(URI sourceLocation) {
return sourceDirectives_.getConfiguration();
}
});

TestParameters testParameters = new TestParameters();
testParameters.setEncoding(sourceDirectives_.getSpecifiedEncoding());
testParameters.setFormatPreferences(sourceDirectives_.getFormatPreferences());
testParameters.setMinVersion(sourceDirectives_.minVersion());
testParameters.setVerifyDiet(sourceDirectives_.isVerifyDiet());
boolean checkPositions = !(params instanceof TestLombokFilesIdempotent || params instanceof TestSourceFiles) && !sourceDirectives_.isSkipCompareContent();
testParameters.setCheckPositions(checkPositions);
String javaVersionString = System.getProperty("compiler.compliance.level");
if (javaVersionString != null) {
long version = Long.parseLong(javaVersionString);
testParameters.setSourceVersion(version);
testParameters.setTargetVersion(version);
}

boolean changed = transformCode(messages, writer, file, sourceDirectives_.getSpecifiedEncoding(), sourceDirectives_.getFormatPreferences(), sourceDirectives_.minVersion(), checkPositions);
TransformationResult result = transformCode(file, testParameters);
boolean changed = result.isChanged();
boolean forceUnchanged = sourceDirectives_.forceUnchanged() || sourceDirectives_.isSkipCompareContent();
if (params.expectChanges() && !forceUnchanged && !changed) messages.add(new CompilerMessage(-1, -1, true, "not flagged modified"));
if (!params.expectChanges() && changed) messages.add(new CompilerMessage(-1, -1, true, "unexpected modification"));
if (params.expectChanges() && !forceUnchanged && !changed) result.addMessage(new CompilerMessage(-1, -1, true, "not flagged modified"));
if (!params.expectChanges() && changed) result.addMessage(new CompilerMessage(-1, -1, true, "unexpected modification"));

compare(file.getName(), expected, writer.toString(), messages, params.printErrors(), sourceDirectives_.isSkipCompareContent() || expected.isSkipCompareContent());
compare(file.getName(), expected, result, params.printErrors(), sourceDirectives_.isSkipCompareContent() || expected.isSkipCompareContent());
}
};
}

protected abstract boolean transformCode(Collection<CompilerMessage> messages, StringWriter result, File file, String encoding, Map<String, String> formatPreferences, int minVersion, boolean checkPositions) throws Throwable;
protected abstract TransformationResult transformCode(File file, TestParameters parameters) throws Throwable;

protected String readFile(File file) throws IOException {
BufferedReader reader;
Expand Down Expand Up @@ -154,7 +162,10 @@ private static void dumpToFile(File file, Collection<CompilerMessage> content) t
}
}

private void compare(String name, LombokTestSource expected, String actualFile, LinkedHashSet<CompilerMessage> actualMessages, boolean printErrors, boolean skipCompareContent) throws Throwable {
private void compare(String name, LombokTestSource expected, TransformationResult result, boolean printErrors, boolean skipCompareContent) throws Throwable {
String actualFile = result.getOutput();
LinkedHashSet<CompilerMessage> actualMessages = result.getMessages();

if (!skipCompareContent) try {
compareContent(name, expected.getContent(), actualFile);
} catch (Throwable e) {
Expand Down
Loading
Loading