KickJava   Java API By Example, From Geeks To Geeks.

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


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
12 package org.eclipse.jdt.internal.ui.text.correction;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.core.runtime.Assert;
18 import org.eclipse.core.runtime.CoreException;
19
20 import org.eclipse.swt.graphics.Image;
21
22 import org.eclipse.jdt.core.ICompilationUnit;
23 import org.eclipse.jdt.core.dom.AST;
24 import org.eclipse.jdt.core.dom.ASTNode;
25 import org.eclipse.jdt.core.dom.Block;
26 import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
27 import org.eclipse.jdt.core.dom.CompilationUnit;
28 import org.eclipse.jdt.core.dom.ITypeBinding;
29 import org.eclipse.jdt.core.dom.IVariableBinding;
30 import org.eclipse.jdt.core.dom.Javadoc;
31 import org.eclipse.jdt.core.dom.MethodDeclaration;
32 import org.eclipse.jdt.core.dom.PrimitiveType;
33 import org.eclipse.jdt.core.dom.ReturnStatement;
34 import org.eclipse.jdt.core.dom.SimpleName;
35 import org.eclipse.jdt.core.dom.Type;
36 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
37 import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
38
39 import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings;
40 import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
41 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
42 import org.eclipse.jdt.internal.corext.dom.Bindings;
43
44 import org.eclipse.jdt.ui.CodeGeneration;
45
46 import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings;
47
48 public abstract class AbstractMethodCompletionProposal extends LinkedCorrectionProposal {
49
50     private ASTNode fNode;
51     private ITypeBinding fSenderBinding;
52
53     public AbstractMethodCompletionProposal(String JavaDoc label, ICompilationUnit targetCU, ASTNode invocationNode, ITypeBinding binding, int relevance, Image image) {
54         super(label, targetCU, null, relevance, image);
55
56         Assert.isTrue(binding != null && Bindings.isDeclarationBinding(binding));
57
58         fNode= invocationNode;
59         fSenderBinding= binding;
60     }
61
62     protected ASTNode getInvocationNode() {
63         return fNode;
64     }
65
66     /**
67      * @return The binding of the type declaration (generic type)
68      */

69     protected ITypeBinding getSenderBinding() {
70         return fSenderBinding;
71     }
72
73     protected ASTRewrite getRewrite() throws CoreException {
74         CompilationUnit astRoot= ASTResolving.findParentCompilationUnit(fNode);
75         ASTNode typeDecl= astRoot.findDeclaringNode(fSenderBinding);
76         ASTNode newTypeDecl= null;
77         boolean isInDifferentCU;
78         if (typeDecl != null) {
79             isInDifferentCU= false;
80             newTypeDecl= typeDecl;
81         } else {
82             isInDifferentCU= true;
83             astRoot= ASTResolving.createQuickFixAST(getCompilationUnit(), null);
84             newTypeDecl= astRoot.findDeclaringNode(fSenderBinding.getKey());
85         }
86         createImportRewrite(astRoot);
87         
88         if (newTypeDecl != null) {
89             ASTRewrite rewrite= ASTRewrite.create(astRoot.getAST());
90
91             MethodDeclaration newStub= getStub(rewrite, newTypeDecl);
92
93             ChildListPropertyDescriptor property= ASTNodes.getBodyDeclarationsProperty(newTypeDecl);
94             List JavaDoc members= (List JavaDoc) newTypeDecl.getStructuralProperty(property);
95
96             int insertIndex;
97             if (isConstructor()) {
98                 insertIndex= findConstructorInsertIndex(members);
99             } else if (!isInDifferentCU) {
100                 insertIndex= findMethodInsertIndex(members, fNode.getStartPosition());
101             } else {
102                 insertIndex= members.size();
103             }
104             ListRewrite listRewriter= rewrite.getListRewrite(newTypeDecl, property);
105             listRewriter.insertAt(newStub, insertIndex, null);
106
107             return rewrite;
108         }
109         return null;
110     }
111
112     private MethodDeclaration getStub(ASTRewrite rewrite, ASTNode targetTypeDecl) throws CoreException {
113         AST ast= targetTypeDecl.getAST();
114         MethodDeclaration decl= ast.newMethodDeclaration();
115
116         SimpleName newNameNode= getNewName(rewrite);
117
118         decl.setConstructor(isConstructor());
119         
120         addNewModifiers(rewrite, targetTypeDecl, decl.modifiers());
121
122         ArrayList JavaDoc takenNames= new ArrayList JavaDoc();
123         addNewTypeParameters(rewrite, takenNames, decl.typeParameters());
124
125         decl.setName(newNameNode);
126
127         IVariableBinding[] declaredFields= fSenderBinding.getDeclaredFields();
128         for (int i= 0; i < declaredFields.length; i++) { // avoid to take parameter names that are equal to field names
129
takenNames.add(declaredFields[i].getName());
130         }
131
132         String JavaDoc bodyStatement= ""; //$NON-NLS-1$
133
if (!isConstructor()) {
134             Type returnType= getNewMethodType(rewrite);
135             if (returnType == null) {
136                 decl.setReturnType2(ast.newPrimitiveType(PrimitiveType.VOID));
137             } else {
138                 decl.setReturnType2(returnType);
139             }
140             if (!fSenderBinding.isInterface() && returnType != null) {
141                 ReturnStatement returnStatement= ast.newReturnStatement();
142                 returnStatement.setExpression(ASTNodeFactory.newDefaultExpression(ast, returnType, 0));
143                 bodyStatement= ASTNodes.asFormattedString(returnStatement, 0, String.valueOf('\n'), getCompilationUnit().getJavaProject().getOptions(true));
144             }
145         }
146         
147         addNewParameters(rewrite, takenNames, decl.parameters());
148         addNewExceptions(rewrite, decl.thrownExceptions());
149
150         Block body= null;
151         if (!fSenderBinding.isInterface()) {
152             body= ast.newBlock();
153             String JavaDoc placeHolder= CodeGeneration.getMethodBodyContent(getCompilationUnit(), fSenderBinding.getName(), newNameNode.getIdentifier(), isConstructor(), bodyStatement, String.valueOf('\n'));
154             if (placeHolder != null) {
155                 ASTNode todoNode= rewrite.createStringPlaceholder(placeHolder, ASTNode.RETURN_STATEMENT);
156                 body.statements().add(todoNode);
157             }
158         }
159         decl.setBody(body);
160
161         CodeGenerationSettings settings= JavaPreferencesSettings.getCodeGenerationSettings(getCompilationUnit().getJavaProject());
162         if (settings.createComments && !fSenderBinding.isAnonymous()) {
163             String JavaDoc string= CodeGeneration.getMethodComment(getCompilationUnit(), fSenderBinding.getName(), decl, null, String.valueOf('\n'));
164             if (string != null) {
165                 Javadoc javadoc= (Javadoc) rewrite.createStringPlaceholder(string, ASTNode.JAVADOC);
166                 decl.setJavadoc(javadoc);
167             }
168         }
169         return decl;
170     }
171
172
173
174     private int findMethodInsertIndex(List JavaDoc decls, int currPos) {
175         int nDecls= decls.size();
176         for (int i= 0; i < nDecls; i++) {
177             ASTNode curr= (ASTNode) decls.get(i);
178             if (curr instanceof MethodDeclaration && currPos < curr.getStartPosition() + curr.getLength()) {
179                 return i + 1;
180             }
181         }
182         return nDecls;
183     }
184
185     private int findConstructorInsertIndex(List JavaDoc decls) {
186         int nDecls= decls.size();
187         int lastMethod= 0;
188         for (int i= nDecls - 1; i >= 0; i--) {
189             ASTNode curr= (ASTNode) decls.get(i);
190             if (curr instanceof MethodDeclaration) {
191                 if (((MethodDeclaration) curr).isConstructor()) {
192                     return i + 1;
193                 }
194                 lastMethod= i;
195             }
196         }
197         return lastMethod;
198     }
199
200     protected abstract boolean isConstructor();
201
202     protected abstract void addNewModifiers(ASTRewrite rewrite, ASTNode targetTypeDecl, List JavaDoc exceptions);
203     protected abstract void addNewTypeParameters(ASTRewrite rewrite, List JavaDoc takenNames, List JavaDoc params) throws CoreException;
204     protected abstract void addNewParameters(ASTRewrite rewrite, List JavaDoc takenNames, List JavaDoc params) throws CoreException;
205     protected abstract void addNewExceptions(ASTRewrite rewrite, List JavaDoc exceptions) throws CoreException;
206
207     protected abstract SimpleName getNewName(ASTRewrite rewrite);
208     protected abstract Type getNewMethodType(ASTRewrite rewrite) throws CoreException;
209
210
211 }
212
Popular Tags