1 11 package org.eclipse.jdt.internal.corext.refactoring.rename; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.List ; 16 17 import org.eclipse.text.edits.ReplaceEdit; 18 import org.eclipse.text.edits.TextEdit; 19 20 import org.eclipse.core.runtime.Assert; 21 import org.eclipse.core.runtime.CoreException; 22 import org.eclipse.core.runtime.IProgressMonitor; 23 import org.eclipse.core.runtime.NullProgressMonitor; 24 import org.eclipse.core.runtime.SubProgressMonitor; 25 26 import org.eclipse.core.resources.IFile; 27 28 import org.eclipse.ltk.core.refactoring.Change; 29 import org.eclipse.ltk.core.refactoring.GroupCategorySet; 30 import org.eclipse.ltk.core.refactoring.RefactoringDescriptor; 31 import org.eclipse.ltk.core.refactoring.RefactoringStatus; 32 import org.eclipse.ltk.core.refactoring.TextChange; 33 import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext; 34 import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments; 35 import org.eclipse.ltk.core.refactoring.participants.RenameArguments; 36 37 import org.eclipse.jdt.core.Flags; 38 import org.eclipse.jdt.core.ICompilationUnit; 39 import org.eclipse.jdt.core.IField; 40 import org.eclipse.jdt.core.IJavaElement; 41 import org.eclipse.jdt.core.IJavaProject; 42 import org.eclipse.jdt.core.IMethod; 43 import org.eclipse.jdt.core.ISourceRange; 44 import org.eclipse.jdt.core.IType; 45 import org.eclipse.jdt.core.ITypeHierarchy; 46 import org.eclipse.jdt.core.JavaModelException; 47 import org.eclipse.jdt.core.WorkingCopyOwner; 48 import org.eclipse.jdt.core.dom.FieldDeclaration; 49 import org.eclipse.jdt.core.dom.MethodDeclaration; 50 import org.eclipse.jdt.core.dom.VariableDeclarationFragment; 51 import org.eclipse.jdt.core.refactoring.IJavaRefactorings; 52 import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor; 53 import org.eclipse.jdt.core.refactoring.descriptors.RenameJavaElementDescriptor; 54 import org.eclipse.jdt.core.search.IJavaSearchConstants; 55 import org.eclipse.jdt.core.search.IJavaSearchScope; 56 import org.eclipse.jdt.core.search.SearchEngine; 57 import org.eclipse.jdt.core.search.SearchMatch; 58 import org.eclipse.jdt.core.search.SearchPattern; 59 60 import org.eclipse.jdt.internal.corext.codemanipulation.GetterSetterUtil; 61 import org.eclipse.jdt.internal.corext.refactoring.Checks; 62 import org.eclipse.jdt.internal.corext.refactoring.CollectingSearchRequestor; 63 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptor; 64 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment; 65 import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments; 66 import org.eclipse.jdt.internal.corext.refactoring.RefactoringAvailabilityTester; 67 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; 68 import org.eclipse.jdt.internal.corext.refactoring.RefactoringScopeFactory; 69 import org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine; 70 import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup; 71 import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext; 72 import org.eclipse.jdt.internal.corext.refactoring.changes.CompilationUnitChange; 73 import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange; 74 import org.eclipse.jdt.internal.corext.refactoring.changes.TextChangeCompatibility; 75 import org.eclipse.jdt.internal.corext.refactoring.code.ScriptableRefactoring; 76 import org.eclipse.jdt.internal.corext.refactoring.delegates.DelegateCreator; 77 import org.eclipse.jdt.internal.corext.refactoring.delegates.DelegateFieldCreator; 78 import org.eclipse.jdt.internal.corext.refactoring.delegates.DelegateMethodCreator; 79 import org.eclipse.jdt.internal.corext.refactoring.participants.JavaProcessors; 80 import org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil; 81 import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; 82 import org.eclipse.jdt.internal.corext.refactoring.tagging.IDelegateUpdating; 83 import org.eclipse.jdt.internal.corext.refactoring.tagging.IReferenceUpdating; 84 import org.eclipse.jdt.internal.corext.refactoring.tagging.ITextUpdating; 85 import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil; 86 import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil; 87 import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager; 88 import org.eclipse.jdt.internal.corext.util.JavaModelUtil; 89 import org.eclipse.jdt.internal.corext.util.JdtFlags; 90 import org.eclipse.jdt.internal.corext.util.Messages; 91 import org.eclipse.jdt.internal.corext.util.SearchUtils; 92 93 import org.eclipse.jdt.ui.JavaElementLabels; 94 95 import org.eclipse.jdt.internal.ui.JavaPlugin; 96 import org.eclipse.jdt.internal.ui.refactoring.RefactoringSaveHelper; 97 98 public class RenameFieldProcessor extends JavaRenameProcessor implements IReferenceUpdating, ITextUpdating, IDelegateUpdating { 99 100 protected static final String ATTRIBUTE_TEXTUAL_MATCHES= "textual"; private static final String ATTRIBUTE_RENAME_GETTER= "getter"; private static final String ATTRIBUTE_RENAME_SETTER= "setter"; private static final String ATTRIBUTE_DELEGATE= "delegate"; private static final String ATTRIBUTE_DEPRECATE= "deprecate"; 106 protected IField fField; 107 private SearchResultGroup[] fReferences; 108 private TextChangeManager fChangeManager; 109 protected boolean fUpdateReferences; 110 protected boolean fUpdateTextualMatches; 111 private boolean fRenameGetter; 112 private boolean fRenameSetter; 113 private boolean fIsComposite; 114 private GroupCategorySet fCategorySet; 115 private boolean fDelegateUpdating; 116 private boolean fDelegateDeprecation; 117 118 public static final String IDENTIFIER= "org.eclipse.jdt.ui.renameFieldProcessor"; 120 124 public RenameFieldProcessor(IField field) { 125 this(field, new TextChangeManager(true), null); 126 fIsComposite= false; 127 } 128 129 138 RenameFieldProcessor(IField field, TextChangeManager manager, GroupCategorySet categorySet) { 139 initialize(field); 140 fChangeManager= manager; 141 fCategorySet= categorySet; 142 fDelegateUpdating= false; 143 fDelegateDeprecation= true; 144 fIsComposite= true; 145 } 146 147 private void initialize(IField field) { 148 fField= field; 149 if (fField != null) 150 setNewElementName(fField.getElementName()); 151 fUpdateReferences= true; 152 fUpdateTextualMatches= false; 153 154 fRenameGetter= false; 155 fRenameSetter= false; 156 } 157 158 public String getIdentifier() { 159 return IDENTIFIER; 160 } 161 162 public boolean isApplicable() throws CoreException { 163 return RefactoringAvailabilityTester.isRenameFieldAvailable(fField); 164 } 165 166 public String getProcessorName() { 167 return RefactoringCoreMessages.RenameFieldRefactoring_name; 168 } 169 170 protected String [] getAffectedProjectNatures() throws CoreException { 171 return JavaProcessors.computeAffectedNatures(fField); 172 } 173 174 public IField getField() { 175 return fField; 176 } 177 178 public Object [] getElements() { 179 return new Object [] { fField}; 180 } 181 182 protected RenameModifications computeRenameModifications() throws CoreException { 183 RenameModifications result= new RenameModifications(); 184 result.rename(fField, new RenameArguments(getNewElementName(), getUpdateReferences())); 185 if (fRenameGetter) { 186 IMethod getter= getGetter(); 187 if (getter != null) { 188 result.rename(getter, new RenameArguments(getNewGetterName(), getUpdateReferences())); 189 } 190 } 191 if (fRenameSetter) { 192 IMethod setter= getSetter(); 193 if (setter != null) { 194 result.rename(setter, new RenameArguments(getNewSetterName(), getUpdateReferences())); 195 } 196 } 197 return result; 198 } 199 200 protected IFile[] getChangedFiles() { 201 return ResourceUtil.getFiles(fChangeManager.getAllCompilationUnits()); 202 } 203 204 206 public final String getCurrentElementName(){ 207 return fField.getElementName(); 208 } 209 210 public final String getCurrentElementQualifier(){ 211 return JavaModelUtil.getFullyQualifiedName(fField.getDeclaringType()); 212 } 213 214 public RefactoringStatus checkNewElementName(String newName) throws CoreException { 215 Assert.isNotNull(newName, "new name"); RefactoringStatus result= Checks.checkFieldName(newName); 217 218 if (isInstanceField(fField) && (!Checks.startsWithLowerCase(newName))) 219 result.addWarning(fIsComposite 220 ? Messages.format(RefactoringCoreMessages.RenameFieldRefactoring_should_start_lowercase2, new String [] { newName, fField.getDeclaringType().getElementName() }) 221 : RefactoringCoreMessages.RenameFieldRefactoring_should_start_lowercase); 222 223 if (Checks.isAlreadyNamed(fField, newName)) 224 result.addError(fIsComposite 225 ? Messages.format(RefactoringCoreMessages.RenameFieldRefactoring_another_name2, new String [] { newName, fField.getDeclaringType().getElementName() }) 226 : RefactoringCoreMessages.RenameFieldRefactoring_another_name, 227 JavaStatusContext.create(fField)); 228 229 if (fField.getDeclaringType().getField(newName).exists()) 230 result.addError(fIsComposite 231 ? Messages.format(RefactoringCoreMessages.RenameFieldRefactoring_field_already_defined2, new String [] { newName, fField.getDeclaringType().getElementName() }) 232 : RefactoringCoreMessages.RenameFieldRefactoring_field_already_defined, 233 JavaStatusContext.create(fField.getDeclaringType().getField(newName))); 234 return result; 235 } 236 237 public Object getNewElement() { 238 return fField.getDeclaringType().getField(getNewElementName()); 239 } 240 241 243 public boolean canEnableTextUpdating() { 244 return true; 245 } 246 247 public boolean getUpdateTextualMatches() { 248 return fUpdateTextualMatches; 249 } 250 251 public void setUpdateTextualMatches(boolean update) { 252 fUpdateTextualMatches= update; 253 } 254 255 257 public boolean canEnableUpdateReferences() { 258 return true; 259 } 260 261 public void setUpdateReferences(boolean update) { 262 fUpdateReferences= update; 263 } 264 265 public boolean getUpdateReferences(){ 266 return fUpdateReferences; 267 } 268 269 271 275 public String canEnableGetterRenaming() throws CoreException{ 276 if (fField.getDeclaringType().isInterface()) 277 return getGetter() == null ? "": null; 279 IMethod getter= getGetter(); 280 if (getter == null) 281 return ""; final NullProgressMonitor monitor= new NullProgressMonitor(); 283 if (MethodChecks.isVirtual(getter)) { 284 final ITypeHierarchy hierarchy= getter.getDeclaringType().newTypeHierarchy(monitor); 285 if (MethodChecks.isDeclaredInInterface(getter, hierarchy, monitor) != null || MethodChecks.overridesAnotherMethod(getter, hierarchy) != null) 286 return RefactoringCoreMessages.RenameFieldRefactoring_declared_in_supertype; 287 } 288 return null; 289 } 290 291 295 public String canEnableSetterRenaming() throws CoreException{ 296 if (fField.getDeclaringType().isInterface()) 297 return getSetter() == null ? "": null; 299 IMethod setter= getSetter(); 300 if (setter == null) 301 return ""; final NullProgressMonitor monitor= new NullProgressMonitor(); 303 if (MethodChecks.isVirtual(setter)) { 304 final ITypeHierarchy hierarchy= setter.getDeclaringType().newTypeHierarchy(monitor); 305 if (MethodChecks.isDeclaredInInterface(setter, hierarchy, monitor) != null || MethodChecks.overridesAnotherMethod(setter, hierarchy) != null) 306 return RefactoringCoreMessages.RenameFieldRefactoring_declared_in_supertype; 307 } 308 return null; 309 } 310 311 public boolean getRenameGetter() { 312 return fRenameGetter; 313 } 314 315 public void setRenameGetter(boolean renameGetter) { 316 fRenameGetter= renameGetter; 317 } 318 319 public boolean getRenameSetter() { 320 return fRenameSetter; 321 } 322 323 public void setRenameSetter(boolean renameSetter) { 324 fRenameSetter= renameSetter; 325 } 326 327 public IMethod getGetter() throws CoreException { 328 return GetterSetterUtil.getGetter(fField); 329 } 330 331 public IMethod getSetter() throws CoreException { 332 return GetterSetterUtil.getSetter(fField); 333 } 334 335 public String getNewGetterName() throws CoreException { 336 IMethod primaryGetterCandidate= JavaModelUtil.findMethod(GetterSetterUtil.getGetterName(fField, new String [0]), new String [0], false, fField.getDeclaringType()); 337 if (! JavaModelUtil.isBoolean(fField) || (primaryGetterCandidate != null && primaryGetterCandidate.exists())) 338 return GetterSetterUtil.getGetterName(fField.getJavaProject(), getNewElementName(), fField.getFlags(), JavaModelUtil.isBoolean(fField), null); 339 return GetterSetterUtil.getGetterName(fField.getJavaProject(), getNewElementName(), fField.getFlags(), false, null); 341 } 342 343 public String getNewSetterName() throws CoreException { 344 return GetterSetterUtil.getSetterName(fField.getJavaProject(), getNewElementName(), fField.getFlags(), JavaModelUtil.isBoolean(fField), null); 345 } 346 347 349 public boolean canEnableDelegateUpdating() { 350 return (getDelegateCount() > 0); 351 } 352 353 public boolean getDelegateUpdating() { 354 return fDelegateUpdating; 355 } 356 357 public void setDelegateUpdating(boolean update) { 358 fDelegateUpdating= update; 359 } 360 361 public void setDeprecateDelegates(boolean deprecate) { 362 fDelegateDeprecation= deprecate; 363 } 364 365 public boolean getDeprecateDelegates() { 366 return fDelegateDeprecation; 367 } 368 369 375 public int getDelegateCount() { 376 int count= 0; 377 try { 378 if (RefactoringAvailabilityTester.isDelegateCreationAvailable(getField())) 379 count++; 380 if (fRenameGetter && getGetter() != null) 381 count++; 382 if (fRenameSetter && getSetter() != null) 383 count++; 384 } catch (CoreException e) { 385 } 387 return count; 388 } 389 390 public int getSaveMode() { 391 return RefactoringSaveHelper.SAVE_NON_JAVA_UPDATES; 392 } 393 394 public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException { 395 IField primary= (IField) fField.getPrimaryElement(); 396 if (primary == null || !primary.exists()) { 397 String message= Messages.format(RefactoringCoreMessages.RenameFieldRefactoring_deleted, fField.getCompilationUnit().getElementName()); 398 return RefactoringStatus.createFatalErrorStatus(message); 399 } 400 fField= primary; 401 402 return Checks.checkIfCuBroken(fField); 403 } 404 405 protected RefactoringStatus doCheckFinalConditions(IProgressMonitor pm, CheckConditionsContext context) throws CoreException { 406 try{ 407 pm.beginTask("", 18); pm.setTaskName(RefactoringCoreMessages.RenameFieldRefactoring_checking); 409 RefactoringStatus result= new RefactoringStatus(); 410 result.merge(Checks.checkIfCuBroken(fField)); 411 if (result.hasFatalError()) 412 return result; 413 result.merge(checkNewElementName(getNewElementName())); 414 pm.worked(1); 415 result.merge(checkEnclosingHierarchy()); 416 pm.worked(1); 417 result.merge(checkNestedHierarchy(fField.getDeclaringType())); 418 pm.worked(1); 419 420 if (fUpdateReferences){ 421 pm.setTaskName(RefactoringCoreMessages.RenameFieldRefactoring_searching); 422 fReferences= getReferences(new SubProgressMonitor(pm, 3), result); 423 pm.setTaskName(RefactoringCoreMessages.RenameFieldRefactoring_checking); 424 } else { 425 fReferences= new SearchResultGroup[0]; 426 pm.worked(3); 427 } 428 429 if (fUpdateReferences) 430 result.merge(analyzeAffectedCompilationUnits()); 431 else 432 Checks.checkCompileErrorsInAffectedFile(result, fField.getResource()); 433 434 if (getGetter() != null && fRenameGetter){ 435 result.merge(checkAccessor(new SubProgressMonitor(pm, 1), getGetter(), getNewGetterName())); 436 result.merge(Checks.checkIfConstructorName(getGetter(), getNewGetterName(), fField.getDeclaringType().getElementName())); 437 } else { 438 pm.worked(1); 439 } 440 441 if (getSetter() != null && fRenameSetter){ 442 result.merge(checkAccessor(new SubProgressMonitor(pm, 1), getSetter(), getNewSetterName())); 443 result.merge(Checks.checkIfConstructorName(getSetter(), getNewSetterName(), fField.getDeclaringType().getElementName())); 444 } else { 445 pm.worked(1); 446 } 447 448 result.merge(createChanges(new SubProgressMonitor(pm, 10))); 449 if (result.hasFatalError()) 450 return result; 451 452 return result; 453 } finally{ 454 pm.done(); 455 } 456 } 457 458 private RefactoringStatus checkAccessor(IProgressMonitor pm, IMethod existingAccessor, String newAccessorName) throws CoreException{ 460 RefactoringStatus result= new RefactoringStatus(); 461 result.merge(checkAccessorDeclarations(pm, existingAccessor)); 462 result.merge(checkNewAccessor(existingAccessor, newAccessorName)); 463 return result; 464 } 465 466 private RefactoringStatus checkNewAccessor(IMethod existingAccessor, String newAccessorName) throws CoreException{ 467 RefactoringStatus result= new RefactoringStatus(); 468 IMethod accessor= JavaModelUtil.findMethod(newAccessorName, existingAccessor.getParameterTypes(), false, fField.getDeclaringType()); 469 if (accessor == null || !accessor.exists()) 470 return null; 471 472 String message= Messages.format(RefactoringCoreMessages.RenameFieldRefactoring_already_exists, 473 new String []{JavaElementUtil.createMethodSignature(accessor), JavaModelUtil.getFullyQualifiedName(fField.getDeclaringType())}); 474 result.addError(message, JavaStatusContext.create(accessor)); 475 return result; 476 } 477 478 private RefactoringStatus checkAccessorDeclarations(IProgressMonitor pm, IMethod existingAccessor) throws CoreException{ 479 RefactoringStatus result= new RefactoringStatus(); 480 SearchPattern pattern= SearchPattern.createPattern(existingAccessor, IJavaSearchConstants.DECLARATIONS, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE); 481 IJavaSearchScope scope= SearchEngine.createHierarchyScope(fField.getDeclaringType()); 482 SearchResultGroup[] groupDeclarations= RefactoringSearchEngine.search(pattern, scope, pm, result); 483 Assert.isTrue(groupDeclarations.length > 0); 484 if (groupDeclarations.length != 1){ 485 String message= Messages.format(RefactoringCoreMessages.RenameFieldRefactoring_overridden, 486 JavaElementUtil.createMethodSignature(existingAccessor)); 487 result.addError(message); 488 } else { 489 SearchResultGroup group= groupDeclarations[0]; 490 Assert.isTrue(group.getSearchResults().length > 0); 491 if (group.getSearchResults().length != 1){ 492 String message= Messages.format(RefactoringCoreMessages.RenameFieldRefactoring_overridden_or_overrides, 493 JavaElementUtil.createMethodSignature(existingAccessor)); 494 result.addError(message); 495 } 496 } 497 return result; 498 } 499 500 private static boolean isInstanceField(IField field) throws CoreException{ 501 if (JavaModelUtil.isInterfaceOrAnnotation(field.getDeclaringType())) 502 return false; 503 else 504 return ! JdtFlags.isStatic(field); 505 } 506 507 private RefactoringStatus checkNestedHierarchy(IType type) throws CoreException { 508 IType[] nestedTypes= type.getTypes(); 509 if (nestedTypes == null) 510 return null; 511 RefactoringStatus result= new RefactoringStatus(); 512 for (int i= 0; i < nestedTypes.length; i++){ 513 IField otherField= nestedTypes[i].getField(getNewElementName()); 514 if (otherField.exists()){ 515 String msg= Messages.format( 516 RefactoringCoreMessages.RenameFieldRefactoring_hiding, 517 new String []{fField.getElementName(), getNewElementName(), JavaModelUtil.getFullyQualifiedName(nestedTypes[i])}); 518 result.addWarning(msg, JavaStatusContext.create(otherField)); 519 } 520 result.merge(checkNestedHierarchy(nestedTypes[i])); 521 } 522 return result; 523 } 524 525 private RefactoringStatus checkEnclosingHierarchy() { 526 IType current= fField.getDeclaringType(); 527 if (Checks.isTopLevel(current)) 528 return null; 529 RefactoringStatus result= new RefactoringStatus(); 530 while (current != null){ 531 IField otherField= current.getField(getNewElementName()); 532 if (otherField.exists()){ 533 String msg= Messages.format(RefactoringCoreMessages.RenameFieldRefactoring_hiding2, 534 new String []{getNewElementName(), JavaModelUtil.getFullyQualifiedName(current), otherField.getElementName()}); 535 result.addWarning(msg, JavaStatusContext.create(otherField)); 536 } 537 current= current.getDeclaringType(); 538 } 539 return result; 540 } 541 542 546 private RefactoringStatus analyzeAffectedCompilationUnits() throws CoreException{ 547 RefactoringStatus result= new RefactoringStatus(); 548 fReferences= Checks.excludeCompilationUnits(fReferences, result); 549 if (result.hasFatalError()) 550 return result; 551 552 result.merge(Checks.checkCompileErrorsInAffectedFiles(fReferences)); 553 return result; 554 } 555 556 private SearchPattern createSearchPattern(){ 557 return SearchPattern.createPattern(fField, IJavaSearchConstants.REFERENCES); 558 } 559 560 private IJavaSearchScope createRefactoringScope() throws CoreException{ 561 return RefactoringScopeFactory.create(fField); 562 } 563 564 private SearchResultGroup[] getReferences(IProgressMonitor pm, RefactoringStatus status) throws CoreException{ 565 return RefactoringSearchEngine.search(createSearchPattern(), createRefactoringScope(), pm, status); 566 } 567 568 public Change createChange(IProgressMonitor monitor) throws CoreException { 569 try { 570 monitor.beginTask(RefactoringCoreMessages.RenameFieldRefactoring_checking, 1); 571 final TextChange[] changes= fChangeManager.getAllChanges(); 572 final List list= new ArrayList (changes.length); 573 list.addAll(Arrays.asList(changes)); 574 String project= null; 575 IJavaProject javaProject= fField.getJavaProject(); 576 if (javaProject != null) 577 project= javaProject.getElementName(); 578 int flags= JavaRefactoringDescriptor.JAR_MIGRATION | JavaRefactoringDescriptor.JAR_REFACTORING | RefactoringDescriptor.STRUCTURAL_CHANGE; 579 try { 580 if (!Flags.isPrivate(fField.getFlags())) 581 flags|= RefactoringDescriptor.MULTI_CHANGE; 582 } catch (JavaModelException exception) { 583 JavaPlugin.log(exception); 584 } 585 final IType declaring= fField.getDeclaringType(); 586 try { 587 if (declaring.isAnonymous() || declaring.isLocal()) 588 flags|= JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT; 589 } catch (JavaModelException exception) { 590 JavaPlugin.log(exception); 591 } 592 final String description= Messages.format(RefactoringCoreMessages.RenameFieldRefactoring_descriptor_description_short, fField.getElementName()); 593 final String header= Messages.format(RefactoringCoreMessages.RenameFieldProcessor_descriptor_description, new String [] { fField.getElementName(), JavaElementLabels.getElementLabel(fField.getParent(), JavaElementLabels.ALL_FULLY_QUALIFIED), getNewElementName()}); 594 final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(project, this, header); 595 if (fRenameGetter) 596 comment.addSetting(RefactoringCoreMessages.RenameFieldRefactoring_setting_rename_getter); 597 if (fRenameSetter) 598 comment.addSetting(RefactoringCoreMessages.RenameFieldRefactoring_setting_rename_settter); 599 final RenameJavaElementDescriptor descriptor= new RenameJavaElementDescriptor(IJavaRefactorings.RENAME_FIELD); 600 descriptor.setProject(project); 601 descriptor.setDescription(description); 602 descriptor.setComment(comment.asString()); 603 descriptor.setFlags(flags); 604 descriptor.setJavaElement(fField); 605 descriptor.setNewName(getNewElementName()); 606 descriptor.setUpdateReferences(fUpdateReferences); 607 descriptor.setUpdateTextualOccurrences(fUpdateTextualMatches); 608 descriptor.setRenameGetters(fRenameGetter); 609 descriptor.setRenameSetters(fRenameSetter); 610 descriptor.setKeepOriginal(fDelegateUpdating); 611 descriptor.setDeprecateDelegate(fDelegateDeprecation); 612 return new DynamicValidationRefactoringChange(descriptor, RefactoringCoreMessages.RenameFieldRefactoring_change_name, (Change[]) list.toArray(new Change[list.size()])); 613 } finally { 614 monitor.done(); 615 } 616 } 617 618 private RefactoringStatus createChanges(IProgressMonitor pm) throws CoreException { 619 pm.beginTask(RefactoringCoreMessages.RenameFieldRefactoring_checking, 10); 620 RefactoringStatus result= new RefactoringStatus(); 621 if (!fIsComposite) 622 fChangeManager.clear(); 623 624 if (fDelegateUpdating) 627 result.merge(addDelegates()); 628 629 addDeclarationUpdate(); 630 631 if (fUpdateReferences) { 632 addReferenceUpdates(new SubProgressMonitor(pm, 1)); 633 result.merge(analyzeRenameChanges(new SubProgressMonitor(pm, 2))); 634 if (result.hasFatalError()) 635 return result; 636 } else { 637 pm.worked(3); 638 } 639 640 if (getGetter() != null && fRenameGetter) { 641 addGetterOccurrences(new SubProgressMonitor(pm, 1), result); 642 } else { 643 pm.worked(1); 644 } 645 646 if (getSetter() != null && fRenameSetter) { 647 addSetterOccurrences(new SubProgressMonitor(pm, 1), result); 648 } else { 649 pm.worked(1); 650 } 651 652 if (fUpdateTextualMatches) { 653 addTextMatches(new SubProgressMonitor(pm, 5)); 654 } else { 655 pm.worked(5); 656 } 657 pm.done(); 658 return result; 659 } 660 661 private void addDeclarationUpdate() throws CoreException { 662 ISourceRange nameRange= fField.getNameRange(); 663 TextEdit textEdit= new ReplaceEdit(nameRange.getOffset(), nameRange.getLength(), getNewElementName()); 664 ICompilationUnit cu= fField.getCompilationUnit(); 665 String groupName= RefactoringCoreMessages.RenameFieldRefactoring_Update_field_declaration; 666 addTextEdit(fChangeManager.get(cu), groupName, textEdit); 667 } 668 669 private RefactoringStatus addDelegates() throws JavaModelException, CoreException { 670 671 RefactoringStatus status= new RefactoringStatus(); 672 CompilationUnitRewrite rewrite= new CompilationUnitRewrite(fField.getCompilationUnit()); 673 rewrite.setResolveBindings(true); 674 675 if (RefactoringAvailabilityTester.isDelegateCreationAvailable(fField)) { 677 FieldDeclaration fieldDeclaration= ASTNodeSearchUtil.getFieldDeclarationNode(fField, rewrite.getRoot()); 678 if (fieldDeclaration.fragments().size() > 1) { 679 status.addWarning(Messages.format(RefactoringCoreMessages.DelegateCreator_cannot_create_field_delegate_more_than_one_fragment, fField 680 .getElementName()), JavaStatusContext.create(fField)); 681 } else if (((VariableDeclarationFragment) fieldDeclaration.fragments().get(0)).getInitializer() == null) { 682 status.addWarning(Messages.format(RefactoringCoreMessages.DelegateCreator_cannot_create_field_delegate_no_initializer, fField 683 .getElementName()), JavaStatusContext.create(fField)); 684 } else { 685 DelegateFieldCreator creator= new DelegateFieldCreator(); 686 creator.setDeclareDeprecated(fDelegateDeprecation); 687 creator.setDeclaration(fieldDeclaration); 688 creator.setNewElementName(getNewElementName()); 689 creator.setSourceRewrite(rewrite); 690 creator.prepareDelegate(); 691 creator.createEdit(); 692 } 693 } 694 695 if (getGetter() != null && fRenameGetter) 698 addMethodDelegate(getGetter(), getNewGetterName(), rewrite); 699 if (getSetter() != null && fRenameSetter) 700 addMethodDelegate(getSetter(), getNewSetterName(), rewrite); 701 702 final CompilationUnitChange change= rewrite.createChange(); 703 if (change != null) { 704 change.setKeepPreviewEdits(true); 705 fChangeManager.manage(fField.getCompilationUnit(), change); 706 } 707 708 return status; 709 } 710 711 private void addMethodDelegate(IMethod getter, String newName, CompilationUnitRewrite rewrite) throws JavaModelException { 712 MethodDeclaration declaration= ASTNodeSearchUtil.getMethodDeclarationNode(getter, rewrite.getRoot()); 713 DelegateCreator creator= new DelegateMethodCreator(); 714 creator.setDeclareDeprecated(fDelegateDeprecation); 715 creator.setDeclaration(declaration); 716 creator.setNewElementName(newName); 717 creator.setSourceRewrite(rewrite); 718 creator.prepareDelegate(); 719 creator.createEdit(); 720 } 721 722 private void addTextEdit(TextChange change, String groupName, TextEdit textEdit) { 723 if (fIsComposite) 724 TextChangeCompatibility.addTextEdit(change, groupName, textEdit, fCategorySet); 725 else 726 TextChangeCompatibility.addTextEdit(change, groupName, textEdit); 727 728 } 729 730 private void addReferenceUpdates(IProgressMonitor pm) { 731 pm.beginTask("", fReferences.length); String editName= RefactoringCoreMessages.RenameFieldRefactoring_Update_field_reference; 733 for (int i= 0; i < fReferences.length; i++){ 734 ICompilationUnit cu= fReferences[i].getCompilationUnit(); 735 if (cu == null) 736 continue; 737 SearchMatch[] results= fReferences[i].getSearchResults(); 738 for (int j= 0; j < results.length; j++){ 739 addTextEdit(fChangeManager.get(cu), editName, createTextChange(results[j])); 740 } 741 pm.worked(1); 742 } 743 } 744 745 private TextEdit createTextChange(SearchMatch match) { 746 return new ReplaceEdit(match.getOffset(), match.getLength(), getNewElementName()); 747 } 748 749 private void addGetterOccurrences(IProgressMonitor pm, RefactoringStatus status) throws CoreException { 750 addAccessorOccurrences(pm, getGetter(), RefactoringCoreMessages.RenameFieldRefactoring_Update_getter_occurrence, getNewGetterName(), status); 751 } 752 753 private void addSetterOccurrences(IProgressMonitor pm, RefactoringStatus status) throws CoreException { 754 addAccessorOccurrences(pm, getSetter(), RefactoringCoreMessages.RenameFieldRefactoring_Update_setter_occurrence, getNewSetterName(), status); 755 } 756 757 private void addAccessorOccurrences(IProgressMonitor pm, IMethod accessor, String editName, String newAccessorName, RefactoringStatus status) throws CoreException { 758 Assert.isTrue(accessor.exists()); 759 760 IJavaSearchScope scope= RefactoringScopeFactory.create(accessor); 761 SearchPattern pattern= SearchPattern.createPattern(accessor, IJavaSearchConstants.ALL_OCCURRENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE); 762 SearchResultGroup[] groupedResults= RefactoringSearchEngine.search( 763 pattern, scope, new MethodOccurenceCollector(accessor.getElementName()), pm, status); 764 765 for (int i= 0; i < groupedResults.length; i++) { 766 ICompilationUnit cu= groupedResults[i].getCompilationUnit(); 767 if (cu == null) 768 continue; 769 SearchMatch[] results= groupedResults[i].getSearchResults(); 770 for (int j= 0; j < results.length; j++){ 771 SearchMatch searchResult= results[j]; 772 TextEdit edit= new ReplaceEdit(searchResult.getOffset(), searchResult.getLength(), newAccessorName); 773 addTextEdit(fChangeManager.get(cu), editName, edit); 774 } 775 } 776 } 777 778 private void addTextMatches(IProgressMonitor pm) throws CoreException { 779 TextMatchUpdater.perform(pm, createRefactoringScope(), this, fChangeManager, fReferences); 780 } 781 782 private RefactoringStatus analyzeRenameChanges(IProgressMonitor pm) throws CoreException { 784 ICompilationUnit[] newWorkingCopies= null; 785 WorkingCopyOwner newWCOwner= new WorkingCopyOwner() { }; 786 try { 787 pm.beginTask("", 2); RefactoringStatus result= new RefactoringStatus(); 789 SearchResultGroup[] oldReferences= fReferences; 790 791 List compilationUnitsToModify= new ArrayList (); 792 if (fIsComposite) { 793 for (int i= 0; i < oldReferences.length; i++) 795 compilationUnitsToModify.add(oldReferences[i].getCompilationUnit()); 796 compilationUnitsToModify.add(fField.getCompilationUnit()); 797 } else { 798 compilationUnitsToModify.addAll(Arrays.asList(fChangeManager.getAllCompilationUnits())); 800 } 801 802 newWorkingCopies= RenameAnalyzeUtil.createNewWorkingCopies((ICompilationUnit[]) compilationUnitsToModify.toArray(new ICompilationUnit[compilationUnitsToModify.size()]), 803 fChangeManager, newWCOwner, new SubProgressMonitor(pm, 1)); 804 805 SearchResultGroup[] newReferences= getNewReferences(new SubProgressMonitor(pm, 1), result, newWCOwner, newWorkingCopies); 806 result.merge(RenameAnalyzeUtil.analyzeRenameChanges2(fChangeManager, oldReferences, newReferences, getNewElementName())); 807 return result; 808 } finally{ 809 pm.done(); 810 if (newWorkingCopies != null){ 811 for (int i= 0; i < newWorkingCopies.length; i++) { 812 newWorkingCopies[i].discardWorkingCopy(); 813 } 814 } 815 } 816 } 817 818 private SearchResultGroup[] getNewReferences(IProgressMonitor pm, RefactoringStatus status, WorkingCopyOwner owner, ICompilationUnit[] newWorkingCopies) throws CoreException { 819 pm.beginTask("", 2); ICompilationUnit declaringCuWorkingCopy= RenameAnalyzeUtil.findWorkingCopyForCu(newWorkingCopies, fField.getCompilationUnit()); 821 if (declaringCuWorkingCopy == null) 822 return new SearchResultGroup[0]; 823 824 IField field= getFieldInWorkingCopy(declaringCuWorkingCopy, getNewElementName()); 825 if (field == null || ! field.exists()) 826 return new SearchResultGroup[0]; 827 828 CollectingSearchRequestor requestor= null; 829 if (fDelegateUpdating && RefactoringAvailabilityTester.isDelegateCreationAvailable(getField())) { 830 final IField oldField= getFieldInWorkingCopy(declaringCuWorkingCopy, getCurrentElementName()); 833 requestor= new CollectingSearchRequestor() { 834 public void acceptSearchMatch(SearchMatch match) throws CoreException { 835 if (!oldField.equals(match.getElement())) 836 super.acceptSearchMatch(match); 837 } 838 }; 839 } else 840 requestor= new CollectingSearchRequestor(); 841 842 SearchPattern newPattern= SearchPattern.createPattern(field, IJavaSearchConstants.REFERENCES); 843 return RefactoringSearchEngine.search(newPattern, owner, createRefactoringScope(), requestor, new SubProgressMonitor(pm, 1), status); 844 } 845 846 private IField getFieldInWorkingCopy(ICompilationUnit newWorkingCopyOfDeclaringCu, String elementName) throws CoreException{ 847 IType type= fField.getDeclaringType(); 848 IType typeWc= (IType) JavaModelUtil.findInCompilationUnit(newWorkingCopyOfDeclaringCu, type); 849 if (typeWc == null) 850 return null; 851 852 return typeWc.getField(elementName); 853 } 854 855 public RefactoringStatus initialize(RefactoringArguments arguments) { 856 if (arguments instanceof JavaRefactoringArguments) { 857 final JavaRefactoringArguments extended= (JavaRefactoringArguments) arguments; 858 final String handle= extended.getAttribute(JDTRefactoringDescriptor.ATTRIBUTE_INPUT); 859 if (handle != null) { 860 final IJavaElement element= JDTRefactoringDescriptor.handleToElement(extended.getProject(), handle, false); 861 if (element == null || !element.exists() || element.getElementType() != IJavaElement.FIELD) 862 return ScriptableRefactoring.createInputFatalStatus(element, getRefactoring().getName(), IJavaRefactorings.RENAME_FIELD); 863 else 864 fField= (IField) element; 865 } else 866 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JDTRefactoringDescriptor.ATTRIBUTE_INPUT)); 867 final String name= extended.getAttribute(JDTRefactoringDescriptor.ATTRIBUTE_NAME); 868 if (name != null && !"".equals(name)) setNewElementName(name); 870 else 871 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JDTRefactoringDescriptor.ATTRIBUTE_NAME)); 872 final String references= extended.getAttribute(JDTRefactoringDescriptor.ATTRIBUTE_REFERENCES); 873 if (references != null) { 874 fUpdateReferences= Boolean.valueOf(references).booleanValue(); 875 } else 876 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JDTRefactoringDescriptor.ATTRIBUTE_REFERENCES)); 877 final String matches= extended.getAttribute(ATTRIBUTE_TEXTUAL_MATCHES); 878 if (matches != null) { 879 fUpdateTextualMatches= Boolean.valueOf(matches).booleanValue(); 880 } else 881 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_TEXTUAL_MATCHES)); 882 final String getters= extended.getAttribute(ATTRIBUTE_RENAME_GETTER); 883 if (getters != null) 884 fRenameGetter= Boolean.valueOf(getters).booleanValue(); 885 else 886 fRenameGetter= false; 887 final String setters= extended.getAttribute(ATTRIBUTE_RENAME_SETTER); 888 if (setters != null) 889 fRenameSetter= Boolean.valueOf(setters).booleanValue(); 890 else 891 fRenameSetter= false; 892 final String delegate= extended.getAttribute(ATTRIBUTE_DELEGATE); 893 if (delegate != null) { 894 fDelegateUpdating= Boolean.valueOf(delegate).booleanValue(); 895 } else 896 fDelegateUpdating= false; 897 final String deprecate= extended.getAttribute(ATTRIBUTE_DEPRECATE); 898 if (deprecate != null) { 899 fDelegateDeprecation= Boolean.valueOf(deprecate).booleanValue(); 900 } else 901 fDelegateDeprecation= false; 902 } else 903 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.InitializableRefactoring_inacceptable_arguments); 904 return new RefactoringStatus(); 905 } 906 907 910 public String getDelegateUpdatingTitle(boolean plural) { 911 if (plural) 912 return RefactoringCoreMessages.DelegateFieldCreator_keep_original_renamed_plural; 913 else 914 return RefactoringCoreMessages.DelegateFieldCreator_keep_original_renamed_singular; 915 } 916 } 917 | Popular Tags |