package org.eclipse.jdt.internal.compiler.ast;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
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.ExtraCompilerModifiers;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.InferenceContext18;
import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.ParameterizedMethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
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.lookup.TypeVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding;
@SuppressWarnings({"rawtypes", "unchecked"})
public abstract class ASTNode implements TypeConstants, TypeIds {
public int sourceStart, sourceEnd;
public final static int Bit1 = 0x1;
public final static int Bit2 = 0x2;
public final static int Bit3 = 0x4;
public final static int Bit4 = 0x8;
public final static int Bit5 = 0x10;
public final static int Bit6 = 0x20;
public final static int Bit7 = 0x40;
public final static int Bit8 = 0x80;
public final static int Bit9 = 0x100;
public final static int Bit10= 0x200;
public final static int Bit11 = 0x400;
public final static int Bit12 = 0x800;
public final static int Bit13 = 0x1000;
public final static int Bit14 = 0x2000;
public final static int Bit15 = 0x4000;
public final static int Bit16 = 0x8000;
public final static int Bit17 = 0x10000;
public final static int Bit18 = 0x20000;
public final static int Bit19 = 0x40000;
public final static int Bit20 = 0x80000;
public final static int Bit21 = 0x100000;
public final static int Bit22 = 0x200000;
public final static int Bit23 = 0x400000;
public final static int Bit24 = 0x800000;
public final static int Bit25 = 0x1000000;
public final static int Bit26 = 0x2000000;
public final static int Bit27 = 0x4000000;
public final static int Bit28 = 0x8000000;
public final static int Bit29 = 0x10000000;
public final static int Bit30 = 0x20000000;
public final static int Bit31 = 0x40000000;
public final static int Bit32 = 0x80000000;
public final static long Bit32L = 0x80000000L;
public final static long Bit33L = 0x100000000L;
public final static long Bit34L = 0x200000000L;
public final static long Bit35L = 0x400000000L;
public final static long Bit36L = 0x800000000L;
public final static long Bit37L = 0x1000000000L;
public final static long Bit38L = 0x2000000000L;
public final static long Bit39L = 0x4000000000L;
public final static long Bit40L = 0x8000000000L;
public final static long Bit41L = 0x10000000000L;
public final static long Bit42L = 0x20000000000L;
public final static long Bit43L = 0x40000000000L;
public final static long Bit44L = 0x80000000000L;
public final static long Bit45L = 0x100000000000L;
public final static long Bit46L = 0x200000000000L;
public final static long Bit47L = 0x400000000000L;
public final static long Bit48L = 0x800000000000L;
public final static long Bit49L = 0x1000000000000L;
public final static long Bit50L = 0x2000000000000L;
public final static long Bit51L = 0x4000000000000L;
public final static long Bit52L = 0x8000000000000L;
public final static long Bit53L = 0x10000000000000L;
public final static long Bit54L = 0x20000000000000L;
public final static long Bit55L = 0x40000000000000L;
public final static long Bit56L = 0x80000000000000L;
public final static long Bit57L = 0x100000000000000L;
public final static long Bit58L = 0x200000000000000L;
public final static long Bit59L = 0x400000000000000L;
public final static long Bit60L = 0x800000000000000L;
public final static long Bit61L = 0x1000000000000000L;
public final static long Bit62L = 0x2000000000000000L;
public final static long Bit63L = 0x4000000000000000L;
public final static long Bit64L = 0x8000000000000000L;
public int bits = IsReachable;
public static final int ReturnTypeIDMASK = Bit1|Bit2|Bit3|Bit4;
public static final int OperatorSHIFT = 6;
public static final int OperatorMASK = Bit7|Bit8|Bit9|Bit10|Bit11|Bit12;
public static final int IsReturnedValue = Bit5;
public static final int UnnecessaryCast = Bit15;
public static final int DisableUnnecessaryCastCheck = Bit6;
public static final int GenerateCheckcast = Bit7;
public static final int UnsafeCast = Bit8;
public static final int RestrictiveFlagMASK = Bit1|Bit2|Bit3;
public static final int IsTypeElided = Bit2;
public static final int IsArgument = Bit3;
public static final int IsLocalDeclarationReachable = Bit31;
public static final int IsForeachElementVariable = Bit5;
public static final int ShadowsOuterLocal = Bit22;
public static final int IsAdditionalDeclarator = Bit23;
public static final int FirstAssignmentToLocal = Bit4;
public static final int NeedReceiverGenericCast = Bit19;
public static final int IsImplicitThis = Bit3;
public static final int DepthSHIFT = 5;
public static final int DepthMASK = Bit6|Bit7|Bit8|Bit9|Bit10|Bit11|Bit12|Bit13;
public static final int IsCapturedOuterLocal = Bit20;
public static final int IsReachable = Bit32;
public static final int LabelUsed = Bit7;
public static final int DocumentedFallthrough = Bit30;
public static final int DocumentedCasesOmitted = Bit31;
public static final int IsSubRoutineEscaping = Bit15;
public static final int IsTryBlockExiting = Bit30;
public static final int ContainsAssertion = Bit1;
public static final int IsLocalType = Bit9;
public static final int IsAnonymousType = Bit10;
public static final int IsMemberType = Bit11;
public static final int HasAbstractMethods = Bit12;
public static final int IsSecondaryType = Bit13;
public static final int HasBeenGenerated = Bit14;
public static final int HasLocalType = Bit2;
public static final int HasBeenResolved = Bit5;
public static final int ParenthesizedSHIFT = 21;
public static final int ParenthesizedMASK = Bit22|Bit23|Bit24|Bit25|Bit26|Bit27|Bit28|Bit29;
public static final int IgnoreNoEffectAssignCheck = Bit30;
public static final int IsStrictlyAssigned = Bit14;
public static final int IsCompoundAssigned = Bit17;
public static final int DiscardEnclosingInstance = Bit14;
public static final int Unchecked = Bit17;
public static final int ResolveJavadoc = Bit17;
public static final int IsUsefulEmptyStatement = Bit1;
public static final int UndocumentedEmptyBlock = Bit4;
public static final int OverridingMethodWithSupercall = Bit5;
public static final int CanBeStatic = Bit9;
public static final int ErrorInSignature = Bit6;
public static final int NeedFreeReturn = Bit7;
public static final int IsDefaultConstructor = Bit8;
public static final int HasAllMethodBodies = Bit5;
public static final int IsImplicitUnit = Bit1;
public static final int InsideJavadoc = Bit16;
public static final int SuperAccess = Bit15;
public static final int Empty = Bit19;
public static final int IsElseIfStatement = Bit30;
public static final int ThenExit = Bit31;
public static final int IsElseStatementUnreachable = Bit8;
public static final int IsThenStatementUnreachable = Bit9;
public static final int IsSuperType = Bit5;
public static final int IsVarArgs = Bit15;
public static final int IgnoreRawTypeCheck = Bit31;
public static final int IsAnnotationDefaultValue = Bit1;
public static final int IsNonNull = Bit18;
public static final int NeededScope = Bit30;
public static final int OnDemand = Bit18;
public static final int Used = Bit2;
public static final int inModule = Bit19;
public static final int DidResolve = Bit19;
public static final int IsAnySubRoutineEscaping = Bit30;
public static final int IsSynchronized = Bit31;
public static final int BlockExit = Bit30;
public static final int IsRecovered = Bit6;
public static final int HasSyntaxErrors = Bit20;
public static final int INVOCATION_ARGUMENT_OK = 0;
public static final int INVOCATION_ARGUMENT_UNCHECKED = 1;
public static final int INVOCATION_ARGUMENT_WILDCARD = 2;
public static final int HasTypeAnnotations = Bit21;
public static final int IsUnionType = Bit30;
public static final int IsDiamond = Bit20;
public static final int InsideExpressionStatement = Bit21;
public static final int IsSynthetic = ASTNode.Bit7;
public static final int HasFunctionalInterfaceTypes = ASTNode.Bit22;
public static final Argument [] NO_ARGUMENTS = new Argument [0];
public ASTNode() {
super();
}
private static int checkInvocationArgument(BlockScope scope, Expression argument, TypeBinding parameterType, TypeBinding argumentType, TypeBinding originalParameterType) {
argument.computeConversion(scope, parameterType, argumentType);
if (argumentType != TypeBinding.NULL && parameterType.kind() == Binding.WILDCARD_TYPE) {
WildcardBinding wildcard = (WildcardBinding) parameterType;
if (wildcard.boundKind != Wildcard.SUPER) {
return INVOCATION_ARGUMENT_WILDCARD;
}
}
TypeBinding checkedParameterType = parameterType;
if (TypeBinding.notEquals(argumentType, checkedParameterType) && argumentType.needsUncheckedConversion(checkedParameterType)) {
scope.problemReporter().unsafeTypeConversion(argument, argumentType, checkedParameterType);
return INVOCATION_ARGUMENT_UNCHECKED;
}
return INVOCATION_ARGUMENT_OK;
}
public static boolean checkInvocationArguments(BlockScope scope, Expression receiver, TypeBinding receiverType, MethodBinding method, Expression[] arguments, TypeBinding[] argumentTypes, boolean argsContainCast, InvocationSite invocationSite) {
long sourceLevel = scope.compilerOptions().sourceLevel;
boolean is1_7 = sourceLevel >= ClassFileConstants.JDK1_7;
TypeBinding[] params = method.parameters;
int paramLength = params.length;
boolean isRawMemberInvocation = !method.isStatic()
&& !receiverType.isUnboundWildcard()
&& method.declaringClass.isRawType()
&& method.hasSubstitutedParameters();
boolean uncheckedBoundCheck = (method.tagBits & TagBits.HasUncheckedTypeArgumentForBoundCheck) != 0;
MethodBinding rawOriginalGenericMethod = null;
if (!isRawMemberInvocation) {
if (method instanceof ParameterizedGenericMethodBinding) {
ParameterizedGenericMethodBinding paramMethod = (ParameterizedGenericMethodBinding) method;
if (paramMethod.isRaw && method.hasSubstitutedParameters()) {
rawOriginalGenericMethod = method.original();
}
}
}
int invocationStatus = INVOCATION_ARGUMENT_OK;
if (arguments == null) {
if (method.isVarargs()) {
TypeBinding parameterType = ((ArrayBinding) params[paramLength-1]).elementsType();
if (!parameterType.isReifiable()
&& (!is1_7 || ((method.tagBits & TagBits.AnnotationSafeVarargs) == 0))) {
scope.problemReporter().unsafeGenericArrayForVarargs(parameterType, (ASTNode)invocationSite);
}
}
} else {
if (method.isVarargs()) {
int lastIndex = paramLength - 1;
for (int i = 0; i < lastIndex; i++) {
TypeBinding originalRawParam = rawOriginalGenericMethod == null ? null : rawOriginalGenericMethod.parameters[i];
invocationStatus |= checkInvocationArgument(scope, arguments[i], params[i] , argumentTypes[i], originalRawParam);
}
int argLength = arguments.length;
if (lastIndex <= argLength) {
TypeBinding parameterType = params[lastIndex];
TypeBinding originalRawParam = null;
if (paramLength != argLength || parameterType.dimensions() != argumentTypes[lastIndex].dimensions()) {
parameterType = ((ArrayBinding) parameterType).elementsType();
if (!parameterType.isReifiable()
&& (!is1_7 || ((method.tagBits & TagBits.AnnotationSafeVarargs) == 0))) {
scope.problemReporter().unsafeGenericArrayForVarargs(parameterType, (ASTNode)invocationSite);
}
originalRawParam = rawOriginalGenericMethod == null ? null : ((ArrayBinding)rawOriginalGenericMethod.parameters[lastIndex]).elementsType();
}
for (int i = lastIndex; i < argLength; i++) {
invocationStatus |= checkInvocationArgument(scope, arguments[i], parameterType, argumentTypes[i], originalRawParam);
}
}
if (paramLength == argLength) {
int varargsIndex = paramLength - 1;
ArrayBinding varargsType = (ArrayBinding) params[varargsIndex];
TypeBinding lastArgType = argumentTypes[varargsIndex];
int dimensions;
if (lastArgType == TypeBinding.NULL) {
if (!(varargsType.leafComponentType().isBaseType() && varargsType.dimensions() == 1))
scope.problemReporter().varargsArgumentNeedCast(method, lastArgType, invocationSite);
} else if (varargsType.dimensions <= (dimensions = lastArgType.dimensions())) {
if (lastArgType.leafComponentType().isBaseType()) {
dimensions--;
}
if (varargsType.dimensions < dimensions) {
scope.problemReporter().varargsArgumentNeedCast(method, lastArgType, invocationSite);
} else if (varargsType.dimensions == dimensions
&& TypeBinding.notEquals(lastArgType, varargsType)
&& TypeBinding.notEquals(lastArgType.leafComponentType().erasure(), varargsType.leafComponentType.erasure())
&& lastArgType.isCompatibleWith(varargsType.elementsType())
&& lastArgType.isCompatibleWith(varargsType)) {
scope.problemReporter().varargsArgumentNeedCast(method, lastArgType, invocationSite);
}
}
}
} else {
for (int i = 0; i < paramLength; i++) {
TypeBinding originalRawParam = rawOriginalGenericMethod == null ? null : rawOriginalGenericMethod.parameters[i];
invocationStatus |= checkInvocationArgument(scope, arguments[i], params[i], argumentTypes[i], originalRawParam);
}
}
if (argsContainCast) {
CastExpression.checkNeedForArgumentCasts(scope, receiver, receiverType, method, arguments, argumentTypes, invocationSite);
}
}
if ((invocationStatus & INVOCATION_ARGUMENT_WILDCARD) != 0) {
scope.problemReporter().wildcardInvocation((ASTNode)invocationSite, receiverType, method, argumentTypes);
} else if (!method.isStatic() && !receiverType.isUnboundWildcard() && method.declaringClass.isRawType() && method.hasSubstitutedParameters()) {
if (scope.compilerOptions().reportUnavoidableGenericTypeProblems || receiver == null || !receiver.forcedToBeRaw(scope.referenceContext())) {
scope.problemReporter().unsafeRawInvocation((ASTNode)invocationSite, method);
}
} else if (rawOriginalGenericMethod != null
|| uncheckedBoundCheck
|| ((invocationStatus & INVOCATION_ARGUMENT_UNCHECKED) != 0)) {
if (method instanceof ParameterizedGenericMethodBinding) {
scope.problemReporter().unsafeRawGenericMethodInvocation((ASTNode)invocationSite, method, argumentTypes);
return true;
}
if (sourceLevel >= ClassFileConstants.JDK1_8)
return true;
}
return false;
}
public ASTNode concreteStatement() {
return this;
}
public final boolean isFieldUseDeprecated(FieldBinding field, Scope scope, int filteredBits) {
if ((this.bits & ASTNode.InsideJavadoc) == 0
&& (filteredBits & IsStrictlyAssigned) == 0
&& field.isOrEnclosedByPrivateType()
&& !scope.isDefinedInField(field))
{
if (((filteredBits & IsCompoundAssigned) != 0))
field.original().compoundUseFlag++;
else
field.original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
}
if ((field.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0) {
ModuleBinding module = field.declaringClass.module();
LookupEnvironment env = (module == null) ? scope.environment() : module.environment;
AccessRestriction restriction =
env.getAccessRestriction(field.declaringClass.erasure());
if (restriction != null) {
scope.problemReporter().forbiddenReference(field, this,
restriction.classpathEntryType, restriction.classpathEntryName,
restriction.getProblemId());
}
}
if (!field.isViewedAsDeprecated()) return false;
if (scope.isDefinedInSameUnit(field.declaringClass)) return false;
if (!scope.compilerOptions().reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
return true;
}
public boolean isImplicitThis() {
return false;
}
public boolean receiverIsImplicitThis() {
return false;
}
public final boolean isMethodUseDeprecated(MethodBinding method, Scope scope,
boolean isExplicitUse, InvocationSite invocation) {
if ((this.bits & ASTNode.InsideJavadoc) == 0 && method.isOrEnclosedByPrivateType() && !scope.isDefinedInMethod(method)) {
method.original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
}
if (isExplicitUse && (method.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0) {
ModuleBinding module = method.declaringClass.module();
LookupEnvironment env = (module == null) ? scope.environment() : module.environment;
AccessRestriction restriction =
env.getAccessRestriction(method.declaringClass.erasure());
if (restriction != null) {
scope.problemReporter().forbiddenReference(method, invocation,
restriction.classpathEntryType, restriction.classpathEntryName,
restriction.getProblemId());
}
}
if (!method.isViewedAsDeprecated()) return false;
if (scope.isDefinedInSameUnit(method.declaringClass)) return false;
if (!isExplicitUse &&
(method.modifiers & ClassFileConstants.AccDeprecated) == 0) {
return false;
}
if (!scope.compilerOptions().reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
return true;
}
public boolean isSuper() {
return false;
}
public boolean isQualifiedSuper() {
return false;
}
public boolean isThis() {
return false;
}
public boolean isUnqualifiedSuper() {
return false;
}
public final boolean isTypeUseDeprecated(TypeBinding type, Scope scope) {
if (type.isArrayType()) {
type = ((ArrayBinding) type).leafComponentType;
}
if (type.isBaseType())
return false;
ReferenceBinding refType = (ReferenceBinding) type;
if ((this.bits & ASTNode.InsideJavadoc) == 0 && refType instanceof TypeVariableBinding) {
refType.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
}
if ((this.bits & ASTNode.InsideJavadoc) == 0 && refType.isOrEnclosedByPrivateType() && !scope.isDefinedInType(refType)) {
((ReferenceBinding)refType.erasure()).modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
}
if (refType.hasRestrictedAccess()) {
ModuleBinding module = refType.module();
LookupEnvironment env = (module == null) ? scope.environment() : module.environment;
AccessRestriction restriction = env.getAccessRestriction(type.erasure());
if (restriction != null) {
scope.problemReporter().forbiddenReference(type, this, restriction.classpathEntryType,
restriction.classpathEntryName, restriction.getProblemId());
}
}
refType.initializeDeprecatedAnnotationTagBits();
if (!refType.isViewedAsDeprecated()) return false;
if (scope.isDefinedInSameUnit(refType)) return false;
if (!scope.compilerOptions().reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
return true;
}
public abstract StringBuffer print(int indent, StringBuffer output);
public static StringBuffer printAnnotations(Annotation[] annotations, StringBuffer output) {
int length = annotations.length;
for (int i = 0; i < length; i++) {
if (i > 0) {
output.append(" ");
}
Annotation annotation2 = annotations[i];
if (annotation2 != null) {
annotation2.print(0, output);
} else {
output.append('?');
}
}
return output;
}
public static StringBuffer printIndent(int indent, StringBuffer output) {
for (int i = indent; i > 0; i--) output.append(" ");
return output;
}
public static StringBuffer printModifiers(int modifiers, StringBuffer output) {
if ((modifiers & ClassFileConstants.AccPublic) != 0)
output.append("public ");
if ((modifiers & ClassFileConstants.AccPrivate) != 0)
output.append("private ");
if ((modifiers & ClassFileConstants.AccProtected) != 0)
output.append("protected ");
if ((modifiers & ClassFileConstants.AccStatic) != 0)
output.append("static ");
if ((modifiers & ClassFileConstants.AccFinal) != 0)
output.append("final ");
if ((modifiers & ClassFileConstants.AccSynchronized) != 0)
output.append("synchronized ");
if ((modifiers & ClassFileConstants.AccVolatile) != 0)
output.append("volatile ");
if ((modifiers & ClassFileConstants.AccTransient) != 0)
output.append("transient ");
if ((modifiers & ClassFileConstants.AccNative) != 0)
output.append("native ");
if ((modifiers & ClassFileConstants.AccAbstract) != 0)
output.append("abstract ");
if ((modifiers & ExtraCompilerModifiers.AccDefaultMethod) != 0)
output.append("default ");
return output;
}
public static MethodBinding resolvePolyExpressionArguments(Invocation invocation, MethodBinding method, TypeBinding[] argumentTypes, BlockScope scope) {
MethodBinding candidateMethod = method.isValidBinding() ? method : method instanceof ProblemMethodBinding ? ((ProblemMethodBinding) method).closestMatch : null;
if (candidateMethod == null)
return method;
ProblemMethodBinding problemMethod = null;
boolean variableArity = candidateMethod.isVarargs();
final TypeBinding[] parameters = candidateMethod.parameters;
Expression[] arguments = invocation.arguments();
if (variableArity && arguments != null && parameters.length == arguments.length) {
if (arguments[arguments.length-1].isCompatibleWith(parameters[parameters.length-1], scope)) {
variableArity = false;
}
}
for (int i = 0, length = arguments == null ? 0 : arguments.length; i < length; i++) {
Expression argument = arguments[i];
TypeBinding parameterType = InferenceContext18.getParameter(parameters, i, variableArity);
if (parameterType == null)
continue;
if (argumentTypes[i] != null && argumentTypes[i].isPolyType()) {
argument.setExpectedType(parameterType);
TypeBinding updatedArgumentType;
if (argument instanceof LambdaExpression) {
LambdaExpression lambda = (LambdaExpression) argument;
boolean skipKosherCheck = method.problemId() == ProblemReasons.Ambiguous;
updatedArgumentType = lambda.resolveType(scope, skipKosherCheck);
if (lambda.hasErrors() || lambda.hasDescripterProblem) {
continue;
}
if (!lambda.isCompatibleWith(parameterType, scope)) {
if (method.isValidBinding() && problemMethod == null) {
TypeBinding[] originalArguments = Arrays.copyOf(argumentTypes, argumentTypes.length);
if (lambda.reportShapeError(parameterType, scope)) {
problemMethod = new ProblemMethodBinding(candidateMethod, method.selector, originalArguments, ProblemReasons.ErrorAlreadyReported);
} else {
problemMethod = new ProblemMethodBinding(candidateMethod, method.selector, originalArguments, ProblemReasons.NotFound);
}
}
continue;
}
lambda.updateLocalTypesInMethod(candidateMethod);
} else {
updatedArgumentType = argument.resolveType(scope);
}
if (updatedArgumentType != null && updatedArgumentType.kind() != Binding.POLY_TYPE) {
argumentTypes[i] = updatedArgumentType;
if (candidateMethod.isPolymorphic())
candidateMethod.parameters[i] = updatedArgumentType;
}
}
}
if (method instanceof ParameterizedGenericMethodBinding) {
InferenceContext18 ic18 = invocation.getInferenceContext((ParameterizedMethodBinding) method);
if (ic18 != null)
ic18.flushBoundOutbox();
}
if (problemMethod != null)
return problemMethod;
return method;
}
public static void resolveAnnotations(BlockScope scope, Annotation[] sourceAnnotations, Binding recipient) {
resolveAnnotations(scope, sourceAnnotations, recipient, false);
if (recipient instanceof SourceTypeBinding)
((SourceTypeBinding) recipient).evaluateNullAnnotations();
}
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.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 :
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) {
switch (recipient.kind()) {
case Binding.TYPE_USE:
if (annotations != null) {
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) {
for (int j = 0; j < length; j++) {
Annotation annot = sourceAnnotations[j];
annotations[j] = annot.getCompilerAnnotation();
}
}
break;
case Binding.LOCAL :
LocalVariableBinding local = (LocalVariableBinding) recipient;
long otherLocalTagBits = ((LocalVariableBinding) annotationRecipient).tagBits;
local.tagBits = otherLocalTagBits;
if ((otherLocalTagBits & TagBits.AnnotationSuppressWarnings) == 0) {
if (annotations != null) {
for (int j = 0; j < length; j++) {
Annotation annot = sourceAnnotations[j];
annotations[j] = annot.getCompilerAnnotation();
}
}
} else if (annotations != null) {
LocalDeclaration localDeclaration = local.declaration;
int declarationSourceEnd = localDeclaration.declarationSourceEnd;
int declarationSourceStart = localDeclaration.declarationSourceStart;
for (int j = 0; j < length; j++) {
Annotation annot = sourceAnnotations[j];
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);
}
}
}
}
break;
}
return annotations;
} else {
annotation.recipient = recipient;
annotation.resolveType(scope);
if (annotations != null) {
annotations[i] = annotation.getCompilerAnnotation();
}
}
}
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);
}
}
if (annotations != null && length > 1) {
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);
}
distinctAnnotations[j] = null;
if (annotationType.isRepeatableAnnotationType()) {
Annotation persistibleAnnotation = sourceAnnotations[i].getPersistibleAnnotation();
if (persistibleAnnotation instanceof ContainerAnnotation)
container = (ContainerAnnotation) persistibleAnnotation;
if (container == null) {
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);
}
}
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;
}
public static TypeBinding resolveAnnotations(BlockScope scope, Annotation[][] sourceAnnotations, TypeBinding type) {
int levels = sourceAnnotations == null ? 0 : sourceAnnotations.length;
if (type == null || levels == 0)
return type;
AnnotationBinding [][] annotationBindings = new AnnotationBinding [levels][];
for (int i = 0; i < levels; i++) {
Annotation[] annotations = sourceAnnotations[i];
if (annotations != null && annotations.length > 0) {
annotationBindings[i] = resolveAnnotations(scope, annotations, TypeBinding.TYPE_USE_BINDING, false);
}
}
return scope.environment().createAnnotatedType(type, annotationBindings);
}
public static void handleNonNullByDefault(BlockScope scope, Annotation[] sourceAnnotations, LocalDeclaration localDeclaration) {
if (sourceAnnotations == null || sourceAnnotations.length == 0) {
return;
}
int length = sourceAnnotations.length;
int defaultNullness = 0;
Annotation lastNNBDAnnotation = null;
for (int i = 0; i < length; i++) {
Annotation annotation = sourceAnnotations[i];
long value = annotation.handleNonNullByDefault(scope);
if (value != 0) {
defaultNullness |= value;
lastNNBDAnnotation = annotation;
}
}
if (defaultNullness != 0) {
LocalVariableBinding binding = new LocalVariableBinding(localDeclaration, null, 0, false);
Binding target = scope.checkRedundantDefaultNullness(defaultNullness, localDeclaration.sourceStart);
boolean recorded = scope.recordNonNullByDefault(binding, defaultNullness, lastNNBDAnnotation,
lastNNBDAnnotation.sourceStart, localDeclaration.declarationSourceEnd);
if (recorded) {
if (target != null) {
scope.problemReporter().nullDefaultAnnotationIsRedundant(localDeclaration,
new Annotation[] { lastNNBDAnnotation }, target);
}
}
}
}
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;
default:
return;
}
AnnotationBinding [] se8Annotations = null;
int se8count = 0;
long se8nullBits = 0;
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)) {
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)) {
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.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);
}
}
}
private static TypeBinding mergeAnnotationsIntoType(BlockScope scope, AnnotationBinding[] se8Annotations, long se8nullBits, Annotation se8NullAnnotation,
TypeReference typeRef, TypeBinding existingType)
{
if (existingType == null || !existingType.isValidBinding()) return existingType;
TypeReference unionRef = typeRef.isUnionType() ? ((UnionTypeReference) typeRef).typeReferences[0] : null;
TypeBinding oldLeafType = (unionRef == null) ? existingType.leafComponentType() : unionRef.resolvedType;
if (se8nullBits != 0) {
if (typeRef instanceof ArrayTypeReference) {
ArrayTypeReference arrayTypeReference = (ArrayTypeReference) typeRef;
if(arrayTypeReference.leafComponentTypeWithoutDefaultNullness != null) {
oldLeafType=arrayTypeReference.leafComponentTypeWithoutDefaultNullness;
}
}
}
if (se8nullBits != 0 && oldLeafType.isBaseType()) {
scope.problemReporter().illegalAnnotationForBaseType(typeRef, new Annotation[] { se8NullAnnotation }, se8nullBits);
return existingType;
}
long prevNullBits = oldLeafType.tagBits & TagBits.AnnotationNullMASK;
if ((prevNullBits | se8nullBits) == TagBits.AnnotationNullMASK) {
if (!(oldLeafType instanceof TypeVariableBinding)) {
if (prevNullBits != TagBits.AnnotationNullMASK && se8nullBits != TagBits.AnnotationNullMASK) {
scope.problemReporter().contradictoryNullAnnotations(se8NullAnnotation);
}
se8Annotations = Binding.NO_ANNOTATIONS;
se8nullBits = 0;
}
oldLeafType = oldLeafType.withoutToplevelNullAnnotation();
}
AnnotationBinding [][] goodies = new AnnotationBinding[typeRef.getAnnotatableLevels()][];
goodies[0] = se8Annotations;
TypeBinding newLeafType = scope.environment().createAnnotatedType(oldLeafType, goodies);
if (unionRef == null) {
typeRef.resolvedType = existingType.isArrayType() ? scope.environment().createArrayType(newLeafType, existingType.dimensions(), existingType.getTypeAnnotations()) : newLeafType;
} else {
unionRef.resolvedType = newLeafType;
unionRef.bits |= HasTypeAnnotations;
}
return typeRef.resolvedType;
}
public static void resolveDeprecatedAnnotations(BlockScope scope, Annotation[] annotations, Binding recipient) {
if (recipient != null) {
int kind = recipient.kind();
if (annotations != null) {
int length;
if ((length = annotations.length) >= 0) {
switch (kind) {
case Binding.PACKAGE :
PackageBinding packageBinding = (PackageBinding) recipient;
if ((packageBinding.tagBits & TagBits.DeprecatedAnnotationResolved) != 0) return;
break;
case Binding.TYPE :
case Binding.GENERIC_TYPE :
ReferenceBinding type = (ReferenceBinding) recipient;
if ((type.tagBits & TagBits.DeprecatedAnnotationResolved) != 0) return;
break;
case Binding.METHOD :
MethodBinding method = (MethodBinding) recipient;
if ((method.tagBits & TagBits.DeprecatedAnnotationResolved) != 0) return;
break;
case Binding.FIELD :
FieldBinding field = (FieldBinding) recipient;
if ((field.tagBits & TagBits.DeprecatedAnnotationResolved) != 0) return;
break;
case Binding.LOCAL :
LocalVariableBinding local = (LocalVariableBinding) recipient;
if ((local.tagBits & TagBits.DeprecatedAnnotationResolved) != 0) return;
break;
default :
return;
}
for (int i = 0; i < length; i++) {
TypeReference annotationTypeRef = annotations[i].type;
if (!CharOperation.equals(TypeConstants.JAVA_LANG_DEPRECATED[2], annotationTypeRef.getLastToken())) continue;
TypeBinding annotationType = annotations[i].type.resolveType(scope);
if(annotationType != null && annotationType.isValidBinding() && annotationType.id == TypeIds.T_JavaLangDeprecated) {
long deprecationTagBits = TagBits.AnnotationDeprecated | TagBits.DeprecatedAnnotationResolved;
if (scope.compilerOptions().complianceLevel >= ClassFileConstants.JDK9) {
for (MemberValuePair memberValuePair : annotations[i].memberValuePairs()) {
if (CharOperation.equals(memberValuePair.name, TypeConstants.FOR_REMOVAL)) {
if (memberValuePair.value instanceof TrueLiteral)
deprecationTagBits |= TagBits.AnnotationTerminallyDeprecated;
break;
}
}
}
switch (kind) {
case Binding.PACKAGE :
PackageBinding packageBinding = (PackageBinding) recipient;
packageBinding.tagBits |= deprecationTagBits;
return;
case Binding.TYPE :
case Binding.GENERIC_TYPE :
case Binding.TYPE_PARAMETER :
ReferenceBinding type = (ReferenceBinding) recipient;
type.tagBits |= deprecationTagBits;
return;
case Binding.METHOD :
MethodBinding method = (MethodBinding) recipient;
method.tagBits |= deprecationTagBits;
return;
case Binding.FIELD :
FieldBinding field = (FieldBinding) recipient;
field.tagBits |= deprecationTagBits;
return;
case Binding.LOCAL :
LocalVariableBinding local = (LocalVariableBinding) recipient;
local.tagBits |= deprecationTagBits;
return;
default:
return;
}
}
}
}
}
switch (kind) {
case Binding.PACKAGE :
PackageBinding packageBinding = (PackageBinding) recipient;
packageBinding.tagBits |= TagBits.DeprecatedAnnotationResolved;
return;
case Binding.TYPE :
case Binding.GENERIC_TYPE :
case Binding.TYPE_PARAMETER :
ReferenceBinding type = (ReferenceBinding) recipient;
type.tagBits |= TagBits.DeprecatedAnnotationResolved;
return;
case Binding.METHOD :
MethodBinding method = (MethodBinding) recipient;
method.tagBits |= TagBits.DeprecatedAnnotationResolved;
return;
case Binding.FIELD :
FieldBinding field = (FieldBinding) recipient;
field.tagBits |= TagBits.DeprecatedAnnotationResolved;
return;
case Binding.LOCAL :
LocalVariableBinding local = (LocalVariableBinding) recipient;
local.tagBits |= TagBits.DeprecatedAnnotationResolved;
return;
default:
return;
}
}
}
public boolean checkingPotentialCompatibility() {
return false;
}
public void acceptPotentiallyCompatibleMethods(MethodBinding [] methods) {
}
public int sourceStart() {
return this.sourceStart;
}
public int sourceEnd() {
return this.sourceEnd;
}
@Override
public String toString() {
return print(0, new StringBuffer(30)).toString();
}
public void traverse(ASTVisitor visitor, BlockScope scope) {
}
}