Search in sources :

Example 1 with ASTNode

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

the class PatchExtensionMethodCompletionProposal method getJavaCompletionProposals.

public static IJavaCompletionProposal[] getJavaCompletionProposals(IJavaCompletionProposal[] javaCompletionProposals, CompletionProposalCollector completionProposalCollector) {
    List<IJavaCompletionProposal> proposals = new ArrayList<IJavaCompletionProposal>(Arrays.asList(javaCompletionProposals));
    if (canExtendCodeAssist(proposals)) {
        IJavaCompletionProposal firstProposal = proposals.get(0);
        int replacementOffset = getReplacementOffset(firstProposal);
        for (Extension extension : getExtensionMethods(completionProposalCollector)) {
            for (MethodBinding method : extension.extensionMethods) {
                ExtensionMethodCompletionProposal newProposal = new ExtensionMethodCompletionProposal(replacementOffset);
                copyNameLookupAndCompletionEngine(completionProposalCollector, firstProposal, newProposal);
                ASTNode node = getAssistNode(completionProposalCollector);
                newProposal.setMethodBinding(method, node);
                createAndAddJavaCompletionProposal(completionProposalCollector, newProposal, proposals);
            }
        }
    }
    return proposals.toArray(new IJavaCompletionProposal[proposals.size()]);
}
Also used : Extension(lombok.eclipse.agent.PatchExtensionMethod.Extension) ArrayList(java.util.ArrayList) ASTNode(org.eclipse.jdt.internal.compiler.ast.ASTNode) MethodBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding) IJavaCompletionProposal(org.eclipse.jdt.ui.text.java.IJavaCompletionProposal)

Example 2 with ASTNode

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

the class HandleSetter method createSetter.

static MethodDeclaration createSetter(TypeDeclaration parent, EclipseNode fieldNode, String name, boolean shouldReturnThis, int modifier, EclipseNode sourceNode, List<Annotation> onMethod, List<Annotation> onParam) {
    FieldDeclaration field = (FieldDeclaration) fieldNode.get();
    ASTNode source = sourceNode.get();
    int pS = source.sourceStart, pE = source.sourceEnd;
    long p = (long) pS << 32 | pE;
    MethodDeclaration method = new MethodDeclaration(parent.compilationResult);
    method.modifiers = modifier;
    if (shouldReturnThis) {
        method.returnType = cloneSelfType(fieldNode, source);
    }
    if (method.returnType == null) {
        method.returnType = TypeReference.baseTypeReference(TypeIds.T_void, 0);
        method.returnType.sourceStart = pS;
        method.returnType.sourceEnd = pE;
        shouldReturnThis = false;
    }
    Annotation[] deprecated = null;
    if (isFieldDeprecated(fieldNode)) {
        deprecated = new Annotation[] { generateDeprecatedAnnotation(source) };
    }
    method.annotations = copyAnnotations(source, onMethod.toArray(new Annotation[0]), deprecated);
    Argument param = new Argument(field.name, p, copyType(field.type, source), Modifier.FINAL);
    param.sourceStart = pS;
    param.sourceEnd = pE;
    method.arguments = new Argument[] { param };
    method.selector = name.toCharArray();
    method.binding = null;
    method.thrownExceptions = null;
    method.typeParameters = null;
    method.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
    Expression fieldRef = createFieldAccessor(fieldNode, FieldAccess.ALWAYS_FIELD, source);
    NameReference fieldNameRef = new SingleNameReference(field.name, p);
    Assignment assignment = new Assignment(fieldRef, fieldNameRef, (int) p);
    assignment.sourceStart = pS;
    assignment.sourceEnd = assignment.statementEnd = pE;
    method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart;
    method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd;
    Annotation[] nonNulls = findAnnotations(field, NON_NULL_PATTERN);
    Annotation[] nullables = findAnnotations(field, NULLABLE_PATTERN);
    List<Statement> statements = new ArrayList<Statement>(5);
    if (nonNulls.length == 0) {
        statements.add(assignment);
    } else {
        Statement nullCheck = generateNullCheck(field, sourceNode);
        if (nullCheck != null)
            statements.add(nullCheck);
        statements.add(assignment);
    }
    if (shouldReturnThis) {
        ThisReference thisRef = new ThisReference(pS, pE);
        ReturnStatement returnThis = new ReturnStatement(thisRef, pS, pE);
        statements.add(returnThis);
    }
    method.statements = statements.toArray(new Statement[0]);
    param.annotations = copyAnnotations(source, nonNulls, nullables, onParam.toArray(new Annotation[0]));
    method.traverse(new SetGeneratedByVisitor(source), parent.scope);
    return method;
}
Also used : NameReference(org.eclipse.jdt.internal.compiler.ast.NameReference) SingleNameReference(org.eclipse.jdt.internal.compiler.ast.SingleNameReference) Argument(org.eclipse.jdt.internal.compiler.ast.Argument) MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) ReturnStatement(org.eclipse.jdt.internal.compiler.ast.ReturnStatement) Statement(org.eclipse.jdt.internal.compiler.ast.Statement) ArrayList(java.util.ArrayList) ThisReference(org.eclipse.jdt.internal.compiler.ast.ThisReference) SingleNameReference(org.eclipse.jdt.internal.compiler.ast.SingleNameReference) FieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) Annotation(org.eclipse.jdt.internal.compiler.ast.Annotation) Assignment(org.eclipse.jdt.internal.compiler.ast.Assignment) Expression(org.eclipse.jdt.internal.compiler.ast.Expression) ASTNode(org.eclipse.jdt.internal.compiler.ast.ASTNode) ReturnStatement(org.eclipse.jdt.internal.compiler.ast.ReturnStatement)

Example 3 with ASTNode

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

the class HandleWither method createWitherForField.

public void createWitherForField(AccessLevel level, EclipseNode fieldNode, EclipseNode sourceNode, boolean whineIfExists, List<Annotation> onMethod, List<Annotation> onParam) {
    ASTNode source = sourceNode.get();
    if (fieldNode.getKind() != Kind.FIELD) {
        sourceNode.addError("@Wither is only supported on a class or a field.");
        return;
    }
    EclipseNode typeNode = fieldNode.up();
    boolean makeAbstract = typeNode != null && typeNode.getKind() == Kind.TYPE && (((TypeDeclaration) typeNode.get()).modifiers & ClassFileConstants.AccAbstract) != 0;
    FieldDeclaration field = (FieldDeclaration) fieldNode.get();
    TypeReference fieldType = copyType(field.type, source);
    boolean isBoolean = isBoolean(fieldType);
    String witherName = toWitherName(fieldNode, isBoolean);
    if (witherName == null) {
        fieldNode.addWarning("Not generating wither for this field: It does not fit your @Accessors prefix list.");
        return;
    }
    if ((field.modifiers & ClassFileConstants.AccStatic) != 0) {
        fieldNode.addWarning("Not generating wither for this field: Withers cannot be generated for static fields.");
        return;
    }
    if ((field.modifiers & ClassFileConstants.AccFinal) != 0 && field.initialization != null) {
        fieldNode.addWarning("Not generating wither for this field: Withers cannot be generated for final, initialized fields.");
        return;
    }
    if (field.name != null && field.name.length > 0 && field.name[0] == '$') {
        fieldNode.addWarning("Not generating wither for this field: Withers cannot be generated for fields starting with $.");
        return;
    }
    for (String altName : toAllWitherNames(fieldNode, isBoolean)) {
        switch(methodExists(altName, fieldNode, false, 1)) {
            case EXISTS_BY_LOMBOK:
                return;
            case EXISTS_BY_USER:
                if (whineIfExists) {
                    String altNameExpl = "";
                    if (!altName.equals(witherName))
                        altNameExpl = String.format(" (%s)", altName);
                    fieldNode.addWarning(String.format("Not generating %s(): A method with that name already exists%s", witherName, altNameExpl));
                }
                return;
            default:
            case NOT_EXISTS:
        }
    }
    int modifier = toEclipseModifier(level);
    MethodDeclaration method = createWither((TypeDeclaration) fieldNode.up().get(), fieldNode, witherName, modifier, sourceNode, onMethod, onParam, makeAbstract);
    injectMethod(fieldNode.up(), method);
}
Also used : MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) ASTNode(org.eclipse.jdt.internal.compiler.ast.ASTNode) EclipseNode(lombok.eclipse.EclipseNode) TypeReference(org.eclipse.jdt.internal.compiler.ast.TypeReference) TypeDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) FieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration)

Example 4 with ASTNode

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

the class HandleWither method createWither.

public MethodDeclaration createWither(TypeDeclaration parent, EclipseNode fieldNode, String name, int modifier, EclipseNode sourceNode, List<Annotation> onMethod, List<Annotation> onParam, boolean makeAbstract) {
    ASTNode source = sourceNode.get();
    if (name == null)
        return null;
    FieldDeclaration field = (FieldDeclaration) fieldNode.get();
    int pS = source.sourceStart, pE = source.sourceEnd;
    long p = (long) pS << 32 | pE;
    MethodDeclaration method = new MethodDeclaration(parent.compilationResult);
    if (makeAbstract)
        modifier = modifier | ClassFileConstants.AccAbstract | ExtraCompilerModifiers.AccSemicolonBody;
    method.modifiers = modifier;
    method.returnType = cloneSelfType(fieldNode, source);
    if (method.returnType == null)
        return null;
    Annotation[] deprecated = null;
    if (isFieldDeprecated(fieldNode)) {
        deprecated = new Annotation[] { generateDeprecatedAnnotation(source) };
    }
    method.annotations = copyAnnotations(source, onMethod.toArray(new Annotation[0]), deprecated);
    Argument param = new Argument(field.name, p, copyType(field.type, source), ClassFileConstants.AccFinal);
    param.sourceStart = pS;
    param.sourceEnd = pE;
    method.arguments = new Argument[] { param };
    method.selector = name.toCharArray();
    method.binding = null;
    method.thrownExceptions = null;
    method.typeParameters = null;
    method.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
    Annotation[] nonNulls = findAnnotations(field, NON_NULL_PATTERN);
    Annotation[] nullables = findAnnotations(field, NULLABLE_PATTERN);
    if (!makeAbstract) {
        List<Expression> args = new ArrayList<Expression>();
        for (EclipseNode child : fieldNode.up().down()) {
            if (child.getKind() != Kind.FIELD)
                continue;
            FieldDeclaration childDecl = (FieldDeclaration) child.get();
            // Skip fields that start with $
            if (childDecl.name != null && childDecl.name.length > 0 && childDecl.name[0] == '$')
                continue;
            long fieldFlags = childDecl.modifiers;
            // Skip static fields.
            if ((fieldFlags & ClassFileConstants.AccStatic) != 0)
                continue;
            // Skip initialized final fields.
            if (((fieldFlags & ClassFileConstants.AccFinal) != 0) && childDecl.initialization != null)
                continue;
            if (child.get() == fieldNode.get()) {
                args.add(new SingleNameReference(field.name, p));
            } else {
                args.add(createFieldAccessor(child, FieldAccess.ALWAYS_FIELD, source));
            }
        }
        AllocationExpression constructorCall = new AllocationExpression();
        constructorCall.arguments = args.toArray(new Expression[0]);
        constructorCall.type = cloneSelfType(fieldNode, source);
        Expression identityCheck = new EqualExpression(createFieldAccessor(fieldNode, FieldAccess.ALWAYS_FIELD, source), new SingleNameReference(field.name, p), OperatorIds.EQUAL_EQUAL);
        ThisReference thisRef = new ThisReference(pS, pE);
        Expression conditional = new ConditionalExpression(identityCheck, thisRef, constructorCall);
        Statement returnStatement = new ReturnStatement(conditional, pS, pE);
        method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart;
        method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd;
        List<Statement> statements = new ArrayList<Statement>(5);
        if (nonNulls.length > 0) {
            Statement nullCheck = generateNullCheck(field, sourceNode);
            if (nullCheck != null)
                statements.add(nullCheck);
        }
        statements.add(returnStatement);
        method.statements = statements.toArray(new Statement[0]);
    }
    param.annotations = copyAnnotations(source, nonNulls, nullables, onParam.toArray(new Annotation[0]));
    method.traverse(new SetGeneratedByVisitor(source), parent.scope);
    return method;
}
Also used : Argument(org.eclipse.jdt.internal.compiler.ast.Argument) MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) ReturnStatement(org.eclipse.jdt.internal.compiler.ast.ReturnStatement) Statement(org.eclipse.jdt.internal.compiler.ast.Statement) ConditionalExpression(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) ArrayList(java.util.ArrayList) EqualExpression(org.eclipse.jdt.internal.compiler.ast.EqualExpression) ThisReference(org.eclipse.jdt.internal.compiler.ast.ThisReference) SingleNameReference(org.eclipse.jdt.internal.compiler.ast.SingleNameReference) FieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) Annotation(org.eclipse.jdt.internal.compiler.ast.Annotation) ConditionalExpression(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) Expression(org.eclipse.jdt.internal.compiler.ast.Expression) AllocationExpression(org.eclipse.jdt.internal.compiler.ast.AllocationExpression) EqualExpression(org.eclipse.jdt.internal.compiler.ast.EqualExpression) AllocationExpression(org.eclipse.jdt.internal.compiler.ast.AllocationExpression) ASTNode(org.eclipse.jdt.internal.compiler.ast.ASTNode) ReturnStatement(org.eclipse.jdt.internal.compiler.ast.ReturnStatement) EclipseNode(lombok.eclipse.EclipseNode)

Example 5 with ASTNode

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

the class HandleConstructor method generateConstructor.

public void generateConstructor(EclipseNode typeNode, AccessLevel level, List<EclipseNode> fields, boolean allToDefault, String staticName, SkipIfConstructorExists skipIfConstructorExists, List<Annotation> onConstructor, EclipseNode sourceNode) {
    ASTNode source = sourceNode.get();
    boolean staticConstrRequired = staticName != null && !staticName.equals("");
    if (skipIfConstructorExists != SkipIfConstructorExists.NO && constructorExists(typeNode) != MemberExistsResult.NOT_EXISTS)
        return;
    if (skipIfConstructorExists != SkipIfConstructorExists.NO) {
        for (EclipseNode child : typeNode.down()) {
            if (child.getKind() == Kind.ANNOTATION) {
                boolean skipGeneration = (annotationTypeMatches(NoArgsConstructor.class, child) || annotationTypeMatches(AllArgsConstructor.class, child) || annotationTypeMatches(RequiredArgsConstructor.class, child));
                if (!skipGeneration && skipIfConstructorExists == SkipIfConstructorExists.YES) {
                    skipGeneration = annotationTypeMatches(Builder.class, child);
                }
                if (skipGeneration) {
                    if (staticConstrRequired) {
                        // @Data has asked us to generate a constructor, but we're going to skip this instruction, as an explicit 'make a constructor' annotation
                        // will take care of it. However, @Data also wants a specific static name; this will be ignored; the appropriate way to do this is to use
                        // the 'staticName' parameter of the @XArgsConstructor you've stuck on your type.
                        // We should warn that we're ignoring @Data's 'staticConstructor' param.
                        typeNode.addWarning("Ignoring static constructor name: explicit @XxxArgsConstructor annotation present; its `staticName` parameter will be used.", source.sourceStart, source.sourceEnd);
                    }
                    return;
                }
            }
        }
    }
    ConstructorDeclaration constr = createConstructor(staticConstrRequired ? AccessLevel.PRIVATE : level, typeNode, fields, allToDefault, sourceNode, onConstructor);
    injectMethod(typeNode, constr);
    if (staticConstrRequired) {
        MethodDeclaration staticConstr = createStaticConstructor(level, staticName, typeNode, allToDefault ? Collections.<EclipseNode>emptyList() : fields, source);
        injectMethod(typeNode, staticConstr);
    }
}
Also used : NoArgsConstructor(lombok.NoArgsConstructor) AllArgsConstructor(lombok.AllArgsConstructor) ConstructorDeclaration(org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration) MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) Builder(lombok.Builder) ASTNode(org.eclipse.jdt.internal.compiler.ast.ASTNode) EclipseNode(lombok.eclipse.EclipseNode)

Aggregations

ASTNode (org.eclipse.jdt.internal.compiler.ast.ASTNode)18 MethodDeclaration (org.eclipse.jdt.internal.compiler.ast.MethodDeclaration)7 SingleNameReference (org.eclipse.jdt.internal.compiler.ast.SingleNameReference)7 FieldDeclaration (org.eclipse.jdt.internal.compiler.ast.FieldDeclaration)6 Statement (org.eclipse.jdt.internal.compiler.ast.Statement)6 ArrayList (java.util.ArrayList)5 EclipseNode (lombok.eclipse.EclipseNode)5 Argument (org.eclipse.jdt.internal.compiler.ast.Argument)5 ReturnStatement (org.eclipse.jdt.internal.compiler.ast.ReturnStatement)5 AllocationExpression (org.eclipse.jdt.internal.compiler.ast.AllocationExpression)4 Annotation (org.eclipse.jdt.internal.compiler.ast.Annotation)4 Expression (org.eclipse.jdt.internal.compiler.ast.Expression)4 ThisReference (org.eclipse.jdt.internal.compiler.ast.ThisReference)4 Assignment (org.eclipse.jdt.internal.compiler.ast.Assignment)3 ConstructorDeclaration (org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration)3 EqualExpression (org.eclipse.jdt.internal.compiler.ast.EqualExpression)3 NameReference (org.eclipse.jdt.internal.compiler.ast.NameReference)3 NullLiteral (org.eclipse.jdt.internal.compiler.ast.NullLiteral)3 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 AbstractMethodDeclaration (org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration)2