Improved aml scanner for this bug
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / internal / compiler / ast / ASTNode.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 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 net.sourceforge.phpeclipse.internal.compiler.ast;
12
13 import net.sourceforge.phpdt.internal.compiler.ASTVisitor;
14 import net.sourceforge.phpdt.internal.compiler.impl.Constant;
15 import net.sourceforge.phpdt.internal.compiler.lookup.ArrayBinding;
16 import net.sourceforge.phpdt.internal.compiler.lookup.BaseTypes;
17 import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope;
18 import net.sourceforge.phpdt.internal.compiler.lookup.CompilerModifiers;
19 import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding;
20 import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding;
21 import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding;
22 import net.sourceforge.phpdt.internal.compiler.lookup.Scope;
23 import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding;
24 import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants;
25 import net.sourceforge.phpdt.internal.compiler.lookup.TypeIds;
26
27
28 public abstract class ASTNode implements BaseTypes, CompilerModifiers, TypeConstants, TypeIds {
29         
30         public int sourceStart, sourceEnd;
31
32         //some global provision for the hierarchy
33         public final static Constant NotAConstant = Constant.NotAConstant;
34
35         // storage for internal flags (32 bits)                 BIT USAGE
36         public final static int Bit1 = 0x1;                     // return type (operators) | name reference kind (name ref) | add assertion (type decl)
37         public final static int Bit2 = 0x2;                     // return type (operators) | name reference kind (name ref) | has local type (type, method, field decl)
38         public final static int Bit3 = 0x4;                     // return type (operators) | name reference kind (name ref) | implicit this (this ref)
39         public final static int Bit4 = 0x8;                     // return type (operators) | first assignment to local (local decl)
40         public final static int Bit5 = 0x10;                    // value for return (binary expression) | 
41         public final static int Bit6 = 0x20;                    // depth (name ref, msg) | only value required (binary expression)
42         public final static int Bit7 = 0x40;                    // depth (name ref, msg) | operator (operators)
43         public final static int Bit8 = 0x80;                    // depth (name ref, msg) | operator (operators) 
44         public final static int Bit9 = 0x100;                   // depth (name ref, msg) | operator (operators)
45         public final static int Bit10= 0x200;                   // depth (name ref, msg) | operator (operators)
46         public final static int Bit11 = 0x400;                  // depth (name ref, msg) | operator (operators)
47         public final static int Bit12 = 0x800;                  // depth (name ref, msg) | operator (operators)
48         public final static int Bit13 = 0x1000;                 // depth (name ref, msg) 
49         public final static int Bit14 = 0x2000;                 // assigned (reference lhs)
50         public final static int Bit15 = 0x4000; 
51         public final static int Bit16 = 0x8000; 
52         public final static int Bit17 = 0x10000; 
53         public final static int Bit18 = 0x20000; 
54         public final static int Bit19 = 0x40000; 
55         public final static int Bit20 = 0x80000; 
56         public final static int Bit21 = 0x100000;               
57         public final static int Bit22 = 0x200000;               // parenthesis count (expression)
58         public final static int Bit23 = 0x400000;               // parenthesis count (expression)
59         public final static int Bit24 = 0x800000;               // parenthesis count (expression)
60         public final static int Bit25 = 0x1000000;              // parenthesis count (expression)
61         public final static int Bit26 = 0x2000000;              // parenthesis count (expression)
62         public final static int Bit27 = 0x4000000;              // parenthesis count (expression)
63         public final static int Bit28 = 0x8000000;              // parenthesis count (expression)
64         public final static int Bit29 = 0x10000000;     // parenthesis count (expression)
65         public final static int Bit30 = 0x20000000;     // assignment with no effect (assignment)
66         public final static int Bit31 = 0x40000000;     // local declaration reachable (local decl)
67         public final static int Bit32 = 0x80000000;     // reachable (statement)
68
69         public int bits = IsReachableMASK;                              // reachable by default
70
71         // for operators 
72         public static final int ReturnTypeIDMASK = Bit1|Bit2|Bit3|Bit4; 
73         public static final int OperatorSHIFT = 6;      // Bit7 -> Bit12
74         public static final int OperatorMASK = Bit7|Bit8|Bit9|Bit10|Bit11|Bit12; // 6 bits for operator ID
75
76         // for binary expressions
77         public static final int ValueForReturnMASK = Bit5; 
78         public static final int OnlyValueRequiredMASK = Bit6; 
79
80         // for name references 
81         public static final int RestrictiveFlagMASK = Bit1|Bit2|Bit3;   
82         public static final int FirstAssignmentToLocalMASK = Bit4;
83         
84         // for this reference
85         public static final int IsImplicitThisMask = Bit3; 
86
87         // for single name references
88         public static final int DepthSHIFT = 5; // Bit6 -> Bit13
89         public static final int DepthMASK = Bit6|Bit7|Bit8|Bit9|Bit10|Bit11|Bit12|Bit13; // 8 bits for actual depth value (max. 255)
90
91         // for statements 
92         public static final int IsReachableMASK = Bit32; 
93         public static final int IsLocalDeclarationReachableMASK = Bit31; 
94
95         // for type declaration
96         public static final int AddAssertionMASK = Bit1;
97         public static final int IsMemberTypeMASK = Bit11; // local member do not know it is local at parse time (need to look at binding)
98         
99         // for type, method and field declarations 
100         public static final int HasLocalTypeMASK = Bit2; // cannot conflict with AddAssertionMASK
101
102         // for expression 
103         public static final int ParenthesizedSHIFT = 21; // Bit22 -> Bit29
104         public static final int ParenthesizedMASK = Bit22|Bit23|Bit24|Bit25|Bit26|Bit27|Bit28|Bit29; // 8 bits for parenthesis count value (max. 255)
105
106         // for assignment
107         public static final int IsAssignmentWithNoEffectMASK = Bit30;   
108         
109         // for references on lhs of assignment (set only for true assignments, as opposed to compound ones)
110         public static final int IsStrictlyAssignedMASK = Bit14;
111         public static final int IsCompoundAssignedMASK = Bit17; // set only for compound assignments, as opposed to other ones
112
113         // for empty statement
114         public static final int IsUsefulEmptyStatementMASK = Bit1;
115
116         // for block and method declaration
117         public static final int UndocumentedEmptyBlockMASK = Bit4;
118
119         // for compilation unit
120         public static final int HasAllMethodBodies = Bit5;
121         
122         // for references in Javadoc comments
123         public static final int InsideJavadoc = Bit16;
124         
125         // for if statement
126         public static final int IsElseIfStatement = Bit30;
127         
128         public ASTNode() {
129
130                 super();
131         }
132
133         public boolean cannotReturn() {
134                 return false;
135         }
136
137         public ASTNode concreteStatement() {
138                 return this;
139         }
140
141         /* Answer true if the field use is considered deprecated.
142         * An access in the same compilation unit is allowed.
143         */
144         public final boolean isFieldUseDeprecated(FieldBinding field, Scope scope) {
145
146                 if (field.isPrivate() && !scope.isDefinedInField(field)) {
147                         // ignore cases where field is used from within inside itself 
148                         field.modifiers |= AccPrivateUsed;
149                 }
150
151                 if (!field.isViewedAsDeprecated()) return false;
152
153                 // inside same unit - no report
154                 if (scope.isDefinedInSameUnit(field.declaringClass)) return false;
155                 
156                 // if context is deprecated, may avoid reporting
157 //              if (!scope.environment().options.reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
158                 return true;
159         }
160
161         public boolean isImplicitThis() {
162                 
163                 return false;
164         }
165         
166         /* Answer true if the method use is considered deprecated.
167         * An access in the same compilation unit is allowed.
168         */
169         public final boolean isMethodUseDeprecated(MethodBinding method, Scope scope) {
170
171                 if (method.isPrivate() && !scope.isDefinedInMethod(method)) {
172                         // ignore cases where method is used from within inside itself (e.g. direct recursions)
173                         method.modifiers |= AccPrivateUsed;
174                 }
175                 
176                 if (!method.isViewedAsDeprecated()) return false;
177
178                 // inside same unit - no report
179                 if (scope.isDefinedInSameUnit(method.declaringClass)) return false;
180                 
181                 // if context is deprecated, may avoid reporting
182 //              if (!scope.environment().options.reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
183                 return true;
184         }
185
186         public boolean isSuper() {
187
188                 return false;
189         }
190
191         public boolean isThis() {
192
193                 return false;
194         }
195
196         /* Answer true if the type use is considered deprecated.
197         * An access in the same compilation unit is allowed.
198         */
199         public final boolean isTypeUseDeprecated(TypeBinding type, Scope scope) {
200
201                 if (type.isArrayType())
202                         type = ((ArrayBinding) type).leafComponentType;
203                 if (type.isBaseType())
204                         return false;
205
206                 ReferenceBinding refType = (ReferenceBinding) type;
207
208                 if (refType.isPrivate() && !scope.isDefinedInType(refType)) {
209                         // ignore cases where type is used from within inside itself 
210                         refType.modifiers |= AccPrivateUsed;
211                 }
212
213                 if (!refType.isViewedAsDeprecated()) return false;
214                 
215                 // inside same unit - no report
216                 if (scope.isDefinedInSameUnit(refType)) return false;
217                 
218                 // if context is deprecated, may avoid reporting
219 //              if (!scope.environment().options.reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
220                 return true;
221         }
222
223         public static String modifiersString(int modifiers) {
224
225                 String s = ""; //$NON-NLS-1$
226                 if ((modifiers & AccPublic) != 0)
227                         s = s + "public "; //$NON-NLS-1$
228                 if ((modifiers & AccPrivate) != 0)
229                         s = s + "private "; //$NON-NLS-1$
230                 if ((modifiers & AccProtected) != 0)
231                         s = s + "protected "; //$NON-NLS-1$
232                 if ((modifiers & AccStatic) != 0)
233                         s = s + "static "; //$NON-NLS-1$
234                 if ((modifiers & AccFinal) != 0)
235                         s = s + "final "; //$NON-NLS-1$
236 //              if ((modifiers & AccSynchronized) != 0)
237 //                      s = s + "synchronized "; //$NON-NLS-1$
238 //              if ((modifiers & AccVolatile) != 0)
239 //                      s = s + "volatile "; //$NON-NLS-1$
240 //              if ((modifiers & AccTransient) != 0)
241 //                      s = s + "transient "; //$NON-NLS-1$
242 //              if ((modifiers & AccNative) != 0)
243 //                      s = s + "native "; //$NON-NLS-1$
244                 if ((modifiers & AccAbstract) != 0)
245                         s = s + "abstract "; //$NON-NLS-1$
246                 return s;
247         }
248
249         public abstract StringBuffer print(int indent, StringBuffer output);
250
251         public static StringBuffer printIndent(int indent, StringBuffer output) {
252
253                 for (int i = indent; i > 0; i--) output.append("  "); //$NON-NLS-1$
254                 return output;
255         }
256
257         public static StringBuffer printModifiers(int modifiers, StringBuffer output) {
258
259                 if ((modifiers & AccPublic) != 0)
260                         output.append("public "); //$NON-NLS-1$
261                 if ((modifiers & AccPrivate) != 0)
262                         output.append("private "); //$NON-NLS-1$
263                 if ((modifiers & AccProtected) != 0)
264                         output.append("protected "); //$NON-NLS-1$
265                 if ((modifiers & AccStatic) != 0)
266                         output.append("static "); //$NON-NLS-1$
267                 if ((modifiers & AccFinal) != 0)
268                         output.append("final "); //$NON-NLS-1$
269 //              if ((modifiers & AccSynchronized) != 0)
270 //                      output.append("synchronized "); //$NON-NLS-1$
271 //              if ((modifiers & AccVolatile) != 0)
272 //                      output.append("volatile "); //$NON-NLS-1$
273 //              if ((modifiers & AccTransient) != 0)
274 //                      output.append("transient "); //$NON-NLS-1$
275 //              if ((modifiers & AccNative) != 0)
276 //                      output.append("native "); //$NON-NLS-1$
277                 if ((modifiers & AccAbstract) != 0)
278                         output.append("abstract "); //$NON-NLS-1$
279                 return output;
280         }
281         /** 
282          * @deprecated - use field instead
283         */
284         public int sourceEnd() {
285                 return sourceEnd;
286         }
287         
288         /** 
289          * @deprecated - use field instead
290         */
291         public int sourceStart() {
292                 return sourceStart;
293         }
294
295         public static String tabString(int tab) {
296
297                 String s = ""; //$NON-NLS-1$
298                 for (int i = tab; i > 0; i--)
299                         s = s + "  "; //$NON-NLS-1$
300                 return s;
301         }
302
303         public String toString() {
304
305                 return toString(0);
306         }
307
308         public String toString(int tab) {
309
310                 return "****" + super.toString() + "****";  //$NON-NLS-2$ //$NON-NLS-1$
311         }
312         
313         public void traverse(ASTVisitor visitor, BlockScope scope) {
314         }
315 }