1 11 package org.eclipse.jdt.internal.ui.text.correction; 12 13 import java.util.List ; 14 15 import org.eclipse.jdt.core.ICompilationUnit; 16 import org.eclipse.jdt.core.dom.AST; 17 import org.eclipse.jdt.core.dom.ASTNode; 18 import org.eclipse.jdt.core.dom.Block; 19 import org.eclipse.jdt.core.dom.CompilationUnit; 20 import org.eclipse.jdt.core.dom.Expression; 21 import org.eclipse.jdt.core.dom.ExpressionStatement; 22 import org.eclipse.jdt.core.dom.IBinding; 23 import org.eclipse.jdt.core.dom.IMethodBinding; 24 import org.eclipse.jdt.core.dom.ITypeBinding; 25 import org.eclipse.jdt.core.dom.IVariableBinding; 26 import org.eclipse.jdt.core.dom.MethodDeclaration; 27 import org.eclipse.jdt.core.dom.Modifier; 28 import org.eclipse.jdt.core.dom.ReturnStatement; 29 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; 30 31 import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory; 32 import org.eclipse.jdt.internal.corext.dom.ASTNodes; 33 import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer; 34 35 import org.eclipse.jdt.internal.ui.JavaPluginImages; 36 37 public class MissingReturnTypeCorrectionProposal extends LinkedCorrectionProposal { 38 39 private static final String RETURN_EXPRESSION_KEY= "value"; 41 private MethodDeclaration fMethodDecl; 42 private ReturnStatement fExistingReturn; 43 44 public MissingReturnTypeCorrectionProposal(ICompilationUnit cu, MethodDeclaration decl, ReturnStatement existingReturn, int relevance) { 45 super("", cu, null, relevance, JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE)); fMethodDecl= decl; 47 fExistingReturn= existingReturn; 48 } 49 50 public String getDisplayString() { 51 if (fExistingReturn != null) { 52 return CorrectionMessages.MissingReturnTypeCorrectionProposal_changereturnstatement_description; 53 } else { 54 return CorrectionMessages.MissingReturnTypeCorrectionProposal_addreturnstatement_description; 55 } 56 } 57 58 61 protected ASTRewrite getRewrite() { 62 AST ast= fMethodDecl.getAST(); 63 64 ITypeBinding returnBinding= getReturnTypeBinding(); 65 66 if (fExistingReturn != null) { 67 ASTRewrite rewrite= ASTRewrite.create(ast); 68 69 Expression expression= evaluateReturnExpressions(ast, returnBinding, fExistingReturn.getStartPosition()); 70 if (expression != null) { 71 rewrite.set(fExistingReturn, ReturnStatement.EXPRESSION_PROPERTY, expression, null); 72 73 addLinkedPosition(rewrite.track(expression), true, RETURN_EXPRESSION_KEY); 74 } 75 return rewrite; 76 } else { 77 ASTRewrite rewrite= ASTRewrite.create(ast); 78 79 Block block= fMethodDecl.getBody(); 80 81 List statements= block.statements(); 82 int nStatements= statements.size(); 83 ASTNode lastStatement= null; 84 if (nStatements > 0) { 85 lastStatement= (ASTNode) statements.get(nStatements - 1); 86 } 87 88 if (returnBinding != null && lastStatement instanceof ExpressionStatement && lastStatement.getNodeType() != ASTNode.ASSIGNMENT) { 89 Expression expression= ((ExpressionStatement) lastStatement).getExpression(); 90 ITypeBinding binding= expression.resolveTypeBinding(); 91 if (binding != null && binding.isAssignmentCompatible(returnBinding)) { 92 Expression placeHolder= (Expression) rewrite.createMoveTarget(expression); 93 94 ReturnStatement returnStatement= ast.newReturnStatement(); 95 returnStatement.setExpression(placeHolder); 96 97 rewrite.replace(lastStatement, returnStatement, null); 98 return rewrite; 99 } 100 } 101 102 int offset; 103 if (lastStatement == null) { 104 offset= block.getStartPosition() + 1; 105 } else { 106 offset= lastStatement.getStartPosition() + lastStatement.getLength(); 107 } 108 ReturnStatement returnStatement= ast.newReturnStatement(); 109 Expression expression= evaluateReturnExpressions(ast, returnBinding, offset); 110 111 returnStatement.setExpression(expression); 112 113 rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY).insertLast(returnStatement, null); 114 115 addLinkedPosition(rewrite.track(returnStatement.getExpression()), true, RETURN_EXPRESSION_KEY); 116 return rewrite; 117 } 118 } 119 120 private ITypeBinding getReturnTypeBinding() { 121 IMethodBinding methodBinding= fMethodDecl.resolveBinding(); 122 if (methodBinding != null && methodBinding.getReturnType() != null) { 123 return methodBinding.getReturnType(); 124 } 125 return null; 126 } 127 128 129 132 private Expression evaluateReturnExpressions(AST ast, ITypeBinding returnBinding, int returnOffset) { 133 CompilationUnit root= (CompilationUnit) fMethodDecl.getRoot(); 134 135 Expression result= null; 136 if (returnBinding != null) { 137 ScopeAnalyzer analyzer= new ScopeAnalyzer(root); 138 IBinding[] bindings= analyzer.getDeclarationsInScope(returnOffset, ScopeAnalyzer.VARIABLES | ScopeAnalyzer.CHECK_VISIBILITY ); 139 for (int i= 0; i < bindings.length; i++) { 140 IVariableBinding curr= (IVariableBinding) bindings[i]; 141 ITypeBinding type= curr.getType(); 142 if (type != null && type.isAssignmentCompatible(returnBinding) && testModifier(curr)) { 143 if (result == null) { 144 result= ast.newSimpleName(curr.getName()); 145 } 146 addLinkedPositionProposal(RETURN_EXPRESSION_KEY, curr.getName(), null); 147 } 148 } 149 } 150 Expression defaultExpression= ASTNodeFactory.newDefaultExpression(ast, fMethodDecl.getReturnType2(), fMethodDecl.getExtraDimensions()); 151 addLinkedPositionProposal(RETURN_EXPRESSION_KEY, ASTNodes.asString(defaultExpression), null); 152 if (result == null) { 153 return defaultExpression; 154 } 155 return result; 156 } 157 158 private boolean testModifier(IVariableBinding curr) { 159 int modifiers= curr.getModifiers(); 160 int staticFinal= Modifier.STATIC | Modifier.FINAL; 161 if ((modifiers & staticFinal) == staticFinal) { 162 return false; 163 } 164 if (Modifier.isStatic(modifiers) && !Modifier.isStatic(fMethodDecl.getModifiers())) { 165 return false; 166 } 167 return true; 168 } 169 170 } 171 | Popular Tags |