aboutsummaryrefslogtreecommitdiff
path: root/src/lombok/javac
diff options
context:
space:
mode:
authorReinier Zwitserloot <reinier@tipit.to>2009-06-17 10:43:39 +0200
committerReinier Zwitserloot <reinier@tipit.to>2009-06-17 10:43:39 +0200
commit024d8ffa9801f463fecadd16f42d51bbed46dea7 (patch)
treeacb0b85f79eafb517e3472bd3d906235d1541ade /src/lombok/javac
parentaa6d2e262f3d6c43f6d89220cdc10c6954bb2bdd (diff)
downloadlombok-024d8ffa9801f463fecadd16f42d51bbed46dea7.tar.gz
lombok-024d8ffa9801f463fecadd16f42d51bbed46dea7.tar.bz2
lombok-024d8ffa9801f463fecadd16f42d51bbed46dea7.zip
Massive refactors. This list isn't complete, but should give you an idea:
A) many things in lombok.eclipse moved to lombok.core to enable reuse with lombok.javac. B) lombok.javac works now similarly to eclipse's model: We first make big ASTs that are bidirectionally traversable, then we walk through that for annotations. C) Instead of getting an annotation instance, you now get an object that is more flexible and can e.g. give you class values in an enum as a string instead of a Class object, which may fail if that class isn't on the classpath of lombok. D) sources to the internal sun classes for javac added to /contrib.
Diffstat (limited to 'src/lombok/javac')
-rw-r--r--src/lombok/javac/HandlerLibrary.java227
-rw-r--r--src/lombok/javac/JavacAST.java329
-rw-r--r--src/lombok/javac/JavacASTAdapter.java35
-rw-r--r--src/lombok/javac/JavacASTVisitor.java182
-rw-r--r--src/lombok/javac/JavacAnnotationHandler.java6
-rw-r--r--src/lombok/javac/JavacNode.java63
-rw-r--r--src/lombok/javac/apt/Processor.java66
-rw-r--r--src/lombok/javac/handlers/HandleGetter_javac.java27
-rw-r--r--src/lombok/javac/handlers/PKG.java9
9 files changed, 703 insertions, 241 deletions
diff --git a/src/lombok/javac/HandlerLibrary.java b/src/lombok/javac/HandlerLibrary.java
index 6f33003f..f8fd0d75 100644
--- a/src/lombok/javac/HandlerLibrary.java
+++ b/src/lombok/javac/HandlerLibrary.java
@@ -1,13 +1,9 @@
package lombok.javac;
import java.lang.annotation.Annotation;
-import java.lang.reflect.Array;
-import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-import java.lang.reflect.Proxy;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -16,19 +12,28 @@ import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import javax.annotation.processing.Messager;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.TypeMirror;
import javax.tools.Diagnostic;
+import lombok.core.AnnotationValues;
import lombok.core.SpiLoadUtil;
+import lombok.core.TypeLibrary;
+import lombok.core.TypeResolver;
+import lombok.core.AnnotationValues.AnnotationValue;
+import lombok.core.AnnotationValues.AnnotationValueDecodeFail;
+
+import com.sun.tools.javac.tree.JCTree.JCAnnotation;
+import com.sun.tools.javac.tree.JCTree.JCAssign;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.tree.JCTree.JCExpression;
+import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
+import com.sun.tools.javac.tree.JCTree.JCIdent;
+import com.sun.tools.javac.tree.JCTree.JCLiteral;
+import com.sun.tools.javac.tree.JCTree.JCNewArray;
public class HandlerLibrary {
+ private final TypeLibrary typeLibrary = new TypeLibrary();
private final Map<String, AnnotationHandlerContainer<?>> annotationHandlers = new HashMap<String, AnnotationHandlerContainer<?>>();
// private final Collection<JavacASTVisitor> visitorHandlers = new ArrayList<JavacASTVisitor>();
@@ -41,9 +46,56 @@ public class HandlerLibrary {
this.annotationClass = annotationClass;
}
- @SuppressWarnings("unchecked")
- public void handle(JavacNode node, Object annInstance) {
- handler.handle(node, (T) annInstance);
+ private Object calculateGuess(JCExpression expr) {
+ if ( expr instanceof JCLiteral ) {
+ return ((JCLiteral)expr).value;
+ } else if ( expr instanceof JCIdent || expr instanceof JCFieldAccess ) {
+ String x = expr.toString();
+ if ( x.endsWith(".class") ) x = x.substring(0, x.length() - 6);
+ else {
+ int idx = x.lastIndexOf('.');
+ if ( idx > -1 ) x = x.substring(idx + 1);
+ }
+ return x;
+ } else return null;
+ }
+
+ public void handle(JavacAST.Node node) {
+ Map<String, AnnotationValue> values = new HashMap<String, AnnotationValue>();
+ JCAnnotation anno = (JCAnnotation) node.get();
+ List<JCExpression> arguments = anno.getArguments();
+ for ( Method m : annotationClass.getDeclaredMethods() ) {
+ if ( !Modifier.isPublic(m.getModifiers()) ) continue;
+ String name = m.getName();
+ List<String> raws = new ArrayList<String>();
+ List<Object> guesses = new ArrayList<Object>();
+
+ for ( JCExpression arg : arguments ) {
+ JCAssign assign = (JCAssign) arg;
+ String mName = assign.lhs.toString();
+ if ( !mName.equals(name) ) continue;
+ JCExpression rhs = assign.rhs;
+ if ( rhs instanceof JCNewArray ) {
+ List<JCExpression> elems = ((JCNewArray)rhs).elems;
+ for ( JCExpression inner : elems ) {
+ raws.add(inner.toString());
+ guesses.add(calculateGuess(inner));
+ }
+ } else {
+ raws.add(rhs.toString());
+ guesses.add(calculateGuess(rhs));
+ }
+ }
+
+ values.put(name, new AnnotationValue(node, raws, guesses) {
+ @Override public void setError(String message, int valueIdx) {
+ //TODO
+ super.setError(message, valueIdx);
+ }
+ });
+ }
+
+ handler.handle(new AnnotationValues<T>(annotationClass, values, node), (JCAnnotation)node.get(), node);
}
}
@@ -68,6 +120,7 @@ public class HandlerLibrary {
messager.printMessage(Diagnostic.Kind.WARNING,
"Duplicate handlers for annotation type: " + container.annotationClass.getName());
}
+ lib.typeLibrary.addType(container.annotationClass.getName());
} catch ( ServiceConfigurationError e ) {
messager.printMessage(Diagnostic.Kind.WARNING,
"Can't load Lombok annotation handler for javac: " + e);
@@ -75,144 +128,26 @@ public class HandlerLibrary {
}
}
- public void handleAnnotation(JavacNode node, TypeElement annotationType) {
- AnnotationHandlerContainer<?> container = annotationHandlers.get(annotationType.getQualifiedName().toString());
- if ( container == null ) return;
- try {
- container.handle(node, createAnnotation(container.annotationClass, annotationType.getQualifiedName(), node));
- } catch ( AnnotationValueDecodeFail e ) {
- node.addError(e.getMessage(), e.mirror, e.value);
- }
- }
-
- private Object createAnnotation(Class<? extends Annotation> target, Name annotationName, JavacNode node)
- throws AnnotationValueDecodeFail {
- AnnotationMirror mirror = fetchMirror(annotationName, node);
- if ( mirror == null ) throw new AssertionError("This can't be.");
-
- InvocationHandler invocations = new AnnotationMirrorInvocationHandler(target, mirror);
- return Proxy.newProxyInstance(target.getClassLoader(), new Class[] { target }, invocations);
- }
-
- private static class AnnotationValueDecodeFail extends Exception {
- private static final long serialVersionUID = 1L;
-
- AnnotationMirror mirror;
- AnnotationValue value;
-
- AnnotationValueDecodeFail(String msg, AnnotationMirror mirror, AnnotationValue value) {
- super(msg);
- this.mirror = mirror;
- this.value = value;
- }
- }
-
- private static class AnnotationMirrorInvocationHandler implements InvocationHandler {
- private final AnnotationMirror mirror;
- private final Map<String, Object> values = new HashMap<String, Object>();
-
- AnnotationMirrorInvocationHandler(Class<?> target, AnnotationMirror mirror) throws AnnotationValueDecodeFail {
- this.mirror = mirror;
-
- for ( Method m : target.getDeclaredMethods() ) {
- if ( !Modifier.isPublic(m.getModifiers()) ) continue;
- values.put(m.getName(), decode(m));
- }
- }
-
- private Object decode(Method m) throws AnnotationValueDecodeFail {
- for ( Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry :
- mirror.getElementValues().entrySet() ) {
-
- if ( entry.getKey().getSimpleName().contentEquals(m.getName()) ) {
- AnnotationValue value = entry.getValue();
- return convert(m.getReturnType(), mirror, value, value.getValue());
- }
- }
+ public void handleAnnotation(JCCompilationUnit unit, JavacAST.Node node, JCAnnotation annotation) {
+ TypeResolver resolver = new TypeResolver(typeLibrary, node.getPackageDeclaration(), node.getImportStatements());
+ String rawType = annotation.annotationType.toString();
+ for ( String fqn : resolver.findTypeMatches(node, rawType) ) {
+ AnnotationHandlerContainer<?> container = annotationHandlers.get(fqn);
+ if ( container == null ) continue;
- return m.getDefaultValue();
- }
-
- @Override public Object invoke(Object proxy, Method method, Object[] args) {
- return values.get(method.getName());
- }
-
- private Object convert(Class<?> expected, AnnotationMirror mirror, AnnotationValue value, Object v) throws AnnotationValueDecodeFail {
- if ( expected == int.class ) {
- if ( v instanceof Number ) return ((Number)v).intValue();
- else throw new AnnotationValueDecodeFail("Expected a numeric value here", mirror, value);
- } else if ( expected == long.class ) {
- if ( v instanceof Number ) return ((Number)v).longValue();
- else throw new AnnotationValueDecodeFail("Expected a numeric value here", mirror, value);
- } else if ( expected == short.class ) {
- if ( v instanceof Number ) return ((Number)v).shortValue();
- else throw new AnnotationValueDecodeFail("Expected a numeric value here", mirror, value);
- } else if ( expected == byte.class ) {
- if ( v instanceof Number ) return ((Number)v).byteValue();
- else throw new AnnotationValueDecodeFail("Expected a numeric value here", mirror, value);
- } else if ( expected == double.class ) {
- if ( v instanceof Number ) return ((Number)v).doubleValue();
- else throw new AnnotationValueDecodeFail("Expected a numeric value here", mirror, value);
- } else if ( expected == float.class ) {
- if ( v instanceof Number ) return ((Number)v).floatValue();
- else throw new AnnotationValueDecodeFail("Expected a numeric value here", mirror, value);
- } else if ( expected == char.class ) {
- if ( v instanceof Character ) return v;
- else throw new AnnotationValueDecodeFail("Expected a character here", mirror, value);
- } else if ( expected == boolean.class ) {
- if ( v instanceof Boolean ) return v;
- else throw new AnnotationValueDecodeFail("Expected a boolean here", mirror, value);
- } else if ( expected == String.class ) {
- if ( v instanceof String ) return v;
- else throw new AnnotationValueDecodeFail("Expected a String here", mirror, value);
- } else if ( expected == Class.class ) {
- if ( v instanceof TypeMirror ) {
- try {
- return Class.forName(v.toString());
- } catch ( ClassNotFoundException e ) {
- throw new AnnotationValueDecodeFail(
- "I can't find this class. Lombok only works well with types in the core java libraries.",
- mirror, value);
- }
- } else throw new AnnotationValueDecodeFail("Expected a class literal here", mirror, value);
- } else if ( Enum.class.isAssignableFrom(expected) ) {
- if ( v instanceof VariableElement ) {
- String n = ((VariableElement)v).getSimpleName().toString();
- @SuppressWarnings("unchecked")
- Object enumVal = Enum.valueOf((Class<? extends Enum>)expected, n);
- return enumVal;
- } else throw new AnnotationValueDecodeFail("Expected an enum value here", mirror, value);
- } else if ( expected.isArray() ) {
- if ( v instanceof Collection<?> ) {
- List<Object> convertedValues = new ArrayList<Object>();
- Class<?> componentType = expected.getComponentType();
- for ( Object innerV : (Collection<?>)v ) {
- convertedValues.add(convert(componentType, mirror, value, innerV));
- }
-
- Object array = Array.newInstance(componentType, convertedValues.size());
- int pos = 0;
- for ( Object converted : convertedValues ) Array.set(array, pos++, converted);
- return array;
- } else throw new AnnotationValueDecodeFail("Expected an array value here", mirror, value);
-// Collection<AnnotationValue> result = (Collection<AnnotationValue>)entry.getValue().getValue();
-// return result;
- } else {
- throw new AssertionError("We didn't know this is even a legal annotation type: " + expected);
+ try {
+ container.handle(node);
+ } catch ( AnnotationValueDecodeFail fail ) {
+ fail.owner.setError(fail.getMessage(), fail.idx);
+ } catch ( Throwable t ) {
+ t.printStackTrace();
+// Eclipse.error(String.format("Lombok annotation handler %s failed", container.handler.getClass()), t);
+ //TODO
}
}
}
- private AnnotationMirror fetchMirror(Name lookingFor, JavacNode node) {
- for ( AnnotationMirror mirror : node.getJavacAST().getAnnotationMirrors() ) {
- if ( !lookingFor.contentEquals(
- ((TypeElement)(mirror.getAnnotationType()).asElement()).getQualifiedName()) ) continue;
- return mirror;
- }
- return null;
- }
-
- public void handleType(TypeElement typeElement) {
+ public void handleAST(JavacAST ast) {
//Later!
}
diff --git a/src/lombok/javac/JavacAST.java b/src/lombok/javac/JavacAST.java
new file mode 100644
index 00000000..f56477fb
--- /dev/null
+++ b/src/lombok/javac/JavacAST.java
@@ -0,0 +1,329 @@
+package lombok.javac;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.annotation.processing.Messager;
+
+import lombok.core.AST;
+
+import com.sun.source.util.Trees;
+import com.sun.tools.javac.processing.JavacProcessingEnvironment;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.TreeMaker;
+import com.sun.tools.javac.tree.JCTree.JCAnnotation;
+import com.sun.tools.javac.tree.JCTree.JCBlock;
+import com.sun.tools.javac.tree.JCTree.JCClassDecl;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.tree.JCTree.JCExpression;
+import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
+import com.sun.tools.javac.tree.JCTree.JCImport;
+import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.tree.JCTree.JCStatement;
+import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
+import com.sun.tools.javac.util.Name;
+
+public class JavacAST extends AST<JCTree> {
+ private final Trees trees;
+ private final JavacProcessingEnvironment env;
+ private final Messager messager;
+ private final Name.Table nameTable;
+ private final TreeMaker treeMaker;
+
+ public JavacAST(Trees trees, JavacProcessingEnvironment env, JCCompilationUnit top) {
+ super(top.sourcefile == null ? null : top.sourcefile.toString());
+ setTop(buildCompilationUnit(top));
+ this.trees = trees;
+ this.env = env;
+ this.messager = env.getMessager();
+ this.nameTable = Name.Table.instance(env.getContext());
+ this.treeMaker = TreeMaker.instance(env.getContext());
+ }
+
+ @Override public String getPackageDeclaration() {
+ JCCompilationUnit unit = (JCCompilationUnit)top().get();
+ return unit.pid instanceof JCFieldAccess ? unit.pid.toString() : null;
+ }
+
+ @Override public Collection<String> getImportStatements() {
+ List<String> imports = new ArrayList<String>();
+ JCCompilationUnit unit = (JCCompilationUnit)top().get();
+ for ( JCTree def : unit.defs ) {
+ if ( def instanceof JCImport ) {
+ imports.add(((JCImport)def).qualid.toString());
+ }
+ }
+
+ return imports;
+ }
+
+ public void traverse(JavacASTVisitor visitor) {
+ Node current = top();
+ visitor.visitCompilationUnit(current, (JCCompilationUnit)current.get());
+ traverseChildren(visitor, current);
+ visitor.endVisitCompilationUnit(current, (JCCompilationUnit)current.get());
+ }
+
+ private void traverseChildren(JavacASTVisitor visitor, Node node) {
+ for ( Node child : node.down() ) {
+ JCTree n = child.get();
+
+ switch ( child.getKind() ) {
+ case TYPE:
+ visitor.visitType(child, (JCClassDecl)n);
+ traverseChildren(visitor, child);
+ visitor.endVisitType(child, (JCClassDecl)n);
+ break;
+ case FIELD:
+ visitor.visitField(child, (JCVariableDecl)n);
+ traverseChildren(visitor, child);
+ visitor.endVisitField(child, (JCVariableDecl)n);
+ break;
+ case METHOD:
+ visitor.visitMethod(child, (JCMethodDecl)n);
+ traverseChildren(visitor, child);
+ visitor.endVisitMethod(child, (JCMethodDecl)n);
+ break;
+ case INITIALIZER:
+ visitor.visitInitializer(child, (JCBlock)n);
+ traverseChildren(visitor, child);
+ visitor.endVisitInitializer(child, (JCBlock)n);
+ break;
+ case ARGUMENT:
+ JCMethodDecl parent = (JCMethodDecl) child.up().get();
+ visitor.visitMethodArgument(child, (JCVariableDecl)n, parent);
+ traverseChildren(visitor, child);
+ visitor.endVisitMethodArgument(child, (JCVariableDecl)n, parent);
+ break;
+ case LOCAL:
+ visitor.visitLocal(child, (JCVariableDecl)n);
+ traverseChildren(visitor, child);
+ visitor.endVisitLocal(child, (JCVariableDecl)n);
+ break;
+ case STATEMENT:
+ visitor.visitStatement(child, (JCTree)n);
+ traverseChildren(visitor, child);
+ visitor.endVisitStatement(node, (JCTree)n);
+ break;
+ case ANNOTATION:
+ switch ( child.up().getKind() ) {
+ case TYPE:
+ visitor.visitAnnotationOnType((JCClassDecl)child.up().get(), child, (JCAnnotation)n);
+ break;
+ case FIELD:
+ visitor.visitAnnotationOnField((JCVariableDecl)child.up().get(), child, (JCAnnotation)n);
+ break;
+ case METHOD:
+ visitor.visitAnnotationOnMethod((JCMethodDecl)child.up().get(), child, (JCAnnotation)n);
+ break;
+ case ARGUMENT:
+ JCVariableDecl argument = (JCVariableDecl)child.up().get();
+ JCMethodDecl method = (JCMethodDecl)child.up().up().get();
+ visitor.visitAnnotationOnMethodArgument(argument, method, child, (JCAnnotation)n);
+ break;
+ case LOCAL:
+ visitor.visitAnnotationOnLocal((JCVariableDecl)child.up().get(), child, (JCAnnotation)n);
+ break;
+ default:
+ throw new AssertionError("Can't be reached");
+ }
+ break;
+ default:
+ throw new AssertionError("Can't be reached: " + child.getKind());
+ }
+ }
+ }
+
+ @Override public Node top() {
+ return (Node) super.top();
+ }
+
+ @Override public Node get(JCTree astNode) {
+ return (Node) super.get(astNode);
+ }
+
+ public Name toName(String name) {
+ return nameTable.fromString(name);
+ }
+
+ public TreeMaker getTreeMaker() {
+ return treeMaker;
+ }
+
+ private Node buildCompilationUnit(JCCompilationUnit top) {
+ List<Node> childNodes = new ArrayList<Node>();
+ for ( JCTree s : top.defs ) {
+ if ( s instanceof JCClassDecl ) {
+ addIfNotNull(childNodes, buildType((JCClassDecl)s));
+ } // else they are import statements, which we don't care about. Or Skip objects, whatever those are.
+ }
+
+ return new Node(top, childNodes, Kind.COMPILATION_UNIT);
+ }
+
+ private Node buildType(JCClassDecl type) {
+ if ( alreadyHandled(type) ) return null;
+ List<Node> childNodes = new ArrayList<Node>();
+
+ for ( JCTree def : type.defs ) {
+ for ( JCAnnotation annotation : type.mods.annotations ) addIfNotNull(childNodes, buildAnnotation(annotation));
+ /* A def can be:
+ * JCClassDecl for inner types
+ * JCMethodDecl for constructors and methods
+ * JCVariableDecl for fields
+ * JCBlock for (static) initializers
+ */
+ if ( def instanceof JCMethodDecl ) addIfNotNull(childNodes, buildMethod((JCMethodDecl)def));
+ else if ( def instanceof JCClassDecl ) addIfNotNull(childNodes, buildType((JCClassDecl)def));
+ else if ( def instanceof JCVariableDecl ) addIfNotNull(childNodes, buildField((JCVariableDecl)def));
+ else if ( def instanceof JCBlock ) addIfNotNull(childNodes, buildInitializer((JCBlock)def));
+ }
+
+ return putInMap(new Node(type, childNodes, Kind.TYPE));
+ }
+
+ private Node buildField(JCVariableDecl field) {
+ if ( alreadyHandled(field) ) return null;
+ List<Node> childNodes = new ArrayList<Node>();
+ for ( JCAnnotation annotation : field.mods.annotations ) addIfNotNull(childNodes, buildAnnotation(annotation));
+ addIfNotNull(childNodes, buildExpression(field.init));
+ return putInMap(new Node(field, childNodes, Kind.FIELD));
+ }
+
+ private Node buildLocalVar(JCVariableDecl local) {
+ if ( alreadyHandled(local) ) return null;
+ List<Node> childNodes = new ArrayList<Node>();
+ for ( JCAnnotation annotation : local.mods.annotations ) addIfNotNull(childNodes, buildAnnotation(annotation));
+ addIfNotNull(childNodes, buildExpression(local.init));
+ return putInMap(new Node(local, childNodes, Kind.LOCAL));
+ }
+
+ private Node buildInitializer(JCBlock initializer) {
+ if ( alreadyHandled(initializer) ) return null;
+ List<Node> childNodes = new ArrayList<Node>();
+ for ( JCStatement statement: initializer.stats ) addIfNotNull(childNodes, buildStatement(statement));
+ return putInMap(new Node(initializer, childNodes, Kind.INITIALIZER));
+ }
+
+ private Node buildMethod(JCMethodDecl method) {
+ if ( alreadyHandled(method) ) return null;
+ List<Node> childNodes = new ArrayList<Node>();
+ for ( JCAnnotation annotation : method.mods.annotations ) addIfNotNull(childNodes, buildAnnotation(annotation));
+ for ( JCVariableDecl param : method.params ) addIfNotNull(childNodes, buildLocalVar(param));
+ if ( method.body != null && method.body.stats != null )
+ for ( JCStatement statement : method.body.stats ) addIfNotNull(childNodes, buildStatement(statement));
+ return putInMap(new Node(method, childNodes, Kind.METHOD));
+ }
+
+ private Node buildAnnotation(JCAnnotation annotation) {
+ if ( alreadyHandled(annotation) ) return null;
+ return putInMap(new Node(annotation, null, Kind.ANNOTATION));
+ }
+
+ private Node buildExpression(JCExpression expression) {
+ return buildStatementOrExpression(expression);
+ }
+
+ private Node buildStatement(JCStatement statement) {
+ return buildStatementOrExpression(statement);
+ }
+
+ private Node buildStatementOrExpression(JCTree statement) {
+ if ( statement == null || alreadyHandled(statement) ) return null;
+ if ( statement instanceof JCAnnotation ) return null;
+ if ( statement instanceof JCClassDecl ) return buildType((JCClassDecl)statement);
+ if ( statement instanceof JCVariableDecl ) return buildLocalVar((JCVariableDecl)statement);
+
+ //We drill down because LocalDeclarations and TypeDeclarations can occur anywhere, even in, say,
+ //an if block, or even the expression on an assert statement!
+
+ setAsHandled(statement);
+ return drill(statement);
+ }
+
+ private Node drill(JCTree statement) {
+ List<Node> childNodes = new ArrayList<Node>();
+ for ( FieldAccess fa : fieldsOf(statement.getClass()) ) childNodes.addAll(buildWithField(Node.class, statement, fa));
+ return putInMap(new Node(statement, childNodes, Kind.STATEMENT));
+ }
+
+ protected Collection<Class<? extends JCTree>> getStatementTypes() {
+ Collection<Class<? extends JCTree>> collection = new ArrayList<Class<? extends JCTree>>(2);
+ collection.add(JCStatement.class);
+ collection.add(JCExpression.class);
+ return collection;
+ }
+
+ private static void addIfNotNull(Collection<Node> nodes, Node node) {
+ if ( node != null ) nodes.add(node);
+ }
+
+ public class Node extends AST<JCTree>.Node {
+ public Node(JCTree node, Collection<Node> children, Kind kind) {
+ super(node, children, kind);
+ }
+
+ @Override public String getName() {
+ final Name n;
+
+ if ( node instanceof JCClassDecl ) n = ((JCClassDecl)node).name;
+ else if ( node instanceof JCMethodDecl ) n = ((JCMethodDecl)node).name;
+ else if ( node instanceof JCVariableDecl ) n = ((JCVariableDecl)node).name;
+ else n = null;
+
+ return n == null ? null : n.toString();
+ }
+
+ @Override protected boolean calculateIsStructurallySignificant() {
+ if ( node instanceof JCClassDecl ) return true;
+ if ( node instanceof JCMethodDecl ) return true;
+ if ( node instanceof JCVariableDecl ) return true;
+ if ( node instanceof JCCompilationUnit ) return true;
+ return false;
+ }
+
+ public TreeMaker getTreeMaker() {
+ return treeMaker;
+ }
+
+ public Name toName(String name) {
+ return JavacAST.this.toName(name);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node directUp() {
+ return (Node) super.directUp();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node up() {
+ return (Node) super.up();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node top() {
+ return (Node) super.top();
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override public Collection<Node> down() {
+ return (Collection<Node>) children;
+ }
+
+ public void addError(String message) {
+ System.err.println("ERR: " + message);
+ //TODO
+ }
+
+ public void addWarning(String message) {
+ System.err.println("WARN: " + message);
+ //TODO
+ }
+ }
+
+ @Override protected Node buildStatement(Object statement) {
+ return buildStatementOrExpression((JCTree) statement);
+ }
+}
diff --git a/src/lombok/javac/JavacASTAdapter.java b/src/lombok/javac/JavacASTAdapter.java
new file mode 100644
index 00000000..5d678f44
--- /dev/null
+++ b/src/lombok/javac/JavacASTAdapter.java
@@ -0,0 +1,35 @@
+package lombok.javac;
+
+import lombok.javac.JavacAST.Node;
+
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCAnnotation;
+import com.sun.tools.javac.tree.JCTree.JCBlock;
+import com.sun.tools.javac.tree.JCTree.JCClassDecl;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
+
+public class JavacASTAdapter implements JavacASTVisitor {
+ @Override public void visitCompilationUnit(Node top, JCCompilationUnit unit) {}
+ @Override public void endVisitCompilationUnit(Node top, JCCompilationUnit unit) {}
+ @Override public void visitType(Node typeNode, JCClassDecl type) {}
+ @Override public void visitAnnotationOnType(JCClassDecl type, Node annotationNode, JCAnnotation annotation) {}
+ @Override public void endVisitType(Node typeNode, JCClassDecl type) {}
+ @Override public void visitField(Node fieldNode, JCVariableDecl field) {}
+ @Override public void visitAnnotationOnField(JCVariableDecl field, Node annotationNode, JCAnnotation annotation) {}
+ @Override public void endVisitField(Node fieldNode, JCVariableDecl field) {}
+ @Override public void visitInitializer(Node initializerNode, JCBlock initializer) {}
+ @Override public void endVisitInitializer(Node initializerNode, JCBlock initializer) {}
+ @Override public void visitMethod(Node methodNode, JCMethodDecl method) {}
+ @Override public void visitAnnotationOnMethod(JCMethodDecl method, Node annotationNode, JCAnnotation annotation) {}
+ @Override public void endVisitMethod(Node methodNode, JCMethodDecl method) {}
+ @Override public void visitMethodArgument(Node argumentNode, JCVariableDecl argument, JCMethodDecl method) {}
+ @Override public void visitAnnotationOnMethodArgument(JCVariableDecl argument, JCMethodDecl method, Node annotationNode, JCAnnotation annotation) {}
+ @Override public void endVisitMethodArgument(Node argumentNode, JCVariableDecl argument, JCMethodDecl method) {}
+ @Override public void visitLocal(Node localNode, JCVariableDecl local) {}
+ @Override public void visitAnnotationOnLocal(JCVariableDecl local, Node annotationNode, JCAnnotation annotation) {}
+ @Override public void endVisitLocal(Node localNode, JCVariableDecl local) {}
+ @Override public void visitStatement(Node statementNode, JCTree statement) {}
+ @Override public void endVisitStatement(Node statementNode, JCTree statement) {}
+}
diff --git a/src/lombok/javac/JavacASTVisitor.java b/src/lombok/javac/JavacASTVisitor.java
new file mode 100644
index 00000000..daeb6b80
--- /dev/null
+++ b/src/lombok/javac/JavacASTVisitor.java
@@ -0,0 +1,182 @@
+package lombok.javac;
+
+import lombok.javac.JavacAST.Node;
+
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCAnnotation;
+import com.sun.tools.javac.tree.JCTree.JCBlock;
+import com.sun.tools.javac.tree.JCTree.JCClassDecl;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
+
+public interface JavacASTVisitor {
+ /**
+ * Called at the very beginning and end.
+ */
+ void visitCompilationUnit(Node top, JCCompilationUnit unit);
+ void endVisitCompilationUnit(Node top, JCCompilationUnit unit);
+
+ /**
+ * Called when visiting a type (a class, interface, annotation, enum, etcetera).
+ */
+ void visitType(Node typeNode, JCClassDecl type);
+ void visitAnnotationOnType(JCClassDecl type, Node annotationNode, JCAnnotation annotation);
+ void endVisitType(Node typeNode, JCClassDecl type);
+
+ /**
+ * Called when visiting a field of a class.
+ */
+ void visitField(Node fieldNode, JCVariableDecl field);
+ void visitAnnotationOnField(JCVariableDecl field, Node annotationNode, JCAnnotation annotation);
+ void endVisitField(Node fieldNode, JCVariableDecl field);
+
+ /**
+ * Called for static and instance initializers. You can tell the difference via the isStatic() method.
+ */
+ void visitInitializer(Node initializerNode, JCBlock initializer);
+ void endVisitInitializer(Node initializerNode, JCBlock initializer);
+
+ /**
+ * Called for both methods and constructors.
+ */
+ void visitMethod(Node methodNode, JCMethodDecl method);
+ void visitAnnotationOnMethod(JCMethodDecl method, Node annotationNode, JCAnnotation annotation);
+ void endVisitMethod(Node methodNode, JCMethodDecl method);
+
+ /**
+ * Visits a method argument.
+ */
+ void visitMethodArgument(Node argumentNode, JCVariableDecl argument, JCMethodDecl method);
+ void visitAnnotationOnMethodArgument(JCVariableDecl argument, JCMethodDecl method, Node annotationNode, JCAnnotation annotation);
+ void endVisitMethodArgument(Node argumentNode, JCVariableDecl argument, JCMethodDecl method);
+
+ /**
+ * Visits a local declaration - that is, something like 'int x = 10;' on the method level. Also called
+ * for method parameters.
+ */
+ void visitLocal(Node localNode, JCVariableDecl local);
+ void visitAnnotationOnLocal(JCVariableDecl local, Node annotationNode, JCAnnotation annotation);
+ void endVisitLocal(Node localNode, JCVariableDecl local);
+
+ /**
+ * Visits a statement that isn't any of the other visit methods (e.g. JCClassDecl).
+ * The statement object is guaranteed to be either a JCStatement or a JCExpression.
+ */
+ void visitStatement(Node statementNode, JCTree statement);
+ void endVisitStatement(Node statementNode, JCTree statement);
+
+ public static class JavacASTPrinter implements JavacASTVisitor {
+ int indent = 0;
+ private void print(String text, Object... params) {
+ StringBuilder sb = new StringBuilder();
+ for ( int i = 0 ; i < indent ; i++ ) sb.append(" ");
+ System.out.printf(sb.append(text).append('\n').toString(), params);
+ }
+
+ @Override public void visitCompilationUnit(Node Node, JCCompilationUnit unit) {
+ System.out.println("---------------------------------------------------------");
+
+ print("<CU %s>", Node.getFileName());
+ indent++;
+ }
+
+ @Override public void endVisitCompilationUnit(Node node, JCCompilationUnit unit) {
+ indent--;
+ print("</CUD>");
+ }
+
+ @Override public void visitType(Node node, JCClassDecl type) {
+ print("<TYPE %s>", type.name);
+ indent++;
+ }
+
+ @Override public void visitAnnotationOnType(JCClassDecl type, Node node, JCAnnotation annotation) {
+ print("<ANNOTATION: %s />", annotation);
+ }
+
+ @Override public void endVisitType(Node node, JCClassDecl type) {
+ indent--;
+ print("</TYPE %s>", type.name);
+ }
+
+ @Override public void visitInitializer(Node node, JCBlock initializer) {
+ print("<%s INITIALIZER>",
+ initializer.isStatic() ? "static" : "instance");
+ indent++;
+ }
+
+ @Override public void endVisitInitializer(Node node, JCBlock initializer) {
+ indent--;
+ print("</%s INITIALIZER>", initializer.isStatic() ? "static" : "instance");
+ }
+
+ @Override public void visitField(Node node, JCVariableDecl field) {
+ print("<FIELD %s %s>", field.type, field.name);
+ indent++;
+ }
+
+ @Override public void visitAnnotationOnField(JCVariableDecl field, Node node, JCAnnotation annotation) {
+ print("<ANNOTATION: %s />", annotation);
+ }
+
+ @Override public void endVisitField(Node node, JCVariableDecl field) {
+ indent--;
+ print("</FIELD %s %s>", field.type, field.name);
+ }
+
+ @Override public void visitMethod(Node node, JCMethodDecl method) {
+ String type = method.name.contentEquals("<init>") ? "CONSTRUCTOR" : "METHOD";
+ print("<%s %s>", type, method.name);
+ indent++;
+ }
+
+ @Override public void visitAnnotationOnMethod(JCMethodDecl method, Node node, JCAnnotation annotation) {
+ print("<ANNOTATION: %s />", annotation);
+ }
+
+ @Override public void endVisitMethod(Node node, JCMethodDecl method) {
+ String type = method.name.contentEquals("<init>") ? "CONSTRUCTOR" : "METHOD";
+ indent--;
+ print("</%s %s>", type, method.name);
+ }
+
+ @Override public void visitMethodArgument(Node node, JCVariableDecl arg, JCMethodDecl method) {
+ print("<METHOARG %s %s = %s>", arg.type, arg.name);
+ indent++;
+ }
+
+ @Override public void visitAnnotationOnMethodArgument(JCVariableDecl arg, JCMethodDecl method, Node nodeAnnotation, JCAnnotation annotation) {
+ print("<ANNOTATION: %s />", annotation);
+ }
+
+ @Override public void endVisitMethodArgument(Node node, JCVariableDecl arg, JCMethodDecl method) {
+ indent--;
+ print("</METHODARG %s %s>", arg.type, arg.name);
+ }
+
+ @Override public void visitLocal(Node node, JCVariableDecl local) {
+ print("<LOCAL %s %s>", local.type, local.name);
+ indent++;
+ }
+
+ @Override public void visitAnnotationOnLocal(JCVariableDecl local, Node node, JCAnnotation annotation) {
+ print("<ANNOTATION: %s />", annotation);
+ }
+
+ @Override public void endVisitLocal(Node node, JCVariableDecl local) {
+ indent--;
+ print("</LOCAL %s %s>", local.type, local.name);
+ }
+
+ @Override public void visitStatement(Node node, JCTree statement) {
+ print("<%s>", statement.getClass());
+ indent++;
+ }
+
+ @Override public void endVisitStatement(Node node, JCTree statement) {
+ indent--;
+ print("</%s>", statement.getClass());
+ }
+ }
+}
diff --git a/src/lombok/javac/JavacAnnotationHandler.java b/src/lombok/javac/JavacAnnotationHandler.java
index 67542a12..ce3c5fd7 100644
--- a/src/lombok/javac/JavacAnnotationHandler.java
+++ b/src/lombok/javac/JavacAnnotationHandler.java
@@ -2,6 +2,10 @@ package lombok.javac;
import java.lang.annotation.Annotation;
+import lombok.core.AnnotationValues;
+
+import com.sun.tools.javac.tree.JCTree.JCAnnotation;
+
public interface JavacAnnotationHandler<T extends Annotation> {
- void handle(JavacNode annotedElement, T annotation);
+ void handle(AnnotationValues<T> annotation, JCAnnotation ast, JavacAST.Node annotedElement);
}
diff --git a/src/lombok/javac/JavacNode.java b/src/lombok/javac/JavacNode.java
deleted file mode 100644
index 2e65e1d1..00000000
--- a/src/lombok/javac/JavacNode.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package lombok.javac;
-
-import javax.annotation.processing.Messager;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-import javax.tools.Diagnostic;
-
-import com.sun.source.util.Trees;
-import com.sun.tools.javac.processing.JavacProcessingEnvironment;
-import com.sun.tools.javac.tree.TreeMaker;
-import com.sun.tools.javac.tree.JCTree.JCClassDecl;
-import com.sun.tools.javac.util.Name;
-
-public class JavacNode {
- private final Element node;
- private final Messager messager;
- private final JavacProcessingEnvironment env;
- private final Trees trees;
-
- public JavacNode(Trees trees, JavacProcessingEnvironment env, Element node) {
- this.trees = trees;
- this.env = env;
- this.node = node;
- this.messager = env.getMessager();
- }
-
- public Element getJavacAST() {
- return node;
- }
-
- public JCClassDecl getEnclosingType() {
- Element parent = node;
- while ( !(parent instanceof TypeElement) ) parent = node.getEnclosingElement();
- TypeElement classElement = (TypeElement)parent;
- return (JCClassDecl)trees.getTree(classElement);
- }
-
- public Name.Table createNameTable() {
- return Name.Table.instance(env.getContext());
- }
-
- public TreeMaker createTreeMaker() {
- return TreeMaker.instance(env.getContext());
- }
-
- public void addError(String message) {
- this.messager.printMessage(Diagnostic.Kind.ERROR, message, node);
- }
-
- public void addError(String message, AnnotationMirror mirror, AnnotationValue value) {
- this.messager.printMessage(Diagnostic.Kind.ERROR, message, node, mirror, value);
- }
-
- public void addWarning(String message) {
- this.messager.printMessage(Diagnostic.Kind.WARNING, message, node);
- }
-
- public void addWarning(String message, AnnotationMirror mirror, AnnotationValue value) {
- this.messager.printMessage(Diagnostic.Kind.WARNING, message, node, mirror, value);
- }
-}
diff --git a/src/lombok/javac/apt/Processor.java b/src/lombok/javac/apt/Processor.java
index 864ef52c..2780ce16 100644
--- a/src/lombok/javac/apt/Processor.java
+++ b/src/lombok/javac/apt/Processor.java
@@ -1,5 +1,8 @@
package lombok.javac.apt;
+import java.util.ArrayList;
+import java.util.IdentityHashMap;
+import java.util.List;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
@@ -12,10 +15,17 @@ import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import lombok.javac.HandlerLibrary;
-import lombok.javac.JavacNode;
+import lombok.javac.JavacAST;
+import lombok.javac.JavacASTAdapter;
+import lombok.javac.JavacAST.Node;
import com.sun.source.util.Trees;
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
+import com.sun.tools.javac.tree.JCTree.JCAnnotation;
+import com.sun.tools.javac.tree.JCTree.JCClassDecl;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
@SupportedAnnotationTypes("*")
@@ -39,23 +49,53 @@ public class Processor extends AbstractProcessor {
if ( processingEnv == null ) return false;
- for ( TypeElement annotationType : annotations ) {
- if ( !handlers.hasHandlerFor(annotationType) ) continue;
- for ( Element element : roundEnv.getElementsAnnotatedWith(annotationType) ) {
- handlers.handleAnnotation(createNode(element), annotationType);
- }
+ IdentityHashMap<JCCompilationUnit, Void> units = new IdentityHashMap<JCCompilationUnit, Void>();
+ for ( Element element : roundEnv.getRootElements() ) units.put(toUnit(element), null);
+
+ List<JavacAST> asts = new ArrayList<JavacAST>();
+
+ for ( JCCompilationUnit unit : units.keySet() ) asts.add(new JavacAST(trees, processingEnv, unit));
+
+ for ( JavacAST ast : asts ) {
+ ast.traverse(new AnnotationVisitor());
+ handlers.handleAST(ast);
+ }
+ return false;
+ }
+
+ private class AnnotationVisitor extends JavacASTAdapter {
+ @Override public void visitAnnotationOnType(JCClassDecl type, Node annotationNode, JCAnnotation annotation) {
+ if ( annotationNode.isHandled() ) return;
+ handlers.handleAnnotation((JCCompilationUnit) annotationNode.top().get(), annotationNode, annotation);
+ annotationNode.setHandled();
}
- for ( Element element : roundEnv.getRootElements() ) {
- if ( element instanceof TypeElement ) {
- handlers.handleType((TypeElement)element);
- }
+ @Override public void visitAnnotationOnField(JCVariableDecl field, Node annotationNode, JCAnnotation annotation) {
+ if ( annotationNode.isHandled() ) return;
+ handlers.handleAnnotation((JCCompilationUnit) annotationNode.top().get(), annotationNode, annotation);
+ annotationNode.setHandled();
}
- return false;
+ @Override public void visitAnnotationOnMethod(JCMethodDecl method, Node annotationNode, JCAnnotation annotation) {
+ if ( annotationNode.isHandled() ) return;
+ handlers.handleAnnotation((JCCompilationUnit) annotationNode.top().get(), annotationNode, annotation);
+ annotationNode.setHandled();
+ }
+
+ @Override public void visitAnnotationOnMethodArgument(JCVariableDecl argument, JCMethodDecl method, Node annotationNode, JCAnnotation annotation) {
+ if ( annotationNode.isHandled() ) return;
+ handlers.handleAnnotation((JCCompilationUnit) annotationNode.top().get(), annotationNode, annotation);
+ annotationNode.setHandled();
+ }
+
+ @Override public void visitAnnotationOnLocal(JCVariableDecl local, Node annotationNode, JCAnnotation annotation) {
+ if ( annotationNode.isHandled() ) return;
+ handlers.handleAnnotation((JCCompilationUnit) annotationNode.top().get(), annotationNode, annotation);
+ annotationNode.setHandled();
+ }
}
- private JavacNode createNode(Element element) {
- return new JavacNode(trees, processingEnv, element);
+ private JCCompilationUnit toUnit(Element element) {
+ return (JCCompilationUnit) trees.getPath(element).getCompilationUnit();
}
}
diff --git a/src/lombok/javac/handlers/HandleGetter_javac.java b/src/lombok/javac/handlers/HandleGetter_javac.java
index 7863a097..8501b65f 100644
--- a/src/lombok/javac/handlers/HandleGetter_javac.java
+++ b/src/lombok/javac/handlers/HandleGetter_javac.java
@@ -2,17 +2,15 @@ package lombok.javac.handlers;
import static lombok.javac.handlers.PKG.*;
-import javax.lang.model.element.Element;
-
import lombok.Getter;
+import lombok.core.AnnotationValues;
+import lombok.core.AST.Kind;
import lombok.javac.JavacAnnotationHandler;
-import lombok.javac.JavacNode;
+import lombok.javac.JavacAST;
import org.mangosdk.spi.ProviderFor;
import com.sun.source.tree.MethodTree;
-import com.sun.tools.javac.code.Symbol;
-import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
@@ -27,26 +25,29 @@ import com.sun.tools.javac.util.Name;
@ProviderFor(JavacAnnotationHandler.class)
public class HandleGetter_javac implements JavacAnnotationHandler<Getter> {
- @Override public void handle(JavacNode node, Getter getter) {
- if ( !node.getJavacAST().getKind().isField() ) {
+ @Override public void handle(AnnotationValues<Getter> annotation, JCAnnotation ast, JavacAST.Node node) {
+ if ( node.up().getKind() != Kind.FIELD ) {
node.addError("@Getter is only supported on a field.");
return;
}
- JCClassDecl javacClassTree = node.getEnclosingType();
+ Getter getter = annotation.getInstance();
+
+ JCClassDecl javacClassTree = (JCClassDecl) node.up().up().get();
int access = toJavacModifier(getter.value());
- MethodTree getterMethod = createGetter(access, node.getJavacAST(), node.createTreeMaker(), node.createNameTable());
+ MethodTree getterMethod = createGetter(access, node.up(), node.getTreeMaker());
javacClassTree.defs = javacClassTree.defs.append((JCTree)getterMethod);
}
- private MethodTree createGetter(int access, Element field, TreeMaker treeMaker, Name.Table nameTable) {
- JCStatement returnStatement = treeMaker.Return(treeMaker.Ident((Symbol)field));
+ private MethodTree createGetter(int access, JavacAST.Node field, TreeMaker treeMaker) {
+ JCVariableDecl fieldNode = (JCVariableDecl) field.get();
+ JCStatement returnStatement = treeMaker.Return(treeMaker.Ident(fieldNode.getName()));
JCBlock methodBody = treeMaker.Block(0, List.of(returnStatement));
- Name methodName = Name.fromString(nameTable, toGetterName(field));
- JCExpression methodType = treeMaker.Type((Type)field.asType());
+ Name methodName = field.toName(toGetterName((JCVariableDecl)field.get()));
+ JCExpression methodType = fieldNode.type != null ? treeMaker.Type(fieldNode.type) : fieldNode.vartype;
List<JCTypeParameter> methodGenericParams = List.nil();
List<JCVariableDecl> parameters = List.nil();
diff --git a/src/lombok/javac/handlers/PKG.java b/src/lombok/javac/handlers/PKG.java
index 4622c3ee..9ba3765a 100644
--- a/src/lombok/javac/handlers/PKG.java
+++ b/src/lombok/javac/handlers/PKG.java
@@ -2,17 +2,16 @@ package lombok.javac.handlers;
import java.lang.reflect.Modifier;
-import javax.lang.model.element.Element;
-import javax.lang.model.type.TypeKind;
+import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import lombok.AccessLevel;
import lombok.core.TransformationsUtil;
class PKG {
- static String toGetterName(Element field) {
- CharSequence fieldName = field.getSimpleName();
+ static String toGetterName(JCVariableDecl field) {
+ CharSequence fieldName = field.name;
- boolean isBoolean = field.asType().getKind() == TypeKind.BOOLEAN;
+ boolean isBoolean = field.vartype.toString().equals("boolean");
return TransformationsUtil.toGetterName(fieldName, isBoolean);
}