Search in sources :

Example 1 with MethodDeclaration

use of org.eclipse.jdt.internal.compiler.ast.MethodDeclaration in project che by eclipse.

the class Util method getUnresolvedJavaElement.

/**
     * Return the java element corresponding to the given compiler binding.
     */
public static JavaElement getUnresolvedJavaElement(MethodBinding methodBinding, WorkingCopyOwner workingCopyOwner, BindingsToNodesMap bindingsToNodes) {
    JavaElement unresolvedJavaElement = getUnresolvedJavaElement(methodBinding.declaringClass, workingCopyOwner, bindingsToNodes);
    if (unresolvedJavaElement == null || unresolvedJavaElement.getElementType() != IJavaElement.TYPE) {
        return null;
    }
    IType declaringType = (IType) unresolvedJavaElement;
    org.eclipse.jdt.internal.compiler.ast.ASTNode node = bindingsToNodes == null ? null : bindingsToNodes.get(methodBinding);
    if (node != null && !declaringType.isBinary()) {
        if (node instanceof AnnotationMethodDeclaration) {
            // node is an AnnotationMethodDeclaration
            AnnotationMethodDeclaration typeMemberDeclaration = (AnnotationMethodDeclaration) node;
            // annotation type members don't have parameters
            return (JavaElement) declaringType.getMethod(String.valueOf(typeMemberDeclaration.selector), CharOperation.NO_STRINGS);
        } else {
            // node is an MethodDeclaration
            MethodDeclaration methodDeclaration = (MethodDeclaration) node;
            Argument[] arguments = methodDeclaration.arguments;
            String[] parameterSignatures;
            if (arguments != null) {
                parameterSignatures = new String[arguments.length];
                for (int i = 0; i < arguments.length; i++) {
                    Argument argument = arguments[i];
                    TypeReference typeReference = argument.type;
                    int arrayDim = typeReference.dimensions();
                    String typeSig = Signature.createTypeSignature(CharOperation.concatWith(typeReference.getTypeName(), '.'), false);
                    if (arrayDim > 0) {
                        typeSig = Signature.createArraySignature(typeSig, arrayDim);
                    }
                    parameterSignatures[i] = typeSig;
                }
            } else {
                parameterSignatures = CharOperation.NO_STRINGS;
            }
            return (JavaElement) declaringType.getMethod(String.valueOf(methodDeclaration.selector), parameterSignatures);
        }
    } else {
        // case of method not in the created AST, or a binary method
        org.eclipse.jdt.internal.compiler.lookup.MethodBinding original = methodBinding.original();
        String selector = original.isConstructor() ? declaringType.getElementName() : new String(original.selector);
        boolean isBinary = declaringType.isBinary();
        ReferenceBinding enclosingType = original.declaringClass.enclosingType();
        // Static inner types' constructors don't get receivers (https://bugs.eclipse.org/bugs/show_bug.cgi?id=388137)
        boolean isInnerBinaryTypeConstructor = isBinary && original.isConstructor() && !original.declaringClass.isStatic() && enclosingType != null;
        TypeBinding[] parameters = original.parameters;
        int length = parameters == null ? 0 : parameters.length;
        int declaringIndex = isInnerBinaryTypeConstructor ? 1 : 0;
        String[] parameterSignatures = new String[declaringIndex + length];
        if (isInnerBinaryTypeConstructor)
            parameterSignatures[0] = new String(enclosingType.genericTypeSignature()).replace('/', '.');
        for (int i = 0; i < length; i++) {
            char[] signature = parameters[i].genericTypeSignature();
            if (isBinary) {
                signature = CharOperation.replaceOnCopy(signature, '/', '.');
            } else {
                signature = toUnresolvedTypeSignature(signature);
            }
            parameterSignatures[declaringIndex + i] = new String(signature);
        }
        IMethod result = declaringType.getMethod(selector, parameterSignatures);
        if (isBinary)
            return (JavaElement) result;
        if (// if perfect match (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=249567 )
        result.exists())
            return (JavaElement) result;
        IMethod[] methods = null;
        try {
            methods = declaringType.getMethods();
        } catch (JavaModelException e) {
            // declaring type doesn't exist
            return null;
        }
        IMethod[] candidates = Member.findMethods(result, methods);
        if (candidates == null || candidates.length == 0)
            return null;
        return (JavaElement) candidates[0];
    }
}
Also used : MethodBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding) JavaModelException(org.eclipse.jdt.core.JavaModelException) AnnotationMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration) Argument(org.eclipse.jdt.internal.compiler.ast.Argument) AnnotationMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration) MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration) TypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding) ASTNode(org.eclipse.jdt.internal.compiler.ast.ASTNode) ReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding) IType(org.eclipse.jdt.core.IType) JavaElement(org.eclipse.jdt.internal.core.JavaElement) IJavaElement(org.eclipse.jdt.core.IJavaElement) TypeReference(org.eclipse.jdt.internal.compiler.ast.TypeReference) UnionTypeReference(org.eclipse.jdt.internal.compiler.ast.UnionTypeReference) IMethod(org.eclipse.jdt.core.IMethod)

Example 2 with MethodDeclaration

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

the class HandleSetter method createSetterForField.

public void createSetterForField(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("@Setter is only supported on a class or a field.");
        return;
    }
    FieldDeclaration field = (FieldDeclaration) fieldNode.get();
    TypeReference fieldType = copyType(field.type, source);
    boolean isBoolean = isBoolean(fieldType);
    String setterName = toSetterName(fieldNode, isBoolean);
    boolean shouldReturnThis = shouldReturnThis(fieldNode);
    if (setterName == null) {
        fieldNode.addWarning("Not generating setter for this field: It does not fit your @Accessors prefix list.");
        return;
    }
    int modifier = toEclipseModifier(level) | (field.modifiers & ClassFileConstants.AccStatic);
    for (String altName : toAllSetterNames(fieldNode, isBoolean)) {
        switch(methodExists(altName, fieldNode, false, 1)) {
            case EXISTS_BY_LOMBOK:
                return;
            case EXISTS_BY_USER:
                if (whineIfExists) {
                    String altNameExpl = "";
                    if (!altName.equals(setterName))
                        altNameExpl = String.format(" (%s)", altName);
                    fieldNode.addWarning(String.format("Not generating %s(): A method with that name already exists%s", setterName, altNameExpl));
                }
                return;
            default:
            case NOT_EXISTS:
        }
    }
    MethodDeclaration method = createSetter((TypeDeclaration) fieldNode.up().get(), fieldNode, setterName, shouldReturnThis, modifier, sourceNode, onMethod, onParam);
    injectMethod(fieldNode.up(), method);
}
Also used : MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) ASTNode(org.eclipse.jdt.internal.compiler.ast.ASTNode) TypeReference(org.eclipse.jdt.internal.compiler.ast.TypeReference) FieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration)

Example 3 with MethodDeclaration

use of org.eclipse.jdt.internal.compiler.ast.MethodDeclaration 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 4 with MethodDeclaration

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

the class HandleSynchronized method handle.

@Override
public void handle(AnnotationValues<Synchronized> annotation, Annotation source, EclipseNode annotationNode) {
    handleFlagUsage(annotationNode, ConfigurationKeys.SYNCHRONIZED_FLAG_USAGE, "@Synchronized");
    int p1 = source.sourceStart - 1;
    int p2 = source.sourceStart - 2;
    long pos = (((long) p1) << 32) | p2;
    EclipseNode methodNode = annotationNode.up();
    if (methodNode == null || methodNode.getKind() != Kind.METHOD || !(methodNode.get() instanceof MethodDeclaration)) {
        annotationNode.addError("@Synchronized is legal only on methods.");
        return;
    }
    MethodDeclaration method = (MethodDeclaration) methodNode.get();
    if (method.isAbstract()) {
        annotationNode.addError("@Synchronized is legal only on concrete methods.");
        return;
    }
    char[] lockName = createLockField(annotation, annotationNode, method.isStatic(), true);
    if (lockName == null)
        return;
    if (method.statements == null)
        return;
    Block block = new Block(0);
    setGeneratedBy(block, source);
    block.statements = method.statements;
    // Positions for in-method generated nodes are special
    block.sourceEnd = method.bodyEnd;
    block.sourceStart = method.bodyStart;
    Expression lockVariable;
    if (method.isStatic())
        lockVariable = new QualifiedNameReference(new char[][] { methodNode.up().getName().toCharArray(), lockName }, new long[] { pos, pos }, p1, p2);
    else {
        lockVariable = new FieldReference(lockName, pos);
        ThisReference thisReference = new ThisReference(p1, p2);
        setGeneratedBy(thisReference, source);
        ((FieldReference) lockVariable).receiver = thisReference;
    }
    setGeneratedBy(lockVariable, source);
    method.statements = new Statement[] { new SynchronizedStatement(lockVariable, block, 0, 0) };
    // Positions for in-method generated nodes are special
    method.statements[0].sourceEnd = method.bodyEnd;
    method.statements[0].sourceStart = method.bodyStart;
    setGeneratedBy(method.statements[0], source);
    methodNode.rebuild();
}
Also used : FieldReference(org.eclipse.jdt.internal.compiler.ast.FieldReference) Expression(org.eclipse.jdt.internal.compiler.ast.Expression) ArrayAllocationExpression(org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression) MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) EclipseNode(lombok.eclipse.EclipseNode) Block(org.eclipse.jdt.internal.compiler.ast.Block) ThisReference(org.eclipse.jdt.internal.compiler.ast.ThisReference) SynchronizedStatement(org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement) QualifiedNameReference(org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference)

Example 5 with MethodDeclaration

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

the class HandleToString method generateToString.

public void generateToString(EclipseNode typeNode, EclipseNode errorNode, List<String> excludes, List<String> includes, boolean includeFieldNames, Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess) {
    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)) != 0;
    if (typeDecl == null || notAClass) {
        errorNode.addError("@ToString is only supported on a class or enum.");
    }
    if (callSuper == null) {
        try {
            callSuper = ((Boolean) ToString.class.getMethod("callSuper").getDefaultValue()).booleanValue();
        } catch (Exception ignore) {
        }
    }
    List<EclipseNode> nodesForToString = new ArrayList<EclipseNode>();
    if (includes != null) {
        for (EclipseNode child : typeNode.down()) {
            if (child.getKind() != Kind.FIELD)
                continue;
            FieldDeclaration fieldDecl = (FieldDeclaration) child.get();
            if (includes.contains(new String(fieldDecl.name)))
                nodesForToString.add(child);
        }
    } else {
        for (EclipseNode child : typeNode.down()) {
            if (child.getKind() != Kind.FIELD)
                continue;
            FieldDeclaration fieldDecl = (FieldDeclaration) child.get();
            if (!filterField(fieldDecl))
                continue;
            //Skip excluded fields.
            if (excludes != null && excludes.contains(new String(fieldDecl.name)))
                continue;
            nodesForToString.add(child);
        }
    }
    switch(methodExists("toString", typeNode, 0)) {
        case NOT_EXISTS:
            MethodDeclaration toString = createToString(typeNode, nodesForToString, includeFieldNames, callSuper, errorNode.get(), fieldAccess);
            injectMethod(typeNode, toString);
            break;
        case EXISTS_BY_LOMBOK:
            break;
        default:
        case EXISTS_BY_USER:
            if (whineIfExists) {
                errorNode.addWarning("Not generating toString(): A method with that name already exists");
            }
    }
}
Also used : MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) ArrayList(java.util.ArrayList) EclipseNode(lombok.eclipse.EclipseNode) ToString(lombok.ToString) ToString(lombok.ToString) TypeDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) FieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration)

Aggregations

MethodDeclaration (org.eclipse.jdt.internal.compiler.ast.MethodDeclaration)40 ReturnStatement (org.eclipse.jdt.internal.compiler.ast.ReturnStatement)22 Statement (org.eclipse.jdt.internal.compiler.ast.Statement)19 TypeReference (org.eclipse.jdt.internal.compiler.ast.TypeReference)19 ArrayList (java.util.ArrayList)18 ThisReference (org.eclipse.jdt.internal.compiler.ast.ThisReference)17 EclipseNode (lombok.eclipse.EclipseNode)16 SingleNameReference (org.eclipse.jdt.internal.compiler.ast.SingleNameReference)16 AbstractMethodDeclaration (org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration)15 Argument (org.eclipse.jdt.internal.compiler.ast.Argument)15 MessageSend (org.eclipse.jdt.internal.compiler.ast.MessageSend)15 QualifiedTypeReference (org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference)15 FieldDeclaration (org.eclipse.jdt.internal.compiler.ast.FieldDeclaration)14 IfStatement (org.eclipse.jdt.internal.compiler.ast.IfStatement)14 FieldReference (org.eclipse.jdt.internal.compiler.ast.FieldReference)13 TypeDeclaration (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration)12 Expression (org.eclipse.jdt.internal.compiler.ast.Expression)11 SingleTypeReference (org.eclipse.jdt.internal.compiler.ast.SingleTypeReference)10 ParameterizedQualifiedTypeReference (org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference)8 ASTNode (org.eclipse.jdt.internal.compiler.ast.ASTNode)6