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
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.jdt.internal.compiler.ast;
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;
18 public abstract class ASTNode implements BaseTypes, CompilerModifiers, TypeConstants, TypeIds {
20 public int sourceStart, sourceEnd;
22 //some global provision for the hierarchy
23 public final static Constant NotAConstant = Constant.NotAConstant;
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)
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;
85 public int bits = IsReachableMASK; // reachable by default
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
92 // for binary expressions
93 public static final int ValueForReturnMASK = Bit5;
94 public static final int OnlyValueRequiredMASK = Bit6;
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;
101 // for name references
102 public static final int RestrictiveFlagMASK = Bit1|Bit2|Bit3;
103 public static final int FirstAssignmentToLocalMASK = Bit4;
105 // for this reference
106 public static final int IsImplicitThisMask = Bit3;
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)
113 public static final int IsReachableMASK = Bit32;
114 public static final int IsLocalDeclarationReachableMASK = Bit31;
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
124 // for type, method and field declarations
125 public static final int HasLocalTypeMASK = Bit2; // cannot conflict with AddAssertionMASK
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)
132 public static final int IsAssignmentWithNoEffectMASK = Bit30;
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
138 // for empty statement
139 public static final int IsUsefulEmptyStatementMASK = Bit1;
141 // for block and method declaration
142 public static final int UndocumentedEmptyBlockMASK = Bit4;
144 // for compilation unit
145 public static final int HasAllMethodBodies = Bit5;
147 // for references in Javadoc comments
148 public static final int InsideJavadoc = Bit16;
151 public static final int IsElseIfStatement = Bit30;
153 // for type reference
154 public static final int IsSuperType = Bit5;
156 // for variable argument
157 public static final int IsVarArgs = Bit15;
163 private static boolean checkInvocationArgument(BlockScope scope, Expression argument, TypeBinding parameterType, TypeBinding argumentType) {
164 argument.computeConversion(scope, parameterType, argumentType);
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);
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;
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())
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);
210 for (int i = 0, argLength = arguments.length; i < argLength; i++)
211 if (checkInvocationArgument(scope, arguments[i], params[i], argumentTypes[i]))
212 unsafeWildcardInvocation = true;
214 if (argsContainCast) {
215 CastExpression.checkNeedForArgumentCasts(scope, receiver, receiverType, method, arguments, argumentTypes, invocationSite);
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);
223 public ASTNode concreteStatement() {
227 /* Answer true if the field use is considered deprecated.
228 * An access in the same compilation unit is allowed.
230 public final boolean isFieldUseDeprecated(FieldBinding field, Scope scope, boolean isStrictlyAssigned) {
232 if (!isStrictlyAssigned && field.isPrivate() && !scope.isDefinedInField(field)) {
233 // ignore cases where field is used from within inside itself
234 field.modifiers |= AccPrivateUsed;
237 if (!field.isViewedAsDeprecated()) return false;
239 // inside same unit - no report
240 if (scope.isDefinedInSameUnit(field.declaringClass)) return false;
242 // if context is deprecated, may avoid reporting
243 if (!scope.environment().options.reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
247 public boolean isImplicitThis() {
252 /* Answer true if the method use is considered deprecated.
253 * An access in the same compilation unit is allowed.
255 public final boolean isMethodUseDeprecated(MethodBinding method, Scope scope) {
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;
262 if (!method.isViewedAsDeprecated()) return false;
264 // inside same unit - no report
265 if (scope.isDefinedInSameUnit(method.declaringClass)) return false;
267 // if context is deprecated, may avoid reporting
268 if (!scope.environment().options.reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
272 public boolean isSuper() {
277 public boolean isThis() {
282 /* Answer true if the type use is considered deprecated.
283 * An access in the same compilation unit is allowed.
285 public final boolean isTypeUseDeprecated(TypeBinding type, Scope scope) {
287 if (type.isArrayType())
288 type = ((ArrayBinding) type).leafComponentType;
289 if (type.isBaseType())
292 ReferenceBinding refType = (ReferenceBinding) type;
294 if (refType.isPrivate() && !scope.isDefinedInType(refType)) {
295 // ignore cases where type is used from within inside itself
296 ((ReferenceBinding)refType.erasure()).modifiers |= AccPrivateUsed;
299 if (refType.hasRestrictedAccess()) {
300 AccessRestriction restriction = scope.environment().getAccessRestriction(type);
301 if (restriction != null) {
302 scope.problemReporter().forbiddenReference(type, this, restriction.getMessageTemplate());
305 if (!refType.isViewedAsDeprecated()) return false;
307 // inside same unit - no report
308 if (scope.isDefinedInSameUnit(refType)) return false;
310 // if context is deprecated, may avoid reporting
311 if (!scope.environment().options.reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
315 public abstract StringBuffer print(int indent, StringBuffer output);
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$
326 public static StringBuffer printIndent(int indent, StringBuffer output) {
328 for (int i = indent; i > 0; i--) output.append(" "); //$NON-NLS-1$
332 public static StringBuffer printModifiers(int modifiers, StringBuffer output) {
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$
358 * Resolve annotations, and check duplicates, answers combined tagBits
359 * for recognized standard annotations
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
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;
374 case Binding.METHOD :
375 MethodBinding method = (MethodBinding) recipient;
376 if ((method.tagBits & TagBits.AnnotationResolved) != 0) return;
377 method.tagBits |= TagBits.AnnotationResolved;
380 FieldBinding field = (FieldBinding) recipient;
381 if ((field.tagBits & TagBits.AnnotationResolved) != 0) return;
382 field.tagBits |= TagBits.AnnotationResolved;
385 LocalVariableBinding local = (LocalVariableBinding) recipient;
386 if ((local.tagBits & TagBits.AnnotationResolved) != 0) return;
387 local.tagBits |= TagBits.AnnotationResolved;
391 if (annotations == null)
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);
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]);
412 if (foundDuplicate) {
413 scope.problemReporter().duplicateAnnotation(annotations[i]);
418 public int sourceStart() {
419 return this.sourceStart;
421 public int sourceEnd() {
422 return this.sourceEnd;
424 public String toString() {
426 return print(0, new StringBuffer(30)).toString();
429 public void traverse(ASTVisitor visitor, BlockScope scope) {
430 // do nothing by default