[fixes #3605] Remove outer type reference when marking class as static

The class now implements Serializable to trigger generation of this$0
fields in the inner class. Since Java 18 the compiler only generates the
reference to the outer class if it is in use or the class is
Serializable.
This commit is contained in:
Rawi01 committed 2024-11-24 20:58:41 +01:00
1 parent 9f5de53e06
commit 4294ebd301
4 files changed
+19 -15

No files matched your search

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015-2021 The Project Lombok Authors.
* Copyright (C) 2015-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
@@ -107,7 +107,7 @@ public class HandleUtilityClass extends JavacAnnotationHandler<UtilityClass> {
if ((typeDecl.mods.flags & (Flags.INTERFACE | Flags.ANNOTATION)) != 0) markStatic = false;
}
if (markStatic) classDecl.mods.flags |= Flags.STATIC;
if (markStatic) markClassAsStatic(classDecl);
for (JavacNode element : typeNode.down()) {
if (element.getKind() == Kind.FIELD) {
@@ -125,21 +125,23 @@ public class HandleUtilityClass extends JavacAnnotationHandler<UtilityClass> {
methodDecl.mods.flags |= Flags.STATIC;
} else if (element.getKind() == Kind.TYPE) {
JCClassDecl innerClassDecl = (JCClassDecl) element.get();
innerClassDecl.mods.flags |= Flags.STATIC;
ClassSymbol innerClassSymbol = innerClassDecl.sym;
if (innerClassSymbol != null) {
if (innerClassSymbol.type instanceof ClassType) {
((ClassType) innerClassSymbol.type).setEnclosingType(Type.noType);
}
innerClassSymbol.erasure_field = null;
}
markClassAsStatic((JCClassDecl) element.get());
}
}
if (makeConstructor) createPrivateDefaultConstructor(typeNode);
}
private void markClassAsStatic(JCClassDecl classDecl) {
classDecl.mods.flags |= Flags.STATIC; // maybe Flags.NOOUTERTHIS too?
ClassSymbol innerClassSymbol = classDecl.sym;
if (innerClassSymbol != null && innerClassSymbol.type instanceof ClassType) {
ClassType classType = (ClassType) innerClassSymbol.type;
classType.setEnclosingType(Type.noType);
innerClassSymbol.erasure_field = null;
}
}
private void createPrivateDefaultConstructor(JavacNode typeNode) {
JavacTreeMaker maker = typeNode.getTreeMaker();
JCModifiers mods = maker.Modifiers(Flags.PRIVATE, List.<JCAnnotation>nil());
@@ -1,5 +1,6 @@
@java.lang.SuppressWarnings("serial")
class UtilityClassInner {
static final class UtilClass {
static final class UtilClass implements java.io.Serializable {
@java.lang.SuppressWarnings("all")
@lombok.Generated
private UtilClass() {
@@ -1,5 +1,5 @@
class UtilityClassInner {
static final @lombok.experimental.UtilityClass class UtilClass {
@java.lang.SuppressWarnings("serial") class UtilityClassInner {
static final @lombok.experimental.UtilityClass class UtilClass implements java.io.Serializable {
private @java.lang.SuppressWarnings("all") @lombok.Generated UtilClass() {
super();
throw new java.lang.UnsupportedOperationException("This is a utility class and cannot be instantiated");
@@ -1,4 +1,5 @@
@java.lang.SuppressWarnings("serial")
class UtilityClassInner {
@lombok.experimental.UtilityClass
class UtilClass {}
class UtilClass implements java.io.Serializable {}
}