Search in sources :

Example 21 with JavacNode

use of lombok.javac.JavacNode in project lombok by rzwitserloot.

the class HandleValue method handle.

@Override
public void handle(AnnotationValues<Value> annotation, JCAnnotation ast, JavacNode annotationNode) {
    @SuppressWarnings("deprecation") Class<? extends Annotation> oldExperimentalValue = lombok.experimental.Value.class;
    handleFlagUsage(annotationNode, ConfigurationKeys.VALUE_FLAG_USAGE, "@Value");
    deleteAnnotationIfNeccessary(annotationNode, Value.class, oldExperimentalValue);
    JavacNode typeNode = annotationNode.up();
    boolean notAClass = !isClass(typeNode);
    if (notAClass) {
        annotationNode.addError("@Value is only supported on a class.");
        return;
    }
    String staticConstructorName = annotation.getInstance().staticConstructor();
    if (!hasAnnotationAndDeleteIfNeccessary(NonFinal.class, typeNode)) {
        JCModifiers jcm = ((JCClassDecl) typeNode.get()).mods;
        if ((jcm.flags & Flags.FINAL) == 0) {
            jcm.flags |= Flags.FINAL;
            typeNode.rebuild();
        }
    }
    new HandleFieldDefaults().generateFieldDefaultsForType(typeNode, annotationNode, AccessLevel.PRIVATE, true, true);
    // TODO move this to the end OR move it to the top in eclipse.
    new HandleConstructor().generateAllArgsConstructor(typeNode, AccessLevel.PUBLIC, staticConstructorName, SkipIfConstructorExists.YES, annotationNode);
    new HandleGetter().generateGetterForType(typeNode, annotationNode, AccessLevel.PUBLIC, true);
    new HandleEqualsAndHashCode().generateEqualsAndHashCodeForType(typeNode, annotationNode);
    new HandleToString().generateToStringForType(typeNode, annotationNode);
}
Also used : JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) JavacNode(lombok.javac.JavacNode) JCModifiers(com.sun.tools.javac.tree.JCTree.JCModifiers) Value(lombok.Value) NonFinal(lombok.experimental.NonFinal)

Example 22 with JavacNode

use of lombok.javac.JavacNode in project lombok by rzwitserloot.

the class HandleWither method handle.

@Override
public void handle(AnnotationValues<Wither> annotation, JCAnnotation ast, JavacNode annotationNode) {
    handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.WITHER_FLAG_USAGE, "@Wither");
    Collection<JavacNode> fields = annotationNode.upFromAnnotationToFields();
    deleteAnnotationIfNeccessary(annotationNode, Wither.class);
    deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel");
    JavacNode node = annotationNode.up();
    AccessLevel level = annotation.getInstance().value();
    if (level == AccessLevel.NONE || node == null)
        return;
    List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Wither(onMethod", annotationNode);
    List<JCAnnotation> onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Wither(onParam", annotationNode);
    switch(node.getKind()) {
        case FIELD:
            createWitherForFields(level, fields, annotationNode, true, onMethod, onParam);
            break;
        case TYPE:
            if (!onMethod.isEmpty())
                annotationNode.addError("'onMethod' is not supported for @Wither on a type.");
            if (!onParam.isEmpty())
                annotationNode.addError("'onParam' is not supported for @Wither on a type.");
            generateWitherForType(node, annotationNode, level, false);
            break;
    }
}
Also used : JavacNode(lombok.javac.JavacNode) AccessLevel(lombok.AccessLevel) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Example 23 with JavacNode

use of lombok.javac.JavacNode in project lombok by rzwitserloot.

the class HandleWither method createWitherForField.

public void createWitherForField(AccessLevel level, JavacNode fieldNode, JavacNode source, boolean strictMode, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) {
    JavacNode typeNode = fieldNode.up();
    boolean makeAbstract = typeNode != null && typeNode.getKind() == Kind.TYPE && (((JCClassDecl) typeNode.get()).mods.flags & Flags.ABSTRACT) != 0;
    if (fieldNode.getKind() != Kind.FIELD) {
        fieldNode.addError("@Wither is only supported on a class or a field.");
        return;
    }
    JCVariableDecl fieldDecl = (JCVariableDecl) fieldNode.get();
    String methodName = toWitherName(fieldNode);
    if (methodName == null) {
        fieldNode.addWarning("Not generating wither for this field: It does not fit your @Accessors prefix list.");
        return;
    }
    if ((fieldDecl.mods.flags & Flags.STATIC) != 0) {
        if (strictMode) {
            fieldNode.addWarning("Not generating wither for this field: Withers cannot be generated for static fields.");
        }
        return;
    }
    if ((fieldDecl.mods.flags & Flags.FINAL) != 0 && fieldDecl.init != null) {
        if (strictMode) {
            fieldNode.addWarning("Not generating wither for this field: Withers cannot be generated for final, initialized fields.");
        }
        return;
    }
    if (fieldDecl.name.toString().startsWith("$")) {
        if (strictMode) {
            fieldNode.addWarning("Not generating wither for this field: Withers cannot be generated for fields starting with $.");
        }
        return;
    }
    for (String altName : toAllWitherNames(fieldNode)) {
        switch(methodExists(altName, fieldNode, false, 1)) {
            case EXISTS_BY_LOMBOK:
                return;
            case EXISTS_BY_USER:
                if (strictMode) {
                    String altNameExpl = "";
                    if (!altName.equals(methodName))
                        altNameExpl = String.format(" (%s)", altName);
                    fieldNode.addWarning(String.format("Not generating %s(): A method with that name already exists%s", methodName, altNameExpl));
                }
                return;
            default:
            case NOT_EXISTS:
        }
    }
    long access = toJavacModifier(level);
    JCMethodDecl createdWither = createWither(access, fieldNode, fieldNode.getTreeMaker(), source, onMethod, onParam, makeAbstract);
    ClassSymbol sym = ((JCClassDecl) fieldNode.up().get()).sym;
    Type returnType = sym == null ? null : sym.type;
    injectMethod(typeNode, createdWither, List.<Type>of(getMirrorForFieldType(fieldNode)), returnType);
}
Also used : JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) Type(com.sun.tools.javac.code.Type) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) JavacNode(lombok.javac.JavacNode) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl)

Example 24 with JavacNode

use of lombok.javac.JavacNode in project lombok by rzwitserloot.

the class HandleWither method createWither.

public JCMethodDecl createWither(long access, JavacNode field, JavacTreeMaker maker, JavacNode source, List<JCAnnotation> onMethod, List<JCAnnotation> onParam, boolean makeAbstract) {
    String witherName = toWitherName(field);
    if (witherName == null)
        return null;
    JCVariableDecl fieldDecl = (JCVariableDecl) field.get();
    List<JCAnnotation> nonNulls = findAnnotations(field, NON_NULL_PATTERN);
    List<JCAnnotation> nullables = findAnnotations(field, NULLABLE_PATTERN);
    Name methodName = field.toName(witherName);
    JCExpression returnType = cloneSelfType(field);
    JCBlock methodBody = null;
    long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, field.getContext());
    List<JCAnnotation> annsOnParam = copyAnnotations(onParam).appendList(nonNulls).appendList(nullables);
    JCVariableDecl param = maker.VarDef(maker.Modifiers(flags, annsOnParam), fieldDecl.name, fieldDecl.vartype, null);
    if (!makeAbstract) {
        ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
        JCExpression selfType = cloneSelfType(field);
        if (selfType == null)
            return null;
        ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
        for (JavacNode child : field.up().down()) {
            if (child.getKind() != Kind.FIELD)
                continue;
            JCVariableDecl childDecl = (JCVariableDecl) child.get();
            // Skip fields that start with $
            if (childDecl.name.toString().startsWith("$"))
                continue;
            long fieldFlags = childDecl.mods.flags;
            // Skip static fields.
            if ((fieldFlags & Flags.STATIC) != 0)
                continue;
            // Skip initialized final fields.
            if (((fieldFlags & Flags.FINAL) != 0) && childDecl.init != null)
                continue;
            if (child.get() == field.get()) {
                args.append(maker.Ident(fieldDecl.name));
            } else {
                args.append(createFieldAccessor(maker, child, FieldAccess.ALWAYS_FIELD));
            }
        }
        JCNewClass newClass = maker.NewClass(null, List.<JCExpression>nil(), selfType, args.toList(), null);
        JCExpression identityCheck = maker.Binary(CTC_EQUAL, createFieldAccessor(maker, field, FieldAccess.ALWAYS_FIELD), maker.Ident(fieldDecl.name));
        JCConditional conditional = maker.Conditional(identityCheck, maker.Ident(field.toName("this")), newClass);
        JCReturn returnStatement = maker.Return(conditional);
        if (nonNulls.isEmpty()) {
            statements.append(returnStatement);
        } else {
            JCStatement nullCheck = generateNullCheck(maker, field, source);
            if (nullCheck != null)
                statements.append(nullCheck);
            statements.append(returnStatement);
        }
        methodBody = maker.Block(0, statements.toList());
    }
    List<JCTypeParameter> methodGenericParams = List.nil();
    List<JCVariableDecl> parameters = List.of(param);
    List<JCExpression> throwsClauses = List.nil();
    JCExpression annotationMethodDefaultValue = null;
    List<JCAnnotation> annsOnMethod = copyAnnotations(onMethod);
    if (isFieldDeprecated(field)) {
        annsOnMethod = annsOnMethod.prepend(maker.Annotation(genJavaLangTypeRef(field, "Deprecated"), List.<JCExpression>nil()));
    }
    if (makeAbstract)
        access = access | Flags.ABSTRACT;
    JCMethodDecl decl = recursiveSetGeneratedBy(maker.MethodDef(maker.Modifiers(access, annsOnMethod), methodName, returnType, methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue), source.get(), field.getContext());
    copyJavadoc(field, decl, CopyJavadoc.WITHER);
    return decl;
}
Also used : JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JCReturn(com.sun.tools.javac.tree.JCTree.JCReturn) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) ListBuffer(com.sun.tools.javac.util.ListBuffer) JCConditional(com.sun.tools.javac.tree.JCTree.JCConditional) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) Name(com.sun.tools.javac.util.Name) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JavacNode(lombok.javac.JavacNode) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Example 25 with JavacNode

use of lombok.javac.JavacNode in project lombok by rzwitserloot.

the class JavacHandlerUtil method deleteAnnotationIfNeccessary0.

private static void deleteAnnotationIfNeccessary0(JavacNode annotation, Class<? extends Annotation>... annotationTypes) {
    if (inNetbeansEditor(annotation))
        return;
    if (!annotation.shouldDeleteLombokAnnotations())
        return;
    JavacNode parentNode = annotation.directUp();
    switch(parentNode.getKind()) {
        case FIELD:
        case ARGUMENT:
        case LOCAL:
            JCVariableDecl variable = (JCVariableDecl) parentNode.get();
            variable.mods.annotations = filterList(variable.mods.annotations, annotation.get());
            break;
        case METHOD:
            JCMethodDecl method = (JCMethodDecl) parentNode.get();
            method.mods.annotations = filterList(method.mods.annotations, annotation.get());
            break;
        case TYPE:
            try {
                JCClassDecl type = (JCClassDecl) parentNode.get();
                type.mods.annotations = filterList(type.mods.annotations, annotation.get());
            } catch (ClassCastException e) {
            //something rather odd has been annotated. Better to just break only delombok instead of everything.
            }
            break;
        default:
            //This really shouldn't happen, but if it does, better just break delombok instead of breaking everything.
            return;
    }
    parentNode.getAst().setChanged();
    for (Class<?> annotationType : annotationTypes) {
        deleteImportFromCompilationUnit(annotation, annotationType.getName());
    }
}
Also used : JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) JavacNode(lombok.javac.JavacNode) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl)

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