package org.eclipse.jdt.internal.compiler.ast;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.ast.NullAnnotationMatching.CheckMode;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.codegen.AnnotationContext;
import org.eclipse.jdt.internal.compiler.codegen.AnnotationTargetTypeConstants;
import org.eclipse.jdt.internal.compiler.flow.FlowContext;
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.eclipse.jdt.internal.compiler.lookup.Substitution;
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
@SuppressWarnings({"rawtypes", "unchecked"})
public abstract class TypeReference extends Expression {
public static final TypeReference[] NO_TYPE_ARGUMENTS = new TypeReference[0];
public static enum AnnotationPosition {
MAIN_TYPE,
LEAF_TYPE,
ANY
}
static class AnnotationCollector extends ASTVisitor {
List annotationContexts;
Expression typeReference;
int targetType;
int info = 0;
int info2 = 0;
LocalVariableBinding localVariable;
Annotation[][] annotationsOnDimensions;
int dimensions;
Wildcard currentWildcard;
public AnnotationCollector(
TypeParameter typeParameter,
int targetType,
int typeParameterIndex,
List annotationContexts) {
this.annotationContexts = annotationContexts;
this.typeReference = typeParameter.type;
this.targetType = targetType;
this.info = typeParameterIndex;
}
public AnnotationCollector(
LocalDeclaration localDeclaration,
int targetType,
LocalVariableBinding localVariable,
List annotationContexts) {
this.annotationContexts = annotationContexts;
this.typeReference = localDeclaration.type;
this.targetType = targetType;
this.localVariable = localVariable;
}
public AnnotationCollector(
LocalDeclaration localDeclaration,
int targetType,
int parameterIndex,
List annotationContexts) {
this.annotationContexts = annotationContexts;
this.typeReference = localDeclaration.type;
this.targetType = targetType;
this.info = parameterIndex;
}
public AnnotationCollector(
TypeReference typeReference,
int targetType,
List annotationContexts) {
this.annotationContexts = annotationContexts;
this.typeReference = typeReference;
this.targetType = targetType;
}
public AnnotationCollector(
Expression typeReference,
int targetType,
int info,
List annotationContexts) {
this.annotationContexts = annotationContexts;
this.typeReference = typeReference;
this.info = info;
this.targetType = targetType;
}
public AnnotationCollector(
TypeReference typeReference,
int targetType,
int info,
int typeIndex,
List annotationContexts) {
this.annotationContexts = annotationContexts;
this.typeReference = typeReference;
this.info = info;
this.targetType = targetType;
this.info2 = typeIndex;
}
public AnnotationCollector(
TypeReference typeReference,
int targetType,
int info,
List annotationContexts,
Annotation[][] annotationsOnDimensions,
int dimensions) {
this.annotationContexts = annotationContexts;
this.typeReference = typeReference;
this.info = info;
this.targetType = targetType;
this.annotationsOnDimensions = annotationsOnDimensions;
this.dimensions = dimensions;
}
private boolean internalVisit(Annotation annotation) {
AnnotationContext annotationContext = null;
if (annotation.isRuntimeTypeInvisible()) {
annotationContext = new AnnotationContext(annotation, this.typeReference, this.targetType, AnnotationContext.INVISIBLE);
} else if (annotation.isRuntimeTypeVisible()) {
annotationContext = new AnnotationContext(annotation, this.typeReference, this.targetType, AnnotationContext.VISIBLE);
}
if (annotationContext != null) {
annotationContext.wildcard = this.currentWildcard;
switch(this.targetType) {
case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER :
case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER :
case AnnotationTargetTypeConstants.CLASS_EXTENDS:
case AnnotationTargetTypeConstants.METHOD_FORMAL_PARAMETER :
case AnnotationTargetTypeConstants.THROWS :
case AnnotationTargetTypeConstants.EXCEPTION_PARAMETER :
case AnnotationTargetTypeConstants.INSTANCEOF:
case AnnotationTargetTypeConstants.NEW :
case AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE :
case AnnotationTargetTypeConstants.METHOD_REFERENCE :
annotationContext.info = this.info;
break;
case AnnotationTargetTypeConstants.LOCAL_VARIABLE :
case AnnotationTargetTypeConstants.RESOURCE_VARIABLE :
annotationContext.variableBinding = this.localVariable;
break;
case AnnotationTargetTypeConstants.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT :
case AnnotationTargetTypeConstants.METHOD_INVOCATION_TYPE_ARGUMENT :
case AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT :
case AnnotationTargetTypeConstants.METHOD_REFERENCE_TYPE_ARGUMENT :
case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND :
case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND :
case AnnotationTargetTypeConstants.CAST:
annotationContext.info2 = this.info2;
annotationContext.info = this.info;
break;
case AnnotationTargetTypeConstants.FIELD :
case AnnotationTargetTypeConstants.METHOD_RETURN :
case AnnotationTargetTypeConstants.METHOD_RECEIVER :
break;
}
this.annotationContexts.add(annotationContext);
}
return true;
}
@Override
public boolean visit(MarkerAnnotation annotation, BlockScope scope) {
return internalVisit(annotation);
}
@Override
public boolean visit(NormalAnnotation annotation, BlockScope scope) {
return internalVisit(annotation);
}
@Override
public boolean visit(SingleMemberAnnotation annotation, BlockScope scope) {
return internalVisit(annotation);
}
@Override
public boolean visit(Wildcard wildcard, BlockScope scope) {
this.currentWildcard = wildcard;
return true;
}
@Override
public boolean visit(Argument argument, BlockScope scope) {
if ((argument.bits & ASTNode.IsUnionType) == 0) {
return true;
}
for (int i = 0, max = this.localVariable.initializationCount; i < max; i++) {
int startPC = this.localVariable.initializationPCs[i << 1];
int endPC = this.localVariable.initializationPCs[(i << 1) + 1];
if (startPC != endPC) {
return true;
}
}
return false;
}
@Override
public boolean visit(Argument argument, ClassScope scope) {
if ((argument.bits & ASTNode.IsUnionType) == 0) {
return true;
}
for (int i = 0, max = this.localVariable.initializationCount; i < max; i++) {
int startPC = this.localVariable.initializationPCs[i << 1];
int endPC = this.localVariable.initializationPCs[(i << 1) + 1];
if (startPC != endPC) {
return true;
}
}
return false;
}
@Override
public boolean visit(LocalDeclaration localDeclaration, BlockScope scope) {
for (int i = 0, max = this.localVariable.initializationCount; i < max; i++) {
int startPC = this.localVariable.initializationPCs[i << 1];
int endPC = this.localVariable.initializationPCs[(i << 1) + 1];
if (startPC != endPC) {
return true;
}
}
return false;
}
@Override
public void endVisit(Wildcard wildcard, BlockScope scope) {
this.currentWildcard = null;
}
}
public static final TypeReference baseTypeReference(int baseType, int dim, Annotation [][] dimAnnotations) {
if (dim == 0) {
switch (baseType) {
case (TypeIds.T_void) :
return new SingleTypeReference(TypeBinding.VOID.simpleName, 0);
case (TypeIds.T_boolean) :
return new SingleTypeReference(TypeBinding.BOOLEAN.simpleName, 0);
case (TypeIds.T_char) :
return new SingleTypeReference(TypeBinding.CHAR.simpleName, 0);
case (TypeIds.T_float) :
return new SingleTypeReference(TypeBinding.FLOAT.simpleName, 0);
case (TypeIds.T_double) :
return new SingleTypeReference(TypeBinding.DOUBLE.simpleName, 0);
case (TypeIds.T_byte) :
return new SingleTypeReference(TypeBinding.BYTE.simpleName, 0);
case (TypeIds.T_short) :
return new SingleTypeReference(TypeBinding.SHORT.simpleName, 0);
case (TypeIds.T_int) :
return new SingleTypeReference(TypeBinding.INT.simpleName, 0);
default :
return new SingleTypeReference(TypeBinding.LONG.simpleName, 0);
}
}
switch (baseType) {
case (TypeIds.T_void) :
return new ArrayTypeReference(TypeBinding.VOID.simpleName, dim, dimAnnotations, 0);
case (TypeIds.T_boolean) :
return new ArrayTypeReference(TypeBinding.BOOLEAN.simpleName, dim, dimAnnotations, 0);
case (TypeIds.T_char) :
return new ArrayTypeReference(TypeBinding.CHAR.simpleName, dim, dimAnnotations, 0);
case (TypeIds.T_float) :
return new ArrayTypeReference(TypeBinding.FLOAT.simpleName, dim, dimAnnotations, 0);
case (TypeIds.T_double) :
return new ArrayTypeReference(TypeBinding.DOUBLE.simpleName, dim, dimAnnotations, 0);
case (TypeIds.T_byte) :
return new ArrayTypeReference(TypeBinding.BYTE.simpleName, dim, dimAnnotations, 0);
case (TypeIds.T_short) :
return new ArrayTypeReference(TypeBinding.SHORT.simpleName, dim, dimAnnotations, 0);
case (TypeIds.T_int) :
return new ArrayTypeReference(TypeBinding.INT.simpleName, dim, dimAnnotations, 0);
default :
return new ArrayTypeReference(TypeBinding.LONG.simpleName, dim, dimAnnotations, 0);
}
}
public static final TypeReference baseTypeReference(int baseType, int dim) {
return baseTypeReference(baseType, dim, null);
}
public Annotation[][] annotations = null;
public void aboutToResolve(Scope scope) {
}
private void checkYieldUsage(Scope currentScope) {
char [][] qName = getTypeName();
String name = qName != null && qName[0] != null ? new String(qName[0]) : null;
long sourceLevel = currentScope.compilerOptions().sourceLevel;
if (sourceLevel < ClassFileConstants.JDK13 || name == null ||
!("yield".equals(new String(name))))
return;
if (sourceLevel == ClassFileConstants.JDK13 && currentScope.compilerOptions().enablePreviewFeatures) {
currentScope.problemReporter().switchExpressionsYieldTypeDeclarationError(this);
} else {
currentScope.problemReporter().switchExpressionsYieldTypeDeclarationWarning(this);
}
}
@Override
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
return flowInfo;
}
public void checkBounds(Scope scope) {
}
public abstract TypeReference augmentTypeWithAdditionalDimensions(int additionalDimensions, Annotation[][] additionalAnnotations, boolean isVarargs);
protected Annotation[][] getMergedAnnotationsOnDimensions(int additionalDimensions, Annotation[][] additionalAnnotations) {
Annotation[][] annotationsOnDimensions = this.getAnnotationsOnDimensions(true);
int dimensions = this.dimensions();
if (annotationsOnDimensions == null && additionalAnnotations == null)
return null;
final int totalDimensions = dimensions + additionalDimensions;
Annotation [][] mergedAnnotations = new Annotation[totalDimensions][];
if (annotationsOnDimensions != null) {
for (int i = 0; i < dimensions; i++) {
mergedAnnotations[i] = annotationsOnDimensions[i];
}
}
if (additionalAnnotations != null) {
for (int i = dimensions, j = 0; i < totalDimensions; i++, j++) {
mergedAnnotations[i] = additionalAnnotations[j];
}
}
return mergedAnnotations;
}
public int dimensions() {
return 0;
}
public int () {
return 0;
}
public AnnotationContext[] getAllAnnotationContexts(int targetType) {
List allAnnotationContexts = new ArrayList();
AnnotationCollector collector = new AnnotationCollector(this, targetType, allAnnotationContexts);
this.traverse(collector, (BlockScope) null);
return (AnnotationContext[]) allAnnotationContexts.toArray(new AnnotationContext[allAnnotationContexts.size()]);
}
public void getAllAnnotationContexts(int targetType, int info, List allAnnotationContexts) {
AnnotationCollector collector = new AnnotationCollector(this, targetType, info, allAnnotationContexts);
this.traverse(collector, (BlockScope) null);
}
public void getAllAnnotationContexts(int targetType, int info, List allAnnotationContexts, Annotation [] se7Annotations) {
AnnotationCollector collector = new AnnotationCollector(this, targetType, info, allAnnotationContexts);
for (int i = 0, length = se7Annotations == null ? 0 : se7Annotations.length; i < length; i++) {
Annotation annotation = se7Annotations[i];
annotation.traverse(collector, (BlockScope) null);
}
this.traverse(collector, (BlockScope) null);
}
public void getAllAnnotationContexts(int targetType, int info, List allAnnotationContexts, Annotation[][] annotationsOnDimensions, int dimensions) {
AnnotationCollector collector = new AnnotationCollector(this, targetType, info, allAnnotationContexts, annotationsOnDimensions, dimensions);
this.traverse(collector, (BlockScope) null);
if (annotationsOnDimensions != null) {
for (int i = 0, max = annotationsOnDimensions.length; i < max; i++) {
Annotation[] annotationsOnDimension = annotationsOnDimensions[i];
if (annotationsOnDimension != null) {
for (int j = 0, max2 = annotationsOnDimension.length; j< max2; j++) {
annotationsOnDimension[j].traverse(collector, (BlockScope) null);
}
}
}
}
}
public void getAllAnnotationContexts(int targetType, int info, int typeIndex, List allAnnotationContexts) {
AnnotationCollector collector = new AnnotationCollector(this, targetType, info, typeIndex, allAnnotationContexts);
this.traverse(collector, (BlockScope) null);
}
public void getAllAnnotationContexts(int targetType, List allAnnotationContexts) {
AnnotationCollector collector = new AnnotationCollector(this, targetType, allAnnotationContexts);
this.traverse(collector, (BlockScope) null);
}
public Annotation[][] getAnnotationsOnDimensions() {
return getAnnotationsOnDimensions(false);
}
public TypeReference [][] getTypeArguments() {
return null;
}
public Annotation[][] getAnnotationsOnDimensions(boolean useSourceOrder) {
return null;
}
public void setAnnotationsOnDimensions(Annotation [][] annotationsOnDimensions) {
}
public abstract char[] getLastToken();
public char [][] getParameterizedTypeName(){
return getTypeName();
}
protected abstract TypeBinding getTypeBinding(Scope scope);
public abstract char [][] getTypeName() ;
protected TypeBinding internalResolveType(Scope scope, int location) {
this.constant = Constant.NotAConstant;
checkYieldUsage(scope);
if (this.resolvedType != null) {
if (this.resolvedType.isValidBinding()) {
return this.resolvedType;
} else {
switch (this.resolvedType.problemId()) {
case ProblemReasons.NotFound :
case ProblemReasons.NotVisible :
case ProblemReasons.InheritedNameHidesEnclosingName :
TypeBinding type = this.resolvedType.closestMatch();
if (type == null) return null;
return scope.environment().convertToRawType(type, false );
default :
return null;
}
}
}
boolean hasError;
TypeBinding type = this.resolvedType = getTypeBinding(scope);
if (type == null) {
return null;
} else if ((hasError = !type.isValidBinding()) == true) {
if (this.isTypeNameVar(scope)) {
reportVarIsNotAllowedHere(scope);
} else {
reportInvalidType(scope);
}
switch (type.problemId()) {
case ProblemReasons.NotFound :
case ProblemReasons.NotVisible :
case ProblemReasons.InheritedNameHidesEnclosingName :
type = type.closestMatch();
if (type == null) return null;
break;
default :
return null;
}
}
if (type.isArrayType() && ((ArrayBinding) type).leafComponentType == TypeBinding.VOID) {
scope.problemReporter().cannotAllocateVoidArray(this);
return null;
}
if (!(this instanceof QualifiedTypeReference)
&& isTypeUseDeprecated(type, scope)) {
reportDeprecatedType(type, scope);
}
type = scope.environment().convertToRawType(type, false );
if (type.leafComponentType().isRawType()
&& (this.bits & ASTNode.IgnoreRawTypeCheck) == 0
&& scope.compilerOptions().getSeverity(CompilerOptions.RawTypeReference) != ProblemSeverities.Ignore) {
scope.problemReporter().rawTypeReference(this, type);
}
if (hasError) {
resolveAnnotations(scope, 0);
return type;
} else {
this.resolvedType = type;
resolveAnnotations(scope, location);
return this.resolvedType;
}
}
@Override
public boolean isTypeReference() {
return true;
}
public boolean isWildcard() {
return false;
}
public boolean isUnionType() {
return false;
}
public boolean isVarargs() {
return (this.bits & ASTNode.IsVarArgs) != 0;
}
public boolean isParameterizedTypeReference() {
return false;
}
protected void reportDeprecatedType(TypeBinding type, Scope scope, int index) {
scope.problemReporter().deprecatedType(type, this, index);
}
protected void reportDeprecatedType(TypeBinding type, Scope scope) {
scope.problemReporter().deprecatedType(type, this, Integer.MAX_VALUE);
}
protected void reportInvalidType(Scope scope) {
scope.problemReporter().invalidType(this, this.resolvedType);
}
protected void reportVarIsNotAllowedHere(Scope scope) {
scope.problemReporter().varIsNotAllowedHere(this);
}
public TypeBinding resolveSuperType(ClassScope scope) {
TypeBinding superType = resolveType(scope);
if (superType == null) return null;
if (superType.isTypeVariable()) {
if (this.resolvedType.isValidBinding()) {
this.resolvedType = new ProblemReferenceBinding(getTypeName(), (ReferenceBinding)this.resolvedType, ProblemReasons.IllegalSuperTypeVariable);
reportInvalidType(scope);
}
return null;
}
return superType;
}
@Override
public final TypeBinding resolveType(BlockScope blockScope) {
return resolveType(blockScope, true );
}
public TypeBinding resolveType(BlockScope scope, boolean checkBounds) {
return resolveType(scope, checkBounds, 0);
}
public TypeBinding resolveType(BlockScope scope, boolean checkBounds, int location) {
return internalResolveType(scope, location);
}
@Override
public TypeBinding resolveType(ClassScope scope) {
return resolveType(scope, 0);
}
public TypeBinding resolveType(ClassScope scope, int location) {
return internalResolveType(scope, location);
}
public TypeBinding resolveTypeArgument(BlockScope blockScope, ReferenceBinding genericType, int rank) {
return resolveType(blockScope, true , Binding.DefaultLocationTypeArgument);
}
public TypeBinding resolveTypeArgument(ClassScope classScope, ReferenceBinding genericType, int rank) {
ReferenceBinding ref = classScope.referenceContext.binding;
boolean pauseHierarchyCheck = false;
try {
if (ref.isHierarchyBeingConnected()) {
pauseHierarchyCheck = (ref.tagBits & TagBits.PauseHierarchyCheck) == 0;
ref.tagBits |= TagBits.PauseHierarchyCheck;
}
return resolveType(classScope, Binding.DefaultLocationTypeArgument);
} finally {
if (pauseHierarchyCheck) {
ref.tagBits &= ~TagBits.PauseHierarchyCheck;
}
}
}
@Override
public abstract void traverse(ASTVisitor visitor, BlockScope scope);
@Override
public abstract void traverse(ASTVisitor visitor, ClassScope scope);
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;
}
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++) {
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);
}
}
}
public int getAnnotatableLevels() {
return 1;
}
protected void checkIllegalNullAnnotations(Scope scope, TypeReference[] typeArguments) {
if (scope.environment().usesNullTypeAnnotations() && typeArguments != null) {
for (int i = 0; i < typeArguments.length; i++) {
TypeReference arg = typeArguments[i];
if (arg.resolvedType != null)
arg.checkIllegalNullAnnotation(scope);
}
}
}
protected void checkNullConstraints(Scope scope, Substitution substitution, TypeBinding[] variables, int rank) {
if (variables != null && variables.length > rank) {
TypeBinding variable = variables[rank];
if (variable.hasNullTypeAnnotations()) {
if (NullAnnotationMatching.analyse(variable, this.resolvedType, null, substitution, -1, null, CheckMode.BOUND_CHECK).isAnyMismatch())
scope.problemReporter().nullityMismatchTypeArgument(variable, this.resolvedType, this);
}
}
checkIllegalNullAnnotation(scope);
}
protected void checkIllegalNullAnnotation(Scope scope) {
if (this.resolvedType.leafComponentType().isBaseType() && hasNullTypeAnnotation(AnnotationPosition.LEAF_TYPE))
scope.problemReporter().illegalAnnotationForBaseType(this, this.annotations[0], this.resolvedType.tagBits & TagBits.AnnotationNullMASK);
}
public Annotation findAnnotation(long nullTagBits) {
if (this.annotations != null) {
Annotation[] innerAnnotations = this.annotations[this.annotations.length-1];
if (innerAnnotations != null) {
int annBit = nullTagBits == TagBits.AnnotationNonNull ? TypeIds.BitNonNullAnnotation : TypeIds.BitNullableAnnotation;
for (int i = 0; i < innerAnnotations.length; i++) {
if (innerAnnotations[i] != null && innerAnnotations[i].hasNullBit(annBit))
return innerAnnotations[i];
}
}
}
return null;
}
public boolean hasNullTypeAnnotation(AnnotationPosition position) {
if (this.annotations != null) {
if (position == AnnotationPosition.MAIN_TYPE) {
Annotation[] innerAnnotations = this.annotations[this.annotations.length-1];
return containsNullAnnotation(innerAnnotations);
} else {
for (Annotation[] someAnnotations: this.annotations) {
if (containsNullAnnotation(someAnnotations))
return true;
}
}
}
return false;
}
public static boolean containsNullAnnotation(Annotation[] annotations) {
if (annotations != null) {
for (int i = 0; i < annotations.length; i++) {
if (annotations[i] != null && (annotations[i].hasNullBit(TypeIds.BitNonNullAnnotation|TypeIds.BitNullableAnnotation)))
return true;
}
}
return false;
}
public TypeReference[] getTypeReferences() {
return new TypeReference [] { this };
}
public boolean isBaseTypeReference() {
return false;
}
public boolean isTypeNameVar(Scope scope) {
CompilerOptions compilerOptions = scope != null ? scope.compilerOptions() : null;
if (compilerOptions != null && compilerOptions.sourceLevel < ClassFileConstants.JDK10) {
return false;
}
char[][] typeName = this.getTypeName();
return typeName.length == 1 && CharOperation.equals(typeName[0], TypeConstants.VAR);
}
}