KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > text > correction > JavadocTagsSubProcessor


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.ui.text.correction;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Collection JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Set JavaDoc;
18
19 import org.eclipse.text.edits.InsertEdit;
20 import org.eclipse.text.edits.TextEdit;
21 import org.eclipse.text.edits.TextEditGroup;
22
23 import org.eclipse.core.runtime.Assert;
24 import org.eclipse.core.runtime.CoreException;
25 import org.eclipse.core.runtime.IStatus;
26
27 import org.eclipse.swt.graphics.Image;
28
29 import org.eclipse.jface.text.BadLocationException;
30 import org.eclipse.jface.text.IDocument;
31 import org.eclipse.jface.text.IRegion;
32 import org.eclipse.jface.text.TextUtilities;
33
34 import org.eclipse.ui.ISharedImages;
35
36 import org.eclipse.jdt.core.ICompilationUnit;
37 import org.eclipse.jdt.core.IJavaProject;
38 import org.eclipse.jdt.core.dom.AST;
39 import org.eclipse.jdt.core.dom.ASTNode;
40 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
41 import org.eclipse.jdt.core.dom.BodyDeclaration;
42 import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
43 import org.eclipse.jdt.core.dom.FieldDeclaration;
44 import org.eclipse.jdt.core.dom.IMethodBinding;
45 import org.eclipse.jdt.core.dom.ITypeBinding;
46 import org.eclipse.jdt.core.dom.Javadoc;
47 import org.eclipse.jdt.core.dom.MethodDeclaration;
48 import org.eclipse.jdt.core.dom.Name;
49 import org.eclipse.jdt.core.dom.PrimitiveType;
50 import org.eclipse.jdt.core.dom.SimpleName;
51 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
52 import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
53 import org.eclipse.jdt.core.dom.TagElement;
54 import org.eclipse.jdt.core.dom.TextElement;
55 import org.eclipse.jdt.core.dom.Type;
56 import org.eclipse.jdt.core.dom.TypeDeclaration;
57 import org.eclipse.jdt.core.dom.TypeParameter;
58 import org.eclipse.jdt.core.dom.VariableDeclaration;
59 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
60 import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
61
62 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
63 import org.eclipse.jdt.internal.corext.dom.Bindings;
64 import org.eclipse.jdt.internal.corext.util.Strings;
65
66 import org.eclipse.jdt.ui.CodeGeneration;
67 import org.eclipse.jdt.ui.text.java.IInvocationContext;
68 import org.eclipse.jdt.ui.text.java.IProblemLocation;
69
70 import org.eclipse.jdt.internal.ui.JavaPlugin;
71 import org.eclipse.jdt.internal.ui.JavaPluginImages;
72 import org.eclipse.jdt.internal.ui.JavaUIStatus;
73
74 /**
75  *
76  */

77 public class JavadocTagsSubProcessor {
78
79     private static final class AddJavadocCommentProposal extends CUCorrectionProposal {
80
81         private final int fInsertPosition;
82         private final String JavaDoc fComment;
83
84         private AddJavadocCommentProposal(String JavaDoc name, ICompilationUnit cu, int relevance, int insertPosition, String JavaDoc comment) {
85             super(name, cu, relevance, JavaPluginImages.get(JavaPluginImages.IMG_OBJS_JAVADOCTAG));
86             fInsertPosition= insertPosition;
87             fComment= comment;
88         }
89
90         protected void addEdits(IDocument document, TextEdit rootEdit) throws CoreException {
91             try {
92                 String JavaDoc lineDelimiter= TextUtilities.getDefaultLineDelimiter(document);
93                 final IJavaProject project= getCompilationUnit().getJavaProject();
94                 IRegion region= document.getLineInformationOfOffset(fInsertPosition);
95
96                 String JavaDoc lineContent= document.get(region.getOffset(), region.getLength());
97                 String JavaDoc indentString= Strings.getIndentString(lineContent, project);
98                 String JavaDoc str= Strings.changeIndent(fComment, 0, project, indentString, lineDelimiter);
99                 InsertEdit edit= new InsertEdit(fInsertPosition, str);
100                 rootEdit.addChild(edit);
101                 if (fComment.charAt(fComment.length() - 1) != '\n') {
102                     rootEdit.addChild(new InsertEdit(fInsertPosition, lineDelimiter));
103                     rootEdit.addChild(new InsertEdit(fInsertPosition, indentString));
104                 }
105             } catch (BadLocationException e) {
106                 throw new CoreException(JavaUIStatus.createError(IStatus.ERROR, e));
107             }
108         }
109     }
110
111     private static final class AddMissingJavadocTagProposal extends LinkedCorrectionProposal {
112
113         private final BodyDeclaration fBodyDecl; // MethodDecl or TypeDecl
114
private final ASTNode fMissingNode;
115
116         public AddMissingJavadocTagProposal(String JavaDoc label, ICompilationUnit cu, BodyDeclaration methodDecl, ASTNode missingNode, int relevance) {
117             super(label, cu, null, relevance, JavaPluginImages.get(JavaPluginImages.IMG_OBJS_JAVADOCTAG));
118             fBodyDecl= methodDecl;
119             fMissingNode= missingNode;
120         }
121
122         protected ASTRewrite getRewrite() throws CoreException {
123             AST ast= fBodyDecl.getAST();
124             ASTRewrite rewrite= ASTRewrite.create(ast);
125             insertMissingJavadocTag(rewrite, fMissingNode, fBodyDecl);
126             return rewrite;
127         }
128
129         private void insertMissingJavadocTag(ASTRewrite rewrite, ASTNode missingNode, BodyDeclaration bodyDecl) {
130             AST ast= bodyDecl.getAST();
131             Javadoc javadoc= bodyDecl.getJavadoc();
132             ListRewrite tagsRewriter= rewrite.getListRewrite(javadoc, Javadoc.TAGS_PROPERTY);
133
134             StructuralPropertyDescriptor location= missingNode.getLocationInParent();
135             TagElement newTag;
136             if (location == SingleVariableDeclaration.NAME_PROPERTY) {
137                 // normal parameter
138
SingleVariableDeclaration decl= (SingleVariableDeclaration) missingNode.getParent();
139
140                 String JavaDoc name= ((SimpleName) missingNode).getIdentifier();
141                 newTag= ast.newTagElement();
142                 newTag.setTagName(TagElement.TAG_PARAM);
143                 List JavaDoc fragments= newTag.fragments();
144                 fragments.add(ast.newSimpleName(name));
145
146                 MethodDeclaration methodDeclaration= (MethodDeclaration) bodyDecl;
147                 List JavaDoc params= methodDeclaration.parameters();
148
149                 Set JavaDoc sameKindLeadingNames= getPreviousParamNames(params, decl);
150
151                 List JavaDoc typeParams= methodDeclaration.typeParameters();
152                 for (int i= 0; i < typeParams.size(); i++) {
153                     String JavaDoc curr= '<' + ((TypeParameter) typeParams.get(i)).getName().getIdentifier() + '>';
154                     sameKindLeadingNames.add(curr);
155                 }
156                 insertTag(tagsRewriter, newTag, sameKindLeadingNames);
157             } else if (location == TypeParameter.NAME_PROPERTY) {
158                 // type parameter
159
TypeParameter typeParam= (TypeParameter) missingNode.getParent();
160
161                 String JavaDoc name= '<' + ((SimpleName) missingNode).getIdentifier() + '>';
162                 newTag= ast.newTagElement();
163                 newTag.setTagName(TagElement.TAG_PARAM);
164                 TextElement text= ast.newTextElement();
165                 text.setText(name);
166                 newTag.fragments().add(text);
167                 List JavaDoc params;
168                 if (bodyDecl instanceof TypeDeclaration) {
169                     params= ((TypeDeclaration) bodyDecl).typeParameters();
170                 } else {
171                     params= ((MethodDeclaration) bodyDecl).typeParameters();
172                 }
173                 insertTag(tagsRewriter, newTag, getPreviousTypeParamNames(params, typeParam));
174             } else if (location == MethodDeclaration.RETURN_TYPE2_PROPERTY) {
175                 newTag= ast.newTagElement();
176                 newTag.setTagName(TagElement.TAG_RETURN);
177                 insertTag(tagsRewriter, newTag, null);
178             } else if (location == MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY) {
179                 newTag= ast.newTagElement();
180                 newTag.setTagName(TagElement.TAG_THROWS);
181                 TextElement excNode= ast.newTextElement();
182                 excNode.setText(ASTNodes.asString(missingNode));
183                 newTag.fragments().add(excNode);
184                 List JavaDoc exceptions= ((MethodDeclaration) bodyDecl).thrownExceptions();
185                 insertTag(tagsRewriter, newTag, getPreviousExceptionNames(exceptions, missingNode));
186             } else {
187                 Assert.isTrue(false, "AddMissingJavadocTagProposal: unexpected node location"); //$NON-NLS-1$
188
return;
189             }
190
191             TextElement textElement= ast.newTextElement();
192             textElement.setText(""); //$NON-NLS-1$
193
newTag.fragments().add(textElement);
194             addLinkedPosition(rewrite.track(textElement), false, "comment_start"); //$NON-NLS-1$
195
}
196     }
197
198     private static final class AddAllMissingJavadocTagsProposal extends LinkedCorrectionProposal {
199
200         private final BodyDeclaration fBodyDecl;
201
202         public AddAllMissingJavadocTagsProposal(String JavaDoc label, ICompilationUnit cu, BodyDeclaration bodyDecl, int relevance) {
203             super(label, cu, null, relevance, JavaPluginImages.get(JavaPluginImages.IMG_OBJS_JAVADOCTAG));
204             fBodyDecl= bodyDecl;
205         }
206
207         protected ASTRewrite getRewrite() throws CoreException {
208             ASTRewrite rewrite= ASTRewrite.create(fBodyDecl.getAST());
209             if (fBodyDecl instanceof MethodDeclaration) {
210                 insertAllMissingMethodTags(rewrite, (MethodDeclaration) fBodyDecl);
211             } else {
212                 insertAllMissingTypeTags(rewrite, (TypeDeclaration) fBodyDecl);
213             }
214             return rewrite;
215         }
216
217         private void insertAllMissingMethodTags(ASTRewrite rewriter, MethodDeclaration methodDecl) {
218             AST ast= methodDecl.getAST();
219             Javadoc javadoc= methodDecl.getJavadoc();
220             ListRewrite tagsRewriter= rewriter.getListRewrite(javadoc, Javadoc.TAGS_PROPERTY);
221
222             List JavaDoc typeParams= methodDecl.typeParameters();
223             List JavaDoc typeParamNames= new ArrayList JavaDoc();
224             for (int i= typeParams.size() - 1; i >= 0 ; i--) {
225                 TypeParameter decl= (TypeParameter) typeParams.get(i);
226                 String JavaDoc name= '<' + decl.getName().getIdentifier() + '>';
227                 if (findTag(javadoc, TagElement.TAG_PARAM, name) == null) {
228                     TagElement newTag= ast.newTagElement();
229                     newTag.setTagName(TagElement.TAG_PARAM);
230                     TextElement text= ast.newTextElement();
231                     text.setText(name);
232                     newTag.fragments().add(text);
233                     insertTabStop(rewriter, newTag.fragments(), "typeParam" + i); //$NON-NLS-1$
234
insertTag(tagsRewriter, newTag, getPreviousTypeParamNames(typeParams, decl));
235                 }
236                 typeParamNames.add(name);
237             }
238             List JavaDoc params= methodDecl.parameters();
239             for (int i= params.size() - 1; i >= 0 ; i--) {
240                 SingleVariableDeclaration decl= (SingleVariableDeclaration) params.get(i);
241                 String JavaDoc name= decl.getName().getIdentifier();
242                 if (findTag(javadoc, TagElement.TAG_PARAM, name) == null) {
243                     TagElement newTag= ast.newTagElement();
244                     newTag.setTagName(TagElement.TAG_PARAM);
245                     newTag.fragments().add(ast.newSimpleName(name));
246                     insertTabStop(rewriter, newTag.fragments(), "methParam" + i); //$NON-NLS-1$
247
Set JavaDoc sameKindLeadingNames= getPreviousParamNames(params, decl);
248                     sameKindLeadingNames.addAll(typeParamNames);
249                     insertTag(tagsRewriter, newTag, sameKindLeadingNames);
250                 }
251             }
252             if (!methodDecl.isConstructor()) {
253                 Type type= methodDecl.getReturnType2();
254                 if (!type.isPrimitiveType() || (((PrimitiveType) type).getPrimitiveTypeCode() != PrimitiveType.VOID)) {
255                     if (findTag(javadoc, TagElement.TAG_RETURN, null) == null) {
256                         TagElement newTag= ast.newTagElement();
257                         newTag.setTagName(TagElement.TAG_RETURN);
258                         insertTabStop(rewriter, newTag.fragments(), "return"); //$NON-NLS-1$
259
insertTag(tagsRewriter, newTag, null);
260                     }
261                 }
262             }
263             List JavaDoc thrownExceptions= methodDecl.thrownExceptions();
264             for (int i= thrownExceptions.size() - 1; i >= 0 ; i--) {
265                 Name exception= (Name) thrownExceptions.get(i);
266                 ITypeBinding binding= exception.resolveTypeBinding();
267                 if (binding != null) {
268                     String JavaDoc name= binding.getName();
269                     if (findThrowsTag(javadoc, name) == null) {
270                         TagElement newTag= ast.newTagElement();
271                         newTag.setTagName(TagElement.TAG_THROWS);
272                         TextElement excNode= ast.newTextElement();
273                         excNode.setText(ASTNodes.asString(exception));
274                         newTag.fragments().add(excNode);
275                         insertTabStop(rewriter, newTag.fragments(), "exception" + i); //$NON-NLS-1$
276
insertTag(tagsRewriter, newTag, getPreviousExceptionNames(thrownExceptions, exception));
277                     }
278                 }
279             }
280          }
281
282         private void insertAllMissingTypeTags(ASTRewrite rewriter, TypeDeclaration typeDecl) {
283             AST ast= typeDecl.getAST();
284             Javadoc javadoc= typeDecl.getJavadoc();
285             ListRewrite tagsRewriter= rewriter.getListRewrite(javadoc, Javadoc.TAGS_PROPERTY);
286
287             List JavaDoc typeParams= typeDecl.typeParameters();
288             for (int i= typeParams.size() - 1; i >= 0; i--) {
289                 TypeParameter decl= (TypeParameter) typeParams.get(i);
290                 String JavaDoc name= '<' + decl.getName().getIdentifier() + '>';
291                 if (findTag(javadoc, TagElement.TAG_PARAM, name) == null) {
292                     TagElement newTag= ast.newTagElement();
293                     newTag.setTagName(TagElement.TAG_PARAM);
294                     TextElement text= ast.newTextElement();
295                     text.setText(name);
296                     newTag.fragments().add(text);
297                     insertTabStop(rewriter, newTag.fragments(), "typeParam" + i); //$NON-NLS-1$
298
insertTag(tagsRewriter, newTag, getPreviousTypeParamNames(typeParams, decl));
299                 }
300             }
301         }
302
303         private void insertTabStop(ASTRewrite rewriter, List JavaDoc fragments, String JavaDoc linkedName) {
304             TextElement textElement= rewriter.getAST().newTextElement();
305             textElement.setText(""); //$NON-NLS-1$
306
fragments.add(textElement);
307             addLinkedPosition(rewriter.track(textElement), false, linkedName);
308         }
309
310     }
311
312     public static void getMissingJavadocTagProposals(IInvocationContext context, IProblemLocation problem, Collection JavaDoc proposals) {
313         ASTNode node= problem.getCoveringNode(context.getASTRoot());
314         if (node == null) {
315             return;
316         }
317         node= ASTNodes.getNormalizedNode(node);
318
319         BodyDeclaration bodyDeclaration= ASTResolving.findParentBodyDeclaration(node);
320         if (bodyDeclaration == null) {
321             return;
322         }
323         Javadoc javadoc= bodyDeclaration.getJavadoc();
324         if (javadoc == null) {
325             return;
326         }
327
328         String JavaDoc label;
329         StructuralPropertyDescriptor location= node.getLocationInParent();
330         if (location == SingleVariableDeclaration.NAME_PROPERTY) {
331             label= CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_paramtag_description;
332             if (node.getParent().getLocationInParent() != MethodDeclaration.PARAMETERS_PROPERTY) {
333                 return; // paranoia checks
334
}
335         } else if (location == TypeParameter.NAME_PROPERTY) {
336             label= CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_paramtag_description;
337             StructuralPropertyDescriptor parentLocation= node.getParent().getLocationInParent();
338             if (parentLocation != MethodDeclaration.TYPE_PARAMETERS_PROPERTY && parentLocation != TypeDeclaration.TYPE_PARAMETERS_PROPERTY) {
339                 return; // paranoia checks
340
}
341         } else if (location == MethodDeclaration.RETURN_TYPE2_PROPERTY) {
342             label= CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_returntag_description;
343         } else if (location == MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY) {
344             label= CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_throwstag_description;
345         } else {
346             return;
347         }
348         ASTRewriteCorrectionProposal proposal= new AddMissingJavadocTagProposal(label, context.getCompilationUnit(), bodyDeclaration, node, 1);
349         proposals.add(proposal);
350
351         String JavaDoc label2= CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_allmissing_description;
352         ASTRewriteCorrectionProposal addAllMissing= new AddAllMissingJavadocTagsProposal(label2, context.getCompilationUnit(), bodyDeclaration, 5);
353         proposals.add(addAllMissing);
354     }
355
356     public static void getMissingJavadocCommentProposals(IInvocationContext context, IProblemLocation problem, Collection JavaDoc proposals) throws CoreException {
357         ASTNode node= problem.getCoveringNode(context.getASTRoot());
358         if (node == null) {
359             return;
360         }
361         BodyDeclaration declaration= ASTResolving.findParentBodyDeclaration(node);
362         if (declaration == null) {
363             return;
364         }
365         ICompilationUnit cu= context.getCompilationUnit();
366         ITypeBinding binding= Bindings.getBindingOfParentType(declaration);
367         if (binding == null) {
368             return;
369         }
370
371         if (declaration instanceof MethodDeclaration) {
372             MethodDeclaration methodDecl= (MethodDeclaration) declaration;
373             IMethodBinding methodBinding= methodDecl.resolveBinding();
374             IMethodBinding overridden= null;
375             if (methodBinding != null) {
376                 overridden= Bindings.findOverriddenMethod(methodBinding, true);
377             }
378
379             String JavaDoc string= CodeGeneration.getMethodComment(cu, binding.getName(), methodDecl, overridden, String.valueOf('\n'));
380             if (string != null) {
381                 String JavaDoc label= CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_method_description;
382                 proposals.add(new AddJavadocCommentProposal(label, cu, 1, declaration.getStartPosition(), string));
383             }
384         } else if (declaration instanceof AbstractTypeDeclaration) {
385             String JavaDoc typeQualifiedName= Bindings.getTypeQualifiedName(binding);
386             String JavaDoc[] typeParamNames;
387             if (declaration instanceof TypeDeclaration) {
388                 List JavaDoc typeParams= ((TypeDeclaration) declaration).typeParameters();
389                 typeParamNames= new String JavaDoc[typeParams.size()];
390                 for (int i= 0; i < typeParamNames.length; i++) {
391                     typeParamNames[i]= ((TypeParameter) typeParams.get(i)).getName().getIdentifier();
392                 }
393             } else {
394                 typeParamNames= new String JavaDoc[0];
395             }
396             String JavaDoc string= CodeGeneration.getTypeComment(cu, typeQualifiedName, typeParamNames, String.valueOf('\n'));
397             if (string != null) {
398                 String JavaDoc label= CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_type_description;
399                 proposals.add(new AddJavadocCommentProposal(label, cu, 1, declaration.getStartPosition(), string));
400             }
401         } else if (declaration instanceof FieldDeclaration) {
402             String JavaDoc comment= "/**\n *\n */\n"; //$NON-NLS-1$
403
List JavaDoc fragments= ((FieldDeclaration)declaration).fragments();
404             if (fragments != null && fragments.size() > 0) {
405                 VariableDeclaration decl= (VariableDeclaration)fragments.get(0);
406                 String JavaDoc fieldName= decl.getName().getIdentifier();
407                 String JavaDoc typeName= binding.getName();
408                 comment= CodeGeneration.getFieldComment(cu, typeName, fieldName, String.valueOf('\n'));
409             }
410             if (comment != null) {
411                 String JavaDoc label= CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_field_description;
412                 proposals.add(new AddJavadocCommentProposal(label, cu, 1, declaration.getStartPosition(), comment));
413             }
414         } else if (declaration instanceof EnumConstantDeclaration) {
415             EnumConstantDeclaration enumDecl= (EnumConstantDeclaration) declaration;
416             String JavaDoc id= enumDecl.getName().getIdentifier();
417             String JavaDoc comment= CodeGeneration.getFieldComment(cu, binding.getName(), id, String.valueOf('\n'));
418             String JavaDoc label= CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_enumconst_description;
419             proposals.add(new AddJavadocCommentProposal(label, cu, 1, declaration.getStartPosition(), comment));
420         }
421     }
422
423     public static Set JavaDoc getPreviousTypeParamNames(List JavaDoc typeParams, ASTNode missingNode) {
424         Set JavaDoc previousNames= new HashSet JavaDoc();
425         for (int i = 0; i < typeParams.size(); i++) {
426             TypeParameter curr= (TypeParameter) typeParams.get(i);
427             if (curr == missingNode) {
428                 return previousNames;
429             }
430             previousNames.add('<' + curr.getName().getIdentifier() + '>');
431         }
432         return previousNames;
433     }
434
435     private static Set JavaDoc getPreviousParamNames(List JavaDoc params, ASTNode missingNode) {
436         Set JavaDoc previousNames= new HashSet JavaDoc();
437         for (int i = 0; i < params.size(); i++) {
438             SingleVariableDeclaration curr= (SingleVariableDeclaration) params.get(i);
439             if (curr == missingNode) {
440                 return previousNames;
441             }
442             previousNames.add(curr.getName().getIdentifier());
443         }
444         return previousNames;
445     }
446
447     private static Set JavaDoc getPreviousExceptionNames(List JavaDoc list, ASTNode missingNode) {
448         Set JavaDoc previousNames= new HashSet JavaDoc();
449         for (int i= 0; i < list.size() && missingNode != list.get(i); i++) {
450             Name curr= (Name) list.get(i);
451             previousNames.add(ASTNodes.getSimpleNameIdentifier(curr));
452         }
453         return previousNames;
454     }
455
456     public static TagElement findTag(Javadoc javadoc, String JavaDoc name, String JavaDoc arg) {
457         List JavaDoc tags= javadoc.tags();
458         int nTags= tags.size();
459         for (int i= 0; i < nTags; i++) {
460             TagElement curr= (TagElement) tags.get(i);
461             if (name.equals(curr.getTagName())) {
462                 if (arg != null) {
463                     String JavaDoc argument= getArgument(curr);
464                     if (arg.equals(argument)) {
465                         return curr;
466                     }
467                 } else {
468                     return curr;
469                 }
470             }
471         }
472         return null;
473     }
474
475     public static TagElement findParamTag(Javadoc javadoc, String JavaDoc arg) {
476         List JavaDoc tags= javadoc.tags();
477         int nTags= tags.size();
478         for (int i= 0; i < nTags; i++) {
479             TagElement curr= (TagElement) tags.get(i);
480             String JavaDoc currName= curr.getTagName();
481             if (TagElement.TAG_PARAM.equals(currName)) {
482                 String JavaDoc argument= getArgument(curr);
483                 if (arg.equals(argument)) {
484                     return curr;
485                 }
486             }
487         }
488         return null;
489     }
490
491
492     public static TagElement findThrowsTag(Javadoc javadoc, String JavaDoc arg) {
493         List JavaDoc tags= javadoc.tags();
494         int nTags= tags.size();
495         for (int i= 0; i < nTags; i++) {
496             TagElement curr= (TagElement) tags.get(i);
497             String JavaDoc currName= curr.getTagName();
498             if (TagElement.TAG_THROWS.equals(currName) || TagElement.TAG_EXCEPTION.equals(currName)) {
499                 String JavaDoc argument= getArgument(curr);
500                 if (arg.equals(argument)) {
501                     return curr;
502                 }
503             }
504         }
505         return null;
506     }
507
508     public static void insertTag(ListRewrite rewriter, TagElement newElement, Set JavaDoc sameKindLeadingNames) {
509         insertTag(rewriter, newElement, sameKindLeadingNames, null);
510     }
511
512     public static void insertTag(ListRewrite rewriter, TagElement newElement, Set JavaDoc sameKindLeadingNames, TextEditGroup groupDescription) {
513         List JavaDoc tags= rewriter.getRewrittenList();
514
515         String JavaDoc insertedTagName= newElement.getTagName();
516
517         ASTNode after= null;
518         int tagRanking= getTagRanking(insertedTagName);
519         for (int i= tags.size() - 1; i >= 0; i--) {
520             TagElement curr= (TagElement) tags.get(i);
521             String JavaDoc tagName= curr.getTagName();
522             if (tagName == null || tagRanking > getTagRanking(tagName)) {
523                 after= curr;
524                 break;
525             }
526             if (sameKindLeadingNames != null && isSameTag(insertedTagName, tagName)) {
527                 String JavaDoc arg= getArgument(curr);
528                 if (arg != null && sameKindLeadingNames.contains(arg)) {
529                     after= curr;
530                     break;
531                 }
532             }
533         }
534         if (after != null) {
535             rewriter.insertAfter(newElement, after, groupDescription);
536         } else {
537             rewriter.insertFirst(newElement, groupDescription);
538         }
539     }
540
541     private static boolean isSameTag(String JavaDoc insertedTagName, String JavaDoc tagName) {
542         if (insertedTagName.equals(tagName)) {
543             return true;
544         }
545         if (TagElement.TAG_EXCEPTION.equals(tagName)) {
546             return TagElement.TAG_THROWS.equals(insertedTagName);
547         }
548         return false;
549     }
550     
551     private static String JavaDoc[] TAG_ORDER= { // see http://java.sun.com/j2se/javadoc/writingdoccomments/index.html#orderoftags
552
TagElement.TAG_AUTHOR,
553         TagElement.TAG_VERSION,
554         TagElement.TAG_PARAM,
555         TagElement.TAG_RETURN,
556         TagElement.TAG_THROWS, // synonym to TAG_EXCEPTION
557
TagElement.TAG_SEE,
558         TagElement.TAG_SINCE,
559         TagElement.TAG_SERIAL,
560         TagElement.TAG_DEPRECATED
561     };
562     
563     private static int getTagRanking(String JavaDoc tagName) {
564         if (tagName.equals(TagElement.TAG_EXCEPTION)) {
565             tagName= TagElement.TAG_THROWS;
566         }
567         for (int i= 0; i < TAG_ORDER.length; i++) {
568             if (tagName.equals(TAG_ORDER[i])) {
569                 return i;
570             }
571         }
572         return TAG_ORDER.length;
573     }
574
575     private static String JavaDoc getArgument(TagElement curr) {
576         List JavaDoc fragments= curr.fragments();
577         if (!fragments.isEmpty()) {
578             Object JavaDoc first= fragments.get(0);
579             if (first instanceof Name) {
580                 return ASTNodes.getSimpleNameIdentifier((Name) first);
581             } else if (first instanceof TextElement && TagElement.TAG_PARAM.equals(curr.getTagName())) {
582                 String JavaDoc text= ((TextElement) first).getText();
583                 if ("<".equals(text) && fragments.size() >= 3) { //$NON-NLS-1$
584
Object JavaDoc second= fragments.get(1);
585                     Object JavaDoc third= fragments.get(2);
586                     if (second instanceof Name && third instanceof TextElement && ">".equals(((TextElement) third).getText())) { //$NON-NLS-1$
587
return '<' + ASTNodes.getSimpleNameIdentifier((Name) second) + '>';
588                     }
589                 } else if (text.startsWith(String.valueOf('<')) && text.endsWith(String.valueOf('>')) && text.length() > 2) {
590                     return text.substring(1, text.length() - 1);
591                 }
592             }
593         }
594         return null;
595     }
596
597     public static void getRemoveJavadocTagProposals(IInvocationContext context, IProblemLocation problem, Collection JavaDoc proposals) {
598         ASTNode node= problem.getCoveringNode(context.getASTRoot());
599         while (node != null && !(node instanceof TagElement)) {
600             node= node.getParent();
601         }
602         if (node == null) {
603             return;
604         }
605         ASTRewrite rewrite= ASTRewrite.create(node.getAST());
606         rewrite.remove(node, null);
607
608         String JavaDoc label= CorrectionMessages.JavadocTagsSubProcessor_removetag_description;
609         Image image= JavaPlugin.getDefault().getWorkbench().getSharedImages().getImage(ISharedImages.IMG_TOOL_DELETE);
610         proposals.add(new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 5, image));
611     }
612 }
613
Popular Tags