diff options
| author | Reinier Zwitserloot <reinier@tipit.to> | 2009-10-16 09:32:36 +0200 |
|---|---|---|
| committer | Reinier Zwitserloot <reinier@tipit.to> | 2009-10-16 09:32:36 +0200 |
| commit | b5c8b725655d2ad8a715cfb1fbbdf25dbdcd4ceb (patch) | |
| tree | 571d13cd7028a6b7d1ebfe84180a4328a20c42d7 /src/lombok/core | |
| parent | 8629a651a66aa5fba9e0ada7df00803528b0e34f (diff) | |
| download | lombok-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.java | 415 | ||||
| -rw-r--r-- | src/lombok/core/AnnotationValues.java | 122 | ||||
| -rw-r--r-- | src/lombok/core/LombokNode.java | 297 | ||||
| -rw-r--r-- | src/lombok/core/SpiLoadUtil.java | 36 | ||||
| -rw-r--r-- | src/lombok/core/TransformationsUtil.java | 30 | ||||
| -rw-r--r-- | src/lombok/core/TypeLibrary.java | 4 | ||||
| -rw-r--r-- | src/lombok/core/TypeResolver.java | 28 |
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 portio |
