]> git.uio.no Git - ifi-stolz-refaktor.git/blob - case-study/jdt-before/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/PromoteTempToFieldRefactoring.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-before / core refactoring / org / eclipse / jdt / internal / corext / refactoring / code / PromoteTempToFieldRefactoring.java
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 package org.eclipse.jdt.internal.corext.refactoring.code;
12
13 import java.util.ArrayList;
14 import java.util.Arrays;
15 import java.util.HashMap;
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.StringTokenizer;
20
21 import org.eclipse.core.runtime.Assert;
22 import org.eclipse.core.runtime.CoreException;
23 import org.eclipse.core.runtime.IProgressMonitor;
24
25 import org.eclipse.text.edits.TextEdit;
26
27 import org.eclipse.ltk.core.refactoring.Change;
28 import org.eclipse.ltk.core.refactoring.Refactoring;
29 import org.eclipse.ltk.core.refactoring.RefactoringChangeDescriptor;
30 import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
31 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
32 import org.eclipse.ltk.core.refactoring.RefactoringStatusContext;
33
34 import org.eclipse.jdt.core.ICompilationUnit;
35 import org.eclipse.jdt.core.IJavaElement;
36 import org.eclipse.jdt.core.IJavaProject;
37 import org.eclipse.jdt.core.dom.AST;
38 import org.eclipse.jdt.core.dom.ASTNode;
39 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
40 import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
41 import org.eclipse.jdt.core.dom.ArrayCreation;
42 import org.eclipse.jdt.core.dom.ArrayInitializer;
43 import org.eclipse.jdt.core.dom.ArrayType;
44 import org.eclipse.jdt.core.dom.Assignment;
45 import org.eclipse.jdt.core.dom.Block;
46 import org.eclipse.jdt.core.dom.BodyDeclaration;
47 import org.eclipse.jdt.core.dom.CatchClause;
48 import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
49 import org.eclipse.jdt.core.dom.CompilationUnit;
50 import org.eclipse.jdt.core.dom.ConstructorInvocation;
51 import org.eclipse.jdt.core.dom.Expression;
52 import org.eclipse.jdt.core.dom.FieldDeclaration;
53 import org.eclipse.jdt.core.dom.IBinding;
54 import org.eclipse.jdt.core.dom.IExtendedModifier;
55 import org.eclipse.jdt.core.dom.IMethodBinding;
56 import org.eclipse.jdt.core.dom.ITypeBinding;
57 import org.eclipse.jdt.core.dom.IVariableBinding;
58 import org.eclipse.jdt.core.dom.Javadoc;
59 import org.eclipse.jdt.core.dom.MethodDeclaration;
60 import org.eclipse.jdt.core.dom.Modifier;
61 import org.eclipse.jdt.core.dom.SimpleName;
62 import org.eclipse.jdt.core.dom.Statement;
63 import org.eclipse.jdt.core.dom.SwitchStatement;
64 import org.eclipse.jdt.core.dom.Type;
65 import org.eclipse.jdt.core.dom.TypeDeclaration;
66 import org.eclipse.jdt.core.dom.VariableDeclaration;
67 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
68 import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
69 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
70 import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
71 import org.eclipse.jdt.core.refactoring.CompilationUnitChange;
72 import org.eclipse.jdt.core.refactoring.IJavaRefactorings;
73 import org.eclipse.jdt.core.refactoring.descriptors.ConvertLocalVariableDescriptor;
74
75 import org.eclipse.jdt.internal.core.refactoring.descriptors.RefactoringSignatureDescriptorFactory;
76 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
77 import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
78 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
79 import org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor;
80 import org.eclipse.jdt.internal.corext.dom.ModifierRewrite;
81 import org.eclipse.jdt.internal.corext.fix.LinkedProposalModel;
82 import org.eclipse.jdt.internal.corext.fix.LinkedProposalPositionGroup;
83 import org.eclipse.jdt.internal.corext.refactoring.Checks;
84 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment;
85 import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments;
86 import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringDescriptorUtil;
87 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
88 import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;
89 import org.eclipse.jdt.internal.corext.refactoring.changes.TextChangeCompatibility;
90 import org.eclipse.jdt.internal.corext.refactoring.rename.TempDeclarationFinder;
91 import org.eclipse.jdt.internal.corext.refactoring.rename.TempOccurrenceAnalyzer;
92 import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
93 import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil;
94 import org.eclipse.jdt.internal.corext.util.JdtFlags;
95 import org.eclipse.jdt.internal.corext.util.Messages;
96
97 import org.eclipse.jdt.ui.CodeGeneration;
98 import org.eclipse.jdt.ui.JavaElementLabels;
99
100 import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;
101 import org.eclipse.jdt.internal.ui.viewsupport.BindingLabelProvider;
102
103 public class PromoteTempToFieldRefactoring extends Refactoring {
104
105         private static final String ATTRIBUTE_STATIC= "static"; //$NON-NLS-1$
106         private static final String ATTRIBUTE_FINAL= "final"; //$NON-NLS-1$
107         private static final String ATTRIBUTE_VISIBILITY= "visibility"; //$NON-NLS-1$
108         private static final String ATTRIBUTE_INITIALIZE= "initialize"; //$NON-NLS-1$
109
110         private int fSelectionStart;
111     private int fSelectionLength;
112     private ICompilationUnit fCu;
113
114         public static final int INITIALIZE_IN_FIELD= 0;
115         public static final int INITIALIZE_IN_METHOD= 1;
116         public static final int INITIALIZE_IN_CONSTRUCTOR= 2;
117
118         private static final String LINKED_NAME= "name"; //$NON-NLS-1$
119
120         //------ settings ---------//
121         private String fFieldName;
122         private int fVisibility;        /*see Modifier*/
123         private boolean fDeclareStatic;
124         private boolean fDeclareFinal;
125         private int fInitializeIn; /*see INITIALIZE_IN_* constraints */
126
127         //------ fields used for computations ---------//
128     private CompilationUnit fCompilationUnitNode;
129     private VariableDeclaration fTempDeclarationNode;
130         //------ analysis ---------//
131         private boolean fInitializerUsesLocalTypes;
132         private boolean fTempTypeUsesClassTypeVariables;
133         //------ scripting --------//
134         private boolean fSelfInitializing= false;
135         private LinkedProposalModel fLinkedProposalModel;
136
137         /**
138          * Creates a new promote temp to field refactoring.
139          * @param unit the compilation unit, or <code>null</code> if invoked by scripting
140          * @param selectionStart start
141          * @param selectionLength length
142          */
143         public PromoteTempToFieldRefactoring(ICompilationUnit unit, int selectionStart, int selectionLength){
144                 Assert.isTrue(selectionStart >= 0);
145                 Assert.isTrue(selectionLength >= 0);
146                 fSelectionStart= selectionStart;
147                 fSelectionLength= selectionLength;
148                 fCu= unit;
149
150         fFieldName= ""; //$NON-NLS-1$
151         fVisibility= Modifier.PRIVATE;
152         fDeclareStatic= false;
153         fDeclareFinal= false;
154         fInitializeIn= INITIALIZE_IN_METHOD;
155         fLinkedProposalModel= null;
156         }
157
158         /**
159          * Creates a new promote temp to field refactoring.
160          * @param declaration the variable declaration node to convert to a field
161          */
162         public PromoteTempToFieldRefactoring(VariableDeclaration declaration) {
163                 Assert.isTrue(declaration != null);
164                 fTempDeclarationNode= declaration;
165                 IVariableBinding resolveBinding= declaration.resolveBinding();
166                 Assert.isTrue(resolveBinding != null && !resolveBinding.isParameter() && !resolveBinding.isField());
167
168                 ASTNode root= declaration.getRoot();
169                 Assert.isTrue(root instanceof CompilationUnit);
170                 fCompilationUnitNode= (CompilationUnit) root;
171
172                 IJavaElement input= fCompilationUnitNode.getJavaElement();
173                 Assert.isTrue(input instanceof ICompilationUnit);
174                 fCu= (ICompilationUnit) input;
175
176                 fSelectionStart= declaration.getStartPosition();
177                 fSelectionLength= declaration.getLength();
178
179         fFieldName= ""; //$NON-NLS-1$
180         fVisibility= Modifier.PRIVATE;
181         fDeclareStatic= false;
182         fDeclareFinal= false;
183         fInitializeIn= INITIALIZE_IN_METHOD;
184         fLinkedProposalModel= null;
185         }
186
187     public PromoteTempToFieldRefactoring(JavaRefactoringArguments arguments, RefactoringStatus status) {
188                 this(null);
189                 RefactoringStatus initializeStatus= initialize(arguments);
190                 status.merge(initializeStatus);
191     }
192
193     @Override
194         public String getName() {
195         return RefactoringCoreMessages.PromoteTempToFieldRefactoring_name;
196     }
197
198     public int[] getAvailableVisibilities(){
199         return new int[]{Modifier.PUBLIC, Modifier.PROTECTED, Modifier.NONE, Modifier.PRIVATE};
200     }
201
202     public int getVisibility() {
203         return fVisibility;
204     }
205
206     public boolean getDeclareFinal() {
207         return fDeclareFinal;
208     }
209
210     public boolean getDeclareStatic() {
211         return fDeclareStatic;
212     }
213
214     public int getInitializeIn() {
215         return fInitializeIn;
216     }
217
218     public void setVisibility(int accessModifier) {
219         Assert.isTrue(accessModifier == Modifier.PRIVATE ||
220                                         accessModifier == Modifier.NONE ||
221                                         accessModifier == Modifier.PROTECTED ||
222                                         accessModifier == Modifier.PUBLIC);
223         fVisibility= accessModifier;
224     }
225
226     public void setDeclareFinal(boolean declareFinal) {
227         fDeclareFinal= declareFinal;
228     }
229
230     public void setDeclareStatic(boolean declareStatic) {
231         fDeclareStatic= declareStatic;
232     }
233
234     public void setFieldName(String fieldName) {
235         Assert.isNotNull(fieldName);
236         fFieldName= fieldName;
237     }
238
239     public void setInitializeIn(int initializeIn) {
240         Assert.isTrue(  initializeIn == INITIALIZE_IN_CONSTRUCTOR ||
241                                         initializeIn == INITIALIZE_IN_FIELD ||
242                                         initializeIn == INITIALIZE_IN_METHOD);
243         fInitializeIn= initializeIn;
244     }
245
246         public boolean canEnableSettingStatic(){
247                 return fInitializeIn != INITIALIZE_IN_CONSTRUCTOR &&
248                                 ! isTempDeclaredInStaticMethod() &&
249                                 ! fTempTypeUsesClassTypeVariables;
250         }
251
252         public boolean canEnableSettingFinal(){
253                 if (fInitializeIn == INITIALIZE_IN_CONSTRUCTOR)
254                         return  canEnableSettingDeclareInConstructors() && ! tempHasAssignmentsOtherThanInitialization();
255                 else if (fInitializeIn == INITIALIZE_IN_FIELD)
256                         return  canEnableSettingDeclareInFieldDeclaration() && ! tempHasAssignmentsOtherThanInitialization();
257                 else    if (getMethodDeclaration().isConstructor())
258                         return  !tempHasAssignmentsOtherThanInitialization();
259                 else
260                         return false;
261         }
262
263     private boolean tempHasAssignmentsOtherThanInitialization() {
264         TempAssignmentFinder assignmentFinder= new TempAssignmentFinder(fTempDeclarationNode);
265         fCompilationUnitNode.accept(assignmentFinder);
266                 return assignmentFinder.hasAssignments();
267     }
268
269         public boolean canEnableSettingDeclareInConstructors(){
270                 return ! fDeclareStatic &&
271                                 ! fInitializerUsesLocalTypes &&
272                                 ! getMethodDeclaration().isConstructor() &&
273                                 ! isDeclaredInAnonymousClass() &&
274                                 ! isTempDeclaredInStaticMethod() &&
275                                 tempHasInitializer();
276         }
277
278         public boolean canEnableSettingDeclareInMethod(){
279                 return ! fDeclareFinal &&
280                                 tempHasInitializer();
281         }
282     private boolean tempHasInitializer() {
283         return getTempInitializer() != null;
284     }
285
286         public boolean canEnableSettingDeclareInFieldDeclaration(){
287                 return ! fInitializerUsesLocalTypes && tempHasInitializer();
288         }
289
290     private Expression getTempInitializer() {
291         return fTempDeclarationNode.getInitializer();
292     }
293
294     private boolean isTempDeclaredInStaticMethod() {
295         return Modifier.isStatic(getMethodDeclaration().getModifiers());
296     }
297
298     private MethodDeclaration getMethodDeclaration(){
299         return (MethodDeclaration)ASTNodes.getParent(fTempDeclarationNode, MethodDeclaration.class);
300     }
301
302     private boolean isDeclaredInAnonymousClass() {
303         return null != ASTNodes.getParent(fTempDeclarationNode, AnonymousClassDeclaration.class);
304     }
305
306     /*
307          * @see org.eclipse.jdt.internal.corext.refactoring.base.Refactoring#checkActivation(org.eclipse.core.runtime.IProgressMonitor)
308          */
309         @Override
310         public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException {
311                 RefactoringStatus result= Checks.validateModifiesFiles(
312                         ResourceUtil.getFiles(new ICompilationUnit[]{fCu}),
313                         getValidationContext());
314                 if (result.hasFatalError())
315                         return result;
316
317                 initAST(pm);
318
319                 if (fTempDeclarationNode == null)
320                         return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_select_declaration);
321
322                 if (! Checks.isDeclaredIn(fTempDeclarationNode, MethodDeclaration.class))
323                         return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_only_declared_in_methods);
324
325                 if (isMethodParameter())
326                         return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_method_parameters);
327
328                 if (isTempAnExceptionInCatchBlock())
329                         return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_exceptions);
330
331                 result.merge(checkTempTypeForLocalTypeUsage());
332                 if (result.hasFatalError())
333                     return result;
334
335                 checkTempInitializerForLocalTypeUsage();
336
337                 if (!fSelfInitializing)
338                         initializeDefaults();
339                 return result;
340         }
341
342     private void initializeDefaults() {
343         fVisibility= Modifier.PRIVATE;
344         fDeclareStatic= Modifier.isStatic(getMethodDeclaration().getModifiers());
345         fDeclareFinal= false;
346         if (canEnableSettingDeclareInMethod())
347                 fInitializeIn= INITIALIZE_IN_METHOD;
348             else if (canEnableSettingDeclareInFieldDeclaration())
349                 fInitializeIn= INITIALIZE_IN_FIELD;
350             else if (canEnableSettingDeclareInConstructors())
351                 fInitializeIn= INITIALIZE_IN_CONSTRUCTOR;
352     }
353
354         public String[] guessFieldNames() {
355                 String rawTempName= StubUtility.getBaseName(fTempDeclarationNode.resolveBinding(), fCu.getJavaProject());
356                 String[] excludedNames= getNamesOfFieldsInDeclaringType();
357                 int dim= ASTNodes.getDimensions(fTempDeclarationNode);
358                 return StubUtility.getFieldNameSuggestions(fCu.getJavaProject(), rawTempName, dim, getModifiers(), excludedNames);
359         }
360
361     private String getInitialFieldName() {
362         String[] suggestedNames= guessFieldNames();
363                 if (suggestedNames.length > 0) {
364                         if (fLinkedProposalModel != null) {
365                                 LinkedProposalPositionGroup nameGroup= fLinkedProposalModel.getPositionGroup(LINKED_NAME, true);
366                                 for (int i= 0; i < suggestedNames.length; i++) {
367                                         nameGroup.addProposal(suggestedNames[i], null, suggestedNames.length - i);
368                                 }
369                         }
370                         return suggestedNames[0];
371                 } else {
372                         return fTempDeclarationNode.getName().getIdentifier();
373                 }
374         }
375
376         private String[] getNamesOfFieldsInDeclaringType() {
377                 final AbstractTypeDeclaration type= getEnclosingType();
378                 if (type instanceof TypeDeclaration) {
379                         FieldDeclaration[] fields= ((TypeDeclaration) type).getFields();
380                         List<String> result= new ArrayList<String>(fields.length);
381                         for (int i= 0; i < fields.length; i++) {
382                                 for (Iterator<VariableDeclarationFragment> iter= fields[i].fragments().iterator(); iter.hasNext();) {
383                                         VariableDeclarationFragment field= iter.next();
384                                         result.add(field.getName().getIdentifier());
385                                 }
386                         }
387                         return result.toArray(new String[result.size()]);
388                 }
389                 return new String[] {};
390         }
391
392     private void checkTempInitializerForLocalTypeUsage() {
393         Expression initializer= fTempDeclarationNode.getInitializer();
394         if (initializer == null)
395                 return;
396
397                 IMethodBinding declaringMethodBinding= getMethodDeclaration().resolveBinding();
398                 ITypeBinding[] methodTypeParameters= declaringMethodBinding == null ? new ITypeBinding[0] : declaringMethodBinding.getTypeParameters();
399             LocalTypeAndVariableUsageAnalyzer localTypeAnalyer= new LocalTypeAndVariableUsageAnalyzer(methodTypeParameters);
400             initializer.accept(localTypeAnalyer);
401             fInitializerUsesLocalTypes= ! localTypeAnalyer.getUsageOfEnclosingNodes().isEmpty();
402     }
403
404     private RefactoringStatus checkTempTypeForLocalTypeUsage(){
405         VariableDeclarationStatement vds= getTempDeclarationStatement();
406         if (vds == null)
407                 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_cannot_promote);
408         Type type=      vds.getType();
409         ITypeBinding binding= type.resolveBinding();
410         if (binding == null)
411                 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_cannot_promote);
412
413                 IMethodBinding declaringMethodBinding= getMethodDeclaration().resolveBinding();
414                 ITypeBinding[] methodTypeParameters= declaringMethodBinding == null ? new ITypeBinding[0] : declaringMethodBinding.getTypeParameters();
415                 LocalTypeAndVariableUsageAnalyzer analyzer= new LocalTypeAndVariableUsageAnalyzer(methodTypeParameters);
416                 type.accept(analyzer);
417                 boolean usesLocalTypes= ! analyzer.getUsageOfEnclosingNodes().isEmpty();
418                 fTempTypeUsesClassTypeVariables= analyzer.getClassTypeVariablesUsed();
419                 if (usesLocalTypes)
420                         return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_uses_type_declared_locally);
421                 return null;
422     }
423
424     private VariableDeclarationStatement getTempDeclarationStatement() {
425         return (VariableDeclarationStatement) ASTNodes.getParent(fTempDeclarationNode, VariableDeclarationStatement.class);
426     }
427
428     private boolean isTempAnExceptionInCatchBlock() {
429                 return (fTempDeclarationNode.getParent() instanceof CatchClause);
430     }
431
432     private boolean isMethodParameter() {
433         return (fTempDeclarationNode.getParent() instanceof MethodDeclaration);
434     }
435
436         private void initAST(IProgressMonitor pm){
437                 if (fCompilationUnitNode == null) {
438                         fCompilationUnitNode= RefactoringASTParser.parseWithASTProvider(fCu, true, pm);
439                         fTempDeclarationNode= TempDeclarationFinder.findTempDeclaration(fCompilationUnitNode, fSelectionStart, fSelectionLength);
440                 }
441         }
442
443         public RefactoringStatus validateInput(){
444                 return Checks.checkFieldName(fFieldName, fCu);
445         }
446
447     /*
448      * @see org.eclipse.jdt.internal.corext.refactoring.base.Refactoring#checkInput(org.eclipse.core.runtime.IProgressMonitor)
449      */
450     @Override
451         public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException {
452         try{
453                 RefactoringStatus result= new RefactoringStatus();
454                 result.merge(checkClashesWithExistingFields());
455                 if (fInitializeIn == INITIALIZE_IN_CONSTRUCTOR)
456                         result.merge(checkClashesInConstructors());
457                 return result;
458         } finally {
459                 pm.done();
460         }
461     }
462
463     private RefactoringStatus checkClashesInConstructors() {
464                 Assert.isTrue(fInitializeIn == INITIALIZE_IN_CONSTRUCTOR);
465                 Assert.isTrue(!isDeclaredInAnonymousClass());
466                 final AbstractTypeDeclaration declaration= (AbstractTypeDeclaration) getMethodDeclaration().getParent();
467                 if (declaration instanceof TypeDeclaration) {
468                         MethodDeclaration[] methods= ((TypeDeclaration) declaration).getMethods();
469                         for (int i= 0; i < methods.length; i++) {
470                                 MethodDeclaration method= methods[i];
471                                 if (!method.isConstructor())
472                                         continue;
473                                 NameCollector nameCollector= new NameCollector(method) {
474                                         @Override
475                                         protected boolean visitNode(ASTNode node) {
476                                                 return true;
477                                         }
478                                 };
479                                 method.accept(nameCollector);
480                                 List<String> names= nameCollector.getNames();
481                                 if (names.contains(fFieldName)) {
482                                         String[] keys= { BasicElementLabels.getJavaElementName(fFieldName), BindingLabelProvider.getBindingLabel(method.resolveBinding(), JavaElementLabels.ALL_FULLY_QUALIFIED)};
483                                         String msg= Messages.format(RefactoringCoreMessages.PromoteTempToFieldRefactoring_Name_conflict, keys);
484                                         return RefactoringStatus.createFatalErrorStatus(msg);
485                                 }
486                         }
487                 }
488                 return null;
489         }
490
491     private RefactoringStatus checkClashesWithExistingFields(){
492         FieldDeclaration[] existingFields= getFieldDeclarations(getBodyDeclarationListOfDeclaringType());
493         for (int i= 0; i < existingFields.length; i++) {
494             FieldDeclaration declaration= existingFields[i];
495                         VariableDeclarationFragment[] fragments= (VariableDeclarationFragment[]) declaration.fragments().toArray(new VariableDeclarationFragment[declaration.fragments().size()]);
496                         for (int j= 0; j < fragments.length; j++) {
497                 VariableDeclarationFragment fragment= fragments[j];
498                 if (fFieldName.equals(fragment.getName().getIdentifier())){
499                         //cannot conflict with more than 1 name
500                         RefactoringStatusContext context= JavaStatusContext.create(fCu, fragment);
501                         return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_Name_conflict_with_field, context);
502                 }
503             }
504         }
505         return null;
506     }
507
508     private ChildListPropertyDescriptor getBodyDeclarationListOfDeclaringType(){
509         ASTNode methodParent= getMethodDeclaration().getParent();
510         if (methodParent instanceof AbstractTypeDeclaration)
511                 return ((AbstractTypeDeclaration) methodParent).getBodyDeclarationsProperty();
512         if (methodParent instanceof AnonymousClassDeclaration)
513                 return AnonymousClassDeclaration.BODY_DECLARATIONS_PROPERTY;
514         Assert.isTrue(false);
515         return null;
516     }
517
518     private FieldDeclaration[] getFieldDeclarations(ChildListPropertyDescriptor descriptor) {
519         final List<BodyDeclaration> bodyDeclarations= (List<BodyDeclaration>) getMethodDeclaration().getParent().getStructuralProperty(descriptor);
520         List<FieldDeclaration> fields= new ArrayList<FieldDeclaration>(1);
521         for (Iterator<BodyDeclaration> iter= bodyDeclarations.iterator(); iter.hasNext();) {
522                 Object each= iter.next();
523                 if (each instanceof FieldDeclaration)
524                         fields.add((FieldDeclaration) each);
525         }
526         return fields.toArray(new FieldDeclaration[fields.size()]);
527     }
528
529     /*
530      * @see org.eclipse.jdt.internal.corext.refactoring.base.IRefactoring#createChange(org.eclipse.core.runtime.IProgressMonitor)
531      */
532     @Override
533         public Change createChange(IProgressMonitor pm) throws CoreException {
534         pm.beginTask("", 1); //$NON-NLS-1$
535         try {
536                 if (fFieldName.length() == 0) {
537                         fFieldName= getInitialFieldName();
538                 }
539
540                 ASTRewrite rewrite= ASTRewrite.create(fCompilationUnitNode.getAST());
541                 if (fInitializeIn == INITIALIZE_IN_METHOD && tempHasInitializer())
542                         addLocalDeclarationSplit(rewrite);
543                         else
544                                 addLocalDeclarationRemoval(rewrite);
545                 if (fInitializeIn == INITIALIZE_IN_CONSTRUCTOR)
546                         addInitializersToConstructors(rewrite);
547                         addTempRenames(rewrite);
548                 addFieldDeclaration(rewrite);
549
550                         CompilationUnitChange result= new CompilationUnitChange(RefactoringCoreMessages.PromoteTempToFieldRefactoring_name, fCu);
551                         result.setDescriptor(new RefactoringChangeDescriptor(getRefactoringDescriptor()));
552                         TextEdit resultingEdits= rewrite.rewriteAST();
553                         TextChangeCompatibility.addTextEdit(result, RefactoringCoreMessages.PromoteTempToFieldRefactoring_editName, resultingEdits);
554                         return result;
555
556         } finally {
557                 pm.done();
558         }
559     }
560
561     private void addTempRenames(ASTRewrite rewrite) {
562         boolean noNameChange= fFieldName.equals(fTempDeclarationNode.getName().getIdentifier());
563                 if (fLinkedProposalModel == null && noNameChange) {
564                         return; // no changes needed
565                 }
566         TempOccurrenceAnalyzer analyzer= new TempOccurrenceAnalyzer(fTempDeclarationNode, false);
567                 analyzer.perform();
568         SimpleName[] tempRefs= analyzer.getReferenceNodes(); // no javadocs (refactoring not for parameters)
569
570
571                 for (int j= 0; j < tempRefs.length; j++) {
572                         SimpleName occurence= tempRefs[j];
573                         if (noNameChange) {
574                                 addLinkedName(rewrite, occurence, false);
575                         } else {
576                                 SimpleName newName= getAST().newSimpleName(fFieldName);
577                                 addLinkedName(rewrite, newName, false);
578                                 rewrite.replace(occurence, newName, null);
579                         }
580                 }
581     }
582
583     private void addInitializersToConstructors(ASTRewrite rewrite) throws CoreException {
584         Assert.isTrue(! isDeclaredInAnonymousClass());
585         final AbstractTypeDeclaration declaration= (AbstractTypeDeclaration)getMethodDeclaration().getParent();
586         final MethodDeclaration[] constructors= getAllConstructors(declaration);
587         if (constructors.length == 0) {
588                 AST ast= rewrite.getAST();
589                 MethodDeclaration newConstructor= ast.newMethodDeclaration();
590                 newConstructor.setConstructor(true);
591                 newConstructor.modifiers().addAll(ast.newModifiers(declaration.getModifiers() & ModifierRewrite.VISIBILITY_MODIFIERS));
592                 newConstructor.setName(ast.newSimpleName(declaration.getName().getIdentifier()));
593                 newConstructor.setJavadoc(getNewConstructorComment(rewrite));
594                 newConstructor.setBody(ast.newBlock());
595
596                 addFieldInitializationToConstructor(rewrite, newConstructor);
597
598                 int insertionIndex= computeInsertIndexForNewConstructor(declaration);
599                         rewrite.getListRewrite(declaration, declaration.getBodyDeclarationsProperty()).insertAt(newConstructor, insertionIndex, null);
600         } else {
601                 for (int index= 0; index < constructors.length; index++) {
602                 if (shouldInsertTempInitialization(constructors[index]))
603                     addFieldInitializationToConstructor(rewrite, constructors[index]);
604             }
605         }
606     }
607
608         private String getEnclosingTypeName() {
609                 return getEnclosingType().getName().getIdentifier();
610         }
611
612         private AbstractTypeDeclaration getEnclosingType() {
613                 return (AbstractTypeDeclaration)ASTNodes.getParent(getTempDeclarationStatement(), AbstractTypeDeclaration.class);
614         }
615
616         private Javadoc getNewConstructorComment(ASTRewrite rewrite) throws CoreException {
617                 if (StubUtility.doAddComments(fCu.getJavaProject())){
618                         String comment= CodeGeneration.getMethodComment(fCu, getEnclosingTypeName(), getEnclosingTypeName(), new String[0], new String[0], null, null, StubUtility.getLineDelimiterUsed(fCu));
619                         if (comment != null && comment.length() > 0) {
620                                 return (Javadoc) rewrite.createStringPlaceholder(comment, ASTNode.JAVADOC);
621                         }
622                 }
623                 return null;
624         }
625
626         private int computeInsertIndexForNewConstructor(AbstractTypeDeclaration declaration) {
627         List<BodyDeclaration> declarations= declaration.bodyDeclarations();
628         if (declarations.isEmpty())
629                 return 0;
630                 int index= findFirstMethodIndex(declaration);
631                 if (index == -1)
632                         return declarations.size();
633                 else
634                         return index;
635     }
636
637     private int findFirstMethodIndex(AbstractTypeDeclaration typeDeclaration) {
638         for (int i= 0, n= typeDeclaration.bodyDeclarations().size(); i < n; i++) {
639             if (typeDeclaration.bodyDeclarations().get(i) instanceof MethodDeclaration)
640                 return i;
641         }
642         return -1;
643     }
644
645     private void addFieldInitializationToConstructor(ASTRewrite rewrite, MethodDeclaration constructor) {
646         if (constructor.getBody() == null)
647                 constructor.setBody(getAST().newBlock());
648                 Statement newStatement= createNewAssignmentStatement(rewrite);
649                 rewrite.getListRewrite(constructor.getBody(), Block.STATEMENTS_PROPERTY).insertLast(newStatement, null);
650     }
651
652     private static boolean shouldInsertTempInitialization(MethodDeclaration constructor){
653         Assert.isTrue(constructor.isConstructor());
654         if (constructor.getBody() == null)
655                 return false;
656         List<Statement> statements= constructor.getBody().statements();
657         if (statements == null)
658                 return false;
659         if (statements.size() > 0 && statements.get(0) instanceof ConstructorInvocation)
660                 return false;
661                 return true;
662     }
663
664     private static MethodDeclaration[] getAllConstructors(AbstractTypeDeclaration typeDeclaration) {
665                 if (typeDeclaration instanceof TypeDeclaration) {
666                         MethodDeclaration[] allMethods= ((TypeDeclaration) typeDeclaration).getMethods();
667                         List<MethodDeclaration> result= new ArrayList<MethodDeclaration>(Math.min(allMethods.length, 1));
668                         for (int i= 0; i < allMethods.length; i++) {
669                                 MethodDeclaration declaration= allMethods[i];
670                                 if (declaration.isConstructor())
671                                         result.add(declaration);
672                         }
673                         return result.toArray(new MethodDeclaration[result.size()]);
674                 }
675                 return new MethodDeclaration[] {};
676         }
677
678
679         private ConvertLocalVariableDescriptor getRefactoringDescriptor() {
680                 final Map<String, String> arguments= new HashMap<String, String>();
681                 String project= null;
682                 IJavaProject javaProject= fCu.getJavaProject();
683                 if (javaProject != null)
684                         project= javaProject.getElementName();
685                 final IVariableBinding binding= fTempDeclarationNode.resolveBinding();
686                 final String description= Messages.format(RefactoringCoreMessages.PromoteTempToFieldRefactoring_descriptor_description_short, BasicElementLabels.getJavaElementName(binding.getName()));
687                 final String header= Messages.format(RefactoringCoreMessages.PromoteTempToFieldRefactoring_descriptor_description, new String[] { BindingLabelProvider.getBindingLabel(binding, JavaElementLabels.ALL_FULLY_QUALIFIED), BindingLabelProvider.getBindingLabel(binding.getDeclaringMethod(), JavaElementLabels.ALL_FULLY_QUALIFIED)});
688                 final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(project, this, header);
689                 comment.addSetting(Messages.format(RefactoringCoreMessages.PromoteTempToFieldRefactoring_original_pattern, BindingLabelProvider.getBindingLabel(binding, JavaElementLabels.ALL_FULLY_QUALIFIED)));
690                 comment.addSetting(Messages.format(RefactoringCoreMessages.PromoteTempToFieldRefactoring_field_pattern, BasicElementLabels.getJavaElementName(fFieldName)));
691                 switch (fInitializeIn) {
692                         case INITIALIZE_IN_CONSTRUCTOR:
693                                 comment.addSetting(RefactoringCoreMessages.PromoteTempToFieldRefactoring_initialize_constructor);
694                                 break;
695                         case INITIALIZE_IN_FIELD:
696                                 comment.addSetting(RefactoringCoreMessages.PromoteTempToFieldRefactoring_initialize_declaration);
697                                 break;
698                         case INITIALIZE_IN_METHOD:
699                                 comment.addSetting(RefactoringCoreMessages.PromoteTempToFieldRefactoring_initialize_method);
700                                 break;
701                 }
702                 String visibility= JdtFlags.getVisibilityString(fVisibility);
703                 if ("".equals(visibility)) //$NON-NLS-1$
704                         visibility= RefactoringCoreMessages.PromoteTempToFieldRefactoring_default_visibility;
705                 comment.addSetting(Messages.format(RefactoringCoreMessages.PromoteTempToFieldRefactoring_visibility_pattern, visibility));
706                 if (fDeclareFinal && fDeclareStatic)
707                         comment.addSetting(RefactoringCoreMessages.PromoteTempToFieldRefactoring_declare_final_static);
708                 else if (fDeclareFinal)
709                         comment.addSetting(RefactoringCoreMessages.PromoteTempToFieldRefactoring_declare_final);
710                 else if (fDeclareStatic)
711                         comment.addSetting(RefactoringCoreMessages.PromoteTempToFieldRefactoring_declare_static);
712                 final ConvertLocalVariableDescriptor descriptor= RefactoringSignatureDescriptorFactory.createConvertLocalVariableDescriptor(project, description, comment.asString(), arguments, RefactoringDescriptor.STRUCTURAL_CHANGE);
713                 arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT, JavaRefactoringDescriptorUtil.elementToHandle(project, fCu));
714                 arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME, fFieldName);
715                 arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION, new Integer(fSelectionStart).toString() + " " + new Integer(fSelectionLength).toString()); //$NON-NLS-1$
716                 arguments.put(ATTRIBUTE_STATIC, Boolean.valueOf(fDeclareStatic).toString());
717                 arguments.put(ATTRIBUTE_FINAL, Boolean.valueOf(fDeclareFinal).toString());
718                 arguments.put(ATTRIBUTE_VISIBILITY, new Integer(fVisibility).toString());
719                 arguments.put(ATTRIBUTE_INITIALIZE, new Integer(fInitializeIn).toString());
720                 return descriptor;
721         }
722
723     private void addLocalDeclarationSplit(ASTRewrite rewrite) {
724         VariableDeclarationStatement tempDeclarationStatement= getTempDeclarationStatement();
725         ASTNode parentStatement= tempDeclarationStatement.getParent();
726
727         ListRewrite listRewrite;
728                 if (parentStatement instanceof SwitchStatement) {
729                         listRewrite= rewrite.getListRewrite(parentStatement, SwitchStatement.STATEMENTS_PROPERTY);
730                 } else if (parentStatement instanceof Block) {
731                         listRewrite= rewrite.getListRewrite(parentStatement, Block.STATEMENTS_PROPERTY);
732                 } else {
733                         // should not happen. VariableDeclaration's can not be in a control statement body
734                         listRewrite= null;
735                         Assert.isTrue(false);
736                 }
737         int statementIndex= listRewrite.getOriginalList().indexOf(tempDeclarationStatement);
738                 Assert.isTrue(statementIndex != -1);
739
740                 Statement newStatement= createNewAssignmentStatement(rewrite);
741
742         List<VariableDeclarationFragment> fragments= tempDeclarationStatement.fragments();
743
744                 int fragmentIndex= fragments.indexOf(fTempDeclarationNode);
745                 Assert.isTrue(fragmentIndex != -1);
746
747                 if (fragments.size() == 1) {
748                         rewrite.replace(tempDeclarationStatement, newStatement, null);
749                         return;
750                 }
751
752         for (int i1= fragmentIndex, n = fragments.size(); i1 < n; i1++) {
753                 VariableDeclarationFragment fragment= fragments.get(i1);
754                 rewrite.remove(fragment, null);
755         }
756         if (fragmentIndex == 0)
757                 rewrite.remove(tempDeclarationStatement, null);
758
759         Assert.isTrue(tempHasInitializer());
760
761         listRewrite.insertAt(newStatement, statementIndex + 1, null);
762
763         if (fragmentIndex + 1 < fragments.size()){
764             VariableDeclarationFragment firstFragmentAfter= fragments.get(fragmentIndex + 1);
765             VariableDeclarationFragment copyfirstFragmentAfter= (VariableDeclarationFragment)rewrite.createCopyTarget(firstFragmentAfter);
766                 VariableDeclarationStatement statement= getAST().newVariableDeclarationStatement(copyfirstFragmentAfter);
767                 Type type= (Type)rewrite.createCopyTarget(tempDeclarationStatement.getType());
768                 statement.setType(type);
769                 List<IExtendedModifier> modifiers= tempDeclarationStatement.modifiers();
770                 if (modifiers.size() > 0) {
771                         ListRewrite modifiersRewrite= rewrite.getListRewrite(tempDeclarationStatement, VariableDeclarationStatement.MODIFIERS2_PROPERTY);
772                         ASTNode firstModifier= (ASTNode) modifiers.get(0);
773                                 ASTNode lastModifier= (ASTNode) modifiers.get(modifiers.size() - 1);
774                                 ASTNode modifiersCopy= modifiersRewrite.createCopyTarget(firstModifier, lastModifier);
775                         statement.modifiers().add(modifiersCopy);
776                 }
777                 for (int i= fragmentIndex + 2; i < fragments.size(); i++) {
778                         VariableDeclarationFragment fragment= fragments.get(i);
779                 VariableDeclarationFragment fragmentCopy= (VariableDeclarationFragment)rewrite.createCopyTarget(fragment);
780                 statement.fragments().add(fragmentCopy);
781             }
782             listRewrite.insertAt(statement, statementIndex + 2, null);
783         }
784     }
785
786     private Statement createNewAssignmentStatement(ASTRewrite rewrite) {
787                 AST ast= getAST();
788                 Assignment assignment= ast.newAssignment();
789                 SimpleName fieldName= ast.newSimpleName(fFieldName);
790                 addLinkedName(rewrite, fieldName, true);
791                 assignment.setLeftHandSide(fieldName);
792                 assignment.setRightHandSide(getTempInitializerCopy(rewrite));
793                 return ast.newExpressionStatement(assignment);
794     }
795
796         private void addLinkedName(ASTRewrite rewrite, SimpleName fieldName, boolean isFirst) {
797                 if (fLinkedProposalModel != null) {
798                         fLinkedProposalModel.getPositionGroup(LINKED_NAME, true).addPosition(rewrite.track(fieldName), isFirst);
799                 }
800         }
801
802         private Expression getTempInitializerCopy(ASTRewrite rewrite) {
803                 final Expression initializer= (Expression) rewrite.createCopyTarget(getTempInitializer());
804                 if (initializer instanceof ArrayInitializer && ASTNodes.getDimensions(fTempDeclarationNode) > 0) {
805                         ArrayCreation arrayCreation= rewrite.getAST().newArrayCreation();
806                         arrayCreation.setType((ArrayType) ASTNodeFactory.newType(rewrite.getAST(), fTempDeclarationNode));
807                         arrayCreation.setInitializer((ArrayInitializer) initializer);
808                         return arrayCreation;
809                 }
810                 return initializer;
811         }
812
813     private void addLocalDeclarationRemoval(ASTRewrite rewrite) {
814                 VariableDeclarationStatement tempDeclarationStatement= getTempDeclarationStatement();
815         List<VariableDeclarationFragment> fragments= tempDeclarationStatement.fragments();
816
817         int fragmentIndex= fragments.indexOf(fTempDeclarationNode);
818         Assert.isTrue(fragmentIndex != -1);
819         VariableDeclarationFragment fragment= fragments.get(fragmentIndex);
820         rewrite.remove(fragment, null);
821         if (fragments.size() == 1)
822                         rewrite.remove(tempDeclarationStatement, null);
823     }
824
825     private void addFieldDeclaration(ASTRewrite rewrite) {
826         final ChildListPropertyDescriptor descriptor= getBodyDeclarationListOfDeclaringType();
827         FieldDeclaration[] fields= getFieldDeclarations(getBodyDeclarationListOfDeclaringType());
828         final ASTNode parent= getMethodDeclaration().getParent();
829         int insertIndex;
830         if (fields.length == 0)
831                 insertIndex= 0;
832         else
833                 insertIndex= ((List<? extends ASTNode>) parent.getStructuralProperty(descriptor)).indexOf(fields[fields.length - 1]) + 1;
834
835         final FieldDeclaration declaration= createNewFieldDeclaration(rewrite);
836                 rewrite.getListRewrite(parent, descriptor).insertAt(declaration, insertIndex, null);
837     }
838
839     private FieldDeclaration createNewFieldDeclaration(ASTRewrite rewrite) {
840                 AST ast= getAST();
841                 VariableDeclarationFragment fragment= ast.newVariableDeclarationFragment();
842                 SimpleName variableName= ast.newSimpleName(fFieldName);
843                 fragment.setName(variableName);
844                 addLinkedName(rewrite, variableName, false);
845                 fragment.setExtraDimensions(fTempDeclarationNode.getExtraDimensions());
846                 if (fInitializeIn == INITIALIZE_IN_FIELD && tempHasInitializer()){
847                     Expression initializer= (Expression)rewrite.createCopyTarget(getTempInitializer());
848                     fragment.setInitializer(initializer);
849                 }
850                 FieldDeclaration fieldDeclaration= ast.newFieldDeclaration(fragment);
851
852                 VariableDeclarationStatement vds= getTempDeclarationStatement();
853                 Type type= (Type)rewrite.createCopyTarget(vds.getType());
854                 fieldDeclaration.setType(type);
855                 fieldDeclaration.modifiers().addAll(ASTNodeFactory.newModifiers(ast, getModifiers()));
856                 return fieldDeclaration;
857     }
858
859     private int getModifiers() {
860         int flags= fVisibility;
861         if (fDeclareFinal)
862                 flags |= Modifier.FINAL;
863         if (fDeclareStatic)
864                 flags |= Modifier.STATIC;
865         return flags;
866     }
867
868     private AST getAST(){
869         return fTempDeclarationNode.getAST();
870     }
871
872     private static class LocalTypeAndVariableUsageAnalyzer extends HierarchicalASTVisitor{
873         private final List<IBinding> fLocalDefinitions= new ArrayList<IBinding>(0); // List of IBinding (Variable and Type)
874         private final List<SimpleName> fLocalReferencesToEnclosing= new ArrayList<SimpleName>(0); // List of ASTNodes
875                 private final List<ITypeBinding> fMethodTypeVariables;
876                 private boolean fClassTypeVariablesUsed= false;
877         public LocalTypeAndVariableUsageAnalyzer(ITypeBinding[] methodTypeVariables) {
878                         fMethodTypeVariables= Arrays.asList(methodTypeVariables);
879                 }
880                 public List<SimpleName> getUsageOfEnclosingNodes(){
881                         return fLocalReferencesToEnclosing;
882                 }
883                 public boolean getClassTypeVariablesUsed() {
884                         return fClassTypeVariablesUsed;
885                 }
886                 @Override
887                 public boolean visit(SimpleName node) {
888                         ITypeBinding typeBinding= node.resolveTypeBinding();
889                         if (typeBinding != null && typeBinding.isLocal()) {
890                                 if (node.isDeclaration()) {
891                                         fLocalDefinitions.add(typeBinding);
892                                 } else if (! fLocalDefinitions.contains(typeBinding)) {
893                                         fLocalReferencesToEnclosing.add(node);
894                                 }
895                         }
896                         if (typeBinding != null && typeBinding.isTypeVariable()) {
897                                 if (node.isDeclaration()) {
898                                         fLocalDefinitions.add(typeBinding);
899                                 } else if (! fLocalDefinitions.contains(typeBinding)) {
900                                         if (fMethodTypeVariables.contains(typeBinding)) {
901                                                 fLocalReferencesToEnclosing.add(node);
902                                         } else {
903                                                 fClassTypeVariablesUsed= true;
904                                         }
905                                 }
906                         }
907                         IBinding binding= node.resolveBinding();
908                         if (binding != null && binding.getKind() == IBinding.VARIABLE && ! ((IVariableBinding)binding).isField()) {
909                                 if (node.isDeclaration()) {
910                                         fLocalDefinitions.add(binding);
911                                 } else if (! fLocalDefinitions.contains(binding)) {
912                                         fLocalReferencesToEnclosing.add(node);
913                                 }
914                         }
915                         return super.visit(node);
916                 }
917     }
918
919         private RefactoringStatus initialize(JavaRefactoringArguments arguments) {
920                 fSelfInitializing= true;
921                 final String selection= arguments.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION);
922                 if (selection != null) {
923                         int offset= -1;
924                         int length= -1;
925                         final StringTokenizer tokenizer= new StringTokenizer(selection);
926                         if (tokenizer.hasMoreTokens())
927                                 offset= Integer.valueOf(tokenizer.nextToken()).intValue();
928                         if (tokenizer.hasMoreTokens())
929                                 length= Integer.valueOf(tokenizer.nextToken()).intValue();
930                         if (offset >= 0 && length >= 0) {
931                                 fSelectionStart= offset;
932                                 fSelectionLength= length;
933                         } else
934                                 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_illegal_argument, new Object[] { selection, JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION}));
935                 } else
936                         return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION));
937                 final String handle= arguments.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT);
938                 if (handle != null) {
939                         final IJavaElement element= JavaRefactoringDescriptorUtil.handleToElement(arguments.getProject(), handle, false);
940                         if (element == null || !element.exists() || element.getElementType() != IJavaElement.COMPILATION_UNIT)
941                                 return JavaRefactoringDescriptorUtil.createInputFatalStatus(element, getName(), IJavaRefactorings.CONVERT_LOCAL_VARIABLE);
942                         else
943                                 fCu= (ICompilationUnit) element;
944                 } else
945                         return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT));
946                 final String visibility= arguments.getAttribute(ATTRIBUTE_VISIBILITY);
947                 if (visibility != null && !"".equals(visibility)) {//$NON-NLS-1$
948                         int flag= 0;
949                         try {
950                                 flag= Integer.parseInt(visibility);
951                         } catch (NumberFormatException exception) {
952                                 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_VISIBILITY));
953                         }
954                         fVisibility= flag;
955                 }
956                 final String initialize= arguments.getAttribute(ATTRIBUTE_INITIALIZE);
957                 if (initialize != null && !"".equals(initialize)) {//$NON-NLS-1$
958                         int value= 0;
959                         try {
960                                 value= Integer.parseInt(initialize);
961                         } catch (NumberFormatException exception) {
962                                 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_INITIALIZE));
963                         }
964                         fInitializeIn= value;
965                 }
966                 final String name= arguments.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME);
967                 if (name != null && !"".equals(name)) //$NON-NLS-1$
968                         fFieldName= name;
969                 else
970                         return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME));
971                 final String declareStatic= arguments.getAttribute(ATTRIBUTE_STATIC);
972                 if (declareStatic != null) {
973                         fDeclareStatic= Boolean.valueOf(declareStatic).booleanValue();
974                 } else
975                         return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_STATIC));
976                 final String declareFinal= arguments.getAttribute(ATTRIBUTE_FINAL);
977                 if (declareFinal != null) {
978                         fDeclareFinal= Boolean.valueOf(declareFinal).booleanValue();
979                 } else
980                         return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_FINAL));
981                 return new RefactoringStatus();
982         }
983
984
985         public void setLinkedProposalModel(LinkedProposalModel model) {
986                 fLinkedProposalModel= model;
987         }
988 }