aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok/javac
diff options
context:
space:
mode:
authorReinier Zwitserloot <reinier@zwitserloot.com>2015-10-06 00:25:32 +0200
committerReinier Zwitserloot <reinier@zwitserloot.com>2015-10-06 00:25:32 +0200
commit9d8c4e4099bef9b7854cc5d77bc996c3b3bf0e41 (patch)
tree6ca48925c989d3f314fbeef08931a1940b5c03cf /src/core/lombok/javac
parentb4d69f5cb8b093718bb7ffb539e5875df52ca48e (diff)
downloadlombok-9d8c4e4099bef9b7854cc5d77bc996c3b3bf0e41.tar.gz
lombok-9d8c4e4099bef9b7854cc5d77bc996c3b3bf0e41.tar.bz2
lombok-9d8c4e4099bef9b7854cc5d77bc996c3b3bf0e41.zip
New feature: FieldDefaults can now be configured to apply to _every_ file, regardless of annotations.
Diffstat (limited to 'src/core/lombok/javac')
-rw-r--r--src/core/lombok/javac/handlers/HandleFieldDefaults.java75
-rw-r--r--src/core/lombok/javac/handlers/HandleVal.java14
2 files changed, 56 insertions, 33 deletions
diff --git a/src/core/lombok/javac/handlers/HandleFieldDefaults.java b/src/core/lombok/javac/handlers/HandleFieldDefaults.java
index 95effded..5fb46afe 100644
--- a/src/core/lombok/javac/handlers/HandleFieldDefaults.java
+++ b/src/core/lombok/javac/handlers/HandleFieldDefaults.java
@@ -31,23 +31,24 @@ import lombok.core.HandlerPriority;
import lombok.experimental.FieldDefaults;
import lombok.experimental.NonFinal;
import lombok.experimental.PackagePrivate;
-import lombok.javac.JavacAnnotationHandler;
+import lombok.javac.JavacASTAdapter;
+import lombok.javac.JavacASTVisitor;
import lombok.javac.JavacNode;
import org.mangosdk.spi.ProviderFor;
import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
-import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
/**
* Handles the {@code lombok.FieldDefaults} annotation for eclipse.
*/
-@ProviderFor(JavacAnnotationHandler.class)
+@ProviderFor(JavacASTVisitor.class)
@HandlerPriority(-2048) //-2^11; to ensure @Value picks up on messing with the fields' 'final' state, run earlier.
-public class HandleFieldDefaults extends JavacAnnotationHandler<FieldDefaults> {
+public class HandleFieldDefaults extends JavacASTAdapter {
public boolean generateFieldDefaultsForType(JavacNode typeNode, JavacNode errorNode, AccessLevel level, boolean makeFinal, boolean checkForTypeLevelFieldDefaults) {
if (checkForTypeLevelFieldDefaults) {
if (hasAnnotation(FieldDefaults.class, typeNode)) {
@@ -72,13 +73,13 @@ public class HandleFieldDefaults extends JavacAnnotationHandler<FieldDefaults> {
//Skip fields that start with $
if (fieldDecl.name.toString().startsWith("$")) continue;
- setFieldDefaultsForField(field, errorNode.get(), level, makeFinal);
+ setFieldDefaultsForField(field, level, makeFinal);
}
return true;
}
- public void setFieldDefaultsForField(JavacNode fieldNode, DiagnosticPosition pos, AccessLevel level, boolean makeFinal) {
+ public void setFieldDefaultsForField(JavacNode fieldNode, AccessLevel level, boolean makeFinal) {
JCVariableDecl field = (JCVariableDecl) fieldNode.get();
if (level != null && level != AccessLevel.NONE) {
if ((field.mods.flags & (Flags.PUBLIC | Flags.PRIVATE | Flags.PROTECTED)) == 0) {
@@ -99,31 +100,53 @@ public class HandleFieldDefaults extends JavacAnnotationHandler<FieldDefaults> {
fieldNode.rebuild();
}
- @Override public void handle(AnnotationValues<FieldDefaults> annotation, JCAnnotation ast, JavacNode annotationNode) {
- handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.FIELD_DEFAULTS_FLAG_USAGE, "@FieldDefaults");
+ @Override public void visitType(JavacNode typeNode, JCClassDecl type) {
+ AnnotationValues<FieldDefaults> fieldDefaults = null;
+ JavacNode source = typeNode;
- deleteAnnotationIfNeccessary(annotationNode, FieldDefaults.class);
- deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel");
- JavacNode node = annotationNode.up();
- FieldDefaults instance = annotation.getInstance();
- AccessLevel level = instance.level();
- boolean makeFinal = instance.makeFinal();
-
- if (level == AccessLevel.NONE && !makeFinal) {
- annotationNode.addError("This does nothing; provide either level or makeFinal or both.");
- return;
+ boolean levelIsExplicit = false;
+ boolean makeFinalIsExplicit = false;
+ FieldDefaults fd = null;
+ for (JavacNode jn : typeNode.down()) {
+ if (jn.getKind() != Kind.ANNOTATION) continue;
+ JCAnnotation ann = (JCAnnotation) jn.get();
+ JCTree typeTree = ann.annotationType;
+ if (typeTree == null) continue;
+ String typeTreeToString = typeTree.toString();
+ if (!typeTreeToString.equals("FieldDefaults") && !typeTreeToString.equals("lombok.experimental.FieldDefaults")) continue;
+ if (!typeMatches(FieldDefaults.class, jn, typeTree)) continue;
+
+ source = jn;
+ fieldDefaults = createAnnotation(FieldDefaults.class, jn);
+ levelIsExplicit = fieldDefaults.isExplicit("level");
+ makeFinalIsExplicit = fieldDefaults.isExplicit("makeFinal");
+
+ handleExperimentalFlagUsage(jn, ConfigurationKeys.FIELD_DEFAULTS_FLAG_USAGE, "@FieldDefaults");
+
+ fd = fieldDefaults.getInstance();
+ if (!levelIsExplicit && !makeFinalIsExplicit) {
+ jn.addError("This does nothing; provide either level or makeFinal or both.");
+ }
+
+ if (levelIsExplicit && fd.level() == AccessLevel.NONE) {
+ jn.addError("AccessLevel.NONE doesn't mean anything here. Pick another value.");
+ levelIsExplicit = false;
+ }
+
+ deleteAnnotationIfNeccessary(jn, FieldDefaults.class);
+ deleteImportFromCompilationUnit(jn, "lombok.AccessLevel");
+ break;
}
- if (level == AccessLevel.PACKAGE) {
- annotationNode.addError("Setting 'level' to PACKAGE does nothing. To force fields as package private, use the @PackagePrivate annotation on the field.");
- }
+ if (fd == null && (type.mods.flags & (Flags.INTERFACE | Flags.ANNOTATION)) != 0) return;
- if (!makeFinal && annotation.isExplicit("makeFinal")) {
- annotationNode.addError("Setting 'makeFinal' to false does nothing. To force fields to be non-final, use the @NonFinal annotation on the field.");
- }
+ boolean defaultToPrivate = Boolean.TRUE.equals(typeNode.getAst().readConfiguration(ConfigurationKeys.FIELD_DEFAULTS_PRIVATE_EVERYWHERE));
+ boolean defaultToFinal = Boolean.TRUE.equals(typeNode.getAst().readConfiguration(ConfigurationKeys.FIELD_DEFAULTS_FINAL_EVERYWHERE));
- if (node == null) return;
+ if (!defaultToPrivate && !defaultToFinal && fieldDefaults == null) return;
+ AccessLevel fdAccessLevel = (fieldDefaults != null && levelIsExplicit) ? fd.level() : defaultToPrivate ? AccessLevel.PRIVATE : null;
+ boolean fdToFinal = (fieldDefaults != null && makeFinalIsExplicit) ? fd.makeFinal() : defaultToFinal;
- generateFieldDefaultsForType(node, annotationNode, level, makeFinal, false);
+ generateFieldDefaultsForType(typeNode, source, fdAccessLevel, fdToFinal, false);
}
}
diff --git a/src/core/lombok/javac/handlers/HandleVal.java b/src/core/lombok/javac/handlers/HandleVal.java
index 9eadd750..337ab2d7 100644
--- a/src/core/lombok/javac/handlers/HandleVal.java
+++ b/src/core/lombok/javac/handlers/HandleVal.java
@@ -51,11 +51,11 @@ import com.sun.tools.javac.util.List;
@ResolutionResetNeeded
public class HandleVal extends JavacASTAdapter {
@Override public void visitLocal(JavacNode localNode, JCVariableDecl local) {
- if (local.vartype == null || (!local.vartype.toString().equals("val") && !local.vartype.toString().equals("lombok.val"))) return;
-
- JCTree source = local.vartype;
-
- if (!typeMatches(val.class, localNode, local.vartype)) return;
+ JCTree typeTree = local.vartype;
+ if (typeTree == null) return;
+ String typeTreeToString = typeTree.toString();
+ if (!typeTreeToString.equals("val") && !typeTreeToString.equals("lombok.val")) return;
+ if (!typeMatches(val.class, localNode, typeTree)) return;
handleFlagUsage(localNode, ConfigurationKeys.VAL_FLAG_USAGE, "val");
@@ -88,7 +88,7 @@ public class HandleVal extends JavacASTAdapter {
local.mods.flags |= Flags.FINAL;
if (!localNode.shouldDeleteLombokAnnotations()) {
- JCAnnotation valAnnotation = recursiveSetGeneratedBy(localNode.getTreeMaker().Annotation(local.vartype, List.<JCExpression>nil()), source, localNode.getContext());
+ JCAnnotation valAnnotation = recursiveSetGeneratedBy(localNode.getTreeMaker().Annotation(local.vartype, List.<JCExpression>nil()), typeTree, localNode.getContext());
local.mods.annotations = local.mods.annotations == null ? List.of(valAnnotation) : local.mods.annotations.append(valAnnotation);
}
@@ -156,7 +156,7 @@ public class HandleVal extends JavacASTAdapter {
local.vartype = JavacResolution.createJavaLangObject(localNode.getAst());
throw e;
} finally {
- recursiveSetGeneratedBy(local.vartype, source, localNode.getContext());
+ recursiveSetGeneratedBy(local.vartype, typeTree, localNode.getContext());
}
}
}