1 11 package org.eclipse.jdt.internal.ui.text.correction; 12 13 import java.util.ArrayList ; 14 import java.util.Collection ; 15 import java.util.Iterator ; 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 58 public class ReturnTypeSubProcessor { 59 60 private static class ReturnStatementCollector extends ASTVisitor { 61 private ArrayList fResult= new ArrayList (); 62 63 public Iterator 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"); } 82 } 83 if (couldBeObject) { 84 return ast.resolveWellKnownType("java.lang.Object"); } 86 return ast.resolveWellKnownType("void"); } 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 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 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 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"); } 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 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 key= "return_type"; 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"); 188 } 189 proposals.add(proposal); 190 } 191 ASTRewrite rewrite= ASTRewrite.create(decl.getAST()); 192 rewrite.remove(returnStatement.getExpression(), null); 193 194 String 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 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"); } 225 if (typeBinding.isWildcardType()) { 226 typeBinding= ASTResolving.normalizeWildcardType(typeBinding, true, ast); 227 } 228 229 ASTRewrite rewrite= ASTRewrite.create(ast); 230 231 String 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"); } 252 253 String key= "return_type"; 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 ASTNode parentType= ASTResolving.findParentType(decl); 266 if (parentType instanceof AbstractTypeDeclaration) { 267 boolean isInterface= parentType instanceof TypeDeclaration && ((TypeDeclaration) parentType).isInterface(); 268 if (!isInterface) { 269 String 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 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))) { 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 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 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 |