Search in sources :

Example 1 with FieldBinding

use of org.eclipse.jdt.internal.compiler.lookup.FieldBinding in project spoon by INRIA.

the class JDTTreeBuilderQuery method hasAnnotationWithType.

/**
 * Checks in an annotation if a given type is present.
 *
 * @param a
 * 		An annotation.
 * @param elementType
 * 		Expected element type of the annotation.
 * @return true if the annotation is compatible with the given element type.
 */
static boolean hasAnnotationWithType(Annotation a, CtAnnotatedElementType elementType) {
    if (a.resolvedType == null) {
        return false;
    }
    // JLS says:
    // "If an annotation of type java.lang.annotation.Target is not present on the declaration of an annotation type T,
    // then T is applicable in all declaration contexts except type parameter declarations, and in no type contexts."
    boolean shouldTargetAnnotationExists = (elementType == CtAnnotatedElementType.TYPE_USE || elementType == CtAnnotatedElementType.TYPE_PARAMETER);
    boolean targetAnnotationExists = false;
    for (AnnotationBinding annotation : a.resolvedType.getAnnotations()) {
        if (!"Target".equals(CharOperation.charToString(annotation.getAnnotationType().sourceName()))) {
            continue;
        }
        targetAnnotationExists = true;
        Object value = annotation.getElementValuePairs()[0].value;
        if (value == null) {
            continue;
        }
        if (value instanceof FieldBinding && elementType.name().equals(CharOperation.charToString(((FieldBinding) value).name))) {
            return true;
        }
        if (value.getClass().isArray()) {
            Object[] fields = (Object[]) value;
            for (Object field : fields) {
                if (field instanceof FieldBinding && elementType.name().equals(CharOperation.charToString(((FieldBinding) field).name))) {
                    return true;
                }
            }
        }
    }
    // true here means that the target annotation is not mandatory and we have not found it
    return !shouldTargetAnnotationExists && !targetAnnotationExists;
}
Also used : AnnotationBinding(org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding) FieldBinding(org.eclipse.jdt.internal.compiler.lookup.FieldBinding) ProblemFieldBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding)

Example 2 with FieldBinding

use of org.eclipse.jdt.internal.compiler.lookup.FieldBinding in project lombok by rzwitserloot.

the class PatchDelegate method addAllMethodBindings0.

private static void addAllMethodBindings0(List<BindingTuple> list, TypeBinding binding, Set<String> banList, char[] fieldName, ASTNode responsible) throws DelegateRecursion {
    if (binding instanceof SourceTypeBinding) {
        ClassScope scope = ((SourceTypeBinding) binding).scope;
        if (scope != null)
            scope.environment().globalOptions.storeAnnotations = true;
    }
    if (binding == null)
        return;
    TypeBinding inner;
    if (binding instanceof ParameterizedTypeBinding) {
        inner = ((ParameterizedTypeBinding) binding).genericType();
    } else {
        inner = binding;
    }
    if (inner instanceof SourceTypeBinding) {
        ClassScope cs = ((SourceTypeBinding) inner).scope;
        if (cs != null) {
            try {
                Reflection.classScopeBuildFieldsAndMethodsMethod.invoke(cs);
            } catch (Exception e) {
            // See 'Reflection' class for why we ignore this exception.
            }
        }
    }
    if (!(binding instanceof ReferenceBinding)) {
        return;
    }
    ReferenceBinding rb = (ReferenceBinding) binding;
    MethodBinding[] availableMethods = rb.availableMethods();
    FieldBinding[] availableFields = rb.availableFields();
    failIfContainsAnnotation(binding, availableMethods);
    failIfContainsAnnotation(binding, availableFields);
    MethodBinding[] parameterizedSigs = availableMethods;
    MethodBinding[] baseSigs = parameterizedSigs;
    if (binding instanceof ParameterizedTypeBinding) {
        baseSigs = ((ParameterizedTypeBinding) binding).genericType().availableMethods();
        if (baseSigs.length != parameterizedSigs.length) {
            // The last known state of eclipse source says this can't happen, so we rely on it,
            // but if this invariant is broken, better to go with 'arg0' naming instead of crashing.
            baseSigs = parameterizedSigs;
        }
    }
    for (int i = 0; i < parameterizedSigs.length; i++) {
        MethodBinding mb = parameterizedSigs[i];
        String sig = printSig(mb);
        if (mb.isStatic())
            continue;
        if (mb.isBridge())
            continue;
        if (mb.isConstructor())
            continue;
        if (mb.isDefaultAbstract())
            continue;
        if (!mb.isPublic())
            continue;
        if (mb.isSynthetic())
            continue;
        // If add returns false, it was already in there.
        if (!banList.add(sig))
            continue;
        BindingTuple pair = new BindingTuple(mb, baseSigs[i], fieldName, responsible);
        list.add(pair);
    }
    addAllMethodBindings0(list, rb.superclass(), banList, fieldName, responsible);
    ReferenceBinding[] interfaces = rb.superInterfaces();
    if (interfaces != null) {
        for (ReferenceBinding iface : interfaces) addAllMethodBindings0(list, iface, banList, fieldName, responsible);
    }
}
Also used : ParameterizedTypeBinding(org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding) ParameterizedTypeBinding(org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding) TypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding) SourceTypeBinding(org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding) BaseTypeBinding(org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding) UnresolvedReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.UnresolvedReferenceBinding) ReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding) ClassScope(org.eclipse.jdt.internal.compiler.lookup.ClassScope) FieldBinding(org.eclipse.jdt.internal.compiler.lookup.FieldBinding) MethodBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding) SourceTypeBinding(org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding)

Example 3 with FieldBinding

use of org.eclipse.jdt.internal.compiler.lookup.FieldBinding in project spoon by INRIA.

the class ContextBuilder method getVariableDeclaration.

@SuppressWarnings("unchecked")
private <T, U extends CtVariable<T>> U getVariableDeclaration(final String name, final Class<U> clazz) {
    final CoreFactory coreFactory = jdtTreeBuilder.getFactory().Core();
    final TypeFactory typeFactory = jdtTreeBuilder.getFactory().Type();
    final ClassFactory classFactory = jdtTreeBuilder.getFactory().Class();
    final InterfaceFactory interfaceFactory = jdtTreeBuilder.getFactory().Interface();
    final FieldFactory fieldFactory = jdtTreeBuilder.getFactory().Field();
    final ReferenceBuilder referenceBuilder = jdtTreeBuilder.getReferencesBuilder();
    final Environment environment = jdtTreeBuilder.getFactory().getEnvironment();
    // there is some extra work to do if we are looking for CtFields (and subclasses)
    final boolean lookingForFields = clazz == null || coreFactory.createField().getClass().isAssignableFrom(clazz);
    // try to find the variable on stack beginning with the most recent element
    for (final ASTPair astPair : stack) {
        // the variable may have been declared directly by one of these elements
        final ScopeRespectingVariableScanner<U> scanner = new ScopeRespectingVariableScanner(name, clazz);
        astPair.element.accept(scanner);
        if (scanner.getResult() != null) {
            return scanner.getResult();
        }
        // the variable may have been declared in a super class/interface
        if (lookingForFields && astPair.node instanceof TypeDeclaration) {
            final TypeDeclaration nodeDeclaration = (TypeDeclaration) astPair.node;
            final Deque<ReferenceBinding> referenceBindings = new ArrayDeque<>();
            // add super class if any
            if (nodeDeclaration.superclass != null && nodeDeclaration.superclass.resolvedType instanceof ReferenceBinding) {
                referenceBindings.push((ReferenceBinding) nodeDeclaration.superclass.resolvedType);
            }
            // add interfaces if any
            if (nodeDeclaration.superInterfaces != null) {
                for (final TypeReference tr : nodeDeclaration.superInterfaces) {
                    if (tr.resolvedType instanceof ReferenceBinding) {
                        referenceBindings.push((ReferenceBinding) tr.resolvedType);
                    }
                }
            }
            while (!referenceBindings.isEmpty()) {
                final ReferenceBinding referenceBinding = referenceBindings.pop();
                for (final FieldBinding fieldBinding : referenceBinding.fields()) {
                    if (name.equals(new String(fieldBinding.readableName()))) {
                        final String qualifiedNameOfParent = new String(referenceBinding.readableName());
                        final CtType parentOfField = referenceBinding.isClass() ? classFactory.create(qualifiedNameOfParent) : interfaceFactory.create(qualifiedNameOfParent);
                        U field = (U) fieldFactory.create(parentOfField, EnumSet.noneOf(ModifierKind.class), referenceBuilder.getTypeReference(fieldBinding.type), name);
                        return field.setExtendedModifiers(JDTTreeBuilderQuery.getModifiers(fieldBinding.modifiers, true, false));
                    }
                }
                // add super class if any
                final ReferenceBinding superclass = referenceBinding.superclass();
                if (superclass != null) {
                    referenceBindings.push(superclass);
                }
                // add interfaces if any
                final ReferenceBinding[] interfaces = referenceBinding.superInterfaces();
                if (interfaces != null) {
                    for (ReferenceBinding rb : interfaces) {
                        referenceBindings.push(rb);
                    }
                }
            }
        }
    }
    // the variable may have been imported statically from another class/interface
    if (lookingForFields) {
        final CtReference potentialReferenceToField = referenceBuilder.getDeclaringReferenceFromImports(name.toCharArray());
        if (potentialReferenceToField != null && potentialReferenceToField instanceof CtTypeReference) {
            final CtTypeReference typeReference = (CtTypeReference) potentialReferenceToField;
            try {
                final Class classOfType = typeReference.getActualClass();
                if (classOfType != null) {
                    final CtType declaringTypeOfField = typeReference.isInterface() ? interfaceFactory.get(classOfType) : classFactory.get(classOfType);
                    final CtField field = declaringTypeOfField.getField(name);
                    if (field != null) {
                        return (U) field;
                    }
                }
            } catch (final SpoonClassNotFoundException scnfe) {
                // field that has been imported statically from another class (or interface).
                if (environment.getNoClasspath()) {
                    // assume a constant value according to JLS.
                    if (name.toUpperCase().equals(name)) {
                        final CtType parentOfField = classFactory.create(typeReference.getQualifiedName());
                        // it is the best thing we can do
                        final CtField field = coreFactory.createField();
                        field.setParent(parentOfField);
                        field.setSimpleName(name);
                        // it is the best thing we can do
                        field.setType(typeFactory.nullType());
                        return (U) field;
                    }
                }
            }
        }
    }
    return null;
}
Also used : FieldFactory(spoon.reflect.factory.FieldFactory) ClassFactory(spoon.reflect.factory.ClassFactory) ReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding) CtReference(spoon.reflect.reference.CtReference) CtTypeReference(spoon.reflect.reference.CtTypeReference) CtField(spoon.reflect.declaration.CtField) SpoonClassNotFoundException(spoon.support.SpoonClassNotFoundException) TypeReference(org.eclipse.jdt.internal.compiler.ast.TypeReference) CtTypeReference(spoon.reflect.reference.CtTypeReference) InterfaceFactory(spoon.reflect.factory.InterfaceFactory) CoreFactory(spoon.reflect.factory.CoreFactory) ArrayDeque(java.util.ArrayDeque) CtType(spoon.reflect.declaration.CtType) FieldBinding(org.eclipse.jdt.internal.compiler.lookup.FieldBinding) Environment(spoon.compiler.Environment) TypeFactory(spoon.reflect.factory.TypeFactory) TypeDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration)

Example 4 with FieldBinding

use of org.eclipse.jdt.internal.compiler.lookup.FieldBinding in project spoon by INRIA.

the class JDTTreeBuilder method visit.

@Override
public boolean visit(SingleNameReference singleNameReference, BlockScope scope) {
    if (singleNameReference.binding instanceof FieldBinding) {
        context.enter(helper.createFieldAccess(singleNameReference), singleNameReference);
    } else if (singleNameReference.binding instanceof VariableBinding) {
        context.enter(helper.createVariableAccess(singleNameReference), singleNameReference);
    } else if (singleNameReference.binding instanceof TypeBinding) {
        context.enter(factory.Code().createTypeAccessWithoutCloningReference(references.getTypeReference((TypeBinding) singleNameReference.binding)), singleNameReference);
    } else if (singleNameReference.binding instanceof ProblemBinding) {
        if (context.stack.peek().element instanceof CtInvocation && Character.isUpperCase(CharOperation.charToString(singleNameReference.token).charAt(0))) {
            context.enter(helper.createTypeAccessNoClasspath(singleNameReference), singleNameReference);
        } else {
            context.enter(helper.createFieldAccessNoClasspath(singleNameReference), singleNameReference);
        }
    } else if (singleNameReference.binding == null) {
        CtExpression access = helper.createVariableAccessNoClasspath(singleNameReference);
        if (access == null) {
            access = helper.createTypeAccessNoClasspath(singleNameReference);
        }
        context.enter(access, singleNameReference);
    }
    return true;
}
Also used : CtInvocation(spoon.reflect.code.CtInvocation) CtExpression(spoon.reflect.code.CtExpression) TypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding) FieldBinding(org.eclipse.jdt.internal.compiler.lookup.FieldBinding) VariableBinding(org.eclipse.jdt.internal.compiler.lookup.VariableBinding) ProblemBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemBinding)

Example 5 with FieldBinding

use of org.eclipse.jdt.internal.compiler.lookup.FieldBinding in project spoon by INRIA.

the class JDTTreeBuilderHelper method createVariableAccess.

/**
 * Creates a variable or a field access from its qualified name.
 *
 * @param qualifiedNameReference
 * 		Used to build the variable access. See all sub methods of this class to understand its usage.
 * @return a variable access.
 */
<T> CtVariableAccess<T> createVariableAccess(QualifiedNameReference qualifiedNameReference) {
    long[] positions = qualifiedNameReference.sourcePositions;
    int sourceStart = qualifiedNameReference.sourceStart();
    int sourceEnd = qualifiedNameReference.sourceEnd();
    if (qualifiedNameReference.indexOfFirstFieldBinding < positions.length) {
        sourceEnd = (int) (positions[qualifiedNameReference.indexOfFirstFieldBinding] >>> 32) - 2;
    }
    CtVariableAccess<T> va;
    CtVariableReference<T> ref;
    boolean fromAssignment = isLhsAssignment(jdtTreeBuilder.getContextBuilder(), qualifiedNameReference);
    boolean isOtherBinding = qualifiedNameReference.otherBindings == null || qualifiedNameReference.otherBindings.length == 0;
    if (qualifiedNameReference.binding instanceof FieldBinding) {
        ref = jdtTreeBuilder.getReferencesBuilder().getVariableReference(qualifiedNameReference.fieldBinding());
        ref.setPosition(jdtTreeBuilder.getPositionBuilder().buildPosition(sourceStart, sourceEnd));
        va = createFieldAccess(ref, createTargetFieldAccess(qualifiedNameReference, (CtFieldReference<Object>) ref), isOtherBinding && fromAssignment);
    } else {
        ref = jdtTreeBuilder.getReferencesBuilder().getVariableReference((VariableBinding) qualifiedNameReference.binding);
        ref.setPosition(jdtTreeBuilder.getPositionBuilder().buildPosition(sourceStart, sourceEnd));
        va = createVariableAccess(ref, isOtherBinding && fromAssignment);
    }
    ref.setPosition(jdtTreeBuilder.getPositionBuilder().buildPosition(sourceStart, sourceEnd));
    if (qualifiedNameReference.otherBindings != null) {
        // positions index;
        int i = 0;
        va.setPosition(ref.getPosition());
        sourceStart = (int) (positions[qualifiedNameReference.indexOfFirstFieldBinding - 1] >>> 32);
        for (FieldBinding b : qualifiedNameReference.otherBindings) {
            isOtherBinding = qualifiedNameReference.otherBindings.length == i + 1;
            CtFieldAccess<T> other = createFieldAccess(jdtTreeBuilder.getReferencesBuilder().<T>getVariableReference(b, qualifiedNameReference.tokens[i + 1]), va, isOtherBinding && fromAssignment);
            // set source position of fa
            if (i + qualifiedNameReference.indexOfFirstFieldBinding >= qualifiedNameReference.otherBindings.length) {
                sourceEnd = qualifiedNameReference.sourceEnd();
            } else {
                sourceEnd = (int) (positions[qualifiedNameReference.indexOfFirstFieldBinding + i + 1] >>> 32) - 2;
            }
            other.setPosition(jdtTreeBuilder.getPositionBuilder().buildPosition(sourceStart, sourceEnd));
            va = other;
            i++;
        }
    } else if (!(qualifiedNameReference.binding instanceof FieldBinding) && qualifiedNameReference.tokens.length > 1) {
        sourceStart = (int) (positions[0] >>> 32);
        for (int i = 1; i < qualifiedNameReference.tokens.length; i++) {
            isOtherBinding = qualifiedNameReference.tokens.length == i + 1;
            CtFieldAccess<T> other = createFieldAccess(jdtTreeBuilder.getReferencesBuilder().<T>getVariableReference(null, qualifiedNameReference.tokens[i]), va, isOtherBinding && fromAssignment);
            // set source position of va;
            sourceEnd = (int) (positions[i]);
            va.setPosition(jdtTreeBuilder.getPositionBuilder().buildPosition(sourceStart, sourceEnd));
            va = other;
        }
    }
    va.setPosition(jdtTreeBuilder.getPositionBuilder().buildPosition(qualifiedNameReference.sourceStart(), qualifiedNameReference.sourceEnd()));
    return va;
}
Also used : CtFieldAccess(spoon.reflect.code.CtFieldAccess) FieldBinding(org.eclipse.jdt.internal.compiler.lookup.FieldBinding) VariableBinding(org.eclipse.jdt.internal.compiler.lookup.VariableBinding)

Aggregations

FieldBinding (org.eclipse.jdt.internal.compiler.lookup.FieldBinding)5 ReferenceBinding (org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding)2 TypeBinding (org.eclipse.jdt.internal.compiler.lookup.TypeBinding)2 VariableBinding (org.eclipse.jdt.internal.compiler.lookup.VariableBinding)2 ArrayDeque (java.util.ArrayDeque)1 TypeDeclaration (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration)1 TypeReference (org.eclipse.jdt.internal.compiler.ast.TypeReference)1 AnnotationBinding (org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding)1 BaseTypeBinding (org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding)1 ClassScope (org.eclipse.jdt.internal.compiler.lookup.ClassScope)1 MethodBinding (org.eclipse.jdt.internal.compiler.lookup.MethodBinding)1 ParameterizedTypeBinding (org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding)1 ProblemBinding (org.eclipse.jdt.internal.compiler.lookup.ProblemBinding)1 ProblemFieldBinding (org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding)1 SourceTypeBinding (org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding)1 UnresolvedReferenceBinding (org.eclipse.jdt.internal.compiler.lookup.UnresolvedReferenceBinding)1 Environment (spoon.compiler.Environment)1 CtExpression (spoon.reflect.code.CtExpression)1 CtFieldAccess (spoon.reflect.code.CtFieldAccess)1 CtInvocation (spoon.reflect.code.CtInvocation)1