]> git.uio.no Git - ifi-stolz-refaktor.git/blame - case-study/jdt-before/ui/org/eclipse/jdt/internal/ui/text/correction/proposals/ConstructorFromSuperclassProposal.java
Some talks, mostly identical.
[ifi-stolz-refaktor.git] / case-study / jdt-before / ui / org / eclipse / jdt / internal / ui / text / correction / proposals / ConstructorFromSuperclassProposal.java
CommitLineData
1b2798f6
EK
1/*******************************************************************************
2 * Copyright (c) 2000, 2011 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
12package org.eclipse.jdt.internal.ui.text.correction.proposals;
13
14import java.util.List;
15
16import org.eclipse.swt.graphics.Image;
17
18import org.eclipse.core.runtime.CoreException;
19
20import org.eclipse.jdt.core.ICompilationUnit;
21import org.eclipse.jdt.core.dom.AST;
22import org.eclipse.jdt.core.dom.ASTNode;
23import org.eclipse.jdt.core.dom.Block;
24import org.eclipse.jdt.core.dom.CompilationUnit;
25import org.eclipse.jdt.core.dom.Expression;
26import org.eclipse.jdt.core.dom.IMethodBinding;
27import org.eclipse.jdt.core.dom.ITypeBinding;
28import org.eclipse.jdt.core.dom.Javadoc;
29import org.eclipse.jdt.core.dom.MethodDeclaration;
30import org.eclipse.jdt.core.dom.Modifier;
31import org.eclipse.jdt.core.dom.Name;
32import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
33import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
34import org.eclipse.jdt.core.dom.TypeDeclaration;
35import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
36import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext;
37
38import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings;
39import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext;
40import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
41import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
42import org.eclipse.jdt.internal.corext.dom.ASTNodes;
43import org.eclipse.jdt.internal.corext.dom.Bindings;
44import org.eclipse.jdt.internal.corext.util.Messages;
45
46import org.eclipse.jdt.ui.CodeGeneration;
47import org.eclipse.jdt.ui.JavaElementImageDescriptor;
48
49import org.eclipse.jdt.internal.ui.JavaPlugin;
50import org.eclipse.jdt.internal.ui.JavaPluginImages;
51import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings;
52import org.eclipse.jdt.internal.ui.text.correction.CorrectionMessages;
53import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;
54import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider;
55
56public class ConstructorFromSuperclassProposal extends LinkedCorrectionProposal {
57
58 private TypeDeclaration fTypeNode;
59 private IMethodBinding fSuperConstructor;
60
61 public ConstructorFromSuperclassProposal(ICompilationUnit cu, TypeDeclaration typeNode, IMethodBinding superConstructor, int relevance) {
62 super("", cu, null, relevance, null); //$NON-NLS-1$
63 fTypeNode= typeNode;
64 fSuperConstructor= superConstructor;
65 }
66
67 /* (non-Javadoc)
68 * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getImage()
69 */
70 @Override
71 public Image getImage() {
72 return JavaPlugin.getImageDescriptorRegistry().get(
73 new JavaElementImageDescriptor(JavaPluginImages.DESC_MISC_PUBLIC, JavaElementImageDescriptor.CONSTRUCTOR, JavaElementImageProvider.SMALL_SIZE)
74 );
75 }
76
77 /* (non-Javadoc)
78 * @see org.eclipse.jdt.internal.ui.text.correction.proposals.ChangeCorrectionProposal#getName()
79 */
80 @Override
81 public String getName() {
82 StringBuffer buf= new StringBuffer();
83 buf.append(fTypeNode.getName().getIdentifier());
84 buf.append('(');
85 if (fSuperConstructor != null) {
86 ITypeBinding[] paramTypes= fSuperConstructor.getParameterTypes();
87 for (int i= 0; i < paramTypes.length; i++) {
88 if (i > 0) {
89 buf.append(',');
90 }
91 buf.append(paramTypes[i].getName());
92 }
93 }
94 buf.append(')');
95 return Messages.format(CorrectionMessages.ConstructorFromSuperclassProposal_description, BasicElementLabels.getJavaElementName(buf.toString()));
96 }
97
98 /* (non-Javadoc)
99 * @see org.eclipse.jdt.internal.ui.text.correction.ASTRewriteCorrectionProposal#getRewrite()
100 */
101 @Override
102 protected ASTRewrite getRewrite() throws CoreException {
103 AST ast= fTypeNode.getAST();
104
105 ASTRewrite rewrite= ASTRewrite.create(ast);
106
107 createImportRewrite((CompilationUnit) fTypeNode.getRoot());
108
109 CodeGenerationSettings settings= JavaPreferencesSettings.getCodeGenerationSettings(getCompilationUnit().getJavaProject());
110 if (!settings.createComments) {
111 settings= null;
112 }
113 ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(fTypeNode, getImportRewrite());
114
115 MethodDeclaration newMethodDecl= createNewMethodDeclaration(ast, fSuperConstructor, rewrite, importRewriteContext, settings);
116 rewrite.getListRewrite(fTypeNode, TypeDeclaration.BODY_DECLARATIONS_PROPERTY).insertFirst(newMethodDecl, null);
117
118 addLinkedRanges(rewrite, newMethodDecl);
119
120 return rewrite;
121 }
122
123 private void addLinkedRanges(ASTRewrite rewrite, MethodDeclaration newStub) {
124 List<SingleVariableDeclaration> parameters= newStub.parameters();
125 for (int i= 0; i < parameters.size(); i++) {
126 SingleVariableDeclaration curr= parameters.get(i);
127 String name= curr.getName().getIdentifier();
128 addLinkedPosition(rewrite.track(curr.getType()), false, "arg_type_" + name); //$NON-NLS-1$
129 addLinkedPosition(rewrite.track(curr.getName()), false, "arg_name_" + name); //$NON-NLS-1$
130 }
131 }
132
133 private MethodDeclaration createNewMethodDeclaration(AST ast, IMethodBinding binding, ASTRewrite rewrite, ImportRewriteContext importRewriteContext, CodeGenerationSettings commentSettings) throws CoreException {
134 String name= fTypeNode.getName().getIdentifier();
135 MethodDeclaration decl= ast.newMethodDeclaration();
136 decl.setConstructor(true);
137 decl.setName(ast.newSimpleName(name));
138 Block body= ast.newBlock();
139 decl.setBody(body);
140
141 SuperConstructorInvocation invocation= null;
142
143 List<SingleVariableDeclaration> parameters= decl.parameters();
144 String[] paramNames= getArgumentNames(binding);
145
146 ITypeBinding enclosingInstance= getEnclosingInstance();
147 if (enclosingInstance != null) {
148 invocation= addEnclosingInstanceAccess(rewrite, importRewriteContext, parameters, paramNames, enclosingInstance);
149 }
150
151 if (binding == null) {
152 decl.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD));
153 } else {
154 decl.modifiers().addAll(ASTNodeFactory.newModifiers(ast, binding.getModifiers()));
155
156 ITypeBinding[] params= binding.getParameterTypes();
157 for (int i= 0; i < params.length; i++) {
158 SingleVariableDeclaration var= ast.newSingleVariableDeclaration();
159 var.setType(getImportRewrite().addImport(params[i], ast, importRewriteContext));
160 var.setName(ast.newSimpleName(paramNames[i]));
161 parameters.add(var);
162 }
163
164 List<Name> thrownExceptions= decl.thrownExceptions();
165 ITypeBinding[] excTypes= binding.getExceptionTypes();
166 for (int i= 0; i < excTypes.length; i++) {
167 String excTypeName= getImportRewrite().addImport(excTypes[i], importRewriteContext);
168 thrownExceptions.add(ASTNodeFactory.newName(ast, excTypeName));
169 }
170
171 if (invocation == null) {
172 invocation= ast.newSuperConstructorInvocation();
173 }
174
175 List<Expression> arguments= invocation.arguments();
176 for (int i= 0; i < paramNames.length; i++) {
177 Name argument= ast.newSimpleName(paramNames[i]);
178 arguments.add(argument);
179 addLinkedPosition(rewrite.track(argument), false, "arg_name_" + paramNames[i]); //$NON-NLS-1$
180 }
181 }
182
183 String bodyStatement= (invocation == null) ? "" : ASTNodes.asFormattedString(invocation, 0, String.valueOf('\n'), getCompilationUnit().getJavaProject().getOptions(true)); //$NON-NLS-1$
184 String placeHolder= CodeGeneration.getMethodBodyContent(getCompilationUnit(), name, name, true, bodyStatement, String.valueOf('\n'));
185 if (placeHolder != null) {
186 ASTNode todoNode= rewrite.createStringPlaceholder(placeHolder, ASTNode.RETURN_STATEMENT);
187 body.statements().add(todoNode);
188 }
189 if (commentSettings != null) {
190 String string= CodeGeneration.getMethodComment(getCompilationUnit(), name, decl, null, String.valueOf('\n'));
191 if (string != null) {
192 Javadoc javadoc= (Javadoc) rewrite.createStringPlaceholder(string, ASTNode.JAVADOC);
193 decl.setJavadoc(javadoc);
194 }
195 }
196 return decl;
197 }
198
199 private SuperConstructorInvocation addEnclosingInstanceAccess(ASTRewrite rewrite, ImportRewriteContext importRewriteContext, List<SingleVariableDeclaration> parameters, String[] paramNames, ITypeBinding enclosingInstance) {
200 AST ast= rewrite.getAST();
201 SuperConstructorInvocation invocation= ast.newSuperConstructorInvocation();
202
203 SingleVariableDeclaration var= ast.newSingleVariableDeclaration();
204 var.setType(getImportRewrite().addImport(enclosingInstance, ast, importRewriteContext));
205 String[] enclosingArgNames= StubUtility.getArgumentNameSuggestions(getCompilationUnit().getJavaProject(), enclosingInstance.getTypeDeclaration().getName(), 0, paramNames);
206 String firstName= enclosingArgNames[0];
207 var.setName(ast.newSimpleName(firstName));
208 parameters.add(var);
209
210 Name enclosing= ast.newSimpleName(firstName);
211 invocation.setExpression(enclosing);
212
213 String key= "arg_name_" + firstName; //$NON-NLS-1$
214 addLinkedPosition(rewrite.track(enclosing), false, key);
215 for (int i= 0; i < enclosingArgNames.length; i++) {
216 addLinkedPositionProposal(key, enclosingArgNames[i], null); // alternative names
217 }
218 return invocation;
219 }
220
221 private ITypeBinding getEnclosingInstance() {
222 ITypeBinding currBinding= fTypeNode.resolveBinding();
223 if (currBinding == null || Modifier.isStatic(currBinding.getModifiers())) {
224 return null;
225 }
226 ITypeBinding superBinding= currBinding.getSuperclass();
227 if (superBinding == null || superBinding.getDeclaringClass() == null || Modifier.isStatic(superBinding.getModifiers())) {
228 return null;
229 }
230 ITypeBinding enclosing= superBinding.getDeclaringClass();
231
232 while (currBinding != null) {
233 if (Bindings.isSuperType(enclosing, currBinding)) {
234 return null; // enclosing in scope
235 }
236 if (Modifier.isStatic(currBinding.getModifiers())) {
237 return null; // no more enclosing instances
238 }
239 currBinding= currBinding.getDeclaringClass();
240 }
241 return enclosing;
242 }
243
244
245 private String[] getArgumentNames(IMethodBinding binding) {
246 if (binding == null) {
247 return new String[0];
248 }
249 return StubUtility.suggestArgumentNames(getCompilationUnit().getJavaProject(), binding);
250 }
251}