use of lombok.javac.JavacNode in project lombok by rzwitserloot.
the class HandleLog method processAnnotation.
public static void processAnnotation(LoggingFramework framework, AnnotationValues<?> annotation, JavacNode annotationNode, String loggerTopic) {
deleteAnnotationIfNeccessary(annotationNode, framework.getAnnotationClass());
JavacNode typeNode = annotationNode.up();
switch(typeNode.getKind()) {
case TYPE:
String logFieldName = annotationNode.getAst().readConfiguration(ConfigurationKeys.LOG_ANY_FIELD_NAME);
if (logFieldName == null)
logFieldName = "log";
boolean useStatic = !Boolean.FALSE.equals(annotationNode.getAst().readConfiguration(ConfigurationKeys.LOG_ANY_FIELD_IS_STATIC));
if ((((JCClassDecl) typeNode.get()).mods.flags & Flags.INTERFACE) != 0) {
annotationNode.addError("@Log is legal only on classes and enums.");
return;
}
if (fieldExists(logFieldName, typeNode) != MemberExistsResult.NOT_EXISTS) {
annotationNode.addWarning("Field '" + logFieldName + "' already exists.");
return;
}
JCFieldAccess loggingType = selfType(typeNode);
createField(framework, typeNode, loggingType, annotationNode.get(), logFieldName, useStatic, loggerTopic);
break;
default:
annotationNode.addError("@Log is legal only on types.");
break;
}
}
use of lombok.javac.JavacNode in project lombok by rzwitserloot.
the class HandleSetter method generateSetterForType.
public void generateSetterForType(JavacNode typeNode, JavacNode errorNode, AccessLevel level, boolean checkForTypeLevelSetter) {
if (checkForTypeLevelSetter) {
if (hasAnnotation(Setter.class, typeNode)) {
//The annotation will make it happen, so we can skip it.
return;
}
}
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("@Setter is only supported on a class or a field.");
return;
}
for (JavacNode field : typeNode.down()) {
if (field.getKind() != Kind.FIELD)
continue;
JCVariableDecl fieldDecl = (JCVariableDecl) field.get();
//Skip fields that start with $
if (fieldDecl.name.toString().startsWith("$"))
continue;
//Skip static fields.
if ((fieldDecl.mods.flags & Flags.STATIC) != 0)
continue;
//Skip final fields.
if ((fieldDecl.mods.flags & Flags.FINAL) != 0)
continue;
generateSetterForField(field, errorNode, level);
}
}
use of lombok.javac.JavacNode in project lombok by rzwitserloot.
the class HandleSneakyThrows method handleMethod.
public void handleMethod(JavacNode annotation, JCMethodDecl method, Collection<String> exceptions) {
JavacNode methodNode = annotation.up();
if ((method.mods.flags & Flags.ABSTRACT) != 0) {
annotation.addError("@SneakyThrows can only be used on concrete methods.");
return;
}
if (method.body == null || method.body.stats.isEmpty()) {
generateEmptyBlockWarning(methodNode, annotation, false);
return;
}
final JCStatement constructorCall = method.body.stats.get(0);
final boolean isConstructorCall = isConstructorCall(constructorCall);
List<JCStatement> contents = isConstructorCall ? method.body.stats.tail : method.body.stats;
if (contents == null || contents.isEmpty()) {
generateEmptyBlockWarning(methodNode, annotation, true);
return;
}
for (String exception : exceptions) {
contents = List.of(buildTryCatchBlock(methodNode, contents, exception, annotation.get()));
}
method.body.stats = isConstructorCall ? List.of(constructorCall).appendList(contents) : contents;
methodNode.rebuild();
}
use of lombok.javac.JavacNode in project lombok by rzwitserloot.
the class HandleSneakyThrows method handle.
@Override
public void handle(AnnotationValues<SneakyThrows> annotation, JCAnnotation ast, JavacNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.SNEAKY_THROWS_FLAG_USAGE, "@SneakyThrows");
deleteAnnotationIfNeccessary(annotationNode, SneakyThrows.class);
Collection<String> exceptionNames = annotation.getRawExpressions("value");
if (exceptionNames.isEmpty()) {
exceptionNames = Collections.singleton("java.lang.Throwable");
}
java.util.List<String> exceptions = new ArrayList<String>();
for (String exception : exceptionNames) {
if (exception.endsWith(".class"))
exception = exception.substring(0, exception.length() - 6);
exceptions.add(exception);
}
JavacNode owner = annotationNode.up();
switch(owner.getKind()) {
case METHOD:
handleMethod(annotationNode, (JCMethodDecl) owner.get(), exceptions);
break;
default:
annotationNode.addError("@SneakyThrows is legal only on methods and constructors.");
break;
}
}
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();
}
Aggregations