Added the SetterHandler for javac. Also added a way to get the SymbolTable on a JavacAST.Node, because you need it to e.g. access constant types like 'void'.

This commit is contained in:
Reinier Zwitserloot committed 2009-06-17 21:27:27 +02:00
1 parent 7c65e0fdff
commit 1929a28c9d
6 files changed
+114 -10

No files matched your search

+12
View File
@@ -0,0 +1,12 @@
package lombok;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.SOURCE)
public @interface Setter {
AccessLevel value() default lombok.AccessLevel.PUBLIC;
}
+12 -4
View File
@@ -5,14 +5,22 @@ public class TransformationsUtil {
public static String toGetterName(CharSequence fieldName, boolean isBoolean) {
final String prefix = isBoolean ? "is" : "get";
final String suffix;
if ( fieldName.length() == 0 ) return prefix;
char first = fieldName.charAt(0);
return buildName(prefix, fieldName.toString());
}
private static String buildName(String prefix, String suffix) {
if ( suffix.length() == 0 ) return prefix;
char first = suffix.charAt(0);
if ( Character.isLowerCase(first) )
suffix = String.format("%s%s", Character.toTitleCase(first), fieldName.subSequence(1, fieldName.length()));
else suffix = fieldName.toString();
suffix = String.format("%s%s", Character.toTitleCase(first), suffix.subSequence(1, suffix.length()));
return String.format("%s%s", prefix, suffix);
}
public static String toSetterName(CharSequence fieldName) {
return buildName("set", fieldName.toString());
}
}
+11
View File
@@ -12,6 +12,7 @@ import javax.tools.JavaFileObject;
import lombok.core.AST;
import com.sun.source.util.Trees;
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.TreeMaker;
@@ -33,6 +34,7 @@ public class JavacAST extends AST<JCTree> {
private final Messager messager;
private final Name.Table nameTable;
private final TreeMaker treeMaker;
private final Symtab symtab;
private final Log log;
public JavacAST(Trees trees, JavacProcessingEnvironment env, JCCompilationUnit top) {
@@ -42,6 +44,7 @@ public class JavacAST extends AST<JCTree> {
this.log = Log.instance(env.getContext());
this.nameTable = Name.Table.instance(env.getContext());
this.treeMaker = TreeMaker.instance(env.getContext());
this.symtab = Symtab.instance(env.getContext());
}
@Override public String getPackageDeclaration() {
@@ -87,6 +90,10 @@ public class JavacAST extends AST<JCTree> {
return treeMaker;
}
public Symtab getSymbolTable() {
return symtab;
}
private Node buildCompilationUnit(JCCompilationUnit top) {
List<Node> childNodes = new ArrayList<Node>();
for ( JCTree s : top.defs ) {
@@ -294,6 +301,10 @@ public class JavacAST extends AST<JCTree> {
return treeMaker;
}
public Symtab getSymbolTable() {
return symtab;
}
public Name toName(String name) {
return JavacAST.this.toName(name);
}
+6 -6
View File
@@ -10,13 +10,12 @@ import lombok.javac.JavacAST;
import org.mangosdk.spi.ProviderFor;
import com.sun.source.tree.MethodTree;
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.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
import com.sun.tools.javac.tree.JCTree.JCStatement;
import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
@@ -26,6 +25,7 @@ import com.sun.tools.javac.util.Name;
@ProviderFor(JavacAnnotationHandler.class)
public class HandleGetter implements JavacAnnotationHandler<Getter> {
@Override public void handle(AnnotationValues<Getter> annotation, JCAnnotation ast, JavacAST.Node annotationNode) {
//TODO Check for existence of the getter and skip it (+ warn) if it's already there.
if ( annotationNode.up().getKind() != Kind.FIELD ) {
annotationNode.addError("@Getter is only supported on a field.");
return;
@@ -37,16 +37,16 @@ public class HandleGetter implements JavacAnnotationHandler<Getter> {
int access = toJavacModifier(getter.value());
MethodTree getterMethod = createGetter(access, annotationNode.up(), annotationNode.getTreeMaker());
javacClassTree.defs = javacClassTree.defs.append((JCTree)getterMethod);
JCMethodDecl getterMethod = createGetter(access, annotationNode.up(), annotationNode.getTreeMaker());
javacClassTree.defs = javacClassTree.defs.append(getterMethod);
}
private MethodTree createGetter(int access, JavacAST.Node field, TreeMaker treeMaker) {
private JCMethodDecl 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 = field.toName(toGetterName((JCVariableDecl)field.get()));
Name methodName = field.toName(toGetterName(fieldNode));
JCExpression methodType = fieldNode.type != null ? treeMaker.Type(fieldNode.type) : fieldNode.vartype;
List<JCTypeParameter> methodGenericParams = List.nil();
@@ -0,0 +1,67 @@
package lombok.javac.handlers;
import static lombok.javac.handlers.PKG.toJavacModifier;
import static lombok.javac.handlers.PKG.toSetterName;
import org.mangosdk.spi.ProviderFor;
import lombok.Setter;
import lombok.core.AnnotationValues;
import lombok.core.AST.Kind;
import lombok.javac.JavacAST;
import lombok.javac.JavacAnnotationHandler;
import lombok.javac.JavacAST.Node;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCAssign;
import com.sun.tools.javac.tree.JCTree.JCBlock;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
import com.sun.tools.javac.tree.JCTree.JCStatement;
import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Name;
@ProviderFor(JavacAnnotationHandler.class)
public class HandleSetter implements JavacAnnotationHandler<Setter> {
@Override public void handle(AnnotationValues<Setter> annotation, JCAnnotation ast, Node annotationNode) {
//TODO Check for existence of the setter and skip it (+ warn) if it's already there.
if ( annotationNode.up().getKind() != Kind.FIELD ) {
annotationNode.addError("@Setter is only supported on a field.");
return;
}
Setter setter = annotation.getInstance();
JCClassDecl javacClassTree = (JCClassDecl) annotationNode.up().up().get();
int access = toJavacModifier(setter.value());
JCMethodDecl setterMethod = createSetter(access, annotationNode.up(), annotationNode.getTreeMaker());
javacClassTree.defs = javacClassTree.defs.append(setterMethod);
}
private JCMethodDecl createSetter(int access, JavacAST.Node field, TreeMaker treeMaker) {
JCVariableDecl fieldDecl = (JCVariableDecl) field.get();
JCFieldAccess thisX = treeMaker.Select(treeMaker.Ident(field.toName("this")), fieldDecl.name);
JCAssign assign = treeMaker.Assign(thisX, treeMaker.Ident(fieldDecl.name));
JCBlock methodBody = treeMaker.Block(0, List.<JCStatement>of(treeMaker.Exec(assign)));
Name methodName = field.toName(toSetterName(fieldDecl));
JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(0, List.<JCAnnotation>nil()), fieldDecl.name, fieldDecl.vartype, null);
JCExpression methodType = treeMaker.Type(field.getSymbolTable().voidType);
List<JCTypeParameter> methodGenericParams = List.nil();
List<JCVariableDecl> parameters = List.of(param);
List<JCExpression> throwsClauses = List.nil();
JCExpression annotationMethodDefaultValue = null;
return treeMaker.MethodDef(treeMaker.Modifiers(access, List.<JCAnnotation>nil()), methodName, methodType,
methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue);
}
}
+6
View File
@@ -16,6 +16,12 @@ class PKG {
return TransformationsUtil.toGetterName(fieldName, isBoolean);
}
static String toSetterName(JCVariableDecl field) {
CharSequence fieldName = field.name;
return TransformationsUtil.toSetterName(fieldName);
}
static int toJavacModifier(AccessLevel accessLevel) {
switch ( accessLevel ) {
case MODULE: