KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 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.List JavaDoc;
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 JavaDoc RETURN_EXPRESSION_KEY= "value"; //$NON-NLS-1$
40

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)); //$NON-NLS-1$
46
fMethodDecl= decl;
47         fExistingReturn= existingReturn;
48     }
49
50     public String JavaDoc getDisplayString() {
51         if (fExistingReturn != null) {
52             return CorrectionMessages.MissingReturnTypeCorrectionProposal_changereturnstatement_description;
53         } else {
54             return CorrectionMessages.MissingReturnTypeCorrectionProposal_addreturnstatement_description;
55         }
56     }
57
58     /*(non-Javadoc)
59      * @see org.eclipse.jdt.internal.ui.text.correction.ASTRewriteCorrectionProposal#getRewrite()
60      */

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 JavaDoc 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     /*
130      * Evaluates possible return expressions. The favourite expression is returned.
131      */

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