aboutsummaryrefslogtreecommitdiff
path: root/src/lombok/core
diff options
context:
space:
mode:
authorReinier Zwitserloot <reinier@tipit.to>2009-10-16 09:32:36 +0200
committerReinier Zwitserloot <reinier@tipit.to>2009-10-16 09:32:36 +0200
commitb5c8b725655d2ad8a715cfb1fbbdf25dbdcd4ceb (patch)
tree571d13cd7028a6b7d1ebfe84180a4328a20c42d7 /src/lombok/core
parent8629a651a66aa5fba9e0ada7df00803528b0e34f (diff)
downloadlombok-b5c8b725655d2ad8a715cfb1fbbdf25dbdcd4ceb.tar.gz
lombok-b5c8b725655d2ad8a715cfb1fbbdf25dbdcd4ceb.tar.bz2
lombok-b5c8b725655d2ad8a715cfb1fbbdf25dbdcd4ceb.zip
Fixed issue #24 by refactoring the AST.Node class - taken it out, and in the process fixed a lot of type annoyance by adding more generics.
Also changed coding style from for/while/if/switch/catch/do ( expr ) {} to for (expr) {}, hence the changes _everywhere_.
Diffstat (limited to 'src/lombok/core')
-rw-r--r--src/lombok/core/AST.java415
-rw-r--r--src/lombok/core/AnnotationValues.java122
-rw-r--r--src/lombok/core/LombokNode.java297
-rw-r--r--src/lombok/core/SpiLoadUtil.java36
-rw-r--r--src/lombok/core/TransformationsUtil.java30
-rw-r--r--src/lombok/core/TypeLibrary.java4
-rw-r--r--src/lombok/core/TypeResolver.java28
7 files changed, 494 insertions, 438 deletions
diff --git a/src/lombok/core/AST.java b/src/lombok/core/AST.java
index d568484e..31b8f0fd 100644
--- a/src/lombok/core/AST.java
+++ b/src/lombok/core/AST.java
@@ -39,26 +39,28 @@ import java.util.Map;
* Lombok wraps the AST produced by a target platform into its own AST system, mostly because both Eclipse and javac
* do not allow upward traversal (from a method to its owning type, for example).
*
+ * @param A Self-type.
+ * @param L type of all LombokNodes.
* @param N The common type of all AST nodes in the internal representation of the target platform.
- * For example, JCTree for javac, and ASTNode for Eclipse.
+ * For example, JCTree for javac, and ASTNode for Eclipse.
*/
-public abstract class AST<N> {
+public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>, N> {
/** The kind of node represented by a given AST.Node object. */
public enum Kind {
COMPILATION_UNIT, TYPE, FIELD, INITIALIZER, METHOD, ANNOTATION, ARGUMENT, LOCAL, STATEMENT;
}
- private Node top;
+ private L top;
private final String fileName;
- private Map<N, Void> identityDetector = new IdentityHashMap<N, Void>();
- private Map<N, Node> nodeMap = new IdentityHashMap<N, Node>();
+ Map<N, Void> identityDetector = new IdentityHashMap<N, Void>();
+ private Map<N, L> nodeMap = new IdentityHashMap<N, L>();
protected AST(String fileName) {
this.fileName = fileName == null ? "(unknown).java" : fileName;
}
/** Set the node object that wraps the internal Compilation Unit node. */
- protected void setTop(Node top) {
+ protected void setTop(L top) {
this.top = top;
}
@@ -80,14 +82,14 @@ public abstract class AST<N> {
* Puts the given node in the map so that javac/Eclipse's own internal AST object can be translated to
* an AST.Node object. Also registers the object as visited to avoid endless loops.
*/
- protected <T extends Node> T putInMap(T node) {
+ protected L putInMap(L node) {
nodeMap.put(node.get(), node);
identityDetector.put(node.get(), null);
return node;
}
/** Returns the node map, that can map javac/Eclipse internal AST objects to AST.Node objects. */
- protected Map<N, Node> getNodeMap() {
+ protected Map<N, L> getNodeMap() {
return nodeMap;
}
@@ -95,7 +97,7 @@ public abstract class AST<N> {
* object is left untouched, and instead a new map is created. */
protected void clearState() {
identityDetector = new IdentityHashMap<N, Void>();
- nodeMap = new IdentityHashMap<N, Node>();
+ nodeMap = new IdentityHashMap<N, L>();
}
/**
@@ -104,7 +106,7 @@ public abstract class AST<N> {
* case you should do nothing lest the AST build process loops endlessly.
*/
protected boolean setAndGetAsHandled(N node) {
- if ( identityDetector.containsKey(node) ) return true;
+ if (identityDetector.containsKey(node)) return true;
identityDetector.put(node, null);
return false;
}
@@ -114,23 +116,23 @@ public abstract class AST<N> {
}
/** The AST.Node object representing the Compilation Unit. */
- public Node top() {
+ public L top() {
return top;
}
/** Maps a javac/Eclipse internal AST Node to the appropriate AST.Node object. */
- public Node get(N node) {
+ public L get(N node) {
return nodeMap.get(node);
}
@SuppressWarnings("unchecked")
- private Node replaceNewWithExistingOld(Map<N, Node> oldNodes, Node newNode) {
- Node oldNode = oldNodes.get(newNode.get());
- Node targetNode = oldNode == null ? newNode : oldNode;
+ L replaceNewWithExistingOld(Map<N, L> oldNodes, L newNode) {
+ L oldNode = oldNodes.get(newNode.get());
+ L targetNode = oldNode == null ? newNode : oldNode;
List children = new ArrayList();
- for ( Node child : newNode.children ) {
- Node oldChild = replaceNewWithExistingOld(oldNodes, child);
+ for (L child : newNode.children) {
+ L oldChild = replaceNewWithExistingOld(oldNodes, child);
children.add(oldChild);
oldChild.parent = targetNode;
}
@@ -140,262 +142,8 @@ public abstract class AST<N> {
return targetNode;
}
- /** An instance of this class wraps an Eclipse/javac internal node object. */
- public abstract class Node {
- protected final Kind kind;
- protected final N node;
- protected final List<? extends Node> children;
- protected Node parent;
-
- /** This flag has no specified meaning; you can set and retrieve it.
- *
- * In practice, for annotation nodes it means: Some AnnotationHandler finished whatever changes were required,
- * and for all other nodes it means: This node was made by a lombok operation.
- */
- protected boolean handled;
-
- /** structurally significant are those nodes that can be annotated in java 1.6 or are method-like toplevels,
- * so fields, local declarations, method arguments, methods, types, the Compilation Unit itself, and initializers. */
- protected boolean isStructurallySignificant;
-
- /**
- * Creates a new Node object that represents the provided node.
- *
- * Make sure you manually set the parent correctly.
- *
- * @param node The AST object in the target parser's own internal AST tree that this node object will represent.
- * @param children A list of child nodes. Passing in null results in the children list being empty, not null.
- * @param kind The kind of node represented by this object.
- */
- protected Node(N node, List<? extends Node> children, Kind kind) {
- this.kind = kind;
- this.node = node;
- this.children = children == null ? new ArrayList<Node>() : children;
- for ( Node child : this.children ) child.parent = this;
- this.isStructurallySignificant = calculateIsStructurallySignificant();
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return String.format("NODE %s (%s) %s%s",
- kind, node == null ? "(NULL)" : node.getClass(), handled ? "[HANDLED]" : "", node == null ? "" : node);
- }
-
- /**
- * Convenient shortcut to the owning JavacAST object's getPackageDeclaration method.
- *
- * @see AST#getPackageDeclaration()
- */
- public String getPackageDeclaration() {
- return AST.this.getPackageDeclaration();
- }
-
- /**
- * Convenient shortcut to the owning JavacAST object's getImportStatements method.
- *
- * @see AST#getImportStatements()
- */
- public Collection<String> getImportStatements() {
- return AST.this.getImportStatements();
- }
-
- /**
- * See {@link #isStructurallySignificant}.
- */
- protected abstract boolean calculateIsStructurallySignificant();
-
- /**
- * Convenient shortcut to the owning JavacAST object's get method.
- *
- * @see AST#get(Object)
- */
- public Node getNodeFor(N obj) {
- return AST.this.get(obj);
- }
-
- /**
- * @return The javac/Eclipse internal AST object wrapped by this AST.Node object.
- */
- public N get() {
- return node;
- }
-
- /**
- * Replaces the AST node represented by this node object with the provided node. This node must
- * have a parent, obviously, for this to work.
- *
- * Also affects the underlying (Eclipse/javac) AST.
- */
- @SuppressWarnings("unchecked")
- public Node replaceWith(N newN, Kind kind) {
- Node newNode = buildTree(newN, kind);
- newNode.parent = parent;
- for ( int i = 0 ; i < parent.children.size() ; i++ ) {
- if ( parent.children.get(i) == this ) ((List)parent.children).set(i, newNode);
- }
-
- parent.replaceChildNode(get(), newN);
- return newNode;
- }
-
- /**
- * Replaces the stated node with a new one. The old node must be a direct child of this node.
- *
- * Also affects the underlying (Eclipse/javac) AST.
- */
- public void replaceChildNode(N oldN, N newN) {
- replaceStatementInNode(get(), oldN, newN);
- }
-
- public Kind getKind() {
- return kind;
- }
-
- /**
- * Return the name of your type (simple name), method, field, or local variable. Return null if this
- * node doesn't really have a name, such as initializers, while statements, etc.
- */
- public abstract String getName();
-
- /** Returns the structurally significant node that encloses this one.
- *
- * @see #isStructurallySignificant()
- */
- public Node up() {
- Node result = parent;
- while ( result != null && !result.isStructurallySignificant ) result = result.parent;
- return result;
- }
-
- /**
- * Returns the direct parent node in the AST tree of this node. For example, a local variable declaration's
- * direct parent can be e.g. an If block, but its up() Node is the Method that contains it.
- */
- public Node directUp() {
- return parent;
- }
-
- /**
- * Returns all children nodes.
- *
- * A copy is created, so changing the list has no effect. Also, while iterating through this list,
- * you may add, remove, or replace children without causing ConcurrentModificationExceptions.
- */
- public Collection<? extends Node> down() {
- return new ArrayList<Node>(children);
- }
-
- /**
- * returns the value of the 'handled' flag.
- *
- * @see #handled
- */
- public boolean isHandled() {
- return handled;
- }
-
- /**
- * Sets the handled flag, then returns 'this'.
- *
- * @see #handled
- */
- public Node setHandled() {
- this.handled = true;
- return this;
- }
-
- /**
- * Convenient shortcut to the owning JavacAST object's top method.
- *
- * @see AST#top()
- */
- public Node top() {
- return top;
- }
-
- /**
- * Convenient shortcut to the owning JavacAST object's getFileName method.
- *
- * @see AST#getFileName()
- */
- public String getFileName() {
- return fileName;
- }
-
- /**
- * Adds the stated node as a direct child of this node.
- *
- * Does not change the underlying (javac/Eclipse) AST, only the wrapped view.
- */
- @SuppressWarnings("unchecked") public Node add(N newChild, Kind kind) {
- Node n = buildTree(newChild, kind);
- if ( n == null ) return null;
- n.parent = this;
- ((List)children).add(n);
- return n;
- }
-
- /**
- * Reparses the AST node represented by this node. Any existing nodes that occupy a different space in the AST are rehomed, any
- * nodes that no longer exist are removed, and new nodes are created.
- *
- * Careful - the node you call this on must not itself have been removed or rehomed - it rebuilds <i>all children</i>.
- */
- public void rebuild() {
- Map<N, Node> oldNodes = new IdentityHashMap<N, Node>();
- gatherAndRemoveChildren(oldNodes);
-
- Node newNode = buildTree(get(), kind);
-
- replaceNewWithExistingOld(oldNodes, newNode);
- }
-
- private void gatherAndRemoveChildren(Map<N, Node> map) {
- for ( Node child : children ) child.gatherAndRemoveChildren(map);
- identityDetector.remove(get());
- map.put(get(), this);
- children.clear();
- nodeMap.remove(get());
- }
-
- /**
- * Removes the stated node, which must be a direct child of this node, from the AST.
- *
- * Does not change the underlying (javac/Eclipse) AST, only the wrapped view.
- */
- public void removeChild(Node child) {
- children.remove(child);
- }
-
- /**
- * Sets the handled flag on this node, and all child nodes, then returns this.
- *
- * @see #handled
- */
- public Node recursiveSetHandled() {
- this.handled = true;
- for ( Node child : children ) child.recursiveSetHandled();
- return this;
- }
-
- /** Generate a compiler error on this node. */
- public abstract void addError(String message);
-
- /** Generate a compiler warning on this node. */
- public abstract void addWarning(String message);
-
- /**
- * Structurally significant means: LocalDeclaration, TypeDeclaration, MethodDeclaration, ConstructorDeclaration,
- * FieldDeclaration, Initializer, and CompilationUnitDeclaration.
- * The rest is e.g. if statements, while loops, etc.
- */
- public boolean isStructurallySignificant() {
- return isStructurallySignificant;
- }
- }
-
/** Build an AST.Node object for the stated internal (javac/Eclipse) AST Node object. */
- protected abstract Node buildTree(N item, Kind kind);
+ protected abstract L buildTree(N item, Kind kind);
/**
* Represents a field that contains AST children.
@@ -420,7 +168,7 @@ public abstract class AST<N> {
*/
protected Collection<FieldAccess> fieldsOf(Class<?> c) {
Collection<FieldAccess> fields = fieldsOfASTClasses.get(c);
- if ( fields != null ) return fields;
+ if (fields != null) return fields;
fields = new ArrayList<FieldAccess>();
getFields(c, fields);
@@ -429,26 +177,26 @@ public abstract class AST<N> {
}
private void getFields(Class<?> c, Collection<FieldAccess> fields) {
- if ( c == Object.class || c == null ) return;
- for ( Field f : c.getDeclaredFields() ) {
- if ( Modifier.isStatic(f.getModifiers()) ) continue;
+ if (c == Object.class || c == null) return;
+ for (Field f : c.getDeclaredFields()) {
+ if (Modifier.isStatic(f.getModifiers())) continue;
Class<?> t = f.getType();
int dim = 0;
- if ( t.isArray() ) {
- while ( t.isArray() ) {
+ if (t.isArray()) {
+ while (t.isArray()) {
dim++;
t = t.getComponentType();
}
- } else if ( Collection.class.isAssignableFrom(t) ) {
- while ( Collection.class.isAssignableFrom(t) ) {
+ } else {
+ while (Collection.class.isAssignableFrom(t)) {
dim++;
t = getComponentType(f.getGenericType());
}
}
- for ( Class<?> statementType : getStatementTypes() ) {
- if ( statementType.isAssignableFrom(t) ) {
+ for (Class<?> statementType : getStatementTypes()) {
+ if (statementType.isAssignableFrom(t)) {
f.setAccessible(true);
fields.add(new FieldAccess(f, dim));
break;
@@ -459,10 +207,12 @@ public abstract class AST<N> {
}
private Class<?> getComponentType(Type type) {
- if ( type instanceof ParameterizedType ) {
+ if (type instanceof ParameterizedType) {
Type component = ((ParameterizedType)type).getActualTypeArguments()[0];
return component instanceof Class<?> ? (Class<?>)component : Object.class;
- } else return Object.class;
+ } else {
+ return Object.class;
+ }
}
/**
@@ -473,8 +223,8 @@ public abstract class AST<N> {
/**
* buildTree implementation that uses reflection to find all child nodes by way of inspecting
* the fields. */
- protected <T extends Node> Collection<T> buildWithField(Class<T> nodeType, N statement, FieldAccess fa) {
- List<T> list = new ArrayList<T>();
+ protected Collection<L> buildWithField(Class<L> nodeType, N statement, FieldAccess fa) {
+ List<L> list = new ArrayList<L>();
buildWithField0(nodeType, statement, fa, list);
return list;
}
@@ -483,8 +233,8 @@ public abstract class AST<N> {
* Uses reflection to find the given direct child on the given statement, and replace it with a new child.
*/
protected boolean replaceStatementInNode(N statement, N oldN, N newN) {
- for ( FieldAccess fa : fieldsOf(statement.getClass()) ) {
- if ( replaceStatementInField(fa, statement, oldN, newN) ) return true;
+ for (FieldAccess fa : fieldsOf(statement.getClass())) {
+ if (replaceStatementInField(fa, statement, oldN, newN)) return true;
}
return false;
@@ -493,42 +243,42 @@ public abstract class AST<N> {
private boolean replaceStatementInField(FieldAccess fa, N statement, N oldN, N newN) {
try {
Object o = fa.field.get(statement);
- if ( o == null ) return false;
+ if (o == null) return false;
- if ( o == oldN ) {
+ if (o == oldN) {
fa.field.set(statement, newN);
return true;
}
- if ( fa.dim > 0 ) {
- if ( o.getClass().isArray() ) {
+ if (fa.dim > 0) {
+ if (o.getClass().isArray()) {
return replaceStatementInArray(o, oldN, newN);
- } else if ( Collection.class.isInstance(o) ) {
+ } else if (Collection.class.isInstance(o)) {
return replaceStatementInCollection(fa.field, statement, new ArrayList<Collection<?>>(), (Collection<?>)o, oldN, newN);
}
}
return false;
- } catch ( IllegalAccessException e ) {
+ } catch (IllegalAccessException e) {
throw sneakyThrow(e);
}
}
private boolean replaceStatementInCollection(Field field, Object fieldRef, List<Collection<?>> chain, Collection<?> collection, N oldN, N newN) throws IllegalAccessException {
- if ( collection == null ) return false;
+ if (collection == null) return false;
int idx = -1;
- for ( Object o : collection ) {
+ for (Object o : collection) {
idx++;
- if ( o == null ) continue;
- if ( Collection.class.isInstance(o) ) {
+ if (o == null) continue;
+ if (Collection.class.isInstance(o)) {
Collection<?> newC = (Collection<?>)o;
List<Collection<?>> newChain = new ArrayList<Collection<?>>(chain);
newChain.add(newC);
- if ( replaceStatementInCollection(field, fieldRef, newChain, newC, oldN, newN) ) return true;
+ if (replaceStatementInCollection(field, fieldRef, newChain, newC, oldN, newN)) return true;
}
- if ( o == oldN ) {
+ if (o == oldN) {
setElementInASTCollection(field, fieldRef, chain, collection, idx, newN);
return true;
}
@@ -540,21 +290,21 @@ public abstract class AST<N> {
/** Override if your AST collection does not support the set method. Javac's for example, does not. */
@SuppressWarnings("unchecked")
protected void setElementInASTCollection(Field field, Object fieldRef, List<Collection<?>> chain, Collection<?> collection, int idx, N newN) throws IllegalAccessException {
- if ( collection instanceof List<?> ) {
+ if (collection instanceof List<?>) {
((List)collection).set(idx, newN);
}
}
private boolean replaceStatementInArray(Object array, N oldN, N newN) {
- if ( array == null ) return false;
+ if (array == null) return false;
int len = Array.getLength(array);
- for ( int i = 0 ; i < len ; i++ ) {
+ for (int i = 0; i < len; i++) {
Object o = Array.get(array, i);
- if ( o == null ) continue;
- if ( o.getClass().isArray() ) {
- if ( replaceStatementInArray(o, oldN, newN) ) return true;
- } else if ( o == oldN ) {
+ if (o == null) continue;
+ if (o.getClass().isArray()) {
+ if (replaceStatementInArray(o, oldN, newN)) return true;
+ } else if (o == oldN) {
Array.set(array, i, newN);
return true;
}
@@ -564,39 +314,46 @@ public abstract class AST<N> {
}
@SuppressWarnings("unchecked")
- private <T extends Node> void buildWithField0(Class<T> nodeType, N child, FieldAccess fa, Collection<T> list) {
+ private void buildWithField0(Class<L> nodeType, N child, FieldAccess fa, Collection<L> list) {
try {
Object o = fa.field.get(child);
- if ( o == null ) return;
- if ( fa.dim == 0 ) {
- Node node = buildTree((N)o, Kind.STATEMENT);
- if ( node != null ) list.add(nodeType.cast(node));
- } else if ( o.getClass().isArray() ) buildWithArray(nodeType, o, list, fa.dim);
- else if ( Collection.class.isInstance(o) ) buildWithCollection(nodeType, o, list, fa.dim);
- } catch ( IllegalAccessException e ) {
+ if (o == null) return;
+ if (fa.dim == 0) {
+ L node = buildTree((N)o, Kind.STATEMENT);
+ if (node != null) list.add(nodeType.cast(node));
+ } else if (o.getClass().isArray()) {
+ buildWithArray(nodeType, o, list, fa.dim);
+ } else if (Collection.class.isInstance(o)) {
+ buildWithCollection(nodeType, o, list, fa.dim);
+ }
+ } catch (IllegalAccessException e) {
sneakyThrow(e);
}
}
@SuppressWarnings("unchecked")
- private <T extends Node> void buildWithArray(Class<T> nodeType, Object array, Collection<T> list, int dim) {
- if ( dim == 1 ) for ( Object v : (Object[])array ) {
- if ( v == null ) continue;
- Node node = buildTree((N)v, Kind.STATEMENT);
- if ( node != null ) list.add(nodeType.cast(node));
- } else for ( Object v : (Object[])array ) {
- if ( v == null ) return;
- buildWithArray(nodeType, v, list, dim-1);
+ private void buildWithArray(Class<L> nodeType, Object array, Collection<L> list, int dim) {
+ if (dim == 1) {
+ for (Object v : (Object[])array) {
+ if (v == null) continue;
+ L node = buildTree((N)v, Kind.STATEMENT);
+ if (node != null) list.add(nodeType.cast(node));
+ }
+ } else for (Object v : (Object[])array) {
+ if (v == null) return;
+ buildWithArray(nodeType, v, list, dim -1);
}
}
@SuppressWarnings("unchecked")
- private <T extends Node> void buildWithCollection(Class<T> nodeType, Object collection, Collection<T> list, int dim) {
- if ( dim == 1 ) for ( Object v : (Collection<?>)collection ) {
- if ( v == null ) continue;
- Node node = buildTree((N)v, Kind.STATEMENT);
- if ( node != null ) list.add(nodeType.cast(node));
- } else for ( Object v : (Collection<?>)collection ) {
+ private void buildWithCollection(Class<L> nodeType, Object collection, Collection<L> list, int dim) {
+ if (dim == 1) {
+ for (Object v : (Collection<?>)collection) {
+ if (v == null) continue;
+ L node = buildTree((N)v, Kind.STATEMENT);
+ if (node != null) list.add(nodeType.cast(node));
+ }
+ } else for (Object v : (Collection<?>)collection) {
buildWithCollection(nodeType, v, list, dim-1);
}
}
diff --git a/src/lombok/core/AnnotationValues.java b/src/lombok/core/AnnotationValues.java
index 663fb86b..fe16a395 100644
--- a/src/lombok/core/AnnotationValues.java
+++ b/src/lombok/core/AnnotationValues.java
@@ -37,7 +37,7 @@ import java.util.Map;
public class AnnotationValues<A extends Annotation> {
private final Class<A> type;
private final Map<String, AnnotationValue> values;
- private final AST<?>.Node ast;
+ private final LombokNode<?, ?, ?> ast;
/**
* Represents a single method on the annotation class. For example, the value() method on the Getter annotation.
@@ -49,7 +49,7 @@ public class AnnotationValues<A extends Annotation> {
/** Guesses for each raw expression. If the raw expression is a literal expression, the guess will
* likely be right. If not, it'll be wrong. */
public final List<Object> valueGuesses;
- private final AST<?>.Node node;
+ private final LombokNode<?, ?, ?> node;
private final boolean isExplicit;
/**
@@ -59,7 +59,7 @@ public class AnnotationValues<A extends Annotation> {
* For classes, supply the class name (qualified or not) as a string.<br />
* For enums, supply the simple name part (everything after the last dot) as a string.<br />
*/
- public AnnotationValue(AST<?>.Node node, String raw, Object valueGuess, boolean isExplicit) {
+ public AnnotationValue(LombokNode<?, ?, ?> node, String raw, Object valueGuess, boolean isExplicit) {
this.node = node;
this.raws = Collections.singletonList(raw);
this.valueGuesses = Collections.singletonList(valueGuess);
@@ -69,7 +69,7 @@ public class AnnotationValues<A extends Annotation> {
/**
* Like the other constructor, but used for when the annotation method is initialized with an array value.
*/
- public AnnotationValue(AST<?>.Node node, List<String> raws, List<Object> valueGuesses, boolean isExplicit) {
+ public AnnotationValue(LombokNode<?, ?, ?> node, List<String> raws, List<Object> valueGuesses, boolean isExplicit) {
this.node = node;
this.raws = raws;
this.valueGuesses = valueGuesses;
@@ -117,7 +117,7 @@ public class AnnotationValues<A extends Annotation> {
* @param values a Map of method names to AnnotationValue instances, for example 'value -> annotationValue instance'.
* @param ast The Annotation node.
*/
- public AnnotationValues(Class<A> type, Map<String, AnnotationValue> values, AST<?>.Node ast) {
+ public AnnotationValues(Class<A> type, Map<String, AnnotationValue> values, LombokNode<?, ?, ?> ast) {
this.type = type;
this.values = values;
this.ast = ast;
@@ -162,50 +162,50 @@ public class AnnotationValues<A extends Annotation> {
*/
@SuppressWarnings("unchecked")
public A getInstance() {
- if ( cachedInstance != null ) return cachedInstance;
+ if (cachedInstance != null) return cachedInstance;
InvocationHandler invocations = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
AnnotationValue v = values.get(method.getName());
- if ( v == null ) {
+ if (v == null) {
Object defaultValue = method.getDefaultValue();
- if ( defaultValue != null ) return defaultValue;
+ if (defaultValue != null) return defaultValue;
throw makeNoDefaultFail(v, method);
}
boolean isArray = false;
Class<?> expected = method.getReturnType();
Object array = null;
- if ( expected.isArray() ) {
+ if (expected.isArray()) {
isArray = true;
expected = expected.getComponentType();
array = Array.newInstance(expected, v.valueGuesses.size());
}
- if ( !isArray && v.valueGuesses.size() > 1 ) {
+ if (!isArray && v.valueGuesses.size() > 1) {
throw new AnnotationValueDecodeFail(v,
"Expected a single value, but " + method.getName() + " has an array of values", -1);
}
- if ( v.valueGuesses.size() == 0 && !isArray ) {
+ if (v.valueGuesses.size() == 0 && !isArray) {
Object defaultValue = method.getDefaultValue();
- if ( defaultValue == null ) throw makeNoDefaultFail(v, method);
+ if (defaultValue == null) throw makeNoDefaultFail(v, method);
return defaultValue;
}
int idx = 0;
- for ( Object guess : v.valueGuesses ) {
+ for (Object guess : v.valueGuesses) {
Object result = guess == null ? null : guessToType(guess, expected, v, idx);
- if ( !isArray ) {
- if ( result == null ) {
+ if (!isArray) {
+ if (result == null) {
Object defaultValue = method.getDefaultValue();
- if ( defaultValue == null ) throw makeNoDefaultFail(v, method);
+ if (defaultValue == null) throw makeNoDefaultFail(v, method);
return defaultValue;
} else return result;
} else {
- if ( result == null ) {
- if ( v.valueGuesses.size() == 1 ) {
+ if (result == null) {
+ if (v.valueGuesses.size() == 1) {
Object defaultValue = method.getDefaultValue();
- if ( defaultValue == null ) throw makeNoDefaultFail(v, method);
+ if (defaultValue == null) throw makeNoDefaultFail(v, method);
return defaultValue;
} else throw new AnnotationValueDecodeFail(v,
"I can't make sense of this annotation value. Try using a fully qualified literal.", idx);
@@ -222,69 +222,69 @@ public class AnnotationValues<A extends Annotation> {
}
private Object guessToType(Object guess, Class<?> expected, AnnotationValue v, int pos) {
- if ( expected == int.class ) {
- if ( guess instanceof Integer || guess instanceof Short || guess instanceof Byte ) {
+ if (expected == int.class) {
+ if (guess instanceof Integer || guess instanceof Short || guess instanceof Byte) {
return ((Number)guess).intValue();
}
}
- if ( expected == long.class ) {
- if ( guess instanceof Long || guess instanceof Integer || guess instanceof Short || guess instanceof Byte ) {
+ if (expected == long.class) {
+ if (guess instanceof Long || guess instanceof Integer || guess instanceof Short || guess instanceof Byte) {
return ((Number)guess).longValue();
}
}
- if ( expected == short.class ) {
- if ( guess instanceof Integer || guess instanceof Short || guess instanceof Byte ) {
+ if (expected == short.class) {
+ if (guess instanceof Integer || guess instanceof Short || guess instanceof Byte) {
int intVal = ((Number)guess).intValue();
int shortVal = ((Number)guess).shortValue();
- if ( shortVal == intVal ) return shortVal;
+ if (shortVal == intVal) return shortVal;
}
}
- if ( expected == byte.class ) {
- if ( guess instanceof Integer || guess instanceof Short || guess instanceof Byte ) {
+ if (expected == byte.class) {
+ if (guess instanceof Integer || guess instanceof Short || guess instanceof Byte) {
int intVal = ((Number)guess).intValue();
int byteVal = ((Number)guess).byteValue();
- if ( byteVal == intVal ) return byteVal;
+ if (byteVal == intVal) return byteVal;
}
}
- if ( expected == double.class ) {
- if ( guess instanceof Number ) return ((Number)guess).doubleValue();
+ if (expected == double.class) {
+ if (guess instanceof Number) return ((Number)guess).doubleValue();
}
- if ( expected == float.class ) {
- if ( guess instanceof Number ) return ((Number)guess).floatValue();
+ if (expected == float.class) {
+ if (guess instanceof Number) return ((Number)guess).floatValue();
}
- if ( expected == boolean.class ) {
- if ( guess instanceof Boolean ) return ((Boolean)guess).booleanValue();
+ if (expected == boolean.class) {
+ if (guess instanceof Boolean) return ((Boolean)guess).booleanValue();
}
- if ( expected == char.class ) {
- if ( guess instanceof Character ) return ((Character)guess).charValue();
+ if (expected == char.class) {
+ if (guess instanceof Character) return ((Character)guess).charValue();
}
- if ( expected == String.class ) {
- if ( guess instanceof String ) return guess;
+ if (expected == String.class) {
+ if (guess instanceof String) return guess;
}
- if ( Enum.class.isAssignableFrom(expected) ) {
- if ( guess instanceof String ) {
- for ( Object enumConstant : expected.getEnumConstants() ) {
+ if (Enum.class.isAssignableFrom(expected) ) {
+ if (guess instanceof String) {
+ for (Object enumConstant : expected.getEnumConstants()) {
String target = ((Enum<?>)enumConstant).name();
- if ( target.equals(guess) ) return enumConstant;
+ if (target.equals(guess)) return enumConstant;
}
throw new AnnotationValueDecodeFail(v,
"Can't translate " + guess + " to an enum of type " + expected, pos);
}
}
- if ( Class.class == expected ) {
- if ( guess instanceof String ) try {
+ if (Class.class == expected) {
+ if (guess instanceof String) try {
return Class.forName(toFQ((String)guess));
- } catch ( ClassNotFoundException e ) {
+ } catch (ClassNotFoundException e) {
throw new AnnotationValueDecodeFail(v,
"Can't translate " + guess + " to a class object.", pos);
}
@@ -334,7 +334,7 @@ public class AnnotationValues<A extends Annotation> {
* The index-th item in the initializer will carry the error (you should only call this method if you know it's there!) */
public void setError(String annotationMethodName, String message, int index) {
AnnotationValue v = values.get(annotationMethodName);
- if ( v == null ) return;
+ if (v == null) return;
v.setError(message, index);
}
@@ -342,7 +342,7 @@ public class AnnotationValues<A extends Annotation> {
* The index-th item in the initializer will carry the error (you should only call this method if you know it's there!) */
public void setWarning(String annotationMethodName, String message, int index) {
AnnotationValue v = values.get(annotationMethodName);
- if ( v == null ) return;
+ if (v == null) return;
v.setWarning(message, index);
}
@@ -354,9 +354,9 @@ public class AnnotationValues<A extends Annotation> {
public List<String> getProbableFQTypes(String annotationMethodName) {
List<String> result = new ArrayList<String>();
AnnotationValue v = values.get(annotationMethodName);
- if ( v == null ) return Collections.emptyList();
+ if (v == null) return Collections.emptyList();
- for ( Object o : v.valueGuesses ) result.add(o == null ? null : toFQ(o.toString()));
+ for (Object o : v.valueGuesses) result.add(o == null ? null : toFQ(o.toString()));
return result;
}
@@ -375,32 +375,32 @@ public class AnnotationValues<A extends Annotation> {
boolean fqn = typeName.indexOf('.') > -1;
String prefix = fqn ? typeName.substring(0, typeName.indexOf('.')) : typeName;
- for ( String im : ast.getImportStatements() ) {
+ for (String im : ast.getImportStatements()) {
int idx = im.lastIndexOf('.');
String simple = im;
- if ( idx > -1 ) simple = im.substring(idx+1);
- if ( simple.equals(prefix) ) {
+ if (idx > -1) simple = im.substring(idx+1);
+ if (simple.equals(prefix)) {
return im + typeName.substring(prefix.length());
}
}
c = tryClass(typeName);
- if ( c != null ) return c.getName();
+ if (c != null) return c.getName();
c = tryClass("java.lang." + typeName);
- if ( c != null ) return c.getName();
+ if (c != null) return c.getName();
//Try star imports
- for ( String im : ast.getImportStatements() ) {
- if ( im.endsWith(".*") ) {
+ for (String im : ast.getImportStatements()) {
+ if (im.endsWith(".*")) {
c = tryClass(im.substring(0, im.length() -1) + typeName);
- if ( c != null ) return c.getName();
+ if (c != null) return c.getName();
}
}
- if ( !fqn ) {
+ if (!fqn) {
String pkg = ast.getPackageDeclaration();
- if ( pkg != null ) return pkg + "." + typeName;
+ if (pkg != null) return pkg + "." + typeName;
}
return null;
@@ -409,7 +409,7 @@ public class AnnotationValues<A extends Annotation> {
private Class<?> tryClass(String name) {
try {
return Class.forName(name);
- } catch ( ClassNotFoundException e ) {
+ } catch (ClassNotFoundException e) {
return null;
}
}
diff --git a/src/lombok/core/LombokNode.java b/src/lombok/core/LombokNode.java
new file mode 100644
index 00000000..e4712313
--- /dev/null
+++ b/src/lombok/core/LombokNode.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.core;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+
+import lombok.core.AST.Kind;
+
+/**
+ * An instance of this class wraps an Eclipse/javac internal node object.
+ *
+ * @param A Type of our owning AST.
+ * @param L self-type.
+ * @param N The common type of all AST nodes in the internal representation of the target platform.
+ * For example, JCTree for javac, and ASTNode for Eclipse.
+ */
+public abstract class LombokNode<A extends AST<A, L, N>, L extends LombokNode<A, L, N>, N> {
+ protected final A ast;
+ protected final Kind kind;
+ protected final N node;
+ protected final List<L> children;
+ protected L parent;
+
+ /** This flag has no specified meaning; you can set and retrieve it.
+ *
+ * In practice, for annotation nodes it means: Some AnnotationHandler finished whatever changes were required,
+ * and for all other nodes it means: This node was made by a lombok operation.
+ */
+ protected boolean handled;
+
+ /** structurally significant are those nodes that can be annotated in java 1.6 or are method-like toplevels,
+ * so fields, local declarations, method arguments, methods, types, the Compilation Unit itself, and initializers. */
+ protected boolean isStructurallySignificant;
+
+ /**
+ * Creates a new Node object that represents the provided node.
+ *
+ * @param ast The owning AST - this node is part of this AST's tree of nodes.
+ * @param node The AST object in the target parser's own internal AST tree that this node object will represent.
+ * @param children A list of child nodes. Passing in null results in the children list being empty, not null.
+ * @param kind The kind of node represented by this object.
+ */
+ @SuppressWarnings("unchecked")
+ protected LombokNode(A ast, N node, List<L> children, Kind kind) {
+ this.ast = ast;
+ this.kind = kind;
+ this.node = node;
+ this.children = children == null ? new ArrayList<L>() : children;
+ for (L child : this.children) child.parent = (L) this;
+ this.isStructurallySignificant = calculateIsStructurallySignificant();
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return String.format("NODE %s (%s) %s%s",
+ kind, node == null ? "(NULL)" : node.getClass(), handled ? "[HANDLED]" : "", node == null ? "" : node);
+ }
+
+ /**
+ * Convenient shortcut to the owning ast object's {@code getPackageDeclaration} method.
+ *
+ * @see AST#getPackageDeclaration()
+ */
+ public String getPackageDeclaration() {
+ return ast.getPackageDeclaration();
+ }
+
+ /**
+ * Convenient shortcut to the owning ast object's {@code getImportStatements} method.
+ *
+ * @see AST#getImportStatements()
+ */
+ public Collection<String> getImportStatements() {
+ return ast.getImportStatements();
+ }
+
+ /**
+ * See {@link #isStructurallySignificant}.
+ */
+ protected abstract boolean calculateIsStructurallySignificant();
+
+ /**
+ * Convenient shortcut to the owning ast object's get method.
+ *
+ * @see AST#get(Object)
+ */
+ public L getNodeFor(N obj) {
+ return ast.get(obj);
+ }
+
+ /**
+ * @return The javac/Eclipse internal AST object wrapped by this LombokNode object.
+ */
+ public N get() {
+ return node;
+ }
+
+ /**
+ * Replaces the AST node represented by this node object with the provided node. This node must
+ * have a parent, obviously, for this to work.
+ *
+ * Also affects the underlying (Eclipse/javac) AST.
+ */
+ @SuppressWarnings("unchecked")
+ public L replaceWith(N newN, Kind kind) {
+ L newNode = ast.buildTree(newN, kind);
+ newNode.parent = parent;
+ for (int i = 0; i < parent.children.size(); i++) {
+ if (parent.children.get(i) == this) ((List)parent.children).set(i, newNode);
+ }
+
+ parent.replaceChildNode(get(), newN);
+ return newNode;
+ }
+
+ /**
+ * Replaces the stated node with a new one. The old node must be a direct child of this node.
+ *
+ * Also affects the underlying (Eclipse/javac) AST.
+ */
+ public void replaceChildNode(N oldN, N newN) {
+ ast.replaceStatementInNode(get(), oldN, newN);
+ }
+
+ public Kind getKind() {
+ return kind;
+ }
+
+ /**
+ * Return the name of your type (simple name), method, field, or local variable. Return null if this
+ * node doesn't really have a name, such as initializers, while statements, etc.
+ */
+ public abstract String getName();
+
+ /** Returns the structurally significant node that encloses this one.
+ *
+ * @see #isStructurallySignificant()
+ */
+ public L up() {
+ L result = parent;
+ while (result != null && !result.isStructurallySignificant) result = result.parent;
+ return result;
+ }
+
+ /**
+ * Returns the direct parent node in the AST tree of this node. For example, a local variable declaration's
+ * direct parent can be e.g. an If block, but its {@code up()} {@code LombokNode} is the {@code Method} that contains it.
+ */
+ public L directUp() {
+ return parent;
+ }
+
+ /**
+ * Returns all children nodes.
+ *
+ * A copy is created, so changing the list has no effect. Also, while iterating through this list,
+ * you may add, remove, or replace children without causing {@code ConcurrentModificationException}s.
+ */
+ public Collection<L> down() {
+ return new ArrayList<L>(children);
+ }
+
+ /**
+ * returns the value of the 'handled' flag.
+ *
+ * @see #handled
+ */
+ public boolean isHandled() {
+ return handled;
+ }
+
+ /**
+ * Sets the handled flag, then returns itself for chaining.
+ *
+ * @see #handled
+ */
+ @SuppressWarnings("unchecked")
+ public L setHandled() {
+ this.handled = true;
+ return (L)this;
+ }
+
+ /**
+ * Convenient shortcut to the owning ast object's top method.
+ *
+ * @see AST#top()
+ */
+ public L top() {
+ return ast.top();
+ }
+
+ /**
+ * Convenient shortcut to the owning ast object's getFileName method.
+ *
+ * @see AST#getFileName()
+ */
+ public String getFileName() {
+ return ast.getFileName();
+ }
+
+ /**
+ * Adds the stated node as a direct child of this node.
+ *
+ * Does not change the underlying (javac/Eclipse) AST, only the wrapped view.
+ */
+ @SuppressWarnings("unchecked")
+ public L add(N newChild, Kind kind) {
+ L n = ast.buildTree(newChild, kind);
+ if (n == null) return null;
+ n.parent = (L) this;
+ ((List)children).add(n);
+ return n;
+ }
+
+ /**
+ * Reparses the AST node represented by this node. Any existing nodes that occupy a different space in the AST are rehomed, any
+ * nodes that no longer exist are removed, and new nodes are created.
+ *
+ * Careful - the node you call this on must not itself have been removed or rehomed - it rebuilds <i>all children</i>.
+ */
+ public void rebuild() {
+ Map<N, L> oldNodes = new IdentityHashMap<N, L>();
+ gatherAndRemoveChildren(oldNodes);
+
+ L newNode = ast.buildTree(get(), kind);
+
+ ast.replaceNewWithExistingOld(oldNodes, newNode);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void gatherAndRemoveChildren(Map<N, L> map) {
+ for (L child : children) child.gatherAndRemoveChildren(map);
+ ast.identityDetector.remove(get());
+ map.put(get(), (L) this);
+ children.clear();
+ ast.getNodeMap().remove(get());
+ }
+
+ /**
+ * Removes the stated node, which must be a direct child of this node, from the AST.
+ *
+ * Does not change the underlying (javac/Eclipse) AST, only the wrapped view.
+ */
+ public void removeChild(L child) {
+ children.remove(child);
+ }
+
+ /**
+ * Sets the handled flag on this node, and all child nodes, then returns itself, for chaining.
+ *
+ * @see #handled
+ */
+ @SuppressWarnings("unchecked")
+ public L recursiveSetHandled() {
+ this.handled = true;
+ for (L child : children) child.recursiveSetHandled();
+ return (L) this;
+ }
+
+ /** Generate a compiler error on this node. */
+ public abstract void addError(String message);
+
+ /** Generate a compiler warning on this node. */
+ public abstract void addWarning(String message);
+
+ /**
+ * Structurally significant means: LocalDeclaration, TypeDeclaration, MethodDeclaration, ConstructorDeclaration,
+ * FieldDeclaration, Initializer, and CompilationUnitDeclaration.
+ * The rest is e.g. if statements, while loops, etc.
+ */
+ public boolean isStructurallySignificant() {
+ return isStructurallySignificant;
+ }
+}
diff --git a/src/lombok/core/SpiLoadUtil.java b/src/lombok/core/SpiLoadUtil.java
index 9f047c22..6245cf5b 100644
--- a/src/lombok/core/SpiLoadUtil.java
+++ b/src/lombok/core/SpiLoadUtil.java
@@ -78,7 +78,7 @@ public class SpiLoadUtil {
public static <C> Iterable<C> findServices(final Class<C> target, final ClassLoader loader) throws IOException {
Enumeration<URL> resources = loader.getResources("META-INF/services/" + target.getName());
final Set<String> entries = new LinkedHashSet<String>();
- while ( resources.hasMoreElements() ) {
+ while (resources.hasMoreElements()) {
URL url = resources.nextElement();
readServicesFromUrl(entries, url);
}
@@ -94,7 +94,7 @@ public class SpiLoadUtil {
@Override public C next() {
try {
return target.cast(Class.forName(names.next(), true, loader).newInstance());
- } catch ( Throwable t ) {
+ } catch (Throwable t) {
throw Lombok.sneakyThrow(t);
}
}
@@ -110,19 +110,21 @@ public class SpiLoadUtil {
private static void readServicesFromUrl(Collection<String> list, URL url) throws IOException {
InputStream in = url.openStream();
try {
- if ( in == null ) return;
+ if (in == null) return;
BufferedReader r = new BufferedReader(new InputStreamReader(in, "UTF-8"));
- while ( true ) {
+ while (true) {
String line = r.readLine();
- if ( line == null ) break;
+ if (line == null) break;
int idx = line.indexOf('#');
- if ( idx != -1 ) line = line.substring(0, idx);
+ if (idx != -1) line = line.substring(0, idx);
line = line.trim();
- if ( line.length() == 0 ) continue;
+ if (line.length() == 0) continue;
list.add(line);
}
} finally {
- try { in.close(); } catch ( Throwable ignore ) {}
+ try {
+ in.close();
+ } catch (Throwable ignore) {}
}
}
@@ -134,14 +136,14 @@ public class SpiLoadUtil {
*/
@SuppressWarnings("unchecked")
public static Class<? extends Annotation> findAnnotationClass(Class<?> c, Class<?> base) {
- if ( c == Object.class || c == null ) return null;
- for ( Type iface : c.getGenericInterfaces() ) {
- if ( iface instanceof ParameterizedType ) {
+ if (c == Object.class || c == null) return null;
+ for (Type iface : c.getGenericInterfaces()) {
+ if (iface instanceof ParameterizedType) {
ParameterizedType p = (ParameterizedType)iface;
- if ( !base.equals(p.getRawType()) ) continue;
+ if (!base.equals(p.getRawType())) continue;
Type target = p.getActualTypeArguments()[0];
- if ( target instanceof Class<?> ) {
- if ( Annotation.class.isAssignableFrom((Class<?>) target) ) {
+ if (target instanceof Class<?>) {
+ if (Annotation.class.isAssignableFrom((Class<?>) target)) {
return (Class<? extends Annotation>) target;
}
}
@@ -151,10 +153,10 @@ public class SpiLoadUtil {
}
Class<? extends Annotation> potential = findAnnotationClass(c.getSuperclass(), base);
- if ( potential != null ) return potential;
- for ( Class<?> iface : c.getInterfaces() ) {
+ if (potential != null) return potential;
+ for (Class<?> iface : c.getInterfaces()) {
potential = findAnnotationClass(iface, base);
- if ( potential != null ) return potential;
+ if (potential != null) return potential;
}
return null;
diff --git a/src/lombok/core/TransformationsUtil.java b/src/lombok/core/TransformationsUtil.java
index ec35f1b9..050dc370 100644
--- a/src/lombok/core/TransformationsUtil.java
+++ b/src/lombok/core/TransformationsUtil.java
@@ -64,12 +64,12 @@ public class TransformationsUtil {
public static String toGetterName(CharSequence fieldName, boolean isBoolean) {
final String prefix = isBoolean ? "is" : "get";
- if ( fieldName.length() == 0 ) return prefix;
+ if (fieldName.length() == 0) return prefix;
- for ( String knownBooleanPrefix : KNOWN_BOOLEAN_PREFIXES ) {
- if ( !fieldName.toString().startsWith(knownBooleanPrefix) ) continue;
- if ( fieldName.length() > knownBooleanPrefix.length() &&
- !Character.isLowerCase(fieldName.charAt(knownBooleanPrefix.length())) ) {
+ for (String knownBooleanPrefix : KNOWN_BOOLEAN_PREFIXES) {
+ if (!fieldName.toString().startsWith(knownBooleanPrefix)) continue;
+ if (fieldName.length() > knownBooleanPrefix.length() &&
+ !Character.isLowerCase(fieldName.charAt(knownBooleanPrefix.length()))) {
//The field is called something like 'isFoo' or 'hasFoo' or 'getFoo', so we shouldn't
//prefix with 'is' but instead just use the field name as is. The isLowerCase check is so we don't turn
//hashCodeGenerated, which so happens to start with 'has', into hasHCodeGenerated instead of isHashCodeGenerated.
@@ -103,10 +103,10 @@ public class TransformationsUtil {
}
private static String buildName(String prefix, String suffix) {
- if ( suffix.length() == 0 ) return prefix;
+ if (suffix.length() == 0) return prefix;
char first = suffix.charAt(0);
- if ( Character.isLowerCase(first) ) {
+ if (Character.isLowerCase(first)) {
boolean useUpperCase = suffix.length() > 2 &&
(Character.isTitleCase(suffix.charAt(1)) || Character.isUpperCase(suffix.charAt(1)));
suffix = String.format("%s%s",
@@ -117,14 +117,14 @@ public class TransformationsUtil {
}
public static List<String> toAllGetterNames(CharSequence fieldName, boolean isBoolean) {
- if ( !isBoolean ) return Collections.singletonList(toGetterName(fieldName, false));
+ if (!isBoolean) return Collections.singletonList(toGetterName(fieldName, false));
List<String> baseNames = new ArrayList<String>();
baseNames.add(fieldName.toString());
- for ( String knownBooleanPrefix : KNOWN_BOOLEAN_PREFIXES ) {
- if ( !fieldName.toString().startsWith(knownBooleanPrefix) ) continue;
- if ( fieldName.length() > knownBooleanPrefix.length() &&
- !Character.isLowerCase(fieldName.charAt(knownBooleanPrefix.length())) ) {
+ for (String knownBooleanPrefix : KNOWN_BOOLEAN_PREFIXES) {
+ if (!fieldName.toString().startsWith(knownBooleanPrefix)) continue;
+ if (fieldName.length() > knownBooleanPrefix.length() &&
+ !Character.isLowerCase(fieldName.charAt(knownBooleanPrefix.length()))) {
//The field is called something like 'isFoo' or 'hasFoo' or 'getFoo', so the practical fieldname
//could also be 'foo'.
baseNames.add(fieldName.toString().substring(knownBooleanPrefix.length()));
@@ -134,12 +134,12 @@ public class TransformationsUtil {
}
Set<String> names = new HashSet<String>();
- for ( String baseName : baseNames ) {
- if ( baseName.length() > 0 && Character.isLowerCase(baseName.charAt(0)) ) {
+ for (String baseName : baseNames) {
+ if (baseName.length() > 0 && Character.isLowerCase(baseName.charAt(0))) {
baseName = Character.toTitleCase(baseName.charAt(0)) + baseName.substring(1);
}
- for ( String prefix : KNOWN_BOOLEAN_PREFIXES ) {
+ for (String prefix : KNOWN_BOOLEAN_PREFIXES) {
names.add(prefix + baseName);
}
}
diff --git a/src/lombok/core/TypeLibrary.java b/src/lombok/core/TypeLibrary.java
index 41b70a68..5de01b70 100644
--- a/src/lombok/core/TypeLibrary.java
+++ b/src/lombok/core/TypeLibrary.java
@@ -47,13 +47,13 @@ public class TypeLibrary {
*/
public void addType(String fullyQualifiedTypeName) {
int idx = fullyQualifiedTypeName.lastIndexOf('.');
- if ( idx == -1 ) throw new IllegalArgumentException(
+ if (idx == -1) throw new IllegalArgumentException(
"Only fully qualified types are allowed (and stuff in the default package is not palatable to us either!)");
final String simpleName = fullyQualifiedTypeName.substring(idx +1);
final String packageName = fullyQualifiedTypeName.substring(0, idx);
- if ( simpleToQualifiedMap.put(fullyQualifiedTypeName, Collections.singleton(fullyQualifiedTypeName)) != null ) return;
+ if (simpleToQualifiedMap.put(fullyQualifiedTypeName, Collections.singleton(fullyQualifiedTypeName)) != null) return;
addToMap(simpleName, fullyQualifiedTypeName);
addToMap(packageName + ".*", fullyQualifiedTypeName);
diff --git a/src/lombok/core/TypeResolver.java b/src/lombok/core/TypeResolver.java
index 3adc82ce..dd1d9a53 100644
--- a/src/lombok/core/TypeResolver.java
+++ b/src/lombok/core/TypeResolver.java
@@ -46,7 +46,7 @@ public class TypeResolver {
private static Collection<String> makeImportList(String packageString, Collection<String> importStrings) {
Set<String> imports = new HashSet<String>();
- if ( packageString != null ) imports.add(packageString + ".*");
+ if (packageString != null) imports.add(packageString + ".*");
imports.addAll(importStrings == null ? Collections.<String>emptySet() : importStrings);
return imports;
}
@@ -56,27 +56,27 @@ public class TypeResolver {
* that shadow type names listed in import statements. If such a shadowing occurs, no matches are returned
* for any shadowed types, as you would expect.
*/
- public Collection<String> findTypeMatches(AST<?>.Node context, String typeRef) {
+ public Collection<String> findTypeMatches(LombokNode<?, ?, ?> context, String typeRef) {
Collection<String> potentialMatches = library.findCompatible(typeRef);
- if ( potentialMatches.isEmpty() ) return Collections.emptyList();
+ if (potentialMatches.isEmpty()) return Collections.emptyList();
int idx = typeRef.indexOf('.');
- if ( idx > -1 ) return potentialMatches;
+ if (idx > -1) return potentialMatches;
String simpleName = typeRef.substring(idx+1);
//If there's an import statement that explicitly imports a 'Getter' that isn't any of our potentials, return no matches.
- if ( nameConflictInImportList(simpleName, potentialMatches) ) return Collections.emptyList();
+ if (nameConflictInImportList(simpleName, potentialMatches)) return Collections.emptyList();
//Check if any of our potentials is even imported in the first place. If not: no matches.
potentialMatches = eliminateImpossibleMatches(potentialMatches);
- if ( potentialMatches.isEmpty() ) return Collections.emptyList();
+ if (potentialMatches.isEmpty()) return Collections.emptyList();
//Find a lexically accessible type of the same simple name in the same Compilation Unit. If it exists: no matches.
- AST<?>.Node n = context;
- while ( n != null ) {
- if ( n.getKind() == Kind.TYPE ) {
+ LombokNode<?, ?, ?> n = context;
+ while (n != null) {
+ if (n.getKind() == Kind.TYPE) {
String name = n.getName();
- if ( name != null && name.equals(simpleName) ) return Collections.emptyList();
+ if (name != null && name.equals(simpleName)) return Collections.emptyList();
}
n = n.up();
}
@@ -88,7 +88,7 @@ public class TypeResolver {
private Collection<String> eliminateImpossibleMatches(Collection<String> potentialMatches) {
Set<String> results = new HashSet<String>();
- for ( String importedType : imports ) {
+ for (String importedType : imports) {
Collection<String> reduced = new HashSet<String>(library.findCompatible(importedType));
reduced.retainAll(potentialMatches);
results.addAll(reduced);
@@ -98,9 +98,9 @@ public class TypeResolver {
}
private boolean nameConflictInImportList(String simpleName, Collection<String> potentialMatches) {
- for ( String importedType : imports ) {
- if ( !toSimpleName(importedType).equals(simpleName) ) continue;
- if ( potentialMatches.contains(importedType) ) continue;
+ for (String importedType : imports) {
+ if (!toSimpleName(importedType).equals(simpleName)) continue;
+ if (potentialMatches.contains(importedType)) continue;
return true;
}