Search in sources :

Example 1 with ElementValuePair

use of org.eclipse.jdt.internal.compiler.lookup.ElementValuePair in project bazel-jdt-java-toolchain by salesforce.

the class Factory method getUnpackedAnnotationBindings.

/* Unwrap container annotations into the repeated annotations, return an array of bindings that includes the container and the containees.
	*/
public static AnnotationBinding[] getUnpackedAnnotationBindings(AnnotationBinding[] annotations) {
    int length = annotations == null ? 0 : annotations.length;
    if (length == 0)
        return annotations;
    List<AnnotationBinding> unpackedAnnotations = new ArrayList<>();
    for (int i = 0; i < length; i++) {
        AnnotationBinding annotation = annotations[i];
        if (annotation == null)
            continue;
        unpackedAnnotations.add(annotation);
        ReferenceBinding annotationType = annotation.getAnnotationType();
        MethodBinding[] values = annotationType.getMethods(TypeConstants.VALUE);
        if (values == null || values.length != 1)
            continue;
        MethodBinding value = values[0];
        if (value.returnType.dimensions() != 1)
            continue;
        TypeBinding containeeType = value.returnType.leafComponentType();
        if (containeeType == null || !containeeType.isAnnotationType() || !containeeType.isRepeatableAnnotationType())
            continue;
        if (// $IDENTITY-COMPARISON$
        containeeType.containerAnnotationType() != annotationType)
            continue;
        // We have a kosher container: unwrap the contained annotations.
        ElementValuePair[] elementValuePairs = annotation.getElementValuePairs();
        for (ElementValuePair elementValuePair : elementValuePairs) {
            if (CharOperation.equals(elementValuePair.getName(), TypeConstants.VALUE)) {
                Object[] containees = (Object[]) elementValuePair.getValue();
                for (Object object : containees) {
                    unpackedAnnotations.add((AnnotationBinding) object);
                }
                break;
            }
        }
    }
    return unpackedAnnotations.toArray(new AnnotationBinding[unpackedAnnotations.size()]);
}
Also used : AnnotationBinding(org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding) ElementValuePair(org.eclipse.jdt.internal.compiler.lookup.ElementValuePair) ParameterizedTypeBinding(org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding) TypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding) BaseTypeBinding(org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding) ArrayList(java.util.ArrayList) MethodBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding) ReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding)

Example 2 with ElementValuePair

use of org.eclipse.jdt.internal.compiler.lookup.ElementValuePair in project bazel-jdt-java-toolchain by salesforce.

the class AnnotationMirrorImpl method invoke.

/*
	 * Used by getAnnotation(), which returns a reflective proxy of the annotation class.  When processors then
	 * invoke methods such as value() on the annotation proxy, this method is called.
	 * <p>
	 * A challenge here is that the processor was not necessarily compiled against the same annotation
	 * definition that the compiler is looking at right now, not to mention that the annotation itself
	 * may be defective in source.  So the actual type of the value may be quite different than the
	 * type expected by the caller, which will result in a ClassCastException, which is ugly for the
	 * processor to try to catch.  So we try to catch and correct this type mismatch where possible.
	 * <p>
	 * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
	 */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if (this._binding == null)
        return null;
    final String methodName = method.getName();
    if (args == null || args.length == 0) {
        if (methodName.equals("hashCode")) {
            // $NON-NLS-1$
            return Integer.valueOf(hashCode());
        } else if (methodName.equals("toString")) {
            // $NON-NLS-1$
            return toString();
        } else if (methodName.equals("annotationType")) {
            // $NON-NLS-1$
            return proxy.getClass().getInterfaces()[0];
        }
    } else if (args.length == 1 && methodName.equals("equals")) {
        // $NON-NLS-1$
        return Boolean.valueOf(equals(args[0]));
    }
    // If it's not one of the above methods, it must be an annotation member, so it cannot take any arguments
    if (args != null && args.length != 0) {
        // $NON-NLS-1$ //$NON-NLS-2$
        throw new NoSuchMethodException("method " + method.getName() + formatArgs(args) + " does not exist on annotation " + toString());
    }
    final MethodBinding methodBinding = getMethodBinding(methodName);
    if (methodBinding == null) {
        // $NON-NLS-1$ //$NON-NLS-2$
        throw new NoSuchMethodException("method " + method.getName() + "() does not exist on annotation" + toString());
    }
    Object actualValue = null;
    boolean foundMethod = false;
    ElementValuePair[] pairs = _binding.getElementValuePairs();
    for (ElementValuePair pair : pairs) {
        if (methodName.equals(new String(pair.getName()))) {
            actualValue = pair.getValue();
            foundMethod = true;
            break;
        }
    }
    if (!foundMethod) {
        // couldn't find explicit value; see if there's a default
        actualValue = methodBinding.getDefaultValue();
    }
    Class<?> expectedType = method.getReturnType();
    TypeBinding actualType = methodBinding.returnType;
    return getReflectionValue(actualValue, actualType, expectedType);
}
Also used : ElementValuePair(org.eclipse.jdt.internal.compiler.lookup.ElementValuePair) TypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding) MethodBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding)

Example 3 with ElementValuePair

use of org.eclipse.jdt.internal.compiler.lookup.ElementValuePair in project bazel-jdt-java-toolchain by salesforce.

the class AnnotationMirrorImpl method getElementValues.

/**
 * @return all the members of this annotation mirror that have explicit values.
 * Default values are not included.
 */
@Override
public Map<? extends ExecutableElement, ? extends AnnotationValue> getElementValues() {
    if (this._binding == null) {
        return Collections.emptyMap();
    }
    ElementValuePair[] pairs = _binding.getElementValuePairs();
    Map<ExecutableElement, AnnotationValue> valueMap = new LinkedHashMap<>(pairs.length);
    for (ElementValuePair pair : pairs) {
        MethodBinding method = pair.getMethodBinding();
        if (method == null) {
            // ideally we should be able to create a fake ExecutableElementImpl
            continue;
        }
        ExecutableElement e = new ExecutableElementImpl(_env, method);
        AnnotationValue v = new AnnotationMemberValue(_env, pair.getValue(), method);
        valueMap.put(e, v);
    }
    return Collections.unmodifiableMap(valueMap);
}
Also used : ElementValuePair(org.eclipse.jdt.internal.compiler.lookup.ElementValuePair) ExecutableElement(javax.lang.model.element.ExecutableElement) AnnotationValue(javax.lang.model.element.AnnotationValue) MethodBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding) LinkedHashMap(java.util.LinkedHashMap)

Example 4 with ElementValuePair

use of org.eclipse.jdt.internal.compiler.lookup.ElementValuePair in project bazel-jdt-java-toolchain by salesforce.

the class AnnotationMirrorImpl method getElementValuesWithDefaults.

/**
 * @see javax.lang.model.util.Elements#getElementValuesWithDefaults(AnnotationMirror)
 * @return all the members of this annotation mirror that have explicit or default
 * values.
 */
public Map<? extends ExecutableElement, ? extends AnnotationValue> getElementValuesWithDefaults() {
    if (this._binding == null) {
        return Collections.emptyMap();
    }
    ElementValuePair[] pairs = _binding.getElementValuePairs();
    ReferenceBinding annoType = _binding.getAnnotationType();
    Map<ExecutableElement, AnnotationValue> valueMap = new LinkedHashMap<>();
    for (MethodBinding method : annoType.methods()) {
        // if binding is in ElementValuePair list, then get value from there
        boolean foundExplicitValue = false;
        for (int i = 0; i < pairs.length; ++i) {
            MethodBinding explicitBinding = pairs[i].getMethodBinding();
            if (method == explicitBinding) {
                ExecutableElement e = new ExecutableElementImpl(_env, explicitBinding);
                AnnotationValue v = new AnnotationMemberValue(_env, pairs[i].getValue(), explicitBinding);
                valueMap.put(e, v);
                foundExplicitValue = true;
                break;
            }
        }
        // else get default value if one exists
        if (!foundExplicitValue) {
            Object defaultVal = method.getDefaultValue();
            if (null != defaultVal) {
                ExecutableElement e = new ExecutableElementImpl(_env, method);
                AnnotationValue v = new AnnotationMemberValue(_env, defaultVal, method);
                valueMap.put(e, v);
            }
        }
    }
    return Collections.unmodifiableMap(valueMap);
}
Also used : ExecutableElement(javax.lang.model.element.ExecutableElement) ReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding) LinkedHashMap(java.util.LinkedHashMap) ElementValuePair(org.eclipse.jdt.internal.compiler.lookup.ElementValuePair) AnnotationValue(javax.lang.model.element.AnnotationValue) MethodBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding)

Example 5 with ElementValuePair

use of org.eclipse.jdt.internal.compiler.lookup.ElementValuePair in project bazel-jdt-java-toolchain by salesforce.

the class Factory method getPackedAnnotationBindings.

/* Wrap repeating annotations into their container, return an array of bindings.
	   Incoming array is not modified. The resulting array may be null but will not contain null
	   entries.
	*/
public static AnnotationBinding[] getPackedAnnotationBindings(AnnotationBinding[] annotations) {
    int length = annotations == null ? 0 : annotations.length;
    if (length == 0)
        return annotations;
    // only replicate if repackaging.
    AnnotationBinding[] repackagedBindings = annotations;
    for (int i = 0; i < length; i++) {
        AnnotationBinding annotation = repackagedBindings[i];
        if (annotation == null)
            continue;
        ReferenceBinding annotationType = annotation.getAnnotationType();
        if (!annotationType.isRepeatableAnnotationType())
            continue;
        ReferenceBinding containerType = annotationType.containerAnnotationType();
        if (containerType == null)
            // FUBAR.
            continue;
        MethodBinding[] values = containerType.getMethods(TypeConstants.VALUE);
        if (values == null || values.length != 1)
            // FUBAR.
            continue;
        MethodBinding value = values[0];
        if (value.returnType == null || value.returnType.dimensions() != 1 || TypeBinding.notEquals(value.returnType.leafComponentType(), annotationType))
            // FUBAR
            continue;
        // We have a kosher repeatable annotation with a kosher containing type. See if actually repeats.
        List<AnnotationBinding> containees = null;
        for (int j = i + 1; j < length; j++) {
            AnnotationBinding otherAnnotation = repackagedBindings[j];
            if (otherAnnotation == null)
                continue;
            if (otherAnnotation.getAnnotationType() == annotationType) {
                // $IDENTITY-COMPARISON$
                if (repackagedBindings == annotations)
                    System.arraycopy(repackagedBindings, 0, repackagedBindings = new AnnotationBinding[length], 0, length);
                // so it is not double packed.
                repackagedBindings[j] = null;
                if (containees == null) {
                    containees = new ArrayList<>();
                    containees.add(annotation);
                }
                containees.add(otherAnnotation);
            }
        }
        if (containees != null) {
            ElementValuePair[] elementValuePairs = new ElementValuePair[] { new ElementValuePair(TypeConstants.VALUE, containees.toArray(), value) };
            repackagedBindings[i] = new AnnotationBinding(containerType, elementValuePairs);
        }
    }
    int finalTally = 0;
    for (int i = 0; i < length; i++) {
        if (repackagedBindings[i] != null)
            finalTally++;
    }
    if (repackagedBindings == annotations && finalTally == length) {
        return annotations;
    }
    annotations = new AnnotationBinding[finalTally];
    for (int i = 0, j = 0; i < length; i++) {
        if (repackagedBindings[i] != null)
            annotations[j++] = repackagedBindings[i];
    }
    return annotations;
}
Also used : AnnotationBinding(org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding) ElementValuePair(org.eclipse.jdt.internal.compiler.lookup.ElementValuePair) MethodBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding) ReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding)

Aggregations

ElementValuePair (org.eclipse.jdt.internal.compiler.lookup.ElementValuePair)6 MethodBinding (org.eclipse.jdt.internal.compiler.lookup.MethodBinding)6 ReferenceBinding (org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding)3 TypeBinding (org.eclipse.jdt.internal.compiler.lookup.TypeBinding)3 LinkedHashMap (java.util.LinkedHashMap)2 AnnotationValue (javax.lang.model.element.AnnotationValue)2 ExecutableElement (javax.lang.model.element.ExecutableElement)2 AnnotationBinding (org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding)2 ArrayList (java.util.ArrayList)1 ASTVisitor (org.eclipse.jdt.internal.compiler.ASTVisitor)1 BaseTypeBinding (org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding)1 Binding (org.eclipse.jdt.internal.compiler.lookup.Binding)1 BlockScope (org.eclipse.jdt.internal.compiler.lookup.BlockScope)1 FieldBinding (org.eclipse.jdt.internal.compiler.lookup.FieldBinding)1 LocalVariableBinding (org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding)1 ParameterizedTypeBinding (org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding)1