use of lombok.javac.JavacNode in project lombok by rzwitserloot.
the class HandleSynchronized method handle.
@Override
public void handle(AnnotationValues<Synchronized> annotation, JCAnnotation ast, JavacNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.SYNCHRONIZED_FLAG_USAGE, "@Synchronized");
if (inNetbeansEditor(annotationNode))
return;
deleteAnnotationIfNeccessary(annotationNode, Synchronized.class);
JavacNode methodNode = annotationNode.up();
if (methodNode == null || methodNode.getKind() != Kind.METHOD || !(methodNode.get() instanceof JCMethodDecl)) {
annotationNode.addError("@Synchronized is legal only on methods.");
return;
}
JCMethodDecl method = (JCMethodDecl) methodNode.get();
if ((method.mods.flags & Flags.ABSTRACT) != 0) {
annotationNode.addError("@Synchronized is legal only on concrete methods.");
return;
}
boolean isStatic = (method.mods.flags & Flags.STATIC) != 0;
String lockName = annotation.getInstance().value();
boolean autoMake = false;
if (lockName.length() == 0) {
autoMake = true;
lockName = isStatic ? STATIC_LOCK_NAME : INSTANCE_LOCK_NAME;
}
JavacTreeMaker maker = methodNode.getTreeMaker().at(ast.pos);
Context context = methodNode.getContext();
if (fieldExists(lockName, methodNode) == MemberExistsResult.NOT_EXISTS) {
if (!autoMake) {
annotationNode.addError("The field " + lockName + " does not exist.");
return;
}
JCExpression objectType = genJavaLangTypeRef(methodNode, ast.pos, "Object");
//We use 'new Object[0];' because unlike 'new Object();', empty arrays *ARE* serializable!
JCNewArray newObjectArray = maker.NewArray(genJavaLangTypeRef(methodNode, ast.pos, "Object"), List.<JCExpression>of(maker.Literal(CTC_INT, 0)), null);
JCVariableDecl fieldDecl = recursiveSetGeneratedBy(maker.VarDef(maker.Modifiers(Flags.PRIVATE | Flags.FINAL | (isStatic ? Flags.STATIC : 0)), methodNode.toName(lockName), objectType, newObjectArray), ast, context);
injectFieldAndMarkGenerated(methodNode.up(), fieldDecl);
}
if (method.body == null)
return;
JCExpression lockNode;
if (isStatic) {
lockNode = chainDots(methodNode, ast.pos, methodNode.up().getName(), lockName);
} else {
lockNode = maker.Select(maker.Ident(methodNode.toName("this")), methodNode.toName(lockName));
}
recursiveSetGeneratedBy(lockNode, ast, context);
method.body = setGeneratedBy(maker.Block(0, List.<JCStatement>of(setGeneratedBy(maker.Synchronized(lockNode, method.body), ast, context))), ast, context);
methodNode.rebuild();
}
use of lombok.javac.JavacNode in project lombok by rzwitserloot.
the class HandleToString method getTypeName.
public static String getTypeName(JavacNode typeNode) {
String typeName = ((JCClassDecl) typeNode.get()).name.toString();
JavacNode upType = typeNode.up();
while (upType.getKind() == Kind.TYPE) {
typeName = ((JCClassDecl) upType.get()).name.toString() + "." + typeName;
upType = upType.up();
}
return typeName;
}
use of lombok.javac.JavacNode in project lombok by rzwitserloot.
the class HandleToString method generateToString.
public void generateToString(JavacNode typeNode, JavacNode source, List<String> excludes, List<String> includes, boolean includeFieldNames, Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess) {
boolean notAClass = true;
if (typeNode.get() instanceof JCClassDecl) {
long flags = ((JCClassDecl) typeNode.get()).mods.flags;
notAClass = (flags & (Flags.INTERFACE | Flags.ANNOTATION)) != 0;
}
if (callSuper == null) {
try {
callSuper = ((Boolean) ToString.class.getMethod("callSuper").getDefaultValue()).booleanValue();
} catch (Exception ignore) {
}
}
if (notAClass) {
source.addError("@ToString is only supported on a class or enum.");
return;
}
ListBuffer<JavacNode> nodesForToString = new ListBuffer<JavacNode>();
if (includes != null) {
for (JavacNode child : typeNode.down()) {
if (child.getKind() != Kind.FIELD)
continue;
JCVariableDecl fieldDecl = (JCVariableDecl) child.get();
if (includes.contains(fieldDecl.name.toString()))
nodesForToString.append(child);
}
} else {
for (JavacNode child : typeNode.down()) {
if (child.getKind() != Kind.FIELD)
continue;
JCVariableDecl fieldDecl = (JCVariableDecl) child.get();
//Skip static fields.
if ((fieldDecl.mods.flags & Flags.STATIC) != 0)
continue;
//Skip excluded fields.
if (excludes != null && excludes.contains(fieldDecl.name.toString()))
continue;
//Skip fields that start with $.
if (fieldDecl.name.toString().startsWith("$"))
continue;
nodesForToString.append(child);
}
}
switch(methodExists("toString", typeNode, 0)) {
case NOT_EXISTS:
JCMethodDecl method = createToString(typeNode, nodesForToString.toList(), includeFieldNames, callSuper, fieldAccess, source.get());
injectMethod(typeNode, method);
break;
case EXISTS_BY_LOMBOK:
break;
default:
case EXISTS_BY_USER:
if (whineIfExists) {
source.addWarning("Not generating toString(): A method with that name already exists");
}
break;
}
}
use of lombok.javac.JavacNode in project lombok by rzwitserloot.
the class HandleUtilityClass method handle.
@Override
public void handle(AnnotationValues<UtilityClass> annotation, JCAnnotation ast, JavacNode annotationNode) {
handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.UTILITY_CLASS_FLAG_USAGE, "@UtilityClass");
deleteAnnotationIfNeccessary(annotationNode, UtilityClass.class);
JavacNode typeNode = annotationNode.up();
if (!checkLegality(typeNode, annotationNode))
return;
changeModifiersAndGenerateConstructor(annotationNode.up(), annotationNode);
}
use of lombok.javac.JavacNode in project lombok by rzwitserloot.
the class HandleUtilityClass method checkLegality.
private static boolean checkLegality(JavacNode typeNode, JavacNode errorNode) {
JCClassDecl typeDecl = null;
if (typeNode.get() instanceof JCClassDecl)
typeDecl = (JCClassDecl) typeNode.get();
long modifiers = typeDecl == null ? 0 : typeDecl.mods.flags;
boolean notAClass = (modifiers & (Flags.INTERFACE | Flags.ANNOTATION | Flags.ENUM)) != 0;
if (typeDecl == null || notAClass) {
errorNode.addError("@UtilityClass is only supported on a class (can't be an interface, enum, or annotation).");
return false;
}
// It might be an inner class. This is okay, but only if it is / can be a static inner class. Thus, all of its parents have to be static inner classes until the top-level.
JavacNode typeWalk = typeNode;
while (true) {
typeWalk = typeWalk.up();
switch(typeWalk.getKind()) {
case TYPE:
JCClassDecl typeDef = (JCClassDecl) typeWalk.get();
if ((typeDef.mods.flags & (Flags.STATIC | Flags.ANNOTATION | Flags.ENUM | Flags.INTERFACE)) != 0)
continue;
if (typeWalk.up().getKind() == Kind.COMPILATION_UNIT)
return true;
errorNode.addError("@UtilityClass automatically makes the class static, however, this class cannot be made static.");
return false;
case COMPILATION_UNIT:
return true;
default:
errorNode.addError("@UtilityClass cannot be placed on a method local or anonymous inner class, or any class nested in such a class.");
return false;
}
}
}
Aggregations