use of org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding in project bazel-jdt-java-toolchain by salesforce.
the class ReferenceExpression method checkNullAnnotations.
protected void checkNullAnnotations(BlockScope scope) {
CompilerOptions compilerOptions = scope.compilerOptions();
if (compilerOptions.isAnnotationBasedNullAnalysisEnabled) {
if (this.expectedType == null || !NullAnnotationMatching.hasContradictions(this.expectedType)) {
// otherwise assume it has been reported and we can do nothing here
ImplicitNullAnnotationVerifier.ensureNullnessIsKnown(this.binding, scope);
// TODO: simplify by using this.freeParameters?
int len;
int expectedlen = this.binding.parameters.length;
int providedLen = this.descriptor.parameters.length;
if (this.receiverPrecedesParameters) {
// one parameter is 'consumed' as the receiver
providedLen--;
TypeBinding descriptorParameter = this.descriptor.parameters[0];
if ((descriptorParameter.tagBits & TagBits.AnnotationNullable) != 0) {
// Note: normal dereferencing of 'unchecked' values is not reported, either
final TypeBinding receiver = scope.environment().createAnnotatedType(this.binding.declaringClass, new AnnotationBinding[] { scope.environment().getNonNullAnnotation() });
scope.problemReporter().referenceExpressionArgumentNullityMismatch(this, receiver, descriptorParameter, this.descriptor, -1, NullAnnotationMatching.NULL_ANNOTATIONS_MISMATCH);
}
}
boolean isVarArgs = false;
if (this.binding.isVarargs()) {
isVarArgs = (providedLen == expectedlen) ? !this.descriptor.parameters[expectedlen - 1].isCompatibleWith(this.binding.parameters[expectedlen - 1]) : true;
// binding parameters will be padded from InferenceContext18.getParameter()
len = providedLen;
} else {
len = Math.min(expectedlen, providedLen);
}
for (int i = 0; i < len; i++) {
TypeBinding descriptorParameter = this.descriptor.parameters[i + (this.receiverPrecedesParameters ? 1 : 0)];
TypeBinding bindingParameter = InferenceContext18.getParameter(this.binding.parameters, i, isVarArgs);
TypeBinding bindingParameterToCheck;
if (bindingParameter.isPrimitiveType() && !descriptorParameter.isPrimitiveType()) {
// replace primitive types by boxed equivalent for checking, e.g. int -> @NonNull Integer
bindingParameterToCheck = scope.environment().createAnnotatedType(scope.boxing(bindingParameter), new AnnotationBinding[] { scope.environment().getNonNullAnnotation() });
} else {
bindingParameterToCheck = bindingParameter;
}
NullAnnotationMatching annotationStatus = NullAnnotationMatching.analyse(bindingParameterToCheck, descriptorParameter, FlowInfo.UNKNOWN);
if (annotationStatus.isAnyMismatch()) {
// immediate reporting:
scope.problemReporter().referenceExpressionArgumentNullityMismatch(this, bindingParameter, descriptorParameter, this.descriptor, i, annotationStatus);
}
}
TypeBinding returnType = this.binding.returnType;
if (!returnType.isPrimitiveType()) {
if (this.binding.isConstructor()) {
returnType = scope.environment().createAnnotatedType(this.receiverType, new AnnotationBinding[] { scope.environment().getNonNullAnnotation() });
}
NullAnnotationMatching annotationStatus = NullAnnotationMatching.analyse(this.descriptor.returnType, returnType, FlowInfo.UNKNOWN);
if (annotationStatus.isAnyMismatch()) {
scope.problemReporter().illegalReturnRedefinition(this, this.descriptor, annotationStatus.isUnchecked(), returnType);
}
}
}
}
}
use of org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding in project bazel-jdt-java-toolchain by salesforce.
the class AnnotationMirrorImpl method convertJDTArrayToReflectionArray.
/**
* Convert an array of JDT types as obtained from ElementValuePair.getValue()
* (e.g., an Object[] containing IntConstant elements) to the type expected by
* a reflective method invocation (e.g., int[]).
* <p>
* This does not handle arrays of Class, but it does handle primitives, enum constants,
* and types such as String.
* @param jdtValue the actual value returned by ElementValuePair.getValue() or MethodBinding.getDefault()
* @param jdtType the return type of the annotation method binding
* @param expectedType the type that the invoker of the method is expecting; must be an array type
* @return an Object which is, e.g., an int[]; or null, if an array cannot be created.
*/
private Object convertJDTArrayToReflectionArray(Object jdtValue, TypeBinding jdtType, Class<?> expectedType) {
assert null != expectedType && expectedType.isArray();
if (!jdtType.isArrayType()) {
// that there's some sort of syntax error.
return null;
}
Object[] jdtArray;
// See bug 261969: it's legal to pass a solo element for an array-typed value
if (jdtValue != null && !(jdtValue instanceof Object[])) {
// Create an array of the expected type
jdtArray = (Object[]) Array.newInstance(jdtValue.getClass(), 1);
jdtArray[0] = jdtValue;
} else {
jdtArray = (Object[]) jdtValue;
}
TypeBinding jdtLeafType = jdtType.leafComponentType();
Class<?> expectedLeafType = expectedType.getComponentType();
final int length = jdtArray.length;
final Object returnArray = Array.newInstance(expectedLeafType, length);
for (int i = 0; i < length; ++i) {
Object jdtElementValue = jdtArray[i];
if (expectedLeafType.isPrimitive() || String.class.equals(expectedLeafType)) {
if (jdtElementValue instanceof Constant) {
if (boolean.class.equals(expectedLeafType)) {
Array.setBoolean(returnArray, i, ((Constant) jdtElementValue).booleanValue());
} else if (byte.class.equals(expectedLeafType)) {
Array.setByte(returnArray, i, ((Constant) jdtElementValue).byteValue());
} else if (char.class.equals(expectedLeafType)) {
Array.setChar(returnArray, i, ((Constant) jdtElementValue).charValue());
} else if (double.class.equals(expectedLeafType)) {
Array.setDouble(returnArray, i, ((Constant) jdtElementValue).doubleValue());
} else if (float.class.equals(expectedLeafType)) {
Array.setFloat(returnArray, i, ((Constant) jdtElementValue).floatValue());
} else if (int.class.equals(expectedLeafType)) {
Array.setInt(returnArray, i, ((Constant) jdtElementValue).intValue());
} else if (long.class.equals(expectedLeafType)) {
Array.setLong(returnArray, i, ((Constant) jdtElementValue).longValue());
} else if (short.class.equals(expectedLeafType)) {
Array.setShort(returnArray, i, ((Constant) jdtElementValue).shortValue());
} else if (String.class.equals(expectedLeafType)) {
Array.set(returnArray, i, ((Constant) jdtElementValue).stringValue());
}
} else {
// Primitive or string is expected, but our actual value cannot be coerced into one.
// TODO: if the actual value is an array of primitives, should we unpack the first one?
Factory.setArrayMatchingDummyValue(returnArray, i, expectedLeafType);
}
} else if (expectedLeafType.isEnum()) {
Object returnVal = null;
if (jdtLeafType != null && jdtLeafType.isEnum() && jdtElementValue instanceof FieldBinding) {
FieldBinding binding = (FieldBinding) jdtElementValue;
try {
Field returnedField = null;
returnedField = expectedLeafType.getField(new String(binding.name));
if (null != returnedField) {
returnVal = returnedField.get(null);
}
} catch (NoSuchFieldException nsfe) {
// return null
} catch (IllegalAccessException iae) {
// return null
}
}
Array.set(returnArray, i, returnVal);
} else if (expectedLeafType.isAnnotation()) {
// member value is expected to be an annotation type. Wrap it in an Annotation proxy.
Object returnVal = null;
if (jdtLeafType.isAnnotationType() && jdtElementValue instanceof AnnotationBinding) {
AnnotationMirrorImpl annoMirror = (AnnotationMirrorImpl) _env.getFactory().newAnnotationMirror((AnnotationBinding) jdtElementValue);
returnVal = Proxy.newProxyInstance(expectedLeafType.getClassLoader(), new Class[] { expectedLeafType }, annoMirror);
}
Array.set(returnArray, i, returnVal);
} else {
Array.set(returnArray, i, null);
}
}
return returnArray;
}
use of org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding in project bazel-jdt-java-toolchain by salesforce.
the class ElementsImpl method getAllAnnotationMirrors.
/**
* Return all the annotation mirrors on this element, including inherited annotations.
* Annotations are inherited only if the annotation type is meta-annotated with @Inherited,
* and the annotation is on a class: e.g., annotations are not inherited for interfaces, methods,
* or fields.
*/
@Override
public List<? extends AnnotationMirror> getAllAnnotationMirrors(Element e) {
// if e is a class, walk up its superclass hierarchy looking for @Inherited annotations not already in the list
if (e.getKind() == ElementKind.CLASS && e instanceof TypeElementImpl) {
List<AnnotationBinding> annotations = new ArrayList<>();
// A class can only have one annotation of a particular annotation type.
Set<ReferenceBinding> annotationTypes = new HashSet<>();
ReferenceBinding binding = (ReferenceBinding) ((TypeElementImpl) e)._binding;
boolean checkIfInherited = false;
while (null != binding) {
if (binding instanceof ParameterizedTypeBinding) {
binding = ((ParameterizedTypeBinding) binding).genericType();
}
for (AnnotationBinding annotation : Factory.getPackedAnnotationBindings(binding.getAnnotations())) {
if (annotation == null)
continue;
ReferenceBinding annotationType = annotation.getAnnotationType();
if (checkIfInherited && (annotationType.getAnnotationTagBits() & TagBits.AnnotationInherited) == 0)
continue;
if (!annotationTypes.contains(annotationType)) {
annotationTypes.add(annotationType);
annotations.add(annotation);
}
}
binding = binding.superclass();
checkIfInherited = true;
}
List<AnnotationMirror> list = new ArrayList<>(annotations.size());
for (AnnotationBinding annotation : annotations) {
list.add(_env.getFactory().newAnnotationMirror(annotation));
}
return Collections.unmodifiableList(list);
} else {
return e.getAnnotationMirrors();
}
}
use of org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding in project bazel-jdt-java-toolchain by salesforce.
the class RoundEnvImpl method collectAnnotations.
private void collectAnnotations(ReferenceBinding[] referenceBindings) {
for (ReferenceBinding referenceBinding : referenceBindings) {
// collect all annotations from the binary types
if (referenceBinding instanceof ParameterizedTypeBinding) {
referenceBinding = ((ParameterizedTypeBinding) referenceBinding).genericType();
}
AnnotationBinding[] annotationBindings = Factory.getPackedAnnotationBindings(referenceBinding.getAnnotations());
for (AnnotationBinding annotationBinding : annotationBindings) {
TypeElement anno = (TypeElement) _factory.newElement(annotationBinding.getAnnotationType());
Element element = _factory.newElement(referenceBinding);
_annoToUnit.put(anno, element);
}
FieldBinding[] fieldBindings = referenceBinding.fields();
for (FieldBinding fieldBinding : fieldBindings) {
annotationBindings = Factory.getPackedAnnotationBindings(fieldBinding.getAnnotations());
for (AnnotationBinding annotationBinding : annotationBindings) {
TypeElement anno = (TypeElement) _factory.newElement(annotationBinding.getAnnotationType());
Element element = _factory.newElement(fieldBinding);
_annoToUnit.put(anno, element);
}
}
MethodBinding[] methodBindings = referenceBinding.methods();
for (MethodBinding methodBinding : methodBindings) {
annotationBindings = Factory.getPackedAnnotationBindings(methodBinding.getAnnotations());
for (AnnotationBinding annotationBinding : annotationBindings) {
TypeElement anno = (TypeElement) _factory.newElement(annotationBinding.getAnnotationType());
Element element = _factory.newElement(methodBinding);
_annoToUnit.put(anno, element);
}
}
ReferenceBinding[] memberTypes = referenceBinding.memberTypes();
collectAnnotations(memberTypes);
}
}
use of org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding in project j2cl by google.
the class JdtAnnotationUtils method getAnnotationBinding.
/**
* Reflective access to {@link AnnotationBinding#binding}.
*
* <p>JDT dom classes like IAnnotationBinding would not provide annotation attributes if the
* annotation class is not present in the compile (even when accessing a previously compiled class
* file). For that reason we obtain here, using reflection, the private reference to the internal
* representation, i.e. org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding to extract the
* attribute values.
*/
private static AnnotationBinding getAnnotationBinding(IAnnotationBinding annotationBinding) {
try {
// Access to the internal compiler class AnnotationBinding through the private field
// binding in the dom class implementing IAnnotationBinding.
Field bindingField = annotationBinding.getClass().getDeclaredField("binding");
bindingField.setAccessible(true);
return (AnnotationBinding) bindingField.get(annotationBinding);
} catch (ReflectiveOperationException e) {
throw new RuntimeException("Unexpectedly unable to access AnnotationBinding.binding via reflection", e);
}
}
Aggregations