diff options
| author | Reinier Zwitserloot <reinier@tipit.to> | 2009-11-25 07:32:49 +0100 |
|---|---|---|
| committer | Reinier Zwitserloot <reinier@tipit.to> | 2009-11-25 07:32:49 +0100 |
| commit | 1a0e611a9c5e1ee518670647ce1a44beae559b44 (patch) | |
| tree | e5ef8f671bc6688f486e874d4e2e1a7813e4f0b2 /src/lombok/core | |
| parent | 7fd947ea40c25dad9ee543ebc4b92de9a2e05efc (diff) | |
| download | lombok-1a0e611a9c5e1ee518670647ce1a44beae559b44.tar.gz lombok-1a0e611a9c5e1ee518670647ce1a44beae559b44.tar.bz2 lombok-1a0e611a9c5e1ee518670647ce1a44beae559b44.zip | |
Refactored the source folders.
Diffstat (limited to 'src/lombok/core')
| -rw-r--r-- | src/lombok/core/AST.java | 367 | ||||
| -rw-r--r-- | src/lombok/core/AnnotationValues.java | 419 | ||||
| -rw-r--r-- | src/lombok/core/LombokNode.java | 297 | ||||
| -rw-r--r-- | src/lombok/core/PrintAST.java | 51 | ||||
| -rw-r--r-- | src/lombok/core/SpiLoadUtil.java | 164 | ||||
| -rw-r--r-- | src/lombok/core/TransformationsUtil.java | 149 | ||||
| -rw-r--r-- | src/lombok/core/TypeLibrary.java | 79 | ||||
| -rw-r--r-- | src/lombok/core/TypeResolver.java | 114 | ||||
| -rw-r--r-- | src/lombok/core/Version.java | 48 | ||||
| -rw-r--r-- | src/lombok/core/package-info.java | 30 |
10 files changed, 0 insertions, 1718 deletions
diff --git a/src/lombok/core/AST.java b/src/lombok/core/AST.java deleted file mode 100644 index 6d786d1e..00000000 --- a/src/lombok/core/AST.java +++ /dev/null @@ -1,367 +0,0 @@ -/* - * 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 static lombok.Lombok.sneakyThrow; - -import java.lang.reflect.Array; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.IdentityHashMap; -import java.util.List; -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. - */ -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 L top; - private final String fileName; - 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(L top) { - this.top = top; - } - - /** - * Return the content of the package declaration on this AST's top (Compilation Unit) node. - * - * Example: "java.util". - */ - public abstract String getPackageDeclaration(); - - /** - * Return the contents of each non-static import statement on this AST's top (Compilation Unit) node. - * - * Example: "java.util.IOException". - */ - public abstract Collection<String> getImportStatements(); - - /** - * 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 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, L> getNodeMap() { - return nodeMap; - } - - /** Clears the registry that avoids endless loops, and empties the node map. The existing node map - * object is left untouched, and instead a new map is created. */ - protected void clearState() { - identityDetector = new IdentityHashMap<N, Void>(); - nodeMap = new IdentityHashMap<N, L>(); - } - - /** - * Marks the stated node as handled (to avoid endless loops if 2 nodes refer to each other, or a node - * refers to itself). Will then return true if it was already set as handled before this call - in which - * case you should do nothing lest the AST build process loops endlessly. - */ - protected boolean setAndGetAsHandled(N node) { - if (identityDetector.containsKey(node)) return true; - identityDetector.put(node, null); - return false; - } - - public String getFileName() { - return fileName; - } - - /** The AST.Node object representing the Compilation Unit. */ - public L top() { - return top; - } - - /** Maps a javac/Eclipse internal AST Node to the appropriate AST.Node object. */ - public L get(N node) { - return nodeMap.get(node); - } - - @SuppressWarnings("unchecked") - 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 (L child : newNode.children) { - L oldChild = replaceNewWithExistingOld(oldNodes, child); - children.add(oldChild); - oldChild.parent = targetNode; - } - - targetNode.children.clear(); - ((List)targetNode.children).addAll(children); - return targetNode; - } - - /** Build an AST.Node object for the stated internal (javac/Eclipse) AST Node object. */ - protected abstract L buildTree(N item, Kind kind); - - /** - * Represents a field that contains AST children. - */ - protected static class FieldAccess { - /** The actual field. */ - public final Field field; - /** Dimensions of the field. Works for arrays, or for java.util.collections. */ - public final int dim; - - FieldAccess(Field field, int dim) { - this.field = field; - this.dim = dim; - } - } - - private static Map<Class<?>, Collection<FieldAccess>> fieldsOfASTClasses = new HashMap<Class<?>, Collection<FieldAccess>>(); - - /** Returns FieldAccess objects for the stated class. Each field that contains objects of the kind returned by - * {@link #getStatementTypes()}, either directly or inside of an array or java.util.collection (or array-of-arrays, - * or collection-of-collections, etcetera), is returned. - */ - protected Collection<FieldAccess> fieldsOf(Class<?> c) { - Collection<FieldAccess> fields = fieldsOfASTClasses.get(c); - if (fields != null) return fields; - - fields = new ArrayList<FieldAccess>(); - getFields(c, fields); - fieldsOfASTClasses.put(c, fields); - return fields; - } - - 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; - Class<?> t = f.getType(); - int dim = 0; - - if (t.isArray()) { - while (t.isArray()) { - dim++; - t = t.getComponentType(); - } - } else { - while (Collection.class.isAssignableFrom(t)) { - dim++; - t = getComponentType(f.getGenericType()); - } - } - - for (Class<?> statementType : getStatementTypes()) { - if (statementType.isAssignableFrom(t)) { - f.setAccessible(true); - fields.add(new FieldAccess(f, dim)); - break; - } - } - } - getFields(c.getSuperclass(), fields); - } - - private Class<?> getComponentType(Type type) { - if (type instanceof ParameterizedType) { - Type component = ((ParameterizedType)type).getActualTypeArguments()[0]; - return component instanceof Class<?> ? (Class<?>)component : Object.class; - } - return Object.class; - } - - /** - * The supertypes which are considered AST Node children. Usually, the Statement, and the Expression, - * though some platforms (such as Eclipse) group these under one common supertype. */ - protected abstract Collection<Class<? extends N>> getStatementTypes(); - - /** - * buildTree implementation that uses reflection to find all child nodes by way of inspecting - * the fields. */ - protected Collection<L> buildWithField(Class<L> nodeType, N statement, FieldAccess fa) { - List<L> list = new ArrayList<L>(); - buildWithField0(nodeType, statement, fa, list); - return list; - } - - /** - * 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; - } - - return false; - } - - 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 == oldN) { - fa.field.set(statement, newN); - return true; - } - - if (fa.dim > 0) { - if (o.getClass().isArray()) { - return replaceStatementInArray(o, oldN, newN); - } else if (Collection.class.isInstance(o)) { - return replaceStatementInCollection(fa.field, statement, new ArrayList<Collection<?>>(), (Collection<?>)o, oldN, newN); - } - } - - return false; - } 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; - - int idx = -1; - for (Object o : collection) { - idx++; - 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 (o == oldN) { - setElementInASTCollection(field, fieldRef, chain, collection, idx, newN); - return true; - } - } - - return false; - } - - /** - * Override if your AST collection does not support the set method. Javac's for example, does not. - * - * @param field The field that contains the array or list of AST nodes. - * @param fieldRef The object that you can supply to the field's {@code get} method. - * @param chain If the collection is immutable, you need to update the pointer to the collection in each element in the chain. - * - * @throws IllegalAccessException This exception won't happen, but we allow you to throw it so you can avoid having to catch it. - */ - @SuppressWarnings("unchecked") - protected void setElementInASTCollection(Field field, Object fieldRef, List<Collection<?>> chain, Collection<?> collection, int idx, N newN) throws IllegalAccessException { - if (collection instanceof List<?>) { - ((List)collection).set(idx, newN); - } - } - - private boolean replaceStatementInArray(Object array, N oldN, N newN) { - if (array == null) return false; - - int len = Array.getLength(array); - 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) { - Array.set(array, i, newN); - return true; - } - } - - return false; - } - - @SuppressWarnings("unchecked") - 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) { - 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<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 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 deleted file mode 100644 index 0408de85..00000000 --- a/src/lombok/core/AnnotationValues.java +++ /dev/null @@ -1,419 +0,0 @@ -/* - * 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.lang.annotation.Annotation; -import java.lang.reflect.Array; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -/** - * Represents a single annotation in a source file and can be used to query the parameters present on it. - * - * @param A The annotation that this class represents, such as {@code lombok.Getter} - */ -public class AnnotationValues<A extends Annotation> { - private final Class<A> type; - private final Map<String, AnnotationValue> values; - private final LombokNode<?, ?, ?> ast; - - /** - * Represents a single method on the annotation class. For example, the value() method on the Getter annotation. - */ - public static class AnnotationValue { - /** A list of the raw expressions. List is size 1 unless an array is provided. */ - public final List<String> raws; - - /** 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 LombokNode<?, ?, ?> node; - private final boolean isExplicit; - - /** - * 'raw' should be the exact expression, for example '5+7', 'AccessLevel.PUBLIC', or 'int.class'. - * 'valueGuess' should be a likely guess at the real value intended. - * - * 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(LombokNode<?, ?, ?> node, String raw, Object valueGuess, boolean isExplicit) { - this.node = node; - this.raws = Collections.singletonList(raw); - this.valueGuesses = Collections.singletonList(valueGuess); - this.isExplicit = isExplicit; - } - - /** - * Like the other constructor, but used for when the annotation method is initialized with an array value. - */ - public AnnotationValue(LombokNode<?, ?, ?> node, List<String> raws, List<Object> valueGuesses, boolean isExplicit) { - this.node = node; - this.raws = raws; - this.valueGuesses = valueGuesses; - this.isExplicit = isExplicit; - } - - /** - * Override this if you want more specific behaviour (to get the source position just right). - * - * @param message English message with the problem. - * @param valueIdx The index into the values for this annotation key that caused the problem. - * -1 for a problem that applies to all values, otherwise the 0-based index into an array of values. - * If there is no array for this value (e.g. value=1 instead of value={1,2}), then always -1 or 0. - */ - public void setError(String message, int valueIdx) { - node.addError(message); - } - - /** - * Override this if you want more specific behaviour (to get the source position just right). - * - * @param message English message with the problem. - * @param valueIdx The index into the values for this annotation key that caused the problem. - * -1 for a problem that applies to all values, otherwise the 0-based index into an array of values. - * If there is no array for this value (e.g. value=1 instead of value={1,2}), then always -1 or 0. - */ - public void setWarning(String message, int valueIdx) { - node.addError(message); - } - - /** {@inheritDoc} */ - @Override public String toString() { - return "raws: " + raws + " valueGuesses: " + valueGuesses; - } - - public boolean isExplicit() { - return isExplicit; - } - } - - /** - * Creates a new AnnotationValues. - * - * @param type The annotation type. For example, "Getter.class" - * @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, LombokNode<?, ?, ?> ast) { - this.type = type; - this.values = values; - this.ast = ast; - } - - /** - * Thrown on the fly if an actual annotation instance procured via the {@link #getInstance()} method is queried - * for a method for which this AnnotationValues instance either doesn't have a guess or can't manage to fit - * the guess into the required data type. - */ - public static class AnnotationValueDecodeFail extends RuntimeException { - private static final long serialVersionUID = 1L; - - /** The index into an array initializer (e.g. if the second value in an array initializer is - * an integer constant expression like '5+SomeOtherClass.CONSTANT', this exception will be thrown, - * and you'll get a '1' for idx. */ - public final int idx; - - /** The AnnotationValue object that goes with the annotation method for which the failure occurred. */ - public final AnnotationValue owner; - - public AnnotationValueDecodeFail(AnnotationValue owner, String msg, int idx) { - super(msg); - this.idx = idx; - this.owner = owner; - } - } - - private static AnnotationValueDecodeFail makeNoDefaultFail(AnnotationValue owner, Method method) { - return new AnnotationValueDecodeFail(owner, - "No value supplied but " + method.getName() + " has no default either.", -1); - } - - private A cachedInstance = null; - - /** - * Creates an actual annotation instance. You can use this to query any annotation methods, except for - * those annotation methods with class literals, as those can most likely not be turned into Class objects. - * - * If some of the methods cannot be implemented, this method still works; it's only when you call a method - * that has a problematic value that an AnnotationValueDecodeFail exception occurs. - */ - @SuppressWarnings("unchecked") - public A getInstance() { - 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) { - Object defaultValue = method.getDefaultValue(); - if (defaultValue != null) return defaultValue; - throw makeNoDefaultFail(v, method); - } - - boolean isArray = false; - Class<?> expected = method.getReturnType(); - Object array = null; - if (expected.isArray()) { - isArray = true; - expected = expected.getComponentType(); - array = Array.newInstance(expected, v.valueGuesses.size()); - } - - 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) { - Object defaultValue = method.getDefaultValue(); - if (defaultValue == null) throw makeNoDefaultFail(v, method); - return defaultValue; - } - - int idx = 0; - for (Object guess : v.valueGuesses) { - Object result = guess == null ? null : guessToType(guess, expected, v, idx); - if (!isArray) { - if (result == null) { - Object defaultValue = method.getDefaultValue(); - if (defaultValue == null) throw makeNoDefaultFail(v, method); - return defaultValue; - } - return result; - } - if (result == null) { - if (v.valueGuesses.size() == 1) { - Object defaultValue = method.getDefaultValue(); - if (defaultValue == null) throw makeNoDefaultFail(v, method); - return defaultValue; - } - throw new AnnotationValueDecodeFail(v, - "I can't make sense of this annotation value. Try using a fully qualified literal.", idx); - } - Array.set(array, idx++, result); - } - - return array; - } - }; - - return cachedInstance = (A) Proxy.newProxyInstance(type.getClassLoader(), new Class[] { type }, invocations); - } - - 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) { - return ((Number)guess).intValue(); - } - } - - 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) { - int intVal = ((Number)guess).intValue(); - int shortVal = ((Number)guess).shortValue(); - if (shortVal == intVal) return shortVal; - } - } - - 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 (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 == boolean.class) { - if (guess instanceof Boolean) return ((Boolean)guess).booleanValue(); - } - - if (expected == char.class) { - if (guess instanceof Character) return ((Character)guess).charValue(); - } - - if (expected == String.class) { - if (guess instanceof String) return guess; - } - - 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; - } - throw new AnnotationValueDecodeFail(v, - "Can't translate " + guess + " to an enum of type " + expected, pos); - } - } - - if (Class.class == expected) { - if (guess instanceof String) try { - return Class.forName(toFQ((String)guess)); - } catch (ClassNotFoundException e) { - throw new AnnotationValueDecodeFail(v, - "Can't translate " + guess + " to a class object.", pos); - } - } - - throw new AnnotationValueDecodeFail(v, - "Can't translate a " + guess.getClass() + " to the expected " + expected, pos); - } - - /** - * Returns the raw expressions used for the provided {@code annotationMethodName}. - * - * You should use this method for annotation methods that return {@code Class} objects. Remember that - * class literals end in ".class" which you probably want to strip off. - */ - public List<String> getRawExpressions(String annotationMethodName) { - AnnotationValue v = values.get(annotationMethodName); - return v == null ? Collections.<String>emptyList() : v.raws; - } - - public boolean isExplicit(String annotationMethodName) { - AnnotationValue annotationValue = values.get(annotationMethodName); - return annotationValue != null && annotationValue.isExplicit(); - } - - /** - * Convenience method to return the first result in a {@link #getRawExpressions(String)} call. - * - * You should use this method if the annotation method is not an array type. - */ - public String getRawExpression(String annotationMethodName) { - List<String> l = getRawExpressions(annotationMethodName); - return l.isEmpty() ? null : l.get(0); - } - - /** Generates an error message on the stated annotation value (you should only call this method if you know it's there!) */ - public void setError(String annotationMethodName, String message) { - setError(annotationMethodName, message, -1); - } - - /** Generates a warning message on the stated annotation value (you should only call this method if you know it's there!) */ - public void setWarning(String annotationMethodName, String message) { - setWarning(annotationMethodName, message, -1); - } - - /** Generates an error message on the stated annotation value, which must have an array initializer. - * 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; - v.setError(message, index); - } - - /** Generates a warning message on the stated annotation value, which must have an array initializer. - * 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; - v.setWarning(message, index); - } - - /** - * Attempts to translate class literals to their fully qualified names, such as 'Throwable.class' to 'java.lang.Throwable'. - * - * This process is at best a guess, but it will take into account import statements. - */ - public List<String> getProbableFQTypes(String annotationMethodName) { - List<String> result = new ArrayList<String>(); - AnnotationValue v = values.get(annotationMethodName); - if (v == null) return Collections.emptyList(); - - for (Object o : v.valueGuesses) result.add(o == null ? null : toFQ(o.toString())); - return result; - } - - /** - * Convenience method to return the first result in a {@link #getProbableFQType(String)} call. - * - * You should use this method if the annotation method is not an array type. - */ - public String getProbableFQType(String annotationMethodName) { - List<String> l = getProbableFQTypes(annotationMethodName); - return l.isEmpty() ? null : l.get(0); - } - - private String toFQ(String typeName) { - Class<?> c; - boolean fqn = typeName.indexOf('.') > -1; - String prefix = fqn ? typeName.substring(0, typeName.indexOf('.')) : typeName; - - for (String im : ast.getImportStatements()) { - int idx = im.lastIndexOf('.'); - String simple = im; - 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(); - - c = tryClass("java.lang." + typeName); - if (c != null) return c.getName(); - - //Try star imports - for (String im : ast.getImportStatements()) { - if (im.endsWith(".*")) { - c = tryClass(im.substring(0, im.length() -1) + typeName); - if (c != null) return c.getName(); - } - } - - if (!fqn) { - String pkg = ast.getPackageDeclaration(); - if (pkg != null) return pkg + "." + typeName; - } - - return null; - } - - private Class<?> tryClass(String name) { - try { - return Class.forName(name); - } catch (ClassNotFoundException e) { - return null; - } - } -} diff --git a/src/lombok/core/LombokNode.java b/src/lombok/core/LombokNode.java deleted file mode 100644 index c8ee4c00..00000000 --- a/src/lombok/core/LombokNode.java +++ /dev/null @@ -1,297 +0,0 @@ -/* - * 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); - } - - /** - * @re |
