1 11 package org.eclipse.jdt.internal.corext.refactoring.structure.constraints; 12 13 import java.util.ArrayList ; 14 import java.util.Collection ; 15 import java.util.Collections ; 16 import java.util.HashMap ; 17 import java.util.HashSet ; 18 import java.util.Iterator ; 19 import java.util.List ; 20 import java.util.Map ; 21 import java.util.Set ; 22 23 import org.eclipse.text.edits.MalformedTreeException; 24 import org.eclipse.text.edits.TextEdit; 25 import org.eclipse.text.edits.TextEditGroup; 26 27 import org.eclipse.core.runtime.Assert; 28 import org.eclipse.core.runtime.CoreException; 29 import org.eclipse.core.runtime.IProgressMonitor; 30 import org.eclipse.core.runtime.NullProgressMonitor; 31 import org.eclipse.core.runtime.SubProgressMonitor; 32 33 import org.eclipse.jface.text.BadLocationException; 34 import org.eclipse.jface.text.Document; 35 import org.eclipse.jface.text.IDocument; 36 37 import org.eclipse.ltk.core.refactoring.GroupCategory; 38 import org.eclipse.ltk.core.refactoring.GroupCategorySet; 39 import org.eclipse.ltk.core.refactoring.RefactoringStatus; 40 import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor; 41 42 import org.eclipse.jdt.core.BindingKey; 43 import org.eclipse.jdt.core.ICompilationUnit; 44 import org.eclipse.jdt.core.IField; 45 import org.eclipse.jdt.core.IJavaElement; 46 import org.eclipse.jdt.core.IJavaProject; 47 import org.eclipse.jdt.core.IMember; 48 import org.eclipse.jdt.core.IMethod; 49 import org.eclipse.jdt.core.IPackageFragment; 50 import org.eclipse.jdt.core.IType; 51 import org.eclipse.jdt.core.ITypeParameter; 52 import org.eclipse.jdt.core.JavaCore; 53 import org.eclipse.jdt.core.JavaModelException; 54 import org.eclipse.jdt.core.WorkingCopyOwner; 55 import org.eclipse.jdt.core.dom.AST; 56 import org.eclipse.jdt.core.dom.ASTNode; 57 import org.eclipse.jdt.core.dom.ASTParser; 58 import org.eclipse.jdt.core.dom.ASTRequestor; 59 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; 60 import org.eclipse.jdt.core.dom.ArrayType; 61 import org.eclipse.jdt.core.dom.BodyDeclaration; 62 import org.eclipse.jdt.core.dom.CastExpression; 63 import org.eclipse.jdt.core.dom.CompilationUnit; 64 import org.eclipse.jdt.core.dom.FieldDeclaration; 65 import org.eclipse.jdt.core.dom.IBinding; 66 import org.eclipse.jdt.core.dom.IMethodBinding; 67 import org.eclipse.jdt.core.dom.ITypeBinding; 68 import org.eclipse.jdt.core.dom.IVariableBinding; 69 import org.eclipse.jdt.core.dom.MethodDeclaration; 70 import org.eclipse.jdt.core.dom.QualifiedName; 71 import org.eclipse.jdt.core.dom.SimpleName; 72 import org.eclipse.jdt.core.dom.SingleVariableDeclaration; 73 import org.eclipse.jdt.core.dom.Type; 74 import org.eclipse.jdt.core.dom.TypeDeclaration; 75 import org.eclipse.jdt.core.dom.TypeParameter; 76 import org.eclipse.jdt.core.dom.VariableDeclaration; 77 import org.eclipse.jdt.core.dom.VariableDeclarationFragment; 78 import org.eclipse.jdt.core.dom.VariableDeclarationStatement; 79 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; 80 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; 81 import org.eclipse.jdt.core.dom.rewrite.ListRewrite; 82 import org.eclipse.jdt.core.formatter.CodeFormatter; 83 import org.eclipse.jdt.core.search.IJavaSearchConstants; 84 import org.eclipse.jdt.core.search.SearchMatch; 85 import org.eclipse.jdt.core.search.SearchPattern; 86 87 import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings; 88 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility; 89 import org.eclipse.jdt.internal.corext.dom.ASTNodes; 90 import org.eclipse.jdt.internal.corext.dom.NodeFinder; 91 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment; 92 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; 93 import org.eclipse.jdt.internal.corext.refactoring.RefactoringScopeFactory; 94 import org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine2; 95 import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup; 96 import org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil; 97 import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; 98 import org.eclipse.jdt.internal.corext.refactoring.structure.ImportRewriteUtil; 99 import org.eclipse.jdt.internal.corext.refactoring.tagging.ICommentProvider; 100 import org.eclipse.jdt.internal.corext.refactoring.tagging.IScriptableRefactoring; 101 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.CompilationUnitRange; 102 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TType; 103 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TypeEnvironment; 104 import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser; 105 import org.eclipse.jdt.internal.corext.refactoring.util.TextEditBasedChangeManager; 106 import org.eclipse.jdt.internal.corext.util.CodeFormatterUtil; 107 import org.eclipse.jdt.internal.corext.util.JavaModelUtil; 108 import org.eclipse.jdt.internal.corext.util.JdtFlags; 109 import org.eclipse.jdt.internal.corext.util.SearchUtils; 110 111 import org.eclipse.jdt.ui.CodeGeneration; 112 113 import org.eclipse.jdt.internal.ui.JavaPlugin; 114 115 121 public abstract class SuperTypeRefactoringProcessor extends RefactoringProcessor implements IScriptableRefactoring, ICommentProvider { 122 123 protected static final String ATTRIBUTE_INSTANCEOF= "instanceof"; 126 protected static final String ATTRIBUTE_REPLACE= "replace"; 129 130 protected static final GroupCategorySet SET_SUPER_TYPE= new GroupCategorySet(new GroupCategory("org.eclipse.jdt.internal.corext.superType", RefactoringCoreMessages.SuperTypeRefactoringProcessor_category_name, RefactoringCoreMessages.SuperTypeRefactoringProcessor_category_description)); 132 133 134 private static final int SIZE_BATCH= 500; 135 136 145 protected static ASTNode createCorrespondingNode(final CompilationUnitRewrite rewrite, final TType type) { 146 return rewrite.getImportRewrite().addImportFromSignature(new BindingKey(type.getBindingKey()).toSignature(), rewrite.getAST()); 147 } 148 149 150 protected String fComment; 151 152 153 protected boolean fInstanceOf= false; 154 155 159 protected Map fObsoleteCasts= null; 160 161 162 protected final WorkingCopyOwner fOwner= new WorkingCopyOwner() { 163 }; 164 165 166 protected boolean fReplace= false; 167 168 169 protected CodeGenerationSettings fSettings; 170 171 172 protected final Set fStaticBindings= new HashSet (); 173 174 175 protected final Set fTypeBindings= new HashSet (); 176 177 181 protected Map fTypeOccurrences= null; 182 183 189 protected SuperTypeRefactoringProcessor(final CodeGenerationSettings settings) { 190 fSettings= settings; 191 } 192 193 202 protected void addSuperTypeSettings(final JDTRefactoringDescriptorComment comment, final boolean addUseSupertype) { 203 Assert.isNotNull(comment); 204 if (fReplace) { 205 if (addUseSupertype) 206 comment.addSetting(RefactoringCoreMessages.SuperTypeRefactoringProcessor_user_supertype_setting); 207 if (fInstanceOf) 208 comment.addSetting(RefactoringCoreMessages.SuperTypeRefactoringProcessor_use_in_instanceof_setting); 209 } 210 } 211 212 215 public boolean canEnableComment() { 216 return true; 217 } 218 219 226 protected abstract SuperTypeConstraintsSolver createContraintSolver(SuperTypeConstraintsModel model); 227 228 240 protected void createMemberDeclarations(CompilationUnitRewrite sourceRewrite, ASTRewrite targetRewrite, AbstractTypeDeclaration targetDeclaration) throws CoreException { 241 } 243 244 268 protected final void createTypeDeclaration(final CompilationUnitRewrite sourceRewrite, final IType subType, final String superName, final AbstractTypeDeclaration sourceDeclaration, final StringBuffer buffer, boolean isInterface, final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException { 269 Assert.isNotNull(sourceRewrite); 270 Assert.isNotNull(subType); 271 Assert.isNotNull(superName); 272 Assert.isNotNull(sourceDeclaration); 273 Assert.isNotNull(buffer); 274 Assert.isNotNull(status); 275 Assert.isNotNull(monitor); 276 try { 277 monitor.beginTask("", 100); monitor.setTaskName(RefactoringCoreMessages.ExtractInterfaceProcessor_creating); 279 final String delimiter= StubUtility.getLineDelimiterUsed(subType.getJavaProject()); 280 if (JdtFlags.isPublic(subType)) { 281 buffer.append(JdtFlags.VISIBILITY_STRING_PUBLIC); 282 buffer.append(" "); } 284 if (isInterface) 285 buffer.append("interface "); else 287 buffer.append("class "); buffer.append(superName); 289 buffer.append(" {"); buffer.append(delimiter); 291 buffer.append(delimiter); 292 buffer.append('}'); 293 final IDocument document= new Document(buffer.toString()); 294 final ASTParser parser= ASTParser.newParser(AST.JLS3); 295 parser.setSource(document.get().toCharArray()); 296 final CompilationUnit unit= (CompilationUnit) parser.createAST(new SubProgressMonitor(monitor, 100)); 297 final ASTRewrite targetRewrite= ASTRewrite.create(unit.getAST()); 298 final AbstractTypeDeclaration targetDeclaration= (AbstractTypeDeclaration) unit.types().get(0); 299 createTypeParameters(targetRewrite, subType, sourceDeclaration, targetDeclaration); 300 createMemberDeclarations(sourceRewrite, targetRewrite, targetDeclaration); 301 final TextEdit edit= targetRewrite.rewriteAST(document, subType.getJavaProject().getOptions(true)); 302 try { 303 edit.apply(document, TextEdit.UPDATE_REGIONS); 304 } catch (MalformedTreeException exception) { 305 JavaPlugin.log(exception); 306 } catch (BadLocationException exception) { 307 JavaPlugin.log(exception); 308 } 309 buffer.setLength(0); 310 buffer.append(document.get()); 311 } finally { 312 monitor.done(); 313 } 314 } 315 316 327 protected final String createTypeImports(final ICompilationUnit unit, final IProgressMonitor monitor) throws CoreException { 328 Assert.isNotNull(unit); 329 Assert.isNotNull(monitor); 330 try { 331 monitor.beginTask("", 100); monitor.setTaskName(RefactoringCoreMessages.ExtractInterfaceProcessor_creating); 333 final ImportRewrite rewrite= StubUtility.createImportRewrite(unit, true); 334 ITypeBinding type= null; 335 for (final Iterator iterator= fTypeBindings.iterator(); iterator.hasNext();) { 336 type= (ITypeBinding) iterator.next(); 337 if (type.isTypeVariable()) { 338 final ITypeBinding[] bounds= type.getTypeBounds(); 339 for (int index= 0; index < bounds.length; index++) 340 rewrite.addImport(bounds[index]); 341 } 342 rewrite.addImport(type); 343 } 344 IBinding binding= null; 345 for (final Iterator iterator= fStaticBindings.iterator(); iterator.hasNext();) { 346 binding= (IBinding) iterator.next(); 347 rewrite.addStaticImport(binding); 348 } 349 final IDocument document= new Document(); 350 try { 351 rewrite.rewriteImports(new SubProgressMonitor(monitor, 100)).apply(document); 352 } catch (MalformedTreeException exception) { 353 JavaPlugin.log(exception); 354 } catch (BadLocationException exception) { 355 JavaPlugin.log(exception); 356 } catch (CoreException exception) { 357 JavaPlugin.log(exception); 358 } 359 fTypeBindings.clear(); 360 fStaticBindings.clear(); 361 return document.get(); 362 } finally { 363 monitor.done(); 364 } 365 } 366 367 379 protected final void createTypeParameters(final ASTRewrite targetRewrite, final IType subType, final AbstractTypeDeclaration sourceDeclaration, final AbstractTypeDeclaration targetDeclaration) { 380 Assert.isNotNull(targetRewrite); 381 Assert.isNotNull(sourceDeclaration); 382 Assert.isNotNull(targetDeclaration); 383 if (sourceDeclaration instanceof TypeDeclaration) { 384 TypeParameter parameter= null; 385 final ListRewrite rewrite= targetRewrite.getListRewrite(targetDeclaration, TypeDeclaration.TYPE_PARAMETERS_PROPERTY); 386 for (final Iterator iterator= ((TypeDeclaration) sourceDeclaration).typeParameters().iterator(); iterator.hasNext();) { 387 parameter= (TypeParameter) iterator.next(); 388 rewrite.insertLast(ASTNode.copySubtree(targetRewrite.getAST(), parameter), null); 389 ImportRewriteUtil.collectImports(subType.getJavaProject(), sourceDeclaration, fTypeBindings, fStaticBindings, false); 390 } 391 } 392 } 393 394 415 protected final String createTypeSource(final ICompilationUnit copy, final IType subType, final String superName, final CompilationUnitRewrite sourceRewrite, final AbstractTypeDeclaration declaration, final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException { 416 Assert.isNotNull(copy); 417 Assert.isNotNull(subType); 418 Assert.isNotNull(superName); 419 Assert.isNotNull(sourceRewrite); 420 Assert.isNotNull(declaration); 421 Assert.isNotNull(status); 422 Assert.isNotNull(monitor); 423 String source= null; 424 try { 425 monitor.beginTask("", 100); monitor.setTaskName(RefactoringCoreMessages.ExtractInterfaceProcessor_creating); 427 final String delimiter= StubUtility.getLineDelimiterUsed(subType.getJavaProject()); 428 String typeComment= null; 429 String fileComment= null; 430 if (fSettings.createComments) { 431 final ITypeParameter[] parameters= subType.getTypeParameters(); 432 final String [] names= new String [parameters.length]; 433 for (int index= 0; index < parameters.length; index++) 434 names[index]= parameters[index].getElementName(); 435 typeComment= CodeGeneration.getTypeComment(copy, superName, names, delimiter); 436 fileComment= CodeGeneration.getFileComment(copy, delimiter); 437 } 438 final StringBuffer buffer= new StringBuffer (64); 439 createTypeDeclaration(sourceRewrite, subType, superName, declaration, buffer, true, status, new SubProgressMonitor(monitor, 40)); 440 final String imports= createTypeImports(copy, new SubProgressMonitor(monitor, 60)); 441 source= createTypeTemplate(copy, imports, fileComment, typeComment, buffer.toString()); 442 if (source == null) { 443 if (!subType.getPackageFragment().isDefaultPackage()) { 444 if (imports.length() > 0) 445 buffer.insert(0, imports); 446 buffer.insert(0, "package " + subType.getPackageFragment().getElementName() + ";"); } 448 source= buffer.toString(); 449 } 450 final IDocument document= new Document(source); 451 final TextEdit edit= CodeFormatterUtil.format2(CodeFormatter.K_COMPILATION_UNIT, source, 0, delimiter, copy.getJavaProject().getOptions(true)); 452 if (edit != null) { 453 try { 454 edit.apply(document, TextEdit.UPDATE_REGIONS); 455 } catch (MalformedTreeException exception) { 456 JavaPlugin.log(exception); 457 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractInterfaceProcessor_internal_error)); 458 } catch (BadLocationException exception) { 459 JavaPlugin.log(exception); 460 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractInterfaceProcessor_internal_error)); 461 } 462 source= document.get(); 463 } 464 } finally { 465 monitor.done(); 466 } 467 return source; 468 } 469 470 487 protected final String createTypeTemplate(final ICompilationUnit unit, final String imports, String fileComment, final String comment, final String content) throws CoreException { 488 Assert.isNotNull(unit); 489 Assert.isNotNull(imports); 490 Assert.isNotNull(content); 491 final IPackageFragment fragment= (IPackageFragment) unit.getParent(); 492 final StringBuffer buffer= new StringBuffer (); 493 final String delimiter= StubUtility.getLineDelimiterUsed(unit.getJavaProject()); 494 if (!fragment.isDefaultPackage()) { 495 buffer.append("package " + fragment.getElementName() + ";"); buffer.append(delimiter); 497 buffer.append(delimiter); 498 } 499 if (imports.length() > 0) 500 buffer.append(imports); 501 502 return StubUtility.getCompilationUnitContent(unit, buffer.toString(), fileComment, comment, content, delimiter); 503 } 504 505 508 protected void finalize() throws Throwable { 509 resetWorkingCopies(); 510 } 511 512 515 public final String getComment() { 516 return fComment; 517 } 518 519 529 protected final IField getCorrespondingField(final VariableDeclarationFragment fragment) throws JavaModelException { 530 final IBinding binding= fragment.getName().resolveBinding(); 531 if (binding instanceof IVariableBinding) { 532 final IVariableBinding variable= (IVariableBinding) binding; 533 if (variable.isField()) { 534 final ICompilationUnit unit= RefactoringASTParser.getCompilationUnit(fragment); 535 final IJavaElement element= unit.getElementAt(fragment.getStartPosition()); 536 if (element instanceof IField) 537 return (IField) element; 538 } 539 } 540 return null; 541 } 542 543 555 protected final void getFieldReferencingCompilationUnits(final Map units, final ASTNode[] nodes) throws JavaModelException { 556 ASTNode node= null; 557 IField field= null; 558 IJavaProject project= null; 559 for (int index= 0; index < nodes.length; index++) { 560 node= nodes[index]; 561 project= RefactoringASTParser.getCompilationUnit(node).getJavaProject(); 562 if (project != null) { 563 final List fields= getReferencingFields(node, project); 564 for (int offset= 0; offset < fields.size(); offset++) { 565 field= (IField) fields.get(offset); 566 Set set= (Set ) units.get(project); 567 if (set == null) { 568 set= new HashSet (); 569 units.put(project, set); 570 } 571 final ICompilationUnit unit= field.getCompilationUnit(); 572 if (unit != null) 573 set.add(unit); 574 } 575 } 576 } 577 } 578 579 591 protected final void getMethodReferencingCompilationUnits(final Map units, final ASTNode[] nodes) throws JavaModelException { 592 ASTNode node= null; 593 IMethod method= null; 594 IJavaProject project= null; 595 for (int index= 0; index < nodes.length; index++) { 596 node= nodes[index]; 597 project= RefactoringASTParser.getCompilationUnit(node).getJavaProject(); 598 if (project != null) { 599 method= getReferencingMethod(node); 600 if (method != null) { 601 Set set= (Set ) units.get(project); 602 if (set == null) { 603 set= new HashSet (); 604 units.put(project, set); 605 } 606 final ICompilationUnit unit= method.getCompilationUnit(); 607 if (unit != null) 608 set.add(unit); 609 } 610 } 611 } 612 } 613 614 628 protected final Map getReferencingCompilationUnits(final IType type, final IProgressMonitor monitor, final RefactoringStatus status) throws JavaModelException { 629 try { 630 monitor.beginTask("", 100); monitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating); 632 final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(); 633 engine.setOwner(fOwner); 634 engine.setFiltering(true, true); 635 engine.setStatus(status); 636 engine.setScope(RefactoringScopeFactory.create(type)); 637 engine.setPattern(SearchPattern.createPattern(type, IJavaSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE)); 638 engine.searchPattern(new SubProgressMonitor(monitor, 100)); 639 return engine.getAffectedProjects(); 640 } finally { 641 monitor.done(); 642 } 643 } 644 645 656 protected final List getReferencingFields(final ASTNode node, final IJavaProject project) throws JavaModelException { 657 List result= Collections.EMPTY_LIST; 658 if (node instanceof Type) { 659 final BodyDeclaration parent= (BodyDeclaration) ASTNodes.getParent(node, BodyDeclaration.class); 660 if (parent instanceof FieldDeclaration) { 661 final List fragments= ((FieldDeclaration) parent).fragments(); 662 result= new ArrayList (fragments.size()); 663 VariableDeclarationFragment fragment= null; 664 for (final Iterator iterator= fragments.iterator(); iterator.hasNext();) { 665 fragment= (VariableDeclarationFragment) iterator.next(); 666 final IField field= getCorrespondingField(fragment); 667 if (field != null) 668 result.add(field); 669 } 670 } 671 } 672 return result; 673 } 674 675 684 protected final IMethod getReferencingMethod(final ASTNode node) throws JavaModelException { 685 if (node instanceof Type) { 686 final BodyDeclaration parent= (BodyDeclaration) ASTNodes.getParent(node, BodyDeclaration.class); 687 if (parent instanceof MethodDeclaration) { 688 final IMethodBinding binding= ((MethodDeclaration) parent).resolveBinding(); 689 if (binding != null) { 690 final ICompilationUnit unit= RefactoringASTParser.getCompilationUnit(node); 691 final IJavaElement element= unit.getElementAt(node.getStartPosition()); 692 if (element instanceof IMethod) 693 return (IMethod) element; 694 } 695 } 696 } 697 return null; 698 } 699 700 protected ICompilationUnit getSharedWorkingCopy(final ICompilationUnit unit, final IProgressMonitor monitor) throws JavaModelException { 701 try { 702 ICompilationUnit copy= unit.findWorkingCopy(fOwner); 703 if (copy == null) 704 copy= unit.getWorkingCopy(fOwner, monitor); 705 return copy; 706 } finally { 707 monitor.done(); 708 } 709 } 710 711 717 public final boolean isInstanceOf() { 718 return fInstanceOf; 719 } 720 721 727 public final boolean isReplace() { 728 return fReplace; 729 } 730 731 749 protected final void performFirstPass(final SuperTypeConstraintsCreator creator, final Map units, final Map groups, final ICompilationUnit unit, final CompilationUnit node, final IProgressMonitor monitor) { 750 try { 751 monitor.beginTask("", 100); monitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating); 753 node.accept(creator); 754 monitor.worked(20); 755 final SearchResultGroup group= (SearchResultGroup) groups.get(unit); 756 if (group != null) { 757 final ASTNode[] nodes= ASTNodeSearchUtil.getAstNodes(group.getSearchResults(), node); 758 try { 759 getMethodReferencingCompilationUnits(units, nodes); 760 monitor.worked(40); 761 getFieldReferencingCompilationUnits(units, nodes); 762 monitor.worked(40); 763 } catch (JavaModelException exception) { 764 JavaPlugin.log(exception); 765 } 766 } 767 } finally { 768 monitor.done(); 769 } 770 } 771 772 784 protected final void performSecondPass(final SuperTypeConstraintsCreator creator, final ICompilationUnit unit, final CompilationUnit node, final IProgressMonitor monitor) { 785 try { 786 monitor.beginTask("", 20); monitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating); 788 node.accept(creator); 789 monitor.worked(20); 790 } finally { 791 monitor.done(); 792 } 793 } 794 795 798 protected void resetWorkingCopies() { 799 final ICompilationUnit[] units= JavaCore.getWorkingCopies(fOwner); 800 for (int index= 0; index < units.length; index++) { 801 final ICompilationUnit unit= units[index]; 802 try { 803 unit.discardWorkingCopy(); 804 } catch (Exception exception) { 805 } 807 } 808 } 809 810 816 protected void resetWorkingCopies(final ICompilationUnit unit) { 817 final ICompilationUnit[] units= JavaCore.getWorkingCopies(fOwner); 818 for (int index= 0; index < units.length; index++) { 819 if (!units[index].equals(unit)) { 820 try { 821 units[index].discardWorkingCopy(); 822 } catch (Exception exception) { 823 } 825 } else { 826 try { 827 units[index].getBuffer().setContents(unit.getPrimary().getBuffer().getContents()); 828 JavaModelUtil.reconcile(units[index]); 829 } catch (JavaModelException exception) { 830 JavaPlugin.log(exception); 831 } 832 } 833 } 834 } 835 836 856 protected final void rewriteTypeOccurrence(final CompilationUnitRange range, final TType estimate, final ASTRequestor requestor, final CompilationUnitRewrite rewrite, final CompilationUnit copy, final Set replacements, final TextEditGroup group) { 857 ASTNode node= null; 858 IBinding binding= null; 859 final CompilationUnit target= rewrite.getRoot(); 860 node= NodeFinder.perform(copy, range.getSourceRange()); 861 if (node != null) { 862 node= ASTNodes.getNormalizedNode(node).getParent(); 863 if (node instanceof VariableDeclaration) { 864 binding= ((VariableDeclaration) node).resolveBinding(); 865 node= target.findDeclaringNode(binding.getKey()); 866 if (node instanceof SingleVariableDeclaration) { 867 rewriteTypeOccurrence(estimate, rewrite, ((SingleVariableDeclaration) node).getType(), group); 868 if (node.getParent() instanceof MethodDeclaration) { 869 binding= ((VariableDeclaration) node).resolveBinding(); 870 if (binding != null) 871 replacements.add(binding.getKey()); 872 } 873 } 874 } else if (node instanceof VariableDeclarationStatement) { 875 binding= ((VariableDeclaration) ((VariableDeclarationStatement) node).fragments().get(0)).resolveBinding(); 876 node= target.findDeclaringNode(binding.getKey()); 877 if (node instanceof VariableDeclarationFragment) 878 rewriteTypeOccurrence(estimate, rewrite, ((VariableDeclarationStatement) ((VariableDeclarationFragment) node).getParent()).getType(), group); 879 } else if (node instanceof MethodDeclaration) { 880 binding= ((MethodDeclaration) node).resolveBinding(); 881 node= target.findDeclaringNode(binding.getKey()); 882 if (node instanceof MethodDeclaration) 883 rewriteTypeOccurrence(estimate, rewrite, ((MethodDeclaration) node).getReturnType2(), group); 884 } else if (node instanceof FieldDeclaration) { 885 binding= ((VariableDeclaration) ((FieldDeclaration) node).fragments().get(0)).resolveBinding(); 886 node= target.findDeclaringNode(binding.getKey()); 887 if (node instanceof VariableDeclarationFragment) { 888 node= node.getParent(); 889 if (node instanceof FieldDeclaration) 890 rewriteTypeOccurrence(estimate, rewrite, ((FieldDeclaration) node).getType(), group); 891 } 892 } else if (node instanceof ArrayType) { 893 final ASTNode type= node; 894 while (node != null && !(node instanceof MethodDeclaration) && !(node instanceof VariableDeclarationFragment)) 895 node= node.getParent(); 896 if (node != null) { 897 final int delta= node.getStartPosition() + node.getLength() - type.getStartPosition(); 898 if (node instanceof MethodDeclaration) 899 binding= ((MethodDeclaration) node).resolveBinding(); 900 else if (node instanceof VariableDeclarationFragment) 901 binding= ((VariableDeclarationFragment) node).resolveBinding(); 902 if (binding != null) { 903 node= target.findDeclaringNode(binding.getKey()); 904 if (node instanceof MethodDeclaration || node instanceof VariableDeclarationFragment) { 905 node= NodeFinder.perform(target, node.getStartPosition() + node.getLength() - delta, 0); 906 if (node instanceof SimpleName) 907 rewriteTypeOccurrence(estimate, rewrite, node, group); 908 } 909 } 910 } 911 } else if (node instanceof QualifiedName) { 912 final ASTNode name= node; 913 while (node != null && !(node instanceof MethodDeclaration) && !(node instanceof VariableDeclarationFragment)) 914 node= node.getParent(); 915 if (node != null) { 916 final int delta= node.getStartPosition() + node.getLength() - name.getStartPosition(); 917 if (node instanceof MethodDeclaration) 918 binding= ((MethodDeclaration) node).resolveBinding(); 919 else if (node instanceof VariableDeclarationFragment) 920 binding= ((VariableDeclarationFragment) node).resolveBinding(); 921 if (binding != null) { 922 node= target.findDeclaringNode(binding.getKey()); 923 if (node instanceof SimpleName || node instanceof MethodDeclaration || node instanceof VariableDeclarationFragment) { 924 node= NodeFinder.perform(target, node.getStartPosition() + node.getLength() - delta, 0); 925 if (node instanceof SimpleName) 926 rewriteTypeOccurrence(estimate, rewrite, node, group); 927 } 928 } 929 } 930 } else if (node instanceof CastExpression) { 931 final ASTNode expression= node; 932 while (node != null && !(node instanceof MethodDeclaration)) 933 node= node.getParent(); 934 if (node != null) { 935 final int delta= node.getStartPosition() + node.getLength() - expression.getStartPosition(); 936 binding= ((MethodDeclaration) node).resolveBinding(); 937 node= target.findDeclaringNode(binding.getKey()); 938 if (node instanceof MethodDeclaration) { 939 node= NodeFinder.perform(target, node.getStartPosition() + node.getLength() - delta, 0); 940 if (node instanceof CastExpression) 941 rewriteTypeOccurrence(estimate, rewrite, ((CastExpression) node).getType(), group); 942 } 943 } 944 } 945 } 946 } 947 948 961 protected final void rewriteTypeOccurrence(final TType estimate, final CompilationUnitRewrite rewrite, final ASTNode node, final TextEditGroup group) { 962 rewrite.getImportRemover().registerRemovedNode(node); 963 rewrite.getASTRewrite().replace(node, createCorrespondingNode(rewrite, estimate), group); 964 } 965 966 989 protected abstract void rewriteTypeOccurrences(TextEditBasedChangeManager manager, ASTRequestor requestor, CompilationUnitRewrite rewrite, ICompilationUnit unit, CompilationUnit node, Set replacements, IProgressMonitor monitor) throws CoreException; 990 991 1014 protected final void rewriteTypeOccurrences(final TextEditBasedChangeManager manager, final ASTRequestor sourceRequestor, final CompilationUnitRewrite sourceRewrite, final ICompilationUnit subUnit, final CompilationUnit subNode, final Set replacements, final RefactoringStatus status, final IProgressMonitor monitor) { 1015 try { 1016 monitor.beginTask("", 300); monitor.setTaskName(RefactoringCoreMessages.ExtractInterfaceProcessor_creating); 1018 if (fTypeOccurrences != null) { 1019 final Set units= new HashSet (fTypeOccurrences.keySet()); 1020 if (subUnit != null) 1021 units.remove(subUnit); 1022 final Map projects= new HashMap (); 1023 Collection collection= null; 1024 IJavaProject project= null; 1025 ICompilationUnit current= null; 1026 for (final Iterator iterator= units.iterator(); iterator.hasNext();) { 1027 current= (ICompilationUnit) iterator.next(); 1028 project= current.getJavaProject(); 1029 collection= (Collection ) projects.get(project); 1030 if (collection == null) { 1031 collection= new ArrayList (); 1032 projects.put(project, collection); 1033 } 1034 collection.add(current); 1035 } 1036 final ASTParser parser= ASTParser.newParser(AST.JLS3); 1037 final IProgressMonitor subMonitor= new SubProgressMonitor(monitor, 320); 1038 try { 1039 final Set keySet= projects.keySet(); 1040 subMonitor.beginTask("", keySet.size() * 100); subMonitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating); 1042 for (final Iterator iterator= keySet.iterator(); iterator.hasNext();) { 1043 project= (IJavaProject) iterator.next(); 1044 collection= (Collection ) projects.get(project); 1045 parser.setWorkingCopyOwner(fOwner); 1046 parser.setResolveBindings(true); 1047 parser.setProject(project); 1048 parser.setCompilerOptions(RefactoringASTParser.getCompilerOptions(project)); 1049 final IProgressMonitor subsubMonitor= new SubProgressMonitor(subMonitor, 100); 1050 try { 1051 subsubMonitor.beginTask("", collection.size() * 100 + 200); subsubMonitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating); 1053 parser.createASTs((ICompilationUnit[]) collection.toArray(new ICompilationUnit[collection.size()]), new String [0], new ASTRequestor() { 1054 1055 public final void acceptAST(final ICompilationUnit unit, final CompilationUnit node) { 1056 final IProgressMonitor subsubsubMonitor= new SubProgressMonitor(subsubMonitor, 100); 1057 try { 1058 subsubsubMonitor.beginTask("", 100); subsubsubMonitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating); 1060 if (sourceRewrite != null) 1061 rewriteTypeOccurrences(manager, this, sourceRewrite, unit, node, replacements, new SubProgressMonitor(subsubsubMonitor, 100)); 1062 } catch (CoreException exception) { 1063 status.merge(RefactoringStatus.createFatalErrorStatus(exception.getLocalizedMessage())); 1064 } finally { 1065 subsubsubMonitor.done(); 1066 } 1067 } 1068 1069 public final void acceptBinding(final String key, final IBinding binding) { 1070 } 1072 }, new SubProgressMonitor(subsubMonitor, 200)); 1073 } finally { 1074 subsubMonitor.done(); 1075 } 1076 } 1077 try { 1078 if (subUnit != null && subNode != null && sourceRewrite != null && sourceRequestor != null) 1079 rewriteTypeOccurrences(manager, sourceRequestor, sourceRewrite, subUnit, subNode, replacements, new SubProgressMonitor(subMonitor, 20)); 1080 } catch (CoreException exception) { 1081 status.merge(RefactoringStatus.createFatalErrorStatus(exception.getLocalizedMessage())); 1082 } 1083 } finally { 1084 subMonitor.done(); 1085 } 1086 } 1087 } finally { 1088 monitor.done(); 1089 } 1090 } 1091 1092 1095 public final void setComment(final String comment) { 1096 fComment= comment; 1097 } 1098 1099 1106 public final void setInstanceOf(final boolean rewrite) { 1107 fInstanceOf= rewrite; 1108 } 1109 1110 1118 public final void setReplace(final boolean replace) { 1119 fReplace= replace; 1120 } 1121 1122 1142 protected final void solveSuperTypeConstraints(final ICompilationUnit subUnit, final CompilationUnit subNode, final IType subType, final ITypeBinding subBinding, final ITypeBinding superBinding, final IProgressMonitor monitor, final RefactoringStatus status) throws JavaModelException { 1143 Assert.isNotNull(subType); 1144 Assert.isNotNull(subBinding); 1145 Assert.isNotNull(superBinding); 1146 Assert.isNotNull(monitor); 1147 Assert.isNotNull(status); 1148 int level= 3; 1149 TypeEnvironment environment= new TypeEnvironment(); 1150 final SuperTypeConstraintsModel model= new SuperTypeConstraintsModel(environment, environment.create(subBinding), environment.create(superBinding)); 1151 final SuperTypeConstraintsCreator creator= new SuperTypeConstraintsCreator(model, fInstanceOf); 1152 try { 1153 monitor.beginTask("", 300); monitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating); 1155 final Map firstPass= getReferencingCompilationUnits(subType, new SubProgressMonitor(monitor, 100), status); 1156 final Map secondPass= new HashMap (); 1157 IJavaProject project= null; 1158 Collection collection= null; 1159 try { 1160 final ASTParser parser= ASTParser.newParser(AST.JLS3); 1161 Object element= null; 1162 ICompilationUnit current= null; 1163 SearchResultGroup group= null; 1164 SearchMatch[] matches= null; 1165 final Map groups= new HashMap (); 1166 for (final Iterator outer= firstPass.keySet().iterator(); outer.hasNext();) { 1167 project= (IJavaProject) outer.next(); 1168 if (level == 3 && !JavaModelUtil.is50OrHigher(project)) 1169 level= 2; 1170 collection= (Collection ) firstPass.get(project); 1171 if (collection != null) { 1172 for (final Iterator inner= collection.iterator(); inner.hasNext();) { 1173 group= (SearchResultGroup) inner.next(); 1174 matches= group.getSearchResults(); 1175 for (int index= 0; index < matches.length; index++) { 1176 element= matches[index].getElement(); 1177 if (element instanceof IMember) { 1178 current= ((IMember) element).getCompilationUnit(); 1179 if (current != null) 1180 groups.put(current, group); 1181 } 1182 } 1183 } 1184 } 1185 } 1186 Set units= null; 1187 final Set processed= new HashSet (); 1188 if (subUnit != null) 1189 processed.add(subUnit); 1190 model.beginCreation(); 1191 IProgressMonitor subMonitor= new SubProgressMonitor(monitor, 120); 1192 try { 1193 final Set keySet= firstPass.keySet(); 1194 subMonitor.beginTask("", keySet.size() * 100); subMonitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating); 1196 for (final Iterator outer= keySet.iterator(); outer.hasNext();) { 1197 project= (IJavaProject) outer.next(); 1198 collection= (Collection ) firstPass.get(project); 1199 if (collection != null) { 1200 units= new HashSet (collection.size()); 1201 for (final Iterator inner= collection.iterator(); inner.hasNext();) { 1202 group= (SearchResultGroup) inner.next(); 1203 matches= group.getSearchResults(); 1204 for (int index= 0; index < matches.length; index++) { 1205 element= matches[index].getElement(); 1206 if (element instanceof IMember) { 1207 current= ((IMember) element).getCompilationUnit(); 1208 if (current != null) 1209 units.add(current); 1210 } 1211 } 1212 } 1213 final List batches= new ArrayList (units); 1214 final int size= batches.size(); 1215 final int iterations= ((size - 1) / SIZE_BATCH) + 1; 1216 final IProgressMonitor subsubMonitor= new SubProgressMonitor(subMonitor, 100); 1217 try { 1218 subsubMonitor.beginTask("", iterations * 100); subsubMonitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating); 1220 final Map options= RefactoringASTParser.getCompilerOptions(project); 1221 for (int index= 0; index < iterations; index++) { 1222 final List iteration= batches.subList(index * SIZE_BATCH, Math.min(size, (index + 1) * SIZE_BATCH)); 1223 parser.setWorkingCopyOwner(fOwner); 1224 parser.setResolveBindings(true); 1225 parser.setProject(project); 1226 parser.setCompilerOptions(options); 1227 final IProgressMonitor subsubsubMonitor= new SubProgressMonitor(subsubMonitor, 100); 1228 try { 1229 final int count= iteration.size(); 1230 subsubsubMonitor.beginTask("", count * 100); subsubsubMonitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating); 1232 parser.createASTs((ICompilationUnit[]) iteration.toArray(new ICompilationUnit[count]), new String [0], new ASTRequestor() { 1233 1234 public final void acceptAST(final ICompilationUnit unit, final CompilationUnit node) { 1235 if (!processed.contains(unit)) { 1236 performFirstPass(creator, secondPass, groups, unit, node, new SubProgressMonitor(subsubsubMonitor, 100)); 1237 processed.add(unit); 1238 } else 1239 subsubsubMonitor.worked(100); 1240 } 1241 1242 public final void acceptBinding(final String key, final IBinding binding) { 1243 } 1245 }, new NullProgressMonitor()); 1246 } finally { 1247 subsubsubMonitor.done(); 1248 } 1249 } 1250 } finally { 1251 subsubMonitor.done(); 1252 } 1253 } 1254 } 1255 } finally { 1256 firstPass.clear(); 1257 subMonitor.done(); 1258 } 1259 if (subUnit != null && subNode != null) 1260 performFirstPass(creator, secondPass, groups, subUnit, subNode, new SubProgressMonitor(subMonitor, 20)); 1261 subMonitor= new SubProgressMonitor(monitor, 100); 1262 try { 1263 final Set keySet= secondPass.keySet(); 1264 subMonitor.beginTask("", keySet.size() * 100); subMonitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating); 1266 for (final Iterator iterator= keySet.iterator(); iterator.hasNext();) { 1267 project= (IJavaProject) iterator.next(); 1268 if (level == 3 && !JavaModelUtil.is50OrHigher(project)) 1269 level= 2; 1270 collection= (Collection ) secondPass.get(project); 1271 if (collection != null) { 1272 parser.setWorkingCopyOwner(fOwner); 1273 parser.setResolveBindings(true); 1274 parser.setProject(project); 1275 parser.setCompilerOptions(RefactoringASTParser.getCompilerOptions(project)); 1276 final IProgressMonitor subsubMonitor= new SubProgressMonitor(subMonitor, 100); 1277 try { 1278 subsubMonitor.beginTask("", collection.size() * 100); subsubMonitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating); 1280 parser.createASTs((ICompilationUnit[]) collection.toArray(new ICompilationUnit[collection.size()]), new String [0], new ASTRequestor() { 1281 1282 public final void acceptAST(final ICompilationUnit unit, final CompilationUnit node) { 1283 if (!processed.contains(unit)) 1284 performSecondPass(creator, unit, node, new SubProgressMonitor(subsubMonitor, 100)); 1285 else 1286 subsubMonitor.worked(100); 1287 } 1288 1289 public final void acceptBinding(final String key, final IBinding binding) { 1290 } 1292 }, new NullProgressMonitor()); 1293 } finally { 1294 subsubMonitor.done(); 1295 } 1296 } 1297 } 1298 } finally { 1299 secondPass.clear(); 1300 subMonitor.done(); 1301 } 1302 } finally { 1303 model.endCreation(); 1304 model.setCompliance(level); 1305 } 1306 final SuperTypeConstraintsSolver solver= createContraintSolver(model); 1307 solver.solveConstraints(); 1308 fTypeOccurrences= solver.getTypeOccurrences(); 1309 fObsoleteCasts= solver.getObsoleteCasts(); 1310 } finally { 1311 monitor.done(); 1312 } 1313 } 1314} 1315 | Popular Tags |