KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > codeassist > complete > CompletionJavadoc


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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.codeassist.complete;
12
13 import org.eclipse.jdt.internal.compiler.ast.*;
14 import org.eclipse.jdt.internal.compiler.lookup.*;
15
16 /**
17  * Node representing a Javadoc comment including code selection.
18  */

19 public class CompletionJavadoc extends Javadoc {
20
21     Expression completionNode;
22
23     public CompletionJavadoc(int sourceStart, int sourceEnd) {
24         super(sourceStart, sourceEnd);
25     }
26
27     /**
28      * @return Returns the completionNode.
29      */

30     public Expression getCompletionNode() {
31         return this.completionNode;
32     }
33
34     /**
35      * Resolve selected node if not null and throw exception to let clients know
36      * that it has been found.
37      *
38      * @throws CompletionNodeFound
39      */

40     private void internalResolve(Scope scope) {
41         if (this.completionNode != null) {
42             if (this.completionNode instanceof CompletionOnJavadocTag) {
43                 ((CompletionOnJavadocTag)this.completionNode).filterPossibleTags(scope);
44             } else {
45                 boolean resolve = true;
46                 if (this.completionNode instanceof CompletionOnJavadocParamNameReference) {
47                     resolve = ((CompletionOnJavadocParamNameReference)this.completionNode).token != null;
48                 } else if (this.completionNode instanceof CompletionOnJavadocTypeParamReference) {
49                     resolve = ((CompletionOnJavadocTypeParamReference)this.completionNode).token != null;
50                 }
51                 if (resolve) {
52                     switch (scope.kind) {
53                         case Scope.CLASS_SCOPE:
54                             this.completionNode.resolveType((ClassScope)scope);
55                             break;
56                         case Scope.METHOD_SCOPE:
57                             this.completionNode.resolveType((MethodScope) scope);
58                             break;
59                     }
60                 }
61                 if (this.completionNode instanceof CompletionOnJavadocParamNameReference) {
62                     CompletionOnJavadocParamNameReference paramNameReference = (CompletionOnJavadocParamNameReference) this.completionNode;
63                     if (scope.kind == Scope.METHOD_SCOPE) {
64                         paramNameReference.missingParams = missingParamTags(paramNameReference.binding, (MethodScope)scope);
65                     }
66                     if (paramNameReference.token == null || paramNameReference.token.length == 0) {
67                         paramNameReference.missingTypeParams = missingTypeParameterTags(paramNameReference.binding, scope);
68                     }
69                 } else if (this.completionNode instanceof CompletionOnJavadocTypeParamReference) {
70                     CompletionOnJavadocTypeParamReference typeParamReference = (CompletionOnJavadocTypeParamReference) this.completionNode;
71                     typeParamReference.missingParams = missingTypeParameterTags(typeParamReference.resolvedType, scope);
72                 }
73             }
74             Binding qualifiedBinding = null;
75             if (this.completionNode instanceof CompletionOnJavadocQualifiedTypeReference) {
76                 CompletionOnJavadocQualifiedTypeReference typeRef = (CompletionOnJavadocQualifiedTypeReference) this.completionNode;
77                 if (typeRef.packageBinding == null) {
78                     qualifiedBinding = typeRef.resolvedType;
79                 } else {
80                     qualifiedBinding = typeRef.packageBinding;
81                 }
82             } else if (this.completionNode instanceof CompletionOnJavadocMessageSend) {
83                 CompletionOnJavadocMessageSend msg = (CompletionOnJavadocMessageSend) this.completionNode;
84                 if (!msg.receiver.isThis()) qualifiedBinding = msg.receiver.resolvedType;
85             } else if (this.completionNode instanceof CompletionOnJavadocAllocationExpression) {
86                 CompletionOnJavadocAllocationExpression alloc = (CompletionOnJavadocAllocationExpression) this.completionNode;
87                 qualifiedBinding = alloc.type.resolvedType;
88             }
89             throw new CompletionNodeFound(this.completionNode, qualifiedBinding, scope);
90         }
91     }
92     
93     /*
94      * @see org.eclipse.jdt.internal.compiler.ast.ASTNode#print(int, java.lang.StringBuffer)
95      */

96     public StringBuffer JavaDoc print(int indent, StringBuffer JavaDoc output) {
97         printIndent(indent, output).append("/**\n"); //$NON-NLS-1$
98
boolean nodePrinted = false;
99         if (this.paramReferences != null) {
100             for (int i = 0, length = this.paramReferences.length; i < length; i++) {
101                 printIndent(indent, output).append(" * @param "); //$NON-NLS-1$
102
this.paramReferences[i].print(indent, output).append('\n');
103                 if (!nodePrinted && this.completionNode != null) {
104                     nodePrinted = this.completionNode == this.paramReferences[i];
105                 }
106             }
107         }
108         if (this.paramTypeParameters != null) {
109             for (int i = 0, length = this.paramTypeParameters.length; i < length; i++) {
110                 printIndent(indent, output).append(" * @param <"); //$NON-NLS-1$
111
this.paramTypeParameters[i].print(indent, output).append(">\n"); //$NON-NLS-1$
112
if (!nodePrinted && this.completionNode != null) {
113                     nodePrinted = this.completionNode == this.paramTypeParameters[i];
114                 }
115             }
116         }
117         if (this.returnStatement != null) {
118             printIndent(indent, output).append(" * @"); //$NON-NLS-1$
119
this.returnStatement.print(indent, output).append('\n');
120         }
121         if (this.exceptionReferences != null) {
122             for (int i = 0, length = this.exceptionReferences.length; i < length; i++) {
123                 printIndent(indent, output).append(" * @throws "); //$NON-NLS-1$
124
this.exceptionReferences[i].print(indent, output).append('\n');
125                 if (!nodePrinted && this.completionNode != null) {
126                     nodePrinted = this.completionNode == this.exceptionReferences[i];
127                 }
128             }
129         }
130         if (this.seeReferences != null) {
131             for (int i = 0, length = this.seeReferences.length; i < length; i++) {
132                 printIndent(indent, output).append(" * @see "); //$NON-NLS-1$
133
this.seeReferences[i].print(indent, output).append('\n');
134                 if (!nodePrinted && this.completionNode != null) {
135                     nodePrinted = this.completionNode == this.seeReferences[i];
136                 }
137             }
138         }
139         if (!nodePrinted && this.completionNode != null) {
140             printIndent(indent, output).append(" * "); //$NON-NLS-1$
141
this.completionNode.print(indent, output).append('\n');
142         }
143         printIndent(indent, output).append(" */\n"); //$NON-NLS-1$
144
return output;
145     }
146
147     /**
148      * Resolve completion node if not null and throw exception to let clients know
149      * that it has been found.
150      *
151      * @throws CompletionNodeFound
152      */

153     public void resolve(ClassScope scope) {
154         super.resolve(scope);
155         internalResolve(scope);
156     }
157
158     /**
159      * Resolve completion node if not null and throw exception to let clients know
160      * that it has been found.
161      *
162      * @throws CompletionNodeFound
163      */

164     public void resolve(CompilationUnitScope scope) {
165         internalResolve(scope);
166     }
167
168     /**
169      * Resolve completion node if not null and throw exception to let clients know
170      * that it has been found.
171      *
172      * @throws CompletionNodeFound
173      */

174     public void resolve(MethodScope scope) {
175         super.resolve(scope);
176         internalResolve(scope);
177     }
178
179     /*
180      * Look for missing method @param tags
181      */

182     private char[][] missingParamTags(Binding paramNameRefBinding, MethodScope methScope) {
183
184         // Verify if there's some possible param tag
185
AbstractMethodDeclaration md = methScope.referenceMethod();
186         int paramTagsSize = this.paramReferences == null ? 0 : this.paramReferences.length;
187         if (md == null) return null;
188         int argumentsSize = md.arguments == null ? 0 : md.arguments.length;
189         if (argumentsSize == 0) return null;
190         
191         // Store all method arguments if there's no @param in javadoc
192
if (paramTagsSize == 0) {
193             char[][] missingParams = new char[argumentsSize][];
194             for (int i = 0; i < argumentsSize; i++) {
195                 missingParams[i] = md.arguments[i].name;
196             }
197             return missingParams;
198         }
199
200         // Look for missing arguments
201
char[][] missingParams = new char[argumentsSize][];
202         int size = 0;
203         for (int i = 0; i < argumentsSize; i++) {
204             Argument arg = md.arguments[i];
205             boolean found = false;
206             int paramNameRefCount = 0;
207             for (int j = 0; j < paramTagsSize && !found; j++) {
208                 JavadocSingleNameReference param = this.paramReferences[j];
209                 if (arg.binding == param.binding) {
210                     if (param.binding == paramNameRefBinding) { // do not count first occurence of param name reference
211
paramNameRefCount++;
212                         found = paramNameRefCount > 1;
213                     } else {
214                         found = true;
215                     }
216                 }
217             }
218             if (!found) {
219                 missingParams[size++] = arg.name;
220             }
221         }
222         if (size > 0) {
223             if (size != argumentsSize) {
224                 System.arraycopy(missingParams, 0, missingParams = new char[size][], 0, size);
225             }
226             return missingParams;
227         }
228         return null;
229     }
230
231     /*
232      * Look for missing type parameters @param tags
233      */

234     private char[][] missingTypeParameterTags(Binding paramNameRefBinding, Scope scope) {
235         int paramTypeParamLength = this.paramTypeParameters == null ? 0 : this.paramTypeParameters.length;
236
237         // Verify if there's any type parameter to tag
238
TypeParameter[] parameters = null;
239         TypeVariableBinding[] typeVariables = null;
240         switch (scope.kind) {
241             case Scope.METHOD_SCOPE:
242                 AbstractMethodDeclaration methodDeclaration = ((MethodScope)scope).referenceMethod();
243                 if (methodDeclaration == null) return null;
244                 parameters = methodDeclaration.typeParameters();
245                 typeVariables = methodDeclaration.binding.typeVariables;
246                 break;
247             case Scope.CLASS_SCOPE:
248                 TypeDeclaration typeDeclaration = ((ClassScope) scope).referenceContext;
249                 parameters = typeDeclaration.typeParameters;
250                 typeVariables = typeDeclaration.binding.typeVariables;
251                 break;
252         }
253         if (typeVariables == null || typeVariables.length == 0) return null;
254         
255         // Store all type parameters if there's no @param in javadoc
256
if (parameters != null) {
257             int typeParametersLength = parameters.length;
258             if (paramTypeParamLength == 0) {
259                 char[][] missingParams = new char[typeParametersLength][];
260                 for (int i = 0; i < typeParametersLength; i++) {
261                     missingParams[i] = parameters[i].name;
262                 }
263                 return missingParams;
264             }
265
266             // Look for missing type parameter
267
char[][] missingParams = new char[typeParametersLength][];
268             int size = 0;
269             for (int i = 0; i < typeParametersLength; i++) {
270                 TypeParameter parameter = parameters[i];
271                 boolean found = false;
272                 int paramNameRefCount = 0;
273                 for (int j = 0; j < paramTypeParamLength && !found; j++) {
274                     if (parameter.binding == this.paramTypeParameters[j].resolvedType) {
275                         if (parameter.binding == paramNameRefBinding) { // do not count first occurence of param nmae reference
276
paramNameRefCount++;
277                             found = paramNameRefCount > 1;
278                         } else {
279                             found = true;
280                         }
281                     }
282                 }
283                 if (!found) {
284                     missingParams[size++] = parameter.name;
285                 }
286             }
287             if (size > 0) {
288                 if (size != typeParametersLength) {
289                     System.arraycopy(missingParams, 0, missingParams = new char[size][], 0, size);
290                 }
291                 return missingParams;
292             }
293         }
294         return null;
295     }
296 }
297
Popular Tags