KickJava   Java API By Example, From Geeks To Geeks.

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


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.Iterator JavaDoc;
16
17 import org.eclipse.core.runtime.CoreException;
18
19 import org.eclipse.swt.graphics.Image;
20
21 import org.eclipse.jdt.core.ICompilationUnit;
22 import org.eclipse.jdt.core.JavaModelException;
23 import org.eclipse.jdt.core.dom.AST;
24 import org.eclipse.jdt.core.dom.ASTNode;
25 import org.eclipse.jdt.core.dom.ASTVisitor;
26 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
27 import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
28 import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
29 import org.eclipse.jdt.core.dom.Block;
30 import org.eclipse.jdt.core.dom.BodyDeclaration;
31 import org.eclipse.jdt.core.dom.CompilationUnit;
32 import org.eclipse.jdt.core.dom.EnumDeclaration;
33 import org.eclipse.jdt.core.dom.Expression;
34 import org.eclipse.jdt.core.dom.ITypeBinding;
35 import org.eclipse.jdt.core.dom.Javadoc;
36 import org.eclipse.jdt.core.dom.MethodDeclaration;
37 import org.eclipse.jdt.core.dom.PrimitiveType;
38 import org.eclipse.jdt.core.dom.ReturnStatement;
39 import org.eclipse.jdt.core.dom.TagElement;
40 import org.eclipse.jdt.core.dom.TextElement;
41 import org.eclipse.jdt.core.dom.Type;
42 import org.eclipse.jdt.core.dom.TypeDeclaration;
43 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
44 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
45
46 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
47 import org.eclipse.jdt.internal.corext.dom.Bindings;
48 import org.eclipse.jdt.internal.corext.util.Messages;
49
50 import org.eclipse.jdt.ui.text.java.IInvocationContext;
51 import org.eclipse.jdt.ui.text.java.IProblemLocation;
52
53 import org.eclipse.jdt.internal.ui.JavaPluginImages;
54 import org.eclipse.jdt.internal.ui.viewsupport.BindingLabelProvider;
55
56 /**
57   */

58 public class ReturnTypeSubProcessor {
59
60     private static class ReturnStatementCollector extends ASTVisitor {
61         private ArrayList JavaDoc fResult= new ArrayList JavaDoc();
62
63         public Iterator JavaDoc returnStatements() {
64             return fResult.iterator();
65         }
66
67         public ITypeBinding getTypeBinding(AST ast) {
68             boolean couldBeObject= false;
69             for (int i= 0; i < fResult.size(); i++) {
70                 ReturnStatement node= (ReturnStatement) fResult.get(i);
71                 Expression expr= node.getExpression();
72                 if (expr != null) {
73                     ITypeBinding binding= Bindings.normalizeTypeBinding(expr.resolveTypeBinding());
74                     if (binding != null) {
75                         return binding;
76                     } else {
77                         couldBeObject= true;
78                     }
79                 } else {
80                     return ast.resolveWellKnownType("void"); //$NON-NLS-1$
81
}
82             }
83             if (couldBeObject) {
84                 return ast.resolveWellKnownType("java.lang.Object"); //$NON-NLS-1$
85
}
86             return ast.resolveWellKnownType("void"); //$NON-NLS-1$
87
}
88
89         public boolean visit(ReturnStatement node) {
90             fResult.add(node);
91             return false;
92         }
93
94         public boolean visit(AnonymousClassDeclaration node) {
95             return false;
96         }
97
98         public boolean visit(TypeDeclaration node) {
99             return false;
100         }
101
102         public boolean visit(EnumDeclaration node) {
103             return false;
104         }
105
106         public boolean visit(AnnotationTypeDeclaration node) {
107             return false;
108         }
109
110     }
111
112
113     public static void addMethodWithConstrNameProposals(IInvocationContext context, IProblemLocation problem, Collection JavaDoc proposals) {
114         ICompilationUnit cu= context.getCompilationUnit();
115
116         ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot());
117         if (selectedNode instanceof MethodDeclaration) {
118             MethodDeclaration declaration= (MethodDeclaration) selectedNode;
119
120             ASTRewrite rewrite= ASTRewrite.create(declaration.getAST());
121             rewrite.set(declaration, MethodDeclaration.CONSTRUCTOR_PROPERTY, Boolean.TRUE, null);
122
123             String JavaDoc label= CorrectionMessages.ReturnTypeSubProcessor_constrnamemethod_description;
124             Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
125             ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, cu, rewrite, 5, image);
126             proposals.add(proposal);
127         }
128
129     }
130
131     public static void addVoidMethodReturnsProposals(IInvocationContext context, IProblemLocation problem, Collection JavaDoc proposals) throws CoreException {
132         ICompilationUnit cu= context.getCompilationUnit();
133
134         CompilationUnit astRoot= context.getASTRoot();
135         ASTNode selectedNode= problem.getCoveringNode(astRoot);
136         if (selectedNode == null) {
137             return;
138         }
139
140         BodyDeclaration decl= ASTResolving.findParentBodyDeclaration(selectedNode);
141         if (decl instanceof MethodDeclaration && selectedNode.getNodeType() == ASTNode.RETURN_STATEMENT) {
142             ReturnStatement returnStatement= (ReturnStatement) selectedNode;
143             Expression expr= returnStatement.getExpression();
144             if (expr != null) {
145                 AST ast= astRoot.getAST();
146                 
147                 ITypeBinding binding= Bindings.normalizeTypeBinding(expr.resolveTypeBinding());
148                 if (binding == null) {
149                     binding= ast.resolveWellKnownType("java.lang.Object"); //$NON-NLS-1$
150
}
151                 if (binding.isWildcardType()) {
152                     binding= ASTResolving.normalizeWildcardType(binding, true, ast);
153                 }
154                 
155                 MethodDeclaration methodDeclaration= (MethodDeclaration) decl;
156
157                 ASTRewrite rewrite= ASTRewrite.create(ast);
158
159                 String JavaDoc label= Messages.format(CorrectionMessages.ReturnTypeSubProcessor_voidmethodreturns_description, BindingLabelProvider.getBindingLabel(binding, BindingLabelProvider.DEFAULT_TEXTFLAGS));
160                 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
161                 LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, cu, rewrite, 6, image);
162                 ImportRewrite imports= proposal.createImportRewrite(astRoot);
163                 Type newReturnType= imports.addImport(binding, ast);
164
165                 if (methodDeclaration.isConstructor()) {
166                     rewrite.set(methodDeclaration, MethodDeclaration.CONSTRUCTOR_PROPERTY, Boolean.FALSE, null);
167                     rewrite.set(methodDeclaration, MethodDeclaration.RETURN_TYPE2_PROPERTY, newReturnType, null);
168                 } else {
169                     rewrite.replace(methodDeclaration.getReturnType2(), newReturnType, null);
170                 }
171                 String JavaDoc key= "return_type"; //$NON-NLS-1$
172
proposal.addLinkedPosition(rewrite.track(newReturnType), true, key);
173                 ITypeBinding[] bindings= ASTResolving.getRelaxingTypes(ast, binding);
174                 for (int i= 0; i < bindings.length; i++) {
175                     proposal.addLinkedPositionProposal(key, bindings[i]);
176                 }
177
178                 Javadoc javadoc= methodDeclaration.getJavadoc();
179                 if (javadoc != null) {
180                     TagElement newTag= ast.newTagElement();
181                     newTag.setTagName(TagElement.TAG_RETURN);
182                     TextElement commentStart= ast.newTextElement();
183                     newTag.fragments().add(commentStart);
184
185                     JavadocTagsSubProcessor.insertTag(rewrite.getListRewrite(javadoc, Javadoc.TAGS_PROPERTY), newTag, null);
186                     proposal.addLinkedPosition(rewrite.track(commentStart), false, "comment_start"); //$NON-NLS-1$
187

188                 }
189                 proposals.add(proposal);
190             }
191             ASTRewrite rewrite= ASTRewrite.create(decl.getAST());
192             rewrite.remove(returnStatement.getExpression(), null);
193
194             String JavaDoc label= CorrectionMessages.ReturnTypeSubProcessor_removereturn_description;
195             Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
196             ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, cu, rewrite, 5, image);
197             proposals.add(proposal);
198         }
199     }
200
201
202
203     public static void addMissingReturnTypeProposals(IInvocationContext context, IProblemLocation problem, Collection JavaDoc proposals) throws CoreException {
204         ICompilationUnit cu= context.getCompilationUnit();
205
206         CompilationUnit astRoot= context.getASTRoot();
207         ASTNode selectedNode= problem.getCoveringNode(astRoot);
208         if (selectedNode == null) {
209             return;
210         }
211         BodyDeclaration decl= ASTResolving.findParentBodyDeclaration(selectedNode);
212         if (decl instanceof MethodDeclaration) {
213             MethodDeclaration methodDeclaration= (MethodDeclaration) decl;
214
215             ReturnStatementCollector eval= new ReturnStatementCollector();
216             decl.accept(eval);
217
218             AST ast= astRoot.getAST();
219             
220             ITypeBinding typeBinding= eval.getTypeBinding(decl.getAST());
221             typeBinding= Bindings.normalizeTypeBinding(typeBinding);
222             if (typeBinding == null) {
223                 typeBinding= ast.resolveWellKnownType("void"); //$NON-NLS-1$
224
}
225             if (typeBinding.isWildcardType()) {
226                 typeBinding= ASTResolving.normalizeWildcardType(typeBinding, true, ast);
227             }
228             
229             ASTRewrite rewrite= ASTRewrite.create(ast);
230
231             String JavaDoc label= Messages.format(CorrectionMessages.ReturnTypeSubProcessor_missingreturntype_description, BindingLabelProvider.getBindingLabel(typeBinding, BindingLabelProvider.DEFAULT_TEXTFLAGS));
232             Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
233             LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, cu, rewrite, 6, image);
234             
235             ImportRewrite imports= proposal.createImportRewrite(astRoot);
236
237             Type type= imports.addImport(typeBinding, ast);
238
239             rewrite.set(methodDeclaration, MethodDeclaration.RETURN_TYPE2_PROPERTY, type, null);
240             rewrite.set(methodDeclaration, MethodDeclaration.CONSTRUCTOR_PROPERTY, Boolean.FALSE, null);
241
242             Javadoc javadoc= methodDeclaration.getJavadoc();
243             if (javadoc != null && typeBinding != null) {
244                 TagElement newTag= ast.newTagElement();
245                 newTag.setTagName(TagElement.TAG_RETURN);
246                 TextElement commentStart= ast.newTextElement();
247                 newTag.fragments().add(commentStart);
248
249                 JavadocTagsSubProcessor.insertTag(rewrite.getListRewrite(javadoc, Javadoc.TAGS_PROPERTY), newTag, null);
250                 proposal.addLinkedPosition(rewrite.track(commentStart), false, "comment_start"); //$NON-NLS-1$
251
}
252
253             String JavaDoc key= "return_type"; //$NON-NLS-1$
254
proposal.addLinkedPosition(rewrite.track(type), true, key);
255             if (typeBinding != null) {
256                 ITypeBinding[] bindings= ASTResolving.getRelaxingTypes(ast, typeBinding);
257                 for (int i= 0; i < bindings.length; i++) {
258                     proposal.addLinkedPositionProposal(key, bindings[i]);
259                 }
260             }
261
262             proposals.add(proposal);
263
264             // change to constructor
265
ASTNode parentType= ASTResolving.findParentType(decl);
266             if (parentType instanceof AbstractTypeDeclaration) {
267                 boolean isInterface= parentType instanceof TypeDeclaration && ((TypeDeclaration) parentType).isInterface();
268                 if (!isInterface) {
269                     String JavaDoc constructorName= ((TypeDeclaration) parentType).getName().getIdentifier();
270                     ASTNode nameNode= methodDeclaration.getName();
271                     label= Messages.format(CorrectionMessages.ReturnTypeSubProcessor_wrongconstructorname_description, constructorName);
272                     proposals.add(new ReplaceCorrectionProposal(label, cu, nameNode.getStartPosition(), nameNode.getLength(), constructorName, 5));
273                 }
274             }
275         }
276     }
277
278     public static void addMissingReturnStatementProposals(IInvocationContext context, IProblemLocation problem, Collection JavaDoc proposals) {
279         ICompilationUnit cu= context.getCompilationUnit();
280
281         ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot());
282         if (selectedNode == null) {
283             return;
284         }
285         BodyDeclaration decl= ASTResolving.findParentBodyDeclaration(selectedNode);
286         if (decl instanceof MethodDeclaration) {
287             MethodDeclaration methodDecl= (MethodDeclaration) decl;
288             Block block= methodDecl.getBody();
289             if (block == null) {
290                 return;
291             }
292             ReturnStatement existingStatement= (selectedNode instanceof ReturnStatement) ? (ReturnStatement) selectedNode : null;
293             proposals.add( new MissingReturnTypeCorrectionProposal(cu, methodDecl, existingStatement, 6));
294
295             Type returnType= methodDecl.getReturnType2();
296             if (returnType != null && !"void".equals(ASTNodes.asString(returnType))) { //$NON-NLS-1$
297
AST ast= methodDecl.getAST();
298                 ASTRewrite rewrite= ASTRewrite.create(ast);
299                 rewrite.replace(returnType, ast.newPrimitiveType(PrimitiveType.VOID), null);
300                 Javadoc javadoc= methodDecl.getJavadoc();
301                 if (javadoc != null) {
302                     TagElement tagElement= JavadocTagsSubProcessor.findTag(javadoc, TagElement.TAG_RETURN, null);
303                     if (tagElement != null) {
304                         rewrite.remove(tagElement, null);
305                     }
306                 }
307
308                 String JavaDoc label= CorrectionMessages.ReturnTypeSubProcessor_changetovoid_description;
309                 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
310                 ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, cu, rewrite, 5, image);
311                 proposals.add(proposal);
312             }
313         }
314     }
315
316     public static void addMethodRetunsVoidProposals(IInvocationContext context, IProblemLocation problem, Collection JavaDoc proposals) throws JavaModelException {
317         CompilationUnit astRoot= context.getASTRoot();
318         ASTNode selectedNode= problem.getCoveringNode(astRoot);
319         if (!(selectedNode instanceof ReturnStatement)) {
320             return;
321         }
322         ReturnStatement returnStatement= (ReturnStatement) selectedNode;
323         Expression expression= returnStatement.getExpression();
324         if (expression == null) {
325             return;
326         }
327         BodyDeclaration decl= ASTResolving.findParentBodyDeclaration(selectedNode);
328         if (decl instanceof MethodDeclaration) {
329             MethodDeclaration methDecl= (MethodDeclaration) decl;
330             Type retType= methDecl.getReturnType2();
331             if (retType == null || retType.resolveBinding() == null) {
332                 return;
333             }
334             TypeMismatchSubProcessor.addChangeSenderTypeProposals(context, expression, retType.resolveBinding(), false, 4, proposals);
335         }
336     }
337 }
338
Popular Tags