1 11 package org.eclipse.jdt.internal.corext.refactoring.structure; 12 13 import java.util.HashMap ; 14 import java.util.Iterator ; 15 import java.util.Map ; 16 17 import org.eclipse.core.runtime.Assert; 18 import org.eclipse.core.runtime.IProgressMonitor; 19 import org.eclipse.core.runtime.OperationCanceledException; 20 import org.eclipse.core.runtime.SubProgressMonitor; 21 22 import org.eclipse.ltk.core.refactoring.CategorizedTextEditGroup; 23 import org.eclipse.ltk.core.refactoring.GroupCategory; 24 import org.eclipse.ltk.core.refactoring.GroupCategorySet; 25 import org.eclipse.ltk.core.refactoring.RefactoringStatus; 26 import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry; 27 28 import org.eclipse.jdt.core.Flags; 29 import org.eclipse.jdt.core.ICompilationUnit; 30 import org.eclipse.jdt.core.IField; 31 import org.eclipse.jdt.core.IInitializer; 32 import org.eclipse.jdt.core.IJavaElement; 33 import org.eclipse.jdt.core.IMember; 34 import org.eclipse.jdt.core.IMethod; 35 import org.eclipse.jdt.core.IPackageFragment; 36 import org.eclipse.jdt.core.IType; 37 import org.eclipse.jdt.core.ITypeHierarchy; 38 import org.eclipse.jdt.core.JavaCore; 39 import org.eclipse.jdt.core.JavaModelException; 40 import org.eclipse.jdt.core.WorkingCopyOwner; 41 import org.eclipse.jdt.core.dom.ASTNode; 42 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; 43 import org.eclipse.jdt.core.dom.BodyDeclaration; 44 import org.eclipse.jdt.core.dom.CompilationUnit; 45 import org.eclipse.jdt.core.dom.FieldDeclaration; 46 import org.eclipse.jdt.core.dom.IExtendedModifier; 47 import org.eclipse.jdt.core.dom.Modifier; 48 import org.eclipse.jdt.core.dom.SimpleName; 49 import org.eclipse.jdt.core.dom.Type; 50 import org.eclipse.jdt.core.dom.VariableDeclarationFragment; 51 import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword; 52 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; 53 import org.eclipse.jdt.core.dom.rewrite.ListRewrite; 54 import org.eclipse.jdt.core.search.IJavaSearchConstants; 55 import org.eclipse.jdt.core.search.IJavaSearchScope; 56 import org.eclipse.jdt.core.search.SearchMatch; 57 import org.eclipse.jdt.core.search.SearchPattern; 58 59 import org.eclipse.jdt.internal.corext.dom.ModifierRewrite; 60 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; 61 import org.eclipse.jdt.internal.corext.refactoring.RefactoringScopeFactory; 62 import org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine2; 63 import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup; 64 import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext; 65 import org.eclipse.jdt.internal.corext.util.JavaModelUtil; 66 import org.eclipse.jdt.internal.corext.util.Messages; 67 import org.eclipse.jdt.internal.corext.util.SearchUtils; 68 69 import org.eclipse.jdt.ui.JavaElementLabels; 70 71 76 public final class MemberVisibilityAdjustor { 77 78 83 public static final GroupCategorySet SET_VISIBILITY_ADJUSTMENTS= new GroupCategorySet(new GroupCategory("org.eclipse.jdt.internal.corext.visibilityAdjustments", RefactoringCoreMessages.MemberVisibilityAdjustor_adjustments_name, RefactoringCoreMessages.MemberVisibilityAdjustor_adjustments_description)); 85 86 87 public static class IncomingMemberVisibilityAdjustment implements IVisibilityAdjustment { 88 89 90 protected final ModifierKeyword fKeyword; 91 92 93 protected final IMember fMember; 94 95 96 protected boolean fNeedsRewriting= true; 97 98 99 protected final RefactoringStatus fRefactoringStatus; 100 101 108 public IncomingMemberVisibilityAdjustment(final IMember member, final ModifierKeyword keyword, final RefactoringStatus status) { 109 Assert.isNotNull(member); 110 Assert.isTrue(!(member instanceof IInitializer)); 111 Assert.isTrue(isVisibilityKeyword(keyword)); 112 fMember= member; 113 fKeyword= keyword; 114 fRefactoringStatus= status; 115 } 116 117 122 public final ModifierKeyword getKeyword() { 123 return fKeyword; 124 } 125 126 131 public final IMember getMember() { 132 return fMember; 133 } 134 135 140 public final RefactoringStatus getStatus() { 141 return fRefactoringStatus; 142 } 143 144 149 public final boolean needsRewriting() { 150 return fNeedsRewriting; 151 } 152 153 163 protected final void rewriteVisibility(final MemberVisibilityAdjustor adjustor, final ASTRewrite rewrite, final CompilationUnit root, final CategorizedTextEditGroup group, final RefactoringStatus status) throws JavaModelException { 164 Assert.isNotNull(adjustor); 165 Assert.isNotNull(rewrite); 166 Assert.isNotNull(root); 167 final int visibility= fKeyword != null ? fKeyword.toFlagValue() : Modifier.NONE; 168 if (fMember instanceof IField && !Flags.isEnum(fMember.getFlags())) { 169 final VariableDeclarationFragment fragment= ASTNodeSearchUtil.getFieldDeclarationFragmentNode((IField) fMember, root); 170 final FieldDeclaration declaration= (FieldDeclaration) fragment.getParent(); 171 if (declaration.fragments().size() == 1) 172 ModifierRewrite.create(rewrite, declaration).setVisibility(visibility, group); 173 else { 174 final VariableDeclarationFragment newFragment= rewrite.getAST().newVariableDeclarationFragment(); 175 newFragment.setName((SimpleName) rewrite.createCopyTarget(fragment.getName())); 176 final FieldDeclaration newDeclaration= rewrite.getAST().newFieldDeclaration(newFragment); 177 newDeclaration.setType((Type) rewrite.createCopyTarget(declaration.getType())); 178 IExtendedModifier extended= null; 179 for (final Iterator iterator= declaration.modifiers().iterator(); iterator.hasNext();) { 180 extended= (IExtendedModifier) iterator.next(); 181 if (extended.isModifier()) { 182 final Modifier modifier= (Modifier) extended; 183 final int flag= modifier.getKeyword().toFlagValue(); 184 if ((flag & (Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE)) != 0) 185 continue; 186 } 187 newDeclaration.modifiers().add(rewrite.createCopyTarget((ASTNode) extended)); 188 } 189 ModifierRewrite.create(rewrite, newDeclaration).setVisibility(visibility, group); 190 final AbstractTypeDeclaration type= (AbstractTypeDeclaration) declaration.getParent(); 191 rewrite.getListRewrite(type, type.getBodyDeclarationsProperty()).insertAfter(newDeclaration, declaration, null); 192 final ListRewrite list= rewrite.getListRewrite(declaration, FieldDeclaration.FRAGMENTS_PROPERTY); 193 list.remove(fragment, group); 194 if (list.getRewrittenList().isEmpty()) 195 rewrite.remove(declaration, null); 196 } 197 if (status != null) 198 adjustor.fStatus.merge(status); 199 } else if (fMember != null) { 200 final BodyDeclaration declaration= ASTNodeSearchUtil.getBodyDeclarationNode(fMember, root); 201 if (declaration != null) { 202 ModifierRewrite.create(rewrite, declaration).setVisibility(visibility, group); 203 if (status != null) 204 adjustor.fStatus.merge(status); 205 } 206 } 207 } 208 209 212 public void rewriteVisibility(final MemberVisibilityAdjustor adjustor, final IProgressMonitor monitor) throws JavaModelException { 213 Assert.isNotNull(adjustor); 214 Assert.isNotNull(monitor); 215 try { 216 monitor.beginTask("", 1); monitor.setTaskName(RefactoringCoreMessages.MemberVisibilityAdjustor_adjusting); 218 if (fNeedsRewriting) { 219 if (adjustor.fRewrite != null && adjustor.fRoot != null) 220 rewriteVisibility(adjustor, adjustor.fRewrite, adjustor.fRoot, null, fRefactoringStatus); 221 else { 222 final CompilationUnitRewrite rewrite= adjustor.getCompilationUnitRewrite(fMember.getCompilationUnit()); 223 rewriteVisibility(adjustor, rewrite.getASTRewrite(), rewrite.getRoot(), rewrite.createCategorizedGroupDescription(Messages.format(RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility, getLabel(getKeyword())), SET_VISIBILITY_ADJUSTMENTS), fRefactoringStatus); 224 } 225 } else if (fRefactoringStatus != null) 226 adjustor.fStatus.merge(fRefactoringStatus); 227 monitor.worked(1); 228 } finally { 229 monitor.done(); 230 } 231 } 232 233 238 public final void setNeedsRewriting(final boolean rewriting) { 239 fNeedsRewriting= rewriting; 240 } 241 } 242 243 244 public interface IVisibilityAdjustment { 245 246 253 public void rewriteVisibility(MemberVisibilityAdjustor adjustor, IProgressMonitor monitor) throws JavaModelException; 254 } 255 256 257 public static class OutgoingMemberVisibilityAdjustment extends IncomingMemberVisibilityAdjustment { 258 259 266 public OutgoingMemberVisibilityAdjustment(final IMember member, final ModifierKeyword keyword, final RefactoringStatus status) { 267 super(member, keyword, status); 268 } 269 270 273 public void rewriteVisibility(final MemberVisibilityAdjustor adjustor, final IProgressMonitor monitor) throws JavaModelException { 274 Assert.isNotNull(adjustor); 275 Assert.isNotNull(monitor); 276 try { 277 monitor.beginTask("", 1); monitor.setTaskName(RefactoringCoreMessages.MemberVisibilityAdjustor_adjusting); 279 if (fNeedsRewriting) { 280 final CompilationUnitRewrite rewrite= adjustor.getCompilationUnitRewrite(fMember.getCompilationUnit()); 281 rewriteVisibility(adjustor, rewrite.getASTRewrite(), rewrite.getRoot(), rewrite.createCategorizedGroupDescription(Messages.format(RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility, getLabel(getKeyword())), SET_VISIBILITY_ADJUSTMENTS), fRefactoringStatus); 282 } 283 monitor.worked(1); 284 } finally { 285 monitor.done(); 286 } 287 } 288 } 289 290 296 public static String getLabel(final IJavaElement element) { 297 Assert.isNotNull(element); 298 return JavaElementLabels.getElementLabel(element, JavaElementLabels.ALL_FULLY_QUALIFIED | JavaElementLabels.ALL_DEFAULT); 299 } 300 301 307 public static String getLabel(final ModifierKeyword keyword) { 308 Assert.isTrue(isVisibilityKeyword(keyword)); 309 if (keyword == null) 310 return RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_default; 311 else if (ModifierKeyword.PUBLIC_KEYWORD.equals(keyword)) 312 return RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_public; 313 else if (ModifierKeyword.PROTECTED_KEYWORD.equals(keyword)) 314 return RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_protected; 315 else 316 return RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_private; 317 } 318 319 325 public static String getMessage(final IMember member) { 326 Assert.isTrue(member instanceof IType || member instanceof IMethod || member instanceof IField); 327 if (member instanceof IType) 328 return RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_type_warning; 329 else if (member instanceof IMethod) 330 return RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_method_warning; 331 else 332 return RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_field_warning; 333 } 334 335 342 public static boolean hasLowerVisibility(final int modifiers, final int threshold) { 343 if (Modifier.isPrivate(threshold)) 344 return false; 345 else if (Modifier.isPublic(threshold)) 346 return !Modifier.isPublic(modifiers); 347 else if (Modifier.isProtected(threshold)) 348 return !Modifier.isProtected(modifiers) && !Modifier.isPublic(modifiers); 349 else 350 return Modifier.isPrivate(modifiers); 351 } 352 353 360 public static boolean hasLowerVisibility(final ModifierKeyword keyword, final ModifierKeyword threshold) { 361 Assert.isTrue(isVisibilityKeyword(keyword)); 362 Assert.isTrue(isVisibilityKeyword(threshold)); 363 return hasLowerVisibility(keyword != null ? keyword.toFlagValue() : Modifier.NONE, threshold != null ? threshold.toFlagValue() : Modifier.NONE); 364 } 365 366 372 private static boolean isStatusSeverity(final int severity) { 373 return severity == RefactoringStatus.ERROR || severity == RefactoringStatus.FATAL || severity == RefactoringStatus.INFO || severity == RefactoringStatus.OK || severity == RefactoringStatus.WARNING; 374 } 375 376 382 private static boolean isVisibilityKeyword(final ModifierKeyword keyword) { 383 return keyword == null || ModifierKeyword.PUBLIC_KEYWORD.equals(keyword) || ModifierKeyword.PROTECTED_KEYWORD.equals(keyword) || ModifierKeyword.PRIVATE_KEYWORD.equals(keyword); 384 } 385 386 392 private static boolean isVisibilityModifier(final int modifier) { 393 return modifier == Modifier.NONE || modifier == Modifier.PUBLIC || modifier == Modifier.PROTECTED || modifier == Modifier.PRIVATE; 394 } 395 396 402 private static int keywordToVisibility(final ModifierKeyword keyword) { 403 int visibility= 0; 404 if (keyword == ModifierKeyword.PUBLIC_KEYWORD) 405 visibility= Flags.AccPublic; 406 else if (keyword == ModifierKeyword.PRIVATE_KEYWORD) 407 visibility= Flags.AccPrivate; 408 else if (keyword == ModifierKeyword.PROTECTED_KEYWORD) 409 visibility= Flags.AccProtected; 410 return visibility; 411 } 412 413 421 public static boolean needsVisibilityAdjustments(final IMember member, final int threshold, final Map adjustments) { 422 Assert.isNotNull(member); 423 Assert.isTrue(isVisibilityModifier(threshold)); 424 Assert.isNotNull(adjustments); 425 final IncomingMemberVisibilityAdjustment adjustment= (IncomingMemberVisibilityAdjustment) adjustments.get(member); 426 if (adjustment != null) { 427 final ModifierKeyword keyword= adjustment.getKeyword(); 428 return hasLowerVisibility(keyword == null ? Modifier.NONE : keyword.toFlagValue(), threshold); 429 } 430 return true; 431 } 432 433 441 public static boolean needsVisibilityAdjustments(final IMember member, final ModifierKeyword threshold, final Map adjustments) { 442 Assert.isNotNull(member); 443 Assert.isNotNull(adjustments); 444 final IncomingMemberVisibilityAdjustment adjustment= (IncomingMemberVisibilityAdjustment) adjustments.get(member); 445 if (adjustment != null) 446 return hasLowerVisibility(adjustment.getKeyword(), threshold); 447 return true; 448 } 449 450 451 private Map fAdjustments= new HashMap (); 452 453 454 private boolean fIncoming= true; 455 456 457 private boolean fOutgoing= true; 458 459 460 private final IMember fReferenced; 461 462 463 private final IJavaElement fReferencing; 464 465 466 private ASTRewrite fRewrite= null; 467 468 469 private Map fRewrites= new HashMap (3); 470 471 472 private CompilationUnit fRoot= null; 473 474 475 private IJavaSearchScope fScope; 476 477 478 private RefactoringStatus fStatus= new RefactoringStatus(); 479 480 481 private final Map fTypeHierarchies= new HashMap (); 482 483 484 private int fVisibilitySeverity= RefactoringStatus.WARNING; 485 486 487 private WorkingCopyOwner fOwner= null; 488 489 495 public MemberVisibilityAdjustor(final IJavaElement referencing, final IMember referenced) { 496 Assert.isTrue(!(referenced instanceof IInitializer)); 497 Assert.isTrue(referencing instanceof ICompilationUnit || referencing instanceof IType || referencing instanceof IPackageFragment); 498 fScope= RefactoringScopeFactory.createReferencedScope(new IJavaElement[] { referenced}, IJavaSearchScope.REFERENCED_PROJECTS | IJavaSearchScope.SOURCES | IJavaSearchScope.APPLICATION_LIBRARIES); 499 fReferencing= referencing; 500 fReferenced= referenced; 501 } 502 503 511 private void adjustIncomingVisibility(final IJavaElement element, IMember referencedMovedElement, final IProgressMonitor monitor) throws JavaModelException { 512 final ModifierKeyword threshold= getVisibilityThreshold(element, referencedMovedElement, monitor); 513 int flags= referencedMovedElement.getFlags(); 514 IType declaring= referencedMovedElement.getDeclaringType(); 515 if (declaring.isInterface()) 516 return; 517 if (hasLowerVisibility(flags, threshold == null ? Modifier.NONE : threshold.toFlagValue()) && needsVisibilityAdjustment(referencedMovedElement, threshold)) 518 fAdjustments.put(referencedMovedElement, new IncomingMemberVisibilityAdjustment(referencedMovedElement, threshold, RefactoringStatus.createStatus(fVisibilitySeverity, Messages.format(getMessage(referencedMovedElement), new String [] { getLabel(referencedMovedElement), getLabel(threshold)}), JavaStatusContext.create(referencedMovedElement), null, RefactoringStatusEntry.NO_CODE, null))); 519 } 520 521 528 private void adjustMemberVisibility(final IMember member, final IProgressMonitor monitor) throws JavaModelException { 529 530 if (member instanceof IType) { 531 final IJavaElement[] typeMembers= ((IType) member).getChildren(); 533 for (int i= 0; i < typeMembers.length; i++) { 534 if (! (typeMembers[i] instanceof IInitializer)) 535 adjustMemberVisibility((IMember) typeMembers[i], monitor); 536 } 537 } 538 539 if ((member.equals(fReferenced)) || (Modifier.isPublic(member.getFlags()))) 540 return; 541 542 final SearchResultGroup[] references= findReferences(member, monitor); 543 for (int i= 0; i < references.length; i++) { 544 final SearchMatch[] searchResults= references[i].getSearchResults(); 545 for (int k= 0; k < searchResults.length; k++) { 546 final IJavaElement referenceToMember= (IJavaElement) searchResults[k].getElement(); 547 if (fAdjustments.get(member) == null && referenceToMember instanceof IMember && !isInsideMovedMember(referenceToMember)) { 548 adjustIncomingVisibility(fReferencing, member, new SubProgressMonitor(monitor, 1)); 552 } 553 } 554 } 555 } 556 557 562 private boolean isInsideMovedMember(final IJavaElement element) { 563 IJavaElement current= element; 564 while ((current= current.getParent()) != null) 565 if (current.equals(fReferenced)) 566 return true; 567 return false; 568 } 569 570 577 private SearchResultGroup[] findReferences(final IMember member, final IProgressMonitor monitor) throws JavaModelException { 578 final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(SearchPattern.createPattern(member, IJavaSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE)); 579 engine.setOwner(fOwner); 580 engine.setFiltering(true, true); 581 engine.setScope(RefactoringScopeFactory.create(member)); 582 engine.searchPattern(new SubProgressMonitor(monitor, 1)); 583 return (SearchResultGroup[]) engine.getResults(); 584 } 585 586 600 private void adjustIncomingVisibility(final SearchResultGroup[] groups, final IProgressMonitor monitor) throws JavaModelException { 601 try { 602 monitor.beginTask("", groups.length); monitor.setTaskName(RefactoringCoreMessages.MemberVisibilityAdjustor_checking); 604 SearchMatch[] matches= null; 605 boolean adjusted= false; 606 for (int index= 0; index < groups.length; index++) { 607 matches= groups[index].getSearchResults(); 608 for (int offset= 0; offset < matches.length; offset++) { 609 final Object element= matches[offset].getElement(); 610 if (element instanceof IMember && !isInsideMovedMember((IMember) element)) { 611 adjustIncomingVisibility(fReferencing, fReferenced, monitor); 614 adjusted= true; break; 616 } 617 } 618 if (adjusted) 619 break; 620 monitor.worked(1); 621 } 622 } finally { 623 monitor.done(); 624 } 625 } 626 627 634 private void adjustOutgoingVisibility(final IField field, final ModifierKeyword threshold) throws JavaModelException { 635 Assert.isTrue(!field.isBinary() && !field.isReadOnly()); 636 final IType declaring= field.getDeclaringType(); 638 if (declaring != null && declaring.equals(fReferenced)) return; 639 if (hasLowerVisibility(field.getFlags(), keywordToVisibility(threshold)) && needsVisibilityAdjustment(field, threshold)) 640 adjustOutgoingVisibility(field, threshold, RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_field_warning); 641 } 642 643 651 private void adjustOutgoingVisibility(final IMember member, final ModifierKeyword threshold, final String template) throws JavaModelException { 652 Assert.isTrue(!member.isBinary() && !member.isReadOnly()); 653 boolean adjust= true; 654 final IType declaring= member.getDeclaringType(); 655 if (declaring != null && (JavaModelUtil.isInterfaceOrAnnotation(declaring) || declaring.equals(fReferenced))) 656 adjust= false; 657 if (adjust && hasLowerVisibility(member.getFlags(), keywordToVisibility(threshold)) && needsVisibilityAdjustment(member, threshold)) 658 fAdjustments.put(member, new OutgoingMemberVisibilityAdjustment(member, threshold, RefactoringStatus.createStatus(fVisibilitySeverity, Messages.format(template, new String [] { JavaElementLabels.getTextLabel(member, JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.ALL_FULLY_QUALIFIED), getLabel(threshold)}), JavaStatusContext.create(member), null, RefactoringStatusEntry.NO_CODE, null))); 659 } 660 661 668 private void adjustOutgoingVisibility(final SearchMatch match, final IProgressMonitor monitor) throws JavaModelException { 669 final Object element= match.getElement(); 670 if (element instanceof IMember) { 671 final IMember member= (IMember) element; 672 if (!member.isBinary() && !member.isReadOnly() && !isInsideMovedMember(member)) { 673 adjustOutgoingVisibilityChain(member, monitor); 674 } 675 } 676 } 677 678 private void adjustOutgoingVisibilityChain(final IMember member, final IProgressMonitor monitor) throws JavaModelException { 679 680 if (!Modifier.isPublic(member.getFlags())) { 681 final ModifierKeyword threshold= computeOutgoingVisibilityThreshold(fReferencing, member, monitor); 682 if (member instanceof IMethod) { 683 adjustOutgoingVisibility(member, threshold, RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_method_warning); 684 } else if (member instanceof IField) { 685 adjustOutgoingVisibility((IField) member, threshold); 686 } else if (member instanceof IType) { 687 adjustOutgoingVisibility(member, threshold, RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_type_warning); 688 } 689 } 690 691 if (member.getDeclaringType() != null) 692 adjustOutgoingVisibilityChain(member.getDeclaringType(), monitor); 693 } 694 695 702 private void adjustOutgoingVisibility(final SearchResultGroup[] groups, final IProgressMonitor monitor) throws JavaModelException { 703 try { 704 monitor.beginTask("", groups.length); monitor.setTaskName(RefactoringCoreMessages.MemberVisibilityAdjustor_checking); 706 IJavaElement element= null; 707 SearchMatch[] matches= null; 708 SearchResultGroup group= null; 709 for (int index= 0; index < groups.length; index++) { 710 group= groups[index]; 711 element= JavaCore.create(group.getResource()); 712 if (element instanceof ICompilationUnit) { 713 matches= group.getSearchResults(); 714 for (int offset= 0; offset < matches.length; offset++) 715 adjustOutgoingVisibility(matches[offset], new SubProgressMonitor(monitor, 1)); 716 } 721 723 monitor.worked(1); 724 } 725 } finally { 726 monitor.done(); 727 } 728 } 729 730 736 public final void adjustVisibility(final IProgressMonitor monitor) throws JavaModelException { 737 try { 738 monitor.beginTask("", 7); monitor.setTaskName(RefactoringCoreMessages.MemberVisibilityAdjustor_checking); 740 final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(SearchPattern.createPattern(fReferenced, IJavaSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE)); 741 engine.setScope(fScope); 742 engine.setStatus(fStatus); 743 engine.setOwner(fOwner); 744 if (fIncoming) { 745 engine.searchPattern(new SubProgressMonitor(monitor, 1)); 748 adjustIncomingVisibility((SearchResultGroup[]) engine.getResults(), new SubProgressMonitor(monitor, 1)); 749 engine.clearResults(); 750 if (fReferenced instanceof IType) { 753 final IType type= (IType) fReferenced; 754 adjustMemberVisibility(type, new SubProgressMonitor(monitor, 1)); 755 } 756 } 757 if (fOutgoing) { 758 765 engine.searchReferencedTypes(fReferenced, new SubProgressMonitor(monitor, 1, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); 766 engine.searchReferencedFields(fReferenced, new SubProgressMonitor(monitor, 1, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); 767 engine.searchReferencedMethods(fReferenced, new SubProgressMonitor(monitor, 1, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); 768 adjustOutgoingVisibility((SearchResultGroup[]) engine.getResults(), new SubProgressMonitor(monitor, 1)); 769 } 770 } finally { 771 monitor.done(); 772 } 773 } 774 775 784 public ModifierKeyword getVisibilityThreshold(final IJavaElement referencing, final IMember referenced, final IProgressMonitor monitor) throws JavaModelException { 785 Assert.isTrue(!(referencing instanceof IInitializer)); 786 Assert.isTrue(!(referenced instanceof IInitializer)); 787 ModifierKeyword keyword= ModifierKeyword.PUBLIC_KEYWORD; 788 try { 789 monitor.beginTask("", 1); monitor.setTaskName(RefactoringCoreMessages.MemberVisibilityAdjustor_checking); 791 final int referencingType= referencing.getElementType(); 792 final int referencedType= referenced.getElementType(); 793 switch (referencedType) { 794 case IJavaElement.TYPE: { 795 final IType typeReferenced= (IType) referenced; 796 final ICompilationUnit referencedUnit= typeReferenced.getCompilationUnit(); 797 switch (referencingType) { 798 case IJavaElement.TYPE: { 799 keyword= thresholdTypeToType((IType) referencing, typeReferenced, monitor); 800 break; 801 } 802 case IJavaElement.FIELD: 803 case IJavaElement.METHOD: { 804 final IMember member= (IMember) referencing; 805 if (typeReferenced.equals(member.getDeclaringType())) 806 keyword= ModifierKeyword.PRIVATE_KEYWORD; 807 else if (referencedUnit != null && referencedUnit.equals(member.getCompilationUnit())) 808 keyword= ModifierKeyword.PRIVATE_KEYWORD; 809 else if (typeReferenced.getPackageFragment().equals(member.getDeclaringType().getPackageFragment())) 810 keyword= null; 811 break; 812 } 813 case IJavaElement.PACKAGE_FRAGMENT: { 814 final IPackageFragment fragment= (IPackageFragment) referencing; 815 if (typeReferenced.getPackageFragment().equals(fragment)) 816 keyword= null; 817 break; 818 } 819 default: 820 Assert.isTrue(false); 821 } 822 break; 823 } 824 case IJavaElement.FIELD: { 825 final IField fieldReferenced= (IField) referenced; 826 final ICompilationUnit referencedUnit= fieldReferenced.getCompilationUnit(); 827 switch (referencingType) { 828 case IJavaElement.TYPE: { 829 keyword= thresholdTypeToField((IType) referencing, fieldReferenced, monitor); 830 break; 831 } 832 case IJavaElement.FIELD: 833 case IJavaElement.METHOD: { 834 final IMember member= (IMember) referencing; 835 if (fieldReferenced.getDeclaringType().equals(member.getDeclaringType())) 836 keyword= ModifierKeyword.PRIVATE_KEYWORD; 837 else if (referencedUnit != null && referencedUnit.equals(member.getCompilationUnit())) 838 keyword= ModifierKeyword.PRIVATE_KEYWORD; 839 else if (fieldReferenced.getDeclaringType().getPackageFragment().equals(member.getDeclaringType().getPackageFragment())) 840 keyword= null; 841 break; 842 } 843 case IJavaElement.PACKAGE_FRAGMENT: { 844 final IPackageFragment fragment= (IPackageFragment) referencing; 845 if (fieldReferenced.getDeclaringType().getPackageFragment().equals(fragment)) 846 keyword= null; 847 break; 848 } 849 default: 850 Assert.isTrue(false); 851 } 852 break; 853 } 854 case IJavaElement.METHOD: { 855 final IMethod methodReferenced= (IMethod) referenced; 856 final ICompilationUnit referencedUnit= methodReferenced.getCompilationUnit(); 857 switch (referencingType) { 858 case IJavaElement.TYPE: { 859 keyword= thresholdTypeToMethod((IType) referencing, methodReferenced, monitor); 860 break; 861 } 862 case IJavaElement.FIELD: 863 case IJavaElement.METHOD: { 864 final IMember member= (IMember) referencing; 865 if (methodReferenced.getDeclaringType().equals(member.getDeclaringType())) 866 keyword= ModifierKeyword.PRIVATE_KEYWORD; 867 else if (referencedUnit != null && referencedUnit.equals(member.getCompilationUnit())) 868 keyword= ModifierKeyword.PRIVATE_KEYWORD; 869 else if (methodReferenced.getDeclaringType().getPackageFragment().equals(member.getDeclaringType().getPackageFragment())) 870 keyword= null; 871 break; 872 } 873 case IJavaElement.PACKAGE_FRAGMENT: { 874 final IPackageFragment fragment= (IPackageFragment) referencing; 875 if (methodReferenced.getDeclaringType().getPackageFragment().equals(fragment)) 876 keyword= null; 877 break; 878 } 879 default: 880 Assert.isTrue(false); 881 } 882 break; 883 } 884 default: 885 Assert.isTrue(false); 886 } 887 } finally { 888 monitor.done(); 889 } 890 return keyword; 891 } 892 893 902 private ModifierKeyword computeOutgoingVisibilityThreshold(final IJavaElement referencing, final IMember referenced, final IProgressMonitor monitor) throws JavaModelException { 903 Assert.isTrue(referencing instanceof ICompilationUnit || referencing instanceof IType || referencing instanceof IPackageFragment); 904 Assert.isTrue(referenced instanceof IType || referenced instanceof IField || referenced instanceof IMethod); 905 ModifierKeyword keyword= ModifierKeyword.PUBLIC_KEYWORD; 906 try { 907 monitor.beginTask("", 1); monitor.setTaskName(RefactoringCoreMessages.MemberVisibilityAdjustor_checking); 909 final int referencingType= referencing.getElementType(); 910 final int referencedType= referenced.getElementType(); 911 switch (referencedType) { 912 case IJavaElement.TYPE: { 913 final IType typeReferenced= (IType) referenced; 914 switch (referencingType) { 915 case IJavaElement.COMPILATION_UNIT: { 916 final ICompilationUnit unit= (ICompilationUnit) referencing; 917 final ICompilationUnit referencedUnit= typeReferenced.getCompilationUnit(); 918 if (referencedUnit != null && referencedUnit.equals(unit)) 919 keyword= ModifierKeyword.PRIVATE_KEYWORD; 920 else if (referencedUnit != null && referencedUnit.getParent().equals(unit.getParent())) 921 keyword= null; 922 break; 923 } 924 case IJavaElement.TYPE: { 925 keyword= thresholdTypeToType((IType) referencing, typeReferenced, monitor); 926 break; 927 } 928 case IJavaElement.PACKAGE_FRAGMENT: { 929 final IPackageFragment fragment= (IPackageFragment) referencing; 930 if (typeReferenced.getPackageFragment().equals(fragment)) 931 keyword= null; 932 break; 933 } 934 default: 935 Assert.isTrue(false); 936 } 937 break; 938 } 939 case IJavaElement.FIELD: { 940 final IField fieldReferenced= (IField) referenced; 941 final ICompilationUnit referencedUnit= fieldReferenced.getCompilationUnit(); 942 switch (referencingType) { 943 case IJavaElement.COMPILATION_UNIT: { 944 final ICompilationUnit unit= (ICompilationUnit) referencing; 945 if (referencedUnit != null && referencedUnit.equals(unit)) 946 keyword= ModifierKeyword.PRIVATE_KEYWORD; 947 else if (referencedUnit != null && referencedUnit.getParent().equals(unit.getParent())) 948 keyword= null; 949 break; 950 } 951 case IJavaElement.TYPE: { 952 keyword= thresholdTypeToField((IType) referencing, fieldReferenced, monitor); 953 break; 954 } 955 case IJavaElement.PACKAGE_FRAGMENT: { 956 final IPackageFragment fragment= (IPackageFragment) referencing; 957 if (fieldReferenced.getDeclaringType().getPackageFragment().equals(fragment)) 958 keyword= null; 959 break; 960 } 961 default: 962 Assert.isTrue(false); 963 } 964 break; 965 } 966 case IJavaElement.METHOD: { 967 final IMethod methodReferenced= (IMethod) referenced; 968 final ICompilationUnit referencedUnit= methodReferenced.getCompilationUnit(); 969 switch (referencingType) { 970 case IJavaElement.COMPILATION_UNIT: { 971 final ICompilationUnit unit= (ICompilationUnit) referencing; 972 if (referencedUnit != null && referencedUnit.equals(unit)) 973 keyword= ModifierKeyword.PRIVATE_KEYWORD; 974 else if (referencedUnit != null && referencedUnit.getParent().equals(unit.getParent())) 975 keyword= null; 976 break; 977 } 978 case IJavaElement.TYPE: { 979 keyword= thresholdTypeToMethod((IType) referencing, methodReferenced, monitor); 980 break; 981 } 982 case IJavaElement.PACKAGE_FRAGMENT: { 983 final IPackageFragment fragment= (IPackageFragment) referencing; 984 if (methodReferenced.getDeclaringType().getPackageFragment().equals(fragment)) 985 keyword= null; 986 break; 987 } 988 default: 989 Assert.isTrue(false); 990 } 991 break; 992 } 993 default: 994 Assert.isTrue(false); 995 } 996 } finally { 997 monitor.done(); 998 } 999 return keyword; 1000 } 1001 1002 1007 public final Map getAdjustments() { 1008 return fAdjustments; 1009 } 1010 1011 1017 private CompilationUnitRewrite getCompilationUnitRewrite(final ICompilationUnit unit) { 1018 CompilationUnitRewrite rewrite= (CompilationUnitRewrite) fRewrites.get(unit); 1019 if (rewrite == null) { 1020 if (fOwner == null) 1021 rewrite= new CompilationUnitRewrite(unit); 1022 else 1023 rewrite= new CompilationUnitRewrite(fOwner, unit); 1024 } 1025 return rewrite; 1026 } 1027 1028 1036 private ITypeHierarchy getTypeHierarchy(final IType type, final IProgressMonitor monitor) throws JavaModelException { 1037 ITypeHierarchy hierarchy= null; 1038 try { 1039 monitor.beginTask("", 1); monitor.setTaskName(RefactoringCoreMessages.MemberVisibilityAdjustor_checking); 1041 try { 1042 hierarchy= (ITypeHierarchy) fTypeHierarchies.get(type); 1043 if (hierarchy == null) { 1044 if (fOwner == null) 1045 hierarchy= type.newSupertypeHierarchy(new SubProgressMonitor(monitor, 1, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); 1046 else 1047 hierarchy= type.newSupertypeHierarchy(fOwner, new SubProgressMonitor(monitor, 1, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); 1048 } 1049 } finally { 1050 monitor.done(); 1051 } 1052 } finally { 1053 monitor.done(); 1054 } 1055 return hierarchy; 1056 } 1057 1058 1065 private boolean needsVisibilityAdjustment(final IMember member, final ModifierKeyword threshold) { 1066 Assert.isNotNull(member); 1067 return needsVisibilityAdjustments(member, threshold, fAdjustments); 1068 } 1069 1070 1077 public final void rewriteVisibility(final ICompilationUnit unit, final IProgressMonitor monitor) throws JavaModelException { 1078 try { 1079 monitor.beginTask("", fAdjustments.keySet().size()); monitor.setTaskName(RefactoringCoreMessages.MemberVisibilityAdjustor_adjusting); 1081 IMember member= null; 1082 IVisibilityAdjustment adjustment= null; 1083 for (final Iterator iterator= fAdjustments.keySet().iterator(); iterator.hasNext();) { 1084 member= (IMember) iterator.next(); 1085 if (unit.equals(member.getCompilationUnit())) { 1086 adjustment= (IVisibilityAdjustment) fAdjustments.get(member); 1087 if (adjustment != null) 1088 adjustment.rewriteVisibility(this, new SubProgressMonitor(monitor, 1)); 1089 } 1090 } 1091 } finally { 1092 fTypeHierarchies.clear(); 1093 monitor.done(); 1094 } 1095 } 1096 1097 1103 public final void rewriteVisibility(final IProgressMonitor monitor) throws JavaModelException { 1104 try { 1105 monitor.beginTask("", fAdjustments.keySet().size()); monitor.setTaskName(RefactoringCoreMessages.MemberVisibilityAdjustor_adjusting); 1107 IMember member= null; 1108 IVisibilityAdjustment adjustment= null; 1109 for (final Iterator iterator= fAdjustments.keySet().iterator(); iterator.hasNext();) { 1110 member= (IMember) iterator.next(); 1111 adjustment= (IVisibilityAdjustment) fAdjustments.get(member); 1112 if (adjustment != null) 1113 adjustment.rewriteVisibility(this, new SubProgressMonitor(monitor, 1)); 1114 if (monitor.isCanceled()) 1115 throw new OperationCanceledException(); 1116 } 1117 } finally { 1118 fTypeHierarchies.clear(); 1119 monitor.done(); 1120 } 1121 } 1122 1123 1130 public final void setAdjustments(final Map adjustments) { 1131 Assert.isNotNull(adjustments); 1132 fAdjustments= adjustments; 1133 } 1134 1135 1142 public final void setFailureSeverity(final int severity) { 1143 Assert.isTrue(isStatusSeverity(severity)); 1144 } 1145 1146 1153 public final void setIncoming(final boolean incoming) { 1154 fIncoming= incoming; 1155 } 1156 1157 1164 public final void setOutgoing(final boolean outgoing) { 1165 fOutgoing= outgoing; 1166 } 1167 1168 1176 public final void setRewrite(final ASTRewrite rewrite, final CompilationUnit root) { 1177 Assert.isTrue(rewrite == null || root != null); 1178 fRewrite= rewrite; 1179 fRoot= root; 1180 } 1181 1182 1189 public final void setRewrites(final Map rewrites) { 1190 Assert.isNotNull(rewrites); 1191 fRewrites= rewrites; 1192 } 1193 1194 1201 public final void setScope(final IJavaSearchScope scope) { 1202 Assert.isNotNull(scope); 1203 fScope= scope; 1204 } 1205 1206 1213 public final void setOwner(final WorkingCopyOwner owner) { 1214 fOwner= owner; 1215 } 1216 1217 1224 public final void setStatus(final RefactoringStatus status) { 1225 Assert.isNotNull(status); 1226 fStatus= status; 1227 } 1228 1229 1236 public final void setVisibilitySeverity(final int severity) { 1237 Assert.isTrue(isStatusSeverity(severity)); 1238 fVisibilitySeverity= severity; 1239 } 1240 1241 1250 private ModifierKeyword thresholdTypeToField(final IType referencing, final IField referenced, final IProgressMonitor monitor) throws JavaModelException { 1251 ModifierKeyword keyword= ModifierKeyword.PUBLIC_KEYWORD; 1252 final ICompilationUnit referencedUnit= referenced.getCompilationUnit(); 1253 if (referenced.getDeclaringType().equals(referencing)) 1254 keyword= ModifierKeyword.PRIVATE_KEYWORD; 1255 else { 1256 final ITypeHierarchy hierarchy= getTypeHierarchy(referencing, new SubProgressMonitor(monitor, 1)); 1257 final IType[] types= hierarchy.getSupertypes(referencing); 1258 IType superType= null; 1259 for (int index= 0; index < types.length; index++) { 1260 superType= types[index]; 1261 if (superType.equals(referenced.getDeclaringType())) { 1262 keyword= ModifierKeyword.PROTECTED_KEYWORD; 1263 return keyword; 1264 } 1265 } 1266 } 1267 final ICompilationUnit typeUnit= referencing.getCompilationUnit(); 1268 if (referencedUnit != null && referencedUnit.equals(typeUnit)) 1269 keyword= ModifierKeyword.PRIVATE_KEYWORD; 1270 else if (referencedUnit != null && typeUnit != null && referencedUnit.getParent().equals(typeUnit.getParent())) 1271 keyword= null; 1272 return keyword; 1273 } 1274 1275 1284 private ModifierKeyword thresholdTypeToMethod(final IType referencing, final IMethod referenced, final IProgressMonitor monitor) throws JavaModelException { 1285 final ICompilationUnit referencedUnit= referenced.getCompilationUnit(); 1286 ModifierKeyword keyword= ModifierKeyword.PUBLIC_KEYWORD; 1287 if (referenced.getDeclaringType().equals(referencing)) 1288 keyword= ModifierKeyword.PRIVATE_KEYWORD; 1289 else { 1290 final ITypeHierarchy hierarchy= getTypeHierarchy(referencing, new SubProgressMonitor(monitor, 1)); 1291 final IType[] types= hierarchy.getSupertypes(referencing); 1292 IType superType= null; 1293 for (int index= 0; index < types.length; index++) { 1294 superType= types[index]; 1295 if (superType.equals(referenced.getDeclaringType())) { 1296 keyword= ModifierKeyword.PROTECTED_KEYWORD; 1297 return keyword; 1298 } 1299 } 1300 } 1301 final ICompilationUnit typeUnit= referencing.getCompilationUnit(); 1302 if (referencedUnit != null && referencedUnit.equals(typeUnit)) { 1303 if (referenced.getDeclaringType().getDeclaringType() != null) 1304 keyword= null; 1305 else 1306 keyword= ModifierKeyword.PRIVATE_KEYWORD; 1307 } else if (referencedUnit != null && referencedUnit.getParent().equals(typeUnit.getParent())) 1308 keyword= null; 1309 return keyword; 1310 } 1311 1312 1321 private ModifierKeyword thresholdTypeToType(final IType referencing, final IType referenced, final IProgressMonitor monitor) throws JavaModelException { 1322 ModifierKeyword keyword= ModifierKeyword.PUBLIC_KEYWORD; 1323 final ICompilationUnit referencedUnit= referenced.getCompilationUnit(); 1324 if (referencing.equals(referenced.getDeclaringType())) 1325 keyword= ModifierKeyword.PRIVATE_KEYWORD; 1326 else { 1327 final ITypeHierarchy hierarchy= getTypeHierarchy(referencing, new SubProgressMonitor(monitor, 1)); 1328 final IType[] types= hierarchy.getSupertypes(referencing); 1329 IType superType= null; 1330 for (int index= 0; index < types.length; index++) { 1331 superType= types[index]; 1332 if (superType.equals(referenced)) { 1333 keyword= null; 1334 return keyword; 1335 } 1336 } 1337 } 1338 final ICompilationUnit typeUnit= referencing.getCompilationUnit(); 1339 if (referencedUnit != null && referencedUnit.equals(typeUnit)) { 1340 if (referenced.getDeclaringType() != null) 1341 keyword= null; 1342 else 1343 keyword= ModifierKeyword.PRIVATE_KEYWORD; 1344 } else if (referencedUnit != null && typeUnit != null && referencedUnit.getParent().equals(typeUnit.getParent())) 1345 keyword= null; 1346 return keyword; 1347 } 1348} 1349 | Popular Tags |