added -J option to preserve unmodified files in preexisting jarfile
[org.ibex.tool.git] / src / org / eclipse / jdt / internal / compiler / ast / ASTNode.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package org.eclipse.jdt.internal.compiler.ast;
12
13 import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
14 import org.eclipse.jdt.internal.compiler.impl.*;
15 import org.eclipse.jdt.internal.compiler.lookup.*;
16 import org.eclipse.jdt.internal.compiler.ASTVisitor;
17
18 public abstract class ASTNode implements BaseTypes, CompilerModifiers, TypeConstants, TypeIds {
19         
20         public int sourceStart, sourceEnd;
21
22         //some global provision for the hierarchy
23         public final static Constant NotAConstant = Constant.NotAConstant;
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 (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)
31         public final static int Bit6 = 0x20;                                            // depth (name ref, msg) | only value required (binary expression) | ignore need cast check (cast expression)
32         public final static int Bit7 = 0x40;                                            // depth (name ref, msg) | operator (operator) | need runtime checkcast (cast expression)
33         public final static int Bit8 = 0x80;                                            // depth (name ref, msg) | operator (operator) 
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) 
39         public final static int Bit14 = 0x2000;                                 // strictly assigned (reference lhs)
40         public final static int Bit15 = 0x4000;                                 // is unnecessary cast (expression)
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; 
44         public final static int Bit19 = 0x40000; 
45         public final static int Bit20 = 0x80000; 
46         public final static int Bit21 = 0x100000;               
47         public final static int Bit22 = 0x200000;                       // parenthesis count (expression)
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;             // assignment with no effect (assignment) | elseif (if statement)
56         public final static int Bit31 = 0x40000000;             // local declaration reachable (local decl)
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
85         public int bits = IsReachableMASK;                              // reachable by default
86
87         // for operators 
88         public static final int ReturnTypeIDMASK = Bit1|Bit2|Bit3|Bit4; 
89         public static final int OperatorSHIFT = 6;      // Bit7 -> Bit12
90         public static final int OperatorMASK = Bit7|Bit8|Bit9|Bit10|Bit11|Bit12; // 6 bits for operator ID
91
92         // for binary expressions
93         public static final int ValueForReturnMASK = Bit5; 
94         public static final int OnlyValueRequiredMASK = Bit6; 
95
96         // for cast expressions
97         public static final int UnnecessaryCastMask = Bit15;
98         public static final int NeedRuntimeCheckCastMASK = Bit7;
99         public static final int IgnoreNeedForCastCheckMASK = Bit6;
100         
101         // for name references 
102         public static final int RestrictiveFlagMASK = Bit1|Bit2|Bit3;   
103         public static final int FirstAssignmentToLocalMASK = Bit4;
104         
105         // for this reference
106         public static final int IsImplicitThisMask = Bit3; 
107
108         // for single name references
109         public static final int DepthSHIFT = 5; // Bit6 -> Bit13
110         public static final int DepthMASK = Bit6|Bit7|Bit8|Bit9|Bit10|Bit11|Bit12|Bit13; // 8 bits for actual depth value (max. 255)
111
112         // for statements 
113         public static final int IsReachableMASK = Bit32; 
114         public static final int IsLocalDeclarationReachableMASK = Bit31; 
115
116         // for type declaration
117         public static final int AddAssertionMASK = Bit1;
118         public static final int IsLocalTypeMASK = Bit9;
119         public static final int IsAnonymousTypeMASK = Bit10; // used to test for anonymous 
120         public static final int AnonymousAndLocalMask = IsAnonymousTypeMASK | IsLocalTypeMASK; // used to set anonymous marker
121         public static final int IsMemberTypeMASK = Bit11; // local member do not know it is local at parse time (need to look at binding)
122         public static final int HasAbstractMethods = Bit12; // used to promote abstract enums
123         
124         // for type, method and field declarations 
125         public static final int HasLocalTypeMASK = Bit2; // cannot conflict with AddAssertionMASK
126
127         // for expression 
128         public static final int ParenthesizedSHIFT = 21; // Bit22 -> Bit29
129         public static final int ParenthesizedMASK = Bit22|Bit23|Bit24|Bit25|Bit26|Bit27|Bit28|Bit29; // 8 bits for parenthesis count value (max. 255)
130
131         // for assignment
132         public static final int IsAssignmentWithNoEffectMASK = Bit30;   
133         
134         // for references on lhs of assignment
135         public static final int IsStrictlyAssignedMASK = Bit14; // set only for true assignments, as opposed to compound ones
136         public static final int IsCompoundAssignedMASK = Bit17; // set only for compound assignments, as opposed to other ones
137
138         // for empty statement
139         public static final int IsUsefulEmptyStatementMASK = Bit1;
140
141         // for block and method declaration
142         public static final int UndocumentedEmptyBlockMASK = Bit4;
143
144         // for compilation unit
145         public static final int HasAllMethodBodies = Bit5;
146         
147         // for references in Javadoc comments
148         public static final int InsideJavadoc = Bit16;
149         
150         // for if statement
151         public static final int IsElseIfStatement = Bit30;
152         
153         // for type reference
154         public static final int IsSuperType = Bit5;
155         
156         // for variable argument
157         public static final int IsVarArgs = Bit15;
158         
159         public ASTNode() {
160
161                 super();
162         }
163         private static boolean checkInvocationArgument(BlockScope scope, Expression argument, TypeBinding parameterType, TypeBinding argumentType) {
164                 argument.computeConversion(scope, parameterType, argumentType);
165
166                 if (argumentType != NullBinding && parameterType.isWildcard() && ((WildcardBinding) parameterType).kind != Wildcard.SUPER)
167                     return true; // unsafeWildcardInvocation
168                 if (argumentType != parameterType && argumentType.isRawType())
169                 if (parameterType.isBoundParameterizedType() || parameterType.isGenericType())
170                                 scope.problemReporter().unsafeRawConversion(argument, argumentType, parameterType);
171                 return false;
172         }
173         public static void checkInvocationArguments(BlockScope scope, Expression receiver, TypeBinding receiverType, MethodBinding method, Expression[] arguments, TypeBinding[] argumentTypes, boolean argsContainCast, InvocationSite invocationSite) {
174                 boolean unsafeWildcardInvocation = false;
175                 TypeBinding[] params = method.parameters;
176                 if (method.isVarargs()) {
177                         // 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})
178                         int lastIndex = params.length - 1;
179                         for (int i = 0; i < lastIndex; i++)
180                             if (checkInvocationArgument(scope, arguments[i], params[i], argumentTypes[i]))
181                                     unsafeWildcardInvocation = true;
182                    int argLength = arguments.length;
183                    if (lastIndex < argLength) { // vararg argument was provided
184                                 TypeBinding parameterType = params[lastIndex];
185                             if (params.length != argLength || parameterType.dimensions() != argumentTypes[lastIndex].dimensions())
186                                 parameterType = ((ArrayBinding) parameterType).elementsType(); // single element was provided for vararg parameter
187                                 for (int i = lastIndex; i < argLength; i++)
188                                     if (checkInvocationArgument(scope, arguments[i], parameterType, argumentTypes[i]))
189                                             unsafeWildcardInvocation = true;
190                         }
191
192                    if (method.parameters.length == argumentTypes.length) { // 70056
193                                 int varargIndex = method.parameters.length - 1;
194                                 ArrayBinding varargType = (ArrayBinding) method.parameters[varargIndex];
195                                 TypeBinding lastArgType = argumentTypes[varargIndex];
196                                 if (lastArgType == NullBinding) {
197                                         if (!(varargType.leafComponentType().isBaseType() && varargType.dimensions() == 1))
198                                                 scope.problemReporter().varargsArgumentNeedCast(method, lastArgType, invocationSite);
199                                 } else if (varargType.dimensions <= lastArgType.dimensions()) {
200                                         int dimensions = lastArgType.dimensions();
201                                         if (lastArgType.leafComponentType().isBaseType())
202                                                 dimensions--;
203                                         if (varargType.dimensions < dimensions)
204                                                 scope.problemReporter().varargsArgumentNeedCast(method, lastArgType, invocationSite);
205                                         else if (varargType.dimensions == dimensions && varargType.leafComponentType != lastArgType.leafComponentType())
206                                                 scope.problemReporter().varargsArgumentNeedCast(method, lastArgType, invocationSite);
207                                 }
208                         }
209                 } else {
210                         for (int i = 0, argLength = arguments.length; i < argLength; i++)
211                             if (checkInvocationArgument(scope, arguments[i], params[i], argumentTypes[i]))
212                                     unsafeWildcardInvocation = true;
213                 }
214                 if (argsContainCast) {
215                         CastExpression.checkNeedForArgumentCasts(scope, receiver, receiverType, method, arguments, argumentTypes, invocationSite);
216                 }
217                 if (unsafeWildcardInvocation) {
218                     scope.problemReporter().wildcardInvocation((ASTNode)invocationSite, receiverType, method, argumentTypes);
219                 } else if (!receiverType.isUnboundWildcard() && method.declaringClass.isRawType() && method.hasSubstitutedParameters()) {
220                     scope.problemReporter().unsafeRawInvocation((ASTNode)invocationSite, method);
221                 }
222         }
223         public ASTNode concreteStatement() {
224                 return this;
225         }
226         
227         /* Answer true if the field use is considered deprecated.
228         * An access in the same compilation unit is allowed.
229         */
230         public final boolean isFieldUseDeprecated(FieldBinding field, Scope scope, boolean isStrictlyAssigned) {
231
232                 if (!isStrictlyAssigned && field.isPrivate() && !scope.isDefinedInField(field)) {
233                         // ignore cases where field is used from within inside itself 
234                         field.modifiers |= AccPrivateUsed;
235                 }
236
237                 if (!field.isViewedAsDeprecated()) return false;
238
239                 // inside same unit - no report
240                 if (scope.isDefinedInSameUnit(field.declaringClass)) return false;
241                 
242                 // if context is deprecated, may avoid reporting
243                 if (!scope.environment().options.reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
244                 return true;
245         }
246
247         public boolean isImplicitThis() {
248                 
249                 return false;
250         }
251         
252         /* Answer true if the method use is considered deprecated.
253         * An access in the same compilation unit is allowed.
254         */
255         public final boolean isMethodUseDeprecated(MethodBinding method, Scope scope) {
256
257                 if (method.isPrivate() && !scope.isDefinedInMethod(method)) {
258                         // ignore cases where method is used from within inside itself (e.g. direct recursions)
259                         method.original().modifiers |= AccPrivateUsed;
260                 }
261                 
262                 if (!method.isViewedAsDeprecated()) return false;
263
264                 // inside same unit - no report
265                 if (scope.isDefinedInSameUnit(method.declaringClass)) return false;
266                 
267                 // if context is deprecated, may avoid reporting
268                 if (!scope.environment().options.reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
269                 return true;
270         }
271
272         public boolean isSuper() {
273
274                 return false;
275         }
276
277         public boolean isThis() {
278
279                 return false;
280         }
281
282         /* Answer true if the type use is considered deprecated.
283         * An access in the same compilation unit is allowed.
284         */
285         public final boolean isTypeUseDeprecated(TypeBinding type, Scope scope) {
286
287                 if (type.isArrayType())
288                         type = ((ArrayBinding) type).leafComponentType;
289                 if (type.isBaseType())
290                         return false;
291
292                 ReferenceBinding refType = (ReferenceBinding) type;
293
294                 if (refType.isPrivate() && !scope.isDefinedInType(refType)) {
295                         // ignore cases where type is used from within inside itself 
296                         ((ReferenceBinding)refType.erasure()).modifiers |= AccPrivateUsed;
297                 }
298                 
299                 if (refType.hasRestrictedAccess()) {
300                         AccessRestriction restriction = scope.environment().getAccessRestriction(type);
301                         if (restriction != null) {
302                                 scope.problemReporter().forbiddenReference(type, this, restriction.getMessageTemplate());
303                         }
304                 }
305                 if (!refType.isViewedAsDeprecated()) return false;
306                 
307                 // inside same unit - no report
308                 if (scope.isDefinedInSameUnit(refType)) return false;
309                 
310                 // if context is deprecated, may avoid reporting
311                 if (!scope.environment().options.reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
312                 return true;
313         }
314
315         public abstract StringBuffer print(int indent, StringBuffer output);
316
317         public static StringBuffer printAnnotations(Annotation[] annotations, StringBuffer output) {
318                 int length = annotations.length;
319                 for (int i = 0; i < length; i++) {
320                         annotations[i].print(0, output);
321                         output.append(" "); //$NON-NLS-1$
322                 }
323                 return output;
324         }
325         
326         public static StringBuffer printIndent(int indent, StringBuffer output) {
327
328                 for (int i = indent; i > 0; i--) output.append("  "); //$NON-NLS-1$
329                 return output;
330         }
331
332         public static StringBuffer printModifiers(int modifiers, StringBuffer output) {
333
334                 if ((modifiers & AccPublic) != 0)
335                         output.append("public "); //$NON-NLS-1$
336                 if ((modifiers & AccPrivate) != 0)
337                         output.append("private "); //$NON-NLS-1$
338                 if ((modifiers & AccProtected) != 0)
339                         output.append("protected "); //$NON-NLS-1$
340                 if ((modifiers & AccStatic) != 0)
341                         output.append("static "); //$NON-NLS-1$
342                 if ((modifiers & AccFinal) != 0)
343                         output.append("final "); //$NON-NLS-1$
344                 if ((modifiers & AccSynchronized) != 0)
345                         output.append("synchronized "); //$NON-NLS-1$
346                 if ((modifiers & AccVolatile) != 0)
347                         output.append("volatile "); //$NON-NLS-1$
348                 if ((modifiers & AccTransient) != 0)
349                         output.append("transient "); //$NON-NLS-1$
350                 if ((modifiers & AccNative) != 0)
351                         output.append("native "); //$NON-NLS-1$
352                 if ((modifiers & AccAbstract) != 0)
353                         output.append("abstract "); //$NON-NLS-1$
354                 return output;
355         }
356         
357         /**
358          * Resolve annotations, and check duplicates, answers combined tagBits 
359          * for recognized standard annotations
360          */
361         public void resolveAnnotations(BlockScope scope, Annotation[] annotations, Binding recipient) {
362                 if (recipient != null) {
363                         switch (recipient.kind()) {
364                                 case Binding.PACKAGE :
365                                         // TODO (philippe) need support for package annotations
366                                         break;
367                                 case Binding.TYPE :
368                                 case Binding.GENERIC_TYPE :
369                                 case Binding.TYPE_PARAMETER :
370                                         ReferenceBinding type = (ReferenceBinding) recipient;
371                                         if ((type.tagBits & TagBits.AnnotationResolved) != 0) return;
372                                         type.tagBits |= TagBits.AnnotationResolved;
373                                         break;
374                                 case Binding.METHOD :
375                                         MethodBinding method = (MethodBinding) recipient;
376                                         if ((method.tagBits & TagBits.AnnotationResolved) != 0) return;
377                                         method.tagBits |= TagBits.AnnotationResolved;
378                                         break;
379                                 case Binding.FIELD :
380                                         FieldBinding field = (FieldBinding) recipient;
381                                         if ((field.tagBits & TagBits.AnnotationResolved) != 0) return;
382                                         field.tagBits |= TagBits.AnnotationResolved;
383                                         break;
384                                 case Binding.LOCAL :
385                                         LocalVariableBinding local = (LocalVariableBinding) recipient;
386                                         if ((local.tagBits & TagBits.AnnotationResolved) != 0) return;
387                                         local.tagBits |= TagBits.AnnotationResolved;
388                                         break;
389                         }                       
390                 }
391                 if (annotations == null) 
392                         return;
393                 int length = annotations.length;
394                 TypeBinding[] annotationTypes = new TypeBinding[length];
395                 for (int i = 0; i < length; i++) {
396                         Annotation annotation = annotations[i];
397                         annotation.recipient = recipient;
398                         annotationTypes[i] = annotation.resolveType(scope);
399                 }
400                 // check duplicate annotations
401                 for (int i = 0; i < length; i++) {
402                         TypeBinding annotationType = annotationTypes[i];
403                         if (annotationType == null) continue;
404                         boolean foundDuplicate = false;
405                         for (int j = i+1; j < length; j++) {
406                                 if (annotationTypes[j] == annotationType) {
407                                         foundDuplicate = true;
408                                         annotationTypes[j] = null; // report it only once
409                                         scope.problemReporter().duplicateAnnotation(annotations[j]);
410                                 }
411                         }
412                         if (foundDuplicate) {
413                                 scope.problemReporter().duplicateAnnotation(annotations[i]);
414                         }
415                 }
416         }
417         
418         public int sourceStart() {
419                 return this.sourceStart;
420         }
421         public int sourceEnd() {
422                 return this.sourceEnd;
423         }
424         public String toString() {
425
426                 return print(0, new StringBuffer(30)).toString();
427         }
428
429         public void traverse(ASTVisitor visitor, BlockScope scope) {
430                 // do nothing by default
431         }
432 }