]> git.uio.no Git - ifi-stolz-refaktor.git/blob - case-study/jdt-before/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/InlineConstantRefactoring.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-before / core refactoring / org / eclipse / jdt / internal / corext / refactoring / code / InlineConstantRefactoring.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.HashMap;
15 import java.util.HashSet;
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.Set;
20 import java.util.StringTokenizer;
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.MalformedTreeException;
29 import org.eclipse.text.edits.RangeMarker;
30 import org.eclipse.text.edits.TextEdit;
31 import org.eclipse.text.edits.TextEditGroup;
32
33 import org.eclipse.jface.text.BadLocationException;
34 import org.eclipse.jface.text.Document;
35 import org.eclipse.jface.text.IDocument;
36 import org.eclipse.jface.text.IRegion;
37 import org.eclipse.jface.text.TextUtilities;
38
39 import org.eclipse.ltk.core.refactoring.Change;
40 import org.eclipse.ltk.core.refactoring.Refactoring;
41 import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
42 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
43
44 import org.eclipse.jdt.core.Flags;
45 import org.eclipse.jdt.core.ICompilationUnit;
46 import org.eclipse.jdt.core.IField;
47 import org.eclipse.jdt.core.IJavaElement;
48 import org.eclipse.jdt.core.IJavaProject;
49 import org.eclipse.jdt.core.ISourceRange;
50 import org.eclipse.jdt.core.JavaModelException;
51 import org.eclipse.jdt.core.dom.AST;
52 import org.eclipse.jdt.core.dom.ASTNode;
53 import org.eclipse.jdt.core.dom.ASTParser;
54 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
55 import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
56 import org.eclipse.jdt.core.dom.ArrayCreation;
57 import org.eclipse.jdt.core.dom.ArrayInitializer;
58 import org.eclipse.jdt.core.dom.ArrayType;
59 import org.eclipse.jdt.core.dom.Assignment;
60 import org.eclipse.jdt.core.dom.BodyDeclaration;
61 import org.eclipse.jdt.core.dom.CastExpression;
62 import org.eclipse.jdt.core.dom.CompilationUnit;
63 import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
64 import org.eclipse.jdt.core.dom.Expression;
65 import org.eclipse.jdt.core.dom.FieldAccess;
66 import org.eclipse.jdt.core.dom.FieldDeclaration;
67 import org.eclipse.jdt.core.dom.IBinding;
68 import org.eclipse.jdt.core.dom.IMethodBinding;
69 import org.eclipse.jdt.core.dom.ITypeBinding;
70 import org.eclipse.jdt.core.dom.IVariableBinding;
71 import org.eclipse.jdt.core.dom.ImportDeclaration;
72 import org.eclipse.jdt.core.dom.MethodInvocation;
73 import org.eclipse.jdt.core.dom.Modifier;
74 import org.eclipse.jdt.core.dom.Name;
75 import org.eclipse.jdt.core.dom.NodeFinder;
76 import org.eclipse.jdt.core.dom.ParenthesizedExpression;
77 import org.eclipse.jdt.core.dom.QualifiedName;
78 import org.eclipse.jdt.core.dom.SimpleName;
79 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
80 import org.eclipse.jdt.core.dom.Type;
81 import org.eclipse.jdt.core.dom.TypeDeclarationStatement;
82 import org.eclipse.jdt.core.dom.VariableDeclaration;
83 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
84 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
85 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext;
86 import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
87 import org.eclipse.jdt.core.refactoring.CompilationUnitChange;
88 import org.eclipse.jdt.core.refactoring.IJavaRefactorings;
89 import org.eclipse.jdt.core.refactoring.descriptors.InlineConstantDescriptor;
90 import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor;
91 import org.eclipse.jdt.core.search.IJavaSearchConstants;
92 import org.eclipse.jdt.core.search.SearchMatch;
93 import org.eclipse.jdt.core.search.SearchPattern;
94
95 import org.eclipse.jdt.internal.core.refactoring.descriptors.RefactoringSignatureDescriptorFactory;
96 import org.eclipse.jdt.internal.corext.Corext;
97 import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext;
98 import org.eclipse.jdt.internal.corext.codemanipulation.ImportReferencesCollector;
99 import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
100 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
101 import org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor;
102 import org.eclipse.jdt.internal.corext.dom.NecessaryParenthesesChecker;
103 import org.eclipse.jdt.internal.corext.dom.fragments.ASTFragmentFactory;
104 import org.eclipse.jdt.internal.corext.dom.fragments.IExpressionFragment;
105 import org.eclipse.jdt.internal.corext.refactoring.Checks;
106 import org.eclipse.jdt.internal.corext.refactoring.IRefactoringSearchRequestor;
107 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment;
108 import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments;
109 import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringDescriptorUtil;
110 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
111 import org.eclipse.jdt.internal.corext.refactoring.RefactoringScopeFactory;
112 import org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine2;
113 import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup;
114 import org.eclipse.jdt.internal.corext.refactoring.base.RefactoringStatusCodes;
115 import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange;
116 import org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil;
117 import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite;
118 import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil;
119 import org.eclipse.jdt.internal.corext.refactoring.util.TightSourceRangeComputer;
120 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
121 import org.eclipse.jdt.internal.corext.util.Messages;
122 import org.eclipse.jdt.internal.corext.util.Strings;
123
124 import org.eclipse.jdt.ui.JavaElementLabels;
125
126 import org.eclipse.jdt.internal.ui.JavaPlugin;
127 import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;
128
129 public class InlineConstantRefactoring extends Refactoring {
130
131         private static final String ATTRIBUTE_REPLACE= "replace"; //$NON-NLS-1$
132         private static final String ATTRIBUTE_REMOVE= "remove";  //$NON-NLS-1$
133
134         private static class InlineTargetCompilationUnit {
135
136                 private static class InitializerTraversal extends HierarchicalASTVisitor {
137
138                         private static boolean areInSameType(ASTNode one, ASTNode other) {
139                                 ASTNode onesContainer= getContainingTypeDeclaration(one);
140                                 ASTNode othersContainer= getContainingTypeDeclaration(other);
141
142                                 if (onesContainer == null || othersContainer == null)
143                                         return false;
144
145                                 ITypeBinding onesContainerBinding= getTypeBindingForTypeDeclaration(onesContainer);
146                                 ITypeBinding othersContainerBinding= getTypeBindingForTypeDeclaration(othersContainer);
147
148                                 Assert.isNotNull(onesContainerBinding);
149                                 Assert.isNotNull(othersContainerBinding);
150
151                                 String onesKey= onesContainerBinding.getKey();
152                                 String othersKey= othersContainerBinding.getKey();
153
154                                 if (onesKey == null || othersKey == null)
155                                         return false;
156
157                                 return onesKey.equals(othersKey);
158                         }
159
160                         private static boolean isStaticAccess(SimpleName memberName) {
161                                 IBinding binding= memberName.resolveBinding();
162                                 Assert.isTrue(binding instanceof IVariableBinding || binding instanceof IMethodBinding || binding instanceof ITypeBinding);
163
164                                 if (binding instanceof ITypeBinding)
165                                         return true;
166
167                                 if (binding instanceof IVariableBinding)
168                                         return ((IVariableBinding) binding).isField();
169
170                                 int modifiers= binding.getModifiers();
171                                 return Modifier.isStatic(modifiers);
172                         }
173
174                         private static ASTNode getContainingTypeDeclaration(ASTNode node) {
175                                 while (node != null && !(node instanceof AbstractTypeDeclaration) && !(node instanceof AnonymousClassDeclaration)) {
176                                         node= node.getParent();
177                                 }
178                                 return node;
179                         }
180
181                         private static ITypeBinding getTypeBindingForTypeDeclaration(ASTNode declaration) {
182                                 if (declaration instanceof AnonymousClassDeclaration)
183                                         return ((AnonymousClassDeclaration) declaration).resolveBinding();
184
185                                 if (declaration instanceof AbstractTypeDeclaration)
186                                         return ((AbstractTypeDeclaration) declaration).resolveBinding();
187
188                                 Assert.isTrue(false);
189                                 return null;
190                         }
191
192                         private final Expression fInitializer;
193                         private ASTRewrite fInitializerRewrite;
194                         private final HashSet<SimpleName> fStaticImportsInInitializer2;
195
196                         // cache:
197                         private Set<String> fNamesDeclaredLocallyAtNewLocation;
198
199                         private final Expression fNewLocation;
200                         private final HashSet<SimpleName> fStaticImportsInReference;
201                         private final CompilationUnitRewrite fNewLocationCuRewrite;
202                         private final ImportRewriteContext fNewLocationContext;
203
204                         public InitializerTraversal(Expression initializer, HashSet<SimpleName> staticImportsInInitializer, Expression newLocation, HashSet<SimpleName> staticImportsInReference, CompilationUnitRewrite newLocationCuRewrite) {
205                                 fInitializer= initializer;
206                                 fInitializerRewrite= ASTRewrite.create(initializer.getAST());
207                                 fStaticImportsInInitializer2= staticImportsInInitializer;
208
209                                 fNewLocation= newLocation;
210                                 fStaticImportsInReference= staticImportsInReference;
211                                 fNewLocationCuRewrite= newLocationCuRewrite;
212                                 fNewLocationContext= new ContextSensitiveImportRewriteContext(fNewLocation, fNewLocationCuRewrite.getImportRewrite());
213
214                                 perform(initializer);
215                         }
216
217                         /**
218                          * @param scope not a TypeDeclaration
219                          * @return Set containing Strings representing simple names
220                          */
221                         private Set<String> getLocallyDeclaredNames(BodyDeclaration scope) {
222                                 Assert.isTrue(!(scope instanceof AbstractTypeDeclaration));
223
224                                 final Set<String> result= new HashSet<String>();
225
226                                 if (scope instanceof FieldDeclaration)
227                                         return result;
228
229                                 scope.accept(new HierarchicalASTVisitor() {
230
231                                         @Override
232                                         public boolean visit(AbstractTypeDeclaration node) {
233                                                 Assert.isTrue(node.getParent() instanceof TypeDeclarationStatement);
234
235                                                 result.add(node.getName().getIdentifier());
236                                                 return false;
237                                         }
238
239                                         @Override
240                                         public boolean visit(AnonymousClassDeclaration anonDecl) {
241                                                 return false;
242                                         }
243
244                                         @Override
245                                         public boolean visit(VariableDeclaration varDecl) {
246                                                 result.add(varDecl.getName().getIdentifier());
247                                                 return false;
248                                         }
249                                 });
250                                 return result;
251                         }
252
253                         public ASTRewrite getInitializerRewrite() {
254                                 return fInitializerRewrite;
255                         }
256
257                         private void perform(Expression initializer) {
258                                 initializer.accept(this);
259                                 addExplicitTypeArgumentsIfNecessary(initializer);
260                         }
261
262                         private void addExplicitTypeArgumentsIfNecessary(Expression invocation) {
263                                 if (Invocations.isResolvedTypeInferredFromExpectedType(invocation)) {
264                                         ASTNode referenceContext= fNewLocation.getParent();
265                                         if (! (referenceContext instanceof VariableDeclarationFragment
266                                                         || referenceContext instanceof SingleVariableDeclaration
267                                                         || referenceContext instanceof Assignment)) {
268                                                 ITypeBinding[] typeArguments= Invocations.getInferredTypeArguments(invocation);
269                                                 ListRewrite typeArgsRewrite= Invocations.getInferredTypeArgumentsRewrite(fInitializerRewrite, invocation);
270                                                 for (int i= 0; i < typeArguments.length; i++) {
271                                                         Type typeArgument= fNewLocationCuRewrite.getImportRewrite().addImport(typeArguments[i], fNewLocationCuRewrite.getAST(), fNewLocationContext);
272                                                         fNewLocationCuRewrite.getImportRemover().registerAddedImports(typeArgument);
273                                                         typeArgsRewrite.insertLast(typeArgument, null);
274                                                 }
275                                                 
276                                                 if (invocation instanceof MethodInvocation) {
277                                                         MethodInvocation methodInvocation= (MethodInvocation) invocation;
278                                                         Expression expression= methodInvocation.getExpression();
279                                                         if (expression == null) {
280                                                                 IMethodBinding methodBinding= methodInvocation.resolveMethodBinding();
281                                                                 if (methodBinding != null) {
282                                                                         expression= fNewLocationCuRewrite.getAST().newName(fNewLocationCuRewrite.getImportRewrite().addImport(methodBinding.getDeclaringClass().getTypeDeclaration(), fNewLocationContext));
283                                                                         fInitializerRewrite.set(invocation, MethodInvocation.EXPRESSION_PROPERTY, expression, null);
284                                                                 }
285                                                         }
286                                                 }
287                                         }
288                                 }
289                         }
290
291                         @Override
292                         public boolean visit(FieldAccess fieldAccess) {
293                                 fieldAccess.getExpression().accept(this);
294                                 return false;
295                         }
296
297                         @Override
298                         public boolean visit(MethodInvocation invocation) {
299                                 if (invocation.getExpression() == null)
300                                         qualifyUnqualifiedMemberNameIfNecessary(invocation.getName());
301                                 else
302                                         invocation.getExpression().accept(this);
303
304                                 for (Iterator<Expression> it= invocation.arguments().iterator(); it.hasNext();)
305                                         it.next().accept(this);
306
307                                 return false;
308                         }
309
310                         @Override
311                         public boolean visit(Name name) {
312                                 SimpleName leftmost= getLeftmost(name);
313
314                                 IBinding leftmostBinding= leftmost.resolveBinding();
315                                 if (leftmostBinding instanceof IVariableBinding || leftmostBinding instanceof IMethodBinding || leftmostBinding instanceof ITypeBinding) {
316                                         if (shouldUnqualify(leftmost))
317                                                 unqualifyMemberName(leftmost);
318                                         else
319                                                 qualifyUnqualifiedMemberNameIfNecessary(leftmost);
320                                 }
321
322                                 if (leftmostBinding instanceof ITypeBinding) {
323                                         String addedImport= fNewLocationCuRewrite.getImportRewrite().addImport((ITypeBinding)leftmostBinding, fNewLocationContext);
324                                         fNewLocationCuRewrite.getImportRemover().registerAddedImport(addedImport);
325                                 }
326
327                                 return false;
328                         }
329
330                         private void qualifyUnqualifiedMemberNameIfNecessary(SimpleName memberName) {
331                                 if (shouldQualify(memberName))
332                                         qualifyMemberName(memberName);
333                         }
334
335                         private boolean shouldUnqualify(SimpleName memberName) {
336                                 if (areInSameType(memberName, fNewLocation))
337                                         return ! mayBeShadowedByLocalDeclaration(memberName);
338
339                                 return false;
340                         }
341
342                         private void unqualifyMemberName(SimpleName memberName) {
343                                 if (doesParentQualify(memberName))
344                                         fInitializerRewrite.replace(memberName.getParent(), memberName, null);
345                         }
346
347                         private boolean shouldQualify(SimpleName memberName) {
348                                 if (! areInSameType(fInitializer, fNewLocation))
349                                         return true;
350
351                                 return mayBeShadowedByLocalDeclaration(memberName);
352                         }
353
354                         private boolean mayBeShadowedByLocalDeclaration(SimpleName memberName) {
355                                 return getNamesDeclaredLocallyAtNewLocation().contains(memberName.getIdentifier());
356                         }
357
358                         private Set<String> getNamesDeclaredLocallyAtNewLocation() {
359                                 if (fNamesDeclaredLocallyAtNewLocation != null)
360                                         return fNamesDeclaredLocallyAtNewLocation;
361
362                                 BodyDeclaration enclosingBodyDecl= (BodyDeclaration) ASTNodes.getParent(fNewLocation, BodyDeclaration.class);
363                                 Assert.isTrue(!(enclosingBodyDecl instanceof AbstractTypeDeclaration));
364
365                                 return fNamesDeclaredLocallyAtNewLocation= getLocallyDeclaredNames(enclosingBodyDecl);
366                         }
367
368                         private void qualifyMemberName(SimpleName memberName) {
369                                 if (isStaticAccess(memberName)) {
370                                         IBinding memberBinding= memberName.resolveBinding();
371
372                                         if (memberBinding instanceof IVariableBinding || memberBinding instanceof IMethodBinding) {
373                                                 if (fStaticImportsInReference.contains(fNewLocation)) { // use static import if reference location used static import
374                                                         importStatically(memberName, memberBinding);
375                                                         return;
376                                                 } else if (fStaticImportsInInitializer2.contains(memberName)) { // use static import if already imported statically in initializer
377                                                         importStatically(memberName, memberBinding);
378                                                         return;
379                                                 }
380                                         }
381                                         qualifyToTopLevelClass(memberName); //otherwise: qualify and import non-static
382                                 }
383                         }
384
385                         private void importStatically(SimpleName toImport, IBinding binding) {
386                                 String newName= fNewLocationCuRewrite.getImportRewrite().addStaticImport(binding);
387                                 fNewLocationCuRewrite.getImportRemover().registerAddedStaticImport(binding);
388
389                                 Name newReference= ASTNodeFactory.newName(fInitializerRewrite.getAST(), newName);
390                                 fInitializerRewrite.replace(toImport, newReference, null);
391                         }
392
393                         private void qualifyToTopLevelClass(SimpleName toQualify) {
394                                 ITypeBinding declaringClass= getDeclaringClassBinding(toQualify);
395                                 if (declaringClass == null)
396                                         return;
397
398                                 Type newQualification= fNewLocationCuRewrite.getImportRewrite().addImport(declaringClass, fInitializerRewrite.getAST(), fNewLocationContext);
399                                 fNewLocationCuRewrite.getImportRemover().registerAddedImports(newQualification);
400
401                                 SimpleName newToQualify= (SimpleName) fInitializerRewrite.createMoveTarget(toQualify);
402                                 Type newType= fInitializerRewrite.getAST().newQualifiedType(newQualification, newToQualify);
403                                 fInitializerRewrite.replace(toQualify, newType, null);
404                         }
405
406                         private static ITypeBinding getDeclaringClassBinding(SimpleName memberName) {
407
408                                 IBinding binding= memberName.resolveBinding();
409                                 if (binding instanceof IMethodBinding)
410                                         return ((IMethodBinding) binding).getDeclaringClass();
411
412                                 if (binding instanceof IVariableBinding)
413                                         return ((IVariableBinding) binding).getDeclaringClass();
414
415                                 if (binding instanceof ITypeBinding)
416                                         return ((ITypeBinding) binding).getDeclaringClass();
417
418                                 Assert.isTrue(false);
419                                 return null;
420
421                         }
422
423                 }
424
425                 private final Expression fInitializer;
426                 private final ICompilationUnit fInitializerUnit;
427                 private final VariableDeclarationFragment fOriginalDeclaration;
428
429                 /** The references in this compilation unit, represented as AST Nodes in the parsed representation of the compilation unit */
430                 private final Expression[] fReferences;
431                 private final VariableDeclarationFragment fDeclarationToRemove;
432                 private final CompilationUnitRewrite fCuRewrite;
433                 private final TightSourceRangeComputer fSourceRangeComputer;
434                 private final HashSet<SimpleName> fStaticImportsInInitializer;
435                 private final boolean fIs15;
436
437                 private InlineTargetCompilationUnit(CompilationUnitRewrite cuRewrite, Name[] references, InlineConstantRefactoring refactoring, HashSet<SimpleName> staticImportsInInitializer) {
438                         fInitializer= refactoring.getInitializer();
439                         fInitializerUnit= refactoring.getDeclaringCompilationUnit();
440
441                         fCuRewrite= cuRewrite;
442                         fSourceRangeComputer= new TightSourceRangeComputer();
443                         fCuRewrite.getASTRewrite().setTargetSourceRangeComputer(fSourceRangeComputer);
444                         if (refactoring.getRemoveDeclaration() && refactoring.getReplaceAllReferences() && cuRewrite.getCu().equals(fInitializerUnit))
445                                 fDeclarationToRemove= refactoring.getDeclaration();
446                         else
447                                 fDeclarationToRemove= null;
448
449                         fOriginalDeclaration= refactoring.getDeclaration();
450
451                         fReferences= new Expression[references.length];
452                         for (int i= 0; i < references.length; i++)
453                                 fReferences[i]= getQualifiedReference(references[i]);
454
455                         fIs15= JavaModelUtil.is50OrHigher(cuRewrite.getCu().getJavaProject());
456                         fStaticImportsInInitializer= fIs15 ? staticImportsInInitializer : new HashSet<SimpleName>(0);
457                 }
458
459                 private static Expression getQualifiedReference(Name fieldName) {
460                         if (doesParentQualify(fieldName))
461                                 return (Expression) fieldName.getParent();
462
463                         return fieldName;
464                 }
465
466                 private static boolean doesParentQualify(Name fieldName) {
467                         ASTNode parent= fieldName.getParent();
468                         Assert.isNotNull(parent);
469
470                         if (parent instanceof FieldAccess && ((FieldAccess) parent).getName() == fieldName)
471                                 return true;
472
473                         if (parent instanceof QualifiedName && ((QualifiedName) parent).getName() == fieldName)
474                                 return true;
475
476                         if (parent instanceof MethodInvocation && ((MethodInvocation) parent).getName() == fieldName)
477                                 return true;
478
479                         return false;
480                 }
481
482                 public CompilationUnitChange getChange() throws CoreException {
483                         for (int i= 0; i < fReferences.length; i++)
484                                 inlineReference(fReferences[i]);
485
486                         removeConstantDeclarationIfNecessary();
487
488                         return fCuRewrite.createChange(true);
489                 }
490
491                 private void inlineReference(Expression reference) throws CoreException {
492                         ASTNode importDecl= ASTNodes.getParent(reference, ImportDeclaration.class);
493                         if (importDecl != null) {
494                                 fCuRewrite.getImportRemover().registerInlinedStaticImport((ImportDeclaration) importDecl);
495                                 return;
496                         }
497
498                         String modifiedInitializer= prepareInitializerForLocation(reference);
499                         if (modifiedInitializer == null)
500                                 return;
501
502                         TextEditGroup msg= fCuRewrite.createGroupDescription(RefactoringCoreMessages.InlineConstantRefactoring_Inline);
503                         
504                         Expression newReference;
505                         boolean isStringPlaceholder= false;
506
507                         AST ast= fCuRewrite.getAST();
508                         ITypeBinding explicitCast= ASTNodes.getExplicitCast(fInitializer, reference);
509                         if (explicitCast != null) {
510                                 CastExpression cast= ast.newCastExpression();
511                                 Expression modifiedInitializerExpr= (Expression) fCuRewrite.getASTRewrite().createStringPlaceholder(modifiedInitializer, reference.getNodeType());
512                                 if (NecessaryParenthesesChecker.needsParentheses(fInitializer, cast, CastExpression.EXPRESSION_PROPERTY)) {
513                                         ParenthesizedExpression parenthesized= ast.newParenthesizedExpression();
514                                         parenthesized.setExpression(modifiedInitializerExpr);
515                                         modifiedInitializerExpr= parenthesized;
516                                 }
517                                 cast.setExpression(modifiedInitializerExpr);
518                                 ImportRewriteContext context= new ContextSensitiveImportRewriteContext(reference, fCuRewrite.getImportRewrite());
519                                 cast.setType(fCuRewrite.getImportRewrite().addImport(explicitCast, ast, context));
520                                 newReference= cast;
521                                 
522                         } else if (fInitializer instanceof ArrayInitializer) {
523                                 ArrayCreation arrayCreation= ast.newArrayCreation();
524                                 ArrayType arrayType= (ArrayType) ASTNodeFactory.newType(ast, fOriginalDeclaration);
525                                 arrayCreation.setType(arrayType);
526
527                                 ArrayInitializer newArrayInitializer= (ArrayInitializer) fCuRewrite.getASTRewrite().createStringPlaceholder(modifiedInitializer,
528                                                 ASTNode.ARRAY_INITIALIZER);
529                                 arrayCreation.setInitializer(newArrayInitializer);
530                                 newReference= arrayCreation;
531
532                                 ITypeBinding typeToAddToImport= ASTNodes.getType(fOriginalDeclaration).resolveBinding();
533                                 ImportRewriteContext context= new ContextSensitiveImportRewriteContext(reference, fCuRewrite.getImportRewrite());
534                                 fCuRewrite.getImportRewrite().addImport(typeToAddToImport, context);
535                                 fCuRewrite.getImportRemover().registerAddedImport(typeToAddToImport.getName());
536                                 
537                         } else {
538                                 newReference= (Expression) fCuRewrite.getASTRewrite().createStringPlaceholder(modifiedInitializer, reference.getNodeType());
539                                 isStringPlaceholder= true;
540                         }
541
542                         if (NecessaryParenthesesChecker.needsParentheses((isStringPlaceholder ? fInitializer : newReference), reference.getParent(), reference.getLocationInParent())) {
543                                 ParenthesizedExpression parenthesized= ast.newParenthesizedExpression();
544                                 parenthesized.setExpression(newReference);
545                                 newReference= parenthesized;
546                         }
547                         fCuRewrite.getASTRewrite().replace(reference, newReference, msg);
548                         fSourceRangeComputer.addTightSourceNode(reference);
549                         fCuRewrite.getImportRemover().registerRemovedNode(reference);
550                 }
551
552                 private String prepareInitializerForLocation(Expression location) throws CoreException {
553                         HashSet<SimpleName> staticImportsInReference= new HashSet<SimpleName>();
554                         final IJavaProject project= fCuRewrite.getCu().getJavaProject();
555                         if (fIs15)
556                                 ImportReferencesCollector.collect(location, project, null, new ArrayList<SimpleName>(), staticImportsInReference);
557
558                         InitializerTraversal traversal= new InitializerTraversal(fInitializer, fStaticImportsInInitializer, location, staticImportsInReference, fCuRewrite);
559                         ASTRewrite initializerRewrite= traversal.getInitializerRewrite();
560                         IDocument document= new Document(fInitializerUnit.getBuffer().getContents()); // could reuse document when generating and applying undo edits
561
562                         final RangeMarker marker= new RangeMarker(fInitializer.getStartPosition(), fInitializer.getLength());
563                         TextEdit[] rewriteEdits= initializerRewrite.rewriteAST(document, fInitializerUnit.getJavaProject().getOptions(true)).removeChildren();
564                         marker.addChildren(rewriteEdits);
565                         try {
566                                 marker.apply(document, TextEdit.UPDATE_REGIONS);
567                                 String rewrittenInitializer= document.get(marker.getOffset(), marker.getLength());
568                                 IRegion region= document.getLineInformation(document.getLineOfOffset(marker.getOffset()));
569                                 int oldIndent= Strings.computeIndentUnits(document.get(region.getOffset(), region.getLength()), project);
570                                 return Strings.changeIndent(rewrittenInitializer, oldIndent, project, "", TextUtilities.getDefaultLineDelimiter(document)); //$NON-NLS-1$
571                         } catch (MalformedTreeException e) {
572                                 JavaPlugin.log(e);
573                         } catch (BadLocationException e) {
574                                 JavaPlugin.log(e);
575                         }
576                         return fInitializerUnit.getBuffer().getText(fInitializer.getStartPosition(), fInitializer.getLength());
577                 }
578
579                 private void removeConstantDeclarationIfNecessary() {
580                         if (fDeclarationToRemove == null)
581                                 return;
582
583                         FieldDeclaration parentDeclaration= (FieldDeclaration) fDeclarationToRemove.getParent();
584                         ASTNode toRemove;
585                         if (parentDeclaration.fragments().size() == 1)
586                                 toRemove= parentDeclaration;
587                         else
588                                 toRemove= fDeclarationToRemove;
589
590                         TextEditGroup msg= fCuRewrite.createGroupDescription(RefactoringCoreMessages.InlineConstantRefactoring_remove_declaration);
591                         fCuRewrite.getASTRewrite().remove(toRemove, msg);
592                         fCuRewrite.getImportRemover().registerRemovedNode(toRemove);
593                 }
594         }
595
596         // ---- End InlineTargetCompilationUnit ----------------------------------------------------------------------------------------------
597
598         private static SimpleName getLeftmost(Name name) {
599                 if (name instanceof SimpleName)
600                         return (SimpleName) name;
601
602                 return getLeftmost(((QualifiedName) name).getQualifier());
603         }
604
605         private int fSelectionStart;
606         private int fSelectionLength;
607
608         private ICompilationUnit fSelectionCu;
609         private CompilationUnitRewrite fSelectionCuRewrite;
610         private Name fSelectedConstantName;
611
612         private IField fField;
613         private CompilationUnitRewrite fDeclarationCuRewrite;
614         private VariableDeclarationFragment fDeclaration;
615         private boolean fDeclarationSelected;
616         private boolean fDeclarationSelectedChecked= false;
617         private boolean fInitializerAllStaticFinal;
618         private boolean fInitializerChecked= false;
619
620         private boolean fRemoveDeclaration= false;
621         private boolean fReplaceAllReferences= true;
622
623         private CompilationUnitChange[] fChanges;
624
625         /**
626          * Creates a new inline constant refactoring.
627          * <p>
628          * This constructor is only used by <code>DelegateCreator</code>.
629          * </p>
630          *
631          * @param field the field to inline
632          */
633         public InlineConstantRefactoring(IField field) {
634                 Assert.isNotNull(field);
635                 Assert.isTrue(!field.isBinary());
636                 fField= field;
637         }
638
639         /**
640          * Creates a new inline constant refactoring.
641          * 
642          * @param unit the compilation unit, or <code>null</code> if invoked by scripting
643          * @param node the compilation unit node, or <code>null</code> if invoked by scripting
644          * @param selectionStart the start of the selection
645          * @param selectionLength the length of the selection
646          */
647         public InlineConstantRefactoring(ICompilationUnit unit, CompilationUnit node, int selectionStart, int selectionLength) {
648                 Assert.isTrue(selectionStart >= 0);
649                 Assert.isTrue(selectionLength >= 0);
650                 fSelectionCu= unit;
651                 fSelectionStart= selectionStart;
652                 fSelectionLength= selectionLength;
653                 if (unit != null)
654                         initialize(unit, node);
655         }
656
657     public InlineConstantRefactoring(JavaRefactoringArguments arguments, RefactoringStatus status) {
658                 this(null, null, 0, 0);
659                 RefactoringStatus initializeStatus= initialize(arguments);
660                 status.merge(initializeStatus);
661     }
662
663         private void initialize(ICompilationUnit cu, CompilationUnit node) {
664                 fSelectionCuRewrite= new CompilationUnitRewrite(cu, node);
665                 fSelectedConstantName= findConstantNameNode();
666         }
667
668         private Name findConstantNameNode() {
669                 ASTNode node= NodeFinder.perform(fSelectionCuRewrite.getRoot(), fSelectionStart, fSelectionLength);
670                 if (node == null)
671                         return null;
672                 if (node instanceof FieldAccess)
673                         node= ((FieldAccess) node).getName();
674                 if (node.getParent() instanceof EnumConstantDeclaration)
675                         return null;
676                 if (!(node instanceof Name))
677                         return null;
678                 Name name= (Name) node;
679                 IBinding binding= name.resolveBinding();
680                 if (!(binding instanceof IVariableBinding))
681                         return null;
682                 IVariableBinding variableBinding= (IVariableBinding) binding;
683                 if (!variableBinding.isField() || variableBinding.isEnumConstant())
684                         return null;
685                 int modifiers= binding.getModifiers();
686                 if (! (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)))
687                         return null;
688
689                 return name;
690         }
691
692         public RefactoringStatus checkStaticFinalConstantNameSelected() {
693                 if (fSelectedConstantName == null)
694                         return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.InlineConstantRefactoring_static_final_field, null, Corext.getPluginId(), RefactoringStatusCodes.NOT_STATIC_FINAL_SELECTED, null);
695
696                 return new RefactoringStatus();
697         }
698
699         @Override
700         public String getName() {
701                 return RefactoringCoreMessages.InlineConstantRefactoring_name;
702         }
703
704         /**
705          * Returns the field to inline, or null if the field could not be found or
706          * {@link #checkInitialConditions(IProgressMonitor)} has not been called yet.
707          *
708          * @return the field, or <code>null</code>
709          */
710         public IJavaElement getField() {
711                 return fField;
712         }
713
714         @Override
715         public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException {
716                 try {
717                         pm.beginTask("", 3); //$NON-NLS-1$
718
719                         if (!fSelectionCu.isStructureKnown())
720                                 return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.InlineConstantRefactoring_syntax_errors, null, Corext.getPluginId(), RefactoringStatusCodes.SYNTAX_ERRORS, null);
721
722                         RefactoringStatus result= checkStaticFinalConstantNameSelected();
723                         if (result.hasFatalError())
724                                 return result;
725
726                         result.merge(findField());
727                         if (result.hasFatalError())
728                                 return result;
729                         pm.worked(1);
730
731                         result.merge(findDeclaration());
732                         if (result.hasFatalError())
733                                 return result;
734                         pm.worked(1);
735
736                         result.merge(checkInitializer());
737                         if (result.hasFatalError())
738                                 return result;
739                         pm.worked(1);
740
741                         return result;
742
743                 } finally {
744                         pm.done();
745                 }
746         }
747
748         private RefactoringStatus findField() {
749                 fField= (IField) ((IVariableBinding) fSelectedConstantName.resolveBinding()).getJavaElement();
750                 if (fField != null && ! fField.exists())
751                         return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.InlineConstantRefactoring_local_anonymous_unsupported, null, Corext.getPluginId(), RefactoringStatusCodes.LOCAL_AND_ANONYMOUS_NOT_SUPPORTED, null);
752
753                 return null;
754         }
755         private RefactoringStatus findDeclaration() throws JavaModelException {
756                 fDeclarationSelectedChecked= true;
757                 fDeclarationSelected= false;
758                 ASTNode parent= fSelectedConstantName.getParent();
759                 if (parent instanceof VariableDeclarationFragment) {
760                         VariableDeclarationFragment parentDeclaration= (VariableDeclarationFragment) parent;
761                         if (parentDeclaration.getName() == fSelectedConstantName) {
762                                 fDeclarationSelected= true;
763                                 fDeclarationCuRewrite= fSelectionCuRewrite;
764                                 fDeclaration= (VariableDeclarationFragment) fSelectedConstantName.getParent();
765                                 return null;
766                         }
767                 }
768
769                 VariableDeclarationFragment declaration= (VariableDeclarationFragment) fSelectionCuRewrite.getRoot().findDeclaringNode(fSelectedConstantName.resolveBinding());
770                 if (declaration != null) {
771                         fDeclarationCuRewrite= fSelectionCuRewrite;
772                         fDeclaration= declaration;
773                         return null;
774                 }
775
776                 if (fField.getCompilationUnit() == null)
777                         return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.InlineConstantRefactoring_binary_file, null, Corext.getPluginId(), RefactoringStatusCodes.DECLARED_IN_CLASSFILE, null);
778
779                 fDeclarationCuRewrite= new CompilationUnitRewrite(fField.getCompilationUnit());
780                 fDeclaration= ASTNodeSearchUtil.getFieldDeclarationFragmentNode(fField, fDeclarationCuRewrite.getRoot());
781                 return null;
782         }
783
784         private RefactoringStatus checkInitializer() {
785                 Expression initializer= getInitializer();
786                 if (initializer == null)
787                         return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.InlineConstantRefactoring_blank_finals, null, Corext.getPluginId(), RefactoringStatusCodes.CANNOT_INLINE_BLANK_FINAL, null);
788
789                 fInitializerAllStaticFinal= ConstantChecks.isStaticFinalConstant((IExpressionFragment) ASTFragmentFactory.createFragmentForFullSubtree(initializer));
790                 fInitializerChecked= true;
791                 return new RefactoringStatus();
792         }
793
794         private VariableDeclarationFragment getDeclaration() {
795                 return fDeclaration;
796         }
797
798         private Expression getInitializer() {
799                 return fDeclaration.getInitializer();
800         }
801
802         private ICompilationUnit getDeclaringCompilationUnit() {
803                 return fField.getCompilationUnit();
804         }
805
806         @Override
807         public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException {
808                 RefactoringStatus result= new RefactoringStatus();
809                 pm.beginTask("", 3); //$NON-NLS-1$
810
811                 try {
812                         List<CompilationUnitChange>changes= new ArrayList<CompilationUnitChange>();
813                         HashSet<SimpleName> staticImportsInInitializer= new HashSet<SimpleName>();
814                         ImportReferencesCollector.collect(getInitializer(), fField.getJavaProject(), null, new ArrayList<SimpleName>(), staticImportsInInitializer);
815
816                         if (getReplaceAllReferences()) {
817                                 SearchResultGroup[] searchResultGroups= findReferences(pm, result);
818                                 for (int i= 0; i < searchResultGroups.length; i++) {
819                                         if (pm.isCanceled())
820                                                 throw new OperationCanceledException();
821                                         SearchResultGroup group= searchResultGroups[i];
822                                         ICompilationUnit cu= group.getCompilationUnit();
823
824                                         CompilationUnitRewrite cuRewrite= getCuRewrite(cu);
825                                         Name[] references= extractReferenceNodes(group.getSearchResults(), cuRewrite.getRoot());
826                                         InlineTargetCompilationUnit targetCompilationUnit= new InlineTargetCompilationUnit(
827                                                         cuRewrite, references, this, staticImportsInInitializer);
828                                         CompilationUnitChange change= targetCompilationUnit.getChange();
829                                         if (change != null)
830                                                 changes.add(change);
831                                 }
832
833                         } else {
834                                 Assert.isTrue(! isDeclarationSelected());
835                                 InlineTargetCompilationUnit targetForOnlySelectedReference= new InlineTargetCompilationUnit(
836                                                 fSelectionCuRewrite, new Name[] { fSelectedConstantName }, this, staticImportsInInitializer);
837                                 CompilationUnitChange change= targetForOnlySelectedReference.getChange();
838                                 if (change != null)
839                                         changes.add(change);
840                         }
841
842                         if (result.hasFatalError())
843                                 return result;
844
845                         if (getRemoveDeclaration() && getReplaceAllReferences()) {
846                                 boolean declarationRemoved= false;
847                                 for (Iterator<CompilationUnitChange> iter= changes.iterator(); iter.hasNext();) {
848                                         CompilationUnitChange change= iter.next();
849                                         if (change.getCompilationUnit().equals(fDeclarationCuRewrite.getCu())) {
850                                                 declarationRemoved= true;
851                                                 break;
852                                         }
853                                 }
854                                 if (! declarationRemoved) {
855                                         InlineTargetCompilationUnit targetForDeclaration= new InlineTargetCompilationUnit(fDeclarationCuRewrite, new Name[0], this, staticImportsInInitializer);
856                                         CompilationUnitChange change= targetForDeclaration.getChange();
857                                         if (change != null)
858                                                 changes.add(change);
859                                 }
860                         }
861
862                         ICompilationUnit[] cus= new ICompilationUnit[changes.size()];
863                         for (int i= 0; i < changes.size(); i++) {
864                                 CompilationUnitChange change= changes.get(i);
865                                 cus[i]= change.getCompilationUnit();
866                         }
867                         result.merge(Checks.validateModifiesFiles(ResourceUtil.getFiles(cus), getValidationContext()));
868
869                         pm.worked(1);
870
871                         fChanges= changes.toArray(new CompilationUnitChange[changes.size()]);
872
873                         return result;
874
875                 } finally {
876                         fSelectionCuRewrite= null;
877                         fSelectedConstantName= null;
878                         fDeclarationCuRewrite= null;
879                         fDeclaration= null;
880                         pm.done();
881                 }
882         }
883
884         private Name[] extractReferenceNodes(SearchMatch[] searchResults, CompilationUnit cuNode) {
885                 Name[] references= new Name[searchResults.length];
886                 for (int i= 0; i < searchResults.length; i++)
887                         references[i]= (Name) NodeFinder.perform(cuNode, searchResults[i].getOffset(), searchResults[i].getLength());
888                 return references;
889         }
890
891         private CompilationUnitRewrite getCuRewrite(ICompilationUnit cu) {
892                 CompilationUnitRewrite cuRewrite;
893                 if (cu.equals(fSelectionCu)) {
894                         cuRewrite= fSelectionCuRewrite;
895                 } else if (cu.equals(fField.getCompilationUnit())) {
896                         cuRewrite= fDeclarationCuRewrite;
897                 } else {
898                         cuRewrite= new CompilationUnitRewrite(cu);
899                 }
900                 return cuRewrite;
901         }
902
903         private SearchResultGroup[] findReferences(IProgressMonitor pm, RefactoringStatus status) throws JavaModelException {
904                 final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(SearchPattern.createPattern(fField, IJavaSearchConstants.REFERENCES));
905                 engine.setFiltering(true, true);
906                 engine.setScope(RefactoringScopeFactory.create(fField));
907                 engine.setStatus(status);
908                 engine.setRequestor(new IRefactoringSearchRequestor() {
909                         public SearchMatch acceptSearchMatch(SearchMatch match) {
910                                 return match.isInsideDocComment() ? null : match;
911                         }
912                 });
913                 engine.searchPattern(new SubProgressMonitor(pm, 1));
914                 return (SearchResultGroup[]) engine.getResults();
915         }
916
917         @Override
918         public Change createChange(IProgressMonitor pm) throws CoreException {
919                 try {
920                         pm.beginTask(RefactoringCoreMessages.InlineConstantRefactoring_preview, 2);
921                         final Map<String, String> arguments= new HashMap<String, String>();
922                         String project= null;
923                         IJavaProject javaProject= fSelectionCu.getJavaProject();
924                         if (javaProject != null)
925                                 project= javaProject.getElementName();
926                         int flags= RefactoringDescriptor.STRUCTURAL_CHANGE | JavaRefactoringDescriptor.JAR_REFACTORING | JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT;
927                         try {
928                                 if (!Flags.isPrivate(fField.getFlags()))
929                                         flags|= RefactoringDescriptor.MULTI_CHANGE;
930                         } catch (JavaModelException exception) {
931                                 JavaPlugin.log(exception);
932                         }
933                         final String description= Messages.format(RefactoringCoreMessages.InlineConstantRefactoring_descriptor_description_short, JavaElementLabels.getElementLabel(fField, JavaElementLabels.ALL_DEFAULT));
934                         final String header= Messages.format(RefactoringCoreMessages.InlineConstantRefactoring_descriptor_description, new String[] { JavaElementLabels.getElementLabel(fField, JavaElementLabels.ALL_FULLY_QUALIFIED), JavaElementLabels.getElementLabel(fField.getParent(), JavaElementLabels.ALL_FULLY_QUALIFIED)});
935                         final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(project, this, header);
936                         comment.addSetting(Messages.format(RefactoringCoreMessages.InlineConstantRefactoring_original_pattern, JavaElementLabels.getElementLabel(fField, JavaElementLabels.ALL_FULLY_QUALIFIED)));
937                         if (fRemoveDeclaration)
938                                 comment.addSetting(RefactoringCoreMessages.InlineConstantRefactoring_remove_declaration);
939                         if (fReplaceAllReferences)
940                                 comment.addSetting(RefactoringCoreMessages.InlineConstantRefactoring_replace_references);
941                         final InlineConstantDescriptor descriptor= RefactoringSignatureDescriptorFactory.createInlineConstantDescriptor(project, description, comment.asString(), arguments, flags);
942                         arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT, JavaRefactoringDescriptorUtil.elementToHandle(project, fSelectionCu));
943                         arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION, new Integer(fSelectionStart).toString() + " " + new Integer(fSelectionLength).toString()); //$NON-NLS-1$
944                         arguments.put(ATTRIBUTE_REMOVE, Boolean.valueOf(fRemoveDeclaration).toString());
945                         arguments.put(ATTRIBUTE_REPLACE, Boolean.valueOf(fReplaceAllReferences).toString());
946                         return new DynamicValidationRefactoringChange(descriptor, RefactoringCoreMessages.InlineConstantRefactoring_inline, fChanges);
947                 } finally {
948                         pm.done();
949                         fChanges= null;
950                 }
951         }
952
953         private void checkInvariant() {
954                 if (isDeclarationSelected())
955                         Assert.isTrue(fReplaceAllReferences);
956         }
957
958         public boolean getRemoveDeclaration() {
959                 return fRemoveDeclaration;
960         }
961
962         public boolean getReplaceAllReferences() {
963                 checkInvariant();
964                 return fReplaceAllReferences;
965         }
966
967         public boolean isDeclarationSelected() {
968                 Assert.isTrue(fDeclarationSelectedChecked);
969                 return fDeclarationSelected;
970         }
971
972         public boolean isInitializerAllStaticFinal() {
973                 Assert.isTrue(fInitializerChecked);
974                 return fInitializerAllStaticFinal;
975         }
976
977         public void setRemoveDeclaration(boolean removeDeclaration) {
978                 fRemoveDeclaration= removeDeclaration;
979         }
980
981         public void setReplaceAllReferences(boolean replaceAllReferences) {
982                 fReplaceAllReferences= replaceAllReferences;
983                 checkInvariant();
984         }
985
986         private RefactoringStatus initialize(JavaRefactoringArguments arguments) {
987                 final String selection= arguments.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION);
988                 if (selection != null) {
989                         int offset= -1;
990                         int length= -1;
991                         final StringTokenizer tokenizer= new StringTokenizer(selection);
992                         if (tokenizer.hasMoreTokens())
993                                 offset= Integer.valueOf(tokenizer.nextToken()).intValue();
994                         if (tokenizer.hasMoreTokens())
995                                 length= Integer.valueOf(tokenizer.nextToken()).intValue();
996                         if (offset >= 0 && length >= 0) {
997                                 fSelectionStart= offset;
998                                 fSelectionLength= length;
999                         } else
1000                                 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_illegal_argument, new Object[] { selection, JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION}));
1001                 }
1002                 final String handle= arguments.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT);
1003                 if (handle != null) {
1004                         final IJavaElement element= JavaRefactoringDescriptorUtil.handleToElement(arguments.getProject(), handle, false);
1005                         if (element == null || !element.exists())
1006                                 return JavaRefactoringDescriptorUtil.createInputFatalStatus(element, getName(), IJavaRefactorings.INLINE_CONSTANT);
1007                         else {
1008                                 if (element instanceof ICompilationUnit) {
1009                                         fSelectionCu= (ICompilationUnit) element;
1010                                         if (selection == null)
1011                                                 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION));
1012                                 } else if (element instanceof IField) {
1013                                         final IField field= (IField) element;
1014                                         try {
1015                                                 final ISourceRange range= field.getNameRange();
1016                                                 if (range != null) {
1017                                                         fSelectionStart= range.getOffset();
1018                                                         fSelectionLength= range.getLength();
1019                                                 } else
1020                                                         return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, IJavaRefactorings.INLINE_CONSTANT));
1021                                         } catch (JavaModelException exception) {
1022                                                 return JavaRefactoringDescriptorUtil.createInputFatalStatus(element, getName(), IJavaRefactorings.INLINE_CONSTANT);
1023                                         }
1024                                         fSelectionCu= field.getCompilationUnit();
1025                                 } else
1026                                         return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_illegal_argument, new Object[] { handle, JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT}));
1027                                 final ASTParser parser= ASTParser.newParser(ASTProvider.SHARED_AST_LEVEL);
1028                                 parser.setResolveBindings(true);
1029                                 parser.setSource(fSelectionCu);
1030                                 final CompilationUnit unit= (CompilationUnit) parser.createAST(null);
1031                                 initialize(fSelectionCu, unit);
1032                                 if (checkStaticFinalConstantNameSelected().hasFatalError())
1033                                         return JavaRefactoringDescriptorUtil.createInputFatalStatus(element, getName(), IJavaRefactorings.INLINE_CONSTANT);
1034                         }
1035                 } else
1036                         return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT));
1037                 final String replace= arguments.getAttribute(ATTRIBUTE_REPLACE);
1038                 if (replace != null) {
1039                         fReplaceAllReferences= Boolean.valueOf(replace).booleanValue();
1040                 } else
1041                         return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_REPLACE));
1042                 final String remove= arguments.getAttribute(ATTRIBUTE_REMOVE);
1043                 if (remove != null)
1044                         fRemoveDeclaration= Boolean.valueOf(remove).booleanValue();
1045                 else
1046                         return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_REMOVE));
1047                 return new RefactoringStatus();
1048         }
1049 }