use of org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding 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;
}
use of org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding in project sonar-java by SonarSource.
the class ASTUtils method resolvePackageAnnotations.
public static IAnnotationBinding[] resolvePackageAnnotations(AST ast, String packageName) {
// See org.eclipse.jdt.core.dom.PackageBinding#getAnnotations()
BindingResolver bindingResolver = ast.getBindingResolver();
LookupEnvironment lookupEnvironment = bindingResolver.lookupEnvironment();
NameEnvironmentAnswer answer = lookupEnvironment.nameEnvironment.findType(TypeConstants.PACKAGE_INFO_NAME, CharOperation.splitOn('.', packageName.toCharArray()));
if (answer == null) {
return NO_ANNOTATIONS;
}
IBinaryType type = answer.getBinaryType();
if (type == null) {
// when there is annotations in the package-info.java file.
return NO_ANNOTATIONS;
}
IBinaryAnnotation[] binaryAnnotations = type.getAnnotations();
AnnotationBinding[] binaryInstances = BinaryTypeBinding.createAnnotations(binaryAnnotations, lookupEnvironment, type.getMissingTypeNames());
AnnotationBinding[] allInstances = AnnotationBinding.addStandardAnnotations(binaryInstances, type.getTagBits(), lookupEnvironment);
IAnnotationBinding[] domInstances = new IAnnotationBinding[allInstances.length];
for (int i = 0; i < allInstances.length; i++) {
// FIXME can be null if annotation can not be resolved e.g. due to incomplete classpath
domInstances[i] = bindingResolver.getAnnotationInstance(allInstances[i]);
}
return domInstances;
}
use of org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding in project bazel-jdt-java-toolchain by salesforce.
the class TypeReference method resolveAnnotations.
protected void resolveAnnotations(Scope scope, int location) {
Annotation[][] annotationsOnDimensions = getAnnotationsOnDimensions();
if (this.annotations != null || annotationsOnDimensions != null) {
BlockScope resolutionScope = Scope.typeAnnotationsResolutionScope(scope);
if (resolutionScope != null) {
int dimensions = this.dimensions();
if (this.annotations != null) {
TypeBinding leafComponentType = this.resolvedType.leafComponentType();
leafComponentType = resolveAnnotations(resolutionScope, this.annotations, leafComponentType);
this.resolvedType = dimensions > 0 ? scope.environment().createArrayType(leafComponentType, dimensions) : leafComponentType;
// contradictory null annotations on the type are already detected in Annotation.resolveType() (SE7 treatment)
}
if (annotationsOnDimensions != null) {
this.resolvedType = resolveAnnotations(resolutionScope, annotationsOnDimensions, this.resolvedType);
if (this.resolvedType instanceof ArrayBinding) {
long[] nullTagBitsPerDimension = ((ArrayBinding) this.resolvedType).nullTagBitsPerDimension;
if (nullTagBitsPerDimension != null) {
for (int i = 0; i < dimensions; i++) {
// skip last annotations at [dimensions] (concerns the leaf type)
if ((nullTagBitsPerDimension[i] & TagBits.AnnotationNullMASK) == TagBits.AnnotationNullMASK) {
scope.problemReporter().contradictoryNullAnnotations(annotationsOnDimensions[i]);
nullTagBitsPerDimension[i] = 0;
}
}
}
}
}
}
}
if (scope.compilerOptions().isAnnotationBasedNullAnalysisEnabled && this.resolvedType != null && (this.resolvedType.tagBits & TagBits.AnnotationNullMASK) == 0 && !this.resolvedType.isTypeVariable() && !this.resolvedType.isWildcard() && location != 0 && scope.hasDefaultNullnessFor(location, this.sourceStart)) {
if (location == Binding.DefaultLocationTypeBound && this.resolvedType.id == TypeIds.T_JavaLangObject) {
scope.problemReporter().implicitObjectBoundNoNullDefault(this);
} else {
LookupEnvironment environment = scope.environment();
AnnotationBinding[] annots = new AnnotationBinding[] { environment.getNonNullAnnotation() };
this.resolvedType = environment.createAnnotatedType(this.resolvedType, annots);
}
}
}
use of org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding in project bazel-jdt-java-toolchain by salesforce.
the class ASTNode method resolveAnnotations.
/**
* Resolve annotations, and check duplicates, answers combined tagBits
* for recognized standard annotations. Return null if nothing new is
* resolved.
*/
public static AnnotationBinding[] resolveAnnotations(BlockScope scope, Annotation[] sourceAnnotations, Binding recipient, boolean copySE8AnnotationsToType) {
AnnotationBinding[] annotations = null;
int length = sourceAnnotations == null ? 0 : sourceAnnotations.length;
if (recipient != null) {
switch(recipient.kind()) {
case Binding.PACKAGE:
PackageBinding packageBinding = (PackageBinding) recipient;
if ((packageBinding.tagBits & TagBits.AnnotationResolved) != 0)
return annotations;
packageBinding.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
break;
case Binding.TYPE:
case Binding.GENERIC_TYPE:
ReferenceBinding type = (ReferenceBinding) recipient;
if ((type.tagBits & TagBits.AnnotationResolved) != 0)
return annotations;
type.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
if (length > 0) {
annotations = new AnnotationBinding[length];
type.setAnnotations(annotations, false);
}
break;
case Binding.METHOD:
MethodBinding method = (MethodBinding) recipient;
if ((method.tagBits & TagBits.AnnotationResolved) != 0)
return annotations;
method.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
if (length > 0) {
annotations = new AnnotationBinding[length];
method.setAnnotations(annotations, false);
}
break;
case Binding.FIELD:
FieldBinding field = (FieldBinding) recipient;
if ((field.tagBits & TagBits.AnnotationResolved) != 0)
return annotations;
field.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
if (length > 0) {
annotations = new AnnotationBinding[length];
field.setAnnotations(annotations, false);
}
break;
case Binding.RECORD_COMPONENT:
RecordComponentBinding rcb = (RecordComponentBinding) recipient;
if ((rcb.tagBits & TagBits.AnnotationResolved) != 0)
return annotations;
rcb.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
if (length > 0) {
annotations = new AnnotationBinding[length];
rcb.setAnnotations(annotations, false);
}
break;
case Binding.LOCAL:
LocalVariableBinding local = (LocalVariableBinding) recipient;
if ((local.tagBits & TagBits.AnnotationResolved) != 0)
return annotations;
local.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
if (length > 0) {
annotations = new AnnotationBinding[length];
local.setAnnotations(annotations, scope, false);
}
break;
case Binding.TYPE_PARAMETER:
case Binding.TYPE_USE:
// deliberately don't set the annotation resolved tagbits, it is not material and also we are working with a dummy static object.
annotations = new AnnotationBinding[length];
break;
case Binding.MODULE:
ModuleBinding module = (ModuleBinding) recipient;
if ((module.tagBits & TagBits.AnnotationResolved) != 0)
return annotations;
module.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
if (length > 0) {
annotations = new AnnotationBinding[length];
module.setAnnotations(annotations, scope, false);
}
break;
default:
return annotations;
}
}
if (sourceAnnotations == null)
return annotations;
for (int i = 0; i < length; i++) {
Annotation annotation = sourceAnnotations[i];
final Binding annotationRecipient = annotation.recipient;
if (annotationRecipient != null && recipient != null) {
// only local and field can share annotations and their types.
switch(recipient.kind()) {
case Binding.TYPE_USE:
if (annotations != null) {
// need to fill the instances array
for (int j = 0; j < length; j++) {
annotations[j] = sourceAnnotations[j].getCompilerAnnotation();
}
}
break;
case Binding.FIELD:
FieldBinding field = (FieldBinding) recipient;
field.tagBits = ((FieldBinding) annotationRecipient).tagBits;
if (annotations != null) {
// need to fill the instances array
for (int j = 0; j < length; j++) {
Annotation annot = sourceAnnotations[j];
annotations[j] = annot.getCompilerAnnotation();
}
}
break;
case Binding.RECORD_COMPONENT:
RecordComponentBinding recordComponentBinding = (RecordComponentBinding) recipient;
recordComponentBinding.tagBits = ((RecordComponentBinding) annotationRecipient).tagBits;
if (annotations != null) {
// need to fill the instances array
for (int j = 0; j < length; j++) {
Annotation annot = sourceAnnotations[j];
annotations[j] = annot.getCompilerAnnotation();
}
}
break;
case Binding.LOCAL:
LocalVariableBinding local = (LocalVariableBinding) recipient;
// Note for JDK>=14, this could be LVB or RCB, hence typecasting to VB
long otherLocalTagBits = ((VariableBinding) annotationRecipient).tagBits;
// Make sure we retain the TagBits.IsArgument bit
local.tagBits = otherLocalTagBits | (local.tagBits & TagBits.IsArgument);
if ((otherLocalTagBits & TagBits.AnnotationSuppressWarnings) == 0) {
// need to fill the instances array
if (annotations != null) {
for (int j = 0; j < length; j++) {
Annotation annot = sourceAnnotations[j];
annotations[j] = annot.getCompilerAnnotation();
}
}
} else if (annotations != null) {
// One of the annotations at least is a SuppressWarnings annotation
LocalDeclaration localDeclaration = local.declaration;
int declarationSourceEnd = localDeclaration.declarationSourceEnd;
int declarationSourceStart = localDeclaration.declarationSourceStart;
for (int j = 0; j < length; j++) {
Annotation annot = sourceAnnotations[j];
/*
* Annotations are shared between two locals, but we still need to record
* the suppress annotation range for the second local
*/
AnnotationBinding annotationBinding = annot.getCompilerAnnotation();
annotations[j] = annotationBinding;
if (annotationBinding != null) {
final ReferenceBinding annotationType = annotationBinding.getAnnotationType();
if (annotationType != null && annotationType.id == TypeIds.T_JavaLangSuppressWarnings) {
annot.recordSuppressWarnings(scope, declarationSourceStart, declarationSourceEnd, scope.compilerOptions().suppressWarnings);
}
}
}
}
// copy the se8 annotations.
if (annotationRecipient instanceof RecordComponentBinding && copySE8AnnotationsToType)
copySE8AnnotationsToType(scope, recipient, sourceAnnotations, false);
break;
}
return annotations;
} else {
annotation.recipient = recipient;
annotation.resolveType(scope);
// null if receiver is a package binding
if (annotations != null) {
annotations[i] = annotation.getCompilerAnnotation();
}
}
}
/* See if the recipient is meta-annotated with @Repeatable and if so validate constraints. We can't do this during resolution of @Repeatable itself as @Target and
@Retention etc could come later
*/
if (recipient != null && recipient.isTaggedRepeatable()) {
for (int i = 0; i < length; i++) {
Annotation annotation = sourceAnnotations[i];
ReferenceBinding annotationType = annotations[i] != null ? annotations[i].getAnnotationType() : null;
if (annotationType != null && annotationType.id == TypeIds.T_JavaLangAnnotationRepeatable)
annotation.checkRepeatableMetaAnnotation(scope);
}
}
// check duplicate annotations
if (annotations != null && length > 1) {
// only copy after 1st duplicate is detected
AnnotationBinding[] distinctAnnotations = annotations;
Map implicitContainerAnnotations = null;
for (int i = 0; i < length; i++) {
AnnotationBinding annotation = distinctAnnotations[i];
if (annotation == null)
continue;
ReferenceBinding annotationType = annotation.getAnnotationType();
boolean foundDuplicate = false;
ContainerAnnotation container = null;
for (int j = i + 1; j < length; j++) {
AnnotationBinding otherAnnotation = distinctAnnotations[j];
if (otherAnnotation == null)
continue;
if (TypeBinding.equalsEquals(otherAnnotation.getAnnotationType(), annotationType)) {
if (distinctAnnotations == annotations) {
System.arraycopy(distinctAnnotations, 0, distinctAnnotations = new AnnotationBinding[length], 0, length);
}
// report/process it only once
distinctAnnotations[j] = null;
if (annotationType.isRepeatableAnnotationType()) {
Annotation persistibleAnnotation = sourceAnnotations[i].getPersistibleAnnotation();
if (persistibleAnnotation instanceof ContainerAnnotation)
container = (ContainerAnnotation) persistibleAnnotation;
if (container == null) {
// first encounter with a duplicate.
ReferenceBinding containerAnnotationType = annotationType.containerAnnotationType();
container = new ContainerAnnotation(sourceAnnotations[i], containerAnnotationType, scope);
if (implicitContainerAnnotations == null)
implicitContainerAnnotations = new HashMap(3);
implicitContainerAnnotations.put(containerAnnotationType, sourceAnnotations[i]);
Annotation.checkForInstancesOfRepeatableWithRepeatingContainerAnnotation(scope, annotationType, sourceAnnotations);
}
container.addContainee(sourceAnnotations[j]);
} else {
foundDuplicate = true;
scope.problemReporter().duplicateAnnotation(sourceAnnotations[j], scope.compilerOptions().sourceLevel);
}
}
}
if (container != null) {
container.resolveType(scope);
}
if (foundDuplicate) {
scope.problemReporter().duplicateAnnotation(sourceAnnotations[i], scope.compilerOptions().sourceLevel);
}
}
// Check for presence of repeating annotation together with the containing annotation
if (implicitContainerAnnotations != null) {
for (int i = 0; i < length; i++) {
if (distinctAnnotations[i] == null)
continue;
Annotation annotation = sourceAnnotations[i];
ReferenceBinding annotationType = distinctAnnotations[i].getAnnotationType();
if (implicitContainerAnnotations.containsKey(annotationType)) {
scope.problemReporter().repeatedAnnotationWithContainer((Annotation) implicitContainerAnnotations.get(annotationType), annotation);
}
}
}
}
if (copySE8AnnotationsToType)
copySE8AnnotationsToType(scope, recipient, sourceAnnotations, false);
return annotations;
}
use of org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding in project bazel-jdt-java-toolchain by salesforce.
the class ASTNode method copySE8AnnotationsToType.
// When SE8 annotations feature in SE7 locations, they get attributed to the declared entity. Copy/move these to the type of the declared entity (field, local, argument etc.)
public static void copySE8AnnotationsToType(BlockScope scope, Binding recipient, Annotation[] annotations, boolean annotatingEnumerator) {
if (annotations == null || annotations.length == 0 || recipient == null)
return;
long recipientTargetMask = 0;
switch(recipient.kind()) {
case Binding.LOCAL:
recipientTargetMask = recipient.isParameter() ? TagBits.AnnotationForParameter : TagBits.AnnotationForLocalVariable;
break;
case Binding.FIELD:
recipientTargetMask = TagBits.AnnotationForField;
break;
case Binding.METHOD:
MethodBinding method = (MethodBinding) recipient;
recipientTargetMask = method.isConstructor() ? TagBits.AnnotationForConstructor : TagBits.AnnotationForMethod;
break;
case Binding.RECORD_COMPONENT:
recipientTargetMask = TagBits.AnnotationForRecordComponent;
break;
default:
return;
}
AnnotationBinding[] se8Annotations = null;
int se8count = 0;
long se8nullBits = 0;
// just any involved annotation so we have a location for error reporting
Annotation se8NullAnnotation = null;
int firstSE8 = -1;
for (int i = 0, length = annotations.length; i < length; i++) {
AnnotationBinding annotation = annotations[i].getCompilerAnnotation();
if (annotation == null)
continue;
final ReferenceBinding annotationType = annotation.getAnnotationType();
long metaTagBits = annotationType.getAnnotationTagBits();
if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
if (annotatingEnumerator) {
if ((metaTagBits & recipientTargetMask) == 0) {
scope.problemReporter().misplacedTypeAnnotations(annotations[i], annotations[i]);
}
continue;
}
if (firstSE8 == -1)
firstSE8 = i;
if (se8Annotations == null) {
se8Annotations = new AnnotationBinding[] { annotation };
se8count = 1;
} else {
System.arraycopy(se8Annotations, 0, se8Annotations = new AnnotationBinding[se8count + 1], 0, se8count);
se8Annotations[se8count++] = annotation;
}
if (annotationType.hasNullBit(TypeIds.BitNonNullAnnotation)) {
se8nullBits |= TagBits.AnnotationNonNull;
se8NullAnnotation = annotations[i];
} else if (annotationType.hasNullBit(TypeIds.BitNullableAnnotation)) {
se8nullBits |= TagBits.AnnotationNullable;
se8NullAnnotation = annotations[i];
}
}
}
if (se8Annotations != null) {
switch(recipient.kind()) {
case Binding.LOCAL:
LocalVariableBinding local = (LocalVariableBinding) recipient;
TypeReference typeRef = local.declaration.type;
if (Annotation.isTypeUseCompatible(typeRef, scope)) {
// discard hybrid annotations on name qualified types.
local.declaration.bits |= HasTypeAnnotations;
typeRef.bits |= HasTypeAnnotations;
local.type = mergeAnnotationsIntoType(scope, se8Annotations, se8nullBits, se8NullAnnotation, typeRef, local.type);
if (scope.environment().usesNullTypeAnnotations()) {
local.tagBits &= ~(se8nullBits);
}
}
break;
case Binding.FIELD:
FieldBinding field = (FieldBinding) recipient;
SourceTypeBinding sourceType = (SourceTypeBinding) field.declaringClass;
FieldDeclaration fieldDeclaration = sourceType.scope.referenceContext.declarationOf(field);
if (Annotation.isTypeUseCompatible(fieldDeclaration.type, scope)) {
// discard hybrid annotations on name qualified types.
fieldDeclaration.bits |= HasTypeAnnotations;
fieldDeclaration.type.bits |= HasTypeAnnotations;
field.type = mergeAnnotationsIntoType(scope, se8Annotations, se8nullBits, se8NullAnnotation, fieldDeclaration.type, field.type);
if (scope.environment().usesNullTypeAnnotations()) {
field.tagBits &= ~(se8nullBits);
}
}
break;
case Binding.RECORD_COMPONENT:
RecordComponentBinding recordComponentBinding = (RecordComponentBinding) recipient;
RecordComponent recordComponent = recordComponentBinding.sourceRecordComponent();
if (Annotation.isTypeUseCompatible(recordComponent.type, scope)) {
// discard hybrid annotations on name qualified types.
recordComponent.bits |= HasTypeAnnotations;
recordComponent.type.bits |= HasTypeAnnotations;
recordComponentBinding.type = mergeAnnotationsIntoType(scope, se8Annotations, se8nullBits, se8NullAnnotation, recordComponent.type, recordComponentBinding.type);
if (scope.environment().usesNullTypeAnnotations()) {
// TODO Bug 562478
recordComponentBinding.tagBits &= ~(se8nullBits);
}
}
break;
case Binding.METHOD:
MethodBinding method = (MethodBinding) recipient;
if (!method.isConstructor()) {
sourceType = (SourceTypeBinding) method.declaringClass;
MethodDeclaration methodDecl = (MethodDeclaration) sourceType.scope.referenceContext.declarationOf(method);
if (Annotation.isTypeUseCompatible(methodDecl.returnType, scope)) {
methodDecl.bits |= HasTypeAnnotations;
methodDecl.returnType.bits |= HasTypeAnnotations;
method.returnType = mergeAnnotationsIntoType(scope, se8Annotations, se8nullBits, se8NullAnnotation, methodDecl.returnType, method.returnType);
if (scope.environment().usesNullTypeAnnotations()) {
method.tagBits &= ~(se8nullBits);
}
}
} else {
method.setTypeAnnotations(se8Annotations);
}
break;
}
AnnotationBinding[] recipientAnnotations = recipient.getAnnotations();
int length = recipientAnnotations == null ? 0 : recipientAnnotations.length;
int newLength = 0;
for (int i = 0; i < length; i++) {
final AnnotationBinding recipientAnnotation = recipientAnnotations[i];
if (recipientAnnotation == null)
continue;
long annotationTargetMask = recipientAnnotation.getAnnotationType().getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
if (annotationTargetMask == 0 || (annotationTargetMask & recipientTargetMask) != 0)
recipientAnnotations[newLength++] = recipientAnnotation;
}
if (newLength != length) {
System.arraycopy(recipientAnnotations, 0, recipientAnnotations = new AnnotationBinding[newLength], 0, newLength);
recipient.setAnnotations(recipientAnnotations, scope, false);
}
}
}
Aggregations