Search in sources :

Example 26 with JCAnnotation

use of com.sun.tools.javac.tree.JCTree.JCAnnotation in project lombok by rzwitserloot.

the class HandleFieldDefaults method visitType.

@Override
public void visitType(JavacNode typeNode, JCClassDecl type) {
    AnnotationValues<FieldDefaults> fieldDefaults = null;
    JavacNode source = typeNode;
    boolean levelIsExplicit = false;
    boolean makeFinalIsExplicit = false;
    FieldDefaults fd = null;
    for (JavacNode jn : typeNode.down()) {
        if (jn.getKind() != Kind.ANNOTATION)
            continue;
        JCAnnotation ann = (JCAnnotation) jn.get();
        JCTree typeTree = ann.annotationType;
        if (typeTree == null)
            continue;
        String typeTreeToString = typeTree.toString();
        if (!typeTreeToString.equals("FieldDefaults") && !typeTreeToString.equals("lombok.experimental.FieldDefaults"))
            continue;
        if (!typeMatches(FieldDefaults.class, jn, typeTree))
            continue;
        source = jn;
        fieldDefaults = createAnnotation(FieldDefaults.class, jn);
        levelIsExplicit = fieldDefaults.isExplicit("level");
        makeFinalIsExplicit = fieldDefaults.isExplicit("makeFinal");
        handleExperimentalFlagUsage(jn, ConfigurationKeys.FIELD_DEFAULTS_FLAG_USAGE, "@FieldDefaults");
        fd = fieldDefaults.getInstance();
        if (!levelIsExplicit && !makeFinalIsExplicit) {
            jn.addError("This does nothing; provide either level or makeFinal or both.");
        }
        if (levelIsExplicit && fd.level() == AccessLevel.NONE) {
            jn.addError("AccessLevel.NONE doesn't mean anything here. Pick another value.");
            levelIsExplicit = false;
        }
        deleteAnnotationIfNeccessary(jn, FieldDefaults.class);
        deleteImportFromCompilationUnit(jn, "lombok.AccessLevel");
        break;
    }
    if (fd == null && (type.mods.flags & (Flags.INTERFACE | Flags.ANNOTATION)) != 0)
        return;
    boolean defaultToPrivate = levelIsExplicit ? false : Boolean.TRUE.equals(typeNode.getAst().readConfiguration(ConfigurationKeys.FIELD_DEFAULTS_PRIVATE_EVERYWHERE));
    boolean defaultToFinal = makeFinalIsExplicit ? false : Boolean.TRUE.equals(typeNode.getAst().readConfiguration(ConfigurationKeys.FIELD_DEFAULTS_FINAL_EVERYWHERE));
    if (!defaultToPrivate && !defaultToFinal && fieldDefaults == null)
        return;
    AccessLevel fdAccessLevel = (fieldDefaults != null && levelIsExplicit) ? fd.level() : defaultToPrivate ? AccessLevel.PRIVATE : null;
    boolean fdToFinal = (fieldDefaults != null && makeFinalIsExplicit) ? fd.makeFinal() : defaultToFinal;
    generateFieldDefaultsForType(typeNode, source, fdAccessLevel, fdToFinal, false);
}
Also used : JavacNode(lombok.javac.JavacNode) JCTree(com.sun.tools.javac.tree.JCTree) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation) AccessLevel(lombok.AccessLevel) FieldDefaults(lombok.experimental.FieldDefaults)

Example 27 with JCAnnotation

use of com.sun.tools.javac.tree.JCTree.JCAnnotation in project lombok by rzwitserloot.

the class HandleGetter method handle.

@Override
public void handle(AnnotationValues<Getter> annotation, JCAnnotation ast, JavacNode annotationNode) {
    handleFlagUsage(annotationNode, ConfigurationKeys.GETTER_FLAG_USAGE, "@Getter");
    Collection<JavacNode> fields = annotationNode.upFromAnnotationToFields();
    deleteAnnotationIfNeccessary(annotationNode, Getter.class);
    deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel");
    JavacNode node = annotationNode.up();
    Getter annotationInstance = annotation.getInstance();
    AccessLevel level = annotationInstance.value();
    boolean lazy = annotationInstance.lazy();
    if (lazy)
        handleFlagUsage(annotationNode, ConfigurationKeys.GETTER_LAZY_FLAG_USAGE, "@Getter(lazy=true)");
    if (level == AccessLevel.NONE) {
        if (lazy)
            annotationNode.addWarning("'lazy' does not work with AccessLevel.NONE.");
        return;
    }
    if (node == null)
        return;
    List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Getter(onMethod", annotationNode);
    switch(node.getKind()) {
        case FIELD:
            createGetterForFields(level, fields, annotationNode, true, lazy, onMethod);
            break;
        case TYPE:
            if (!onMethod.isEmpty()) {
                annotationNode.addError("'onMethod' is not supported for @Getter on a type.");
            }
            if (lazy)
                annotationNode.addError("'lazy' is not supported for @Getter on a type.");
            generateGetterForType(node, annotationNode, level, false);
            break;
    }
}
Also used : JavacNode(lombok.javac.JavacNode) Getter(lombok.Getter) AccessLevel(lombok.AccessLevel) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Example 28 with JCAnnotation

use of com.sun.tools.javac.tree.JCTree.JCAnnotation in project lombok by rzwitserloot.

the class HandleGetter method findDelegatesAndRemoveFromField.

public static List<JCAnnotation> findDelegatesAndRemoveFromField(JavacNode field) {
    JCVariableDecl fieldNode = (JCVariableDecl) field.get();
    List<JCAnnotation> delegates = List.nil();
    for (JCAnnotation annotation : fieldNode.mods.annotations) {
        if (typeMatches(Delegate.class, field, annotation.annotationType)) {
            delegates = delegates.append(annotation);
        }
    }
    if (!delegates.isEmpty()) {
        ListBuffer<JCAnnotation> withoutDelegates = new ListBuffer<JCAnnotation>();
        for (JCAnnotation annotation : fieldNode.mods.annotations) {
            if (!delegates.contains(annotation)) {
                withoutDelegates.append(annotation);
            }
        }
        fieldNode.mods.annotations = withoutDelegates.toList();
        field.rebuild();
    }
    return delegates;
}
Also used : ListBuffer(com.sun.tools.javac.util.ListBuffer) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Example 29 with JCAnnotation

use of com.sun.tools.javac.tree.JCTree.JCAnnotation in project lombok by rzwitserloot.

the class HandleEqualsAndHashCode method createEquals.

public JCMethodDecl createEquals(JavacNode typeNode, List<JavacNode> fields, boolean callSuper, FieldAccess fieldAccess, boolean needsCanEqual, JCTree source, List<JCAnnotation> onParam) {
    JavacTreeMaker maker = typeNode.getTreeMaker();
    Name oName = typeNode.toName("o");
    Name otherName = typeNode.toName("other");
    Name thisName = typeNode.toName("this");
    JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(typeNode, "Override"), List.<JCExpression>nil());
    JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.of(overrideAnnotation));
    JCExpression objectType = genJavaLangTypeRef(typeNode, "Object");
    JCExpression returnType = maker.TypeIdent(CTC_BOOLEAN);
    long finalFlag = JavacHandlerUtil.addFinalIfNeeded(0L, typeNode.getContext());
    ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
    final List<JCVariableDecl> params = List.of(maker.VarDef(maker.Modifiers(finalFlag | Flags.PARAMETER, onParam), oName, objectType, null));
    /* if (o == this) return true; */
    {
        statements.append(maker.If(maker.Binary(CTC_EQUAL, maker.Ident(oName), maker.Ident(thisName)), returnBool(maker, true), null));
    }
    /* if (!(o instanceof Outer.Inner.MyType)) return false; */
    {
        JCUnary notInstanceOf = maker.Unary(CTC_NOT, maker.Parens(maker.TypeTest(maker.Ident(oName), createTypeReference(typeNode, false))));
        statements.append(maker.If(notInstanceOf, returnBool(maker, false), null));
    }
    /* Outer.Inner.MyType<?> other = (Outer.Inner.MyType<?>) o; */
    {
        if (!fields.isEmpty() || needsCanEqual) {
            final JCExpression selfType1 = createTypeReference(typeNode, true), selfType2 = createTypeReference(typeNode, true);
            statements.append(maker.VarDef(maker.Modifiers(finalFlag), otherName, selfType1, maker.TypeCast(selfType2, maker.Ident(oName))));
        }
    }
    /* if (!other.canEqual((java.lang.Object) this)) return false; */
    {
        if (needsCanEqual) {
            List<JCExpression> exprNil = List.nil();
            JCExpression thisRef = maker.Ident(thisName);
            JCExpression castThisRef = maker.TypeCast(genJavaLangTypeRef(typeNode, "Object"), thisRef);
            JCExpression equalityCheck = maker.Apply(exprNil, maker.Select(maker.Ident(otherName), typeNode.toName("canEqual")), List.of(castThisRef));
            statements.append(maker.If(maker.Unary(CTC_NOT, equalityCheck), returnBool(maker, false), null));
        }
    }
    /* if (!super.equals(o)) return false; */
    if (callSuper) {
        JCMethodInvocation callToSuper = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(typeNode.toName("super")), typeNode.toName("equals")), List.<JCExpression>of(maker.Ident(oName)));
        JCUnary superNotEqual = maker.Unary(CTC_NOT, callToSuper);
        statements.append(maker.If(superNotEqual, returnBool(maker, false), null));
    }
    Name thisDollar = typeNode.toName("this$");
    Name otherDollar = typeNode.toName("other$");
    for (JavacNode fieldNode : fields) {
        JCExpression fType = getFieldType(fieldNode, fieldAccess);
        JCExpression thisFieldAccessor = createFieldAccessor(maker, fieldNode, fieldAccess);
        JCExpression otherFieldAccessor = createFieldAccessor(maker, fieldNode, fieldAccess, maker.Ident(otherName));
        if (fType instanceof JCPrimitiveTypeTree) {
            switch(((JCPrimitiveTypeTree) fType).getPrimitiveTypeKind()) {
                case FLOAT:
                    /* if (Float.compare(this.fieldName, other.fieldName) != 0) return false; */
                    statements.append(generateCompareFloatOrDouble(thisFieldAccessor, otherFieldAccessor, maker, typeNode, false));
                    break;
                case DOUBLE:
                    /* if (Double.compare(this.fieldName, other.fieldName) != 0) return false; */
                    statements.append(generateCompareFloatOrDouble(thisFieldAccessor, otherFieldAccessor, maker, typeNode, true));
                    break;
                default:
                    /* if (this.fieldName != other.fieldName) return false; */
                    statements.append(maker.If(maker.Binary(CTC_NOT_EQUAL, thisFieldAccessor, otherFieldAccessor), returnBool(maker, false), null));
                    break;
            }
        } else if (fType instanceof JCArrayTypeTree) {
            /* if (!java.util.Arrays.deepEquals(this.fieldName, other.fieldName)) return false; //use equals for primitive arrays. */
            boolean multiDim = ((JCArrayTypeTree) fType).elemtype instanceof JCArrayTypeTree;
            boolean primitiveArray = ((JCArrayTypeTree) fType).elemtype instanceof JCPrimitiveTypeTree;
            boolean useDeepEquals = multiDim || !primitiveArray;
            JCExpression eqMethod = chainDots(typeNode, "java", "util", "Arrays", useDeepEquals ? "deepEquals" : "equals");
            List<JCExpression> args = List.of(thisFieldAccessor, otherFieldAccessor);
            statements.append(maker.If(maker.Unary(CTC_NOT, maker.Apply(List.<JCExpression>nil(), eqMethod, args)), returnBool(maker, false), null));
        } else /* objects */
        {
            /* final java.lang.Object this$fieldName = this.fieldName; */
            /* final java.lang.Object other$fieldName = other.fieldName; */
            /* if (this$fieldName == null ? other$fieldName != null : !this$fieldName.equals(other$fieldName)) return false; */
            Name fieldName = ((JCVariableDecl) fieldNode.get()).name;
            Name thisDollarFieldName = thisDollar.append(fieldName);
            Name otherDollarFieldName = otherDollar.append(fieldName);
            statements.append(maker.VarDef(maker.Modifiers(finalFlag), thisDollarFieldName, genJavaLangTypeRef(typeNode, "Object"), thisFieldAccessor));
            statements.append(maker.VarDef(maker.Modifiers(finalFlag), otherDollarFieldName, genJavaLangTypeRef(typeNode, "Object"), otherFieldAccessor));
            JCExpression thisEqualsNull = maker.Binary(CTC_EQUAL, maker.Ident(thisDollarFieldName), maker.Literal(CTC_BOT, null));
            JCExpression otherNotEqualsNull = maker.Binary(CTC_NOT_EQUAL, maker.Ident(otherDollarFieldName), maker.Literal(CTC_BOT, null));
            JCExpression thisEqualsThat = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(thisDollarFieldName), typeNode.toName("equals")), List.<JCExpression>of(maker.Ident(otherDollarFieldName)));
            JCExpression fieldsAreNotEqual = maker.Conditional(thisEqualsNull, otherNotEqualsNull, maker.Unary(CTC_NOT, thisEqualsThat));
            statements.append(maker.If(fieldsAreNotEqual, returnBool(maker, false), null));
        }
    }
    /* return true; */
    {
        statements.append(returnBool(maker, true));
    }
    JCBlock body = maker.Block(0, statements.toList());
    return recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("equals"), returnType, List.<JCTypeParameter>nil(), params, List.<JCExpression>nil(), body, null), source, typeNode.getContext());
}
Also used : JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JavacTreeMaker(lombok.javac.JavacTreeMaker) ListBuffer(com.sun.tools.javac.util.ListBuffer) 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) JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) JCPrimitiveTypeTree(com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JavacNode(lombok.javac.JavacNode) JCModifiers(com.sun.tools.javac.tree.JCTree.JCModifiers) JCUnary(com.sun.tools.javac.tree.JCTree.JCUnary) ArrayList(java.util.ArrayList) List(com.sun.tools.javac.util.List) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation) JCArrayTypeTree(com.sun.tools.javac.tree.JCTree.JCArrayTypeTree)

Example 30 with JCAnnotation

use of com.sun.tools.javac.tree.JCTree.JCAnnotation in project lombok by rzwitserloot.

the class HandleEqualsAndHashCode method handle.

@Override
public void handle(AnnotationValues<EqualsAndHashCode> annotation, JCAnnotation ast, JavacNode annotationNode) {
    handleFlagUsage(annotationNode, ConfigurationKeys.EQUALS_AND_HASH_CODE_FLAG_USAGE, "@EqualsAndHashCode");
    deleteAnnotationIfNeccessary(annotationNode, EqualsAndHashCode.class);
    EqualsAndHashCode ann = annotation.getInstance();
    List<String> excludes = List.from(ann.exclude());
    List<String> includes = List.from(ann.of());
    JavacNode typeNode = annotationNode.up();
    List<JCAnnotation> onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@EqualsAndHashCode(onParam", annotationNode);
    checkForBogusFieldNames(typeNode, annotation);
    Boolean callSuper = ann.callSuper();
    if (!annotation.isExplicit("callSuper"))
        callSuper = null;
    if (!annotation.isExplicit("exclude"))
        excludes = null;
    if (!annotation.isExplicit("of"))
        includes = null;
    if (excludes != null && includes != null) {
        excludes = null;
        annotation.setWarning("exclude", "exclude and of are mutually exclusive; the 'exclude' parameter will be ignored.");
    }
    Boolean doNotUseGettersConfiguration = annotationNode.getAst().readConfiguration(ConfigurationKeys.EQUALS_AND_HASH_CODE_DO_NOT_USE_GETTERS);
    boolean doNotUseGetters = annotation.isExplicit("doNotUseGetters") || doNotUseGettersConfiguration == null ? ann.doNotUseGetters() : doNotUseGettersConfiguration;
    FieldAccess fieldAccess = doNotUseGetters ? FieldAccess.PREFER_FIELD : FieldAccess.GETTER;
    generateMethods(typeNode, annotationNode, excludes, includes, callSuper, true, fieldAccess, onParam);
}
Also used : JavacNode(lombok.javac.JavacNode) EqualsAndHashCode(lombok.EqualsAndHashCode) FieldAccess(lombok.javac.handlers.JavacHandlerUtil.FieldAccess) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Aggregations

JCAnnotation (com.sun.tools.javac.tree.JCTree.JCAnnotation)53 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)32 ListBuffer (com.sun.tools.javac.util.ListBuffer)17 Name (com.sun.tools.javac.util.Name)16 JCTree (com.sun.tools.javac.tree.JCTree)15 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)15 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)13 JavacNode (lombok.javac.JavacNode)13 JCTypeParameter (com.sun.tools.javac.tree.JCTree.JCTypeParameter)12 JCBlock (com.sun.tools.javac.tree.JCTree.JCBlock)11 JCModifiers (com.sun.tools.javac.tree.JCTree.JCModifiers)10 JCAssign (com.sun.tools.javac.tree.JCTree.JCAssign)8 JavacTreeMaker (lombok.javac.JavacTreeMaker)8 JCPrimitiveTypeTree (com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree)6 Type (com.redhat.ceylon.model.typechecker.model.Type)5 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)5 JCNewArray (com.sun.tools.javac.tree.JCTree.JCNewArray)5 ArrayList (java.util.ArrayList)5 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)4 Parameter (com.redhat.ceylon.model.typechecker.model.Parameter)4