001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: * Matt McCutchen
011: * Partial fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=122995.
012: *******************************************************************************/package org.eclipse.jdt.internal.compiler.ast;
013:
014: import org.eclipse.jdt.core.compiler.CharOperation;
015: import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
016: import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
017: import org.eclipse.jdt.internal.compiler.lookup.*;
018: import org.eclipse.jdt.internal.compiler.ASTVisitor;
019:
020: public abstract class ASTNode implements TypeConstants, TypeIds {
021:
022: public int sourceStart, sourceEnd;
023:
024: // storage for internal flags (32 bits) BIT USAGE
025: public final static int Bit1 = 0x1; // return type (operator) | name reference kind (name ref) | add assertion (type decl) | useful empty statement (empty statement)
026: public final static int Bit2 = 0x2; // return type (operator) | name reference kind (name ref) | has local type (type, method, field decl)
027: public final static int Bit3 = 0x4; // return type (operator) | name reference kind (name ref) | implicit this (this ref)
028: public final static int Bit4 = 0x8; // return type (operator) | first assignment to local (name ref,local decl) | undocumented empty block (block, type and method decl)
029: public final static int Bit5 = 0x10; // value for return (expression) | has all method bodies (unit) | supertype ref (type ref) | resolved (field decl)
030: public final static int Bit6 = 0x20; // depth (name ref, msg) | ignore need cast check (cast expression) | error in signature (method declaration/ initializer)
031: public final static int Bit7 = 0x40; // depth (name ref, msg) | operator (operator) | need runtime checkcast (cast expression) | label used (labelStatement) | needFreeReturn (AbstractMethodDeclaration)
032: public final static int Bit8 = 0x80; // depth (name ref, msg) | operator (operator) | unsafe cast (cast expression) | is default constructor (constructor declaration)
033: public final static int Bit9 = 0x100; // depth (name ref, msg) | operator (operator) | is local type (type decl)
034: public final static int Bit10 = 0x200; // depth (name ref, msg) | operator (operator) | is anonymous type (type decl)
035: public final static int Bit11 = 0x400; // depth (name ref, msg) | operator (operator) | is member type (type decl)
036: public final static int Bit12 = 0x800; // depth (name ref, msg) | operator (operator) | has abstract methods (type decl)
037: public final static int Bit13 = 0x1000; // depth (name ref, msg) | is secondary type (type decl)
038: public final static int Bit14 = 0x2000; // strictly assigned (reference lhs) | discard enclosing instance (explicit constr call) | hasBeenGenerated (type decl)
039: public final static int Bit15 = 0x4000; // is unnecessary cast (expression) | is varargs (type ref) | isSubRoutineEscaping (try statement) | superAccess (javadoc allocation expression/javadoc message send/javadoc return statement)
040: public final static int Bit16 = 0x8000; // in javadoc comment (name ref, type ref, msg)
041: public final static int Bit17 = 0x10000; // compound assigned (reference lhs)
042: public final static int Bit18 = 0x20000; // non null (expression) | onDemand (import reference)
043: public final static int Bit19 = 0x40000; // didResolve (parameterized qualified type ref/parameterized single type ref) | empty (javadoc return statement)
044: public final static int Bit20 = 0x80000;
045: public final static int Bit21 = 0x100000;
046: public final static int Bit22 = 0x200000; // parenthesis count (expression) | used (import reference)
047: public final static int Bit23 = 0x400000; // parenthesis count (expression)
048: public final static int Bit24 = 0x800000; // parenthesis count (expression)
049: public final static int Bit25 = 0x1000000; // parenthesis count (expression)
050: public final static int Bit26 = 0x2000000; // parenthesis count (expression)
051: public final static int Bit27 = 0x4000000; // parenthesis count (expression)
052: public final static int Bit28 = 0x8000000; // parenthesis count (expression)
053: public final static int Bit29 = 0x10000000; // parenthesis count (expression)
054: public final static int Bit30 = 0x20000000; // elseif (if statement) | try block exit (try statement) | fall-through (case statement) | ignore no effect assign (expression ref) | needScope (for statement) | isAnySubRoutineEscaping (return statement) | blockExit (synchronized statement)
055: public final static int Bit31 = 0x40000000; // local declaration reachable (local decl) | ignore raw type check (type ref) | discard entire assignment (assignment) | isSynchronized (return statement) | thenExit (if statement)
056: public final static int Bit32 = 0x80000000; // reachable (statement)
057:
058: public final static long Bit32L = 0x80000000L;
059: public final static long Bit33L = 0x100000000L;
060: public final static long Bit34L = 0x200000000L;
061: public final static long Bit35L = 0x400000000L;
062: public final static long Bit36L = 0x800000000L;
063: public final static long Bit37L = 0x1000000000L;
064: public final static long Bit38L = 0x2000000000L;
065: public final static long Bit39L = 0x4000000000L;
066: public final static long Bit40L = 0x8000000000L;
067: public final static long Bit41L = 0x10000000000L;
068: public final static long Bit42L = 0x20000000000L;
069: public final static long Bit43L = 0x40000000000L;
070: public final static long Bit44L = 0x80000000000L;
071: public final static long Bit45L = 0x100000000000L;
072: public final static long Bit46L = 0x200000000000L;
073: public final static long Bit47L = 0x400000000000L;
074: public final static long Bit48L = 0x800000000000L;
075: public final static long Bit49L = 0x1000000000000L;
076: public final static long Bit50L = 0x2000000000000L;
077: public final static long Bit51L = 0x4000000000000L;
078: public final static long Bit52L = 0x8000000000000L;
079: public final static long Bit53L = 0x10000000000000L;
080: public final static long Bit54L = 0x20000000000000L;
081: public final static long Bit55L = 0x40000000000000L;
082: public final static long Bit56L = 0x80000000000000L;
083: public final static long Bit57L = 0x100000000000000L;
084: public final static long Bit58L = 0x200000000000000L;
085: public final static long Bit59L = 0x400000000000000L;
086: public final static long Bit60L = 0x800000000000000L;
087: public final static long Bit61L = 0x1000000000000000L;
088: public final static long Bit62L = 0x2000000000000000L;
089: public final static long Bit63L = 0x4000000000000000L;
090: public final static long Bit64L = 0x8000000000000000L;
091:
092: public int bits = IsReachable; // reachable by default
093:
094: // for operators
095: public static final int ReturnTypeIDMASK = Bit1 | Bit2 | Bit3
096: | Bit4;
097: public static final int OperatorSHIFT = 6; // Bit7 -> Bit12
098: public static final int OperatorMASK = Bit7 | Bit8 | Bit9 | Bit10
099: | Bit11 | Bit12; // 6 bits for operator ID
100:
101: // for binary expressions
102: public static final int IsReturnedValue = Bit5;
103:
104: // for cast expressions
105: public static final int UnnecessaryCast = Bit15;
106: public static final int DisableUnnecessaryCastCheck = Bit6;
107: public static final int GenerateCheckcast = Bit7;
108: public static final int UnsafeCast = Bit8;
109:
110: // for name references
111: public static final int RestrictiveFlagMASK = Bit1 | Bit2 | Bit3;
112:
113: // for name refs or local decls
114: public static final int FirstAssignmentToLocal = Bit4;
115:
116: // for this reference
117: public static final int IsImplicitThis = Bit3;
118:
119: // for single name references
120: public static final int DepthSHIFT = 5; // Bit6 -> Bit13
121: public static final int DepthMASK = Bit6 | Bit7 | Bit8 | Bit9
122: | Bit10 | Bit11 | Bit12 | Bit13; // 8 bits for actual depth value (max. 255)
123:
124: // for statements
125: public static final int IsReachable = Bit32;
126: public static final int LabelUsed = Bit7;
127: public static final int DocumentedFallthrough = Bit30;
128:
129: // local decls
130: public static final int IsLocalDeclarationReachable = Bit31;
131:
132: // try statements
133: public static final int IsSubRoutineEscaping = Bit15;
134: public static final int IsTryBlockExiting = Bit30;
135:
136: // for type declaration
137: public static final int ContainsAssertion = Bit1;
138: public static final int IsLocalType = Bit9;
139: public static final int IsAnonymousType = Bit10; // used to test for anonymous
140: public static final int IsMemberType = Bit11; // local member do not know it is local at parse time (need to look at binding)
141: public static final int HasAbstractMethods = Bit12; // used to promote abstract enums
142: public static final int IsSecondaryType = Bit13; // used to test for secondary
143: public static final int HasBeenGenerated = Bit14;
144:
145: // for type, method and field declarations
146: public static final int HasLocalType = Bit2; // cannot conflict with AddAssertionMASK
147: public static final int HasBeenResolved = Bit5; // field decl only (to handle forward references)
148:
149: // for expression
150: public static final int ParenthesizedSHIFT = 21; // Bit22 -> Bit29
151: public static final int ParenthesizedMASK = Bit22 | Bit23 | Bit24
152: | Bit25 | Bit26 | Bit27 | Bit28 | Bit29; // 8 bits for parenthesis count value (max. 255)
153: public static final int IgnoreNoEffectAssignCheck = Bit30;
154:
155: // for references on lhs of assignment
156: public static final int IsStrictlyAssigned = Bit14; // set only for true assignments, as opposed to compound ones
157: public static final int IsCompoundAssigned = Bit17; // set only for compound assignments, as opposed to other ones
158:
159: // for explicit constructor call
160: public static final int DiscardEnclosingInstance = Bit14; // used for codegen
161:
162: // for empty statement
163: public static final int IsUsefulEmptyStatement = Bit1;
164:
165: // for block and method declaration
166: public static final int UndocumentedEmptyBlock = Bit4;
167: public static final int OverridingMethodWithSupercall = Bit5;
168:
169: // for initializer and method declaration
170: public static final int ErrorInSignature = Bit6;
171:
172: // for abstract method declaration
173: public static final int NeedFreeReturn = Bit7; // abstract method declaration
174:
175: // for constructor declaration
176: public static final int IsDefaultConstructor = Bit8;
177:
178: // for compilation unit
179: public static final int HasAllMethodBodies = Bit5;
180: public static final int IsImplicitUnit = Bit1;
181:
182: // for references in Javadoc comments
183: public static final int InsideJavadoc = Bit16;
184:
185: // for javadoc allocation expression/javadoc message send/javadoc return statement
186: public static final int SuperAccess = Bit15;
187:
188: // for javadoc return statement
189: public static final int Empty = Bit19;
190:
191: // for if statement
192: public static final int IsElseIfStatement = Bit30;
193: public static final int ThenExit = Bit31;
194:
195: // for type reference
196: public static final int IsSuperType = Bit5;
197: public static final int IsVarArgs = Bit15;
198: public static final int IgnoreRawTypeCheck = Bit31;
199:
200: // for array initializer
201: public static final int IsAnnotationDefaultValue = Bit1;
202:
203: // for null reference analysis
204: public static final int IsNonNull = Bit18;
205:
206: // for for statement
207: public static final int NeededScope = Bit30;
208:
209: // for import reference
210: public static final int OnDemand = Bit18;
211: public static final int Used = Bit2;
212:
213: // for parameterized qualified/single type ref
214: public static final int DidResolve = Bit19;
215:
216: // for return statement
217: public static final int IsAnySubRoutineEscaping = Bit30;
218: public static final int IsSynchronized = Bit31;
219:
220: // for synchronized statement
221: public static final int BlockExit = Bit30;
222:
223: // constants used when checking invocation arguments
224: public static final int INVOCATION_ARGUMENT_OK = 0;
225: public static final int INVOCATION_ARGUMENT_UNCHECKED = 1;
226: public static final int INVOCATION_ARGUMENT_WILDCARD = 2;
227:
228: public ASTNode() {
229:
230: super ();
231: }
232:
233: private static int checkInvocationArgument(BlockScope scope,
234: Expression argument, TypeBinding parameterType,
235: TypeBinding argumentType, TypeBinding originalParameterType) {
236: argument.computeConversion(scope, parameterType, argumentType);
237:
238: if (argumentType != TypeBinding.NULL
239: && parameterType.isWildcard()) {
240: WildcardBinding wildcard = (WildcardBinding) parameterType;
241: if (wildcard.boundKind != Wildcard.SUPER
242: && wildcard.otherBounds == null) // lub wildcards are tolerated
243: return INVOCATION_ARGUMENT_WILDCARD;
244: }
245: TypeBinding checkedParameterType = originalParameterType == null ? parameterType
246: : originalParameterType;
247: if (argumentType != checkedParameterType
248: && argumentType
249: .needsUncheckedConversion(checkedParameterType)) {
250: scope.problemReporter().unsafeTypeConversion(argument,
251: argumentType, checkedParameterType);
252: return INVOCATION_ARGUMENT_UNCHECKED;
253: }
254: return INVOCATION_ARGUMENT_OK;
255: }
256:
257: public static void checkInvocationArguments(BlockScope scope,
258: Expression receiver, TypeBinding receiverType,
259: MethodBinding method, Expression[] arguments,
260: TypeBinding[] argumentTypes, boolean argsContainCast,
261: InvocationSite invocationSite) {
262: TypeBinding[] params = method.parameters;
263: int paramLength = params.length;
264: boolean isRawMemberInvocation = !method.isStatic()
265: && !receiverType.isUnboundWildcard()
266: && method.declaringClass.isRawType()
267: && method.hasSubstitutedParameters();
268:
269: MethodBinding rawOriginalGenericMethod = null;
270: if (!isRawMemberInvocation) {
271: if (method instanceof ParameterizedGenericMethodBinding) {
272: ParameterizedGenericMethodBinding paramMethod = (ParameterizedGenericMethodBinding) method;
273: if (paramMethod.isUnchecked
274: || (paramMethod.isRaw && method
275: .hasSubstitutedParameters())) {
276: rawOriginalGenericMethod = method.original();
277: }
278: }
279: }
280: int invocationStatus = INVOCATION_ARGUMENT_OK;
281: if (arguments == null) {
282: if (method.isVarargs()) {
283: TypeBinding parameterType = ((ArrayBinding) params[paramLength - 1])
284: .elementsType(); // no element was supplied for vararg parameter
285: if (!parameterType.isReifiable()) {
286: scope.problemReporter()
287: .unsafeGenericArrayForVarargs(
288: parameterType,
289: (ASTNode) invocationSite);
290: }
291: }
292: } else {
293: if (method.isVarargs()) {
294: // 4 possibilities exist for a call to the vararg method foo(int i, long ... value) : foo(1), foo(1, 2), foo(1, 2, 3, 4) & foo(1, new long[] {1, 2})
295: int lastIndex = paramLength - 1;
296: for (int i = 0; i < lastIndex; i++) {
297: TypeBinding originalRawParam = rawOriginalGenericMethod == null ? null
298: : rawOriginalGenericMethod.parameters[i];
299: invocationStatus |= checkInvocationArgument(scope,
300: arguments[i], params[i], argumentTypes[i],
301: originalRawParam);
302: }
303: int argLength = arguments.length;
304: if (lastIndex < argLength) { // vararg argument was provided
305: TypeBinding parameterType = params[lastIndex];
306: TypeBinding originalRawParam = null;
307:
308: if (paramLength != argLength
309: || parameterType.dimensions() != argumentTypes[lastIndex]
310: .dimensions()) {
311: parameterType = ((ArrayBinding) parameterType)
312: .elementsType(); // single element was provided for vararg parameter
313: if (!parameterType.isReifiable()) {
314: scope.problemReporter()
315: .unsafeGenericArrayForVarargs(
316: parameterType,
317: (ASTNode) invocationSite);
318: }
319: originalRawParam = rawOriginalGenericMethod == null ? null
320: : ((ArrayBinding) rawOriginalGenericMethod.parameters[lastIndex])
321: .elementsType();
322: }
323: for (int i = lastIndex; i < argLength; i++) {
324: invocationStatus |= checkInvocationArgument(
325: scope, arguments[i], parameterType,
326: argumentTypes[i], originalRawParam);
327: }
328: }
329:
330: if (paramLength == argumentTypes.length) { // 70056
331: int varargsIndex = paramLength - 1;
332: ArrayBinding varargsType = (ArrayBinding) params[varargsIndex];
333: TypeBinding lastArgType = argumentTypes[varargsIndex];
334: int dimensions;
335: if (lastArgType == TypeBinding.NULL) {
336: if (!(varargsType.leafComponentType()
337: .isBaseType() && varargsType
338: .dimensions() == 1))
339: scope
340: .problemReporter()
341: .varargsArgumentNeedCast(method,
342: lastArgType, invocationSite);
343: } else if (varargsType.dimensions <= (dimensions = lastArgType
344: .dimensions())) {
345: if (lastArgType.leafComponentType()
346: .isBaseType()) {
347: dimensions--;
348: }
349: if (varargsType.dimensions < dimensions) {
350: scope
351: .problemReporter()
352: .varargsArgumentNeedCast(method,
353: lastArgType, invocationSite);
354: } else if (varargsType.dimensions == dimensions
355: && lastArgType != varargsType
356: && lastArgType.leafComponentType()
357: .erasure() != varargsType.leafComponentType
358: .erasure()
359: && lastArgType
360: .isCompatibleWith(varargsType
361: .elementsType())
362: && lastArgType
363: .isCompatibleWith(varargsType)) {
364: scope
365: .problemReporter()
366: .varargsArgumentNeedCast(method,
367: lastArgType, invocationSite);
368: }
369: }
370: }
371: } else {
372: for (int i = 0; i < paramLength; i++) {
373: TypeBinding originalRawParam = rawOriginalGenericMethod == null ? null
374: : rawOriginalGenericMethod.parameters[i];
375: invocationStatus |= checkInvocationArgument(scope,
376: arguments[i], params[i], argumentTypes[i],
377: originalRawParam);
378: }
379: }
380: if (argsContainCast) {
381: CastExpression.checkNeedForArgumentCasts(scope,
382: receiver, receiverType, method, arguments,
383: argumentTypes, invocationSite);
384: }
385: }
386: if ((invocationStatus & INVOCATION_ARGUMENT_WILDCARD) != 0) {
387: scope.problemReporter().wildcardInvocation(
388: (ASTNode) invocationSite, receiverType, method,
389: argumentTypes);
390: } else if (!method.isStatic()
391: && !receiverType.isUnboundWildcard()
392: && method.declaringClass.isRawType()
393: && method.hasSubstitutedParameters()) {
394: scope.problemReporter().unsafeRawInvocation(
395: (ASTNode) invocationSite, method);
396: } else if (rawOriginalGenericMethod != null) {
397: scope.problemReporter().unsafeRawGenericMethodInvocation(
398: (ASTNode) invocationSite, method);
399: }
400: }
401:
402: public ASTNode concreteStatement() {
403: return this ;
404: }
405:
406: public final boolean isFieldUseDeprecated(FieldBinding field,
407: Scope scope, boolean isStrictlyAssigned) {
408:
409: if (!isStrictlyAssigned
410: && (field.isPrivate() || (field.declaringClass != null && field.declaringClass
411: .isLocalType()))
412: && !scope.isDefinedInField(field)) {
413: // ignore cases where field is used from within inside itself
414: field.original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
415: }
416:
417: if ((field.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0) {
418: AccessRestriction restriction = scope.environment()
419: .getAccessRestriction(
420: field.declaringClass.erasure());
421: if (restriction != null) {
422: scope.problemReporter().forbiddenReference(field, this ,
423: restriction.getFieldAccessMessageTemplate(),
424: restriction.getProblemId());
425: }
426: }
427:
428: if (!field.isViewedAsDeprecated())
429: return false;
430:
431: // inside same unit - no report
432: if (scope.isDefinedInSameUnit(field.declaringClass))
433: return false;
434:
435: // if context is deprecated, may avoid reporting
436: if (!scope.compilerOptions().reportDeprecationInsideDeprecatedCode
437: && scope.isInsideDeprecatedCode())
438: return false;
439: return true;
440: }
441:
442: public boolean isImplicitThis() {
443:
444: return false;
445: }
446:
447: /* Answer true if the method use is considered deprecated.
448: * An access in the same compilation unit is allowed.
449: */
450: public final boolean isMethodUseDeprecated(MethodBinding method,
451: Scope scope, boolean isExplicitUse) {
452: if ((method.isPrivate() || method.declaringClass.isLocalType())
453: && !scope.isDefinedInMethod(method)) {
454: // ignore cases where method is used from within inside itself (e.g. direct recursions)
455: method.original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
456: }
457:
458: // TODO (maxime) consider separating concerns between deprecation and access restriction.
459: // Caveat: this was not the case when access restriction funtion was added.
460: if (isExplicitUse
461: && (method.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0) {
462: // note: explicit constructors calls warnings are kept despite the 'new C1()' case (two
463: // warnings, one on type, the other on constructor), because of the 'super()' case.
464: AccessRestriction restriction = scope.environment()
465: .getAccessRestriction(
466: method.declaringClass.erasure());
467: if (restriction != null) {
468: if (method.isConstructor()) {
469: scope
470: .problemReporter()
471: .forbiddenReference(
472: method,
473: this ,
474: restriction
475: .getConstructorAccessMessageTemplate(),
476: restriction.getProblemId());
477: } else {
478: scope.problemReporter().forbiddenReference(
479: method,
480: this ,
481: restriction
482: .getMethodAccessMessageTemplate(),
483: restriction.getProblemId());
484: }
485: }
486: }
487:
488: if (!method.isViewedAsDeprecated())
489: return false;
490:
491: // inside same unit - no report
492: if (scope.isDefinedInSameUnit(method.declaringClass))
493: return false;
494:
495: // non explicit use and non explicitly deprecated - no report
496: if (!isExplicitUse
497: && (method.modifiers & ClassFileConstants.AccDeprecated) == 0) {
498: return false;
499: }
500:
501: // if context is deprecated, may avoid reporting
502: if (!scope.compilerOptions().reportDeprecationInsideDeprecatedCode
503: && scope.isInsideDeprecatedCode())
504: return false;
505: return true;
506: }
507:
508: public boolean isSuper() {
509:
510: return false;
511: }
512:
513: public boolean isThis() {
514:
515: return false;
516: }
517:
518: /* Answer true if the type use is considered deprecated.
519: * An access in the same compilation unit is allowed.
520: */
521: public final boolean isTypeUseDeprecated(TypeBinding type,
522: Scope scope) {
523:
524: if (type.isArrayType())
525: type = ((ArrayBinding) type).leafComponentType;
526: if (type.isBaseType())
527: return false;
528:
529: ReferenceBinding refType = (ReferenceBinding) type;
530:
531: if ((refType.isPrivate() || refType.isLocalType())
532: && !scope.isDefinedInType(refType)) {
533: // ignore cases where type is used from within inside itself
534: ((ReferenceBinding) refType.erasure()).modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
535: }
536:
537: if (refType.hasRestrictedAccess()) {
538: AccessRestriction restriction = scope.environment()
539: .getAccessRestriction(type.erasure());
540: if (restriction != null) {
541: scope.problemReporter().forbiddenReference(type, this ,
542: restriction.getMessageTemplate(),
543: restriction.getProblemId());
544: }
545: }
546:
547: // force annotations resolution before deciding whether the type may be deprecated
548: refType.initializeDeprecatedAnnotationTagBits();
549:
550: if (!refType.isViewedAsDeprecated())
551: return false;
552:
553: // inside same unit - no report
554: if (scope.isDefinedInSameUnit(refType))
555: return false;
556:
557: // if context is deprecated, may avoid reporting
558: if (!scope.compilerOptions().reportDeprecationInsideDeprecatedCode
559: && scope.isInsideDeprecatedCode())
560: return false;
561: return true;
562: }
563:
564: public abstract StringBuffer print(int indent, StringBuffer output);
565:
566: public static StringBuffer printAnnotations(
567: Annotation[] annotations, StringBuffer output) {
568: int length = annotations.length;
569: for (int i = 0; i < length; i++) {
570: annotations[i].print(0, output);
571: output.append(" "); //$NON-NLS-1$
572: }
573: return output;
574: }
575:
576: public static StringBuffer printIndent(int indent,
577: StringBuffer output) {
578:
579: for (int i = indent; i > 0; i--)
580: output.append(" "); //$NON-NLS-1$
581: return output;
582: }
583:
584: public static StringBuffer printModifiers(int modifiers,
585: StringBuffer output) {
586:
587: if ((modifiers & ClassFileConstants.AccPublic) != 0)
588: output.append("public "); //$NON-NLS-1$
589: if ((modifiers & ClassFileConstants.AccPrivate) != 0)
590: output.append("private "); //$NON-NLS-1$
591: if ((modifiers & ClassFileConstants.AccProtected) != 0)
592: output.append("protected "); //$NON-NLS-1$
593: if ((modifiers & ClassFileConstants.AccStatic) != 0)
594: output.append("static "); //$NON-NLS-1$
595: if ((modifiers & ClassFileConstants.AccFinal) != 0)
596: output.append("final "); //$NON-NLS-1$
597: if ((modifiers & ClassFileConstants.AccSynchronized) != 0)
598: output.append("synchronized "); //$NON-NLS-1$
599: if ((modifiers & ClassFileConstants.AccVolatile) != 0)
600: output.append("volatile "); //$NON-NLS-1$
601: if ((modifiers & ClassFileConstants.AccTransient) != 0)
602: output.append("transient "); //$NON-NLS-1$
603: if ((modifiers & ClassFileConstants.AccNative) != 0)
604: output.append("native "); //$NON-NLS-1$
605: if ((modifiers & ClassFileConstants.AccAbstract) != 0)
606: output.append("abstract "); //$NON-NLS-1$
607: return output;
608: }
609:
610: /**
611: * Resolve annotations, and check duplicates, answers combined tagBits
612: * for recognized standard annotations
613: */
614: public static void resolveAnnotations(BlockScope scope,
615: Annotation[] annotations, Binding recipient) {
616: AnnotationBinding[] instances = null;
617: int length = annotations == null ? 0 : annotations.length;
618: if (recipient != null) {
619: switch (recipient.kind()) {
620: case Binding.PACKAGE:
621: PackageBinding packageBinding = (PackageBinding) recipient;
622: if ((packageBinding.tagBits & TagBits.AnnotationResolved) != 0)
623: return;
624: packageBinding.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
625: break;
626: case Binding.TYPE:
627: case Binding.GENERIC_TYPE:
628: ReferenceBinding type = (ReferenceBinding) recipient;
629: if ((type.tagBits & TagBits.AnnotationResolved) != 0)
630: return;
631: type.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
632: if (length > 0) {
633: instances = new AnnotationBinding[length];
634: type.setAnnotations(instances);
635: }
636: break;
637: case Binding.METHOD:
638: MethodBinding method = (MethodBinding) recipient;
639: if ((method.tagBits & TagBits.AnnotationResolved) != 0)
640: return;
641: method.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
642: if (length > 0) {
643: instances = new AnnotationBinding[length];
644: method.setAnnotations(instances);
645: }
646: break;
647: case Binding.FIELD:
648: FieldBinding field = (FieldBinding) recipient;
649: if ((field.tagBits & TagBits.AnnotationResolved) != 0)
650: return;
651: field.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
652: if (length > 0) {
653: instances = new AnnotationBinding[length];
654: field.setAnnotations(instances);
655: }
656: break;
657: case Binding.LOCAL:
658: LocalVariableBinding local = (LocalVariableBinding) recipient;
659: if ((local.tagBits & TagBits.AnnotationResolved) != 0)
660: return;
661: local.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
662: if (length > 0) {
663: instances = new AnnotationBinding[length];
664: local.setAnnotations(instances);
665: }
666: break;
667: default:
668: return;
669: }
670: }
671: if (annotations == null)
672: return;
673: TypeBinding[] annotationTypes = new TypeBinding[length];
674: for (int i = 0; i < length; i++) {
675: Annotation annotation = annotations[i];
676: final Binding annotationRecipient = annotation.recipient;
677: if (annotationRecipient != null && recipient != null) {
678: // only local and field can share annnotations
679: switch (recipient.kind()) {
680: case Binding.FIELD:
681: FieldBinding field = (FieldBinding) recipient;
682: field.tagBits = ((FieldBinding) annotationRecipient).tagBits;
683: break;
684: case Binding.LOCAL:
685: LocalVariableBinding local = (LocalVariableBinding) recipient;
686: local.tagBits = ((LocalVariableBinding) annotationRecipient).tagBits;
687: break;
688: }
689: if (instances != null) {
690: // need to fill the instances array
691: instances[0] = annotation.getCompilerAnnotation();
692: for (int j = 1; j < length; j++) {
693: Annotation annot = annotations[j];
694: instances[j] = annot.getCompilerAnnotation();
695: }
696: }
697: return;
698: } else {
699: annotation.recipient = recipient;
700: annotationTypes[i] = annotation.resolveType(scope);
701: // null if receiver is a package binding
702: if (instances != null) {
703: instances[i] = annotation.getCompilerAnnotation();
704: }
705: }
706: }
707: // check duplicate annotations
708: for (int i = 0; i < length; i++) {
709: TypeBinding annotationType = annotationTypes[i];
710: if (annotationType == null)
711: continue;
712: boolean foundDuplicate = false;
713: for (int j = i + 1; j < length; j++) {
714: if (annotationTypes[j] == annotationType) {
715: foundDuplicate = true;
716: annotationTypes[j] = null; // report it only once
717: scope.problemReporter().duplicateAnnotation(
718: annotations[j]);
719: }
720: }
721: if (foundDuplicate) {
722: scope.problemReporter().duplicateAnnotation(
723: annotations[i]);
724: }
725: }
726: }
727:
728: /**
729: * Figures if @Deprecated annotation is specified, do not resolve entire annotations.
730: */
731: public static void resolveDeprecatedAnnotations(BlockScope scope,
732: Annotation[] annotations, Binding recipient) {
733: if (recipient != null) {
734: int kind = recipient.kind();
735: if (annotations != null) {
736: int length;
737: if ((length = annotations.length) >= 0) {
738: switch (kind) {
739: case Binding.PACKAGE:
740: PackageBinding packageBinding = (PackageBinding) recipient;
741: if ((packageBinding.tagBits & TagBits.DeprecatedAnnotationResolved) != 0)
742: return;
743: break;
744: case Binding.TYPE:
745: case Binding.GENERIC_TYPE:
746: ReferenceBinding type = (ReferenceBinding) recipient;
747: if ((type.tagBits & TagBits.DeprecatedAnnotationResolved) != 0)
748: return;
749: break;
750: case Binding.METHOD:
751: MethodBinding method = (MethodBinding) recipient;
752: if ((method.tagBits & TagBits.DeprecatedAnnotationResolved) != 0)
753: return;
754: break;
755: case Binding.FIELD:
756: FieldBinding field = (FieldBinding) recipient;
757: if ((field.tagBits & TagBits.DeprecatedAnnotationResolved) != 0)
758: return;
759: break;
760: case Binding.LOCAL:
761: LocalVariableBinding local = (LocalVariableBinding) recipient;
762: if ((local.tagBits & TagBits.DeprecatedAnnotationResolved) != 0)
763: return;
764: break;
765: default:
766: return;
767: }
768: for (int i = 0; i < length; i++) {
769: TypeReference annotationTypeRef = annotations[i].type;
770: // only resolve type name if 'Deprecated' last token
771: if (!CharOperation.equals(
772: TypeConstants.JAVA_LANG_DEPRECATED[2],
773: annotationTypeRef.getLastToken()))
774: return;
775: TypeBinding annotationType = annotations[i].type
776: .resolveType(scope);
777: if (annotationType != null
778: && annotationType.isValidBinding()
779: && annotationType.id == TypeIds.T_JavaLangDeprecated) {
780: switch (kind) {
781: case Binding.PACKAGE:
782: PackageBinding packageBinding = (PackageBinding) recipient;
783: packageBinding.tagBits |= (TagBits.AnnotationDeprecated | TagBits.DeprecatedAnnotationResolved);
784: return;
785: case Binding.TYPE:
786: case Binding.GENERIC_TYPE:
787: case Binding.TYPE_PARAMETER:
788: ReferenceBinding type = (ReferenceBinding) recipient;
789: type.tagBits |= (TagBits.AnnotationDeprecated | TagBits.DeprecatedAnnotationResolved);
790: return;
791: case Binding.METHOD:
792: MethodBinding method = (MethodBinding) recipient;
793: method.tagBits |= (TagBits.AnnotationDeprecated | TagBits.DeprecatedAnnotationResolved);
794: return;
795: case Binding.FIELD:
796: FieldBinding field = (FieldBinding) recipient;
797: field.tagBits |= (TagBits.AnnotationDeprecated | TagBits.DeprecatedAnnotationResolved);
798: return;
799: case Binding.LOCAL:
800: LocalVariableBinding local = (LocalVariableBinding) recipient;
801: local.tagBits |= (TagBits.AnnotationDeprecated | TagBits.DeprecatedAnnotationResolved);
802: return;
803: default:
804: return;
805: }
806: }
807: }
808: }
809: }
810: switch (kind) {
811: case Binding.PACKAGE:
812: PackageBinding packageBinding = (PackageBinding) recipient;
813: packageBinding.tagBits |= TagBits.DeprecatedAnnotationResolved;
814: return;
815: case Binding.TYPE:
816: case Binding.GENERIC_TYPE:
817: case Binding.TYPE_PARAMETER:
818: ReferenceBinding type = (ReferenceBinding) recipient;
819: type.tagBits |= TagBits.DeprecatedAnnotationResolved;
820: return;
821: case Binding.METHOD:
822: MethodBinding method = (MethodBinding) recipient;
823: method.tagBits |= TagBits.DeprecatedAnnotationResolved;
824: return;
825: case Binding.FIELD:
826: FieldBinding field = (FieldBinding) recipient;
827: field.tagBits |= TagBits.DeprecatedAnnotationResolved;
828: return;
829: case Binding.LOCAL:
830: LocalVariableBinding local = (LocalVariableBinding) recipient;
831: local.tagBits |= TagBits.DeprecatedAnnotationResolved;
832: return;
833: default:
834: return;
835: }
836: }
837: }
838:
839: public int sourceStart() {
840: return this .sourceStart;
841: }
842:
843: public int sourceEnd() {
844: return this .sourceEnd;
845: }
846:
847: public String toString() {
848:
849: return print(0, new StringBuffer(30)).toString();
850: }
851:
852: public void traverse(ASTVisitor visitor, BlockScope scope) {
853: // do nothing by default
854: }
855: }
|