package org.eclipse.jdt.internal.compiler.lookup;
import java.util.Arrays;
import java.util.Comparator;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.InvalidInputException;
import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.NullAnnotationMatching;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
abstract public class ReferenceBinding extends TypeBinding {
public char[][] compoundName;
public char[] sourceName;
public int modifiers;
public PackageBinding fPackage;
char[] fileName;
char[] constantPoolName;
char[] signature;
private SimpleLookupTable compatibleCache;
int typeBits;
protected MethodBinding [] singleAbstractMethod;
public static final ReferenceBinding LUB_GENERIC = new ReferenceBinding() {
{ this.id = TypeIds.T_undefined; }
@Override
public boolean hasTypeBit(int bit) { return false; }
};
private static final Comparator<FieldBinding> FIELD_COMPARATOR = new Comparator<FieldBinding>() {
@Override
public int compare(FieldBinding o1, FieldBinding o2) {
char[] n1 = o1.name;
char[] n2 = o2.name;
return ReferenceBinding.compare(n1, n2, n1.length, n2.length);
}
};
private static final Comparator<MethodBinding> METHOD_COMPARATOR = new Comparator<MethodBinding>() {
@Override
public int compare(MethodBinding m1, MethodBinding m2) {
char[] s1 = m1.selector;
char[] s2 = m2.selector;
int c = ReferenceBinding.compare(s1, s2, s1.length, s2.length);
return c == 0 ? m1.parameters.length - m2.parameters.length : c;
}
};
static protected ProblemMethodBinding samProblemBinding = new ProblemMethodBinding(TypeConstants.ANONYMOUS_METHOD, null, ProblemReasons.NoSuchSingleAbstractMethod);
public ReferenceBinding(ReferenceBinding prototype) {
super(prototype);
this.compoundName = prototype.compoundName;
this.sourceName = prototype.sourceName;
this.modifiers = prototype.modifiers;
this.fPackage = prototype.fPackage;
this.fileName = prototype.fileName;
this.constantPoolName = prototype.constantPoolName;
this.signature = prototype.signature;
this.compatibleCache = prototype.compatibleCache;
this.typeBits = prototype.typeBits;
this.singleAbstractMethod = prototype.singleAbstractMethod;
}
public ReferenceBinding() {
super();
}
public static FieldBinding binarySearch(char[] name, FieldBinding[] sortedFields) {
if (sortedFields == null)
return null;
int max = sortedFields.length;
if (max == 0)
return null;
int left = 0, right = max - 1, nameLength = name.length;
int mid = 0;
char[] midName;
while (left <= right) {
mid = left + (right - left) /2;
int compare = compare(name, midName = sortedFields[mid].name, nameLength, midName.length);
if (compare < 0) {
right = mid-1;
} else if (compare > 0) {
left = mid+1;
} else {
return sortedFields[mid];
}
}
return null;
}
public static long binarySearch(char[] selector, MethodBinding[] sortedMethods) {
if (sortedMethods == null)
return -1;
int max = sortedMethods.length;
if (max == 0)
return -1;
int left = 0, right = max - 1, selectorLength = selector.length;
int mid = 0;
char[] midSelector;
while (left <= right) {
mid = left + (right - left) /2;
int compare = compare(selector, midSelector = sortedMethods[mid].selector, selectorLength, midSelector.length);
if (compare < 0) {
right = mid-1;
} else if (compare > 0) {
left = mid+1;
} else {
int start = mid, end = mid;
while (start > left && CharOperation.equals(sortedMethods[start-1].selector, selector)){ start--; }
while (end < right && CharOperation.equals(sortedMethods[end+1].selector, selector)){ end++; }
return start + ((long)end<< 32);
}
}
return -1;
}
static int compare(char[] str1, char[] str2, int len1, int len2) {
int n= Math.min(len1, len2);
int i= 0;
while (n-- != 0) {
char c1= str1[i];
char c2= str2[i++];
if (c1 != c2) {
return c1 - c2;
}
}
return len1 - len2;
}
public static void sortFields(FieldBinding[] sortedFields, int left, int right) {
Arrays.sort(sortedFields, left, right, FIELD_COMPARATOR);
}
public static void sortMethods(MethodBinding[] sortedMethods, int left, int right) {
Arrays.sort(sortedMethods, left, right, METHOD_COMPARATOR);
}
static void sortMemberTypes(ReferenceBinding[] sortedMemberTypes, int left, int right) {
Arrays.sort(sortedMemberTypes, left, right, BASIC_MEMBER_TYPES_COMPARATOR);
}
static final Comparator<ReferenceBinding> BASIC_MEMBER_TYPES_COMPARATOR = (ReferenceBinding o1, ReferenceBinding o2) -> {
char[] n1 = o1.sourceName;
char[] n2 = o2.sourceName;
if (n1 == null) {
if (n2 == null) {
return 0;
}
return -1;
} else if (n2 == null) {
return 1;
}
return ReferenceBinding.compare(n1, n2, n1.length, n2.length);
};
public FieldBinding[] availableFields() {
return fields();
}
public MethodBinding[] availableMethods() {
return methods();
}
public boolean hasHierarchyCheckStarted() {
return (this.tagBits & TagBits.BeginHierarchyCheck) != 0;
}
public void setHierarchyCheckDone() {
return;
}
@Override
public boolean canBeInstantiated() {
return (this.modifiers & (ClassFileConstants.AccAbstract | ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation)) == 0;
}
public boolean canBeSeenBy(PackageBinding invocationPackage) {
if (isPublic()) return true;
if (isPrivate()) return false;
return invocationPackage == this.fPackage;
}
public boolean canBeSeenBy(ReferenceBinding receiverType, ReferenceBinding invocationType) {
if (isPublic()) return true;
if (isStatic() && (receiverType.isRawType() || receiverType.isParameterizedType()))
receiverType = receiverType.actualType();
if (TypeBinding.equalsEquals(invocationType, this) && TypeBinding.equalsEquals(invocationType, receiverType)) return true;
if (isProtected()) {
if (TypeBinding.equalsEquals(invocationType, this)) return true;
if (invocationType.fPackage == this.fPackage) return true;
TypeBinding currentType = invocationType.erasure();
TypeBinding declaringClass = enclosingType().erasure();
if (TypeBinding.equalsEquals(declaringClass, invocationType)) return true;
if (declaringClass == null) return false;
do {
if (currentType.findSuperTypeOriginatingFrom(declaringClass) != null) return true;
currentType = currentType.enclosingType();
} while (currentType != null);
return false;
}
if (isPrivate()) {
receiverCheck: {
if (!(TypeBinding.equalsEquals(receiverType, this) || TypeBinding.equalsEquals(receiverType, enclosingType()))) {
if (receiverType.isTypeVariable()) {
TypeVariableBinding typeVariable = (TypeVariableBinding) receiverType;
if (typeVariable.environment.globalOptions.complianceLevel <= ClassFileConstants.JDK1_6 && (typeVariable.isErasureBoundTo(erasure()) || typeVariable.isErasureBoundTo(enclosingType().erasure())))
break receiverCheck;
}
return false;
}
}
if (TypeBinding.notEquals(invocationType, this)) {
ReferenceBinding outerInvocationType = invocationType;
ReferenceBinding temp = outerInvocationType.enclosingType();
while (temp != null) {
outerInvocationType = temp;
temp = temp.enclosingType();
}
ReferenceBinding outerDeclaringClass = (ReferenceBinding)erasure();
temp = outerDeclaringClass.enclosingType();
while (temp != null) {
outerDeclaringClass = temp;
temp = temp.enclosingType();
}
if (TypeBinding.notEquals(outerInvocationType, outerDeclaringClass)) return false;
}
return true;
}
if (invocationType.fPackage != this.fPackage) return false;
ReferenceBinding currentType = receiverType;
TypeBinding originalDeclaringClass = (enclosingType() == null ? this : enclosingType()).original();
do {
if (currentType.isCapture()) {
if (TypeBinding.equalsEquals(originalDeclaringClass, currentType.erasure().original())) return true;
} else {
if (TypeBinding.equalsEquals(originalDeclaringClass, currentType.original())) return true;
}
PackageBinding currentPackage = currentType.fPackage;
if (currentPackage != null && currentPackage != this.fPackage) return false;
} while ((currentType = currentType.superclass()) != null);
return false;
}
@Override
public boolean canBeSeenBy(Scope scope) {
if (isPublic()) return true;
SourceTypeBinding invocationType = scope.enclosingSourceType();
if (TypeBinding.equalsEquals(invocationType, this)) return true;
if (invocationType == null)
return !isPrivate() && scope.getCurrentPackage() == this.fPackage;
if (isProtected()) {
if (invocationType.fPackage == this.fPackage) return true;
TypeBinding declaringClass = enclosingType();
if (declaringClass == null) return false;
declaringClass = declaringClass.erasure();
TypeBinding currentType = invocationType.erasure();
do {
if (TypeBinding.equalsEquals(declaringClass, invocationType)) return true;
if (currentType.findSuperTypeOriginatingFrom(declaringClass) != null) return true;
currentType = currentType.enclosingType();
} while (currentType != null);
return false;
}
if (isPrivate()) {
ReferenceBinding outerInvocationType = invocationType;
ReferenceBinding temp = outerInvocationType.enclosingType();
while (temp != null) {
outerInvocationType = temp;
temp = temp.enclosingType();
}
ReferenceBinding outerDeclaringClass = (ReferenceBinding)erasure();
temp = outerDeclaringClass.enclosingType();
while (temp != null) {
outerDeclaringClass = temp;
temp = temp.enclosingType();
}
return TypeBinding.equalsEquals(outerInvocationType, outerDeclaringClass);
}
return invocationType.fPackage == this.fPackage;
}
public char[] computeGenericTypeSignature(TypeVariableBinding[] typeVariables) {
boolean isMemberOfGeneric = isMemberType() && hasEnclosingInstanceContext() && (enclosingType().modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0;
if (typeVariables == Binding.NO_TYPE_VARIABLES && !isMemberOfGeneric) {
return signature();
}
StringBuffer sig = new StringBuffer(10);
if (isMemberOfGeneric) {
char[] typeSig = enclosingType().genericTypeSignature();
sig.append(typeSig, 0, typeSig.length-1);
sig.append('.');
sig.append(this.sourceName);
} else {
char[] typeSig = signature();
sig.append(typeSig, 0, typeSig.length-1);
}
if (typeVariables == Binding.NO_TYPE_VARIABLES) {
sig.append(';');
} else {
sig.append('<');
for (int i = 0, length = typeVariables.length; i < length; i++) {
sig.append(typeVariables[i].genericTypeSignature());
}
sig.append(">;");
}
int sigLength = sig.length();
char[] result = new char[sigLength];
sig.getChars(0, sigLength, result, 0);
return result;
}
public void computeId() {
switch (this.compoundName.length) {
case 3 :
char[] packageName = this.compoundName[0];
switch (packageName.length) {
case 3:
if (CharOperation.equals(TypeConstants.ORG_JUNIT_ASSERT, this.compoundName))
this.id = TypeIds.T_OrgJunitAssert;
return;
case 4:
if (!CharOperation.equals(TypeConstants.JAVA, packageName))
return;
break;
case 5:
switch (packageName[1]) {
case 'a':
if (CharOperation.equals(TypeConstants.JAVAX_ANNOTATION_INJECT_INJECT, this.compoundName))
this.id = TypeIds.T_JavaxInjectInject;
return;
case 'u':
if (CharOperation.equals(TypeConstants.JUNIT_FRAMEWORK_ASSERT, this.compoundName))
this.id = TypeIds.T_JunitFrameworkAssert;
return;
}
return;
default: return;
}
packageName = this.compoundName[1];
if (packageName.length == 0) return;
char[] typeName = this.compoundName[2];
if (typeName.length == 0) return;
if (!CharOperation.equals(TypeConstants.LANG, this.compoundName[1])) {
switch (packageName[0]) {
case 'i' :
if (CharOperation.equals(packageName, TypeConstants.IO)) {
switch (typeName[0]) {
case 'C' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_CLOSEABLE[2]))
this.typeBits |= TypeIds.BitCloseable;
return;
case 'E' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_EXTERNALIZABLE[2]))
this.id = TypeIds.T_JavaIoExternalizable;
return;
case 'I' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_IOEXCEPTION[2]))
this.id = TypeIds.T_JavaIoException;
return;
case 'O' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_OBJECTSTREAMEXCEPTION[2]))
this.id = TypeIds.T_JavaIoObjectStreamException;
return;
case 'P' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_PRINTSTREAM[2]))
this.id = TypeIds.T_JavaIoPrintStream;
return;
case 'S' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_SERIALIZABLE[2]))
this.id = TypeIds.T_JavaIoSerializable;
return;
}
}
return;
case 'u' :
if (CharOperation.equals(packageName, TypeConstants.UTIL)) {
switch (typeName[0]) {
case 'C' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_UTIL_COLLECTION[2])) {
this.id = TypeIds.T_JavaUtilCollection;
this.typeBits |= TypeIds.BitCollection;
}
return;
case 'I' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_UTIL_ITERATOR[2]))
this.id = TypeIds.T_JavaUtilIterator;
return;
case 'L' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_UTIL_LIST[2])) {
this.id = TypeIds.T_JavaUtilList;
this.typeBits |= TypeIds.BitList;
}
return;
case 'M' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_UTIL_MAP[2])) {
this.id = TypeIds.T_JavaUtilMap;
this.typeBits |= TypeIds.BitMap;
}
return;
case 'O' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_UTIL_OBJECTS[2]))
this.id = TypeIds.T_JavaUtilObjects;
return;
}
}
return;
}
return;
}
switch (typeName[0]) {
case 'A' :
switch(typeName.length) {
case 13 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_AUTOCLOSEABLE[2])) {
this.id = TypeIds.T_JavaLangAutoCloseable;
this.typeBits |= TypeIds.BitAutoCloseable;
}
return;
case 14:
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ASSERTIONERROR[2]))
this.id = TypeIds.T_JavaLangAssertionError;
return;
}
return;
case 'B' :
switch (typeName.length) {
case 4 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_BYTE[2]))
this.id = TypeIds.T_JavaLangByte;
return;
case 7 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_BOOLEAN[2]))
this.id = TypeIds.T_JavaLangBoolean;
return;
}
return;
case 'C' :
switch (typeName.length) {
case 5 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_CLASS[2]))
this.id = TypeIds.T_JavaLangClass;
return;
case 9 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_CHARACTER[2]))
this.id = TypeIds.T_JavaLangCharacter;
else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_CLONEABLE[2]))
this.id = TypeIds.T_JavaLangCloneable;
return;
case 22 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_CLASSNOTFOUNDEXCEPTION[2]))
this.id = TypeIds.T_JavaLangClassNotFoundException;
return;
}
return;
case 'D' :
switch (typeName.length) {
case 6 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_DOUBLE[2]))
this.id = TypeIds.T_JavaLangDouble;
return;
case 10 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_DEPRECATED[2]))
this.id = TypeIds.T_JavaLangDeprecated;
return;
}
return;
case 'E' :
switch (typeName.length) {
case 4 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ENUM[2]))
this.id = TypeIds.T_JavaLangEnum;
return;
case 5 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ERROR[2]))
this.id = TypeIds.T_JavaLangError;
return;
case 9 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_EXCEPTION[2]))
this.id = TypeIds.T_JavaLangException;
return;
}
return;
case 'F' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_FLOAT[2]))
this.id = TypeIds.T_JavaLangFloat;
else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_FUNCTIONAL_INTERFACE[2]))
this.id = TypeIds.T_JavaLangFunctionalInterface;
return;
case 'I' :
switch (typeName.length) {
case 7 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_INTEGER[2]))
this.id = TypeIds.T_JavaLangInteger;
return;
case 8 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ITERABLE[2]))
this.id = TypeIds.T_JavaLangIterable;
return;
case 24 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ILLEGALARGUMENTEXCEPTION[2]))
this.id = TypeIds.T_JavaLangIllegalArgumentException;
return;
}
return;
case 'L' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_LONG[2]))
this.id = TypeIds.T_JavaLangLong;
return;
case 'N' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_NOCLASSDEFERROR[2]))
this.id = TypeIds.T_JavaLangNoClassDefError;
return;
case 'O' :
switch (typeName.length) {
case 6 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_OBJECT[2]))
this.id = TypeIds.T_JavaLangObject;
return;
case 8 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_OVERRIDE[2]))
this.id = TypeIds.T_JavaLangOverride;
return;
}
return;
case 'R' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_RUNTIMEEXCEPTION[2]))
this.id = TypeIds.T_JavaLangRuntimeException;
break;
case 'S' :
switch (typeName.length) {
case 5 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_SHORT[2]))
this.id = TypeIds.T_JavaLangShort;
return;
case 6 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_STRING[2]))
this.id = TypeIds.T_JavaLangString;
else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_SYSTEM[2]))
this.id = TypeIds.T_JavaLangSystem;
return;
case 11 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_SAFEVARARGS[2]))
this.id = TypeIds.T_JavaLangSafeVarargs;
return;
case 12 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_STRINGBUFFER[2]))
this.id = TypeIds.T_JavaLangStringBuffer;
return;
case 13 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_STRINGBUILDER[2]))
this.id = TypeIds.T_JavaLangStringBuilder;
return;
case 16 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_SUPPRESSWARNINGS[2]))
this.id = TypeIds.T_JavaLangSuppressWarnings;
return;
}
return;
case 'T' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_THROWABLE[2]))
this.id = TypeIds.T_JavaLangThrowable;
return;
case 'V' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_VOID[2]))
this.id = TypeIds.T_JavaLangVoid;
return;
}
break;
case 4:
if (CharOperation.equals(TypeConstants.COM_GOOGLE_INJECT_INJECT, this.compoundName)) {
this.id = TypeIds.T_ComGoogleInjectInject;
return;
}
if (!CharOperation.equals(TypeConstants.JAVA, this.compoundName[0]))
return;
packageName = this.compoundName[1];
if (packageName.length == 0) return;
packageName = this.compoundName[2];
if (packageName.length == 0) return;
typeName = this.compoundName[3];
if (typeName.length == 0) return;
switch (packageName[0]) {
case 'a' :
if (CharOperation.equals(packageName, TypeConstants.ANNOTATION)) {
switch (typeName[0]) {
case 'A' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_ANNOTATION[3]))
this.id = TypeIds.T_JavaLangAnnotationAnnotation;
return;
case 'D' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_DOCUMENTED[3]))
this.id = TypeIds.T_JavaLangAnnotationDocumented;
return;
case 'E' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE[3]))
this.id = TypeIds.T_JavaLangAnnotationElementType;
return;
case 'I' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_INHERITED[3]))
this.id = TypeIds.T_JavaLangAnnotationInherited;
return;
case 'R' :
switch (typeName.length) {
case 9 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_RETENTION[3]))
this.id = TypeIds.T_JavaLangAnnotationRetention;
return;
case 10 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_REPEATABLE[3]))
this.id = TypeIds.T_JavaLangAnnotationRepeatable;
return;
case 15 :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_RETENTIONPOLICY[3]))
this.id = TypeIds.T_JavaLangAnnotationRetentionPolicy;
return;
}
return;
case 'T' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_TARGET[3]))
this.id = TypeIds.T_JavaLangAnnotationTarget;
return;
}
}
return;
case 'i':
if (CharOperation.equals(packageName, TypeConstants.INVOKE)) {
if (typeName.length == 0) return;
switch (typeName[0]) {
case 'M' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_$_POLYMORPHICSIGNATURE[3]))
this.id = TypeIds.T_JavaLangInvokeMethodHandlePolymorphicSignature;
return;
}
}
return;
case 'r' :
if (CharOperation.equals(packageName, TypeConstants.REFLECT)) {
switch (typeName[0]) {
case 'C' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_REFLECT_CONSTRUCTOR[2]))
this.id = TypeIds.T_JavaLangReflectConstructor;
return;
case 'F' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_REFLECT_FIELD[2]))
this.id = TypeIds.T_JavaLangReflectField;
return;
case 'M' :
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_REFLECT_METHOD[2]))
this.id = TypeIds.T_JavaLangReflectMethod;
return;
}
}
return;
}
break;
case 5 :
packageName = this.compoundName[0];
switch (packageName[0]) {
case 'j' :
if (!CharOperation.equals(TypeConstants.JAVA, this.compoundName[0]))
return;
packageName = this.compoundName[1];
if (packageName.length == 0) return;
if (CharOperation.equals(TypeConstants.LANG, packageName)) {
packageName = this.compoundName[2];
if (packageName.length == 0) return;
switch (packageName[0]) {
case 'i' :
if (CharOperation.equals(packageName, TypeConstants.INVOKE)) {
typeName = this.compoundName[3];
if (typeName.length == 0) return;
switch (typeName[0]) {
case 'M' :
char[] memberTypeName = this.compoundName[4];
if (memberTypeName.length == 0) return;
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_POLYMORPHICSIGNATURE[3])
&& CharOperation.equals(memberTypeName, TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_POLYMORPHICSIGNATURE[4]))
this.id = TypeIds.T_JavaLangInvokeMethodHandlePolymorphicSignature;
return;
}
}
return;
}
return;
}
return;
case 'o':
if (!CharOperation.equals(TypeConstants.ORG, this.compoundName[0]))
return;
packageName = this.compoundName[1];
if (packageName.length == 0) return;
switch (packageName[0]) {
case 'e':
if (CharOperation.equals(TypeConstants.ECLIPSE, packageName)) {
packageName = this.compoundName[2];
if (packageName.length == 0) return;
switch (packageName[0]) {
case 'c' :
if (CharOperation.equals(packageName, TypeConstants.CORE)) {
typeName = this.compoundName[3];
if (typeName.length == 0) return;
switch (typeName[0]) {
case 'r' :
char[] memberTypeName = this.compoundName[4];
if (memberTypeName.length == 0) return;
if (CharOperation.equals(typeName, TypeConstants.ORG_ECLIPSE_CORE_RUNTIME_ASSERT[3])
&& CharOperation.equals(memberTypeName, TypeConstants.ORG_ECLIPSE_CORE_RUNTIME_ASSERT[4]))
this.id = TypeIds.T_OrgEclipseCoreRuntimeAssert;
return;
}
}
return;
}
return;
}
return;
case 'a':
if (CharOperation.equals(TypeConstants.APACHE, packageName)) {
if (CharOperation.equals(TypeConstants.COMMONS, this.compoundName[2])) {
if (CharOperation.equals(TypeConstants.ORG_APACHE_COMMONS_LANG_VALIDATE, this.compoundName))
this.id = TypeIds.T_OrgApacheCommonsLangValidate;
else if (CharOperation.equals(TypeConstants.ORG_APACHE_COMMONS_LANG3_VALIDATE, this.compoundName))
this.id = TypeIds.T_OrgApacheCommonsLang3Validate;
}
}
return;
}
return;
case 'c':
if (!CharOperation.equals(TypeConstants.COM, this.compoundName[0]))
return;
if (CharOperation.equals(TypeConstants.COM_GOOGLE_COMMON_BASE_PRECONDITIONS, this.compoundName))
this.id = TypeIds.T_ComGoogleCommonBasePreconditions;
return;
}
break;
case 6:
if (CharOperation.equals(TypeConstants.ORG, this.compoundName[0])) {
if (CharOperation.equals(TypeConstants.SPRING, this.compoundName[1])) {
if (CharOperation.equals(TypeConstants.AUTOWIRED, this.compoundName[5])) {
if (CharOperation.equals(TypeConstants.ORG_SPRING_AUTOWIRED, this.compoundName)) {
this.id = TypeIds.T_OrgSpringframeworkBeansFactoryAnnotationAutowired;
}
}
return;
}
if (CharOperation.equals(TypeConstants.JUNIT, this.compoundName[1])) {
if (CharOperation.equals(TypeConstants.METHOD_SOURCE, this.compoundName[5])) {
if (CharOperation.equals(TypeConstants.ORG_JUNIT_METHOD_SOURCE, this.compoundName)) {
this.id = TypeIds.T_OrgJunitJupiterParamsProviderMethodSource;
}
}
return;
}
if (!CharOperation.equals(TypeConstants.JDT, this.compoundName[2]) || !CharOperation.equals(TypeConstants.ITYPEBINDING, this.compoundName[5]))
return;
if (CharOperation.equals(TypeConstants.ORG_ECLIPSE_JDT_CORE_DOM_ITYPEBINDING, this.compoundName))
this.typeBits |= TypeIds.BitUninternedType;
}
break;
case 7 :
if (!CharOperation.equals(TypeConstants.JDT, this.compoundName[2]) || !CharOperation.equals(TypeConstants.TYPEBINDING, this.compoundName[6]))
return;
if (CharOperation.equals(TypeConstants.ORG_ECLIPSE_JDT_INTERNAL_COMPILER_LOOKUP_TYPEBINDING, this.compoundName))
this.typeBits |= TypeIds.BitUninternedType;
break;
}
}
public void computeId(LookupEnvironment environment) {
environment.getUnannotatedType(this);
}
@Override
public char[] computeUniqueKey(boolean isLeaf) {
if (!isLeaf) return signature();
return genericTypeSignature();
}
@Override
public char[] constantPoolName() {
if (this.constantPoolName != null) return this.constantPoolName;
return this.constantPoolName = CharOperation.concatWith(this.compoundName, '/');
}
@Override
public String debugName() {
return (this.compoundName != null) ? this.hasTypeAnnotations() ? annotatedDebugName() : new String(readableName()) : "UNNAMED TYPE";
}
@Override
public int depth() {
int depth = 0;
ReferenceBinding current = this;
while ((current = current.enclosingType()) != null)
depth++;
return depth;
}
public boolean detectAnnotationCycle() {
if ((this.tagBits & TagBits.EndAnnotationCheck) != 0) return false;
if ((this.tagBits & TagBits.BeginAnnotationCheck) != 0) return true;
this.tagBits |= TagBits.BeginAnnotationCheck;
MethodBinding[] currentMethods = methods();
boolean inCycle = false;
for (int i = 0, l = currentMethods.length; i < l; i++) {
TypeBinding returnType = currentMethods[i].returnType.leafComponentType().erasure();
if (TypeBinding.equalsEquals(this, returnType)) {
if (this instanceof SourceTypeBinding) {
MethodDeclaration decl = (MethodDeclaration) currentMethods[i].sourceMethod();
((SourceTypeBinding) this).scope.problemReporter().annotationCircularity(this, this, decl != null ? decl.returnType : null);
}
} else if (returnType.isAnnotationType() && ((ReferenceBinding) returnType).detectAnnotationCycle()) {
if (this instanceof SourceTypeBinding) {
MethodDeclaration decl = (MethodDeclaration) currentMethods[i].sourceMethod();
((SourceTypeBinding) this).scope.problemReporter().annotationCircularity(this, returnType, decl != null ? decl.returnType : null);
}
inCycle = true;
}
}
if (inCycle)
return true;
this.tagBits |= TagBits.EndAnnotationCheck;
return false;
}
public final ReferenceBinding enclosingTypeAt(int relativeDepth) {
ReferenceBinding current = this;
while (relativeDepth-- > 0 && current != null)
current = current.enclosingType();
return current;
}
public int enumConstantCount() {
int count = 0;
FieldBinding[] fields = fields();
for (int i = 0, length = fields.length; i < length; i++) {
if ((fields[i].modifiers & ClassFileConstants.AccEnum) != 0) count++;
}
return count;
}
public int fieldCount() {
return fields().length;
}
public FieldBinding[] fields() {
return Binding.NO_FIELDS;
}
public final int getAccessFlags() {
return this.modifiers & ExtraCompilerModifiers.AccJustFlag;
}
@Override
public AnnotationBinding[] getAnnotations() {
return retrieveAnnotations(this);
}
@Override
public long getAnnotationTagBits() {
return this.tagBits;
}
public int getEnclosingInstancesSlotSize() {
if (isStatic()) return 0;
return enclosingType() == null ? 0 : 1;
}
public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) {
return null;
}
public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes, CompilationUnitScope refScope) {
return null;
}
public FieldBinding getField(char[] fieldName, boolean needResolve) {
return null;
}
public char[] getFileName() {
return this.fileName;
}
public ReferenceBinding getMemberType(char[] typeName) {
ReferenceBinding[] memberTypes = memberTypes();
int memberTypeIndex = binarySearch(typeName, memberTypes);
if (memberTypeIndex >= 0) {
return memberTypes[memberTypeIndex];
}
return null;
}
static int binarySearch(char[] sourceName, ReferenceBinding[] sortedMemberTypes) {
if (sortedMemberTypes == null)
return -1;
int max = sortedMemberTypes.length, nameLength = sourceName.length;
if (max == 0)
return -1;
int left = 0, right = max - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
char[] midName = sortedMemberTypes[mid].sourceName;
int compare = midName == null ? 1 : compare(sourceName, midName, nameLength, midName.length);
if (compare < 0) {
right = mid-1;
} else if (compare > 0) {
left = mid+1;
} else {
return mid;
}
}
return -1;
}
@Override
public MethodBinding[] getMethods(char[] selector) {
return Binding.NO_METHODS;
}
public MethodBinding[] getMethods(char[] selector, int suggestedParameterLength) {
return getMethods(selector);
}
public int getOuterLocalVariablesSlotSize() {
return 0;
}
@Override
public PackageBinding getPackage() {
return this.fPackage;
}
public TypeVariableBinding getTypeVariable(char[] variableName) {
TypeVariableBinding[] typeVariables = typeVariables();
for (int i = typeVariables.length; --i >= 0;)
if (CharOperation.equals(typeVariables[i].sourceName, variableName))
return typeVariables[i];
return null;
}
@Override
public int hashCode() {
return (this.compoundName == null || this.compoundName.length == 0)
? super.hashCode()
: CharOperation.hashCode(this.compoundName[this.compoundName.length - 1]);
}
final int identityHashCode() {
return super.hashCode();
}
public boolean hasIncompatibleSuperType(ReferenceBinding otherType) {
if (TypeBinding.equalsEquals(this, otherType)) return false;
ReferenceBinding[] interfacesToVisit = null;
int nextPosition = 0;
ReferenceBinding currentType = this;
TypeBinding match;
do {
match = otherType.findSuperTypeOriginatingFrom(currentType);
if (match != null && match.isProvablyDistinct(currentType))
return true;
ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
if (interfacesToVisit == null) {
interfacesToVisit = itsInterfaces;
nextPosition = interfacesToVisit.length;
} else {
int itsLength = itsInterfaces.length;
if (nextPosition + itsLength >= interfacesToVisit.length)
System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
nextInterface : for (int a = 0; a < itsLength; a++) {
ReferenceBinding next = itsInterfaces[a];
for (int b = 0; b < nextPosition; b++)
if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
interfacesToVisit[nextPosition++] = next;
}
}
}
} while ((currentType = currentType.superclass()) != null);
for (int i = 0; i < nextPosition; i++) {
currentType = interfacesToVisit[i];
if (TypeBinding.equalsEquals(currentType, otherType)) return false;
match = otherType.findSuperTypeOriginatingFrom(currentType);
if (match != null && match.isProvablyDistinct(currentType))
return true;
ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
int itsLength = itsInterfaces.length;
if (nextPosition + itsLength >= interfacesToVisit.length)
System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
nextInterface : for (int a = 0; a < itsLength; a++) {
ReferenceBinding next = itsInterfaces[a];
for (int b = 0; b < nextPosition; b++)
if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
interfacesToVisit[nextPosition++] = next;
}
}
}
return false;
}
public boolean hasMemberTypes() {
return false;
}
boolean hasNonNullDefaultFor(int location, int sourceStart) {
ReferenceBinding currentType = this;
while (currentType != null) {
int nullDefault = ((ReferenceBinding)currentType.original()).getNullDefault();
if (nullDefault != 0)
return (nullDefault & location) != 0;
currentType = currentType.enclosingType();
}
return (this.getPackage().getDefaultNullness() & location) != 0;
}
int getNullDefault() {
return 0;
}
@Override
public boolean acceptsNonNullDefault() {
return true;
}
public final boolean hasRestrictedAccess() {
return (this.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0;
}
public boolean hasNullBit(int mask) {
return (this.typeBits & mask) != 0;
}
public boolean implementsInterface(ReferenceBinding anInterface, boolean searchHierarchy) {
if (TypeBinding.equalsEquals(this, anInterface))
return true;
ReferenceBinding[] interfacesToVisit = null;
int nextPosition = 0;
ReferenceBinding currentType = this;
do {
ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
if (interfacesToVisit == null) {
interfacesToVisit = itsInterfaces;
nextPosition = interfacesToVisit.length;
} else {
int itsLength = itsInterfaces.length;
if (nextPosition + itsLength >= interfacesToVisit.length)
System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
nextInterface : for (int a = 0; a < itsLength; a++) {
ReferenceBinding next = itsInterfaces[a];
for (int b = 0; b < nextPosition; b++)
if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
interfacesToVisit[nextPosition++] = next;
}
}
}
} while (searchHierarchy && (currentType = currentType.superclass()) != null);
for (int i = 0; i < nextPosition; i++) {
currentType = interfacesToVisit[i];
if (currentType.isEquivalentTo(anInterface))
return true;
ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
int itsLength = itsInterfaces.length;
if (nextPosition + itsLength >= interfacesToVisit.length)
System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
nextInterface : for (int a = 0; a < itsLength; a++) {
ReferenceBinding next = itsInterfaces[a];
for (int b = 0; b < nextPosition; b++)
if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
interfacesToVisit[nextPosition++] = next;
}
}
}
return false;
}
boolean implementsMethod(MethodBinding method) {
char[] selector = method.selector;
ReferenceBinding type = this;
while (type != null) {
MethodBinding[] methods = type.methods();
long range;
if ((range = ReferenceBinding.binarySearch(selector, methods)) >= 0) {
int start = (int) range, end = (int) (range >> 32);
for (int i = start; i <= end; i++) {
if (methods[i].areParametersEqual(method))
return true;
}
}
type = type.superclass();
}
return false;
}
public final boolean isAbstract() {
return (this.modifiers & ClassFileConstants.AccAbstract) != 0;
}
@Override
public boolean isAnnotationType() {
return (this.modifiers & ClassFileConstants.AccAnnotation) != 0;
}
public final boolean isBinaryBinding() {
return (this.tagBits & TagBits.IsBinaryBinding) != 0;
}
@Override
public boolean isClass() {
return (this.modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) == 0;
}
private static SourceTypeBinding getSourceTypeBinding(ReferenceBinding ref) {
if (ref instanceof SourceTypeBinding)
return (SourceTypeBinding) ref;
if (ref instanceof ParameterizedTypeBinding) {
ParameterizedTypeBinding ptb = (ParameterizedTypeBinding) ref;
return ptb.type instanceof SourceTypeBinding ? (SourceTypeBinding) ptb.type : null;
}
return null;
}
public boolean isNestmateOf(ReferenceBinding other) {
SourceTypeBinding s1 = getSourceTypeBinding(this);
SourceTypeBinding s2 = getSourceTypeBinding(other);
if (s1 == null || s2 == null) return false;
return s1.isNestmateOf(s2);
}
@Override
public boolean isProperType(boolean admitCapture18) {
ReferenceBinding outer = enclosingType();
if (outer != null && !outer.isProperType(admitCapture18))
return false;
return super.isProperType(admitCapture18);
}
@Override
public boolean isCompatibleWith(TypeBinding otherType, Scope captureScope) {
if (equalsEquals(otherType, this))
return true;
if (otherType.id == TypeIds.T_JavaLangObject)
return true;
Object result;
if (this.compatibleCache == null) {
this.compatibleCache = new SimpleLookupTable(3);
result = null;
} else {
result = this.compatibleCache.get(otherType);
if (result != null) {
return result == Boolean.TRUE;
}
}
this.compatibleCache.put(otherType, Boolean.FALSE);
if (isCompatibleWith0(otherType, captureScope)) {
this.compatibleCache.put(otherType, Boolean.TRUE);
return true;
}
if (captureScope == null
&& this instanceof TypeVariableBinding
&& ((TypeVariableBinding)this).firstBound instanceof ParameterizedTypeBinding) {
this.compatibleCache.put(otherType, null);
}
return false;
}
private boolean isCompatibleWith0(TypeBinding otherType, Scope captureScope) {
if (TypeBinding.equalsEquals(otherType, this))
return true;
if (otherType.id == TypeIds.T_JavaLangObject)
return true;
if (isEquivalentTo(otherType))
return true;
switch (otherType.kind()) {
case Binding.WILDCARD_TYPE :
case Binding.INTERSECTION_TYPE:
return false;
case Binding.TYPE_PARAMETER :
if (otherType.isCapture()) {
CaptureBinding otherCapture = (CaptureBinding) otherType;
TypeBinding otherLowerBound;
if ((otherLowerBound = otherCapture.lowerBound) != null) {
if (otherLowerBound.isArrayType()) return false;
return isCompatibleWith(otherLowerBound);
}
}
if (otherType instanceof InferenceVariable) {
if (captureScope != null) {
MethodScope methodScope = captureScope.methodScope();
if (methodScope != null) {
ReferenceContext referenceContext = methodScope.referenceContext;
if (referenceContext instanceof LambdaExpression
&& ((LambdaExpression)referenceContext).inferenceContext != null)
return true;
}
}
}
case Binding.GENERIC_TYPE :
case Binding.TYPE :
case Binding.PARAMETERIZED_TYPE :
case Binding.RAW_TYPE :
case Binding.INTERSECTION_TYPE18 :
switch (kind()) {
case Binding.GENERIC_TYPE :
case Binding.PARAMETERIZED_TYPE :
case Binding.RAW_TYPE :
if (TypeBinding.equalsEquals(erasure(), otherType.erasure()))
return false;
}
ReferenceBinding otherReferenceType = (ReferenceBinding) otherType;
if (otherReferenceType.isIntersectionType18()) {
ReferenceBinding[] intersectingTypes = ((IntersectionTypeBinding18)otherReferenceType).intersectingTypes;
for (ReferenceBinding binding : intersectingTypes) {
if (!isCompatibleWith(binding))
return false;
}
return true;
}
if (otherReferenceType.isInterface()) {
if (implementsInterface(otherReferenceType, true))
return true;
if (this instanceof TypeVariableBinding && captureScope != null) {
TypeVariableBinding typeVariable = (TypeVariableBinding) this;
if (typeVariable.firstBound instanceof ParameterizedTypeBinding) {
TypeBinding bound = typeVariable.firstBound.capture(captureScope, -1, -1);
return bound.isCompatibleWith(otherReferenceType);
}
}
}
if (isInterface())
return false;
return otherReferenceType.isSuperclassOf(this);
default :
return false;
}
}
@Override
public boolean isSubtypeOf(TypeBinding other, boolean simulatingBugJDK8026527) {
if (isSubTypeOfRTL(other))
return true;
TypeBinding candidate = findSuperTypeOriginatingFrom(other);
if (candidate == null)
return false;
if (TypeBinding.equalsEquals(candidate, other))
return true;
if (other.isRawType() && TypeBinding.equalsEquals(candidate.erasure(), other.erasure()))
return true;
TypeBinding[] sis = other.typeArguments();
TypeBinding[] tis = candidate.typeArguments();
if (tis == null || sis == null)
return false;
if (sis.length != tis.length)
return false;
for (int i = 0; i < sis.length; i++) {
if (!tis[i].isTypeArgumentContainedBy(sis[i]))
return false;
}
return true;
}
protected boolean isSubTypeOfRTL(TypeBinding other) {
if (TypeBinding.equalsEquals(this, other))
return true;
if (other instanceof CaptureBinding) {
TypeBinding lower = ((CaptureBinding) other).lowerBound;
return (lower != null && isSubtypeOf(lower, false));
}
if (other instanceof ReferenceBinding) {
TypeBinding[] intersecting = ((ReferenceBinding) other).getIntersectingTypes();
if (intersecting != null) {
for (int i = 0; i < intersecting.length; i++) {
if (!isSubtypeOf(intersecting[i], false))
return false;
}
return true;
}
}
return false;
}
public final boolean isDefault() {
return (this.modifiers & (ClassFileConstants.AccPublic | ClassFileConstants.AccProtected | ClassFileConstants.AccPrivate)) == 0;
}
public final boolean isDeprecated() {
return (this.modifiers & ClassFileConstants.AccDeprecated) != 0;
}
@Override
public boolean isEnum() {
return (this.modifiers & ClassFileConstants.AccEnum) != 0;
}
public final boolean isFinal() {
return (this.modifiers & ClassFileConstants.AccFinal) != 0;
}
public boolean isHierarchyBeingConnected() {
return (this.tagBits & TagBits.EndHierarchyCheck) == 0 && (this.tagBits & TagBits.BeginHierarchyCheck) != 0;
}
public boolean isHierarchyBeingActivelyConnected() {
return (this.tagBits & TagBits.EndHierarchyCheck) == 0 && (this.tagBits & TagBits.BeginHierarchyCheck) != 0 && (this.tagBits & TagBits.PauseHierarchyCheck) == 0;
}
public boolean isHierarchyConnected() {
return true;
}
@Override
public boolean isInterface() {
return (this.modifiers & ClassFileConstants.AccInterface) != 0;
}
@Override
public boolean isFunctionalInterface(Scope scope) {
MethodBinding method;
return isInterface() && (method = getSingleAbstractMethod(scope, true)) != null && method.isValidBinding();
}
public final boolean isPrivate() {
return (this.modifiers & ClassFileConstants.AccPrivate) != 0;
}
public final boolean isOrEnclosedByPrivateType() {
if (isLocalType()) return true;
ReferenceBinding type = this;
while (type != null) {
if ((type.modifiers & ClassFileConstants.AccPrivate) != 0)
return true;
type = type.enclosingType();
}
return false;
}
public final boolean isProtected() {
return (this.modifiers & ClassFileConstants.AccProtected) != 0;
}
public final boolean isPublic() {
return (this.modifiers & ClassFileConstants.AccPublic) != 0;
}
@Override
public final boolean isStatic() {
return (this.modifiers & (ClassFileConstants.AccStatic | ClassFileConstants.AccInterface)) != 0 || (this.tagBits & TagBits.IsNestedType) == 0;
}
public final boolean isStrictfp() {
return (this.modifiers & ClassFileConstants.AccStrictfp) != 0;
}
public boolean isSuperclassOf(ReferenceBinding otherType) {
while ((otherType = otherType.superclass()) != null) {
if (otherType.isEquivalentTo(this)) return true;
}
return false;
}
@Override
public boolean isThrowable() {
ReferenceBinding current = this;
do {
switch (current.id) {
case TypeIds.T_JavaLangThrowable :
case TypeIds.T_JavaLangError :
case TypeIds.T_JavaLangRuntimeException :
case TypeIds.T_JavaLangException :
return true;
}
} while ((current = current.superclass()) != null);
return false;
}
@Override
public boolean isUncheckedException(boolean includeSupertype) {
switch (this.id) {
case TypeIds.T_JavaLangError :
case TypeIds.T_JavaLangRuntimeException :
return true;
case TypeIds.T_JavaLangThrowable :
case TypeIds.T_JavaLangException :
return includeSupertype;
}
ReferenceBinding current = this;
while ((current = current.superclass()) != null) {
switch (current.id) {
case TypeIds.T_JavaLangError :
case TypeIds.T_JavaLangRuntimeException :
return true;
case TypeIds.T_JavaLangThrowable :
case TypeIds.T_JavaLangException :
return false;
}
}
return false;
}
public final boolean isUsed() {
return (this.modifiers & ExtraCompilerModifiers.AccLocallyUsed) != 0;
}
public final boolean isViewedAsDeprecated() {
if ((this.modifiers & (ClassFileConstants.AccDeprecated | ExtraCompilerModifiers.AccDeprecatedImplicitly)) != 0)
return true;
if (getPackage().isViewedAsDeprecated()) {
this.tagBits |= (getPackage().tagBits & TagBits.AnnotationTerminallyDeprecated);
return true;
}
return false;
}
public ReferenceBinding[] memberTypes() {
return Binding.NO_MEMBER_TYPES;
}
public MethodBinding[] methods() {
return Binding.NO_METHODS;
}
public final ReferenceBinding outermostEnclosingType() {
ReferenceBinding current = this;
while (true) {
ReferenceBinding last = current;
if ((current = current.enclosingType()) == null)
return last;
}
}
@Override
public char[] qualifiedSourceName() {
if (isMemberType())
return CharOperation.concat(enclosingType().qualifiedSourceName(), sourceName(), '.');
return sourceName();
}
@Override
public char[] readableName() {
return readableName(true);
}
public char[] readableName(boolean showGenerics) {
char[] readableName;
if (isMemberType()) {
readableName = CharOperation.concat(enclosingType().readableName(showGenerics && hasEnclosingInstanceContext()), this.sourceName, '.');
} else {
readableName = CharOperation.concatWith(this.compoundName, '.');
}
if (showGenerics) {
TypeVariableBinding[] typeVars;
if ((typeVars = typeVariables()) != Binding.NO_TYPE_VARIABLES) {
StringBuffer nameBuffer = new StringBuffer(10);
nameBuffer.append(readableName).append('<');
for (int i = 0, length = typeVars.length; i < length; i++) {
if (i > 0) nameBuffer.append(',');
nameBuffer.append(typeVars[i].readableName());
}
nameBuffer.append('>');
int nameLength = nameBuffer.length();
readableName = new char[nameLength];
nameBuffer.getChars(0, nameLength, readableName, 0);
}
}
return readableName;
}
protected void appendNullAnnotation(StringBuffer nameBuffer, CompilerOptions options) {
if (options.isAnnotationBasedNullAnalysisEnabled) {
if (options.usesNullTypeAnnotations()) {
for (AnnotationBinding annotation : this.typeAnnotations) {
ReferenceBinding annotationType = annotation.getAnnotationType();
if (annotationType.hasNullBit(TypeIds.BitNonNullAnnotation|TypeIds.BitNullableAnnotation)) {
nameBuffer.append('@').append(annotationType.shortReadableName()).append(' ');
}
}
} else {
if ((this.tagBits & TagBits.AnnotationNonNull) != 0) {
char[][] nonNullAnnotationName = options.nonNullAnnotationName;
nameBuffer.append('@').append(nonNullAnnotationName[nonNullAnnotationName.length-1]).append(' ');
}
if ((this.tagBits & TagBits.AnnotationNullable) != 0) {
char[][] nullableAnnotationName = options.nullableAnnotationName;
nameBuffer.append('@').append(nullableAnnotationName[nullableAnnotationName.length-1]).append(' ');
}
}
}
}
public AnnotationHolder retrieveAnnotationHolder(Binding binding, boolean forceInitialization) {
SimpleLookupTable store = storedAnnotations(forceInitialization, false);
return store == null ? null : (AnnotationHolder) store.get(binding);
}
AnnotationBinding[] retrieveAnnotations(Binding binding) {
AnnotationHolder holder = retrieveAnnotationHolder(binding, true);
return holder == null ? Binding.NO_ANNOTATIONS : holder.getAnnotations();
}
@Override
public void setAnnotations(AnnotationBinding[] annotations, boolean forceStore) {
storeAnnotations(this, annotations, forceStore);
}
public void setContainerAnnotationType(ReferenceBinding value) {
}
public void tagAsHavingDefectiveContainerType() {
}
@Override
public char[] nullAnnotatedReadableName(CompilerOptions options, boolean shortNames) {
if (shortNames)
return nullAnnotatedShortReadableName(options);
return nullAnnotatedReadableName(options);
}
char[] nullAnnotatedReadableName(CompilerOptions options) {
StringBuffer nameBuffer = new StringBuffer(10);
if (isMemberType()) {
nameBuffer.append(enclosingType().nullAnnotatedReadableName(options, false));
nameBuffer.append('.');
appendNullAnnotation(nameBuffer, options);
nameBuffer.append(this.sourceName);
} else if (this.compoundName != null) {
int i;
int l=this.compoundName.length;
for (i=0; i<l-1; i++) {
nameBuffer.append(this.compoundName[i]);
nameBuffer.append('.');
}
appendNullAnnotation(nameBuffer, options);
nameBuffer.append(this.compoundName[i]);
} else {
appendNullAnnotation(nameBuffer, options);
if (this.sourceName != null)
nameBuffer.append(this.sourceName);
else
nameBuffer.append(this.readableName());
}
TypeBinding [] arguments = typeArguments();
if (arguments != null && arguments.length > 0) {
nameBuffer.append('<');
for (int i = 0, length = arguments.length; i < length; i++) {
if (i > 0) nameBuffer.append(',');
nameBuffer.append(arguments[i].nullAnnotatedReadableName(options, false));
}
nameBuffer.append('>');
}
int nameLength = nameBuffer.length();
char[] readableName = new char[nameLength];
nameBuffer.getChars(0, nameLength, readableName, 0);
return readableName;
}
char[] nullAnnotatedShortReadableName(CompilerOptions options) {
StringBuffer nameBuffer = new StringBuffer(10);
if (isMemberType()) {
nameBuffer.append(enclosingType().nullAnnotatedReadableName(options, true));
nameBuffer.append('.');
appendNullAnnotation(nameBuffer, options);
nameBuffer.append(this.sourceName);
} else {
appendNullAnnotation(nameBuffer, options);
if (this.sourceName != null)
nameBuffer.append(this.sourceName);
else
nameBuffer.append(this.shortReadableName());
}
TypeBinding [] arguments = typeArguments();
if (arguments != null && arguments.length > 0) {
nameBuffer.append('<');
for (int i = 0, length = arguments.length; i < length; i++) {
if (i > 0) nameBuffer.append(',');
nameBuffer.append(arguments[i].nullAnnotatedReadableName(options, true));
}
nameBuffer.append('>');
}
int nameLength = nameBuffer.length();
char[] shortReadableName = new char[nameLength];
nameBuffer.getChars(0, nameLength, shortReadableName, 0);
return shortReadableName;
}
@Override
public char[] shortReadableName() {
return shortReadableName(true);
}
public char[] shortReadableName(boolean showGenerics) {
char[] shortReadableName;
if (isMemberType()) {
shortReadableName = CharOperation.concat(enclosingType().shortReadableName(showGenerics && hasEnclosingInstanceContext()), this.sourceName, '.');
} else {
shortReadableName = this.sourceName;
}
if (showGenerics) {
TypeVariableBinding[] typeVars;
if ((typeVars = typeVariables()) != Binding.NO_TYPE_VARIABLES) {
StringBuffer nameBuffer = new StringBuffer(10);
nameBuffer.append(shortReadableName).append('<');
for (int i = 0, length = typeVars.length; i < length; i++) {
if (i > 0) nameBuffer.append(',');
nameBuffer.append(typeVars[i].shortReadableName());
}
nameBuffer.append('>');
int nameLength = nameBuffer.length();
shortReadableName = new char[nameLength];
nameBuffer.getChars(0, nameLength, shortReadableName, 0);
}
}
return shortReadableName;
}
@Override
public char[] signature() {
if (this.signature != null)
return this.signature;
return this.signature = CharOperation.concat('L', constantPoolName(), ';');
}
@Override
public char[] sourceName() {
return this.sourceName;
}
@Override
public ReferenceBinding upwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
return this;
}
@Override
public ReferenceBinding downwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
return this;
}
void storeAnnotationHolder(Binding binding, AnnotationHolder holder) {
if (holder == null) {
SimpleLookupTable store = storedAnnotations(false, false);
if (store != null)
store.removeKey(binding);
} else {
SimpleLookupTable store = storedAnnotations(true, false);
if (store != null)
store.put(binding, holder);
}
}
void storeAnnotations(Binding binding, AnnotationBinding[] annotations, boolean forceStore) {
AnnotationHolder holder = null;
if (annotations == null || annotations.length == 0) {
SimpleLookupTable store = storedAnnotations(false, forceStore);
if (store != null)
holder = (AnnotationHolder) store.get(binding);
if (holder == null) return;
} else {
SimpleLookupTable store = storedAnnotations(true, forceStore);
if (store == null) return;
holder = (AnnotationHolder) store.get(binding);
if (holder == null)
holder = new AnnotationHolder();
}
storeAnnotationHolder(binding, holder.setAnnotations(annotations));
}
SimpleLookupTable storedAnnotations(boolean forceInitialize, boolean forceStore) {
return null;
}
@Override
public ReferenceBinding superclass() {
return null;
}
@Override
public ReferenceBinding[] superInterfaces() {
return Binding.NO_SUPERINTERFACES;
}
public ReferenceBinding[] syntheticEnclosingInstanceTypes() {
if (isStatic()) return null;
ReferenceBinding enclosingType = enclosingType();
if (enclosingType == null)
return null;
return new ReferenceBinding[] {enclosingType};
}
MethodBinding[] unResolvedMethods() {
return methods();
}
public FieldBinding[] unResolvedFields() {
return Binding.NO_FIELDS;
}
protected int applyCloseableClassWhitelists() {
switch (this.compoundName.length) {
case 3:
if (CharOperation.equals(TypeConstants.JAVA, this.compoundName[0])) {
if (CharOperation.equals(TypeConstants.IO, this.compoundName[1])) {
char[] simpleName = this.compoundName[2];
int l = TypeConstants.JAVA_IO_WRAPPER_CLOSEABLES.length;
for (int i = 0; i < l; i++) {
if (CharOperation.equals(simpleName, TypeConstants.JAVA_IO_WRAPPER_CLOSEABLES[i]))
return TypeIds.BitWrapperCloseable;
}
l = TypeConstants.JAVA_IO_RESOURCE_FREE_CLOSEABLES.length;
for (int i = 0; i < l; i++) {
if (CharOperation.equals(simpleName, TypeConstants.JAVA_IO_RESOURCE_FREE_CLOSEABLES[i]))
return TypeIds.BitResourceFreeCloseable;
}
}
}
break;
case 4:
if (CharOperation.equals(TypeConstants.JAVA, this.compoundName[0])) {
if (CharOperation.equals(TypeConstants.UTIL, this.compoundName[1])) {
if (CharOperation.equals(TypeConstants.ZIP, this.compoundName[2])) {
char[] simpleName = this.compoundName[3];
int l = TypeConstants.JAVA_UTIL_ZIP_WRAPPER_CLOSEABLES.length;
for (int i = 0; i < l; i++) {
if (CharOperation.equals(simpleName, TypeConstants.JAVA_UTIL_ZIP_WRAPPER_CLOSEABLES[i]))
return TypeIds.BitWrapperCloseable;
}
}
}
}
break;
}
int l = TypeConstants.OTHER_WRAPPER_CLOSEABLES.length;
for (int i = 0; i < l; i++) {
if (CharOperation.equals(this.compoundName, TypeConstants.OTHER_WRAPPER_CLOSEABLES[i]))
return TypeIds.BitWrapperCloseable;
}
return 0;
}
protected int applyCloseableInterfaceWhitelists() {
switch (this.compoundName.length) {
case 4:
for (int i=0; i<2; i++)
if (!CharOperation.equals(this.compoundName[i], TypeConstants.JAVA_UTIL_STREAM[i]))
return 0;
for (char[] streamName : TypeConstants.RESOURCE_FREE_CLOSEABLE_J_U_STREAMS)
if (CharOperation.equals(this.compoundName[3], streamName))
return TypeIds.BitResourceFreeCloseable;
break;
}
return 0;
}
protected MethodBinding [] getInterfaceAbstractContracts(Scope scope, boolean replaceWildcards, boolean filterDefaultMethods) throws InvalidInputException {
if (!isInterface() || !isValidBinding()) {
throw new InvalidInputException("Not a functional interface");
}
MethodBinding [] methods = methods();
MethodBinding [] contracts = new MethodBinding[0];
int contractsCount = 0;
int contractsLength = 0;
ReferenceBinding [] superInterfaces = superInterfaces();
for (int i = 0, length = superInterfaces.length; i < length; i++) {
MethodBinding [] superInterfaceContracts = superInterfaces[i].getInterfaceAbstractContracts(scope, replaceWildcards, false);
final int superInterfaceContractsLength = superInterfaceContracts == null ? 0 : superInterfaceContracts.length;
if (superInterfaceContractsLength == 0) continue;
if (contractsLength < contractsCount + superInterfaceContractsLength) {
System.arraycopy(contracts, 0, contracts = new MethodBinding[contractsLength = contractsCount + superInterfaceContractsLength], 0, contractsCount);
}
System.arraycopy(superInterfaceContracts, 0, contracts, contractsCount, superInterfaceContractsLength);
contractsCount += superInterfaceContractsLength;
}
LookupEnvironment environment = scope.environment();
for (int i = 0, length = methods == null ? 0 : methods.length; i < length; i++) {
final MethodBinding method = methods[i];
if (method == null || method.isStatic() || method.redeclaresPublicObjectMethod(scope) || method.isPrivate())
continue;
if (!method.isValidBinding())
throw new InvalidInputException("Not a functional interface");
for (int j = 0; j < contractsCount;) {
if ( contracts[j] != null && MethodVerifier.doesMethodOverride(method, contracts[j], environment)) {
contractsCount--;
if (j < contractsCount) {
System.arraycopy(contracts, j+1, contracts, j, contractsCount - j);
continue;
}
}
j++;
}
if (filterDefaultMethods && method.isDefaultMethod())
continue;
if (contractsCount == contractsLength) {
System.arraycopy(contracts, 0, contracts = new MethodBinding[contractsLength += 16], 0, contractsCount);
}
if(environment.globalOptions.isAnnotationBasedNullAnalysisEnabled) {
ImplicitNullAnnotationVerifier.ensureNullnessIsKnown(method, scope);
}
contracts[contractsCount++] = method;
}
for (int i = 0; i < contractsCount; i++) {
MethodBinding contractI = contracts[i];
if (TypeBinding.equalsEquals(contractI.declaringClass, this))
continue;
for (int j = 0; j < contractsCount; j++) {
MethodBinding contractJ = contracts[j];
if (i == j || TypeBinding.equalsEquals(contractJ.declaringClass, this))
continue;
if (contractI == contractJ || MethodVerifier.doesMethodOverride(contractI, contractJ, environment)) {
contractsCount--;
if (j < contractsCount) {
System.arraycopy(contracts, j+1, contracts, j, contractsCount - j);
}
j--;
if (j < i)
i--;
continue;
}
}
if (filterDefaultMethods && contractI.isDefaultMethod()) {
contractsCount--;
if (i < contractsCount) {
System.arraycopy(contracts, i+1, contracts, i, contractsCount - i);
}
i--;
}
}
if (contractsCount < contractsLength) {
System.arraycopy(contracts, 0, contracts = new MethodBinding[contractsCount], 0, contractsCount);
}
return contracts;
}
@Override
public MethodBinding getSingleAbstractMethod(Scope scope, boolean replaceWildcards) {
int index = replaceWildcards ? 0 : 1;
if (this.singleAbstractMethod != null) {
if (this.singleAbstractMethod[index] != null)
return this.singleAbstractMethod[index];
} else {
this.singleAbstractMethod = new MethodBinding[2];
}
if (this.compoundName != null)
scope.compilationUnitScope().recordQualifiedReference(this.compoundName);
MethodBinding[] methods = null;
try {
methods = getInterfaceAbstractContracts(scope, replaceWildcards, true);
if (methods == null || methods.length == 0)
return this.singleAbstractMethod[index] = samProblemBinding;
int contractParameterLength = 0;
char [] contractSelector = null;
for (int i = 0, length = methods.length; i < length; i++) {
MethodBinding method = methods[i];
if (method == null) continue;
if (contractSelector == null) {
contractSelector = method.selector;
contractParameterLength = method.parameters == null ? 0 : method.parameters.length;
} else {
int methodParameterLength = method.parameters == null ? 0 : method.parameters.length;
if (methodParameterLength != contractParameterLength || !CharOperation.equals(method.selector, contractSelector))
return this.singleAbstractMethod[index] = samProblemBinding;
}
}
} catch (InvalidInputException e) {
return this.singleAbstractMethod[index] = samProblemBinding;
}
if (methods.length == 1)
return this.singleAbstractMethod[index] = methods[0];
final LookupEnvironment environment = scope.environment();
boolean genericMethodSeen = false;
int length = methods.length;
boolean analyseNullAnnotations = environment.globalOptions.isAnnotationBasedNullAnalysisEnabled;
next:for (int i = length - 1; i >= 0; --i) {
MethodBinding method = methods[i], otherMethod = null;
if (method.typeVariables != Binding.NO_TYPE_VARIABLES)
genericMethodSeen = true;
TypeBinding returnType = method.returnType;
TypeBinding[] parameters = method.parameters;
for (int j = 0; j < length; j++) {
if (i == j) continue;
otherMethod = methods[j];
if (otherMethod.typeVariables != Binding.NO_TYPE_VARIABLES)
genericMethodSeen = true;
if (genericMethodSeen) {
otherMethod = MethodVerifier.computeSubstituteMethod(otherMethod, method, environment);
if (otherMethod == null)
continue next;
}
if (!MethodVerifier.isSubstituteParameterSubsignature(method, otherMethod, environment) || !MethodVerifier.areReturnTypesCompatible(method, otherMethod, environment))
continue next;
if (analyseNullAnnotations) {
returnType = NullAnnotationMatching.strongerType(returnType, otherMethod.returnType, environment);
parameters = NullAnnotationMatching.weakerTypes(parameters, otherMethod.parameters, environment);
}
}
ReferenceBinding [] exceptions = new ReferenceBinding[0];
int exceptionsCount = 0, exceptionsLength = 0;
final MethodBinding theAbstractMethod = method;
boolean shouldEraseThrows = theAbstractMethod.typeVariables == Binding.NO_TYPE_VARIABLES && genericMethodSeen;
boolean shouldAdaptThrows = theAbstractMethod.typeVariables != Binding.NO_TYPE_VARIABLES;
final int typeVariableLength = theAbstractMethod.typeVariables.length;
none:for (i = 0; i < length; i++) {
method = methods[i];
ReferenceBinding[] methodThrownExceptions = method.thrownExceptions;
int methodExceptionsLength = methodThrownExceptions == null ? 0: methodThrownExceptions.length;
if (methodExceptionsLength == 0) break none;
if (shouldAdaptThrows && method != theAbstractMethod) {
System.arraycopy(methodThrownExceptions, 0, methodThrownExceptions = new ReferenceBinding[methodExceptionsLength], 0, methodExceptionsLength);
for (int tv = 0; tv < typeVariableLength; tv++) {
if (methodThrownExceptions[tv] instanceof TypeVariableBinding) {
methodThrownExceptions[tv] = theAbstractMethod.typeVariables[tv];
}
}
}
nextException: for (int j = 0; j < methodExceptionsLength; j++) {
ReferenceBinding methodException = methodThrownExceptions[j];
if (shouldEraseThrows)
methodException = (ReferenceBinding) methodException.erasure();
nextMethod: for (int k = 0; k < length; k++) {
if (i == k) continue;
otherMethod = methods[k];
ReferenceBinding[] otherMethodThrownExceptions = otherMethod.thrownExceptions;
int otherMethodExceptionsLength = otherMethodThrownExceptions == null ? 0 : otherMethodThrownExceptions.length;
if (otherMethodExceptionsLength == 0) break none;
if (shouldAdaptThrows && otherMethod != theAbstractMethod) {
System.arraycopy(otherMethodThrownExceptions,
0,
otherMethodThrownExceptions = new ReferenceBinding[otherMethodExceptionsLength],
0,
otherMethodExceptionsLength);
for (int tv = 0; tv < typeVariableLength; tv++) {
if (otherMethodThrownExceptions[tv] instanceof TypeVariableBinding) {
otherMethodThrownExceptions[tv] = theAbstractMethod.typeVariables[tv];
}
}
}
for (int l = 0; l < otherMethodExceptionsLength; l++) {
ReferenceBinding otherException = otherMethodThrownExceptions[l];
if (shouldEraseThrows)
otherException = (ReferenceBinding) otherException.erasure();
if (methodException.isCompatibleWith(otherException))
continue nextMethod;
}
continue nextException;
}
if (exceptionsCount == exceptionsLength) {
System.arraycopy(exceptions, 0, exceptions = new ReferenceBinding[exceptionsLength += 16], 0, exceptionsCount);
}
exceptions[exceptionsCount++] = methodException;
}
}
if (exceptionsCount != exceptionsLength) {
System.arraycopy(exceptions, 0, exceptions = new ReferenceBinding[exceptionsCount], 0, exceptionsCount);
}
this.singleAbstractMethod[index] = new MethodBinding(theAbstractMethod.modifiers | ClassFileConstants.AccSynthetic,
theAbstractMethod.selector,
returnType,
parameters,
exceptions,
theAbstractMethod.declaringClass);
this.singleAbstractMethod[index].typeVariables = theAbstractMethod.typeVariables;
return this.singleAbstractMethod[index];
}
return this.singleAbstractMethod[index] = samProblemBinding;
}
public static boolean isConsistentIntersection(TypeBinding[] intersectingTypes) {
TypeBinding[] ci = new TypeBinding[intersectingTypes.length];
for (int i = 0; i < ci.length; i++) {
TypeBinding current = intersectingTypes[i];
ci[i] = (current.isClass() || current.isArrayType())
? current : current.superclass();
}
TypeBinding mostSpecific = ci[0];
for (int i = 1; i < ci.length; i++) {
TypeBinding current = ci[i];
if (current.isTypeVariable() || current.isWildcard() || !current.isProperType(true))
continue;
if (mostSpecific.isSubtypeOf(current, false))
continue;
else if (current.isSubtypeOf(mostSpecific, false))
mostSpecific = current;
else
return false;
}
return true;
}
public ModuleBinding module() {
if (this.fPackage != null)
return this.fPackage.enclosingModule;
return null;
}
public boolean hasEnclosingInstanceContext() {
if (isMemberType() && !isStatic())
return true;
MethodBinding enclosingMethod = enclosingMethod();
if (enclosingMethod != null)
return !enclosingMethod.isStatic();
return false;
}
}