]>
Commit | Line | Data |
---|---|---|
1b2798f6 EK |
1 | /******************************************************************************* |
2 | * Copyright (c) 2007, 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 | package org.eclipse.jdt.internal.corext.refactoring.structure; | |
12 | ||
13 | import java.util.ArrayList; | |
14 | import java.util.Arrays; | |
15 | import java.util.HashSet; | |
16 | import java.util.Iterator; | |
17 | import java.util.LinkedHashMap; | |
18 | import java.util.List; | |
19 | import java.util.Map; | |
20 | import java.util.Set; | |
21 | ||
22 | import org.eclipse.core.runtime.Assert; | |
23 | import org.eclipse.core.runtime.CoreException; | |
24 | import org.eclipse.core.runtime.IProgressMonitor; | |
25 | import org.eclipse.core.runtime.OperationCanceledException; | |
26 | import org.eclipse.core.runtime.SubProgressMonitor; | |
27 | ||
28 | import org.eclipse.text.edits.TextEditGroup; | |
29 | ||
30 | import org.eclipse.ltk.core.refactoring.Change; | |
31 | import org.eclipse.ltk.core.refactoring.Refactoring; | |
32 | import org.eclipse.ltk.core.refactoring.RefactoringDescriptor; | |
33 | import org.eclipse.ltk.core.refactoring.RefactoringStatus; | |
34 | import org.eclipse.ltk.core.refactoring.resource.ResourceChange; | |
35 | ||
36 | import org.eclipse.jdt.core.Flags; | |
37 | import org.eclipse.jdt.core.ICompilationUnit; | |
38 | import org.eclipse.jdt.core.IField; | |
39 | import org.eclipse.jdt.core.IJavaElement; | |
40 | import org.eclipse.jdt.core.IJavaProject; | |
41 | import org.eclipse.jdt.core.IPackageFragment; | |
42 | import org.eclipse.jdt.core.IPackageFragmentRoot; | |
43 | import org.eclipse.jdt.core.IType; | |
44 | import org.eclipse.jdt.core.ITypeRoot; | |
45 | import org.eclipse.jdt.core.JavaModelException; | |
46 | import org.eclipse.jdt.core.NamingConventions; | |
47 | import org.eclipse.jdt.core.Signature; | |
48 | import org.eclipse.jdt.core.dom.AST; | |
49 | import org.eclipse.jdt.core.dom.ASTNode; | |
50 | import org.eclipse.jdt.core.dom.ASTVisitor; | |
51 | import org.eclipse.jdt.core.dom.ArrayCreation; | |
52 | import org.eclipse.jdt.core.dom.ArrayInitializer; | |
53 | import org.eclipse.jdt.core.dom.Assignment; | |
54 | import org.eclipse.jdt.core.dom.ClassInstanceCreation; | |
55 | import org.eclipse.jdt.core.dom.CompilationUnit; | |
56 | import org.eclipse.jdt.core.dom.Expression; | |
57 | import org.eclipse.jdt.core.dom.FieldAccess; | |
58 | import org.eclipse.jdt.core.dom.FieldDeclaration; | |
59 | import org.eclipse.jdt.core.dom.IExtendedModifier; | |
60 | import org.eclipse.jdt.core.dom.IPackageBinding; | |
61 | import org.eclipse.jdt.core.dom.ITypeBinding; | |
62 | import org.eclipse.jdt.core.dom.IVariableBinding; | |
63 | import org.eclipse.jdt.core.dom.Javadoc; | |
64 | import org.eclipse.jdt.core.dom.Modifier; | |
65 | import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword; | |
66 | import org.eclipse.jdt.core.dom.NodeFinder; | |
67 | import org.eclipse.jdt.core.dom.NullLiteral; | |
68 | import org.eclipse.jdt.core.dom.QualifiedName; | |
69 | import org.eclipse.jdt.core.dom.SimpleName; | |
70 | import org.eclipse.jdt.core.dom.SuperFieldAccess; | |
71 | import org.eclipse.jdt.core.dom.Type; | |
72 | import org.eclipse.jdt.core.dom.TypeDeclaration; | |
73 | import org.eclipse.jdt.core.dom.VariableDeclaration; | |
74 | import org.eclipse.jdt.core.dom.VariableDeclarationFragment; | |
75 | import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; | |
76 | import org.eclipse.jdt.core.dom.rewrite.ListRewrite; | |
77 | import org.eclipse.jdt.core.refactoring.descriptors.ExtractClassDescriptor; | |
78 | import org.eclipse.jdt.core.refactoring.descriptors.ExtractClassDescriptor.Field; | |
79 | import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor; | |
80 | import org.eclipse.jdt.core.search.IJavaSearchConstants; | |
81 | import org.eclipse.jdt.core.search.SearchMatch; | |
82 | import org.eclipse.jdt.core.search.SearchPattern; | |
83 | ||
84 | import org.eclipse.jdt.internal.corext.codemanipulation.GetterSetterUtil; | |
85 | import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility; | |
86 | import org.eclipse.jdt.internal.corext.dom.ASTNodes; | |
87 | import org.eclipse.jdt.internal.corext.dom.Bindings; | |
88 | import org.eclipse.jdt.internal.corext.dom.TypeBindingVisitor; | |
89 | import org.eclipse.jdt.internal.corext.refactoring.Checks; | |
90 | import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment; | |
91 | import org.eclipse.jdt.internal.corext.refactoring.ParameterInfo; | |
92 | import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; | |
93 | import org.eclipse.jdt.internal.corext.refactoring.RefactoringScopeFactory; | |
94 | import org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine; | |
95 | import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup; | |
96 | import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext; | |
97 | import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange; | |
98 | import org.eclipse.jdt.internal.corext.refactoring.structure.ParameterObjectFactory.CreationListener; | |
99 | import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager; | |
100 | import org.eclipse.jdt.internal.corext.util.JavaModelUtil; | |
101 | import org.eclipse.jdt.internal.corext.util.Messages; | |
102 | ||
103 | import org.eclipse.jdt.internal.ui.JavaPlugin; | |
104 | import org.eclipse.jdt.internal.ui.text.correction.ASTResolving; | |
105 | import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels; | |
106 | ||
107 | public class ExtractClassRefactoring extends Refactoring { | |
108 | ||
109 | public static class ExtractClassDescriptorVerification { | |
110 | private ExtractClassDescriptor fDescriptor; | |
111 | ||
112 | public ExtractClassDescriptorVerification(ExtractClassDescriptor descriptor) { | |
113 | fDescriptor= descriptor; | |
114 | } | |
115 | ||
116 | public RefactoringStatus validateClassName() { | |
117 | RefactoringStatus status= new RefactoringStatus(); | |
118 | status.merge(Checks.checkTypeName(fDescriptor.getClassName(), fDescriptor.getType())); | |
119 | status.merge(checkClass()); | |
120 | return status; | |
121 | } | |
122 | ||
123 | private RefactoringStatus checkClass() { | |
124 | RefactoringStatus status= new RefactoringStatus(); | |
125 | IType type= fDescriptor.getType(); | |
126 | if (!fDescriptor.isCreateTopLevel()) { | |
127 | if (type.getType(fDescriptor.getClassName()).exists()) { | |
128 | status.addError(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_errror_nested_name_clash, new Object[] { BasicElementLabels.getJavaElementName(fDescriptor.getClassName()), BasicElementLabels.getJavaElementName(type.getElementName()) })); | |
129 | } | |
130 | } else { | |
131 | status.merge(checkPackageClass()); | |
132 | } | |
133 | return status; | |
134 | } | |
135 | ||
136 | private RefactoringStatus checkPackageClass() { | |
137 | RefactoringStatus status= new RefactoringStatus(); | |
138 | IType type= fDescriptor.getType(); | |
139 | IPackageFragmentRoot ancestor= (IPackageFragmentRoot) type.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); | |
140 | IPackageFragment packageFragment= ancestor.getPackageFragment(fDescriptor.getPackage()); | |
141 | if (packageFragment.getCompilationUnit(fDescriptor.getClassName() + JavaModelUtil.DEFAULT_CU_SUFFIX).exists()) | |
142 | status.addError(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_error_toplevel_name_clash, new Object[] { BasicElementLabels.getJavaElementName(fDescriptor.getClassName()), BasicElementLabels.getJavaElementName(fDescriptor.getPackage()) })); | |
143 | return status; | |
144 | } | |
145 | ||
146 | public RefactoringStatus validateTopLevel() { | |
147 | return checkClass(); | |
148 | } | |
149 | ||
150 | public RefactoringStatus validateParameterName() { | |
151 | RefactoringStatus status= new RefactoringStatus(); | |
152 | String parameterName= fDescriptor.getFieldName(); | |
153 | IType type= fDescriptor.getType(); | |
154 | status.merge(Checks.checkFieldName(parameterName, type)); | |
155 | validateFieldNames(status, parameterName, type); | |
156 | return status; | |
157 | } | |
158 | ||
159 | private void validateFieldNames(RefactoringStatus status, String parameterName, IType type) { | |
160 | if (type.getField(parameterName).exists()) { | |
161 | Field[] fields= fDescriptor.getFields(); | |
162 | for (int i= 0; i < fields.length; i++) { | |
163 | Field field= fields[i]; | |
164 | if (parameterName.equals(field.getFieldName())){ | |
165 | if (!field.isCreateField()) | |
166 | status.addError(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_error_field_already_exists, BasicElementLabels.getJavaElementName(parameterName))); | |
167 | } | |
168 | } | |
169 | } | |
170 | } | |
171 | ||
172 | public RefactoringStatus validateFields() { | |
173 | RefactoringStatus status= new RefactoringStatus(); | |
174 | Field[] fields= fDescriptor.getFields(); | |
175 | Set<String> names= new HashSet<String>(); | |
176 | for (int i= 0; i < fields.length; i++) { | |
177 | Field field= fields[i]; | |
178 | if (field.isCreateField()) { | |
179 | if (names.contains(field.getNewFieldName())) { | |
180 | status.addError(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_error_duplicate_field_name, BasicElementLabels.getJavaElementName(field.getNewFieldName()))); | |
181 | } | |
182 | names.add(field.getNewFieldName()); | |
183 | status.merge(Checks.checkFieldName(field.getNewFieldName(), fDescriptor.getType())); | |
184 | } | |
185 | } | |
186 | if (names.size() == 0) { | |
187 | status.addError(RefactoringCoreMessages.ExtractClassRefactoring_error_msg_one_field); | |
188 | } | |
189 | validateFieldNames(status, fDescriptor.getFieldName(), fDescriptor.getType()); | |
190 | return status; | |
191 | } | |
192 | ||
193 | public RefactoringStatus validateAll() { | |
194 | RefactoringStatus status= new RefactoringStatus(); | |
195 | status.merge(validateClassName()); //also validates toplevel | |
196 | status.merge(validateFields()); | |
197 | status.merge(validateParameterName()); | |
198 | return status; | |
199 | } | |
200 | } | |
201 | ||
202 | ||
203 | private final class FieldReferenceFinder extends ASTVisitor { | |
204 | public boolean fFieldRefFound= false; | |
205 | ||
206 | private FieldReferenceFinder() { | |
207 | } | |
208 | ||
209 | @Override | |
210 | public boolean visit(FieldAccess node) { | |
211 | IVariableBinding fieldBinding= node.resolveFieldBinding(); | |
212 | return checkVariableBinding(fieldBinding); | |
213 | } | |
214 | ||
215 | @Override | |
216 | public boolean visit(SimpleName node) { | |
217 | IVariableBinding variableBinding= ASTNodes.getVariableBinding(node); | |
218 | return checkVariableBinding(variableBinding); | |
219 | } | |
220 | ||
221 | private boolean checkVariableBinding(IVariableBinding fieldBinding) { | |
222 | if (fieldBinding != null) { | |
223 | if (fieldBinding.isField()) { | |
224 | ITypeBinding declaringClass= fieldBinding.getDeclaringClass(); | |
225 | if ((declaringClass != null) && declaringClass.getQualifiedName().equals(fDescriptor.getType().getFullyQualifiedName())) { | |
226 | FieldInfo fi= fVariables.get(fieldBinding.getName()); | |
227 | if (fi != null && isCreateField(fi) && Bindings.equals(fieldBinding, fi.pi.getOldBinding())) { | |
228 | fFieldRefFound= true; | |
229 | return false; | |
230 | } | |
231 | } | |
232 | } | |
233 | } | |
234 | return true; | |
235 | } | |
236 | } | |
237 | ||
238 | private final class FieldInfo { | |
239 | ParameterInfo pi; | |
240 | VariableDeclarationFragment declaration; | |
241 | IField ifield; | |
242 | String name; | |
243 | Expression initializer; | |
244 | private Boolean hasFieldReferences= null; | |
245 | ||
246 | public boolean hasFieldReference() { | |
247 | if (hasFieldReferences == null) { | |
248 | if (initializer != null) { | |
249 | FieldReferenceFinder frf= new FieldReferenceFinder(); | |
250 | initializer.accept(frf); | |
251 | hasFieldReferences= Boolean.valueOf(frf.fFieldRefFound); | |
252 | } else { | |
253 | hasFieldReferences= Boolean.FALSE; | |
254 | } | |
255 | } | |
256 | return hasFieldReferences.booleanValue(); | |
257 | } | |
258 | ||
259 | private FieldInfo(ParameterInfo parameterInfo, IField ifield) { | |
260 | super(); | |
261 | this.pi= parameterInfo; | |
262 | this.ifield= ifield; | |
263 | this.name= ifield.getElementName(); | |
264 | } | |
265 | } | |
266 | ||
267 | private ExtractClassDescriptor fDescriptor; | |
268 | private Map<String, FieldInfo> fVariables; | |
269 | private CompilationUnitRewrite fBaseCURewrite; | |
270 | private TextChangeManager fChangeManager; | |
271 | private ParameterObjectFactory fParameterObjectFactory; | |
272 | private ExtractClassDescriptorVerification fVerification; | |
273 | ||
274 | public ExtractClassRefactoring(ExtractClassDescriptor descriptor) { | |
275 | fDescriptor= descriptor; | |
276 | IType type= fDescriptor.getType(); | |
277 | if (fDescriptor.getPackage() == null) { | |
278 | fDescriptor.setPackage(type.getPackageFragment().getElementName()); | |
279 | } | |
280 | if (fDescriptor.getClassName() == null) { | |
281 | fDescriptor.setClassName(type.getElementName() + "Data"); //$NON-NLS-1$ | |
282 | } | |
283 | if (fDescriptor.getFieldName() == null) { | |
284 | fDescriptor.setFieldName(StubUtility.getVariableNameSuggestions(NamingConventions.VK_INSTANCE_FIELD, type.getJavaProject(), "data", 0, null, true)[0]); //$NON-NLS-1$ | |
285 | } | |
286 | if (fDescriptor.getFields() == null) { | |
287 | try { | |
288 | fDescriptor.setFields(ExtractClassDescriptor.getFields(type)); | |
289 | } catch (JavaModelException e) { | |
290 | JavaPlugin.log(e); | |
291 | } | |
292 | } | |
293 | fVerification= new ExtractClassDescriptorVerification(descriptor); | |
294 | } | |
295 | ||
296 | ||
297 | @Override | |
298 | public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException { | |
299 | RefactoringStatus result= new RefactoringStatus(); | |
300 | pm.beginTask(RefactoringCoreMessages.ExtractClassRefactoring_progress_msg_check_initial_condition, 5); | |
301 | try { | |
302 | result.merge(fDescriptor.validateDescriptor()); | |
303 | if (!result.isOK()) | |
304 | return result; | |
305 | IType type= fDescriptor.getType(); | |
306 | result.merge(Checks.checkAvailability(type)); | |
307 | if (!result.isOK()) | |
308 | return result; | |
309 | pm.worked(1); | |
310 | Field[] fields= ExtractClassDescriptor.getFields(fDescriptor.getType()); | |
311 | pm.worked(1); | |
312 | if (pm.isCanceled()) | |
313 | throw new OperationCanceledException(); | |
314 | fVariables= new LinkedHashMap<String, FieldInfo>(); | |
315 | if (fields.length == 0) { | |
316 | result.addFatalError(RefactoringCoreMessages.ExtractClassRefactoring_error_no_usable_fields, JavaStatusContext.create(type)); | |
317 | return result; | |
318 | } | |
319 | for (int i= 0; i < fields.length; i++) { | |
320 | Field field= fields[i]; | |
321 | String fieldName= field.getFieldName(); | |
322 | IField declField= type.getField(fieldName); | |
323 | ParameterInfo info= new ParameterInfo(Signature.toString(declField.getTypeSignature()), fieldName, i); | |
324 | fVariables.put(fieldName, new FieldInfo(info, declField)); | |
325 | if (pm.isCanceled()) | |
326 | throw new OperationCanceledException(); | |
327 | } | |
328 | pm.worked(3); | |
329 | } finally { | |
330 | pm.done(); | |
331 | } | |
332 | return result; | |
333 | } | |
334 | ||
335 | @Override | |
336 | public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException { | |
337 | RefactoringStatus result= new RefactoringStatus(); | |
338 | result.merge(fVerification.validateAll()); | |
339 | try { | |
340 | pm.beginTask(RefactoringCoreMessages.ExtractClassRefactoring_progress_final_conditions, 95); | |
341 | for (Iterator<FieldInfo> iter= fVariables.values().iterator(); iter.hasNext();) { | |
342 | FieldInfo fi= iter.next(); | |
343 | boolean createField= isCreateField(fi); | |
344 | if (createField) { | |
345 | IField field= fi.ifield; | |
346 | int flags= field.getFlags(); | |
347 | if (Flags.isStatic(flags)) { | |
348 | result.addFatalError(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_error_field_is_static, BasicElementLabels.getJavaElementName(field.getElementName())), JavaStatusContext.create(field)); | |
349 | return result; | |
350 | } | |
351 | if (Flags.isTransient(flags)) { | |
352 | result.addWarning(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_warning_field_is_transient, BasicElementLabels.getJavaElementName(field.getElementName())), JavaStatusContext.create(field)); | |
353 | } | |
354 | if (Flags.isVolatile(flags)) { | |
355 | result.addWarning(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_warning_field_is_volatile, BasicElementLabels.getJavaElementName(field.getElementName())), JavaStatusContext.create(field)); | |
356 | } | |
357 | } | |
358 | } | |
359 | pm.worked(5); | |
360 | fChangeManager= new TextChangeManager(); | |
361 | fParameterObjectFactory= initializeFactory(); | |
362 | IType type= fDescriptor.getType(); | |
363 | pm.worked(5); | |
364 | ||
365 | FieldDeclaration field= performFieldRewrite(type, fParameterObjectFactory, result); | |
366 | int flags= RefactoringDescriptor.STRUCTURAL_CHANGE | JavaRefactoringDescriptor.JAR_MIGRATION | JavaRefactoringDescriptor.JAR_REFACTORING | JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT; | |
367 | if (!Modifier.isPrivate(field.getModifiers())) | |
368 | flags|= RefactoringDescriptor.MULTI_CHANGE; | |
369 | fDescriptor.setFlags(flags); | |
370 | ||
371 | result.merge(updateReferences(type, fParameterObjectFactory, new SubProgressMonitor(pm, 65))); | |
372 | ||
373 | } finally { | |
374 | pm.done(); | |
375 | } | |
376 | return result; | |
377 | } | |
378 | ||
379 | @Override | |
380 | public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { | |
381 | pm.beginTask(RefactoringCoreMessages.ExtractClassRefactoring_progress_create_change, 10); | |
382 | try { | |
383 | ICompilationUnit typeCU= fDescriptor.getType().getCompilationUnit(); | |
384 | IPackageFragmentRoot packageRoot= (IPackageFragmentRoot) typeCU.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); | |
385 | ArrayList<Change> changes= new ArrayList<Change>(); | |
386 | ||
387 | changes.addAll(createParameterObject(fParameterObjectFactory, packageRoot)); | |
388 | fChangeManager.manage(typeCU, fBaseCURewrite.createChange(true, pm)); | |
389 | changes.addAll(Arrays.asList(fChangeManager.getAllChanges())); | |
390 | String project= fDescriptor.getType().getJavaProject().getElementName(); | |
391 | fDescriptor.setProject(project); | |
392 | fDescriptor.setDescription(getName()); | |
393 | fDescriptor.setComment(createComment()); | |
394 | DynamicValidationRefactoringChange change= new DynamicValidationRefactoringChange(fDescriptor, RefactoringCoreMessages.ExtractClassRefactoring_change_name, changes | |
395 | .toArray(new Change[changes.size()])); | |
396 | return change; | |
397 | } finally { | |
398 | pm.done(); | |
399 | } | |
400 | } | |
401 | ||
402 | private String createComment() { | |
403 | Object[] keys= new Object[] { BasicElementLabels.getJavaElementName(fDescriptor.getClassName()), BasicElementLabels.getJavaElementName(fDescriptor.getType().getElementName()) }; | |
404 | String header= Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_change_comment_header, keys); | |
405 | JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(fDescriptor.getType().getJavaProject().getElementName(), this, header); | |
406 | comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_comment_extracted_class, BasicElementLabels.getJavaElementName(fDescriptor.getClassName()))); | |
407 | ||
408 | if (fDescriptor.isCreateTopLevel()) | |
409 | comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_comment_package, BasicElementLabels.getJavaElementName(fDescriptor.getPackage()))); | |
410 | ||
411 | Field[] fields= fDescriptor.getFields(); | |
412 | ArrayList<String> strings= new ArrayList<String>(); | |
413 | for (int i= 0; i < fields.length; i++) { | |
414 | Field field= fields[i]; | |
415 | if (field.isCreateField()) { | |
416 | strings.add(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_comment_field_renamed, new Object[] { BasicElementLabels.getJavaElementName(field.getFieldName()), BasicElementLabels.getJavaElementName(field.getNewFieldName()) })); | |
417 | } | |
418 | } | |
419 | String fieldString= JDTRefactoringDescriptorComment.createCompositeSetting(RefactoringCoreMessages.ExtractClassRefactoring_comment_move_field, strings.toArray(new String[strings | |
420 | .size()])); | |
421 | comment.addSetting(fieldString); | |
422 | ||
423 | if (fDescriptor.isCreateGetterSetter()) | |
424 | comment.addSetting(RefactoringCoreMessages.ExtractClassRefactoring_comment_getters); | |
425 | ||
426 | comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_comment_fieldname, BasicElementLabels.getJavaElementName(fDescriptor.getFieldName()))); | |
427 | return comment.asString(); | |
428 | } | |
429 | ||
430 | private class FieldUpdate extends CreationListener { | |
431 | @Override | |
432 | public void fieldCreated(CompilationUnitRewrite cuRewrite, FieldDeclaration field, ParameterInfo pi) { | |
433 | FieldInfo fieldInfo= getFieldInfo(pi.getOldName()); | |
434 | FieldDeclaration parent= (FieldDeclaration) fieldInfo.declaration.getParent(); | |
435 | List<IExtendedModifier> modifiers= parent.modifiers(); | |
436 | ListRewrite listRewrite= cuRewrite.getASTRewrite().getListRewrite(field, FieldDeclaration.MODIFIERS2_PROPERTY); | |
437 | for (Iterator<IExtendedModifier> iterator= modifiers.iterator(); iterator.hasNext();) { | |
438 | IExtendedModifier mod= iterator.next(); | |
439 | //Temporarily disabled until initialization of final fields is handled correctly | |
440 | // if (mod.isModifier()) { | |
441 | // Modifier modifier= (Modifier) mod; | |
442 | // if (modifier.isFinal()) | |
443 | // listRewrite.insertLast(moveNode(cuRewrite, modifier), null); | |
444 | // } | |
445 | if (mod.isAnnotation()) { | |
446 | listRewrite.insertFirst(moveNode(cuRewrite, (ASTNode) mod), null); | |
447 | } | |
448 | } | |
449 | if (fieldInfo.initializer != null && fieldInfo.hasFieldReference()) { | |
450 | List<VariableDeclarationFragment> fragments= field.fragments(); | |
451 | for (Iterator<VariableDeclarationFragment> iterator= fragments.iterator(); iterator.hasNext();) { | |
452 | VariableDeclarationFragment vdf= iterator.next(); | |
453 | vdf.setInitializer((Expression) moveNode(cuRewrite, fieldInfo.initializer)); | |
454 | } | |
455 | } | |
456 | if (parent.getJavadoc() != null) { | |
457 | field.setJavadoc((Javadoc) moveNode(cuRewrite, parent.getJavadoc())); | |
458 | } | |
459 | } | |
460 | ||
461 | @Override | |
462 | public boolean isCreateSetter(ParameterInfo pi) { | |
463 | return true; //ignore that the original variable was final | |
464 | } | |
465 | ||
466 | @Override | |
467 | public boolean isUseInConstructor(ParameterInfo pi) { | |
468 | FieldInfo fi= getFieldInfo(pi.getOldName()); | |
469 | return fi.initializer != null && !fi.hasFieldReference(); | |
470 | } | |
471 | } | |
472 | ||
473 | private List<ResourceChange> createParameterObject(ParameterObjectFactory pof, IPackageFragmentRoot packageRoot) throws CoreException { | |
474 | FieldUpdate fieldUpdate= new FieldUpdate(); | |
475 | if (fDescriptor.isCreateTopLevel()) | |
476 | return pof.createTopLevelParameterObject(packageRoot, fieldUpdate); | |
477 | else { | |
478 | CompilationUnit root= fBaseCURewrite.getRoot(); | |
479 | TypeDeclaration typeDecl= (TypeDeclaration) NodeFinder.perform(root, fDescriptor.getType().getSourceRange()); | |
480 | ASTRewrite rewrite= fBaseCURewrite.getASTRewrite(); | |
481 | ListRewrite listRewrite= rewrite.getListRewrite(typeDecl, TypeDeclaration.BODY_DECLARATIONS_PROPERTY); | |
482 | TypeDeclaration paramClass= pof.createClassDeclaration(typeDecl.getName().getFullyQualifiedName(), fBaseCURewrite, fieldUpdate); | |
483 | paramClass.modifiers().add(rewrite.getAST().newModifier(ModifierKeyword.PUBLIC_KEYWORD)); | |
484 | paramClass.modifiers().add(rewrite.getAST().newModifier(ModifierKeyword.STATIC_KEYWORD)); | |
485 | listRewrite.insertFirst(paramClass, fBaseCURewrite.createGroupDescription(RefactoringCoreMessages.ExtractClassRefactoring_group_insert_parameter)); | |
486 | return new ArrayList<ResourceChange>(); //Change will be generated later for fBaseCURewrite | |
487 | } | |
488 | ||
489 | } | |
490 | ||
491 | private ParameterObjectFactory initializeFactory() { | |
492 | ParameterObjectFactory pof= new ParameterObjectFactory(); | |
493 | pof.setClassName(fDescriptor.getClassName()); | |
494 | pof.setPackage(fDescriptor.getPackage()); | |
495 | pof.setEnclosingType(fDescriptor.getType().getFullyQualifiedName()); | |
496 | pof.setCreateGetter(fDescriptor.isCreateGetterSetter()); | |
497 | pof.setCreateSetter(fDescriptor.isCreateGetterSetter()); | |
498 | List<ParameterInfo> variables= new ArrayList<ParameterInfo>(); | |
499 | for (Iterator<FieldInfo> iterator= fVariables.values().iterator(); iterator.hasNext();) { | |
500 | FieldInfo info= iterator.next(); | |
501 | boolean createField= isCreateField(info); | |
502 | info.pi.setCreateField(createField); | |
503 | if (createField) { | |
504 | Field field= getField(info.name); | |
505 | info.pi.setNewName(field.getNewFieldName()); | |
506 | } | |
507 | variables.add(info.pi); | |
508 | } | |
509 | pof.setVariables(variables); | |
510 | return pof; | |
511 | } | |
512 | ||
513 | private Field getField(String name) { | |
514 | Field[] fields= fDescriptor.getFields(); | |
515 | for (int i= 0; i < fields.length; i++) { | |
516 | Field field= fields[i]; | |
517 | if (field.getFieldName().equals(name)) | |
518 | return field; | |
519 | } | |
520 | return null; | |
521 | } | |
522 | ||
523 | ||
524 | private RefactoringStatus updateReferences(IType type, ParameterObjectFactory pof, IProgressMonitor pm) throws CoreException { | |
525 | RefactoringStatus status= new RefactoringStatus(); | |
526 | pm.beginTask(RefactoringCoreMessages.ExtractClassRefactoring_progress_updating_references, 100); | |
527 | try { | |
528 | pm.worked(10); | |
529 | if (pm.isCanceled()) | |
530 | throw new OperationCanceledException(); | |
531 | List<IField> validIFields= new ArrayList<IField>(); | |
532 | for (Iterator<FieldInfo> iterator= fVariables.values().iterator(); iterator.hasNext();) { | |
533 | FieldInfo info= iterator.next(); | |
534 | if (isCreateField(info)) | |
535 | validIFields.add(info.ifield); | |
536 | } | |
537 | if (validIFields.size() == 0) { | |
538 | status.addWarning(RefactoringCoreMessages.ExtractClassRefactoring_warning_no_fields_moved, JavaStatusContext.create(type)); | |
539 | return status; | |
540 | } | |
541 | SearchPattern pattern= RefactoringSearchEngine.createOrPattern(validIFields.toArray(new IField[validIFields.size()]), IJavaSearchConstants.ALL_OCCURRENCES); | |
542 | SearchResultGroup[] results= RefactoringSearchEngine.search(pattern, RefactoringScopeFactory.create(type), pm, status); | |
543 | SubProgressMonitor spm= new SubProgressMonitor(pm, 90); | |
544 | spm.beginTask(RefactoringCoreMessages.ExtractClassRefactoring_progress_updating_references, results.length * 10); | |
545 | try { | |
546 | for (int i= 0; i < results.length; i++) { | |
547 | SearchResultGroup group= results[i]; | |
548 | ICompilationUnit unit= group.getCompilationUnit(); | |
549 | ||
550 | CompilationUnitRewrite cuRewrite; | |
551 | if (unit.equals(fBaseCURewrite.getCu())) | |
552 | cuRewrite= fBaseCURewrite; | |
553 | else | |
554 | cuRewrite= new CompilationUnitRewrite(unit); | |
555 | spm.worked(1); | |
556 | ||
557 | status.merge(replaceReferences(pof, group, cuRewrite)); | |
558 | if (cuRewrite != fBaseCURewrite) //Change for fBaseCURewrite will be generated later | |
559 | fChangeManager.manage(unit, cuRewrite.createChange(true, new SubProgressMonitor(spm, 9))); | |
560 | if (spm.isCanceled()) | |
561 | throw new OperationCanceledException(); | |
562 | } | |
563 | } finally { | |
564 | spm.done(); | |
565 | } | |
566 | } finally { | |
567 | pm.done(); | |
568 | } | |
569 | return status; | |
570 | } | |
571 | ||
572 | private RefactoringStatus replaceReferences(ParameterObjectFactory pof, SearchResultGroup group, CompilationUnitRewrite cuRewrite) { | |
573 | TextEditGroup writeGroup= cuRewrite.createGroupDescription(RefactoringCoreMessages.ExtractClassRefactoring_group_replace_write); | |
574 | TextEditGroup readGroup= cuRewrite.createGroupDescription(RefactoringCoreMessages.ExtractClassRefactoring_group_replace_read); | |
575 | ITypeRoot typeRoot= cuRewrite.getCu(); | |
576 | IJavaProject javaProject= typeRoot.getJavaProject(); | |
577 | AST ast= cuRewrite.getAST(); | |
578 | ||
579 | RefactoringStatus status= new RefactoringStatus(); | |
580 | String parameterName= fDescriptor.getFieldName(); | |
581 | ||
582 | SearchMatch[] searchResults= group.getSearchResults(); | |
583 | for (int j= 0; j < searchResults.length; j++) { | |
584 | SearchMatch searchMatch= searchResults[j]; | |
585 | ASTNode node= NodeFinder.perform(cuRewrite.getRoot(), searchMatch.getOffset(), searchMatch.getLength()); | |
586 | ASTNode parent= node.getParent(); | |
587 | boolean isDeclaration= parent instanceof VariableDeclaration && ((VariableDeclaration)parent).getInitializer() != node; | |
588 | if (!isDeclaration && node instanceof SimpleName) { | |
589 | ASTRewrite rewrite= cuRewrite.getASTRewrite(); | |
590 | if (parent.getNodeType() == ASTNode.SWITCH_CASE) | |
591 | status.addError(RefactoringCoreMessages.ExtractClassRefactoring_error_switch, JavaStatusContext.create(typeRoot, node)); | |
592 | ||
593 | SimpleName name= (SimpleName) node; | |
594 | ParameterInfo pi= getFieldInfo(name.getIdentifier()).pi; | |
595 | boolean writeAccess= ASTResolving.isWriteAccess(name); | |
596 | if (writeAccess && fDescriptor.isCreateGetterSetter()) { | |
597 | boolean useSuper= parent.getNodeType() == ASTNode.SUPER_FIELD_ACCESS; | |
598 | Expression qualifier= getQualifier(parent); | |
599 | ASTNode replaceNode= getReplacementNode(parent, useSuper, qualifier); | |
600 | Expression assignedValue= getAssignedValue(pof, parameterName, javaProject, status, rewrite, pi, useSuper, name.resolveTypeBinding(), qualifier, replaceNode, typeRoot); | |
601 | if (assignedValue == null) { | |
602 | status.addError(RefactoringCoreMessages.ExtractClassRefactoring_error_unable_to_convert_node, JavaStatusContext.create(typeRoot, replaceNode)); | |
603 | } else { | |
604 | NullLiteral marker= qualifier == null ? null : ast.newNullLiteral(); | |
605 | Expression access= pof.createFieldWriteAccess(pi, parameterName, ast, javaProject, assignedValue, useSuper, marker); | |
606 | replaceMarker(rewrite, qualifier, access, marker); | |
607 | rewrite.replace(replaceNode, access, writeGroup); | |
608 | } | |
609 | } else { | |
610 | Expression fieldReadAccess= pof.createFieldReadAccess(pi, parameterName, ast, javaProject, false, null); //qualifier is already there | |
611 | rewrite.replace(name, fieldReadAccess, readGroup); | |
612 | } | |
613 | } | |
614 | } | |
615 | return status; | |
616 | } | |
617 | ||
618 | private Expression getAssignedValue(ParameterObjectFactory pof, String parameterName, IJavaProject javaProject, RefactoringStatus status, ASTRewrite rewrite, ParameterInfo pi, boolean useSuper, ITypeBinding typeBinding, Expression qualifier, ASTNode replaceNode, ITypeRoot typeRoot) { | |
619 | AST ast= rewrite.getAST(); | |
620 | boolean is50OrHigher= JavaModelUtil.is50OrHigher(javaProject); | |
621 | Expression assignedValue= handleSimpleNameAssignment(replaceNode, pof, parameterName, ast, javaProject, useSuper); | |
622 | if (assignedValue == null) { | |
623 | NullLiteral marker= qualifier == null ? null : ast.newNullLiteral(); | |
624 | Expression fieldReadAccess= pof.createFieldReadAccess(pi, parameterName, ast, javaProject, useSuper, marker); | |
625 | assignedValue= GetterSetterUtil.getAssignedValue(replaceNode, rewrite, fieldReadAccess, typeBinding, is50OrHigher); | |
626 | boolean markerReplaced= replaceMarker(rewrite, qualifier, assignedValue, marker); | |
627 | if (markerReplaced) { | |
628 | switch (qualifier.getNodeType()) { | |
629 | case ASTNode.METHOD_INVOCATION: | |
630 | case ASTNode.CLASS_INSTANCE_CREATION: | |
631 | case ASTNode.SUPER_METHOD_INVOCATION: | |
632 | case ASTNode.PARENTHESIZED_EXPRESSION: | |
633 | status.addWarning(RefactoringCoreMessages.ExtractClassRefactoring_warning_semantic_change, JavaStatusContext.create(typeRoot, replaceNode)); | |
634 | break; | |
635 | } | |
636 | } | |
637 | } | |
638 | return assignedValue; | |
639 | } | |
640 | ||
641 | private ASTNode getReplacementNode(ASTNode parent, boolean useSuper, Expression qualifier) { | |
642 | if (qualifier != null || useSuper) { | |
643 | return parent.getParent(); | |
644 | } else { | |
645 | return parent; | |
646 | } | |
647 | } | |
648 | ||
649 | private Expression getQualifier(ASTNode parent) { | |
650 | switch (parent.getNodeType()) { | |
651 | case ASTNode.FIELD_ACCESS: | |
652 | return ((FieldAccess) parent).getExpression(); | |
653 | case ASTNode.QUALIFIED_NAME: | |
654 | return ((QualifiedName)parent).getQualifier(); | |
655 | case ASTNode.SUPER_FIELD_ACCESS: | |
656 | return ((SuperFieldAccess)parent).getQualifier(); | |
657 | default: | |
658 | return null; | |
659 | } | |
660 | } | |
661 | ||
662 | /* | |
663 | * Replaces the NullLiteral dummy with the copied qualifier | |
664 | */ | |
665 | private boolean replaceMarker(final ASTRewrite rewrite, final Expression qualifier, Expression assignedValue, final NullLiteral marker) { | |
666 | class MarkerReplacer extends ASTVisitor { | |
667 | ||
668 | private boolean fReplaced= false; | |
669 | ||
670 | @Override | |
671 | public boolean visit(NullLiteral node) { | |
672 | if (node == marker) { | |
673 | rewrite.replace(node, rewrite.createCopyTarget(qualifier), null); | |
674 | fReplaced= true; | |
675 | return false; | |
676 | } | |
677 | return true; | |
678 | } | |
679 | } | |
680 | if (assignedValue != null && qualifier != null) { | |
681 | MarkerReplacer visitor= new MarkerReplacer(); | |
682 | assignedValue.accept(visitor); | |
683 | return visitor.fReplaced; | |
684 | } | |
685 | return false; | |
686 | } | |
687 | ||
688 | private Expression handleSimpleNameAssignment(ASTNode replaceNode, ParameterObjectFactory pof, String parameterName, AST ast, IJavaProject javaProject, boolean useSuper) { | |
689 | if (replaceNode instanceof Assignment) { | |
690 | Assignment assignment= (Assignment) replaceNode; | |
691 | Expression rightHandSide= assignment.getRightHandSide(); | |
692 | if (rightHandSide.getNodeType() == ASTNode.SIMPLE_NAME) { | |
693 | SimpleName sn= (SimpleName) rightHandSide; | |
694 | IVariableBinding binding= ASTNodes.getVariableBinding(sn); | |
695 | if (binding != null && binding.isField()) { | |
696 | if (fDescriptor.getType().getFullyQualifiedName().equals(binding.getDeclaringClass().getQualifiedName())) { | |
697 | FieldInfo fieldInfo= getFieldInfo(binding.getName()); | |
698 | if (fieldInfo != null && binding == fieldInfo.pi.getOldBinding()) { | |
699 | return pof.createFieldReadAccess(fieldInfo.pi, parameterName, ast, javaProject, useSuper, null); | |
700 | } | |
701 | } | |
702 | } | |
703 | } | |
704 | } | |
705 | return null; | |
706 | } | |
707 | ||
708 | private FieldInfo getFieldInfo(String identifier) { | |
709 | return fVariables.get(identifier); | |
710 | } | |
711 | ||
712 | private FieldDeclaration performFieldRewrite(IType type, ParameterObjectFactory pof, RefactoringStatus status) throws CoreException { | |
713 | fBaseCURewrite= new CompilationUnitRewrite(type.getCompilationUnit()); | |
714 | SimpleName name= (SimpleName) NodeFinder.perform(fBaseCURewrite.getRoot(), type.getNameRange()); | |
715 | TypeDeclaration typeNode= (TypeDeclaration) ASTNodes.getParent(name, ASTNode.TYPE_DECLARATION); | |
716 | ASTRewrite rewrite= fBaseCURewrite.getASTRewrite(); | |
717 | int modifier= Modifier.PRIVATE; | |
718 | TextEditGroup removeFieldGroup= fBaseCURewrite.createGroupDescription(RefactoringCoreMessages.ExtractClassRefactoring_group_remove_field); | |
719 | FieldDeclaration lastField= null; | |
720 | initializeDeclaration(typeNode); | |
721 | for (Iterator<FieldInfo> iter= fVariables.values().iterator(); iter.hasNext();) { | |
722 | FieldInfo pi= iter.next(); | |
723 | if (isCreateField(pi)) { | |
724 | VariableDeclarationFragment vdf= pi.declaration; | |
725 | FieldDeclaration parent= (FieldDeclaration) vdf.getParent(); | |
726 | if (lastField == null) | |
727 | lastField= parent; | |
728 | else if (lastField.getStartPosition() < parent.getStartPosition()) | |
729 | lastField= parent; | |
730 | ||
731 | ListRewrite listRewrite= rewrite.getListRewrite(parent, FieldDeclaration.FRAGMENTS_PROPERTY); | |
732 | removeNode(vdf, removeFieldGroup, fBaseCURewrite); | |
733 | if (listRewrite.getRewrittenList().size() == 0) { | |
734 | removeNode(parent, removeFieldGroup, fBaseCURewrite); | |
735 | } | |
736 | ||
737 | if (fDescriptor.isCreateTopLevel()) { | |
738 | IVariableBinding binding= vdf.resolveBinding(); | |
739 | ITypeRoot typeRoot= fBaseCURewrite.getCu(); | |
740 | if (binding == null || binding.getType() == null){ | |
741 | status.addFatalError(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_fatal_error_cannot_resolve_binding, BasicElementLabels.getJavaElementName(pi.name)), JavaStatusContext.create(typeRoot, vdf)); | |
742 | } else { | |
743 | ITypeBinding typeBinding= binding.getType(); | |
744 | if (Modifier.isPrivate(typeBinding.getDeclaredModifiers())){ | |
745 | status.addError(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_error_referencing_private_class, BasicElementLabels.getJavaElementName(typeBinding.getName())), JavaStatusContext.create(typeRoot, vdf)); | |
746 | } else if (Modifier.isProtected(typeBinding.getDeclaredModifiers())){ | |
747 | ITypeBinding declaringClass= typeBinding.getDeclaringClass(); | |
748 | if (declaringClass != null) { | |
749 | IPackageBinding package1= declaringClass.getPackage(); | |
750 | if (package1 != null && !fDescriptor.getPackage().equals(package1.getName())){ | |
751 | status.addError(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_error_referencing_protected_class, new String[] {BasicElementLabels.getJavaElementName(typeBinding.getName()), BasicElementLabels.getJavaElementName(fDescriptor.getPackage())}), JavaStatusContext.create(typeRoot, vdf)); | |
752 | } | |
753 | } | |
754 | } | |
755 | } | |
756 | } | |
757 | Expression initializer= vdf.getInitializer(); | |
758 | if (initializer != null) | |
759 | pi.initializer= initializer; | |
760 | int modifiers= parent.getModifiers(); | |
761 | if (!MemberVisibilityAdjustor.hasLowerVisibility(modifiers, modifier)){ | |
762 | modifier= modifiers; | |
763 | } | |
764 | } | |
765 | } | |
766 | FieldDeclaration fieldDeclaration= createParameterObjectField(pof, typeNode, modifier); | |
767 | ListRewrite bodyDeclList= rewrite.getListRewrite(typeNode, TypeDeclaration.BODY_DECLARATIONS_PROPERTY); | |
768 | if (lastField != null) | |
769 | bodyDeclList.insertAfter(fieldDeclaration, lastField, null); | |
770 | else | |
771 | bodyDeclList.insertFirst(fieldDeclaration, null); | |
772 | return fieldDeclaration; | |
773 | } | |
774 | ||
775 | private void initializeDeclaration(TypeDeclaration node) { | |
776 | FieldDeclaration[] fields= node.getFields(); | |
777 | for (int i= 0; i < fields.length; i++) { | |
778 | FieldDeclaration fieldDeclaration= fields[i]; | |
779 | List<VariableDeclarationFragment> fragments= fieldDeclaration.fragments(); | |
780 | for (Iterator<VariableDeclarationFragment> iterator= fragments.iterator(); iterator.hasNext();) { | |
781 | VariableDeclarationFragment vdf= iterator.next(); | |
782 | FieldInfo fieldInfo= getFieldInfo(vdf.getName().getIdentifier()); | |
783 | if (fieldInfo != null) { | |
784 | Assert.isNotNull(vdf); | |
785 | fieldInfo.declaration= vdf; | |
786 | fieldInfo.pi.setOldBinding(vdf.resolveBinding()); | |
787 | } | |
788 | } | |
789 | } | |
790 | } | |
791 | ||
792 | private void removeNode(ASTNode parent, TextEditGroup removeFieldGroup, CompilationUnitRewrite baseCURewrite) { | |
793 | baseCURewrite.getASTRewrite().remove(parent, removeFieldGroup); | |
794 | baseCURewrite.getImportRemover().registerRemovedNode(parent); | |
795 | } | |
796 | ||
797 | private FieldDeclaration createParameterObjectField(ParameterObjectFactory pof, TypeDeclaration typeNode, int modifier) { | |
798 | AST ast= fBaseCURewrite.getAST(); | |
799 | ClassInstanceCreation creation= ast.newClassInstanceCreation(); | |
800 | creation.setType(pof.createType(fDescriptor.isCreateTopLevel(), fBaseCURewrite, typeNode.getStartPosition())); | |
801 | ListRewrite listRewrite= fBaseCURewrite.getASTRewrite().getListRewrite(creation, ClassInstanceCreation.ARGUMENTS_PROPERTY); | |
802 | for (Iterator<FieldInfo> iter= fVariables.values().iterator(); iter.hasNext();) { | |
803 | FieldInfo fi= iter.next(); | |
804 | if (isCreateField(fi)) { | |
805 | Expression expression= fi.initializer; | |
806 | if (expression != null && !fi.hasFieldReference()) { | |
807 | importNodeTypes(expression, fBaseCURewrite); | |
808 | ASTNode createMoveTarget= fBaseCURewrite.getASTRewrite().createMoveTarget(expression); | |
809 | if (expression instanceof ArrayInitializer) { | |
810 | ArrayInitializer ai= (ArrayInitializer) expression; | |
811 | ITypeBinding componentType= ai.resolveTypeBinding().getComponentType(); | |
812 | ArrayCreation arrayCreation= ast.newArrayCreation(); | |
813 | Type addImport= fBaseCURewrite.getImportRewrite().addImport(componentType, ast); | |
814 | fBaseCURewrite.getImportRemover().registerAddedImports(addImport); | |
815 | arrayCreation.setType(ast.newArrayType(addImport)); | |
816 | arrayCreation.setInitializer((ArrayInitializer) createMoveTarget); | |
817 | listRewrite.insertLast(arrayCreation, null); | |
818 | } else { | |
819 | listRewrite.insertLast(createMoveTarget, null); | |
820 | } | |
821 | } | |
822 | } | |
823 | } | |
824 | ||
825 | VariableDeclarationFragment fragment= ast.newVariableDeclarationFragment(); | |
826 | fragment.setName(ast.newSimpleName(fDescriptor.getFieldName())); | |
827 | fragment.setInitializer(creation); | |
828 | ||
829 | ModifierKeyword acc= null; | |
830 | if (Modifier.isPublic(modifier)) { | |
831 | acc= ModifierKeyword.PUBLIC_KEYWORD; | |
832 | } else if (Modifier.isProtected(modifier)) { | |
833 | acc= ModifierKeyword.PROTECTED_KEYWORD; | |
834 | } else if (Modifier.isPrivate(modifier)) { | |
835 | acc= ModifierKeyword.PRIVATE_KEYWORD; | |
836 | } | |
837 | ||
838 | FieldDeclaration fieldDeclaration= ast.newFieldDeclaration(fragment); | |
839 | fieldDeclaration.setType(pof.createType(fDescriptor.isCreateTopLevel(), fBaseCURewrite, typeNode.getStartPosition())); | |
840 | if (acc != null) | |
841 | fieldDeclaration.modifiers().add(ast.newModifier(acc)); | |
842 | return fieldDeclaration; | |
843 | } | |
844 | ||
845 | private void importNodeTypes(ASTNode node, final CompilationUnitRewrite cuRewrite) { | |
846 | ASTResolving.visitAllBindings(node, new TypeBindingVisitor() { | |
847 | public boolean visit(ITypeBinding nodeBinding) { | |
848 | ParameterObjectFactory.importBinding(nodeBinding, cuRewrite); | |
849 | return false; | |
850 | } | |
851 | }); | |
852 | } | |
853 | ||
854 | private boolean isCreateField(FieldInfo fi) { | |
855 | return getField(fi.name).isCreateField(); | |
856 | } | |
857 | ||
858 | ||
859 | @Override | |
860 | public String getName() { | |
861 | return RefactoringCoreMessages.ExtractClassRefactoring_refactoring_name; | |
862 | } | |
863 | ||
864 | /* (non-Javadoc) | |
865 | * @see org.eclipse.ltk.core.refactoring.Refactoring#getAdapter(java.lang.Class) | |
866 | */ | |
867 | @Override | |
868 | public Object getAdapter(Class adapter) { | |
869 | if (adapter == ExtractClassDescriptorVerification.class) { | |
870 | return fVerification; | |
871 | } | |
872 | return super.getAdapter(adapter); | |
873 | } | |
874 | } |