KickJava   Java API By Example, From Geeks To Geeks.

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


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.List JavaDoc;
15
16 import org.eclipse.core.runtime.CoreException;
17
18 import org.eclipse.swt.graphics.Image;
19
20 import org.eclipse.jdt.core.ICompilationUnit;
21 import org.eclipse.jdt.core.dom.AST;
22 import org.eclipse.jdt.core.dom.ASTNode;
23 import org.eclipse.jdt.core.dom.Block;
24 import org.eclipse.jdt.core.dom.CompilationUnit;
25 import org.eclipse.jdt.core.dom.IMethodBinding;
26 import org.eclipse.jdt.core.dom.ITypeBinding;
27 import org.eclipse.jdt.core.dom.Javadoc;
28 import org.eclipse.jdt.core.dom.MethodDeclaration;
29 import org.eclipse.jdt.core.dom.Modifier;
30 import org.eclipse.jdt.core.dom.Name;
31 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
32 import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
33 import org.eclipse.jdt.core.dom.TypeDeclaration;
34 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
35
36 import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings;
37 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
38 import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
39 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
40 import org.eclipse.jdt.internal.corext.dom.Bindings;
41 import org.eclipse.jdt.internal.corext.util.Messages;
42
43 import org.eclipse.jdt.ui.CodeGeneration;
44 import org.eclipse.jdt.ui.JavaElementImageDescriptor;
45
46 import org.eclipse.jdt.internal.ui.JavaPlugin;
47 import org.eclipse.jdt.internal.ui.JavaPluginImages;
48 import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings;
49 import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider;
50
51 public class ConstructorFromSuperclassProposal extends LinkedCorrectionProposal {
52
53     private TypeDeclaration fTypeNode;
54     private IMethodBinding fSuperConstructor;
55
56     public ConstructorFromSuperclassProposal(ICompilationUnit cu, TypeDeclaration typeNode, IMethodBinding superConstructor, int relevance) {
57         super("", cu, null, relevance, null); //$NON-NLS-1$
58
fTypeNode= typeNode;
59         fSuperConstructor= superConstructor;
60     }
61
62     /**
63      * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getImage()
64      */

65     public Image getImage() {
66         return JavaPlugin.getImageDescriptorRegistry().get(
67             new JavaElementImageDescriptor(JavaPluginImages.DESC_MISC_PUBLIC, JavaElementImageDescriptor.CONSTRUCTOR, JavaElementImageProvider.SMALL_SIZE)
68         );
69     }
70
71     /**
72      * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getDisplayString()
73      */

74     public String JavaDoc getDisplayString() {
75         StringBuffer JavaDoc buf= new StringBuffer JavaDoc();
76         buf.append(fTypeNode.getName().getIdentifier());
77         buf.append('(');
78         if (fSuperConstructor != null) {
79             ITypeBinding[] paramTypes= fSuperConstructor.getParameterTypes();
80             for (int i= 0; i < paramTypes.length; i++) {
81                 if (i > 0) {
82                     buf.append(',');
83                 }
84                 buf.append(paramTypes[i].getName());
85             }
86         }
87         buf.append(')');
88         return Messages.format(CorrectionMessages.ConstructorFromSuperclassProposal_description, buf.toString());
89     }
90
91     /* (non-Javadoc)
92      * @see org.eclipse.jdt.internal.ui.text.correction.ASTRewriteCorrectionProposal#getRewrite()
93      */

94     protected ASTRewrite getRewrite() throws CoreException {
95         AST ast= fTypeNode.getAST();
96
97         ASTRewrite rewrite= ASTRewrite.create(ast);
98         
99         createImportRewrite((CompilationUnit) fTypeNode.getRoot());
100         
101         CodeGenerationSettings settings= JavaPreferencesSettings.getCodeGenerationSettings(getCompilationUnit().getJavaProject());
102         if (!settings.createComments) {
103             settings= null;
104         }
105
106         MethodDeclaration newMethodDecl= createNewMethodDeclaration(ast, fSuperConstructor, rewrite, settings);
107         rewrite.getListRewrite(fTypeNode, TypeDeclaration.BODY_DECLARATIONS_PROPERTY).insertFirst(newMethodDecl, null);
108
109         addLinkedRanges(rewrite, newMethodDecl);
110
111         return rewrite;
112     }
113
114     private void addLinkedRanges(ASTRewrite rewrite, MethodDeclaration newStub) {
115         List JavaDoc parameters= newStub.parameters();
116         for (int i= 0; i < parameters.size(); i++) {
117             SingleVariableDeclaration curr= (SingleVariableDeclaration) parameters.get(i);
118             String JavaDoc name= curr.getName().getIdentifier();
119             addLinkedPosition(rewrite.track(curr.getType()), false, "arg_type_" + name); //$NON-NLS-1$
120
addLinkedPosition(rewrite.track(curr.getName()), false, "arg_name_" + name); //$NON-NLS-1$
121
}
122     }
123
124     private MethodDeclaration createNewMethodDeclaration(AST ast, IMethodBinding binding, ASTRewrite rewrite, CodeGenerationSettings commentSettings) throws CoreException {
125         String JavaDoc name= fTypeNode.getName().getIdentifier();
126         MethodDeclaration decl= ast.newMethodDeclaration();
127         decl.setConstructor(true);
128         decl.setName(ast.newSimpleName(name));
129         Block body= ast.newBlock();
130         decl.setBody(body);
131
132         SuperConstructorInvocation invocation= null;
133
134         List JavaDoc parameters= decl.parameters();
135         String JavaDoc[] paramNames= getArgumentNames(binding);
136
137         ITypeBinding enclosingInstance= getEnclosingInstance();
138         if (enclosingInstance != null) {
139             invocation= addEnclosingInstanceAccess(rewrite, parameters, paramNames, enclosingInstance);
140         }
141
142         if (binding == null) {
143             decl.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD));
144         } else {
145             decl.modifiers().addAll(ASTNodeFactory.newModifiers(ast, binding.getModifiers()));
146
147             ITypeBinding[] params= binding.getParameterTypes();
148             for (int i= 0; i < params.length; i++) {
149                 SingleVariableDeclaration var= ast.newSingleVariableDeclaration();
150                 var.setType(getImportRewrite().addImport(params[i], ast));
151                 var.setName(ast.newSimpleName(paramNames[i]));
152                 parameters.add(var);
153             }
154
155             List JavaDoc thrownExceptions= decl.thrownExceptions();
156             ITypeBinding[] excTypes= binding.getExceptionTypes();
157             for (int i= 0; i < excTypes.length; i++) {
158                 String JavaDoc excTypeName= getImportRewrite().addImport(excTypes[i]);
159                 thrownExceptions.add(ASTNodeFactory.newName(ast, excTypeName));
160             }
161
162             if (invocation == null) {
163                 invocation= ast.newSuperConstructorInvocation();
164             }
165
166             List JavaDoc arguments= invocation.arguments();
167             for (int i= 0; i < paramNames.length; i++) {
168                 Name argument= ast.newSimpleName(paramNames[i]);
169                 arguments.add(argument);
170                 addLinkedPosition(rewrite.track(argument), false, "arg_name_" + paramNames[i]); //$NON-NLS-1$
171
}
172         }
173
174         String JavaDoc bodyStatement= (invocation == null) ? "" : ASTNodes.asFormattedString(invocation, 0, String.valueOf('\n'), getCompilationUnit().getJavaProject().getOptions(true)); //$NON-NLS-1$
175
String JavaDoc placeHolder= CodeGeneration.getMethodBodyContent(getCompilationUnit(), name, name, true, bodyStatement, String.valueOf('\n'));
176         if (placeHolder != null) {
177             ASTNode todoNode= rewrite.createStringPlaceholder(placeHolder, ASTNode.RETURN_STATEMENT);
178             body.statements().add(todoNode);
179         }
180         if (commentSettings != null) {
181             String JavaDoc string= CodeGeneration.getMethodComment(getCompilationUnit(), name, decl, null, String.valueOf('\n'));
182             if (string != null) {
183                 Javadoc javadoc= (Javadoc) rewrite.createStringPlaceholder(string, ASTNode.JAVADOC);
184                 decl.setJavadoc(javadoc);
185             }
186         }
187         return decl;
188     }
189
190     private SuperConstructorInvocation addEnclosingInstanceAccess(ASTRewrite rewrite, List JavaDoc parameters, String JavaDoc[] paramNames, ITypeBinding enclosingInstance) throws CoreException {
191         AST ast= rewrite.getAST();
192         SuperConstructorInvocation invocation= ast.newSuperConstructorInvocation();
193
194         SingleVariableDeclaration var= ast.newSingleVariableDeclaration();
195         var.setType(getImportRewrite().addImport(enclosingInstance, ast));
196         String JavaDoc[] enclosingArgNames= StubUtility.getArgumentNameSuggestions(getCompilationUnit().getJavaProject(), enclosingInstance.getTypeDeclaration().getName(), 0, paramNames);
197         String JavaDoc firstName= enclosingArgNames[0];
198         var.setName(ast.newSimpleName(firstName));
199         parameters.add(var);
200
201         Name enclosing= ast.newSimpleName(firstName);
202         invocation.setExpression(enclosing);
203
204         String JavaDoc key= "arg_name_" + firstName; //$NON-NLS-1$
205
addLinkedPosition(rewrite.track(enclosing), false, key);
206         for (int i= 0; i < enclosingArgNames.length; i++) {
207             addLinkedPositionProposal(key, enclosingArgNames[i], null); // alternative names
208
}
209         return invocation;
210     }
211
212     private ITypeBinding getEnclosingInstance() {
213         ITypeBinding currBinding= fTypeNode.resolveBinding();
214         if (currBinding == null || Modifier.isStatic(currBinding.getModifiers())) {
215             return null;
216         }
217         ITypeBinding superBinding= currBinding.getSuperclass();
218         if (superBinding == null || superBinding.getDeclaringClass() == null || Modifier.isStatic(superBinding.getModifiers())) {
219             return null;
220         }
221         ITypeBinding enclosing= superBinding.getDeclaringClass();
222
223         while (currBinding != null) {
224             if (Bindings.isSuperType(enclosing, currBinding)) {
225                 return null; // enclosing in scope
226
}
227             if (Modifier.isStatic(currBinding.getModifiers())) {
228                 return null; // no more enclosing instances
229
}
230             currBinding= currBinding.getDeclaringClass();
231         }
232         return enclosing;
233     }
234
235
236     private String JavaDoc[] getArgumentNames(IMethodBinding binding) {
237         if (binding == null) {
238             return new String JavaDoc[0];
239         }
240         return StubUtility.suggestArgumentNames(getCompilationUnit().getJavaProject(), binding);
241     }
242 }
243
Popular Tags