KickJava   Java API By Example, From Geeks To Geeks.

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


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  *******************************************************************************/

11 package org.eclipse.jdt.internal.compiler.ast;
12
13 import org.eclipse.jdt.core.compiler.CharOperation;
14 import org.eclipse.jdt.internal.compiler.ASTVisitor;
15 import org.eclipse.jdt.internal.compiler.impl.Constant;
16 import org.eclipse.jdt.internal.compiler.lookup.*;
17
18
19 public class JavadocMessageSend extends MessageSend {
20
21     public int tagSourceStart, tagSourceEnd;
22     public int tagValue;
23
24     public JavadocMessageSend(char[] name, long pos) {
25         this.selector = name;
26         this.nameSourcePosition = pos;
27         this.sourceStart = (int) (this.nameSourcePosition >>> 32);
28         this.sourceEnd = (int) this.nameSourcePosition;
29         this.bits |= InsideJavadoc;
30     }
31     public JavadocMessageSend(char[] name, long pos, JavadocArgumentExpression[] arguments) {
32         this(name, pos);
33         this.arguments = arguments;
34     }
35
36     /*
37      * Resolves type on a Block or Class scope.
38      */

39     private TypeBinding internalResolveType(Scope scope) {
40         // Answer the signature return type
41
// Base type promotion
42
this.constant = Constant.NotAConstant;
43         if (this.receiver == null) {
44             this.actualReceiverType = scope.enclosingSourceType();
45         } else if (scope.kind == Scope.CLASS_SCOPE) {
46             this.actualReceiverType = this.receiver.resolveType((ClassScope) scope);
47         } else {
48             this.actualReceiverType = this.receiver.resolveType((BlockScope) scope);
49         }
50
51         // will check for null after args are resolved
52

53         TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
54         boolean hasArgsTypeVar = false;
55         if (this.arguments != null) {
56             boolean argHasError = false; // typeChecks all arguments
57
int length = this.arguments.length;
58             argumentTypes = new TypeBinding[length];
59             for (int i = 0; i < length; i++){
60                 Expression argument = this.arguments[i];
61                 if (scope.kind == Scope.CLASS_SCOPE) {
62                     argumentTypes[i] = argument.resolveType((ClassScope)scope);
63                 } else {
64                     argumentTypes[i] = argument.resolveType((BlockScope)scope);
65                 }
66                 if (argumentTypes[i] == null) {
67                     argHasError = true;
68                 } else if (!hasArgsTypeVar) {
69                     hasArgsTypeVar = argumentTypes[i].isTypeVariable();
70                 }
71             }
72             if (argHasError) {
73                 return null;
74             }
75         }
76
77         // check receiver type
78
if (this.actualReceiverType == null) {
79             return null;
80         }
81         this.actualReceiverType = scope.environment().convertToRawType(this.receiver.resolvedType);
82         SourceTypeBinding enclosingType = scope.enclosingSourceType();
83         if (enclosingType==null ? false : enclosingType.isCompatibleWith(this.actualReceiverType)) {
84             this.bits |= ASTNode.SuperAccess;
85         }
86
87         // base type cannot receive any message
88
if (this.actualReceiverType.isBaseType()) {
89             scope.problemReporter().javadocErrorNoMethodFor(this, this.actualReceiverType, argumentTypes, scope.getDeclarationModifiers());
90             return null;
91         }
92         this.binding = scope.getMethod(this.actualReceiverType, this.selector, argumentTypes, this);
93         if (!this.binding.isValidBinding()) {
94             // Try method in enclosing types
95
TypeBinding enclosingTypeBinding = this.actualReceiverType;
96             MethodBinding methodBinding = this.binding;
97             while (!methodBinding.isValidBinding() && (enclosingTypeBinding.isMemberType() || enclosingTypeBinding.isLocalType())) {
98                 enclosingTypeBinding = enclosingTypeBinding.enclosingType();
99                 methodBinding = scope.getMethod(enclosingTypeBinding, this.selector, argumentTypes, this);
100             }
101             if (methodBinding.isValidBinding()) {
102                 this.binding = methodBinding;
103             } else {
104                 // Try to search a constructor instead
105
enclosingTypeBinding = this.actualReceiverType;
106                 MethodBinding contructorBinding = this.binding;
107                 while (!contructorBinding.isValidBinding() && (enclosingTypeBinding.isMemberType() || enclosingTypeBinding.isLocalType())) {
108                     enclosingTypeBinding = enclosingTypeBinding.enclosingType();
109                     if (CharOperation.equals(this.selector, enclosingTypeBinding.shortReadableName())) {
110                         contructorBinding = scope.getConstructor((ReferenceBinding)enclosingTypeBinding, argumentTypes, this);
111                     }
112                 }
113                 if (contructorBinding.isValidBinding()) {
114                     this.binding = contructorBinding;
115                 }
116             }
117         }
118         if (!this.binding.isValidBinding()) {
119             // implicit lookup may discover issues due to static/constructor contexts. javadoc must be resilient
120
switch (this.binding.problemId()) {
121                 case ProblemReasons.NonStaticReferenceInConstructorInvocation:
122                 case ProblemReasons.NonStaticReferenceInStaticContext:
123                 case ProblemReasons.InheritedNameHidesEnclosingName :
124                 case ProblemReasons.Ambiguous:
125                     MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
126                     if (closestMatch != null) {
127                         this.binding = closestMatch; // ignore problem if can reach target method through it
128
}
129             }
130         }
131         if (!this.binding.isValidBinding()) {
132             if (this.binding.declaringClass == null) {
133                 if (this.actualReceiverType instanceof ReferenceBinding) {
134                     this.binding.declaringClass = (ReferenceBinding) this.actualReceiverType;
135                 } else {
136                     scope.problemReporter().javadocErrorNoMethodFor(this, this.actualReceiverType, argumentTypes, scope.getDeclarationModifiers());
137                     return null;
138                 }
139             }
140             scope.problemReporter().javadocInvalidMethod(this, this.binding, scope.getDeclarationModifiers());
141             // record the closest match, for clients who may still need hint about possible method match
142
if (this.binding instanceof ProblemMethodBinding) {
143                 MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
144                 if (closestMatch != null) this.binding = closestMatch;
145             }
146             return this.resolvedType = this.binding == null ? null : this.binding.returnType;
147         } else if (hasArgsTypeVar) {
148             MethodBinding problem = new ProblemMethodBinding(this.binding, this.selector, argumentTypes, ProblemReasons.NotFound);
149             scope.problemReporter().javadocInvalidMethod(this, problem, scope.getDeclarationModifiers());
150         } else if (binding.isVarargs()) {
151             int length = argumentTypes.length;
152             if (!(binding.parameters.length == length && argumentTypes[length-1].isArrayType())) {
153                 MethodBinding problem = new ProblemMethodBinding(this.binding, this.selector, argumentTypes, ProblemReasons.NotFound);
154                 scope.problemReporter().javadocInvalidMethod(this, problem, scope.getDeclarationModifiers());
155             }
156         } else {
157             int length = argumentTypes.length;
158             for (int i=0; i<length; i++) {
159                 if (this.binding.parameters[i].erasure() != argumentTypes[i].erasure()) {
160                     MethodBinding problem = new ProblemMethodBinding(this.binding, this.selector, argumentTypes, ProblemReasons.NotFound);
161                     scope.problemReporter().javadocInvalidMethod(this, problem, scope.getDeclarationModifiers());
162                     break;
163                 }
164             }
165         }
166         if (isMethodUseDeprecated(this.binding, scope, true)) {
167             scope.problemReporter().javadocDeprecatedMethod(this.binding, this, scope.getDeclarationModifiers());
168         }
169
170         return this.resolvedType = this.binding.returnType;
171     }
172     
173     /* (non-Javadoc)
174      * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#isSuperAccess()
175      */

176     public boolean isSuperAccess() {
177         return (this.bits & ASTNode.SuperAccess) != 0;
178     }
179
180     public StringBuffer JavaDoc printExpression(int indent, StringBuffer JavaDoc output){
181     
182         if (this.receiver != null) {
183             this.receiver.printExpression(0, output);
184         }
185         output.append('#').append(this.selector).append('(');
186         if (this.arguments != null) {
187             for (int i = 0; i < this.arguments.length ; i ++) {
188                 if (i > 0) output.append(", "); //$NON-NLS-1$
189
this.arguments[i].printExpression(0, output);
190             }
191         }
192         return output.append(')');
193     }
194
195     public TypeBinding resolveType(BlockScope scope) {
196         return internalResolveType(scope);
197     }
198
199     public TypeBinding resolveType(ClassScope scope) {
200         return internalResolveType(scope);
201     }
202
203     /* (non-Javadoc)
204      * Redefine to capture javadoc specific signatures
205      * @see org.eclipse.jdt.internal.compiler.ast.ASTNode#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
206      */

207     public void traverse(ASTVisitor visitor, BlockScope blockScope) {
208         if (visitor.visit(this, blockScope)) {
209             if (this.receiver != null) {
210                 this.receiver.traverse(visitor, blockScope);
211             }
212             if (this.arguments != null) {
213                 int argumentsLength = this.arguments.length;
214                 for (int i = 0; i < argumentsLength; i++)
215                     this.arguments[i].traverse(visitor, blockScope);
216             }
217         }
218         visitor.endVisit(this, blockScope);
219     }
220     /* (non-Javadoc)
221      * Redefine to capture javadoc specific signatures
222      * @see org.eclipse.jdt.internal.compiler.ast.ASTNode#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
223      */

224     public void traverse(ASTVisitor visitor, ClassScope scope) {
225         if (visitor.visit(this, scope)) {
226             if (this.receiver != null) {
227                 this.receiver.traverse(visitor, scope);
228             }
229             if (this.arguments != null) {
230                 int argumentsLength = this.arguments.length;
231                 for (int i = 0; i < argumentsLength; i++)
232                     this.arguments[i].traverse(visitor, scope);
233             }
234         }
235         visitor.endVisit(this, scope);
236     }
237 }
238
Popular Tags