From b5c8b725655d2ad8a715cfb1fbbdf25dbdcd4ceb Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 16 Oct 2009 09:32:36 +0200 Subject: 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_. --- src/lombok/core/AST.java | 415 +++++++------------------------ src/lombok/core/AnnotationValues.java | 122 ++++----- src/lombok/core/LombokNode.java | 297 ++++++++++++++++++++++ src/lombok/core/SpiLoadUtil.java | 36 +-- src/lombok/core/TransformationsUtil.java | 30 +-- src/lombok/core/TypeLibrary.java | 4 +- src/lombok/core/TypeResolver.java | 28 +-- 7 files changed, 494 insertions(+), 438 deletions(-) create mode 100644 src/lombok/core/LombokNode.java (limited to 'src/lombok/core') 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 { +public abstract class AST, L extends LombokNode, 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 identityDetector = new IdentityHashMap(); - private Map nodeMap = new IdentityHashMap(); + Map identityDetector = new IdentityHashMap(); + private Map nodeMap = new IdentityHashMap(); 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 { * 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 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 getNodeMap() { + protected Map getNodeMap() { return nodeMap; } @@ -95,7 +97,7 @@ public abstract class AST { * object is left untouched, and instead a new map is created. */ protected void clearState() { identityDetector = new IdentityHashMap(); - nodeMap = new IdentityHashMap(); + nodeMap = new IdentityHashMap(); } /** @@ -104,7 +106,7 @@ public abstract class AST { * 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 { } /** 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 oldNodes, Node newNode) { - Node oldNode = oldNodes.get(newNode.get()); - Node targetNode = oldNode == null ? newNode : oldNode; + L replaceNewWithExistingOld(Map 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 { 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 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 children, Kind kind) { - this.kind = kind; - this.node = node; - this.children = children == null ? new ArrayList() : 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 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 down() { - return new ArrayList(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 all children. - */ - public void rebuild() { - Map oldNodes = new IdentityHashMap(); - gatherAndRemoveChildren(oldNodes); - - Node newNode = buildTree(get(), kind); - - replaceNewWithExistingOld(oldNodes, newNode); - } - - private void gatherAndRemoveChildren(Map 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 { */ protected Collection fieldsOf(Class c) { Collection fields = fieldsOfASTClasses.get(c); - if ( fields != null ) return fields; + if (fields != null) return fields; fields = new ArrayList(); getFields(c, fields); @@ -429,26 +177,26 @@ public abstract class AST { } private void getFields(Class c, Collection 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 { } 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 { /** * buildTree implementation that uses reflection to find all child nodes by way of inspecting * the fields. */ - protected Collection buildWithField(Class nodeType, N statement, FieldAccess fa) { - List list = new ArrayList(); + protected Collection buildWithField(Class nodeType, N statement, FieldAccess fa) { + List list = new ArrayList(); buildWithField0(nodeType, statement, fa, list); return list; } @@ -483,8 +233,8 @@ public abstract class AST { * 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 { 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)o, oldN, newN); } } return false; - } catch ( IllegalAccessException e ) { + } catch (IllegalAccessException e) { throw sneakyThrow(e); } } private boolean replaceStatementInCollection(Field field, Object fieldRef, List> 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> newChain = new ArrayList>(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 { /** 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> 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 { } @SuppressWarnings("unchecked") - private void buildWithField0(Class nodeType, N child, FieldAccess fa, Collection list) { + private void buildWithField0(Class nodeType, N child, FieldAccess fa, Collection 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 void buildWithArray(Class nodeType, Object array, Collection 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 nodeType, Object array, Collection 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 void buildWithCollection(Class nodeType, Object collection, Collection 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 nodeType, Object collection, Collection 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 { private final Class type; private final Map 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 { /** 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 valueGuesses; - private final AST.Node node; + private final LombokNode node; private final boolean isExplicit; /** @@ -59,7 +59,7 @@ public class AnnotationValues { * For classes, supply the class name (qualified or not) as a string.
* For enums, supply the simple name part (everything after the last dot) as a string.
*/ - 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
{ /** * Like the other constructor, but used for when the annotation method is initialized with an array value. */ - public AnnotationValue(AST.Node node, List raws, List valueGuesses, boolean isExplicit) { + public AnnotationValue(LombokNode node, List raws, List valueGuesses, boolean isExplicit) { this.node = node; this.raws = raws; this.valueGuesses = valueGuesses; @@ -117,7 +117,7 @@ public class AnnotationValues { * @param values a Map of method names to AnnotationValue instances, for example 'value -> annotationValue instance'. * @param ast The Annotation node. */ - public AnnotationValues(Class type, Map values, AST.Node ast) { + public AnnotationValues(Class type, Map values, LombokNode ast) { this.type = type; this.values = values; this.ast = ast; @@ -162,50 +162,50 @@ public class AnnotationValues { */ @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 { } 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 { * 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 { * 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 { public List getProbableFQTypes(String annotationMethodName) { List result = new ArrayList(); 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 { 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 { 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, L extends LombokNode, N> { + protected final A ast; + protected final Kind kind; + protected final N node; + protected final List 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 children, Kind kind) { + this.ast = ast; + this.kind = kind; + this.node = node; + this.children = children == null ? new ArrayList() : 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 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 down() { + return new ArrayList(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 all children. + */ + public void rebuild() { + Map oldNodes = new IdentityHashMap(); + gatherAndRemoveChildren(oldNodes); + + L newNode = ast.buildTree(get(), kind); + + ast.replaceNewWithExistingOld(oldNodes, newNode); + } + + @SuppressWarnings("unchecked") + private void gatherAndRemoveChildren(Map 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 Iterable findServices(final Class target, final ClassLoader loader) throws IOException { Enumeration resources = loader.getResources("META-INF/services/" + target.getName()); final Set entries = new LinkedHashSet(); - 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 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 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) target; } } @@ -151,10 +153,10 @@ public class SpiLoadUtil { } Class 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 toAllGetterNames(CharSequence fieldName, boolean isBoolean) { - if ( !isBoolean ) return Collections.singletonList(toGetterName(fieldName, false)); + if (!isBoolean) return Collections.singletonList(toGetterName(fieldName, false)); List baseNames = new ArrayList(); 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 names = new HashSet(); - 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 makeImportList(String packageString, Collection importStrings) { Set imports = new HashSet(); - if ( packageString != null ) imports.add(packageString + ".*"); + if (packageString != null) imports.add(packageString + ".*"); imports.addAll(importStrings == null ? Collections.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 findTypeMatches(AST.Node context, String typeRef) { + public Collection findTypeMatches(LombokNode context, String typeRef) { Collection 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 eliminateImpossibleMatches(Collection potentialMatches) { Set results = new HashSet(); - for ( String importedType : imports ) { + for (String importedType : imports) { Collection reduced = new HashSet(library.findCompatible(importedType)); reduced.retainAll(potentialMatches); results.addAll(reduced); @@ -98,9 +98,9 @@ public class TypeResolver { } private boolean nameConflictInImportList(String simpleName, Collection 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; } -- cgit