KickJava   Java API By Example, From Geeks To Geeks.

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


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  * Nick Teryaev - fix for bug (https://bugs.eclipse.org/bugs/show_bug.cgi?id=40752)
11  *******************************************************************************/

12 package org.eclipse.jdt.internal.compiler.ast;
13
14 import org.eclipse.jdt.core.compiler.CharOperation;
15 import org.eclipse.jdt.internal.compiler.ASTVisitor;
16 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
17 import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
18 import org.eclipse.jdt.internal.compiler.flow.FlowContext;
19 import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
20 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
21 import org.eclipse.jdt.internal.compiler.impl.Constant;
22 import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
23 import org.eclipse.jdt.internal.compiler.lookup.Binding;
24 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
25 import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
26 import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
27 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
28 import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding;
29 import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
30 import org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding;
31 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
32 import org.eclipse.jdt.internal.compiler.lookup.Scope;
33 import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
34 import org.eclipse.jdt.internal.compiler.lookup.TagBits;
35 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
36 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
37 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
38 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
39
40 public class MessageSend extends Expression implements InvocationSite {
41     
42     public Expression receiver;
43     public char[] selector;
44     public Expression[] arguments;
45     public MethodBinding binding; // exact binding resulting from lookup
46
protected MethodBinding codegenBinding; // actual binding used for code generation (if no synthetic accessor)
47
MethodBinding syntheticAccessor; // synthetic accessor for inner-emulation
48
public TypeBinding expectedType; // for generic method invocation (return type inference)
49

50     public long nameSourcePosition ; //(start<<32)+end
51

52     public TypeBinding actualReceiverType;
53     public TypeBinding receiverGenericCast; // extra reference type cast to perform on generic receiver
54
public TypeBinding valueCast; // extra reference type cast to perform on method returned value
55
public TypeReference[] typeArguments;
56     public TypeBinding[] genericTypeArguments;
57     
58 public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
59
60     boolean nonStatic = !this.binding.isStatic();
61     flowInfo = this.receiver.analyseCode(currentScope, flowContext, flowInfo, nonStatic).unconditionalInits();
62     if (nonStatic) {
63         this.receiver.checkNPE(currentScope, flowContext, flowInfo);
64     }
65
66     if (this.arguments != null) {
67         int length = this.arguments.length;
68         for (int i = 0; i < length; i++) {
69             flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
70         }
71     }
72     ReferenceBinding[] thrownExceptions;
73     if ((thrownExceptions = this.binding.thrownExceptions) != Binding.NO_EXCEPTIONS) {
74         // must verify that exceptions potentially thrown by this expression are caught in the method
75
flowContext.checkExceptionHandlers(thrownExceptions, this, flowInfo.copy(), currentScope);
76         // TODO (maxime) the copy above is needed because of a side effect into
77
// checkExceptionHandlers; consider protecting there instead of here;
78
// NullReferenceTest#test0510
79
}
80     manageSyntheticAccessIfNecessary(currentScope, flowInfo);
81     return flowInfo;
82 }
83 /**
84  * @see org.eclipse.jdt.internal.compiler.ast.Expression#computeConversion(org.eclipse.jdt.internal.compiler.lookup.Scope, org.eclipse.jdt.internal.compiler.lookup.TypeBinding, org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
85  */

86 public void computeConversion(Scope scope, TypeBinding runtimeTimeType, TypeBinding compileTimeType) {
87     if (runtimeTimeType == null || compileTimeType == null)
88         return;
89     // set the generic cast after the fact, once the type expectation is fully known (no need for strict cast)
90
if (this.binding != null && this.binding.isValidBinding()) {
91         MethodBinding originalBinding = this.binding.original();
92         TypeBinding originalType = originalBinding.returnType;
93         // extra cast needed if method return type is type variable
94
if (originalBinding != this.binding
95                 && originalType != this.binding.returnType
96                 && runtimeTimeType.id != TypeIds.T_JavaLangObject
97                 && (originalType.tagBits & TagBits.HasTypeVariable) != 0) {
98             TypeBinding targetType = (!compileTimeType.isBaseType() && runtimeTimeType.isBaseType())
99                 ? compileTimeType // unboxing: checkcast before conversion
100
: runtimeTimeType;
101             this.valueCast = originalType.genericCast(targetType);
102         } else if (this.actualReceiverType.isArrayType()
103                         && runtimeTimeType.id != TypeIds.T_JavaLangObject
104                         && this.binding.parameters == Binding.NO_PARAMETERS
105                         && scope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_5
106                         && CharOperation.equals(this.binding.selector, TypeConstants.CLONE)) {
107                     // from 1.5 compliant mode on, array#clone() resolves to array type, but codegen to #clone()Object - thus require extra inserted cast
108
this.valueCast = runtimeTimeType;
109         }
110     }
111     super.computeConversion(scope, runtimeTimeType, compileTimeType);
112 }
113
114 /**
115  * MessageSend code generation
116  *
117  * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
118  * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
119  * @param valueRequired boolean
120  */

121 public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
122
123     int pc = codeStream.position;
124
125     // generate receiver/enclosing instance access
126
boolean isStatic = this.codegenBinding.isStatic();
127     if (isStatic) {
128         this.receiver.generateCode(currentScope, codeStream, false);
129         codeStream.recordPositionsFrom(pc, this.sourceStart);
130     } else if ((this.bits & ASTNode.DepthMASK) != 0 && this.receiver.isImplicitThis()) { // outer access ?
131
// outer method can be reached through emulation if implicit access
132
ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT);
133         Object JavaDoc[] path = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/);
134         codeStream.generateOuterAccess(path, this, targetType, currentScope);
135     } else {
136         this.receiver.generateCode(currentScope, codeStream, true);
137         if (this.receiverGenericCast != null)
138             codeStream.checkcast(this.receiverGenericCast);
139         codeStream.recordPositionsFrom(pc, this.sourceStart);
140         
141     }
142     // generate arguments
143
generateArguments(this.binding, this.arguments, currentScope, codeStream);
144     // actual message invocation
145
if (this.syntheticAccessor == null){
146         if (isStatic){
147             codeStream.invokestatic(this.codegenBinding);
148         } else {
149             if( (this.receiver.isSuper()) || this.codegenBinding.isPrivate()){
150                 codeStream.invokespecial(this.codegenBinding);
151             } else {
152                 if (this.codegenBinding.declaringClass.isInterface()) { // interface or annotation type
153
codeStream.invokeinterface(this.codegenBinding);
154                 } else {
155                     codeStream.invokevirtual(this.codegenBinding);
156                 }
157             }
158         }
159     } else {
160         codeStream.invokestatic(this.syntheticAccessor);
161     }
162     // required cast must occur even if no value is required
163
if (this.valueCast != null) codeStream.checkcast(this.valueCast);
164     if (valueRequired){
165         // implicit conversion if necessary
166
codeStream.generateImplicitConversion(this.implicitConversion);
167     } else {
168         boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0;
169         // conversion only generated if unboxing
170
if (isUnboxing) codeStream.generateImplicitConversion(this.implicitConversion);
171         switch (isUnboxing ? postConversionType(currentScope).id : this.codegenBinding.returnType.id) {
172             case T_long :
173             case T_double :
174                 codeStream.pop2();
175                 break;
176             case T_void :
177                 break;
178             default :
179                 codeStream.pop();
180         }
181     }
182     codeStream.recordPositionsFrom(pc, (int)(this.nameSourcePosition >>> 32)); // highlight selector
183
}
184
185 /**
186  * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#genericTypeArguments()
187  */

188 public TypeBinding[] genericTypeArguments() {
189     return this.genericTypeArguments;
190 }
191
192 public boolean isSuperAccess() {
193     return this.receiver.isSuper();
194 }
195 public boolean isTypeAccess() {
196     return this.receiver != null && this.receiver.isTypeReference();
197 }
198 public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo){
199
200     if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return;
201
202     // if method from parameterized type got found, use the original method at codegen time
203
this.codegenBinding = this.binding.original();
204     if (this.binding.isPrivate()){
205
206         // depth is set for both implicit and explicit access (see MethodBinding#canBeSeenBy)
207
if (currentScope.enclosingSourceType() != this.codegenBinding.declaringClass){
208         
209             this.syntheticAccessor = ((SourceTypeBinding)this.codegenBinding.declaringClass).addSyntheticMethod(this.codegenBinding, isSuperAccess());
210             currentScope.problemReporter().needToEmulateMethodAccess(this.codegenBinding, this);
211             return;
212         }
213
214     } else if (this.receiver instanceof QualifiedSuperReference){ // qualified super
215

216         // qualified super need emulation always
217
SourceTypeBinding destinationType = (SourceTypeBinding)(((QualifiedSuperReference)this.receiver).currentCompatibleType);
218         this.syntheticAccessor = destinationType.addSyntheticMethod(this.codegenBinding, isSuperAccess());
219         currentScope.problemReporter().needToEmulateMethodAccess(this.codegenBinding, this);
220         return;
221
222     } else if (this.binding.isProtected()){
223
224         SourceTypeBinding enclosingSourceType;
225         if (((this.bits & ASTNode.DepthMASK) != 0)
226                 && this.codegenBinding.declaringClass.getPackage()
227                     != (enclosingSourceType = currentScope.enclosingSourceType()).getPackage()){
228
229             SourceTypeBinding currentCompatibleType = (SourceTypeBinding)enclosingSourceType.enclosingTypeAt((this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT);
230             this.syntheticAccessor = currentCompatibleType.addSyntheticMethod(this.codegenBinding, isSuperAccess());
231             currentScope.problemReporter().needToEmulateMethodAccess(this.codegenBinding, this);
232             return;
233         }
234     }
235     
236     // if the binding declaring class is not visible, need special action
237
// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
238
// NOTE: from target 1.2 on, method's declaring class is touched if any different from receiver type
239
// and not from Object or implicit static method call.
240
if (this.binding.declaringClass != this.actualReceiverType
241             && this.receiverGenericCast == null
242             && !this.actualReceiverType.isArrayType()) {
243         CompilerOptions options = currentScope.compilerOptions();
244         if ((options.targetJDK >= ClassFileConstants.JDK1_2
245                 && (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(this.receiver.isImplicitThis() && this.codegenBinding.isStatic()))
246                 && this.binding.declaringClass.id != TypeIds.T_JavaLangObject) // no change for Object methods
247
|| !this.binding.declaringClass.canBeSeenBy(currentScope)) {
248
249             this.codegenBinding = currentScope.enclosingSourceType().getUpdatedMethodBinding(
250                                                             this.codegenBinding, (ReferenceBinding) this.actualReceiverType.erasure());
251         }
252         // Post 1.4.0 target, array clone() invocations are qualified with array type
253
// This is handled in array type #clone method binding resolution (see Scope and UpdatedMethodBinding)
254
}
255 }
256 public int nullStatus(FlowInfo flowInfo) {
257     return FlowInfo.UNKNOWN;
258 }
259
260 /**
261  * @see org.eclipse.jdt.internal.compiler.ast.Expression#postConversionType(Scope)
262  */

263 public TypeBinding postConversionType(Scope scope) {
264     TypeBinding convertedType = this.resolvedType;
265     if (this.valueCast != null)
266         convertedType = this.valueCast;
267     int runtimeType = (this.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
268     switch (runtimeType) {
269         case T_boolean :
270             convertedType = TypeBinding.BOOLEAN;
271             break;
272         case T_byte :
273             convertedType = TypeBinding.BYTE;
274             break;
275         case T_short :
276             convertedType = TypeBinding.SHORT;
277             break;
278         case T_char :
279             convertedType = TypeBinding.CHAR;
280             break;
281         case T_int :
282             convertedType = TypeBinding.INT;
283             break;
284         case T_float :
285             convertedType = TypeBinding.FLOAT;
286             break;
287         case T_long :
288             convertedType = TypeBinding.LONG;
289             break;
290         case T_double :
291             convertedType = TypeBinding.DOUBLE;
292             break;
293         default :
294     }
295     if ((this.implicitConversion & TypeIds.BOXING) != 0) {
296         convertedType = scope.environment().computeBoxingType(convertedType);
297     }
298     return convertedType;
299 }
300     
301 public StringBuffer JavaDoc printExpression(int indent, StringBuffer JavaDoc output){
302     
303     if (!this.receiver.isImplicitThis()) this.receiver.printExpression(0, output).append('.');
304     if (this.typeArguments != null) {
305         output.append('<');
306         int max = this.typeArguments.length - 1;
307         for (int j = 0; j < max; j++) {
308             this.typeArguments[j].print(0, output);
309             output.append(", ");//$NON-NLS-1$
310
}
311         this.typeArguments[max].print(0, output);
312         output.append('>');
313     }
314     output.append(this.selector).append('(') ;
315     if (this.arguments != null) {
316         for (int i = 0; i < this.arguments.length ; i ++) {
317             if (i > 0) output.append(", "); //$NON-NLS-1$
318
this.arguments[i].printExpression(0, output);
319         }
320     }
321     return output.append(')');
322 }
323
324 public TypeBinding resolveType(BlockScope scope) {
325     // Answer the signature return type
326
// Base type promotion
327

328     this.constant = Constant.NotAConstant;
329     boolean receiverCast = false, argsContainCast = false;
330     if (this.receiver instanceof CastExpression) {
331         this.receiver.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
332
receiverCast = true;
333     }
334     this.actualReceiverType = this.receiver.resolveType(scope);
335     boolean receiverIsType = this.receiver instanceof NameReference && (((NameReference) this.receiver).bits & Binding.TYPE) != 0;
336     if (receiverCast && this.actualReceiverType != null) {
337          // due to change of declaring class with receiver type, only identity cast should be notified
338
if (((CastExpression)this.receiver).expression.resolvedType == this.actualReceiverType) {
339             scope.problemReporter().unnecessaryCast((CastExpression)this.receiver);
340         }
341     }
342     // resolve type arguments (for generic constructor call)
343
if (this.typeArguments != null) {
344         int length = this.typeArguments.length;
345         boolean argHasError = false; // typeChecks all arguments
346
this.genericTypeArguments = new TypeBinding[length];
347         for (int i = 0; i < length; i++) {
348             TypeReference typeReference = this.typeArguments[i];
349             if ((this.genericTypeArguments[i] = typeReference.resolveType(scope, true /* check bounds*/)) == null) {
350                 argHasError = true;
351             }
352             if (argHasError && typeReference instanceof Wildcard) {
353                 scope.problemReporter().illegalUsageOfWildcard(typeReference);
354             }
355         }
356         if (argHasError) {
357             return null;
358         }
359     }
360     // will check for null after args are resolved
361
TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
362     if (this.arguments != null) {
363         boolean argHasError = false; // typeChecks all arguments
364
int length = this.arguments.length;
365         argumentTypes = new TypeBinding[length];
366         for (int i = 0; i < length; i++){
367             Expression argument = this.arguments[i];
368             if (argument instanceof CastExpression) {
369                 argument.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
370
argsContainCast = true;
371             }
372             if ((argumentTypes[i] = argument.resolveType(scope)) == null){
373                 argHasError = true;
374             }
375         }
376         if (argHasError) {
377             if (this.actualReceiverType instanceof ReferenceBinding) {
378                 // record a best guess, for clients who need hint about possible method match
379
TypeBinding[] pseudoArgs = new TypeBinding[length];
380                 for (int i = length; --i >= 0;)
381                     pseudoArgs[i] = argumentTypes[i] == null ? TypeBinding.NULL : argumentTypes[i]; // replace args with errors with null type
382
this.binding =
383                     this.receiver.isImplicitThis()
384                         ? scope.getImplicitMethod(this.selector, pseudoArgs, this)
385                         : scope.findMethod((ReferenceBinding) this.actualReceiverType, this.selector, pseudoArgs, this);
386                 if (this.binding != null && !this.binding.isValidBinding()) {
387                     MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
388                     // record the closest match, for clients who may still need hint about possible method match
389
if (closestMatch != null) {
390                         if (closestMatch.original().typeVariables != Binding.NO_TYPE_VARIABLES) { // generic method
391
// shouldn't return generic method outside its context, rather convert it to raw method (175409)
392
closestMatch = scope.environment().createParameterizedGenericMethod(closestMatch.original(), (RawTypeBinding)null);
393                         }
394                         this.binding = closestMatch;
395                         MethodBinding closestMatchOriginal = closestMatch.original();
396                         if ((closestMatchOriginal.isPrivate() || closestMatchOriginal.declaringClass.isLocalType()) && !scope.isDefinedInMethod(closestMatchOriginal)) {
397                             // ignore cases where method is used from within inside itself (e.g. direct recursions)
398
closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
399                         }
400                     }
401                 }
402             }
403             return null;
404         }
405     }
406     if (this.actualReceiverType == null) {
407         return null;
408     }
409     // base type cannot receive any message
410
if (this.actualReceiverType.isBaseType()) {
411         scope.problemReporter().errorNoMethodFor(this, this.actualReceiverType, argumentTypes);
412         return null;
413     }
414     this.binding =
415         this.receiver.isImplicitThis()
416             ? scope.getImplicitMethod(this.selector, argumentTypes, this)
417             : scope.getMethod(this.actualReceiverType, this.selector, argumentTypes, this);
418     if (!this.binding.isValidBinding()) {
419         if (this.binding.declaringClass == null) {
420             if (this.actualReceiverType instanceof ReferenceBinding) {
421                 this.binding.declaringClass = (ReferenceBinding) this.actualReceiverType;
422             } else {
423                 scope.problemReporter().errorNoMethodFor(this, this.actualReceiverType, argumentTypes);
424                 return null;
425             }
426         }
427         scope.problemReporter().invalidMethod(this, this.binding);
428         MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
429         switch (this.binding.problemId()) {
430             case ProblemReasons.Ambiguous :
431                 break; // no resilience on ambiguous
432
case ProblemReasons.NotVisible :
433             case ProblemReasons.NonStaticReferenceInConstructorInvocation :
434             case ProblemReasons.NonStaticReferenceInStaticContext :
435             case ProblemReasons.ReceiverTypeNotVisible :
436             case ProblemReasons.ParameterBoundMismatch :
437                 // only steal returnType in cases listed above
438
if (closestMatch != null) this.resolvedType = closestMatch.returnType;
439             default :
440         }
441         // record the closest match, for clients who may still need hint about possible method match
442
if (closestMatch != null) {
443             this.binding = closestMatch;
444             MethodBinding closestMatchOriginal = closestMatch.original();
445             if ((closestMatchOriginal.isPrivate() || closestMatchOriginal.declaringClass.isLocalType()) && !scope.isDefinedInMethod(closestMatchOriginal)) {
446                 // ignore cases where method is used from within inside itself (e.g. direct recursions)
447
closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
448             }
449         }
450         return this.resolvedType;
451     }
452     final CompilerOptions compilerOptions = scope.compilerOptions();
453     if (!this.binding.isStatic()) {
454         // the "receiver" must not be a type, in other words, a NameReference that the TC has bound to a Type
455
if (receiverIsType) {
456             scope.problemReporter().mustUseAStaticMethod(this, this.binding);
457             if (this.actualReceiverType.isRawType()
458                     && (this.receiver.bits & ASTNode.IgnoreRawTypeCheck) == 0
459                     && compilerOptions.getSeverity(CompilerOptions.RawTypeReference) != ProblemSeverities.Ignore) {
460                 scope.problemReporter().rawTypeReference(this.receiver, this.actualReceiverType);
461             }
462         } else {
463             this.receiver.computeConversion(scope, this.actualReceiverType, this.actualReceiverType);
464             // compute generic cast if necessary
465
TypeBinding receiverErasure = this.actualReceiverType.erasure();
466             if (receiverErasure instanceof ReferenceBinding) {
467                 if (receiverErasure.findSuperTypeWithSameErasure(this.binding.declaringClass) == null) {
468                     this.receiverGenericCast = this.binding.declaringClass; // handle indirect inheritance thru variable secondary bound
469
}
470             }
471         }
472     } else {
473         // static message invoked through receiver? legal but unoptimal (optional warning).
474
if (!(this.receiver.isImplicitThis() || this.receiver.isSuper() || receiverIsType)) {
475             scope.problemReporter().nonStaticAccessToStaticMethod(this, this.binding);
476         }
477         if (!this.receiver.isImplicitThis() && this.binding.declaringClass != this.actualReceiverType) {
478             scope.problemReporter().indirectAccessToStaticMethod(this, this.binding);
479         }
480     }
481     checkInvocationArguments(scope, this.receiver, this.actualReceiverType, this.binding, this.arguments, argumentTypes, argsContainCast, this);
482
483     //-------message send that are known to fail at compile time-----------
484
if (this.binding.isAbstract()) {
485         if (this.receiver.isSuper()) {
486             scope.problemReporter().cannotDireclyInvokeAbstractMethod(this, this.binding);
487         }
488         // abstract private methods cannot occur nor abstract static............
489
}
490     if (isMethodUseDeprecated(this.binding, scope, true))
491         scope.problemReporter().deprecatedMethod(this.binding, this);
492
493     // from 1.5 compliance on, array#clone() returns the array type (but binding still shows Object)
494
if (this.actualReceiverType.isArrayType()
495             && this.binding.parameters == Binding.NO_PARAMETERS
496             && compilerOptions.complianceLevel >= ClassFileConstants.JDK1_5
497             && CharOperation.equals(this.binding.selector, TypeConstants.CLONE)) {
498         this.resolvedType = this.actualReceiverType;
499     } else {
500         TypeBinding returnType = this.binding.returnType;
501         if (returnType != null) returnType = returnType.capture(scope, this.sourceEnd);
502         this.resolvedType = returnType;
503     }
504     if (this.receiver.isSuper() && compilerOptions.getSeverity(CompilerOptions.OverridingMethodWithoutSuperInvocation) != ProblemSeverities.Ignore) {
505         final ReferenceContext referenceContext = scope.methodScope().referenceContext;
506         if (referenceContext instanceof AbstractMethodDeclaration) {
507             final AbstractMethodDeclaration abstractMethodDeclaration = (AbstractMethodDeclaration) referenceContext;
508             MethodBinding enclosingMethodBinding = abstractMethodDeclaration.binding;
509             if (enclosingMethodBinding.isOverriding()
510                     && CharOperation.equals(this.binding.selector, enclosingMethodBinding.selector)
511                     && this.binding.areParametersEqual(enclosingMethodBinding)) {
512                 abstractMethodDeclaration.bits |= ASTNode.OverridingMethodWithSupercall;
513             }
514         }
515     }
516     return this.resolvedType;
517 }
518
519 public void setActualReceiverType(ReferenceBinding receiverType) {
520     if (receiverType == null) return; // error scenario only
521
this.actualReceiverType = receiverType;
522 }
523 public void setDepth(int depth) {
524     this.bits &= ~ASTNode.DepthMASK; // flush previous depth if any
525
if (depth > 0) {
526         this.bits |= (depth & 0xFF) << ASTNode.DepthSHIFT; // encoded on 8 bits
527
}
528 }
529
530 /**
531  * @see org.eclipse.jdt.internal.compiler.ast.Expression#setExpectedType(org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
532  */

533 public void setExpectedType(TypeBinding expectedType) {
534     this.expectedType = expectedType;
535 }
536 public void setFieldIndex(int depth) {
537     // ignore for here
538
}
539
540 public void traverse(ASTVisitor visitor, BlockScope blockScope) {
541     if (visitor.visit(this, blockScope)) {
542         this.receiver.traverse(visitor, blockScope);
543         if (this.typeArguments != null) {
544             for (int i = 0, typeArgumentsLength = this.typeArguments.length; i < typeArgumentsLength; i++) {
545                 this.typeArguments[i].traverse(visitor, blockScope);
546             }
547         }
548         if (this.arguments != null) {
549             int argumentsLength = this.arguments.length;
550             for (int i = 0; i < argumentsLength; i++)
551                 this.arguments[i].traverse(visitor, blockScope);
552         }
553     }
554     visitor.endVisit(this, blockScope);
555 }
556 }
557
Popular Tags