KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > ast > ASTNode


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Matt McCutchen
11  * Partial fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=122995.
12  *******************************************************************************/

13 package org.eclipse.jdt.internal.compiler.ast;
14
15 import org.eclipse.jdt.core.compiler.CharOperation;
16 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
17 import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
18 import org.eclipse.jdt.internal.compiler.lookup.*;
19 import org.eclipse.jdt.internal.compiler.ASTVisitor;
20
21 public abstract class ASTNode implements TypeConstants, TypeIds {
22
23     public int sourceStart, sourceEnd;
24
25     // storage for internal flags (32 bits) BIT USAGE
26
public final static int Bit1 = 0x1; // return type (operator) | name reference kind (name ref) | add assertion (type decl) | useful empty statement (empty statement)
27
public final static int Bit2 = 0x2; // return type (operator) | name reference kind (name ref) | has local type (type, method, field decl)
28
public final static int Bit3 = 0x4; // return type (operator) | name reference kind (name ref) | implicit this (this ref)
29
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)
30
public final static int Bit5 = 0x10; // value for return (expression) | has all method bodies (unit) | supertype ref (type ref) | resolved (field decl)
31
public final static int Bit6 = 0x20; // depth (name ref, msg) | ignore need cast check (cast expression) | error in signature (method declaration/ initializer)
32
public final static int Bit7 = 0x40; // depth (name ref, msg) | operator (operator) | need runtime checkcast (cast expression) | label used (labelStatement) | needFreeReturn (AbstractMethodDeclaration)
33
public final static int Bit8 = 0x80; // depth (name ref, msg) | operator (operator) | unsafe cast (cast expression) | is default constructor (constructor declaration)
34
public final static int Bit9 = 0x100; // depth (name ref, msg) | operator (operator) | is local type (type decl)
35
public final static int Bit10= 0x200; // depth (name ref, msg) | operator (operator) | is anonymous type (type decl)
36
public final static int Bit11 = 0x400; // depth (name ref, msg) | operator (operator) | is member type (type decl)
37
public final static int Bit12 = 0x800; // depth (name ref, msg) | operator (operator) | has abstract methods (type decl)
38
public final static int Bit13 = 0x1000; // depth (name ref, msg) | is secondary type (type decl)
39
public final static int Bit14 = 0x2000; // strictly assigned (reference lhs) | discard enclosing instance (explicit constr call) | hasBeenGenerated (type decl)
40
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)
41
public final static int Bit16 = 0x8000; // in javadoc comment (name ref, type ref, msg)
42
public final static int Bit17 = 0x10000; // compound assigned (reference lhs)
43
public final static int Bit18 = 0x20000; // non null (expression) | onDemand (import reference)
44
public final static int Bit19 = 0x40000; // didResolve (parameterized qualified type ref/parameterized single type ref) | empty (javadoc return statement)
45
public final static int Bit20 = 0x80000;
46     public final static int Bit21 = 0x100000;
47     public final static int Bit22 = 0x200000; // parenthesis count (expression) | used (import reference)
48
public final static int Bit23 = 0x400000; // parenthesis count (expression)
49
public final static int Bit24 = 0x800000; // parenthesis count (expression)
50
public final static int Bit25 = 0x1000000; // parenthesis count (expression)
51
public final static int Bit26 = 0x2000000; // parenthesis count (expression)
52
public final static int Bit27 = 0x4000000; // parenthesis count (expression)
53
public final static int Bit28 = 0x8000000; // parenthesis count (expression)
54
public final static int Bit29 = 0x10000000; // parenthesis count (expression)
55
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)
56
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)
57
public final static int Bit32 = 0x80000000; // reachable (statement)
58

59     public final static long Bit32L = 0x80000000L;
60     public final static long Bit33L = 0x100000000L;
61     public final static long Bit34L = 0x200000000L;
62     public final static long Bit35L = 0x400000000L;
63     public final static long Bit36L = 0x800000000L;
64     public final static long Bit37L = 0x1000000000L;
65     public final static long Bit38L = 0x2000000000L;
66     public final static long Bit39L = 0x4000000000L;
67     public final static long Bit40L = 0x8000000000L;
68     public final static long Bit41L = 0x10000000000L;
69     public final static long Bit42L = 0x20000000000L;
70     public final static long Bit43L = 0x40000000000L;
71     public final static long Bit44L = 0x80000000000L;
72     public final static long Bit45L = 0x100000000000L;
73     public final static long Bit46L = 0x200000000000L;
74     public final static long Bit47L = 0x400000000000L;
75     public final static long Bit48L = 0x800000000000L;
76     public final static long Bit49L = 0x1000000000000L;
77     public final static long Bit50L = 0x2000000000000L;
78     public final static long Bit51L = 0x4000000000000L;
79     public final static long Bit52L = 0x8000000000000L;
80     public final static long Bit53L = 0x10000000000000L;
81     public final static long Bit54L = 0x20000000000000L;
82     public final static long Bit55L = 0x40000000000000L;
83     public final static long Bit56L = 0x80000000000000L;
84     public final static long Bit57L = 0x100000000000000L;
85     public final static long Bit58L = 0x200000000000000L;
86     public final static long Bit59L = 0x400000000000000L;
87     public final static long Bit60L = 0x800000000000000L;
88     public final static long Bit61L = 0x1000000000000000L;
89     public final static long Bit62L = 0x2000000000000000L;
90     public final static long Bit63L = 0x4000000000000000L;
91     public final static long Bit64L = 0x8000000000000000L;
92
93     public int bits = IsReachable; // reachable by default
94

95     // for operators
96
public static final int ReturnTypeIDMASK = Bit1|Bit2|Bit3|Bit4;
97     public static final int OperatorSHIFT = 6; // Bit7 -> Bit12
98
public static final int OperatorMASK = Bit7|Bit8|Bit9|Bit10|Bit11|Bit12; // 6 bits for operator ID
99

100     // for binary expressions
101
public static final int IsReturnedValue = Bit5;
102
103     // for cast expressions
104
public static final int UnnecessaryCast = Bit15;
105     public static final int DisableUnnecessaryCastCheck = Bit6;
106     public static final int GenerateCheckcast = Bit7;
107     public static final int UnsafeCast = Bit8;
108
109     // for name references
110
public static final int RestrictiveFlagMASK = Bit1|Bit2|Bit3;
111
112     // for name refs or local decls
113
public static final int FirstAssignmentToLocal = Bit4;
114
115     // for this reference
116
public static final int IsImplicitThis = Bit3;
117
118     // for single name references
119
public static final int DepthSHIFT = 5; // Bit6 -> Bit13
120
public static final int DepthMASK = Bit6|Bit7|Bit8|Bit9|Bit10|Bit11|Bit12|Bit13; // 8 bits for actual depth value (max. 255)
121

122     // for statements
123
public static final int IsReachable = Bit32;
124     public static final int LabelUsed = Bit7;
125     public static final int DocumentedFallthrough = Bit30;
126
127     // local decls
128
public static final int IsLocalDeclarationReachable = Bit31;
129
130     // try statements
131
public static final int IsSubRoutineEscaping = Bit15;
132     public static final int IsTryBlockExiting = Bit30;
133
134     // for type declaration
135
public static final int ContainsAssertion = Bit1;
136     public static final int IsLocalType = Bit9;
137     public static final int IsAnonymousType = Bit10; // used to test for anonymous
138
public static final int IsMemberType = Bit11; // local member do not know it is local at parse time (need to look at binding)
139
public static final int HasAbstractMethods = Bit12; // used to promote abstract enums
140
public static final int IsSecondaryType = Bit13; // used to test for secondary
141
public static final int HasBeenGenerated = Bit14;
142
143     // for type, method and field declarations
144
public static final int HasLocalType = Bit2; // cannot conflict with AddAssertionMASK
145
public static final int HasBeenResolved = Bit5; // field decl only (to handle forward references)
146

147     // for expression
148
public static final int ParenthesizedSHIFT = 21; // Bit22 -> Bit29
149
public static final int ParenthesizedMASK = Bit22|Bit23|Bit24|Bit25|Bit26|Bit27|Bit28|Bit29; // 8 bits for parenthesis count value (max. 255)
150
public static final int IgnoreNoEffectAssignCheck = Bit30;
151
152     // for references on lhs of assignment
153
public static final int IsStrictlyAssigned = Bit14; // set only for true assignments, as opposed to compound ones
154
public static final int IsCompoundAssigned = Bit17; // set only for compound assignments, as opposed to other ones
155

156     // for explicit constructor call
157
public static final int DiscardEnclosingInstance = Bit14; // used for codegen
158

159     // for empty statement
160
public static final int IsUsefulEmptyStatement = Bit1;
161
162     // for block and method declaration
163
public static final int UndocumentedEmptyBlock = Bit4;
164     public static final int OverridingMethodWithSupercall = Bit5;
165
166     // for initializer and method declaration
167
public static final int ErrorInSignature = Bit6;
168     
169     // for abstract method declaration
170
public static final int NeedFreeReturn = Bit7; // abstract method declaration
171

172     // for constructor declaration
173
public static final int IsDefaultConstructor = Bit8;
174
175     // for compilation unit
176
public static final int HasAllMethodBodies = Bit5;
177     public static final int IsImplicitUnit = Bit1;
178
179     // for references in Javadoc comments
180
public static final int InsideJavadoc = Bit16;
181
182     // for javadoc allocation expression/javadoc message send/javadoc return statement
183
public static final int SuperAccess = Bit15;
184
185     // for javadoc return statement
186
public static final int Empty = Bit19;
187
188     // for if statement
189
public static final int IsElseIfStatement = Bit30;
190     public static final int ThenExit = Bit31;
191
192     // for type reference
193
public static final int IsSuperType = Bit5;
194     public static final int IsVarArgs = Bit15;
195     public static final int IgnoreRawTypeCheck = Bit31;
196
197     // for array initializer
198
public static final int IsAnnotationDefaultValue = Bit1;
199
200     // for null reference analysis
201
public static final int IsNonNull = Bit18;
202
203     // for for statement
204
public static final int NeededScope = Bit30;
205
206     // for import reference
207
public static final int OnDemand = Bit18;
208     public static final int Used = Bit2;
209     
210     // for parameterized qualified/single type ref
211
public static final int DidResolve = Bit19;
212     
213     // for return statement
214
public static final int IsAnySubRoutineEscaping = Bit30;
215     public static final int IsSynchronized = Bit31;
216     
217     // for synchronized statement
218
public static final int BlockExit = Bit30;
219     
220     // constants used when checking invocation arguments
221
public static final int INVOCATION_ARGUMENT_OK = 0;
222     public static final int INVOCATION_ARGUMENT_UNCHECKED = 1;
223     public static final int INVOCATION_ARGUMENT_WILDCARD = 2;
224
225     public ASTNode() {
226
227         super();
228     }
229     private static int checkInvocationArgument(BlockScope scope, Expression argument, TypeBinding parameterType, TypeBinding argumentType, TypeBinding originalParameterType) {
230         argument.computeConversion(scope, parameterType, argumentType);
231
232         if (argumentType != TypeBinding.NULL && parameterType.isWildcard()) {
233             WildcardBinding wildcard = (WildcardBinding) parameterType;
234             if (wildcard.boundKind != Wildcard.SUPER && wildcard.otherBounds == null) // lub wildcards are tolerated
235
return INVOCATION_ARGUMENT_WILDCARD;
236         }
237         TypeBinding checkedParameterType = originalParameterType == null ? parameterType : originalParameterType;
238         if (argumentType != checkedParameterType && argumentType.needsUncheckedConversion(checkedParameterType)) {
239             scope.problemReporter().unsafeTypeConversion(argument, argumentType, checkedParameterType);
240             return INVOCATION_ARGUMENT_UNCHECKED;
241         }
242         return INVOCATION_ARGUMENT_OK;
243     }
244     public static void checkInvocationArguments(BlockScope scope, Expression receiver, TypeBinding receiverType, MethodBinding method, Expression[] arguments, TypeBinding[] argumentTypes, boolean argsContainCast, InvocationSite invocationSite) {
245         TypeBinding[] params = method.parameters;
246         int paramLength = params.length;
247         boolean isRawMemberInvocation = !method.isStatic()
248                 && !receiverType.isUnboundWildcard()
249                 && method.declaringClass.isRawType()
250                 && method.hasSubstitutedParameters();
251
252         MethodBinding rawOriginalGenericMethod = null;
253         if (!isRawMemberInvocation) {
254             if (method instanceof ParameterizedGenericMethodBinding) {
255                 ParameterizedGenericMethodBinding paramMethod = (ParameterizedGenericMethodBinding) method;
256                 if (paramMethod.isUnchecked || (paramMethod.isRaw && method.hasSubstitutedParameters())) {
257                     rawOriginalGenericMethod = method.original();
258                 }
259             }
260         }
261         int invocationStatus = INVOCATION_ARGUMENT_OK;
262         if (arguments == null) {
263             if (method.isVarargs()) {
264                 TypeBinding parameterType = ((ArrayBinding) params[paramLength-1]).elementsType(); // no element was supplied for vararg parameter
265
if (!parameterType.isReifiable()) {
266                     scope.problemReporter().unsafeGenericArrayForVarargs(parameterType, (ASTNode)invocationSite);
267                 }
268             }
269         } else {
270             if (method.isVarargs()) {
271                 // 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})
272
int lastIndex = paramLength - 1;
273                 for (int i = 0; i < lastIndex; i++) {
274                     TypeBinding originalRawParam = rawOriginalGenericMethod == null ? null : rawOriginalGenericMethod.parameters[i];
275                     invocationStatus |= checkInvocationArgument(scope, arguments[i], params[i] , argumentTypes[i], originalRawParam);
276                 }
277                int argLength = arguments.length;
278                if (lastIndex < argLength) { // vararg argument was provided
279
TypeBinding parameterType = params[lastIndex];
280                     TypeBinding originalRawParam = null;
281
282                     if (paramLength != argLength || parameterType.dimensions() != argumentTypes[lastIndex].dimensions()) {
283                         parameterType = ((ArrayBinding) parameterType).elementsType(); // single element was provided for vararg parameter
284
if (!parameterType.isReifiable()) {
285                             scope.problemReporter().unsafeGenericArrayForVarargs(parameterType, (ASTNode)invocationSite);
286                         }
287                         originalRawParam = rawOriginalGenericMethod == null ? null : ((ArrayBinding)rawOriginalGenericMethod.parameters[lastIndex]).elementsType();
288                     }
289                     for (int i = lastIndex; i < argLength; i++) {
290                         invocationStatus |= checkInvocationArgument(scope, arguments[i], parameterType, argumentTypes[i], originalRawParam);
291                     }
292                 }
293
294                if (paramLength == argumentTypes.length) { // 70056
295
int varargsIndex = paramLength - 1;
296                     ArrayBinding varargsType = (ArrayBinding) params[varargsIndex];
297                     TypeBinding lastArgType = argumentTypes[varargsIndex];
298                     int dimensions;
299                     if (lastArgType == TypeBinding.NULL) {
300                         if (!(varargsType.leafComponentType().isBaseType() && varargsType.dimensions() == 1))
301                             scope.problemReporter().varargsArgumentNeedCast(method, lastArgType, invocationSite);
302                     } else if (varargsType.dimensions <= (dimensions = lastArgType.dimensions())) {
303                         if (lastArgType.leafComponentType().isBaseType()) {
304                             dimensions--;
305                         }
306                         if (varargsType.dimensions < dimensions) {
307                             scope.problemReporter().varargsArgumentNeedCast(method, lastArgType, invocationSite);
308                         } else if (varargsType.dimensions == dimensions
309                                         && lastArgType != varargsType
310                                         && lastArgType.leafComponentType().erasure() != varargsType.leafComponentType.erasure()
311                                         && lastArgType.isCompatibleWith(varargsType.elementsType())
312                                         && lastArgType.isCompatibleWith(varargsType)) {
313                             scope.problemReporter().varargsArgumentNeedCast(method, lastArgType, invocationSite);
314                         }
315                     }
316                 }
317             } else {
318                 for (int i = 0; i < paramLength; i++) {
319                     TypeBinding originalRawParam = rawOriginalGenericMethod == null ? null : rawOriginalGenericMethod.parameters[i];
320                     invocationStatus |= checkInvocationArgument(scope, arguments[i], params[i], argumentTypes[i], originalRawParam);
321                 }
322             }
323             if (argsContainCast) {
324                 CastExpression.checkNeedForArgumentCasts(scope, receiver, receiverType, method, arguments, argumentTypes, invocationSite);
325             }
326         }
327         if ((invocationStatus & INVOCATION_ARGUMENT_WILDCARD) != 0) {
328             scope.problemReporter().wildcardInvocation((ASTNode)invocationSite, receiverType, method, argumentTypes);
329         } else if (!method.isStatic() && !receiverType.isUnboundWildcard() && method.declaringClass.isRawType() && method.hasSubstitutedParameters()) {
330             scope.problemReporter().unsafeRawInvocation((ASTNode)invocationSite, method);
331         } else if (rawOriginalGenericMethod != null) {
332             scope.problemReporter().unsafeRawGenericMethodInvocation((ASTNode)invocationSite, method);
333         }
334     }
335     public ASTNode concreteStatement() {
336         return this;
337     }
338
339     public final boolean isFieldUseDeprecated(FieldBinding field, Scope scope, boolean isStrictlyAssigned) {
340
341         if (!isStrictlyAssigned && (field.isPrivate() || (field.declaringClass != null && field.declaringClass.isLocalType())) && !scope.isDefinedInField(field)) {
342             // ignore cases where field is used from within inside itself
343
field.original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
344         }
345
346         if ((field.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0) {
347             AccessRestriction restriction =
348                 scope.environment().getAccessRestriction(field.declaringClass.erasure());
349             if (restriction != null) {
350                 scope.problemReporter().forbiddenReference(field, this,
351                         restriction.getFieldAccessMessageTemplate(), restriction.getProblemId());
352             }
353         }
354
355         if (!field.isViewedAsDeprecated()) return false;
356
357         // inside same unit - no report
358
if (scope.isDefinedInSameUnit(field.declaringClass)) return false;
359
360         // if context is deprecated, may avoid reporting
361
if (!scope.compilerOptions().reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
362         return true;
363     }
364
365     public boolean isImplicitThis() {
366
367         return false;
368     }
369
370     /* Answer true if the method use is considered deprecated.
371     * An access in the same compilation unit is allowed.
372     */

373     public final boolean isMethodUseDeprecated(MethodBinding method, Scope scope,
374             boolean isExplicitUse) {
375         if ((method.isPrivate() || method.declaringClass.isLocalType()) && !scope.isDefinedInMethod(method)) {
376             // ignore cases where method is used from within inside itself (e.g. direct recursions)
377
method.original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
378         }
379
380         // TODO (maxime) consider separating concerns between deprecation and access restriction.
381
// Caveat: this was not the case when access restriction funtion was added.
382
if (isExplicitUse && (method.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0) {
383             // note: explicit constructors calls warnings are kept despite the 'new C1()' case (two
384
// warnings, one on type, the other on constructor), because of the 'super()' case.
385
AccessRestriction restriction =
386                 scope.environment().getAccessRestriction(method.declaringClass.erasure());
387             if (restriction != null) {
388                 if (method.isConstructor()) {
389                     scope.problemReporter().forbiddenReference(method, this,
390                             restriction.getConstructorAccessMessageTemplate(),
391                             restriction.getProblemId());
392                 }
393                 else {
394                     scope.problemReporter().forbiddenReference(method, this,
395                             restriction.getMethodAccessMessageTemplate(),
396                             restriction.getProblemId());
397                 }
398             }
399         }
400
401         if (!method.isViewedAsDeprecated()) return false;
402
403         // inside same unit - no report
404
if (scope.isDefinedInSameUnit(method.declaringClass)) return false;
405
406         // non explicit use and non explicitly deprecated - no report
407
if (!isExplicitUse &&
408                 (method.modifiers & ClassFileConstants.AccDeprecated) == 0) {
409             return false;
410         }
411
412         // if context is deprecated, may avoid reporting
413
if (!scope.compilerOptions().reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
414         return true;
415     }
416
417     public boolean isSuper() {
418
419         return false;
420     }
421
422     public boolean isThis() {
423
424         return false;
425     }
426
427     /* Answer true if the type use is considered deprecated.
428     * An access in the same compilation unit is allowed.
429     */

430     public final boolean isTypeUseDeprecated(TypeBinding type, Scope scope) {
431
432         if (type.isArrayType())
433             type = ((ArrayBinding) type).leafComponentType;
434         if (type.isBaseType())
435             return false;
436
437         ReferenceBinding refType = (ReferenceBinding) type;
438
439         if ((refType.isPrivate() || refType.isLocalType()) && !scope.isDefinedInType(refType)) {
440             // ignore cases where type is used from within inside itself
441
((ReferenceBinding)refType.erasure()).modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
442         }
443
444         if (refType.hasRestrictedAccess()) {
445             AccessRestriction restriction = scope.environment().getAccessRestriction(type.erasure());
446             if (restriction != null) {
447                 scope.problemReporter().forbiddenReference(type, this, restriction.getMessageTemplate(), restriction.getProblemId());
448             }
449         }
450
451         // force annotations resolution before deciding whether the type may be deprecated
452
refType.initializeDeprecatedAnnotationTagBits();
453
454         if (!refType.isViewedAsDeprecated()) return false;
455
456         // inside same unit - no report
457
if (scope.isDefinedInSameUnit(refType)) return false;
458
459         // if context is deprecated, may avoid reporting
460
if (!scope.compilerOptions().reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
461         return true;
462     }
463
464     public abstract StringBuffer JavaDoc print(int indent, StringBuffer JavaDoc output);
465
466     public static StringBuffer JavaDoc printAnnotations(Annotation[] annotations, StringBuffer JavaDoc output) {
467         int length = annotations.length;
468         for (int i = 0; i < length; i++) {
469             annotations[i].print(0, output);
470             output.append(" "); //$NON-NLS-1$
471
}
472         return output;
473     }
474
475     public static StringBuffer JavaDoc printIndent(int indent, StringBuffer JavaDoc output) {
476
477         for (int i = indent; i > 0; i--) output.append(" "); //$NON-NLS-1$
478
return output;
479     }
480
481     public static StringBuffer JavaDoc printModifiers(int modifiers, StringBuffer JavaDoc output) {
482
483         if ((modifiers & ClassFileConstants.AccPublic) != 0)
484             output.append("public "); //$NON-NLS-1$
485
if ((modifiers & ClassFileConstants.AccPrivate) != 0)
486             output.append("private "); //$NON-NLS-1$
487
if ((modifiers & ClassFileConstants.AccProtected) != 0)
488             output.append("protected "); //$NON-NLS-1$
489
if ((modifiers & ClassFileConstants.AccStatic) != 0)
490             output.append("static "); //$NON-NLS-1$
491
if ((modifiers & ClassFileConstants.AccFinal) != 0)
492             output.append("final "); //$NON-NLS-1$
493
if ((modifiers & ClassFileConstants.AccSynchronized) != 0)
494             output.append("synchronized "); //$NON-NLS-1$
495
if ((modifiers & ClassFileConstants.AccVolatile) != 0)
496             output.append("volatile "); //$NON-NLS-1$
497
if ((modifiers & ClassFileConstants.AccTransient) != 0)
498             output.append("transient "); //$NON-NLS-1$
499
if ((modifiers & ClassFileConstants.AccNative) != 0)
500             output.append("native "); //$NON-NLS-1$
501
if ((modifiers & ClassFileConstants.AccAbstract) != 0)
502             output.append("abstract "); //$NON-NLS-1$
503
return output;
504     }
505
506     /**
507      * Resolve annotations, and check duplicates, answers combined tagBits
508      * for recognized standard annotations
509      */

510     public static void resolveAnnotations(BlockScope scope, Annotation[] annotations, Binding recipient) {
511         AnnotationBinding[] instances = null;
512         int length = annotations == null ? 0 : annotations.length;
513         if (recipient != null) {
514             switch (recipient.kind()) {
515                 case Binding.PACKAGE :
516                     PackageBinding packageBinding = (PackageBinding) recipient;
517                     if ((packageBinding.tagBits & TagBits.AnnotationResolved) != 0) return;
518                     packageBinding.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
519                     break;
520                 case Binding.TYPE :
521                 case Binding.GENERIC_TYPE :
522                     ReferenceBinding type = (ReferenceBinding) recipient;
523                     if ((type.tagBits & TagBits.AnnotationResolved) != 0) return;
524                     type.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
525                     if (length > 0) {
526                         instances = new AnnotationBinding[length];
527                         type.setAnnotations(instances);
528                     }
529                     break;
530                 case Binding.METHOD :
531                     MethodBinding method = (MethodBinding) recipient;
532                     if ((method.tagBits & TagBits.AnnotationResolved) != 0) return;
533                     method.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
534                     if (length > 0) {
535                         instances = new AnnotationBinding[length];
536                         method.setAnnotations(instances);
537                     }
538                     break;
539                 case Binding.FIELD :
540                     FieldBinding field = (FieldBinding) recipient;
541                     if ((field.tagBits & TagBits.AnnotationResolved) != 0) return;
542                     field.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
543                     if (length > 0) {
544                         instances = new AnnotationBinding[length];
545                         field.setAnnotations(instances);
546                     }
547                     break;
548                 case Binding.LOCAL :
549                     LocalVariableBinding local = (LocalVariableBinding) recipient;
550                     if ((local.tagBits & TagBits.AnnotationResolved) != 0) return;
551                     local.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
552                     if (length > 0) {
553                         instances = new AnnotationBinding[length];
554                         local.setAnnotations(instances);
555                     }
556                     break;
557                 default :
558                     return;
559             }
560         }
561         if (annotations == null)
562             return;
563         TypeBinding[] annotationTypes = new TypeBinding[length];
564         for (int i = 0; i < length; i++) {
565             Annotation annotation = annotations[i];
566             final Binding annotationRecipient = annotation.recipient;
567             if (annotationRecipient != null && recipient != null) {
568                 // only local and field can share annnotations
569
switch (recipient.kind()) {
570                     case Binding.FIELD :
571                         FieldBinding field = (FieldBinding) recipient;
572                         field.tagBits = ((FieldBinding) annotationRecipient).tagBits;
573                         break;
574                     case Binding.LOCAL :
575                         LocalVariableBinding local = (LocalVariableBinding) recipient;
576                         local.tagBits = ((LocalVariableBinding) annotationRecipient).tagBits;
577                         break;
578                 }
579                 if (instances != null) {
580                     // need to fill the instances array
581
instances[0] = annotation.getCompilerAnnotation();
582                     for (int j = 1; j < length; j++) {
583                         Annotation annot = annotations[j];
584                         instances[j] = annot.getCompilerAnnotation();
585                     }
586                 }
587                 return;
588             } else {
589                 annotation.recipient = recipient;
590                 annotationTypes[i] = annotation.resolveType(scope);
591                 // null if receiver is a package binding
592
if (instances != null) {
593                     instances[i] = annotation.getCompilerAnnotation();
594                 }
595             }
596         }
597         // check duplicate annotations
598
for (int i = 0; i < length; i++) {
599             TypeBinding annotationType = annotationTypes[i];
600             if (annotationType == null) continue;
601             boolean foundDuplicate = false;
602             for (int j = i+1; j < length; j++) {
603                 if (annotationTypes[j] == annotationType) {
604                     foundDuplicate = true;
605                     annotationTypes[j] = null; // report it only once
606
scope.problemReporter().duplicateAnnotation(annotations[j]);
607                 }
608             }
609             if (foundDuplicate) {
610                 scope.problemReporter().duplicateAnnotation(annotations[i]);
611             }
612         }
613     }
614
615 /**
616  * Figures if @Deprecated annotation is specified, do not resolve entire annotations.
617  */

618 public static void resolveDeprecatedAnnotations(BlockScope scope, Annotation[] annotations, Binding recipient) {
619     if (recipient != null) {
620         int kind = recipient.kind();
621         if (annotations != null) {
622             int length;
623             if ((length = annotations.length) >= 0) {
624                 switch (kind) {
625                     case Binding.PACKAGE :
626                         PackageBinding packageBinding = (PackageBinding) recipient;
627                         if ((packageBinding.tagBits & TagBits.DeprecatedAnnotationResolved) != 0) return;
628                         break;
629                     case Binding.TYPE :
630                     case Binding.GENERIC_TYPE :
631                         ReferenceBinding type = (ReferenceBinding) recipient;
632                         if ((type.tagBits & TagBits.DeprecatedAnnotationResolved) != 0) return;
633                         break;
634                     case Binding.METHOD :
635                         MethodBinding method = (MethodBinding) recipient;
636                         if ((method.tagBits & TagBits.DeprecatedAnnotationResolved) != 0) return;
637                         break;
638                     case Binding.FIELD :
639                         FieldBinding field = (FieldBinding) recipient;
640                         if ((field.tagBits & TagBits.DeprecatedAnnotationResolved) != 0) return;
641                         break;
642                     case Binding.LOCAL :
643                         LocalVariableBinding local = (LocalVariableBinding) recipient;
644                         if ((local.tagBits & TagBits.DeprecatedAnnotationResolved) != 0) return;
645                         break;
646                     default :
647                         return;
648                 }
649                 for (int i = 0; i < length; i++) {
650                     TypeReference annotationTypeRef = annotations[i].type;
651                     // only resolve type name if 'Deprecated' last token
652
if (!CharOperation.equals(TypeConstants.JAVA_LANG_DEPRECATED[2], annotationTypeRef.getLastToken())) return;
653                     TypeBinding annotationType = annotations[i].type.resolveType(scope);
654                     if(annotationType != null && annotationType.isValidBinding() && annotationType.id == TypeIds.T_JavaLangDeprecated) {
655                         switch (kind) {
656                             case Binding.PACKAGE :
657                                 PackageBinding packageBinding = (PackageBinding) recipient;
658                                 packageBinding.tagBits |= (TagBits.AnnotationDeprecated | TagBits.DeprecatedAnnotationResolved);
659                                 return;
660                             case Binding.TYPE :
661                             case Binding.GENERIC_TYPE :
662                             case Binding.TYPE_PARAMETER :
663                                 ReferenceBinding type = (ReferenceBinding) recipient;
664                                 type.tagBits |= (TagBits.AnnotationDeprecated | TagBits.DeprecatedAnnotationResolved);
665                                 return;
666                             case Binding.METHOD :
667                                 MethodBinding method = (MethodBinding) recipient;
668                                 method.tagBits |= (TagBits.AnnotationDeprecated | TagBits.DeprecatedAnnotationResolved);
669                                 return;
670                             case Binding.FIELD :
671                                 FieldBinding field = (FieldBinding) recipient;
672                                 field.tagBits |= (TagBits.AnnotationDeprecated | TagBits.DeprecatedAnnotationResolved);
673                                 return;
674                             case Binding.LOCAL :
675                                 LocalVariableBinding local = (LocalVariableBinding) recipient;
676                                 local.tagBits |= (TagBits.AnnotationDeprecated | TagBits.DeprecatedAnnotationResolved);
677                                 return;
678                             default:
679                                 return;
680                         }
681                     }
682                 }
683             }
684         }
685         switch (kind) {
686             case Binding.PACKAGE :
687                 PackageBinding packageBinding = (PackageBinding) recipient;
688                 packageBinding.tagBits |= TagBits.DeprecatedAnnotationResolved;
689                 return;
690             case Binding.TYPE :
691             case Binding.GENERIC_TYPE :
692             case Binding.TYPE_PARAMETER :
693                 ReferenceBinding type = (ReferenceBinding) recipient;
694                 type.tagBits |= TagBits.DeprecatedAnnotationResolved;
695                 return;
696             case Binding.METHOD :
697                 MethodBinding method = (MethodBinding) recipient;
698                 method.tagBits |= TagBits.DeprecatedAnnotationResolved;
699                 return;
700             case Binding.FIELD :
701                 FieldBinding field = (FieldBinding) recipient;
702                 field.tagBits |= TagBits.DeprecatedAnnotationResolved;
703                 return;
704             case Binding.LOCAL :
705                 LocalVariableBinding local = (LocalVariableBinding) recipient;
706                 local.tagBits |= TagBits.DeprecatedAnnotationResolved;
707                 return;
708             default:
709                 return;
710         }
711     }
712 }
713
714     public int sourceStart() {
715         return this.sourceStart;
716     }
717     public int sourceEnd() {
718         return this.sourceEnd;
719     }
720     public String JavaDoc toString() {
721
722         return print(0, new StringBuffer JavaDoc(30)).toString();
723     }
724
725     public void traverse(ASTVisitor visitor, BlockScope scope) {
726         // do nothing by default
727
}
728 }
729
Popular Tags