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()]);
}
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);
}
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);
}
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);
}
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;
}
Aggregations