[fieldNameConstants] code review, docs, tests, fixup.

This commit is contained in:
Reinier Zwitserloot committed 2018-04-05 14:22:40 +02:00
1 parent 2c93d336c1
commit b6fb3c03fa
22 files changed
+223 -131

No files matched your search

+4 -2
View File
@@ -3,9 +3,11 @@ Lombok Changelog
### v1.16.21 "Edgy Guinea Pig"
* v1.16.20 is the latest stable release of Project Lombok.
* FEATURE: `@FieldNameConstants` is an new feature that generates string constants for your field names. [Docs on @FieldNameConstants](https://projectlombok.org/features/experimental/FieldNameConstants).
* PLATFORM: Fix for using lombok together with JDK9's new `module-info.java` feature. [Issue #985](https://github.com/rzwitserloot/lombok/issues/985)
* PLATFORM: Some initial work on supporting JDK10.
* BUGFIX: Potential fix for Netbeans < 9. [Issue #1555](https://github.com/rzwitserloot/lombok/issues/1555)
* PLATFORM: Some initial work on supporting JDK10 and JDK11.
* BUGFIX: Solved some issues in eclipse that resulted in error 'A save participant caused problems'. [Issue #879](https://github.com/rzwitserloot/lombok/issues/879)
* BUGFIX: Bugfix for Netbeans < 9. [Issue #1555](https://github.com/rzwitserloot/lombok/issues/1555)
* PROMOTION: `var` has been promoted from experimental to the main package with no changes. The 'old' experimental one is still around but is deprecated, and is an alias for the new main package one. [var documentation](https://projectlombok.org/features/var.html).
* OLD-CRUFT: `lombok.experimental.Builder` and `lombok.experimental.Value` are deprecated remnants of when these features were still in experimental. They are now removed entirely. If your project is dependent on an older version of lombok which still has those; fret not, lombok still processes these annotations. It just no longer includes them in the jar.
+8
View File
@@ -499,6 +499,14 @@ public class ConfigurationKeys {
*/
public static final ConfigurationKey<FlagUsageType> UTILITY_CLASS_FLAG_USAGE = new ConfigurationKey<FlagUsageType>("lombok.utilityClass.flagUsage", "Emit a warning or error if @UtilityClass is used.") {};
// ----- FieldNameConstants -----
/**
* lombok configuration: {@code lombok.fieldNameConstants.flagUsage} = {@code WARNING} | {@code ERROR}.
*
* If set, <em>any</em> usage of {@code @FieldNameConstants} results in a warning / error.
*/
public static final ConfigurationKey<FlagUsageType> FIELD_NAME_CONSTANTS_FLAG_USAGE = new ConfigurationKey<FlagUsageType>("lombok.fieldNameConstants.flagUsage", "Emit a warning or error if @FieldNameConstants is used.") {};
// ----- Wither -----
/**
@@ -441,4 +441,16 @@ public class HandlerUtil {
}
return String.format("%s%s", prefix, suffix);
}
public static String camelCaseToConstant(String fieldName) {
if (fieldName == null || fieldName.isEmpty()) return "";
StringBuilder b = new StringBuilder();
b.append(Character.toUpperCase(fieldName.charAt(0)));
for (int i = 1; i < fieldName.length(); i++) {
char c = fieldName.charAt(i);
if (Character.isUpperCase(c)) b.append('_');
b.append(Character.toUpperCase(c));
}
return b.toString();
}
}
@@ -1097,7 +1097,7 @@ public class EclipseHandlerUtil {
public static boolean filterField(FieldDeclaration declaration, boolean skipStatic) {
// Skip the fake fields that represent enum constants.
if (declaration.initialization instanceof AllocationExpression &&
((AllocationExpression)declaration.initialization).enumConstant != null) return false;
((AllocationExpression) declaration.initialization).enumConstant != null) return false;
if (declaration.type == null) return false;
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2014 The Project Lombok Authors.
* Copyright (C) 2014-2018 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
@@ -21,15 +21,17 @@
*/
package lombok.eclipse.handlers;
import static java.lang.Character.*;
import static lombok.core.handlers.HandlerUtil.handleExperimentalFlagUsage;
import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
import java.lang.reflect.Modifier;
import java.util.Collection;
import lombok.AccessLevel;
import lombok.ConfigurationKeys;
import lombok.core.AST.Kind;
import lombok.core.AnnotationValues;
import lombok.core.handlers.HandlerUtil;
import lombok.eclipse.Eclipse;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
@@ -45,16 +47,9 @@ import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.mangosdk.spi.ProviderFor;
@ProviderFor(EclipseAnnotationHandler.class) public class HandleFieldNameConstants extends EclipseAnnotationHandler<FieldNameConstants> {
public boolean generateFieldDefaultsForType(EclipseNode typeNode, EclipseNode errorNode, AccessLevel level, boolean checkForTypeLevelFieldNameConstants) {
if (checkForTypeLevelFieldNameConstants) {
if (hasAnnotation(FieldNameConstants.class, typeNode)) {
return true;
}
}
@ProviderFor(EclipseAnnotationHandler.class)
public class HandleFieldNameConstants extends EclipseAnnotationHandler<FieldNameConstants> {
public void generateFieldNameConstantsForType(EclipseNode typeNode, EclipseNode errorNode, AccessLevel level) {
TypeDeclaration typeDecl = null;
if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get();
@@ -62,45 +57,20 @@ import org.mangosdk.spi.ProviderFor;
boolean notAClass = (modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation)) != 0;
if (typeDecl == null || notAClass) {
errorNode.addError("@FieldNameConstants is only supported on a class or an enum or a field.");
return false;
errorNode.addError("@FieldNameConstants is only supported on a class, an enum, or a field.");
return;
}
for (EclipseNode field : typeNode.down()) {
if (fieldQualifiesForFieldNameConstantsGeneration(field)) generateFieldNameConstantsForField(field, errorNode.get(), level);
if (field.getKind() != Kind.FIELD) return false;
}
return true;
}
private void generateFieldNameConstantsForField(EclipseNode fieldNode, ASTNode pos, AccessLevel level) {
if (hasAnnotation(FieldNameConstants.class, fieldNode)) {
return;
}
if (hasAnnotation(FieldNameConstants.class, fieldNode)) return;
createFieldNameConstantsForField(level, fieldNode, fieldNode, pos, false);
}
private void createFieldNameConstantsForField(AccessLevel level, EclipseNode fieldNode, EclipseNode errorNode, ASTNode source, boolean whineIfExists) {
if (fieldNode.getKind() != Kind.FIELD) {
errorNode.addError("@FieldNameConstants is only supported on a class or a field");
return;
}
FieldDeclaration field = (FieldDeclaration) fieldNode.get();
String constantName = camelCaseToConstant(new String(field.name));
if (constantName == null) {
errorNode.addWarning("Not generating constant for this field: It does not fit in your @Accessors prefix list");
return;
}
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long) pS << 32 | pE;
FieldDeclaration fieldConstant = new FieldDeclaration(constantName.toCharArray(), pS,pE);
fieldConstant.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
fieldConstant.modifiers = toEclipseModifier(level) | Modifier.STATIC | Modifier.FINAL;
fieldConstant.type = new QualifiedTypeReference(TypeConstants.JAVA_LANG_STRING, new long[]{p,p,p});
fieldConstant.initialization = new StringLiteral(field.name, pS,pE,0);
injectField(fieldNode.up(), fieldConstant);
}
private boolean fieldQualifiesForFieldNameConstantsGeneration(EclipseNode field) {
if (field.getKind() != Kind.FIELD) return false;
FieldDeclaration fieldDecl = (FieldDeclaration) field.get();
@@ -108,43 +78,52 @@ import org.mangosdk.spi.ProviderFor;
}
public void handle(AnnotationValues<FieldNameConstants> annotation, Annotation ast, EclipseNode annotationNode) {
handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.FIELD_NAME_CONSTANTS_FLAG_USAGE, "@FieldNameConstants");
EclipseNode node = annotationNode.up();
FieldNameConstants annotatationInstance = annotation.getInstance();
AccessLevel level = annotatationInstance.level();
if (node == null) return;
switch (node.getKind()){
switch (node.getKind()) {
case FIELD:
createFieldNameConstantsForFields(level, annotationNode.upFromAnnotationToFields(), annotationNode, annotationNode.get(), true);
if (level != AccessLevel.NONE) createFieldNameConstantsForFields(level, annotationNode.upFromAnnotationToFields(), annotationNode, annotationNode.get(), true);
break;
case TYPE:
generateFieldDefaultsForType(node, annotationNode, level, false);
if (level == AccessLevel.NONE) {
annotationNode.addWarning("type-level '@FieldNameConstants' does not work with AccessLevel.NONE.");
return;
}
generateFieldNameConstantsForType(node, annotationNode, level);
break;
}
}
private void createFieldNameConstantsForFields(AccessLevel level, Collection<EclipseNode> fieldNodes, EclipseNode errorNode, ASTNode source, boolean whineIfExists) {
for (EclipseNode fieldNode : fieldNodes){
createFieldNameConstantsForField(level, fieldNode, errorNode, source, whineIfExists);
}
}
public static String camelCaseToConstant(final String fieldName) {
if (fieldName == null || fieldName.isEmpty()) return "";
char[] chars = fieldName.toCharArray();
StringBuilder b = new StringBuilder();
b.append(toUpperCase(chars[0]));
for (int i = 1, iend = chars.length; i < iend; i++) {
char c = chars[i];
if (isUpperCase(c)) {
b.append('_');
} else {
c = toUpperCase(c);
}
b.append(c);
}
return b.toString();
for (EclipseNode fieldNode : fieldNodes) createFieldNameConstantsForField(level, fieldNode, errorNode, source, whineIfExists);
}
private void createFieldNameConstantsForField(AccessLevel level, EclipseNode fieldNode, EclipseNode errorNode, ASTNode source, boolean whineIfExists) {
if (fieldNode.getKind() != Kind.FIELD) {
errorNode.addError("@FieldNameConstants is only supported on a class, an enum, or a field");
return;
}
FieldDeclaration field = (FieldDeclaration) fieldNode.get();
String fieldName = new String(field.name);
String constantName = HandlerUtil.camelCaseToConstant(fieldName);
if (constantName.equals(fieldName)) {
fieldNode.addWarning("Not generating constant for this field: The name of the constant would be equal to the name of this field.");
return;
}
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long) pS << 32 | pE;
FieldDeclaration fieldConstant = new FieldDeclaration(constantName.toCharArray(), pS,pE);
fieldConstant.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
fieldConstant.modifiers = toEclipseModifier(level) | Modifier.STATIC | Modifier.FINAL;
fieldConstant.type = new QualifiedTypeReference(TypeConstants.JAVA_LANG_STRING, new long[] {p,p,p});
fieldConstant.initialization = new StringLiteral(field.name, pS, pE, 0);
injectField(fieldNode.up(), fieldConstant);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2013 The Project Lombok Authors.
* Copyright (C) 2014-2018 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
@@ -28,16 +28,11 @@ import java.lang.annotation.Target;
import lombok.AccessLevel;
/**
* Generates String constants containing the field name for each field.
*
*/
@Target(ElementType.TYPE)
@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.SOURCE)
public @interface FieldNameConstants {
lombok.AccessLevel level()default AccessLevel.PUBLIC;
lombok.AccessLevel level() default AccessLevel.PUBLIC;
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2014 The Project Lombok Authors.
* Copyright (C) 2014-2018 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
@@ -21,13 +21,16 @@
*/
package lombok.javac.handlers;
import static lombok.core.handlers.HandlerUtil.handleExperimentalFlagUsage;
import static lombok.javac.handlers.JavacHandlerUtil.*;
import java.lang.reflect.Modifier;
import java.util.Collection;
import lombok.AccessLevel;
import lombok.ConfigurationKeys;
import lombok.core.AST.Kind;
import lombok.core.handlers.HandlerUtil;
import lombok.core.AnnotationValues;
import lombok.experimental.FieldNameConstants;
import lombok.javac.JavacAnnotationHandler;
@@ -43,18 +46,10 @@ import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCModifiers;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.List;
@ProviderFor(JavacAnnotationHandler.class) @SuppressWarnings("restriction") public class HandleFieldNameConstants extends JavacAnnotationHandler<FieldNameConstants> {
public void generateFieldDefaultsForType(JavacNode typeNode, JavacNode errorNode, AccessLevel level, boolean checkForTypeLevelFieldNameConstants) {
if (checkForTypeLevelFieldNameConstants) {
if (hasAnnotation(FieldNameConstants.class, typeNode)) {
return;
}
}
@ProviderFor(JavacAnnotationHandler.class)
public class HandleFieldNameConstants extends JavacAnnotationHandler<FieldNameConstants> {
public void generateFieldNameConstantsForType(JavacNode typeNode, JavacNode errorNode, AccessLevel level) {
JCClassDecl typeDecl = null;
if (typeNode.get() instanceof JCClassDecl) typeDecl = (JCClassDecl) typeNode.get();
@@ -62,21 +57,18 @@ import com.sun.tools.javac.util.List;
boolean notAClass = (modifiers & (Flags.INTERFACE | Flags.ANNOTATION)) != 0;
if (typeDecl == null || notAClass) {
errorNode.addError("@FieldNameConstants is only supported on a class or an enum or a field.");
errorNode.addError("@FieldNameConstants is only supported on a class, an enum, or a field.");
return;
}
for (JavacNode field : typeNode.down()) {
if (fieldQualifiesForFieldNameConstantsGeneration(field)) generateFieldNameConstantsForField(field, errorNode.get(), level);
}
}
private void generateFieldNameConstantsForField(JavacNode fieldNode, DiagnosticPosition pos, AccessLevel level) {
if (hasAnnotation(FieldNameConstants.class, fieldNode)) {
return;
}
createFieldNameConstantsForField(level, fieldNode, fieldNode, false, List.<JCAnnotation>nil());
if (hasAnnotation(FieldNameConstants.class, fieldNode)) return;
createFieldNameConstantsForField(level, fieldNode, fieldNode, false);
}
private boolean fieldQualifiesForFieldNameConstantsGeneration(JavacNode field) {
@@ -88,6 +80,7 @@ import com.sun.tools.javac.util.List;
}
public void handle(AnnotationValues<FieldNameConstants> annotation, JCAnnotation ast, JavacNode annotationNode) {
handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.FIELD_NAME_CONSTANTS_FLAG_USAGE, "@FieldNameConstants");
Collection<JavacNode> fields = annotationNode.upFromAnnotationToFields();
deleteAnnotationIfNeccessary(annotationNode, FieldNameConstants.class);
@@ -95,40 +88,36 @@ import com.sun.tools.javac.util.List;
JavacNode node = annotationNode.up();
FieldNameConstants annotatationInstance = annotation.getInstance();
AccessLevel level = annotatationInstance.level();
if (level == AccessLevel.NONE) {
annotationNode.addWarning("'lazy' does not work with AccessLevel.NONE.");
return;
}
if (node == null) return;
List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@FieldNameConstants(onMethod=", annotationNode);
switch (node.getKind()) {
case FIELD:
createFieldNameConstantsForFields(level, fields, annotationNode, annotationNode, true, onMethod);
if (level != AccessLevel.NONE) createFieldNameConstantsForFields(level, fields, annotationNode, annotationNode, true);
break;
case TYPE:
if (!onMethod.isEmpty()) {
annotationNode.addError("'onMethod' is not supported for @FieldNameConstants on a type.");
if (level == AccessLevel.NONE) {
annotationNode.addWarning("type-level '@FieldNameConstants' does not work with AccessLevel.NONE.");
return;
}
generateFieldDefaultsForType(node, annotationNode, level, false);
generateFieldNameConstantsForType(node, annotationNode, level);
break;
}
}
private void createFieldNameConstantsForFields(AccessLevel level, Collection<JavacNode> fieldNodes, JavacNode annotationNode, JavacNode errorNode, boolean whineIfExists, List<JCAnnotation> onMethod) {
for (JavacNode fieldNode : fieldNodes) {
createFieldNameConstantsForField(level, fieldNode, errorNode, whineIfExists, onMethod);
}
private void createFieldNameConstantsForFields(AccessLevel level, Collection<JavacNode> fieldNodes, JavacNode annotationNode, JavacNode errorNode, boolean whineIfExists) {
for (JavacNode fieldNode : fieldNodes) createFieldNameConstantsForField(level, fieldNode, errorNode, whineIfExists);
}
private void createFieldNameConstantsForField(AccessLevel level, JavacNode fieldNode, JavacNode source, boolean whineIfExists, List<JCAnnotation> onMethod) {
private void createFieldNameConstantsForField(AccessLevel level, JavacNode fieldNode, JavacNode source, boolean whineIfExists) {
if (fieldNode.getKind() != Kind.FIELD) {
source.addError("@FieldNameConstants is only supported on a class or a field");
source.addError("@FieldNameConstants is only supported on a class, an enum, or a field");
return;
}
JCVariableDecl field = (JCVariableDecl) fieldNode.get();
String constantName = camelCaseToConstant(field.name.toString());
if (constantName == null) {
source.addWarning("Not generating constant for this field: It does not fit in your @Accessors prefix list");
String fieldName = field.name.toString();
String constantName = HandlerUtil.camelCaseToConstant(fieldName);
if (constantName.equals(fieldName)) {
fieldNode.addWarning("Not generating constant for this field: The name of the constant would be equal to the name of this field.");
return;
}
@@ -139,21 +128,4 @@ import com.sun.tools.javac.util.List;
JCVariableDecl fieldConstant = treeMaker.VarDef(modifiers, fieldNode.toName(constantName), returnType, init);
injectField(fieldNode.up(), fieldConstant);
}
public static String camelCaseToConstant(final String fieldName) {
if (fieldName == null || fieldName.isEmpty()) return "";
char[] chars = fieldName.toCharArray();
StringBuilder b = new StringBuilder();
b.append(Character.toUpperCase(chars[0]));
for (int i = 1, iend = chars.length; i < iend; i++) {
char c = chars[i];
if (Character.isUpperCase(c)) {
b.append('_');
} else {
c = Character.toUpperCase(c);
}
b.append(c);
}
return b.toString();
}
}
+1 -1
View File
@@ -243,7 +243,7 @@ public abstract class AbstractRunTests {
int size = Math.min(expectedLines.length, actualLines.length);
if (size == 0 && expectedLines.length + actualLines.length > 0) {
Assert.fail("Missing / empty expected file.");
Assert.fail("Missing / empty expected file: " + name);
}
for (int i = 0; i < size; i++) {
@@ -1,3 +1,4 @@
//version 7:
public class EqualsAndHashCodeWithGenericsOnInners<A> {
class Inner<B> {
int x;
@@ -0,0 +1,8 @@
public class FieldNameConstantsBasic {
protected static final java.lang.String I_AM_A_DVD_PLAYER = "iAmADvdPlayer";
public static final java.lang.String BUT_PRINT_ME_PLEASE = "butPrintMePlease";
String iAmADvdPlayer;
int $skipMe;
static double skipMeToo;
String butPrintMePlease;
}
@@ -0,0 +1,4 @@
public class FieldNameConstantsWeird {
String iAmADvdPlayer;
String X;
}
@@ -1,3 +1,4 @@
//version 8:
class A {
class B {
String s;
@@ -48,4 +49,4 @@ class C {
return "C.D(a=" + this.getA() + ")";
}
}
}
}
@@ -0,0 +1,15 @@
import lombok.experimental.FieldNameConstants;
import lombok.AccessLevel;
public @FieldNameConstants class FieldNameConstantsBasic {
public static final java.lang.String BUT_PRINT_ME_PLEASE = "butPrintMePlease";
protected static final java.lang.String I_AM_A_DVD_PLAYER = "iAmADvdPlayer";
@FieldNameConstants(level = AccessLevel.PROTECTED) String iAmADvdPlayer;
int $skipMe;
static double skipMeToo;
String butPrintMePlease;
<clinit>() {
}
public FieldNameConstantsBasic() {
super();
}
}
@@ -0,0 +1,9 @@
import lombok.experimental.FieldNameConstants;
import lombok.AccessLevel;
public @FieldNameConstants class FieldNameConstantsWeird {
@FieldNameConstants(level = AccessLevel.NONE) String iAmADvdPlayer;
String X;
public FieldNameConstantsWeird() {
super();
}
}
@@ -0,0 +1,11 @@
import lombok.experimental.FieldNameConstants;
import lombok.AccessLevel;
@FieldNameConstants
public class FieldNameConstantsBasic {
@FieldNameConstants(level = AccessLevel.PROTECTED)
String iAmADvdPlayer;
int $skipMe;
static double skipMeToo;
String butPrintMePlease;
}
@@ -0,0 +1,9 @@
import lombok.experimental.FieldNameConstants;
import lombok.AccessLevel;
@FieldNameConstants
public class FieldNameConstantsWeird {
@FieldNameConstants(level = AccessLevel.NONE)
String iAmADvdPlayer;
String X;
}
@@ -0,0 +1 @@
8 Not generating constant for this field: The name of the constant would be equal to the name of this field.
@@ -0,0 +1 @@
8 Not generating constant for this field: The name of the constant would be equal to the name of this field.
@@ -0,0 +1,7 @@
public class FieldNameConstantsExample {
public static final String I_AM_A_FIELD = "iAmAField";
static final String AND_SO_AM_I = "andSoAmI";
private final String iAmAField;
private final int andSoAmI;
}
@@ -0,0 +1,9 @@
import lombok.experimental.FieldNameConstants;
import lombok.AccessLevel;
@FieldNameConstants
public class FieldNameConstantsExample {
private final String iAmAField;
@FieldNameConstants(level = AccessLevel.PACKAGE)
private final int andSoAmI;
}
@@ -0,0 +1,44 @@
<#import "../_features.html" as f>
<@f.scaffold title="@FieldNameConstants" logline="Name... that... field! String constants for your field's names.">
<@f.history>
<p>
@FieldNameConstants was introduced as experimental feature in lombok v2.0.0.
</p>
</@f.history>
<@f.experimental>
<ul>
<li>
New feature; unsure if this busts enough boilerplate.
</li>
</ul>
Current status: <em>neutral</em> - As a just-introduced feature we're still gathering feedback.
</@f.experimental>
<@f.overview>
<p>
The <code>@FieldNameConstants</code> annotation generates string constants (fields marked <code>public static final</code>, of type <code>java.lang.String</code>) containing the field's name, as a string. This is useful for various marshalling and serialization frameworks. The constant field has the same as the field it represents, except with all uppercase letters, with underscores in front of the uppercase letters in the original field. If this results in the exact same name, the constant is not generated (a warning is generated instead).
</p><p>
The <code>public</code> access modifier can be changed via the parameter <code>level = AccessLevel.PACKAGE</code> for example. You can force a field to be skipped by supplying <code>level = AccessLevel.NONE</code>.
</p><p>
Can be applied to classes (in which case every field gets a constant), or to an individual field.
</p>
</@f.overview>
<@f.snippets name="experimental/FieldNameConstants" />
<@f.confKeys>
<dt>
<code>lombok.fieldNameConstants.flagUsage</code> = [<code>warning</code> | <code>error</code>] (default: not set)
</dt><dd>
Lombok will flag any usage of <code>@FieldDefaults</code> as a warning or error if configured.
</dd>
</@f.confKeys>
<@f.smallPrint>
<p>
Like other lombok handlers that touch fields, any field whose name starts with a dollar (<code>$</code>) symbol is skipped entirely. Such a field will not be modified at all. Static fields are also skipped.
</p>
</@f.smallPrint>
</@f.scaffold>
@@ -62,6 +62,10 @@
<@main.feature title="@Helper" href="Helper">
With a little help from my friends... Helper methods for java.
</@main.feature>
<@main.feature title="@FieldNameConstants" href="FieldNameConstants">
Name... that... field! String constants for your field's names.
</@main.feature>
</div>
<@f.confKeys>