Search in sources :

Example 16 with JavacNode

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();
}
Also used : Context(com.sun.tools.javac.util.Context) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) JavacTreeMaker(lombok.javac.JavacTreeMaker) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JavacNode(lombok.javac.JavacNode) JCNewArray(com.sun.tools.javac.tree.JCTree.JCNewArray) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl)

Example 17 with JavacNode

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;
}
Also used : JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) JavacNode(lombok.javac.JavacNode) ToString(lombok.ToString)

Example 18 with JavacNode

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;
    }
}
Also used : JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) JavacNode(lombok.javac.JavacNode) ListBuffer(com.sun.tools.javac.util.ListBuffer) ToString(lombok.ToString) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl)

Example 19 with JavacNode

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);
}
Also used : JavacNode(lombok.javac.JavacNode)

Example 20 with JavacNode

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;
        }
    }
}
Also used : JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) JavacNode(lombok.javac.JavacNode)

Aggregations

JavacNode (lombok.javac.JavacNode)52 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)27 JCClassDecl (com.sun.tools.javac.tree.JCTree.JCClassDecl)23 ListBuffer (com.sun.tools.javac.util.ListBuffer)18 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)15 JavacTreeMaker (lombok.javac.JavacTreeMaker)15 JCAnnotation (com.sun.tools.javac.tree.JCTree.JCAnnotation)13 JCMethodDecl (com.sun.tools.javac.tree.JCTree.JCMethodDecl)13 Name (com.sun.tools.javac.util.Name)11 JCTypeParameter (com.sun.tools.javac.tree.JCTree.JCTypeParameter)9 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)8 JCModifiers (com.sun.tools.javac.tree.JCTree.JCModifiers)7 JCBlock (com.sun.tools.javac.tree.JCTree.JCBlock)6 ArrayList (java.util.ArrayList)6 JCMethodInvocation (com.sun.tools.javac.tree.JCTree.JCMethodInvocation)5 JCTree (com.sun.tools.javac.tree.JCTree)4 JCArrayTypeTree (com.sun.tools.javac.tree.JCTree.JCArrayTypeTree)4 JCFieldAccess (com.sun.tools.javac.tree.JCTree.JCFieldAccess)4 JCPrimitiveTypeTree (com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree)4 AccessLevel (lombok.AccessLevel)4