[fixes #933] Add javadoc for generated constructors

This commit is contained in:
Rawi01 committed 2024-05-21 00:09:45 +02:00
1 parent 30e19e4cdc
commit eabcc3fb4a
11 files changed
+175 -5

No files matched your search

+17 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2022 The Project Lombok Authors.
* Copyright (C) 2013-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
@@ -981,4 +981,20 @@ public class HandlerUtil {
}
return null;
}
public static String getConstructorJavadocHeader(String typeName) {
return "Creates a new {@code " + typeName + "} instance.\n\n";
}
public static String getConstructorParameterJavadoc(String paramName, String fieldJavadoc) {
String fieldBaseJavadoc = stripSectionsFromJavadoc(fieldJavadoc);
String paramJavadoc = getParamJavadoc(fieldBaseJavadoc, paramName);
if (paramJavadoc == null) {
paramJavadoc = stripLinesWithTagFromJavadoc(fieldBaseJavadoc, JavadocTag.PARAM);
paramJavadoc = stripLinesWithTagFromJavadoc(paramJavadoc, JavadocTag.RETURN);
}
return paramJavadoc;
}
}
@@ -2815,10 +2815,14 @@ public class EclipseHandlerUtil {
return null;
}
public static void setDocComment(EclipseNode typeNode, EclipseNode eclipseNode, String doc) {
setDocComment((CompilationUnitDeclaration) eclipseNode.top().get(), (TypeDeclaration) typeNode.get(), eclipseNode.get(), doc);
}
public static void setDocComment(CompilationUnitDeclaration cud, EclipseNode eclipseNode, String doc) {
setDocComment(cud, (TypeDeclaration) upToTypeNode(eclipseNode).get(), eclipseNode.get(), doc);
}
public static void setDocComment(CompilationUnitDeclaration cud, TypeDeclaration type, ASTNode node, String doc) {
if (doc == null) return;
@@ -22,7 +22,7 @@
package lombok.eclipse.handlers;
import static lombok.core.handlers.HandlerUtil.*;
import static lombok.eclipse.Eclipse.*;
import static lombok.eclipse.Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
import java.lang.reflect.Modifier;
@@ -286,7 +286,8 @@ public class HandleConstructor {
ConstructorDeclaration constr = createConstructor(
staticConstrRequired ? AccessLevel.PRIVATE : level, typeNode, fieldsToParam, forceDefaults,
sourceNode, onConstructor);
injectMethod(typeNode, constr);
EclipseNode constructorNode = injectMethod(typeNode, constr);
generateConstructorJavadoc(typeNode, constructorNode, fieldsToParam);
}
generateStaticConstructor(staticConstrRequired, typeNode, staticName, level, fieldsToParam, source);
}
@@ -294,7 +295,8 @@ public class HandleConstructor {
private void generateStaticConstructor(boolean staticConstrRequired, EclipseNode typeNode, String staticName, AccessLevel level, Collection<EclipseNode> fields, ASTNode source) {
if (staticConstrRequired) {
MethodDeclaration staticConstr = createStaticConstructor(level, staticName, typeNode, fields, source);
injectMethod(typeNode, staticConstr);
EclipseNode constructorNode = injectMethod(typeNode, staticConstr);
generateConstructorJavadoc(typeNode, constructorNode, fields);
}
}
@@ -584,4 +586,27 @@ public class HandleConstructor {
constructor.traverse(new SetGeneratedByVisitor(source), typeDecl.scope);
return constructor;
}
private void generateConstructorJavadoc(EclipseNode typeNode, EclipseNode constructorNode, Collection<EclipseNode> fields) {
if (fields.isEmpty()) return;
String constructorJavadoc = getConstructorJavadocHeader(typeNode.getName());
boolean fieldDescriptionAdded = false;
for (EclipseNode fieldNode : fields) {
String paramName = String.valueOf(removePrefixFromField(fieldNode));
String fieldJavadoc = getDocComment(fieldNode);
String paramJavadoc = getConstructorParameterJavadoc(paramName, fieldJavadoc);
if (paramJavadoc == null) {
paramJavadoc = "";
} else {
fieldDescriptionAdded = true;
}
constructorJavadoc = addJavadocLine(constructorJavadoc, "@param " + paramName + " " + paramJavadoc);
}
if (fieldDescriptionAdded) {
setDocComment(typeNode, constructorNode, constructorJavadoc);
}
}
}
@@ -30,6 +30,7 @@ import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCBlock;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
@@ -251,6 +252,7 @@ public class HandleConstructor {
if (!(skipIfConstructorExists != SkipIfConstructorExists.NO && constructorExists(typeNode) != MemberExistsResult.NOT_EXISTS)) {
JCMethodDecl constr = createConstructor(staticConstrRequired ? AccessLevel.PRIVATE : level, onConstructor, typeNode, fields, allToDefault, source);
generateConstructorJavadoc(constr, typeNode, fields);
injectMethod(typeNode, constr);
}
generateStaticConstructor(staticConstrRequired, typeNode, staticName, level, allToDefault, fields, source);
@@ -259,6 +261,7 @@ public class HandleConstructor {
private void generateStaticConstructor(boolean staticConstrRequired, JavacNode typeNode, String staticName, AccessLevel level, boolean allToDefault, List<JavacNode> fields, JavacNode source) {
if (staticConstrRequired) {
JCMethodDecl staticConstr = createStaticConstructor(staticName, level, typeNode, allToDefault ? List.<JavacNode>nil() : fields, source);
generateConstructorJavadoc(staticConstr, typeNode, fields);
injectMethod(typeNode, staticConstr);
}
}
@@ -474,4 +477,28 @@ public class HandleConstructor {
createRelevantNonNullAnnotation(typeNode, methodDef);
return recursiveSetGeneratedBy(methodDef, source);
}
private void generateConstructorJavadoc(JCMethodDecl constructor, JavacNode typeNode, List<JavacNode> fields) {
if (fields.isEmpty()) return;
JCCompilationUnit cu = ((JCCompilationUnit) typeNode.top().get());
String constructorJavadoc = getConstructorJavadocHeader(typeNode.getName());
boolean fieldDescriptionAdded = false;
for (JavacNode fieldNode : fields) {
String paramName = removePrefixFromField(fieldNode).toString();
String fieldJavadoc = getDocComment(cu, fieldNode.get());
String paramJavadoc = getConstructorParameterJavadoc(paramName, fieldJavadoc);
if (paramJavadoc == null) {
paramJavadoc = "";
} else {
fieldDescriptionAdded = true;
}
constructorJavadoc = addJavadocLine(constructorJavadoc, "@param " + paramName + " " + paramJavadoc);
}
if (fieldDescriptionAdded) {
setDocComment(cu, constructor, constructorJavadoc);
}
}
}
@@ -87,6 +87,15 @@ class BuilderJavadoc<T> {
return "BuilderJavadoc.BuilderJavadocBuilder(basic=" + this.basic + ", getsetwith=" + this.getsetwith + ", predef=" + this.predef + ", predefWithJavadoc=" + this.predefWithJavadoc + ")";
}
}
/**
* Creates a new {@code BuilderJavadoc} instance.
*
* @param basic basic gets only a builder setter.
* @see #getsetwith
* @param getsetwith getsetwith gets a builder setter, an instance getter and setter, and a wither.
* @param predef Predef has a predefined builder setter with no javadoc, and the builder setter does not get this one.
* @param predefWithJavadoc predefWithJavadoc has a predefined builder setter with javadoc, so it keeps that one untouched.
*/
@java.lang.SuppressWarnings("all")
@lombok.Generated
BuilderJavadoc(final int basic, final int getsetwith, final int predef, final int predefWithJavadoc) {
@@ -10,6 +10,14 @@ public class BuilderWithDeprecated {
java.util.List<String> strings;
@Deprecated
ImmutableList<Integer> numbers;
/**
* Creates a new {@code BuilderWithDeprecated} instance.
*
* @param dep1 @deprecated since always
* @param dep2
* @param strings
* @param numbers
*/
@java.lang.SuppressWarnings("all")
@lombok.Generated
BuilderWithDeprecated(final String dep1, final int dep2, final java.util.List<String> strings, final ImmutableList<Integer> numbers) {
@@ -0,0 +1,28 @@
public class ConstructorJavadoc {
/**
* Some text
*
* @param fieldName Hello, World1
* --- GETTER ---
* Getter section
*
* @return Sky is blue1
*/
private int fieldName;
/**
* Sky is blue
*/
private int fieldName2;
/**
* Creates a new {@code ConstructorJavadoc} instance.
*
* @param fieldName Some text
* @param fieldName2 Sky is blue
*/
@java.lang.SuppressWarnings("all")
@lombok.Generated
public ConstructorJavadoc(final int fieldName, final int fieldName2) {
this.fieldName = fieldName;
this.fieldName2 = fieldName2;
}
}
@@ -46,6 +46,15 @@ import java.util.List;
private @lombok.Getter @lombok.Setter @lombok.experimental.Wither int getsetwith;
private final int predef;
private final int predefWithJavadoc;
/**
* Creates a new {@code BuilderJavadoc} instance.
*
* @param basic basic gets only a builder setter.
* @see #getsetwith
* @param getsetwith getsetwith gets a builder setter, an instance getter and setter, and a wither.
* @param predef Predef has a predefined builder setter with no javadoc, and the builder setter does not get this one.
* @param predefWithJavadoc predefWithJavadoc has a predefined builder setter with javadoc, so it keeps that one untouched.
*/
@java.lang.SuppressWarnings("all") @lombok.Generated BuilderJavadoc(final int basic, final int getsetwith, final int predef, final int predefWithJavadoc) {
super();
this.basic = basic;
@@ -89,6 +89,14 @@ public @Builder class BuilderWithDeprecated {
@Deprecated int dep2;
@Singular @Deprecated java.util.List<String> strings;
@Singular @Deprecated ImmutableList<Integer> numbers;
/**
* Creates a new {@code BuilderWithDeprecated} instance.
*
* @param dep1 @deprecated since always
* @param dep2
* @param strings
* @param numbers
*/
@java.lang.SuppressWarnings("all") @lombok.Generated BuilderWithDeprecated(final String dep1, final int dep2, final java.util.List<String> strings, final ImmutableList<Integer> numbers) {
super();
this.dep1 = dep1;
@@ -0,0 +1,16 @@
import lombok.AllArgsConstructor;
public @AllArgsConstructor class ConstructorJavadoc {
private int fieldName;
private int fieldName2;
/**
* Creates a new {@code ConstructorJavadoc} instance.
*
* @param fieldName Some text
* @param fieldName2 Sky is blue
*/
public @java.lang.SuppressWarnings("all") @lombok.Generated ConstructorJavadoc(final int fieldName, final int fieldName2) {
super();
this.fieldName = fieldName;
this.fieldName2 = fieldName2;
}
}
@@ -0,0 +1,20 @@
import lombok.AllArgsConstructor;
@AllArgsConstructor
public class ConstructorJavadoc {
/**
* Some text
*
* @param fieldName Hello, World1
* --- GETTER ---
* Getter section
*
* @return Sky is blue1
*/
private int fieldName;
/**
* Sky is blue
*/
private int fieldName2;
}