mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-19 06:15:19 +00:00
Added format preferences: Suppress @SuppressWarnings, suppress needless application of 'final'.
This commit is contained in:
1 parent
9639bc2ff4
commit
7e21683515
9 files changed
+100
-41
No files matched your search
@@ -22,9 +22,10 @@
|
||||
package lombok.javac;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import lombok.delombok.FormatPreferences;
|
||||
|
||||
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import com.sun.tools.javac.util.Options;
|
||||
@@ -32,17 +33,17 @@ import com.sun.tools.javac.util.Options;
|
||||
public abstract class LombokOptions extends Options {
|
||||
private boolean deleteLombokAnnotations = true;
|
||||
private final Set<JCCompilationUnit> changed = new HashSet<JCCompilationUnit>();
|
||||
private Map<String, String> formatPreferences = null;
|
||||
private FormatPreferences formatPreferences = new FormatPreferences(null);
|
||||
|
||||
public boolean isChanged(JCCompilationUnit ast) {
|
||||
return changed.contains(ast);
|
||||
}
|
||||
|
||||
public void setFormatPreferences(Map<String, String> formatPreferences) {
|
||||
public void setFormatPreferences(FormatPreferences formatPreferences) {
|
||||
this.formatPreferences = formatPreferences;
|
||||
}
|
||||
|
||||
public Map<String, String> getFormatPreferences() {
|
||||
public FormatPreferences getFormatPreferences() {
|
||||
return this.formatPreferences;
|
||||
}
|
||||
|
||||
|
||||
@@ -235,7 +235,8 @@ public class HandleConstructor {
|
||||
Name rawName = field.name;
|
||||
List<JCAnnotation> nonNulls = findAnnotations(fieldNode, TransformationsUtil.NON_NULL_PATTERN);
|
||||
List<JCAnnotation> nullables = findAnnotations(fieldNode, TransformationsUtil.NULLABLE_PATTERN);
|
||||
JCVariableDecl param = maker.VarDef(maker.Modifiers(Flags.FINAL | Flags.PARAMETER, nonNulls.appendList(nullables)), fieldName, field.vartype, null);
|
||||
long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, typeNode.getContext());
|
||||
JCVariableDecl param = maker.VarDef(maker.Modifiers(flags, nonNulls.appendList(nullables)), fieldName, field.vartype, null);
|
||||
params.append(param);
|
||||
JCFieldAccess thisX = maker.Select(maker.Ident(fieldNode.toName("this")), rawName);
|
||||
JCAssign assign = maker.Assign(thisX, maker.Ident(fieldName));
|
||||
@@ -297,7 +298,8 @@ public class HandleConstructor {
|
||||
JCExpression pType = cloneType(maker, field.vartype, source, typeNode.getContext());
|
||||
List<JCAnnotation> nonNulls = findAnnotations(fieldNode, TransformationsUtil.NON_NULL_PATTERN);
|
||||
List<JCAnnotation> nullables = findAnnotations(fieldNode, TransformationsUtil.NULLABLE_PATTERN);
|
||||
JCVariableDecl param = maker.VarDef(maker.Modifiers(Flags.FINAL | Flags.PARAMETER, nonNulls.appendList(nullables)), fieldName, pType, null);
|
||||
long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, typeNode.getContext());
|
||||
JCVariableDecl param = maker.VarDef(maker.Modifiers(flags, nonNulls.appendList(nullables)), fieldName, pType, null);
|
||||
params.append(param);
|
||||
args.append(maker.Ident(fieldName));
|
||||
}
|
||||
|
||||
@@ -305,7 +305,8 @@ public class HandleDelegate extends JavacAnnotationHandler<Delegate> {
|
||||
|
||||
int idx = 0;
|
||||
for (TypeMirror param : sig.type.getParameterTypes()) {
|
||||
JCModifiers paramMods = maker.Modifiers(Flags.FINAL | Flags.PARAMETER);
|
||||
long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, annotation.getContext());
|
||||
JCModifiers paramMods = maker.Modifiers(flags);
|
||||
String[] paramNames = sig.getParameterNames();
|
||||
Name name = annotation.toName(paramNames[idx++]);
|
||||
params.append(maker.VarDef(paramMods, name, JavacResolution.typeToJCTree((Type) param, annotation.getAst(), true), null));
|
||||
|
||||
@@ -228,10 +228,11 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
|
||||
|
||||
Name primeName = typeNode.toName(PRIME_NAME);
|
||||
Name resultName = typeNode.toName(RESULT_NAME);
|
||||
long finalFlag = JavacHandlerUtil.addFinalIfNeeded(0L, typeNode.getContext());
|
||||
|
||||
/* final int PRIME = 31; */ {
|
||||
if (!fields.isEmpty() || callSuper) {
|
||||
statements.append(maker.VarDef(maker.Modifiers(Flags.FINAL),
|
||||
primeName, maker.TypeIdent(CTC_INT), maker.Literal(31)));
|
||||
statements.append(maker.VarDef(maker.Modifiers(finalFlag), primeName, maker.TypeIdent(CTC_INT), maker.Literal(31)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,7 +259,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
|
||||
break;
|
||||
case LONG: {
|
||||
Name dollarFieldName = dollar.append(((JCVariableDecl)fieldNode.get()).name);
|
||||
statements.append(maker.VarDef(maker.Modifiers(Flags.FINAL), dollarFieldName, maker.TypeIdent(CTC_LONG), fieldAccessor));
|
||||
statements.append(maker.VarDef(maker.Modifiers(finalFlag), dollarFieldName, maker.TypeIdent(CTC_LONG), fieldAccessor));
|
||||
statements.append(createResultCalculation(typeNode, longToIntForHashCode(maker, maker.Ident(dollarFieldName), maker.Ident(dollarFieldName))));
|
||||
}
|
||||
break;
|
||||
@@ -276,7 +277,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
|
||||
List.<JCExpression>nil(),
|
||||
chainDots(typeNode, "java", "lang", "Double", "doubleToLongBits"),
|
||||
List.of(fieldAccessor));
|
||||
statements.append(maker.VarDef(maker.Modifiers(Flags.FINAL), dollarFieldName, maker.TypeIdent(CTC_LONG), init));
|
||||
statements.append(maker.VarDef(maker.Modifiers(finalFlag), dollarFieldName, maker.TypeIdent(CTC_LONG), init));
|
||||
statements.append(createResultCalculation(typeNode, longToIntForHashCode(maker, maker.Ident(dollarFieldName), maker.Ident(dollarFieldName))));
|
||||
}
|
||||
break;
|
||||
@@ -302,7 +303,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
|
||||
/* $fieldName == null ? 0 : $fieldName.hashCode() */
|
||||
|
||||
Name dollarFieldName = dollar.append(((JCVariableDecl)fieldNode.get()).name);
|
||||
statements.append(maker.VarDef(maker.Modifiers(Flags.FINAL), dollarFieldName, chainDots(typeNode, "java", "lang", "Object"), fieldAccessor));
|
||||
statements.append(maker.VarDef(maker.Modifiers(finalFlag), dollarFieldName, chainDots(typeNode, "java", "lang", "Object"), fieldAccessor));
|
||||
|
||||
JCExpression hcCall = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(dollarFieldName), typeNode.toName("hashCode")),
|
||||
List.<JCExpression>nil());
|
||||
@@ -370,8 +371,10 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
|
||||
JCExpression objectType = chainDots(typeNode, "java", "lang", "Object");
|
||||
JCExpression returnType = maker.TypeIdent(CTC_BOOLEAN);
|
||||
|
||||
long finalFlag = JavacHandlerUtil.addFinalIfNeeded(0L, typeNode.getContext());
|
||||
|
||||
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
|
||||
final List<JCVariableDecl> params = List.of(maker.VarDef(maker.Modifiers(Flags.FINAL | Flags.PARAMETER), oName, objectType, null));
|
||||
final List<JCVariableDecl> params = List.of(maker.VarDef(maker.Modifiers(finalFlag | Flags.PARAMETER), oName, objectType, null));
|
||||
|
||||
/* if (o == this) return true; */ {
|
||||
statements.append(maker.If(maker.Binary(CTC_EQUAL, maker.Ident(oName),
|
||||
@@ -403,7 +406,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
|
||||
}
|
||||
|
||||
statements.append(
|
||||
maker.VarDef(maker.Modifiers(Flags.FINAL), otherName, selfType1, maker.TypeCast(selfType2, maker.Ident(oName))));
|
||||
maker.VarDef(maker.Modifiers(finalFlag), otherName, selfType1, maker.TypeCast(selfType2, maker.Ident(oName))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -468,8 +471,8 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
|
||||
Name thisDollarFieldName = thisDollar.append(fieldName);
|
||||
Name otherDollarFieldName = otherDollar.append(fieldName);
|
||||
|
||||
statements.append(maker.VarDef(maker.Modifiers(Flags.FINAL), thisDollarFieldName, chainDots(typeNode, "java", "lang", "Object"), thisFieldAccessor));
|
||||
statements.append(maker.VarDef(maker.Modifiers(Flags.FINAL), otherDollarFieldName, chainDots(typeNode, "java", "lang", "Object"), otherFieldAccessor));
|
||||
statements.append(maker.VarDef(maker.Modifiers(finalFlag), thisDollarFieldName, chainDots(typeNode, "java", "lang", "Object"), thisFieldAccessor));
|
||||
statements.append(maker.VarDef(maker.Modifiers(finalFlag), otherDollarFieldName, chainDots(typeNode, "java", "lang", "Object"), otherFieldAccessor));
|
||||
|
||||
JCExpression thisEqualsNull = maker.Binary(CTC_EQUAL, maker.Ident(thisDollarFieldName), maker.Literal(CTC_BOT, null));
|
||||
JCExpression otherNotEqualsNull = maker.Binary(CTC_NOT_EQUAL, maker.Ident(otherDollarFieldName), maker.Literal(CTC_BOT, null));
|
||||
@@ -501,7 +504,8 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
|
||||
Name canEqualName = typeNode.toName("canEqual");
|
||||
JCExpression objectType = chainDots(typeNode, "java", "lang", "Object");
|
||||
Name otherName = typeNode.toName("other");
|
||||
List<JCVariableDecl> params = List.of(maker.VarDef(maker.Modifiers(Flags.FINAL | Flags.PARAMETER), otherName, objectType, null));
|
||||
long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, typeNode.getContext());
|
||||
List<JCVariableDecl> params = List.of(maker.VarDef(maker.Modifiers(flags), otherName, objectType, null));
|
||||
|
||||
JCBlock body = maker.Block(0, List.<JCStatement>of(
|
||||
maker.Return(maker.TypeTest(maker.Ident(otherName), createTypeReference(typeNode)))));
|
||||
|
||||
@@ -211,7 +211,8 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> {
|
||||
Name methodName = field.toName(setterName);
|
||||
List<JCAnnotation> annsOnParam = copyAnnotations(onParam).appendList(nonNulls).appendList(nullables);
|
||||
|
||||
JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(Flags.FINAL | Flags.PARAMETER, annsOnParam), fieldDecl.name, fieldDecl.vartype, null);
|
||||
long flags = JavacHandlerUtil.addFinalIfNeeded(0L, field.getContext());
|
||||
JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(flags, annsOnParam), fieldDecl.name, fieldDecl.vartype, null);
|
||||
|
||||
if (nonNulls.isEmpty()) {
|
||||
statements.append(treeMaker.Exec(assign));
|
||||
|
||||
@@ -214,7 +214,8 @@ public class HandleWither extends JavacAnnotationHandler<Wither> {
|
||||
Name methodName = field.toName(witherName);
|
||||
List<JCAnnotation> annsOnParam = copyAnnotations(onParam).appendList(nonNulls).appendList(nullables);
|
||||
|
||||
JCVariableDecl param = maker.VarDef(maker.Modifiers(Flags.FINAL | Flags.PARAMETER, annsOnParam), fieldDecl.name, fieldDecl.vartype, null);
|
||||
long flags = JavacHandlerUtil.addFinalIfNeeded(0L, field.getContext());
|
||||
JCVariableDecl param = maker.VarDef(maker.Modifiers(flags, annsOnParam), fieldDecl.name, fieldDecl.vartype, null);
|
||||
|
||||
JCExpression selfType = cloneSelfType(field);
|
||||
if (selfType == null) return null;
|
||||
|
||||
@@ -43,6 +43,7 @@ import lombok.core.AnnotationValues;
|
||||
import lombok.core.AnnotationValues.AnnotationValue;
|
||||
import lombok.core.TransformationsUtil;
|
||||
import lombok.core.TypeResolver;
|
||||
import lombok.delombok.LombokOptionsFactory;
|
||||
import lombok.experimental.Accessors;
|
||||
import lombok.javac.Javac;
|
||||
import lombok.javac.JavacNode;
|
||||
@@ -892,7 +893,15 @@ public class JavacHandlerUtil {
|
||||
return typeNode.add(type, Kind.TYPE);
|
||||
}
|
||||
|
||||
public static long addFinalIfNeeded(long flags, Context context) {
|
||||
boolean addFinal = LombokOptionsFactory.getDelombokOptions(context).getFormatPreferences().generateFinalParams();
|
||||
|
||||
if (addFinal) flags |= Flags.FINAL;
|
||||
return flags;
|
||||
}
|
||||
|
||||
private static void addSuppressWarningsAll(JCModifiers mods, JavacNode node, int pos, JCTree source, Context context) {
|
||||
if (!LombokOptionsFactory.getDelombokOptions(context).getFormatPreferences().generateSuppressWarnings()) return;
|
||||
JavacTreeMaker maker = node.getTreeMaker();
|
||||
JCExpression suppressWarningsType = chainDots(node, "java", "lang", "SuppressWarnings");
|
||||
JCLiteral allLiteral = maker.Literal("all");
|
||||
|
||||
@@ -58,6 +58,7 @@ import com.sun.tools.javac.util.Context;
|
||||
import com.zwitserloot.cmdreader.CmdReader;
|
||||
import com.zwitserloot.cmdreader.Description;
|
||||
import com.zwitserloot.cmdreader.Excludes;
|
||||
import com.zwitserloot.cmdreader.FullName;
|
||||
import com.zwitserloot.cmdreader.InvalidCommandLineException;
|
||||
import com.zwitserloot.cmdreader.Mandatory;
|
||||
import com.zwitserloot.cmdreader.Sequential;
|
||||
@@ -91,9 +92,12 @@ public class Delombok {
|
||||
private boolean verbose;
|
||||
|
||||
@Shorthand("f")
|
||||
@Description("Sets formatting rules. Use 'help' or 'list' to list all available rules. Unset format rules are inferred by scanning the source for usages.")
|
||||
@Description("Sets formatting rules. Use --format-help to list all available rules. Unset format rules are inferred by scanning the source for usages.")
|
||||
private List<String> format = new ArrayList<String>();
|
||||
|
||||
@FullName("format-help")
|
||||
private boolean formatHelp;
|
||||
|
||||
@Shorthand("q")
|
||||
@Description("No warnings or errors will be emitted to standard error")
|
||||
@Excludes("verbose")
|
||||
@@ -109,7 +113,7 @@ public class Delombok {
|
||||
|
||||
@Shorthand("d")
|
||||
@Description("Directory to save delomboked files to")
|
||||
@Mandatory(onlyIfNot={"print", "help"})
|
||||
@Mandatory(onlyIfNot={"print", "help", "format-help"})
|
||||
private String target;
|
||||
|
||||
@Shorthand("c")
|
||||
@@ -176,7 +180,7 @@ public class Delombok {
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.help || args.input.isEmpty()) {
|
||||
if (args.help || (args.input.isEmpty() && !args.formatHelp)) {
|
||||
if (!args.help) System.err.println("ERROR: no files or directories to delombok specified.");
|
||||
System.err.println(reader.generateCommandLineHelp("delombok"));
|
||||
System.exit(args.help ? 0 : 1);
|
||||
@@ -193,20 +197,20 @@ public class Delombok {
|
||||
|
||||
Map<String, String> formatPrefs = new HashMap<String, String>();
|
||||
|
||||
for (String format : args.format) {
|
||||
if ("help".equalsIgnoreCase(format) || "list".equalsIgnoreCase(format)) {
|
||||
System.out.println("Available format keys (to use, -f key:value -f key2:value2 -f ... ):");
|
||||
for (Map.Entry<String, String> e : FormatPreferences.getKeysAndDescriptions().entrySet()) {
|
||||
System.out.print(" ");
|
||||
System.out.print(e.getKey());
|
||||
System.out.println(":");
|
||||
System.out.println(indentAndWordbreak(e.getValue(), 4, 70));
|
||||
}
|
||||
System.out.println("Example: -f indent:4 -f emptyLines:indent");
|
||||
System.exit(0);
|
||||
return;
|
||||
if (args.formatHelp) {
|
||||
System.out.println("Available format keys (to use, -f key:value -f key2:value2 -f ... ):");
|
||||
for (Map.Entry<String, String> e : FormatPreferences.getKeysAndDescriptions().entrySet()) {
|
||||
System.out.print(" ");
|
||||
System.out.print(e.getKey());
|
||||
System.out.println(":");
|
||||
System.out.println(indentAndWordbreak(e.getValue(), 4, 70));
|
||||
}
|
||||
|
||||
System.out.println("Example: -f indent:4 -f emptyLines:indent");
|
||||
System.exit(0);
|
||||
return;
|
||||
}
|
||||
|
||||
for (String format : args.format) {
|
||||
int idx = format.indexOf(':');
|
||||
if (idx == -1) {
|
||||
System.err.println("Format keys need to be 2 values separated with a colon. Try -f help.");
|
||||
@@ -438,7 +442,7 @@ public class Delombok {
|
||||
if (classpath != null) options.putJavacOption("CLASSPATH", classpath);
|
||||
if (sourcepath != null) options.putJavacOption("SOURCEPATH", sourcepath);
|
||||
if (bootclasspath != null) options.putJavacOption("BOOTCLASSPATH", bootclasspath);
|
||||
options.setFormatPreferences(formatPrefs);
|
||||
options.setFormatPreferences(new FormatPreferences(formatPrefs));
|
||||
options.put("compilePolicy", "check");
|
||||
|
||||
CommentCatcher catcher = CommentCatcher.create(context);
|
||||
|
||||
@@ -28,17 +28,25 @@ import java.util.Map;
|
||||
|
||||
public final class FormatPreferences {
|
||||
private final String indent;
|
||||
private final boolean filledEmpties;
|
||||
private final Boolean filledEmpties;
|
||||
private final boolean generateSuppressWarnings;
|
||||
private final boolean generateFinalParams;
|
||||
static final Map<String, String> KEYS;
|
||||
|
||||
static {
|
||||
Map<String, String> keys = new LinkedHashMap<String, String>();
|
||||
keys.put("indent", "The indent to use. 'tab' can be used to represent 1 tab. A number means that many spaces. Default: 'tab'");
|
||||
keys.put("emptyLines", "Either 'indent' or 'blank'. indent means: Indent an empty line to the right level. Default: 'blank'");
|
||||
keys.put("suppressWarnings", "Either 'generate' or 'skip'. generate means: All lombok-generated methods get a @SuppressWarnings annotation. Default: 'generate'");
|
||||
keys.put("finalParams", "Either 'generate' or 'skip'. generate means: All lombok-generated methods set all parameters to final. Default: 'generate'");
|
||||
KEYS = Collections.unmodifiableMap(keys);
|
||||
}
|
||||
|
||||
public FormatPreferences(Map<String, String> preferences, String indent, boolean filledEmpties) {
|
||||
public FormatPreferences(Map<String, String> preferences) {
|
||||
this(preferences, null, null);
|
||||
}
|
||||
|
||||
public FormatPreferences(Map<String, String> preferences, String indent, Boolean filledEmpties) {
|
||||
if (preferences == null) preferences = Collections.emptyMap();
|
||||
|
||||
String indent_ = preferences.get("indent");
|
||||
@@ -57,21 +65,49 @@ public final class FormatPreferences {
|
||||
if ("indent".equalsIgnoreCase(empties_)) filledEmpties = true;
|
||||
else if ("blank".equalsIgnoreCase(empties_)) filledEmpties = false;
|
||||
else if (empties_ != null && !"scan".equalsIgnoreCase(empties_)) {
|
||||
throw new IllegalArgumentException("Legal values for 'emptyLines' is scan, indent, or blank.");
|
||||
throw new IllegalArgumentException("Legal values for 'emptyLines' are 'scan', 'indent', or 'blank'.");
|
||||
}
|
||||
|
||||
this.indent = indent;
|
||||
this.filledEmpties = filledEmpties;
|
||||
|
||||
String generateFinalParams_ = preferences.get("finalParams");
|
||||
if (generateFinalParams_ == null || "generate".equalsIgnoreCase(generateFinalParams_)) {
|
||||
this.generateFinalParams = true;
|
||||
} else if ("skip".equalsIgnoreCase(generateFinalParams_)) {
|
||||
this.generateFinalParams = false;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Legal values for 'finalParams' are 'generate', or 'skip'.");
|
||||
}
|
||||
|
||||
String generateSuppressWarnings_ = preferences.get("suppressWarnings");
|
||||
if (generateSuppressWarnings_ == null || "generate".equalsIgnoreCase(generateSuppressWarnings_)) {
|
||||
this.generateSuppressWarnings = true;
|
||||
} else if ("skip".equalsIgnoreCase(generateSuppressWarnings_)) {
|
||||
this.generateSuppressWarnings = false;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Legal values for 'suppressWarnings' are 'generate', or 'skip'.");
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, String> getKeysAndDescriptions() {
|
||||
return KEYS;
|
||||
}
|
||||
|
||||
/** If true, empty lines should still be appropriately indented. If false, empty lines should be completely blank. */
|
||||
public boolean fillEmpties() {
|
||||
return filledEmpties;
|
||||
return filledEmpties == null ? false : filledEmpties;
|
||||
}
|
||||
|
||||
public String indent() {
|
||||
return indent;
|
||||
return indent == null ? "\t" : indent;
|
||||
}
|
||||
|
||||
public boolean generateSuppressWarnings() {
|
||||
return generateSuppressWarnings;
|
||||
}
|
||||
|
||||
public boolean generateFinalParams() {
|
||||
return generateFinalParams;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user