Search in sources :

Example 36 with TypeDeclaration

use of org.eclipse.jdt.internal.compiler.ast.TypeDeclaration in project lombok by rzwitserloot.

the class HandleUtilityClass method checkLegality.

private static boolean checkLegality(EclipseNode typeNode, EclipseNode errorNode) {
    TypeDeclaration typeDecl = null;
    if (typeNode.get() instanceof TypeDeclaration)
        typeDecl = (TypeDeclaration) typeNode.get();
    int modifiers = typeDecl == null ? 0 : typeDecl.modifiers;
    boolean notAClass = (modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) != 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.
    EclipseNode typeWalk = typeNode;
    while (true) {
        typeWalk = typeWalk.up();
        switch(typeWalk.getKind()) {
            case TYPE:
                if ((((TypeDeclaration) typeWalk.get()).modifiers & (ClassFileConstants.AccStatic | ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) != 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 : EclipseNode(lombok.eclipse.EclipseNode) TypeDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration)

Example 37 with TypeDeclaration

use of org.eclipse.jdt.internal.compiler.ast.TypeDeclaration in project lombok by rzwitserloot.

the class HandleValue method handle.

public void handle(AnnotationValues<Value> annotation, Annotation ast, EclipseNode annotationNode) {
    handleFlagUsage(annotationNode, ConfigurationKeys.VALUE_FLAG_USAGE, "@Value");
    Value ann = annotation.getInstance();
    EclipseNode typeNode = annotationNode.up();
    TypeDeclaration typeDecl = null;
    if (typeNode.get() instanceof TypeDeclaration)
        typeDecl = (TypeDeclaration) typeNode.get();
    int modifiers = typeDecl == null ? 0 : typeDecl.modifiers;
    boolean notAClass = (modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) != 0;
    if (typeDecl == null || notAClass) {
        annotationNode.addError("@Value is only supported on a class.");
        return;
    }
    // Make class final.
    if (!hasAnnotation(NonFinal.class, typeNode)) {
        if ((typeDecl.modifiers & ClassFileConstants.AccFinal) == 0) {
            typeDecl.modifiers |= ClassFileConstants.AccFinal;
            typeNode.rebuild();
        }
    }
    new HandleFieldDefaults().generateFieldDefaultsForType(typeNode, annotationNode, AccessLevel.PRIVATE, true, true);
    //Careful: Generate the public static constructor (if there is one) LAST, so that any attempt to
    //'find callers' on the annotation node will find callers of the constructor, which is by far the
    //most useful of the many methods built by @Value. This trick won't work for the non-static constructor,
    //for whatever reason, though you can find callers of that one by focusing on the class name itself
    //and hitting 'find callers'.
    new HandleGetter().generateGetterForType(typeNode, annotationNode, AccessLevel.PUBLIC, true);
    new HandleEqualsAndHashCode().generateEqualsAndHashCodeForType(typeNode, annotationNode);
    new HandleToString().generateToStringForType(typeNode, annotationNode);
    new HandleConstructor().generateAllArgsConstructor(typeNode, AccessLevel.PUBLIC, ann.staticConstructor(), SkipIfConstructorExists.YES, Collections.<Annotation>emptyList(), annotationNode);
}
Also used : Value(lombok.Value) EclipseNode(lombok.eclipse.EclipseNode) NonFinal(lombok.experimental.NonFinal) TypeDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration)

Example 38 with TypeDeclaration

use of org.eclipse.jdt.internal.compiler.ast.TypeDeclaration in project lombok by rzwitserloot.

the class HandleWither method generateWitherForType.

public boolean generateWitherForType(EclipseNode typeNode, EclipseNode pos, AccessLevel level, boolean checkForTypeLevelWither) {
    if (checkForTypeLevelWither) {
        if (hasAnnotation(Wither.class, typeNode)) {
            //The annotation will make it happen, so we can skip it.
            return true;
        }
    }
    TypeDeclaration typeDecl = null;
    if (typeNode.get() instanceof TypeDeclaration)
        typeDecl = (TypeDeclaration) typeNode.get();
    int modifiers = typeDecl == null ? 0 : typeDecl.modifiers;
    boolean notAClass = (modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) != 0;
    if (typeDecl == null || notAClass) {
        pos.addError("@Wither is only supported on a class or a field.");
        return false;
    }
    for (EclipseNode field : typeNode.down()) {
        if (field.getKind() != Kind.FIELD)
            continue;
        FieldDeclaration fieldDecl = (FieldDeclaration) field.get();
        if (!filterField(fieldDecl))
            continue;
        //Skip final fields.
        if ((fieldDecl.modifiers & ClassFileConstants.AccFinal) != 0 && fieldDecl.initialization != null)
            continue;
        generateWitherForField(field, pos, level);
    }
    return true;
}
Also used : EclipseNode(lombok.eclipse.EclipseNode) TypeDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) FieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration)

Example 39 with TypeDeclaration

use of org.eclipse.jdt.internal.compiler.ast.TypeDeclaration in project lombok by rzwitserloot.

the class EclipseHandlerUtil method methodExists.

/**
	 * Checks if there is a method with the provided name. In case of multiple methods (overloading), only
	 * the first method decides if EXISTS_BY_USER or EXISTS_BY_LOMBOK is returned.
	 * 
	 * @param methodName the method name to check for.
	 * @param node Any node that represents the Type (TypeDeclaration) to look in, or any child node thereof.
	 * @param caseSensitive If the search should be case sensitive.
	 * @param params The number of parameters the method should have; varargs count as 0-*. Set to -1 to find any method with the appropriate name regardless of parameter count.
	 */
public static MemberExistsResult methodExists(String methodName, EclipseNode node, boolean caseSensitive, int params) {
    while (node != null && !(node.get() instanceof TypeDeclaration)) {
        node = node.up();
    }
    if (node != null && node.get() instanceof TypeDeclaration) {
        TypeDeclaration typeDecl = (TypeDeclaration) node.get();
        if (typeDecl.methods != null)
            top: for (AbstractMethodDeclaration def : typeDecl.methods) {
                if (def instanceof MethodDeclaration) {
                    char[] mName = def.selector;
                    if (mName == null)
                        continue;
                    boolean nameEquals = caseSensitive ? methodName.equals(new String(mName)) : methodName.equalsIgnoreCase(new String(mName));
                    if (nameEquals) {
                        if (params > -1) {
                            int minArgs = 0;
                            int maxArgs = 0;
                            if (def.arguments != null && def.arguments.length > 0) {
                                minArgs = def.arguments.length;
                                if ((def.arguments[def.arguments.length - 1].type.bits & ASTNode.IsVarArgs) != 0) {
                                    minArgs--;
                                    maxArgs = Integer.MAX_VALUE;
                                } else {
                                    maxArgs = minArgs;
                                }
                            }
                            if (params < minArgs || params > maxArgs)
                                continue;
                        }
                        if (isTolerate(node, def))
                            continue top;
                        return getGeneratedBy(def) == null ? MemberExistsResult.EXISTS_BY_USER : MemberExistsResult.EXISTS_BY_LOMBOK;
                    }
                }
            }
    }
    return MemberExistsResult.NOT_EXISTS;
}
Also used : MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration) TypeDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration)

Example 40 with TypeDeclaration

use of org.eclipse.jdt.internal.compiler.ast.TypeDeclaration in project lombok by rzwitserloot.

the class EclipseHandlerUtil method injectField.

/**
	 * Inserts a field into an existing type. The type must represent a {@code TypeDeclaration}.
	 */
public static EclipseNode injectField(EclipseNode type, FieldDeclaration field) {
    TypeDeclaration parent = (TypeDeclaration) type.get();
    if (parent.fields == null) {
        parent.fields = new FieldDeclaration[1];
        parent.fields[0] = field;
    } else {
        int size = parent.fields.length;
        FieldDeclaration[] newArray = new FieldDeclaration[size + 1];
        System.arraycopy(parent.fields, 0, newArray, 0, size);
        int index = 0;
        for (; index < size; index++) {
            FieldDeclaration f = newArray[index];
            if (isEnumConstant(f) || isGenerated(f))
                continue;
            break;
        }
        System.arraycopy(newArray, index, newArray, index + 1, size - index);
        newArray[index] = field;
        parent.fields = newArray;
    }
    if (isEnumConstant(field) || (field.modifiers & Modifier.STATIC) != 0) {
        if (!hasClinit(parent)) {
            parent.addClinit();
        }
    }
    return type.add(field, Kind.FIELD);
}
Also used : TypeDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) FieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration)

Aggregations

TypeDeclaration (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration)44 EclipseNode (lombok.eclipse.EclipseNode)25 FieldDeclaration (org.eclipse.jdt.internal.compiler.ast.FieldDeclaration)16 ArrayList (java.util.ArrayList)14 MethodDeclaration (org.eclipse.jdt.internal.compiler.ast.MethodDeclaration)12 AbstractMethodDeclaration (org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration)11 TypeReference (org.eclipse.jdt.internal.compiler.ast.TypeReference)7 AllocationExpression (org.eclipse.jdt.internal.compiler.ast.AllocationExpression)6 Expression (org.eclipse.jdt.internal.compiler.ast.Expression)6 SingleNameReference (org.eclipse.jdt.internal.compiler.ast.SingleNameReference)6 Annotation (org.eclipse.jdt.internal.compiler.ast.Annotation)5 ClassLiteralAccess (org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess)5 ConstructorDeclaration (org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration)5 QualifiedTypeReference (org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference)5 SingleTypeReference (org.eclipse.jdt.internal.compiler.ast.SingleTypeReference)5 Statement (org.eclipse.jdt.internal.compiler.ast.Statement)5 ThisReference (org.eclipse.jdt.internal.compiler.ast.ThisReference)5 TypeParameter (org.eclipse.jdt.internal.compiler.ast.TypeParameter)5 Argument (org.eclipse.jdt.internal.compiler.ast.Argument)4 ISourceType (org.eclipse.jdt.internal.compiler.env.ISourceType)4