1 11 package org.eclipse.jdt.internal.corext.refactoring.structure; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.HashMap ; 16 import java.util.HashSet ; 17 import java.util.Iterator ; 18 import java.util.LinkedList ; 19 import java.util.List ; 20 import java.util.Map ; 21 import java.util.Set ; 22 23 import org.eclipse.text.edits.MultiTextEdit; 24 import org.eclipse.text.edits.RangeMarker; 25 import org.eclipse.text.edits.TextEdit; 26 import org.eclipse.text.edits.TextEditGroup; 27 import org.eclipse.text.edits.TextEditProcessor; 28 29 import org.eclipse.core.runtime.Assert; 30 import org.eclipse.core.runtime.CoreException; 31 import org.eclipse.core.runtime.IProgressMonitor; 32 import org.eclipse.core.runtime.IStatus; 33 import org.eclipse.core.runtime.OperationCanceledException; 34 import org.eclipse.core.runtime.Status; 35 import org.eclipse.core.runtime.SubProgressMonitor; 36 37 import org.eclipse.core.resources.IFile; 38 39 import org.eclipse.jface.text.BadLocationException; 40 import org.eclipse.jface.text.Document; 41 import org.eclipse.jface.text.IDocument; 42 import org.eclipse.jface.text.IRegion; 43 import org.eclipse.jface.text.Region; 44 import org.eclipse.jface.text.TextUtilities; 45 46 import org.eclipse.ltk.core.refactoring.Change; 47 import org.eclipse.ltk.core.refactoring.RefactoringDescriptor; 48 import org.eclipse.ltk.core.refactoring.RefactoringStatus; 49 import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry; 50 import org.eclipse.ltk.core.refactoring.TextChange; 51 import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext; 52 import org.eclipse.ltk.core.refactoring.participants.MoveProcessor; 53 import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments; 54 import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant; 55 import org.eclipse.ltk.core.refactoring.participants.SharableParticipants; 56 57 import org.eclipse.jdt.core.Flags; 58 import org.eclipse.jdt.core.ICompilationUnit; 59 import org.eclipse.jdt.core.IField; 60 import org.eclipse.jdt.core.IJavaElement; 61 import org.eclipse.jdt.core.IJavaProject; 62 import org.eclipse.jdt.core.IMethod; 63 import org.eclipse.jdt.core.IType; 64 import org.eclipse.jdt.core.ITypeHierarchy; 65 import org.eclipse.jdt.core.JavaCore; 66 import org.eclipse.jdt.core.JavaModelException; 67 import org.eclipse.jdt.core.dom.AST; 68 import org.eclipse.jdt.core.dom.ASTNode; 69 import org.eclipse.jdt.core.dom.ASTVisitor; 70 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; 71 import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration; 72 import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; 73 import org.eclipse.jdt.core.dom.Assignment; 74 import org.eclipse.jdt.core.dom.Block; 75 import org.eclipse.jdt.core.dom.BodyDeclaration; 76 import org.eclipse.jdt.core.dom.ClassInstanceCreation; 77 import org.eclipse.jdt.core.dom.EnumDeclaration; 78 import org.eclipse.jdt.core.dom.Expression; 79 import org.eclipse.jdt.core.dom.FieldAccess; 80 import org.eclipse.jdt.core.dom.IBinding; 81 import org.eclipse.jdt.core.dom.IMethodBinding; 82 import org.eclipse.jdt.core.dom.ITypeBinding; 83 import org.eclipse.jdt.core.dom.IVariableBinding; 84 import org.eclipse.jdt.core.dom.Javadoc; 85 import org.eclipse.jdt.core.dom.MethodDeclaration; 86 import org.eclipse.jdt.core.dom.MethodInvocation; 87 import org.eclipse.jdt.core.dom.MethodRef; 88 import org.eclipse.jdt.core.dom.MethodRefParameter; 89 import org.eclipse.jdt.core.dom.Modifier; 90 import org.eclipse.jdt.core.dom.Name; 91 import org.eclipse.jdt.core.dom.NullLiteral; 92 import org.eclipse.jdt.core.dom.PostfixExpression; 93 import org.eclipse.jdt.core.dom.PrefixExpression; 94 import org.eclipse.jdt.core.dom.PrimitiveType; 95 import org.eclipse.jdt.core.dom.QualifiedName; 96 import org.eclipse.jdt.core.dom.SimpleName; 97 import org.eclipse.jdt.core.dom.SingleVariableDeclaration; 98 import org.eclipse.jdt.core.dom.SuperFieldAccess; 99 import org.eclipse.jdt.core.dom.SuperMethodInvocation; 100 import org.eclipse.jdt.core.dom.TagElement; 101 import org.eclipse.jdt.core.dom.ThisExpression; 102 import org.eclipse.jdt.core.dom.TypeDeclaration; 103 import org.eclipse.jdt.core.dom.TypeParameter; 104 import org.eclipse.jdt.core.dom.VariableDeclaration; 105 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; 106 import org.eclipse.jdt.core.dom.rewrite.ListRewrite; 107 import org.eclipse.jdt.core.refactoring.IJavaRefactorings; 108 import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor; 109 import org.eclipse.jdt.core.search.IJavaSearchConstants; 110 import org.eclipse.jdt.core.search.SearchMatch; 111 import org.eclipse.jdt.core.search.SearchPattern; 112 113 import org.eclipse.jdt.internal.corext.SourceRange; 114 import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings; 115 import org.eclipse.jdt.internal.corext.codemanipulation.GetterSetterUtil; 116 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility; 117 import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory; 118 import org.eclipse.jdt.internal.corext.dom.ASTNodes; 119 import org.eclipse.jdt.internal.corext.dom.Bindings; 120 import org.eclipse.jdt.internal.corext.dom.ModifierRewrite; 121 import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer; 122 import org.eclipse.jdt.internal.corext.refactoring.Checks; 123 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptor; 124 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment; 125 import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments; 126 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; 127 import org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine2; 128 import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup; 129 import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext; 130 import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange; 131 import org.eclipse.jdt.internal.corext.refactoring.code.ScriptableRefactoring; 132 import org.eclipse.jdt.internal.corext.refactoring.delegates.DelegateMethodCreator; 133 import org.eclipse.jdt.internal.corext.refactoring.structure.MemberVisibilityAdjustor.IVisibilityAdjustment; 134 import org.eclipse.jdt.internal.corext.refactoring.tagging.ICommentProvider; 135 import org.eclipse.jdt.internal.corext.refactoring.tagging.IDelegateUpdating; 136 import org.eclipse.jdt.internal.corext.refactoring.tagging.IScriptableRefactoring; 137 import org.eclipse.jdt.internal.corext.refactoring.util.JavadocUtil; 138 import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil; 139 import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager; 140 import org.eclipse.jdt.internal.corext.util.JavaModelUtil; 141 import org.eclipse.jdt.internal.corext.util.JdtFlags; 142 import org.eclipse.jdt.internal.corext.util.Messages; 143 import org.eclipse.jdt.internal.corext.util.SearchUtils; 144 import org.eclipse.jdt.internal.corext.util.Strings; 145 146 import org.eclipse.jdt.ui.JavaElementLabels; 147 148 import org.eclipse.jdt.internal.ui.JavaPlugin; 149 import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings; 150 import org.eclipse.jdt.internal.ui.viewsupport.BindingLabelProvider; 151 152 155 public final class MoveInstanceMethodProcessor extends MoveProcessor implements IScriptableRefactoring, IDelegateUpdating, ICommentProvider { 156 157 161 public final class AnonymousClassReferenceFinder extends AstNodeFinder { 162 163 164 protected int fAnonymousClass= 0; 165 166 167 protected final ITypeBinding fDeclaringType; 168 169 175 public AnonymousClassReferenceFinder(final MethodDeclaration declaration) { 176 fDeclaringType= declaration.resolveBinding().getDeclaringClass(); 177 } 178 179 public final void endVisit(final AnonymousClassDeclaration node) { 180 Assert.isNotNull(node); 181 if (fAnonymousClass > 0) 182 fAnonymousClass--; 183 super.endVisit(node); 184 } 185 186 public final boolean visit(final AnonymousClassDeclaration node) { 187 Assert.isNotNull(node); 188 fAnonymousClass++; 189 return super.visit(node); 190 } 191 192 public final boolean visit(final MethodInvocation node) { 193 Assert.isNotNull(node); 194 if (fAnonymousClass > 0) { 195 final IMethodBinding binding= node.resolveMethodBinding(); 196 if (binding != null) { 197 if (node.getExpression() == null && !Modifier.isStatic(binding.getModifiers())) 198 fResult.add(node.getName()); 199 } 200 } 201 return true; 202 } 203 204 public boolean visit(final SimpleName node) { 205 Assert.isNotNull(node); 206 if (fAnonymousClass > 0) { 207 if (!(node.getParent() instanceof FieldAccess)) { 208 final IBinding binding= node.resolveBinding(); 209 if (binding instanceof IVariableBinding) { 210 final IVariableBinding variable= (IVariableBinding) binding; 211 final ITypeBinding declaring= variable.getDeclaringClass(); 212 if (declaring != null && Bindings.equals(declaring, fDeclaringType)) 213 fResult.add(node); 214 } 215 } 216 } 217 return false; 218 } 219 } 220 221 224 protected static class AstNodeFinder extends ASTVisitor { 225 226 227 protected final Set fResult= new HashSet (); 228 229 230 protected final RefactoringStatus fStatus= new RefactoringStatus(); 231 232 237 public final Set getResult() { 238 return fResult; 239 } 240 241 246 public final RefactoringStatus getStatus() { 247 return fStatus; 248 } 249 } 250 251 class DelegateInstanceMethodCreator extends DelegateMethodCreator { 252 253 private Map fAdjustments; 254 255 private boolean fNeededInsertion; 256 257 private Map fRewrites; 258 259 public DelegateInstanceMethodCreator(Map adjustments, Map rewrites) { 260 super(); 261 fAdjustments= adjustments; 262 fRewrites= rewrites; 263 } 264 265 protected ASTNode createBody(BodyDeclaration bd) throws JavaModelException { 266 MethodDeclaration methodDeclaration= (MethodDeclaration) bd; 267 final MethodInvocation invocation= getAst().newMethodInvocation(); 268 invocation.setName(getAst().newSimpleName(getNewElementName())); 269 invocation.setExpression(createSimpleTargetAccessExpression(methodDeclaration)); 270 fNeededInsertion= createArgumentList(methodDeclaration, invocation.arguments(), new VisibilityAdjustingArgumentFactory(getAst(), fRewrites, fAdjustments)); 271 final Block block= getAst().newBlock(); 272 block.statements().add(createMethodInvocation(methodDeclaration, invocation)); 273 if (!fSourceRewrite.getCu().equals(fTargetType.getCompilationUnit())) 274 fSourceRewrite.getImportRemover().registerRemovedNode(methodDeclaration.getBody()); 275 return block; 276 } 277 278 protected ASTNode createDocReference(final BodyDeclaration declaration) throws JavaModelException { 279 return MoveInstanceMethodProcessor.this.createMethodReference((MethodDeclaration) declaration, getAst()); 280 } 281 282 protected boolean getNeededInsertion() { 283 return fNeededInsertion; 284 } 285 } 286 287 290 public final class EnclosingInstanceReferenceFinder extends AstNodeFinder { 291 292 293 private final List fEnclosingTypes= new ArrayList (3); 294 295 301 public EnclosingInstanceReferenceFinder(final ITypeBinding binding) { 302 Assert.isNotNull(binding); 303 ITypeBinding declaring= binding.getDeclaringClass(); 304 while (declaring != null) { 305 fEnclosingTypes.add(declaring); 306 declaring= declaring.getDeclaringClass(); 307 } 308 } 309 310 public final boolean visit(final SimpleName node) { 311 Assert.isNotNull(node); 312 final IBinding binding= node.resolveBinding(); 313 ITypeBinding declaring= null; 314 if (binding instanceof IVariableBinding) { 315 final IVariableBinding variable= (IVariableBinding) binding; 316 if (Flags.isStatic(variable.getModifiers())) 317 return false; 318 declaring= variable.getDeclaringClass(); 319 } else if (binding instanceof IMethodBinding) { 320 final IMethodBinding method= (IMethodBinding) binding; 321 if (Flags.isStatic(method.getModifiers())) 322 return false; 323 declaring= method.getDeclaringClass(); 324 } 325 if (declaring != null) { 326 ITypeBinding enclosing= null; 327 for (final Iterator iterator= fEnclosingTypes.iterator(); iterator.hasNext();) { 328 enclosing= (ITypeBinding) iterator.next(); 329 if (Bindings.equals(enclosing, declaring)) { 330 fStatus.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_refers_enclosing_instances, JavaStatusContext.create(fMethod.getCompilationUnit(), node))); 331 fResult.add(node); 332 break; 333 } 334 } 335 } 336 return false; 337 } 338 339 public final boolean visit(final ThisExpression node) { 340 Assert.isNotNull(node); 341 if (node.getQualifier() != null) { 342 fStatus.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_refers_enclosing_instances, JavaStatusContext.create(fMethod.getCompilationUnit(), node))); 343 fResult.add(node); 344 } 345 return false; 346 } 347 } 348 349 352 public final class GenericReferenceFinder extends AstNodeFinder { 353 354 355 protected final Set fBindings= new HashSet (); 356 357 363 public GenericReferenceFinder(final MethodDeclaration declaration) { 364 Assert.isNotNull(declaration); 365 ITypeBinding binding= null; 366 TypeParameter parameter= null; 367 for (final Iterator iterator= declaration.typeParameters().iterator(); iterator.hasNext();) { 368 parameter= (TypeParameter) iterator.next(); 369 binding= parameter.resolveBinding(); 370 if (binding != null) 371 fBindings.add(binding.getKey()); 372 } 373 } 374 375 378 public final boolean visit(final SimpleName node) { 379 Assert.isNotNull(node); 380 final IBinding binding= node.resolveBinding(); 381 if (binding instanceof ITypeBinding) { 382 final ITypeBinding type= (ITypeBinding) binding; 383 if (!fBindings.contains(type.getKey()) && type.isTypeVariable()) { 384 fResult.add(node); 385 fStatus.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_type_variables, JavaStatusContext.create(fMethod.getCompilationUnit(), node))); 386 return false; 387 } 388 } 389 return true; 390 } 391 } 392 393 396 protected static interface IArgumentFactory { 397 398 410 public ASTNode getArgumentNode(IVariableBinding binding, boolean last) throws JavaModelException; 411 412 419 public ASTNode getTargetNode() throws JavaModelException; 420 } 421 422 425 public final class MethodBodyRewriter extends ASTVisitor { 426 427 428 protected int fAnonymousClass= 0; 429 430 431 protected final MethodDeclaration fDeclaration; 432 433 434 protected final Set fMethodDeclarations= new HashSet (); 435 436 437 protected final ASTRewrite fRewrite; 438 439 440 protected final Set fStaticImports= new HashSet (); 441 442 443 protected final RefactoringStatus fStatus= new RefactoringStatus(); 444 445 446 protected final CompilationUnitRewrite fTargetRewrite; 447 448 458 public MethodBodyRewriter(final CompilationUnitRewrite targetRewrite, final ASTRewrite rewrite, final MethodDeclaration sourceDeclaration) { 459 Assert.isNotNull(targetRewrite); 460 Assert.isNotNull(rewrite); 461 Assert.isNotNull(sourceDeclaration); 462 fTargetRewrite= targetRewrite; 463 fRewrite= rewrite; 464 fDeclaration= sourceDeclaration; 465 fStaticImports.clear(); 466 ImportRewriteUtil.collectImports(fMethod.getJavaProject(), sourceDeclaration, new HashSet (), fStaticImports, false); 467 } 468 469 public final void endVisit(final AnonymousClassDeclaration node) { 470 Assert.isNotNull(node); 471 if (fAnonymousClass > 0) 472 fAnonymousClass--; 473 super.endVisit(node); 474 } 475 476 public final boolean visit(final AnonymousClassDeclaration node) { 477 Assert.isNotNull(node); 478 fAnonymousClass++; 479 return super.visit(node); 480 } 481 482 public final boolean visit(final ClassInstanceCreation node) { 483 Assert.isNotNull(node); 484 if (node.getParent() instanceof ClassInstanceCreation) { 485 final AnonymousClassDeclaration declaration= node.getAnonymousClassDeclaration(); 486 if (declaration != null) 487 visit(declaration); 488 return false; 489 } 490 return super.visit(node); 491 } 492 493 public final boolean visit(final FieldAccess node) { 494 Assert.isNotNull(node); 495 final Expression expression= node.getExpression(); 496 final IVariableBinding variable= node.resolveFieldBinding(); 497 final AST ast= fRewrite.getAST(); 498 if (expression instanceof ThisExpression) { 499 if (Bindings.equals(fTarget, variable)) { 500 if (fAnonymousClass > 0) { 501 final ThisExpression target= ast.newThisExpression(); 502 target.setQualifier(ast.newSimpleName(fTargetType.getElementName())); 503 fRewrite.replace(node, target, null); 504 } else 505 fRewrite.replace(node, ast.newThisExpression(), null); 506 return false; 507 } 508 } 509 if (expression instanceof FieldAccess) { 510 final FieldAccess access= (FieldAccess) expression; 511 final IBinding binding= access.getName().resolveBinding(); 512 if ((access.getExpression() instanceof ThisExpression) && Bindings.equals(fTarget, binding)) { 513 fRewrite.replace(node, ast.newSimpleName(node.getName().getIdentifier()), null); 514 return false; 515 } 516 } else if (expression != null) { 517 final IMethodBinding method= fDeclaration.resolveBinding(); 518 if (variable != null && method != null && !JdtFlags.isStatic(variable) && Bindings.equals(method.getDeclaringClass(), variable.getDeclaringClass())) { 519 fRewrite.replace(expression, ast.newSimpleName(fTargetName), null); 520 return false; 521 } 522 } 523 return true; 524 } 525 526 public final void visit(final List nodes) { 527 Assert.isNotNull(nodes); 528 ASTNode node= null; 529 for (final Iterator iterator= nodes.iterator(); iterator.hasNext();) { 530 node= (ASTNode) iterator.next(); 531 node.accept(this); 532 } 533 } 534 535 public final boolean visit(final MethodInvocation node) { 536 Assert.isNotNull(node); 537 final Expression expression= node.getExpression(); 538 final IMethodBinding method= node.resolveMethodBinding(); 539 if (method != null) { 540 final ASTRewrite rewrite= fRewrite; 541 if (expression == null) { 542 final AST ast= node.getAST(); 543 if (!JdtFlags.isStatic(method)) 544 rewrite.set(node, MethodInvocation.EXPRESSION_PROPERTY, ast.newSimpleName(fTargetName), null); 545 else 546 rewrite.set(node, MethodInvocation.EXPRESSION_PROPERTY, ast.newSimpleType(ast.newSimpleName(fMethod.getDeclaringType().getElementName())), null); 547 return true; 548 } else { 549 if (expression instanceof FieldAccess) { 550 final FieldAccess access= (FieldAccess) expression; 551 if (Bindings.equals(access.resolveFieldBinding(), fTarget)) { 552 rewrite.remove(expression, null); 553 visit(node.arguments()); 554 return false; 555 } 556 } else if (expression instanceof Name) { 557 final Name name= (Name) expression; 558 if (Bindings.equals(name.resolveBinding(), fTarget)) { 559 rewrite.remove(expression, null); 560 visit(node.arguments()); 561 return false; 562 } 563 } 564 } 565 } 566 return true; 567 } 568 569 public final boolean visit(final QualifiedName node) { 570 Assert.isNotNull(node); 571 IBinding binding= node.resolveBinding(); 572 if (binding instanceof ITypeBinding) { 573 final ITypeBinding type= (ITypeBinding) binding; 574 if (type.isClass() && type.getDeclaringClass() != null) { 575 final String name= fTargetRewrite.getImportRewrite().addImport(type); 576 if (name != null && name.length() > 0) { 577 fRewrite.replace(node, ASTNodeFactory.newName(node.getAST(), name), null); 578 return false; 579 } 580 } 581 } 582 binding= node.getQualifier().resolveBinding(); 583 if (Bindings.equals(binding, fTarget)) { 584 fRewrite.replace(node, fRewrite.createCopyTarget(node.getName()), null); 585 return false; 586 } 587 return true; 588 } 589 590 public final boolean visit(final SimpleName node) { 591 Assert.isNotNull(node); 592 final AST ast= node.getAST(); 593 final ASTRewrite rewrite= fRewrite; 594 final IBinding binding= node.resolveBinding(); 595 if (binding instanceof ITypeBinding) { 596 final ITypeBinding type= (ITypeBinding) binding; 597 if (type.isClass() && type.getDeclaringClass() != null) { 598 final String name= fTargetRewrite.getImportRewrite().addImport(type); 599 if (name != null && name.length() > 0) { 600 fRewrite.replace(node, ASTNodeFactory.newName(ast, name), null); 601 return false; 602 } 603 } 604 } 605 if (Bindings.equals(binding, fTarget)) 606 if (fAnonymousClass > 0) { 607 final ThisExpression target= ast.newThisExpression(); 608 target.setQualifier(ast.newSimpleName(fTargetType.getElementName())); 609 fRewrite.replace(node, target, null); 610 } else 611 rewrite.replace(node, ast.newThisExpression(), null); 612 else if (binding instanceof IVariableBinding) { 613 final IVariableBinding variable= (IVariableBinding) binding; 614 final IMethodBinding method= fDeclaration.resolveBinding(); 615 final ITypeBinding declaring= variable.getDeclaringClass(); 616 if (method != null) { 617 if (Bindings.equals(method.getDeclaringClass(), declaring)) { 618 if (JdtFlags.isStatic(variable)) 619 rewrite.replace(node, ast.newQualifiedName(ASTNodeFactory.newName(ast, fTargetRewrite.getImportRewrite().addImport(declaring)), ast.newSimpleName(node.getFullyQualifiedName())), null); 620 else { 621 final FieldAccess access= ast.newFieldAccess(); 622 access.setExpression(ast.newSimpleName(fTargetName)); 623 access.setName(ast.newSimpleName(node.getFullyQualifiedName())); 624 rewrite.replace(node, access, null); 625 } 626 } else if (!(node.getParent() instanceof QualifiedName) && JdtFlags.isStatic(variable) && !fStaticImports.contains(variable)) { 627 rewrite.replace(node, ast.newQualifiedName(ASTNodeFactory.newName(ast, fTargetRewrite.getImportRewrite().addImport(declaring)), ast.newSimpleName(node.getFullyQualifiedName())), null); 628 } 629 } 630 } 631 return false; 632 } 633 634 public final boolean visit(final ThisExpression node) { 635 Assert.isNotNull(node); 636 fRewrite.replace(node, node.getAST().newSimpleName(fTargetName), null); 637 return false; 638 } 639 } 640 641 644 public static class ReadyOnlyFieldFinder extends ASTVisitor { 645 646 654 protected static IVariableBinding getFieldBinding(final Expression expression) { 655 Assert.isNotNull(expression); 656 if (expression instanceof FieldAccess) 657 return (IVariableBinding) ((FieldAccess) expression).getName().resolveBinding(); 658 if (expression instanceof Name) { 659 final IBinding binding= ((Name) expression).resolveBinding(); 660 if (binding instanceof IVariableBinding) { 661 final IVariableBinding variable= (IVariableBinding) binding; 662 if (variable.isField()) 663 return variable; 664 } 665 } 666 return null; 667 } 668 669 678 protected static boolean isQualifiedEntity(final Name name) { 679 Assert.isNotNull(name); 680 final ASTNode parent= name.getParent(); 681 if ((parent instanceof QualifiedName && ((QualifiedName) parent).getName().equals(name)) || (parent instanceof FieldAccess && ((FieldAccess) parent).getName().equals(name)) || (parent instanceof SuperFieldAccess)) 682 return true; 683 else if (parent instanceof MethodInvocation) { 684 final MethodInvocation invocation= (MethodInvocation) parent; 685 return invocation.getExpression() != null && invocation.getName().equals(name); 686 } 687 return false; 688 } 689 690 691 protected final List fBindings= new LinkedList (); 692 693 694 protected final Set fFound= new HashSet (); 695 696 697 protected final Set fWritten= new HashSet (); 698 699 706 public ReadyOnlyFieldFinder(final ITypeBinding binding) { 707 Assert.isNotNull(binding); 708 final IVariableBinding[] bindings= binding.getDeclaredFields(); 709 IVariableBinding variable= null; 710 for (int index= 0; index < bindings.length; index++) { 711 variable= bindings[index]; 712 if (!variable.isSynthetic() && !fFound.contains(variable.getKey())) { 713 fFound.add(variable.getKey()); 714 fBindings.add(variable); 715 } 716 } 717 } 718 719 725 public final IVariableBinding[] getDeclaredFields() { 726 final IVariableBinding[] result= new IVariableBinding[fBindings.size()]; 727 fBindings.toArray(result); 728 return result; 729 } 730 731 737 public final IVariableBinding[] getReadOnlyFields() { 738 IVariableBinding binding= null; 739 final List list= new LinkedList (fBindings); 740 for (final Iterator iterator= list.iterator(); iterator.hasNext();) { 741 binding= (IVariableBinding) iterator.next(); 742 if (fWritten.contains(binding.getKey())) 743 iterator.remove(); 744 } 745 final IVariableBinding[] result= new IVariableBinding[list.size()]; 746 list.toArray(result); 747 return result; 748 } 749 750 public final boolean visit(final Assignment node) { 751 Assert.isNotNull(node); 752 final IVariableBinding binding= getFieldBinding(node.getLeftHandSide()); 753 if (binding != null) 754 fWritten.add(binding.getKey()); 755 return true; 756 } 757 758 public final boolean visit(final FieldAccess node) { 759 Assert.isNotNull(node); 760 if (node.getExpression() instanceof ThisExpression) { 761 final IVariableBinding binding= (IVariableBinding) node.getName().resolveBinding(); 762 if (binding != null) { 763 final String key= binding.getKey(); 764 if (!fFound.contains(key)) { 765 fFound.add(key); 766 fBindings.add(binding); 767 } 768 } 769 } 770 return true; 771 } 772 773 public final boolean visit(final PostfixExpression node) { 774 final IVariableBinding binding= getFieldBinding(node.getOperand()); 775 if (binding != null) 776 fWritten.add(binding.getKey()); 777 return true; 778 } 779 780 public final boolean visit(final PrefixExpression node) { 781 final IVariableBinding binding= getFieldBinding(node.getOperand()); 782 if (binding != null) 783 fWritten.add(binding.getKey()); 784 return false; 785 } 786 787 public final boolean visit(final SimpleName node) { 788 Assert.isNotNull(node); 789 final IBinding binding= node.resolveBinding(); 790 if (binding != null) 791 if (isFieldAccess(node) && !isQualifiedEntity(node)) { 792 final IVariableBinding variable= (IVariableBinding) binding; 793 final String key= variable.getKey(); 794 if (!fFound.contains(key)) { 795 fFound.add(key); 796 fBindings.add(variable); 797 } 798 } 799 return false; 800 } 801 } 802 803 806 public final class RecursiveCallFinder extends AstNodeFinder { 807 808 809 protected final IMethodBinding fBinding; 810 811 817 public RecursiveCallFinder(final MethodDeclaration declaration) { 818 Assert.isNotNull(declaration); 819 fBinding= declaration.resolveBinding(); 820 } 821 822 public final boolean visit(final MethodInvocation node) { 823 Assert.isNotNull(node); 824 final Expression expression= node.getExpression(); 825 final IMethodBinding binding= node.resolveMethodBinding(); 826 if (binding == null || (!Modifier.isStatic(binding.getModifiers()) && Bindings.equals(binding, fBinding) && (expression == null || expression instanceof ThisExpression))) { 827 fStatus.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_potentially_recursive, JavaStatusContext.create(fMethod.getCompilationUnit(), node))); 828 fResult.add(node); 829 return false; 830 } 831 return true; 832 } 833 } 834 835 838 public final class SuperReferenceFinder extends AstNodeFinder { 839 840 public final boolean visit(final AnnotationTypeDeclaration node) { 841 return false; 842 } 843 844 public final boolean visit(final AnonymousClassDeclaration node) { 845 return false; 846 } 847 848 public final boolean visit(final EnumDeclaration node) { 849 return false; 850 } 851 852 public final boolean visit(final SuperFieldAccess node) { 853 Assert.isNotNull(node); 854 fStatus.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_uses_super, JavaStatusContext.create(fMethod.getCompilationUnit(), node))); 855 fResult.add(node); 856 return false; 857 } 858 859 public final boolean visit(final SuperMethodInvocation node) { 860 Assert.isNotNull(node); 861 fStatus.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_uses_super, JavaStatusContext.create(fMethod.getCompilationUnit(), node))); 862 fResult.add(node); 863 return false; 864 } 865 866 public final boolean visit(final TypeDeclaration node) { 867 return false; 868 } 869 } 870 871 874 public final class ThisReferenceFinder extends AstNodeFinder { 875 876 public final boolean visit(final MethodInvocation node) { 877 Assert.isNotNull(node); 878 final IMethodBinding binding= node.resolveMethodBinding(); 879 if (binding != null && !JdtFlags.isStatic(binding) && node.getExpression() == null) { 880 fResult.add(node); 881 fStatus.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_this_reference, JavaStatusContext.create(fMethod.getCompilationUnit(), node))); 882 } 883 return true; 884 } 885 886 public final boolean visit(final SimpleName node) { 887 Assert.isNotNull(node); 888 if (isFieldAccess(node) && !isTargetAccess(node)) { 889 fResult.add(node); 890 fStatus.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_this_reference, JavaStatusContext.create(fMethod.getCompilationUnit(), node))); 891 } 892 return false; 893 } 894 895 public final boolean visit(final ThisExpression node) { 896 Assert.isNotNull(node); 897 fResult.add(node); 898 fStatus.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_this_reference, JavaStatusContext.create(fMethod.getCompilationUnit(), node))); 899 return false; 900 } 901 } 902 903 906 public class VisibilityAdjustingArgumentFactory implements IArgumentFactory { 907 908 909 private final Map fAdjustments; 910 911 912 private final AST fAst; 913 914 915 private final Map fRewrites; 916 917 927 public VisibilityAdjustingArgumentFactory(final AST ast, final Map rewrites, final Map adjustments) { 928 Assert.isNotNull(ast); 929 Assert.isNotNull(rewrites); 930 Assert.isNotNull(adjustments); 931 fAst= ast; 932 fRewrites= rewrites; 933 fAdjustments= adjustments; 934 } 935 936 protected final void adjustTypeVisibility(final ITypeBinding binding) throws JavaModelException { 937 Assert.isNotNull(binding); 938 final IJavaElement element= binding.getJavaElement(); 939 if (element instanceof IType) { 940 final IType type= (IType) element; 941 if (!type.isBinary() && !type.isReadOnly() && !Flags.isPublic(type.getFlags())) { 942 boolean same= false; 943 final CompilationUnitRewrite rewrite= getCompilationUnitRewrite(fRewrites, type.getCompilationUnit()); 944 final AbstractTypeDeclaration declaration= ASTNodeSearchUtil.getAbstractTypeDeclarationNode(type, rewrite.getRoot()); 945 if (declaration != null) { 946 final ITypeBinding declaring= declaration.resolveBinding(); 947 if (declaring != null && Bindings.equals(binding.getPackage(), fTarget.getType().getPackage())) 948 same= true; 949 final Modifier.ModifierKeyword keyword= same ? null : Modifier.ModifierKeyword.PUBLIC_KEYWORD; 950 final String modifier= same ? RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_default : RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_public; 951 if (MemberVisibilityAdjustor.hasLowerVisibility(binding.getModifiers(), same ? Modifier.NONE : (keyword == null ? Modifier.NONE : keyword.toFlagValue())) && MemberVisibilityAdjustor.needsVisibilityAdjustments(type, keyword, fAdjustments)) 952 fAdjustments.put(type, new MemberVisibilityAdjustor.OutgoingMemberVisibilityAdjustment(type, keyword, RefactoringStatus.createWarningStatus(Messages.format(RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_type_warning, new String [] { BindingLabelProvider.getBindingLabel(declaration.resolveBinding(), JavaElementLabels.ALL_FULLY_QUALIFIED), modifier }), JavaStatusContext.create(type.getCompilationUnit(), declaration)))); 953 } 954 } 955 } 956 } 957 958 public ASTNode getArgumentNode(final IVariableBinding binding, final boolean last) throws JavaModelException { 959 Assert.isNotNull(binding); 960 adjustTypeVisibility(binding.getType()); 961 return fAst.newSimpleName(binding.getName()); 962 } 963 964 public ASTNode getTargetNode() throws JavaModelException { 965 return fAst.newThisExpression(); 966 } 967 } 968 969 private static final String ATTRIBUTE_DEPRECATE= "deprecate"; 971 private static final String ATTRIBUTE_INLINE= "inline"; 973 private static final String ATTRIBUTE_REMOVE= "remove"; 975 private static final String ATTRIBUTE_TARGET_INDEX= "targetIndex"; 977 private static final String ATTRIBUTE_TARGET_NAME= "targetName"; 979 private static final String ATTRIBUTE_USE_GETTER= "getter"; 981 private static final String ATTRIBUTE_USE_SETTER= "setter"; 983 984 public static final String IDENTIFIER= "org.eclipse.jdt.ui.moveInstanceMethodProcessor"; 986 994 protected static IVariableBinding[] getArgumentBindings(final MethodDeclaration declaration) { 995 Assert.isNotNull(declaration); 996 final List parameters= new ArrayList (declaration.parameters().size()); 997 VariableDeclaration variable= null; 998 IVariableBinding binding= null; 999 for (final Iterator iterator= declaration.parameters().iterator(); iterator.hasNext();) { 1000 variable= (VariableDeclaration) iterator.next(); 1001 binding= variable.resolveBinding(); 1002 if (binding == null) 1003 return new IVariableBinding[0]; 1004 parameters.add(binding); 1005 } 1006 final IVariableBinding[] result= new IVariableBinding[parameters.size()]; 1007 parameters.toArray(result); 1008 return result; 1009 } 1010 1011 1019 protected static ITypeBinding[] getArgumentTypes(final MethodDeclaration declaration) { 1020 Assert.isNotNull(declaration); 1021 final IVariableBinding[] parameters= getArgumentBindings(declaration); 1022 final List types= new ArrayList (parameters.length); 1023 IVariableBinding binding= null; 1024 ITypeBinding type= null; 1025 for (int index= 0; index < parameters.length; index++) { 1026 binding= parameters[index]; 1027 type= binding.getType(); 1028 if (type != null) 1029 types.add(type); 1030 } 1031 final ITypeBinding[] result= new ITypeBinding[types.size()]; 1032 types.toArray(result); 1033 return result; 1034 } 1035 1036 1044 protected static boolean isFieldAccess(final SimpleName name) { 1045 Assert.isNotNull(name); 1046 final IBinding binding= name.resolveBinding(); 1047 if (!(binding instanceof IVariableBinding)) 1048 return false; 1049 final IVariableBinding variable= (IVariableBinding) binding; 1050 if (!variable.isField()) 1051 return false; 1052 if ("length".equals(name.getIdentifier())) { final ASTNode parent= name.getParent(); 1054 if (parent instanceof QualifiedName) { 1055 final QualifiedName qualified= (QualifiedName) parent; 1056 final ITypeBinding type= qualified.getQualifier().resolveTypeBinding(); 1057 if (type != null && type.isArray()) 1058 return false; 1059 } 1060 } 1061 return !Modifier.isStatic(variable.getModifiers()); 1062 } 1063 1064 1065 private IVariableBinding[] fCandidateTargets= new IVariableBinding[0]; 1066 1067 1068 private TextChangeManager fChangeManager= null; 1069 1070 1071 private String fComment; 1072 1073 1074 private boolean fDelegateDeprecation= true; 1075 1076 private boolean fDelegatingUpdating; 1077 1078 1079 private boolean fInline= false; 1080 1081 1082 private IMethod fMethod; 1083 1084 1085 private String fMethodName; 1086 1087 1088 private IVariableBinding[] fPossibleTargets= new IVariableBinding[0]; 1089 1090 1091 private boolean fRemove= false; 1092 1093 1094 private CodeGenerationSettings fSettings; 1095 1096 1097 private CompilationUnitRewrite fSourceRewrite; 1098 1099 1100 private IVariableBinding fTarget= null; 1101 1102 1103 private String fTargetName; 1104 1105 1106 private boolean fTargetNode= true; 1107 1108 1109 private IType fTargetType= null; 1110 1111 1112 private boolean fUseGetters= true; 1113 1114 1115 private boolean fUseSetters= true; 1116 1117 1127 public MoveInstanceMethodProcessor(final IMethod method, final CodeGenerationSettings settings) { 1128 fSettings= settings; 1129 fMethod= method; 1130 if (method != null) 1131 initialize(method); 1132 } 1133 1134 1137 public boolean canEnableComment() { 1138 return true; 1139 } 1140 1141 1144 public final boolean canEnableDelegateUpdating() { 1145 return true; 1146 } 1147 1148 1160 protected void checkConflictingMethod(final IProgressMonitor monitor, final RefactoringStatus status) throws JavaModelException { 1161 Assert.isNotNull(monitor); 1162 Assert.isNotNull(status); 1163 final IMethod[] methods= fTargetType.getMethods(); 1164 try { 1165 monitor.beginTask("", methods.length); monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking); 1167 IMethod method= null; 1168 for (int index= 0; index < methods.length; index++) { 1169 method= methods[index]; 1170 if (method.getElementName().equals(fMethodName) && method.getParameterTypes().length == fMethod.getParameterTypes().length - 1) 1171 status.merge(RefactoringStatus.createErrorStatus(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_method_already_exists, new String [] { fMethodName, fTargetType.getElementName() }), JavaStatusContext.create(method))); 1172 monitor.worked(1); 1173 } 1174 if (fMethodName.equals(fTargetType.getElementName())) 1175 status.merge(RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_method_type_clash, fMethodName), JavaStatusContext.create(fTargetType))); 1176 } finally { 1177 monitor.done(); 1178 } 1179 } 1180 1181 1193 protected void checkConflictingTarget(final IProgressMonitor monitor, final RefactoringStatus status) throws JavaModelException { 1194 Assert.isNotNull(monitor); 1195 Assert.isNotNull(status); 1196 final MethodDeclaration declaration= ASTNodeSearchUtil.getMethodDeclarationNode(fMethod, fSourceRewrite.getRoot()); 1197 VariableDeclaration variable= null; 1198 final List parameters= declaration.parameters(); 1199 try { 1200 monitor.beginTask("", parameters.size()); monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking); 1202 for (final Iterator iterator= parameters.iterator(); iterator.hasNext();) { 1203 variable= (VariableDeclaration) iterator.next(); 1204 if (fTargetName.equals(variable.getName().getIdentifier())) { 1205 status.merge(RefactoringStatus.createErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_target_name_already_used, JavaStatusContext.create(fMethod))); 1206 break; 1207 } 1208 monitor.worked(1); 1209 } 1210 } finally { 1211 monitor.done(); 1212 } 1213 } 1214 1215 1219 public final RefactoringStatus checkFinalConditions(final IProgressMonitor monitor, final CheckConditionsContext context) throws CoreException, OperationCanceledException { 1220 Assert.isNotNull(monitor); 1221 Assert.isNotNull(context); 1222 Assert.isNotNull(fTarget); 1223 final RefactoringStatus status= new RefactoringStatus(); 1224 fChangeManager= new TextChangeManager(); 1225 try { 1226 monitor.beginTask("", 4); monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking); 1228 status.merge(Checks.checkIfCuBroken(fMethod)); 1229 if (!status.hasError()) { 1230 checkGenericTarget(new SubProgressMonitor(monitor, 1), status); 1231 if (status.isOK()) { 1232 final IType type= getTargetType(); 1233 if (type != null) { 1234 if (type.isBinary() || type.isReadOnly() || !fMethod.exists() || fMethod.isBinary() || fMethod.isReadOnly()) 1235 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_binary, JavaStatusContext.create(fMethod))); 1236 else { 1237 status.merge(Checks.checkIfCuBroken(type)); 1238 if (!status.hasError()) { 1239 if (!type.exists() || type.isBinary() || type.isReadOnly()) 1240 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_binary, JavaStatusContext.create(fMethod))); 1241 checkConflictingTarget(new SubProgressMonitor(monitor, 1), status); 1242 checkConflictingMethod(new SubProgressMonitor(monitor, 1), status); 1243 status.merge(Checks.validateModifiesFiles(computeModifiedFiles(fMethod.getCompilationUnit(), type.getCompilationUnit()), null)); 1244 monitor.worked(1); 1245 if (!status.hasFatalError()) 1246 fChangeManager= createChangeManager(status, new SubProgressMonitor(monitor, 1)); 1247 } 1248 } 1249 } else 1250 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_resolved_target, JavaStatusContext.create(fMethod))); 1251 } 1252 } 1253 } finally { 1254 monitor.done(); 1255 } 1256 return status; 1257 } 1258 1259 1267 protected void checkGenericTarget(final IProgressMonitor monitor, final RefactoringStatus status) { 1268 Assert.isNotNull(monitor); 1269 Assert.isNotNull(status); 1270 try { 1271 monitor.beginTask("", 1); monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking); 1273 final ITypeBinding binding= fTarget.getType(); 1274 if (binding == null || binding.isTypeVariable()) 1275 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_generic_targets, JavaStatusContext.create(fMethod))); 1276 } finally { 1277 monitor.done(); 1278 } 1279 } 1280 1281 1292 protected void checkGenericTypes(final IProgressMonitor monitor, final MethodDeclaration declaration, final RefactoringStatus status) { 1293 Assert.isNotNull(monitor); 1294 Assert.isNotNull(declaration); 1295 Assert.isNotNull(status); 1296 try { 1297 monitor.beginTask("", 1); monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking); 1299 final AstNodeFinder finder= new GenericReferenceFinder(declaration); 1300 declaration.accept(finder); 1301 if (!finder.getStatus().isOK()) 1302 status.merge(finder.getStatus()); 1303 } finally { 1304 monitor.done(); 1305 } 1306 } 1307 1308 1311 public final RefactoringStatus checkInitialConditions(final IProgressMonitor monitor) throws CoreException, OperationCanceledException { 1312 Assert.isNotNull(monitor); 1313 final RefactoringStatus status= new RefactoringStatus(); 1314 try { 1315 monitor.beginTask("", 4); monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking); 1317 status.merge(Checks.checkIfCuBroken(fMethod)); 1318 if (!status.hasError()) { 1319 checkMethodDeclaration(new SubProgressMonitor(monitor, 1), status); 1320 if (status.isOK()) { 1321 final MethodDeclaration declaration= ASTNodeSearchUtil.getMethodDeclarationNode(fMethod, fSourceRewrite.getRoot()); 1322 checkGenericTypes(new SubProgressMonitor(monitor, 1), declaration, status); 1323 checkMethodBody(new SubProgressMonitor(monitor, 1), declaration, status); 1324 checkPossibleTargets(new SubProgressMonitor(monitor, 1), declaration, status); 1325 } 1326 } 1327 } finally { 1328 monitor.done(); 1329 } 1330 return status; 1331 } 1332 1333 1344 protected void checkMethodBody(final IProgressMonitor monitor, final MethodDeclaration declaration, final RefactoringStatus status) { 1345 Assert.isNotNull(monitor); 1346 Assert.isNotNull(declaration); 1347 Assert.isNotNull(status); 1348 try { 1349 monitor.beginTask("", 3); monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking); 1351 AstNodeFinder finder= new SuperReferenceFinder(); 1352 declaration.accept(finder); 1353 if (!finder.getStatus().isOK()) 1354 status.merge(finder.getStatus()); 1355 monitor.worked(1); 1356 finder= null; 1357 final IMethodBinding binding= declaration.resolveBinding(); 1358 if (binding != null) { 1359 final ITypeBinding declaring= binding.getDeclaringClass(); 1360 if (declaring != null) 1361 finder= new EnclosingInstanceReferenceFinder(declaring); 1362 } 1363 if (finder != null) { 1364 declaration.accept(finder); 1365 if (!finder.getStatus().isOK()) 1366 status.merge(finder.getStatus()); 1367 monitor.worked(1); 1368 finder= new RecursiveCallFinder(declaration); 1369 declaration.accept(finder); 1370 if (!finder.getStatus().isOK()) 1371 status.merge(finder.getStatus()); 1372 monitor.worked(1); 1373 } 1374 } finally { 1375 monitor.done(); 1376 } 1377 } 1378 1379 1390 protected void checkMethodDeclaration(final IProgressMonitor monitor, final RefactoringStatus status) throws JavaModelException { 1391 Assert.isNotNull(monitor); 1392 Assert.isNotNull(status); 1393 try { 1394 monitor.beginTask("", 5); monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking); 1396 final int flags= fMethod.getFlags(); 1397 if (Flags.isStatic(flags)) 1398 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_static_methods, JavaStatusContext.create(fMethod))); 1399 else if (Flags.isAbstract(flags)) 1400 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_single_implementation, JavaStatusContext.create(fMethod))); 1401 monitor.worked(1); 1402 if (Flags.isNative(flags)) 1403 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_native_methods, JavaStatusContext.create(fMethod))); 1404 monitor.worked(1); 1405 if (Flags.isSynchronized(flags)) 1406 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_synchronized_methods, JavaStatusContext.create(fMethod))); 1407 monitor.worked(1); 1408 if (fMethod.isConstructor()) 1409 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_constructors, JavaStatusContext.create(fMethod))); 1410 monitor.worked(1); 1411 if (fMethod.getDeclaringType().isAnnotation()) 1412 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_annotation, JavaStatusContext.create(fMethod))); 1413 else if (fMethod.getDeclaringType().isInterface()) 1414 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_interface, JavaStatusContext.create(fMethod))); 1415 monitor.worked(1); 1416 } finally { 1417 monitor.done(); 1418 } 1419 } 1420 1421 1431 protected void checkPossibleTargets(final IProgressMonitor monitor, final MethodDeclaration declaration, final RefactoringStatus status) { 1432 Assert.isNotNull(monitor); 1433 Assert.isNotNull(declaration); 1434 Assert.isNotNull(status); 1435 try { 1436 monitor.beginTask("", 1); monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking); 1438 if (computeTargetCategories(declaration).length < 1) 1439 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_cannot_be_moved, JavaStatusContext.create(fMethod))); 1440 } finally { 1441 monitor.done(); 1442 } 1443 } 1444 1445 1456 protected SearchResultGroup[] computeMethodReferences(final IProgressMonitor monitor, final RefactoringStatus status) throws CoreException { 1457 Assert.isNotNull(monitor); 1458 Assert.isNotNull(status); 1459 try { 1460 monitor.beginTask("", 1); monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking); 1462 final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(SearchPattern.createPattern(fMethod, IJavaSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE)); 1463 engine.setStatus(status); 1464 engine.searchPattern(new SubProgressMonitor(monitor, 1)); 1465 return (SearchResultGroup[]) engine.getResults(); 1466 } finally { 1467 monitor.done(); 1468 } 1469 } 1470 1471 1480 protected IFile[] computeModifiedFiles(final ICompilationUnit source, final ICompilationUnit target) { 1481 Assert.isNotNull(source); 1482 Assert.isNotNull(target); 1483 if (source.equals(target)) 1484 return ResourceUtil.getFiles(new ICompilationUnit[] { source }); 1485 return ResourceUtil.getFiles(new ICompilationUnit[] { source, target }); 1486 } 1487 1488 1495 protected String [] computeReservedIdentifiers() throws JavaModelException { 1496 final List names= new ArrayList (); 1497 final MethodDeclaration declaration= ASTNodeSearchUtil.getMethodDeclarationNode(fMethod, fSourceRewrite.getRoot()); 1498 if (declaration != null) { 1499 final List parameters= declaration.parameters(); 1500 VariableDeclaration variable= null; 1501 for (int index= 0; index < parameters.size(); index++) { 1502 variable= (VariableDeclaration) parameters.get(index); 1503 names.add(variable.getName().getIdentifier()); 1504 } 1505 final Block body= declaration.getBody(); 1506 if (body != null) { 1507 final IBinding[] bindings= new ScopeAnalyzer(fSourceRewrite.getRoot()).getDeclarationsAfter(body.getStartPosition(), ScopeAnalyzer.VARIABLES); 1508 for (int index= 0; index < bindings.length; index++) 1509 names.add(bindings[index].getName()); 1510 } 1511 } 1512 final String [] result= new String [names.size()]; 1513 names.toArray(result); 1514 return result; 1515 } 1516 1517 1525 protected IVariableBinding[] computeTargetCategories(final MethodDeclaration declaration) { 1526 Assert.isNotNull(declaration); 1527 if (fPossibleTargets.length == 0 || fCandidateTargets.length == 0) { 1528 final List possibleTargets= new ArrayList (16); 1529 final List candidateTargets= new ArrayList (16); 1530 final IMethodBinding method= declaration.resolveBinding(); 1531 if (method != null) { 1532 final ITypeBinding declaring= method.getDeclaringClass(); 1533 IVariableBinding[] bindings= getArgumentBindings(declaration); 1534 ITypeBinding binding= null; 1535 for (int index= 0; index < bindings.length; index++) { 1536 binding= bindings[index].getType(); 1537 if ((binding.isClass() || binding.isEnum()) && binding.isFromSource()) { 1538 possibleTargets.add(bindings[index]); 1539 candidateTargets.add(bindings[index]); 1540 } 1541 } 1542 final ReadyOnlyFieldFinder visitor= new ReadyOnlyFieldFinder(declaring); 1543 declaration.accept(visitor); 1544 bindings= visitor.getReadOnlyFields(); 1545 for (int index= 0; index < bindings.length; index++) { 1546 binding= bindings[index].getType(); 1547 if (binding.isClass() && binding.isFromSource()) 1548 possibleTargets.add(bindings[index]); 1549 } 1550 bindings= visitor.getDeclaredFields(); 1551 for (int index= 0; index < bindings.length; index++) { 1552 binding= bindings[index].getType(); 1553 if (binding.isClass() && binding.isFromSource()) 1554 candidateTargets.add(bindings[index]); 1555 } 1556 } 1557 fPossibleTargets= new IVariableBinding[possibleTargets.size()]; 1558 possibleTargets.toArray(fPossibleTargets); 1559 fCandidateTargets= new IVariableBinding[candidateTargets.size()]; 1560 candidateTargets.toArray(fCandidateTargets); 1561 } 1562 return fPossibleTargets; 1563 } 1564 1565 1582 protected Expression createAdjustedTargetExpression(final IJavaElement enclosingElement, final Expression expression, final Map adjustments, final ASTRewrite rewrite) throws JavaModelException { 1583 Assert.isNotNull(enclosingElement); 1584 Assert.isNotNull(adjustments); 1585 Assert.isNotNull(rewrite); 1586 final IJavaElement element= fTarget.getJavaElement(); 1587 if (element != null && !Modifier.isPublic(fTarget.getModifiers())) { 1588 final IField field= (IField) fTarget.getJavaElement(); 1589 if (field != null) { 1590 boolean same= field.getAncestor(IJavaElement.PACKAGE_FRAGMENT).equals(enclosingElement.getAncestor(IJavaElement.PACKAGE_FRAGMENT)); 1591 final Modifier.ModifierKeyword keyword= same ? null : Modifier.ModifierKeyword.PUBLIC_KEYWORD; 1592 final String modifier= same ? RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_default : RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_public; 1593 if (fUseGetters) { 1594 final IMethod getter= GetterSetterUtil.getGetter(field); 1595 if (getter != null) { 1596 final MethodDeclaration method= ASTNodeSearchUtil.getMethodDeclarationNode(getter, fSourceRewrite.getRoot()); 1597 if (method != null) { 1598 final IMethodBinding binding= method.resolveBinding(); 1599 if (binding != null && MemberVisibilityAdjustor.hasLowerVisibility(getter.getFlags(), same ? Modifier.NONE : (keyword == null ? Modifier.NONE : keyword.toFlagValue())) && MemberVisibilityAdjustor.needsVisibilityAdjustments(getter, keyword, adjustments)) 1600 adjustments.put(getter, new MemberVisibilityAdjustor.OutgoingMemberVisibilityAdjustment(getter, keyword, RefactoringStatus.createWarningStatus(Messages.format(RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_method_warning, new String [] { BindingLabelProvider.getBindingLabel(binding, JavaElementLabels.ALL_FULLY_QUALIFIED), modifier }), JavaStatusContext.create(getter)))); 1601 final MethodInvocation invocation= rewrite.getAST().newMethodInvocation(); 1602 invocation.setExpression(expression); 1603 invocation.setName(rewrite.getAST().newSimpleName(getter.getElementName())); 1604 return invocation; 1605 } 1606 } 1607 } 1608 if (MemberVisibilityAdjustor.hasLowerVisibility(field.getFlags(), (keyword == null ? Modifier.NONE : keyword.toFlagValue())) && MemberVisibilityAdjustor.needsVisibilityAdjustments(field, keyword, adjustments)) 1609 adjustments.put(field, new MemberVisibilityAdjustor.OutgoingMemberVisibilityAdjustment(field, keyword, RefactoringStatus.createWarningStatus(Messages.format(RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_field_warning, new String [] { BindingLabelProvider.getBindingLabel(fTarget, JavaElementLabels.ALL_FULLY_QUALIFIED), modifier }), JavaStatusContext.create(field)))); 1610 } 1611 } 1612 return null; 1613 } 1614 1615 1629 protected boolean createArgumentList(final MethodDeclaration declaration, final List arguments, final IArgumentFactory factory) throws JavaModelException { 1630 Assert.isNotNull(declaration); 1631 Assert.isNotNull(arguments); 1632 Assert.isNotNull(factory); 1633 final AstNodeFinder finder= new ThisReferenceFinder(); 1634 declaration.accept(finder); 1635 IVariableBinding binding= null; 1636 VariableDeclaration variable= null; 1637 boolean added= false; 1638 final int size= declaration.parameters().size(); 1639 for (int index= 0; index < size; index++) { 1640 variable= (VariableDeclaration) declaration.parameters().get(index); 1641 binding= variable.resolveBinding(); 1642 if (binding != null) { 1643 if (!Bindings.equals(binding, fTarget)) 1644 arguments.add(factory.getArgumentNode(binding, index == size - 1)); 1645 else if (!finder.getStatus().isOK()) { 1646 arguments.add(factory.getTargetNode()); 1647 added= true; 1648 } 1649 } else 1650 arguments.add(factory.getArgumentNode(binding, index == size - 1)); 1651 } 1652 if (!finder.getStatus().isOK() && !added) { 1653 arguments.add(0, factory.getTargetNode()); 1654 added= true; 1655 } 1656 return added; 1657 } 1658 1659 1662 public final Change createChange(final IProgressMonitor monitor) throws CoreException, OperationCanceledException { 1663 Assert.isNotNull(monitor); 1664 try { 1665 monitor.beginTask("", 6); monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_creating); 1667 final TextChange[] changes= fChangeManager.getAllChanges(); 1668 if (changes.length == 1) 1669 return changes[0]; 1670 final List list= new ArrayList (changes.length); 1671 list.addAll(Arrays.asList(changes)); 1672 final Map arguments= new HashMap (); 1673 String project= null; 1674 final IJavaProject javaProject= fMethod.getJavaProject(); 1675 if (javaProject != null) 1676 project= javaProject.getElementName(); 1677 int flags= JavaRefactoringDescriptor.JAR_REFACTORING | JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT | RefactoringDescriptor.STRUCTURAL_CHANGE | RefactoringDescriptor.MULTI_CHANGE; 1678 final IType declaring= fMethod.getDeclaringType(); 1679 try { 1680 if (declaring.isAnonymous() || declaring.isLocal()) 1681 flags|= JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT; 1682 } catch (JavaModelException exception) { 1683 JavaPlugin.log(exception); 1684 } 1685 final String description= Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_descriptor_description_short, fMethod.getElementName()); 1686 final String header= Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_descriptor_description, new String [] { JavaElementLabels.getElementLabel(fMethod, JavaElementLabels.ALL_FULLY_QUALIFIED), BindingLabelProvider.getBindingLabel(fTarget, JavaElementLabels.ALL_FULLY_QUALIFIED) }); 1687 final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(project, this, header); 1688 comment.addSetting(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_moved_element_pattern, RefactoringCoreMessages.JavaRefactoringDescriptor_not_available)); 1689 comment.addSetting(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_target_element_pattern, BindingLabelProvider.getBindingLabel(fTarget, JavaElementLabels.ALL_FULLY_QUALIFIED))); 1690 comment.addSetting(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_method_name_pattern, getMethodName())); 1691 if (needsTargetNode()) 1692 comment.addSetting(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_parameter_name_pattern, getTargetName())); 1693 final JDTRefactoringDescriptor descriptor= new JDTRefactoringDescriptor(IJavaRefactorings.MOVE_METHOD, project, description, comment.asString(), arguments, flags); 1694 arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_INPUT, descriptor.elementToHandle(fMethod)); 1695 arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_NAME, fMethodName); 1696 arguments.put(ATTRIBUTE_TARGET_NAME, fTargetName); 1697 arguments.put(ATTRIBUTE_DEPRECATE, Boolean.valueOf(fDelegateDeprecation).toString()); 1698 arguments.put(ATTRIBUTE_REMOVE, Boolean.valueOf(fRemove).toString()); 1699 arguments.put(ATTRIBUTE_INLINE, Boolean.valueOf(fInline).toString()); 1700 arguments.put(ATTRIBUTE_USE_GETTER, Boolean.valueOf(fUseGetters).toString()); 1701 arguments.put(ATTRIBUTE_USE_SETTER, Boolean.valueOf(fUseSetters).toString()); 1702 arguments.put(ATTRIBUTE_TARGET_INDEX, new Integer (getTargetIndex()).toString()); 1703 return new DynamicValidationRefactoringChange(descriptor, RefactoringCoreMessages.MoveInstanceMethodRefactoring_name, (Change[]) list.toArray(new Change[list.size()])); 1704 } finally { 1705 monitor.done(); 1706 } 1707 } 1708 1709 1722 protected TextChangeManager createChangeManager(final RefactoringStatus status, final IProgressMonitor monitor) throws JavaModelException, CoreException { 1723 Assert.isNotNull(status); 1724 Assert.isNotNull(monitor); 1725 try { 1726 monitor.beginTask("", 7); monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_creating); 1728 fSourceRewrite.clearASTAndImportRewrites(); 1729 final TextChangeManager manager= new TextChangeManager(); 1730 final CompilationUnitRewrite targetRewrite= fMethod.getCompilationUnit().equals(getTargetType().getCompilationUnit()) ? fSourceRewrite : new CompilationUnitRewrite(getTargetType().getCompilationUnit()); 1731 final MethodDeclaration declaration= ASTNodeSearchUtil.getMethodDeclarationNode(fMethod, fSourceRewrite.getRoot()); 1732 final SearchResultGroup[] references= computeMethodReferences(new SubProgressMonitor(monitor, 1), status); 1733 final Map rewrites= new HashMap (2); 1734 rewrites.put(fSourceRewrite.getCu(), fSourceRewrite); 1735 if (!fSourceRewrite.getCu().equals(targetRewrite.getCu())) 1736 rewrites.put(targetRewrite.getCu(), targetRewrite); 1737 final ASTRewrite sourceRewrite= ASTRewrite.create(fSourceRewrite.getRoot().getAST()); 1738 final MemberVisibilityAdjustor adjustor= new MemberVisibilityAdjustor(fTargetType, fMethod); 1739 adjustor.setStatus(status); 1740 adjustor.setVisibilitySeverity(RefactoringStatus.WARNING); 1741 adjustor.setFailureSeverity(RefactoringStatus.WARNING); 1742 adjustor.setRewrites(rewrites); 1743 adjustor.setRewrite(sourceRewrite, fSourceRewrite.getRoot()); 1744 adjustor.adjustVisibility(new SubProgressMonitor(monitor, 1)); 1745 final IDocument document= new Document(fMethod.getCompilationUnit().getBuffer().getContents()); 1746 final boolean target= createMethodCopy(document, declaration, sourceRewrite, rewrites, adjustor.getAdjustments(), status, new SubProgressMonitor(monitor, 1)); 1747 createMethodJavadocReferences(rewrites, declaration, references, target, status, new SubProgressMonitor(monitor, 1)); 1748 if (!fSourceRewrite.getCu().equals(targetRewrite.getCu())) 1749 createMethodImports(targetRewrite, declaration, new SubProgressMonitor(monitor, 1), status); 1750 boolean removable= false; 1751 if (fInline) { 1752 removable= createMethodDelegator(rewrites, declaration, references, adjustor.getAdjustments(), target, status, new SubProgressMonitor(monitor, 1)); 1753 if (fRemove && removable) { 1754 fSourceRewrite.getASTRewrite().remove(declaration, fSourceRewrite.createGroupDescription(RefactoringCoreMessages.MoveInstanceMethodProcessor_remove_original_method)); 1755 if (!fSourceRewrite.getCu().equals(fTargetType.getCompilationUnit())) 1756 fSourceRewrite.getImportRemover().registerRemovedNode(declaration); 1757 } 1758 } 1759 if (!fRemove || !removable) 1760 createMethodDelegation(declaration, rewrites, adjustor.getAdjustments(), status, new SubProgressMonitor(monitor, 1)); 1761 1762 final IJavaElement targetElement= fTarget.getJavaElement(); 1765 if (targetElement != null && targetElement instanceof IField && (Flags.isPrivate(fMethod.getFlags()) || !fInline)) { 1766 final IVisibilityAdjustment adjustmentForTarget= (IVisibilityAdjustment) adjustor.getAdjustments().get(targetElement); 1767 if (adjustmentForTarget != null) 1768 adjustor.getAdjustments().remove(targetElement); 1769 } 1770 1771 adjustor.rewriteVisibility(new SubProgressMonitor(monitor, 1)); 1772 sourceRewrite.rewriteAST(document, fMethod.getJavaProject().getOptions(true)); 1773 createMethodSignature(document, declaration, sourceRewrite, rewrites); 1774 ICompilationUnit unit= null; 1775 CompilationUnitRewrite rewrite= null; 1776 for (final Iterator iterator= rewrites.keySet().iterator(); iterator.hasNext();) { 1777 unit= (ICompilationUnit) iterator.next(); 1778 rewrite= (CompilationUnitRewrite) rewrites.get(unit); 1779 manager.manage(unit, rewrite.createChange()); 1780 } 1781 return manager; 1782 } finally { 1783 monitor.done(); 1784 } 1785 } 1786 1787 1810 protected boolean createInlinedMethodInvocation(final CompilationUnitRewrite rewriter, final MethodDeclaration declaration, final SearchMatch match, final Map adjustments, final boolean target, final RefactoringStatus status) throws JavaModelException { 1811 Assert.isNotNull(rewriter); 1812 Assert.isNotNull(declaration); 1813 Assert.isNotNull(match); 1814 Assert.isNotNull(adjustments); 1815 Assert.isNotNull(status); 1816 boolean result= true; 1817 final ASTRewrite rewrite= rewriter.getASTRewrite(); 1818 final ASTNode node= ASTNodeSearchUtil.findNode(match, rewriter.getRoot()); 1819 final TextEditGroup group= rewriter.createGroupDescription(RefactoringCoreMessages.MoveInstanceMethodProcessor_inline_method_invocation); 1820 if (node instanceof MethodInvocation) { 1821 final MethodInvocation invocation= (MethodInvocation) node; 1822 final ListRewrite list= rewrite.getListRewrite(invocation, MethodInvocation.ARGUMENTS_PROPERTY); 1823 if (fTarget.isField()) { 1824 Expression access= null; 1825 if (invocation.getExpression() != null) { 1826 access= createInlinedTargetExpression(rewriter, (IJavaElement) match.getElement(), invocation.getExpression(), adjustments, status); 1827 rewrite.set(invocation, MethodInvocation.EXPRESSION_PROPERTY, access, group); 1828 } else 1829 rewrite.set(invocation, MethodInvocation.EXPRESSION_PROPERTY, rewrite.getAST().newSimpleName(fTarget.getName()), group); 1830 if (target) { 1831 if (access == null || !(access instanceof FieldAccess)) 1832 list.insertFirst(rewrite.getAST().newThisExpression(), null); 1833 else 1834 list.insertLast(rewrite.createCopyTarget(invocation.getExpression()), null); 1835 } 1836 } else { 1837 final IVariableBinding[] bindings= getArgumentBindings(declaration); 1838 if (bindings.length > 0) { 1839 int index= 0; 1840 for (; index < bindings.length; index++) 1841 if (Bindings.equals(bindings[index], fTarget)) 1842 break; 1843 if (index < bindings.length && invocation.arguments().size() > index) { 1844 final Expression argument= (Expression) invocation.arguments().get(index); 1845 if (argument instanceof NullLiteral) { 1846 status.merge(RefactoringStatus.createErrorStatus(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_null_argument, BindingLabelProvider.getBindingLabel(declaration.resolveBinding(), JavaElementLabels.ALL_FULLY_QUALIFIED)), JavaStatusContext.create(rewriter.getCu(), invocation))); 1847 result= false; 1848 } else { 1849 if (argument instanceof ThisExpression) 1850 rewrite.remove(invocation.getExpression(), null); 1851 else 1852 rewrite.set(invocation, MethodInvocation.EXPRESSION_PROPERTY, rewrite.createCopyTarget(argument), group); 1853 if (target) { 1854 if (invocation.getExpression() != null) 1855 list.replace(argument, rewrite.createCopyTarget(invocation.getExpression()), group); 1856 else { 1857 final ThisExpression expression= rewrite.getAST().newThisExpression(); 1858 final AbstractTypeDeclaration member= (AbstractTypeDeclaration) ASTNodes.getParent(invocation, AbstractTypeDeclaration.class); 1859 if (member != null) { 1860 final ITypeBinding resolved= member.resolveBinding(); 1861 if (ASTNodes.getParent(invocation, AnonymousClassDeclaration.class) != null || (resolved != null && resolved.isMember())) { 1862 final IMethodBinding method= declaration.resolveBinding(); 1863 if (method != null) { 1864 final ITypeBinding declaring= method.getDeclaringClass(); 1865 if (declaring != null) 1866 expression.setQualifier(rewrite.getAST().newSimpleName(declaring.getName())); 1867 } 1868 } 1869 } 1870 list.replace(argument, expression, group); 1871 } 1872 } else 1873 list.remove(argument, group); 1874 } 1875 } 1876 } 1877 } 1878 if (result) 1879 rewrite.set(invocation, MethodInvocation.NAME_PROPERTY, rewrite.getAST().newSimpleName(fMethodName), group); 1880 } 1881 return result; 1882 } 1883 1884 1901 protected Expression createInlinedTargetExpression(final CompilationUnitRewrite rewriter, final IJavaElement enclosingElement, final Expression original, final Map adjustments, final RefactoringStatus status) throws JavaModelException { 1902 Assert.isNotNull(rewriter); 1903 Assert.isNotNull(enclosingElement); 1904 Assert.isNotNull(original); 1905 Assert.isNotNull(adjustments); 1906 Assert.isNotNull(status); 1907 Assert.isTrue(fTarget.isField()); 1908 final Expression expression= (Expression) ASTNode.copySubtree(fSourceRewrite.getASTRewrite().getAST(), original); 1909 final Expression result= createAdjustedTargetExpression(enclosingElement, expression, adjustments, fSourceRewrite.getASTRewrite()); 1910 if (result == null) { 1911 final FieldAccess access= fSourceRewrite.getASTRewrite().getAST().newFieldAccess(); 1912 access.setExpression(expression); 1913 access.setName(fSourceRewrite.getASTRewrite().getAST().newSimpleName(fTarget.getName())); 1914 return access; 1915 } 1916 return result; 1917 } 1918 1919 1937 protected boolean createMethodArguments(final Map rewrites, final ASTRewrite rewrite, final MethodDeclaration declaration, final Map adjustments, final RefactoringStatus status) throws JavaModelException { 1938 Assert.isNotNull(rewrites); 1939 Assert.isNotNull(declaration); 1940 Assert.isNotNull(rewrite); 1941 Assert.isNotNull(adjustments); 1942 Assert.isNotNull(status); 1943 final CompilationUnitRewrite rewriter= getCompilationUnitRewrite(rewrites, getTargetType().getCompilationUnit()); 1944 final AST ast= rewriter.getRoot().getAST(); 1945 final AstNodeFinder finder= new AnonymousClassReferenceFinder(declaration); 1946 declaration.accept(finder); 1947 final List arguments= new ArrayList (declaration.parameters().size() + 1); 1948 final boolean result= createArgumentList(declaration, arguments, new VisibilityAdjustingArgumentFactory(ast, rewrites, adjustments) { 1949 1950 public final ASTNode getArgumentNode(final IVariableBinding binding, final boolean last) throws JavaModelException { 1951 Assert.isNotNull(binding); 1952 final SingleVariableDeclaration variable= ast.newSingleVariableDeclaration(); 1953 final ITypeBinding type= binding.getType(); 1954 adjustTypeVisibility(type); 1955 variable.setName(ast.newSimpleName(binding.getName())); 1956 variable.modifiers().addAll(ast.newModifiers(binding.getModifiers())); 1957 final IMethodBinding method= binding.getDeclaringMethod(); 1958 if (last && method != null && method.isVarargs()) { 1959 variable.setVarargs(true); 1960 String name= null; 1961 if (type.isArray()) { 1962 name= type.getElementType().getName(); 1963 if (PrimitiveType.toCode(name) != null) 1964 variable.setType(ast.newPrimitiveType(PrimitiveType.toCode(name))); 1965 else 1966 variable.setType(ast.newSimpleType(ast.newSimpleName(name))); 1967 } else { 1968 name= type.getName(); 1969 if (PrimitiveType.toCode(name) != null) 1970 variable.setType(ast.newPrimitiveType(PrimitiveType.toCode(name))); 1971 else 1972 variable.setType(ast.newSimpleType(ast.newSimpleName(name))); 1973 } 1974 } else 1975 variable.setType(rewriter.getImportRewrite().addImport(type, ast)); 1976 return variable; 1977 } 1978 1979 public final ASTNode getTargetNode() throws JavaModelException { 1980 final SingleVariableDeclaration variable= ast.newSingleVariableDeclaration(); 1981 final IMethodBinding method= declaration.resolveBinding(); 1982 if (method != null) { 1983 final ITypeBinding declaring= method.getDeclaringClass(); 1984 if (declaring != null) { 1985 adjustTypeVisibility(declaring); 1986 variable.setType(rewriter.getImportRewrite().addImport(declaring, ast)); 1987 variable.setName(ast.newSimpleName(fTargetName)); 1988 if (finder.getResult().size() > 0) 1989 variable.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.FINAL_KEYWORD)); 1990 } 1991 } 1992 return variable; 1993 } 1994 }); 1995 final ListRewrite list= rewrite.getListRewrite(declaration, MethodDeclaration.PARAMETERS_PROPERTY); 1996 ASTNode node= null; 1997 for (final Iterator iterator= declaration.parameters().iterator(); iterator.hasNext();) { 1998 node= (ASTNode) iterator.next(); 1999 list.remove(node, null); 2000 } 2001 for (final Iterator iterator= arguments.iterator(); iterator.hasNext();) { 2002 node= (ASTNode) iterator.next(); 2003 list.insertLast(node, null); 2004 } 2005 return result; 2006 } 2007 2008 2018 protected void createMethodBody(final CompilationUnitRewrite rewriter, final ASTRewrite rewrite, final MethodDeclaration declaration) { 2019 Assert.isNotNull(declaration); 2020 declaration.getBody().accept(new MethodBodyRewriter(rewriter, rewrite, declaration)); 2021 } 2022 2023 2033 protected void createMethodComment(final ASTRewrite rewrite, final MethodDeclaration declaration) throws JavaModelException { 2034 Assert.isNotNull(rewrite); 2035 Assert.isNotNull(declaration); 2036 final Javadoc comment= declaration.getJavadoc(); 2037 if (comment != null) { 2038 final List tags= new LinkedList (comment.tags()); 2039 final IVariableBinding[] bindings= getArgumentBindings(declaration); 2040 final Map elements= new HashMap (bindings.length); 2041 String name= null; 2042 List fragments= null; 2043 TagElement element= null; 2044 TagElement reference= null; 2045 IVariableBinding binding= null; 2046 for (int index= 0; index < bindings.length; index++) { 2047 binding= bindings[index]; 2048 for (final Iterator iterator= comment.tags().iterator(); iterator.hasNext();) { 2049 element= (TagElement) iterator.next(); 2050 name= element.getTagName(); 2051 fragments= element.fragments(); 2052 if (name != null) { 2053 if (name.equals(TagElement.TAG_PARAM) && !fragments.isEmpty() && fragments.get(0) instanceof SimpleName) { 2054 final SimpleName simple= (SimpleName) fragments.get(0); 2055 if (binding.getName().equals(simple.getIdentifier())) { 2056 elements.put(binding.getKey(), element); 2057 tags.remove(element); 2058 } 2059 } else if (reference == null) 2060 reference= element; 2061 } 2062 } 2063 } 2064 if (bindings.length == 0 && reference == null) { 2065 for (final Iterator iterator= comment.tags().iterator(); iterator.hasNext();) { 2066 element= (TagElement) iterator.next(); 2067 name= element.getTagName(); 2068 fragments= element.fragments(); 2069 if (name != null && !name.equals(TagElement.TAG_PARAM)) 2070 reference= element; 2071 } 2072 } 2073 final List arguments= new ArrayList (bindings.length + 1); 2074 createArgumentList(declaration, arguments, new IArgumentFactory() { 2075 2076 public final ASTNode getArgumentNode(final IVariableBinding argument, final boolean last) throws JavaModelException { 2077 Assert.isNotNull(argument); 2078 if (elements.containsKey(argument.getKey())) 2079 return rewrite.createCopyTarget((ASTNode) elements.get(argument.getKey())); 2080 return JavadocUtil.createParamTag(argument.getName(), declaration.getAST(), fMethod.getJavaProject()); 2081 } 2082 2083 public final ASTNode getTargetNode() throws JavaModelException { 2084 return JavadocUtil.createParamTag(fTargetName, declaration.getAST(), fMethod.getJavaProject()); 2085 } 2086 }); 2087 final ListRewrite rewriter= rewrite.getListRewrite(comment, Javadoc.TAGS_PROPERTY); 2088 ASTNode tag= null; 2089 for (final Iterator iterator= comment.tags().iterator(); iterator.hasNext();) { 2090 tag= (ASTNode) iterator.next(); 2091 if (!tags.contains(tag)) 2092 rewriter.remove(tag, null); 2093 } 2094 for (final Iterator iterator= arguments.iterator(); iterator.hasNext();) { 2095 tag= (ASTNode) iterator.next(); 2096 if (reference != null) 2097 rewriter.insertBefore(tag, reference, null); 2098 else 2099 rewriter.insertLast(tag, null); 2100 } 2101 } 2102 } 2103 2104 2117 protected String createMethodContent(final IDocument document, final MethodDeclaration declaration, final ASTRewrite rewrite) throws BadLocationException { 2118 Assert.isNotNull(document); 2119 Assert.isNotNull(declaration); 2120 Assert.isNotNull(rewrite); 2121 final IRegion range= new Region(declaration.getStartPosition(), declaration.getLength()); 2122 final RangeMarker marker= new RangeMarker(range.getOffset(), range.getLength()); 2123 final IJavaProject project= fMethod.getJavaProject(); 2124 final TextEdit[] edits= rewrite.rewriteAST(document, project.getOptions(true)).removeChildren(); 2125 for (int index= 0; index < edits.length; index++) 2126 marker.addChild(edits[index]); 2127 final MultiTextEdit result= new MultiTextEdit(); 2128 result.addChild(marker); 2129 final TextEditProcessor processor= new TextEditProcessor(document, new MultiTextEdit(0, document.getLength()), TextEdit.UPDATE_REGIONS); 2130 processor.getRoot().addChild(result); 2131 processor.performEdits(); 2132 final IRegion region= document.getLineInformation(document.getLineOfOffset(marker.getOffset())); 2133 return Strings.changeIndent(document.get(marker.getOffset(), marker.getLength()), Strings.computeIndentUnits(document.get(region.getOffset(), region.getLength()), project), project, "", TextUtilities.getDefaultLineDelimiter(document)); } 2135 2136 2160 protected boolean createMethodCopy(final IDocument document, final MethodDeclaration declaration, final ASTRewrite rewrite, final Map rewrites, final Map adjustments, final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException { 2161 Assert.isNotNull(document); 2162 Assert.isNotNull(declaration); 2163 Assert.isNotNull(rewrite); 2164 Assert.isNotNull(rewrites); 2165 Assert.isNotNull(adjustments); 2166 Assert.isNotNull(status); 2167 Assert.isNotNull(monitor); 2168 boolean target= false; 2169 final CompilationUnitRewrite rewriter= getCompilationUnitRewrite(rewrites, getTargetType().getCompilationUnit()); 2170 try { 2171 rewrite.set(declaration, MethodDeclaration.NAME_PROPERTY, rewrite.getAST().newSimpleName(fMethodName), null); 2172 boolean same= false; 2173 final IMethodBinding binding= declaration.resolveBinding(); 2174 if (binding != null) { 2175 final ITypeBinding declaring= binding.getDeclaringClass(); 2176 if (declaring != null && Bindings.equals(declaring.getPackage(), fTarget.getType().getPackage())) 2177 same= true; 2178 final Modifier.ModifierKeyword keyword= same ? null : Modifier.ModifierKeyword.PUBLIC_KEYWORD; 2179 if (MemberVisibilityAdjustor.hasLowerVisibility(binding.getModifiers(), same ? Modifier.NONE : (keyword == null ? Modifier.NONE : keyword.toFlagValue())) && MemberVisibilityAdjustor.needsVisibilityAdjustments(fMethod, keyword, adjustments)) { 2180 final MemberVisibilityAdjustor.IncomingMemberVisibilityAdjustment adjustment= new MemberVisibilityAdjustor.IncomingMemberVisibilityAdjustment(fMethod, keyword, RefactoringStatus.createStatus(RefactoringStatus.WARNING, Messages.format(RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_method_warning, new String [] { MemberVisibilityAdjustor.getLabel(fMethod), MemberVisibilityAdjustor.getLabel(keyword) }), JavaStatusContext.create(fMethod), null, RefactoringStatusEntry.NO_CODE, null)); 2181 ModifierRewrite.create(rewrite, declaration).setVisibility(keyword == null ? Modifier.NONE : keyword.toFlagValue(), null); 2182 adjustment.setNeedsRewriting(false); 2183 adjustments.put(fMethod, adjustment); 2184 } 2185 } 2186 target= createMethodArguments(rewrites, rewrite, declaration, adjustments, status); 2187 createMethodTypeParameters(rewrite, declaration, status); 2188 createMethodComment(rewrite, declaration); 2189 createMethodBody(rewriter, rewrite, declaration); 2190 } finally { 2191 if (fMethod.getCompilationUnit().equals(getTargetType().getCompilationUnit())) 2192 rewriter.clearImportRewrites(); 2193 } 2194 return target; 2195 } 2196 2197 2216 protected boolean createMethodDelegation(final MethodDeclaration declaration, final Map rewrites, final Map adjustments, final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException { 2217 Assert.isNotNull(declaration); 2218 Assert.isNotNull(monitor); 2219 2220 final DelegateInstanceMethodCreator creator= new DelegateInstanceMethodCreator(adjustments, rewrites); 2221 creator.setSourceRewrite(fSourceRewrite); 2222 creator.setCopy(false); 2223 creator.setDeclareDeprecated(fDelegateDeprecation); 2224 creator.setDeclaration(declaration); 2225 creator.setNewElementName(fMethodName); 2226 creator.prepareDelegate(); 2227 creator.createEdit(); 2228 2229 return creator.getNeededInsertion(); 2230 } 2231 2232 2256 protected boolean createMethodDelegator(final Map rewrites, final MethodDeclaration declaration, final SearchResultGroup[] groups, final Map adjustments, final boolean target, final RefactoringStatus status, final IProgressMonitor monitor) { 2257 Assert.isNotNull(rewrites); 2258 Assert.isNotNull(declaration); 2259 Assert.isNotNull(groups); 2260 Assert.isNotNull(adjustments); 2261 Assert.isNotNull(status); 2262 Assert.isNotNull(monitor); 2263 try { 2264 monitor.beginTask("", groups.length); monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_creating); 2266 try { 2267 boolean result= true; 2268 boolean found= false; 2269 final ITypeHierarchy hierarchy= fMethod.getDeclaringType().newTypeHierarchy(new SubProgressMonitor(monitor, 1)); 2270 IType type= null; 2271 IMethod method= null; 2272 IType[] types= hierarchy.getAllSubtypes(fMethod.getDeclaringType()); 2273 for (int index= 0; index < types.length && !found; index++) { 2274 type= types[index]; 2275 method= JavaModelUtil.findMethod(fMethod.getElementName(), fMethod.getParameterTypes(), false, type); 2276 if (method != null) 2277 found= true; 2278 } 2279 types= hierarchy.getAllSupertypes(fMethod.getDeclaringType()); 2280 for (int index= 0; index < types.length && !found; index++) { 2281 type= types[index]; 2282 method= JavaModelUtil.findMethod(fMethod.getElementName(), fMethod.getParameterTypes(), false, type); 2283 if (method != null) 2284 found= true; 2285 } 2286 if (found) { 2287 status.merge(RefactoringStatus.createWarningStatus(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_inline_overridden, BindingLabelProvider.getBindingLabel(declaration.resolveBinding(), JavaElementLabels.ALL_FULLY_QUALIFIED)), JavaStatusContext.create(fMethod))); 2288 result= false; 2289 } else { 2290 monitor.worked(1); 2291 SearchMatch[] matches= null; 2292 IJavaElement element= null; 2293 ICompilationUnit unit= null; 2294 CompilationUnitRewrite rewrite= null; 2295 SearchResultGroup group= null; 2296 for (int index= 0; index < groups.length; index++) { 2297 group= groups[index]; 2298 element= JavaCore.create(group.getResource()); 2299 if (element instanceof ICompilationUnit) { 2300 matches= group.getSearchResults(); 2301 unit= (ICompilationUnit) element; 2302 rewrite= getCompilationUnitRewrite(rewrites, unit); 2303 SearchMatch match= null; 2304 for (int offset= 0; offset < matches.length; offset++) { 2305 match= matches[offset]; 2306 if (match.getAccuracy() == SearchMatch.A_INACCURATE) { 2307 status.merge(RefactoringStatus.createWarningStatus(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_inline_inaccurate, unit.getCorrespondingResource().getName()), JavaStatusContext.create(unit, new SourceRange(match.getOffset(), match.getLength())))); 2308 result= false; 2309 } else if (!createInlinedMethodInvocation(rewrite, declaration, match, adjustments, target, status)) 2310 result= false; 2311 } 2312 } else if (element != null) { 2313 status.merge(RefactoringStatus.createWarningStatus(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_inline_binary_project, element.getJavaProject().getElementName()))); 2314 result= false; 2315 } else { 2316 status.merge(RefactoringStatus.createWarningStatus(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_inline_binary_resource, group.getResource().getName()))); 2317 result= false; 2318 } 2319 } 2320 monitor.worked(1); 2321 } 2322 return result; 2323 } catch (CoreException exception) { 2324 status.merge(RefactoringStatus.create(exception.getStatus())); 2325 return false; 2326 } 2327 } finally { 2328 monitor.done(); 2329 } 2330 } 2331 2332 2347 protected void createMethodImports(final CompilationUnitRewrite rewrite, final MethodDeclaration declaration, final IProgressMonitor monitor, final RefactoringStatus status) throws CoreException { 2348 Assert.isNotNull(rewrite); 2349 Assert.isNotNull(declaration); 2350 Assert.isNotNull(monitor); 2351 Assert.isNotNull(status); 2352 monitor.beginTask("", 1); monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_creating); 2354 try { 2355 ImportRewriteUtil.addImports(rewrite, declaration, new HashMap (), new HashMap (), false); 2356 } finally { 2357 monitor.done(); 2358 } 2359 } 2360 2361 2377 protected void createMethodJavadocReference(final CompilationUnitRewrite rewrite, final MethodDeclaration declaration, final SearchMatch match, final boolean targetNode, final RefactoringStatus status) { 2378 Assert.isNotNull(rewrite); 2379 Assert.isNotNull(declaration); 2380 Assert.isNotNull(match); 2381 Assert.isNotNull(status); 2382 final ASTNode node= ASTNodeSearchUtil.findNode(match, rewrite.getRoot()); 2383 if (node instanceof MethodRef) { 2384 final AST ast= node.getAST(); 2385 final MethodRef successor= ast.newMethodRef(); 2386 2387 rewrite.getASTRewrite().replace(node, successor, null); 2388 } 2389 } 2390 2391 2410 protected void createMethodJavadocReferences(final Map rewrites, final MethodDeclaration declaration, final SearchResultGroup[] groups, final boolean target, final RefactoringStatus status, final IProgressMonitor monitor) { 2411 Assert.isNotNull(rewrites); 2412 Assert.isNotNull(declaration); 2413 Assert.isNotNull(status); 2414 Assert.isNotNull(monitor); 2415 try { 2416 monitor.beginTask("", groups.length); monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_creating); 2418 try { 2419 SearchMatch[] matches= null; 2420 IJavaElement element= null; 2421 ICompilationUnit unit= null; 2422 CompilationUnitRewrite rewrite= null; 2423 SearchResultGroup group= null; 2424 for (int index= 0; index < groups.length; index++) { 2425 group= groups[index]; 2426 element= JavaCore.create(group.getResource()); 2427 unit= group.getCompilationUnit(); 2428 if (element instanceof ICompilationUnit) { 2429 matches= group.getSearchResults(); 2430 unit= (ICompilationUnit) element; 2431 rewrite= getCompilationUnitRewrite(rewrites, unit); 2432 SearchMatch match= null; 2433 for (int offset= 0; offset < matches.length; offset++) { 2434 match= matches[offset]; 2435 if (match.getAccuracy() == SearchMatch.A_INACCURATE) { 2436 status.merge(RefactoringStatus.createWarningStatus(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_inline_inaccurate, unit.getCorrespondingResource().getName()), JavaStatusContext.create(unit, new SourceRange(match.getOffset(), match.getLength())))); 2437 } else 2438 createMethodJavadocReference(rewrite, declaration, match, target, status); 2439 } 2440 } else if (element != null) { 2441 status.merge(RefactoringStatus.createWarningStatus(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_javadoc_binary_project, element.getJavaProject().getElementName()))); 2442 } else { 2443 status.merge(RefactoringStatus.createWarningStatus(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_javadoc_binary_resource, group.getResource().getName()))); 2444 } 2445 monitor.worked(1); 2446 } 2447 } catch (CoreException exception) { 2448 status.merge(RefactoringStatus.create(exception.getStatus())); 2449 } 2450 } finally { 2451 monitor.done(); 2452 } 2453 } 2454 2455 2466 protected ASTNode createMethodReference(final MethodDeclaration declaration, final AST ast) throws JavaModelException { 2467 Assert.isNotNull(ast); 2468 Assert.isNotNull(declaration); 2469 final MethodRef reference= ast.newMethodRef(); 2470 reference.setName(ast.newSimpleName(fMethodName)); 2471 reference.setQualifier(ASTNodeFactory.newName(ast, JavaModelUtil.getFullyQualifiedName(fTargetType))); 2472 createArgumentList(declaration, reference.parameters(), new IArgumentFactory() { 2473 2474 public final ASTNode getArgumentNode(final IVariableBinding binding, final boolean last) { 2475 Assert.isNotNull(binding); 2476 final MethodRefParameter parameter= ast.newMethodRefParameter(); 2477 parameter.setType(ASTNodeFactory.newType(ast, binding.getType().getName())); 2478 return parameter; 2479 } 2480 2481 public final ASTNode getTargetNode() { 2482 final MethodRefParameter parameter= ast.newMethodRefParameter(); 2483 final IMethodBinding method= declaration.resolveBinding(); 2484 if (method != null) { 2485 final ITypeBinding declaring= method.getDeclaringClass(); 2486 if (declaring != null) 2487 parameter.setType(ASTNodeFactory.newType(ast, Bindings.getFullyQualifiedName(declaring))); 2488 } 2489 return parameter; 2490 } 2491 }); 2492 return reference; 2493 } 2494 2495 2508 protected void createMethodSignature(final IDocument document, final MethodDeclaration declaration, final ASTRewrite rewrite, final Map rewrites) throws JavaModelException { 2509 Assert.isNotNull(document); 2510 Assert.isNotNull(declaration); 2511 Assert.isNotNull(rewrite); 2512 Assert.isNotNull(rewrites); 2513 try { 2514 final CompilationUnitRewrite rewriter= getCompilationUnitRewrite(rewrites, getTargetType().getCompilationUnit()); 2515 final MethodDeclaration stub= (MethodDeclaration) rewriter.getASTRewrite().createStringPlaceholder(createMethodContent(document, declaration, rewrite), ASTNode.METHOD_DECLARATION); 2516 final AbstractTypeDeclaration type= ASTNodeSearchUtil.getAbstractTypeDeclarationNode(getTargetType(), rewriter.getRoot()); 2517 rewriter.getASTRewrite().getListRewrite(type, type.getBodyDeclarationsProperty()).insertAt(stub, ASTNodes.getInsertionIndex(stub, type.bodyDeclarations()), rewriter.createGroupDescription(RefactoringCoreMessages.MoveInstanceMethodProcessor_add_moved_method)); 2518 } catch (BadLocationException exception) { 2519 JavaPlugin.log(exception); 2520 } 2521 } 2522 2523 2534 protected void createMethodTypeParameters(final ASTRewrite rewrite, final MethodDeclaration declaration, final RefactoringStatus status) { 2535 ITypeBinding binding= fTarget.getType(); 2536 if (binding != null && binding.isParameterizedType()) { 2537 final IMethodBinding method= declaration.resolveBinding(); 2538 if (method != null) { 2539 final ITypeBinding[] parameters= method.getTypeParameters(); 2540 if (parameters.length > 0) { 2541 final ListRewrite rewriter= rewrite.getListRewrite(declaration, MethodDeclaration.TYPE_PARAMETERS_PROPERTY); 2542 boolean foundStatic= false; 2543 while (binding != null && !foundStatic) { 2544 if (Flags.isStatic(binding.getModifiers())) 2545 foundStatic= true; 2546 final ITypeBinding[] bindings= binding.getTypeArguments(); 2547 for (int index= 0; index < bindings.length; index++) { 2548 for (int offset= 0; offset < parameters.length; offset++) { 2549 if (parameters[offset].getName().equals(bindings[index].getName())) { 2550 rewriter.remove((ASTNode) rewriter.getOriginalList().get(offset), null); 2551 status.addWarning(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_present_type_parameter_warning, new Object [] { parameters[offset].getName(), BindingLabelProvider.getBindingLabel(binding, JavaElementLabels.ALL_FULLY_QUALIFIED) }), JavaStatusContext.create(fMethod)); 2552 } 2553 } 2554 } 2555 binding= binding.getDeclaringClass(); 2556 } 2557 } 2558 } 2559 } 2560 } 2561 2562 2569 protected Expression createSimpleTargetAccessExpression(final MethodDeclaration declaration) { 2570 Assert.isNotNull(declaration); 2571 Expression expression= null; 2572 final AST ast= declaration.getAST(); 2573 final ITypeBinding type= fTarget.getDeclaringClass(); 2574 if (type != null) { 2575 boolean shadows= false; 2576 final IVariableBinding[] bindings= getArgumentBindings(declaration); 2577 IVariableBinding variable= null; 2578 for (int index= 0; index < bindings.length; index++) { 2579 variable= bindings[index]; 2580 if (fMethod.getDeclaringType().getField(variable.getName()).exists()) { 2581 shadows= true; 2582 break; 2583 } 2584 } 2585 if (fSettings.useKeywordThis || shadows) { 2586 final FieldAccess access= ast.newFieldAccess(); 2587 access.setName(ast.newSimpleName(fTarget.getName())); 2588 access.setExpression(ast.newThisExpression()); 2589 expression= access; 2590 } else 2591 expression= ast.newSimpleName(fTarget.getName()); 2592 } else 2593 expression= ast.newSimpleName(fTarget.getName()); 2594 return expression; 2595 } 2596 2597 2603 public final IVariableBinding[] getCandidateTargets() { 2604 Assert.isNotNull(fCandidateTargets); 2605 return fCandidateTargets; 2606 } 2607 2608 2611 public String getComment() { 2612 return fComment; 2613 } 2614 2615 2624 protected CompilationUnitRewrite getCompilationUnitRewrite(final Map rewrites, final ICompilationUnit unit) { 2625 Assert.isNotNull(rewrites); 2626 Assert.isNotNull(unit); 2627 CompilationUnitRewrite rewrite= (CompilationUnitRewrite) rewrites.get(unit); 2628 if (rewrite == null) { 2629 rewrite= new CompilationUnitRewrite(unit); 2630 rewrites.put(unit, rewrite); 2631 } 2632 return rewrite; 2633 } 2634 2635 2638 public final boolean getDelegateUpdating() { 2639 return fDelegatingUpdating; 2640 } 2641 2642 2645 public String getDelegateUpdatingTitle(boolean plural) { 2646 if (plural) 2647 return RefactoringCoreMessages.DelegateMethodCreator_keep_original_moved_plural; 2648 else 2649 return RefactoringCoreMessages.DelegateMethodCreator_keep_original_moved_singular; 2650 } 2651 2652 2655 public final boolean getDeprecateDelegates() { 2656 return fDelegateDeprecation; 2657 } 2658 2659 2662 public final Object [] getElements() { 2663 return new Object [] { fMethod }; 2664 } 2665 2666 2669 public final String getIdentifier() { 2670 return IDENTIFIER; 2671 } 2672 2673 2678 public final IMethod getMethod() { 2679 return fMethod; 2680 } 2681 2682 2687 public final String getMethodName() { 2688 return fMethodName; 2689 } 2690 2691 2697 public final IVariableBinding[] getPossibleTargets() { 2698 Assert.isNotNull(fPossibleTargets); 2699 return fPossibleTargets; 2700 } 2701 2702 2705 public final String getProcessorName() { 2706 return RefactoringCoreMessages.MoveInstanceMethodProcessor_name; 2707 } 2708 2709 2714 protected final int getTargetIndex() { 2715 final IVariableBinding[] targets= getPossibleTargets(); 2716 int result= -1; 2717 for (int index= 0; index < targets.length; index++) { 2718 if (Bindings.equals(fTarget, targets[index])) { 2719 result= index; 2720 break; 2721 } 2722 } 2723 return result; 2724 } 2725 2726 2731 public final String getTargetName() { 2732 return fTargetName; 2733 } 2734 2735 2742 protected IType getTargetType() throws JavaModelException { 2743 Assert.isNotNull(fTarget); 2744 if (fTargetType == null) { 2745 final ITypeBinding binding= fTarget.getType(); 2746 if (binding != null) 2747 fTargetType= (IType) binding.getJavaElement(); 2748 else 2749 throw new JavaModelException(new CoreException(new Status(IStatus.ERROR, JavaPlugin.getPluginId(), 0, RefactoringCoreMessages.MoveInstanceMethodProcessor_cannot_be_moved, null))); 2750 } 2751 return fTargetType; 2752 } 2753 2754 2760 protected void initialize(final IMethod method) { 2761 Assert.isNotNull(method); 2762 fSourceRewrite= new CompilationUnitRewrite(fMethod.getCompilationUnit()); 2763 fMethodName= method.getElementName(); 2764 fTargetName= suggestTargetName(); 2765 if (fSettings == null) 2766 fSettings= JavaPreferencesSettings.getCodeGenerationSettings(fMethod.getJavaProject()); 2767 } 2768 2769 2772 public RefactoringStatus initialize(final RefactoringArguments arguments) { 2773 if (arguments instanceof JavaRefactoringArguments) { 2774 final JavaRefactoringArguments extended= (JavaRefactoringArguments) arguments; 2775 final String handle= extended.getAttribute(JDTRefactoringDescriptor.ATTRIBUTE_INPUT); 2776 if (handle != null) { 2777 final IJavaElement element= JDTRefactoringDescriptor.handleToElement(extended.getProject(), handle, false); 2778 if (element == null || !element.exists() || element.getElementType() != IJavaElement.METHOD) 2779 return ScriptableRefactoring.createInputFatalStatus(element, getRefactoring().getName(), IJavaRefactorings.MOVE_METHOD); 2780 else { 2781 fMethod= (IMethod) element; 2782 initialize(fMethod); 2783 } 2784 } else 2785 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JDTRefactoringDescriptor.ATTRIBUTE_INPUT)); 2786 final String name= extended.getAttribute(JDTRefactoringDescriptor.ATTRIBUTE_NAME); 2787 if (name != null) { 2788 final RefactoringStatus status= setMethodName(name); 2789 if (status.hasError()) 2790 return status; 2791 } else 2792 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JDTRefactoringDescriptor.ATTRIBUTE_NAME)); 2793 final String deprecate= extended.getAttribute(ATTRIBUTE_DEPRECATE); 2794 if (deprecate != null) { 2795 fDelegateDeprecation= Boolean.valueOf(deprecate).booleanValue(); 2796 } else 2797 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_DEPRECATE)); 2798 final String remove= extended.getAttribute(ATTRIBUTE_REMOVE); 2799 if (remove != null) { 2800 fRemove= Boolean.valueOf(remove).booleanValue(); 2801 } else 2802 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_REMOVE)); 2803 final String inline= extended.getAttribute(ATTRIBUTE_INLINE); 2804 if (inline != null) { 2805 fInline= Boolean.valueOf(inline).booleanValue(); 2806 } else 2807 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_INLINE)); 2808 final String getter= extended.getAttribute(ATTRIBUTE_USE_GETTER); 2809 if (getter != null) 2810 fUseGetters= Boolean.valueOf(getter).booleanValue(); 2811 else 2812 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_USE_GETTER)); 2813 final String setter= extended.getAttribute(ATTRIBUTE_USE_SETTER); 2814 if (setter != null) 2815 fUseSetters= Boolean.valueOf(setter).booleanValue(); 2816 else 2817 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_USE_SETTER)); 2818 final String target= extended.getAttribute(ATTRIBUTE_TARGET_NAME); 2819 if (target != null) { 2820 final RefactoringStatus status= setTargetName(target); 2821 if (status.hasError()) 2822 return status; 2823 } else 2824 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_TARGET_NAME)); 2825 final String value= extended.getAttribute(ATTRIBUTE_TARGET_INDEX); 2826 if (value != null) { 2827 try { 2828 final int index= Integer.valueOf(value).intValue(); 2829 if (index >= 0) { 2830 final MethodDeclaration declaration= ASTNodeSearchUtil.getMethodDeclarationNode(fMethod, fSourceRewrite.getRoot()); 2831 if (declaration != null) { 2832 final IVariableBinding[] bindings= computeTargetCategories(declaration); 2833 if (bindings != null && index < bindings.length) 2834 setTarget(bindings[index]); 2835 } 2836 } 2837 } catch (NumberFormatException exception) { 2838 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_illegal_argument, new String [] { value, ATTRIBUTE_TARGET_INDEX })); 2839 } catch (JavaModelException exception) { 2840 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_illegal_argument, new String [] { value, ATTRIBUTE_TARGET_INDEX })); 2841 } 2842 } else 2843 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_TARGET_INDEX)); 2844 } else 2845 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.InitializableRefactoring_inacceptable_arguments); 2846 return new RefactoringStatus(); 2847 } 2848 2849 2852 public final boolean isApplicable() throws CoreException { 2853 return fMethod.exists() && !fMethod.isConstructor() && !fMethod.isBinary() && !fMethod.isReadOnly() && fMethod.getCompilationUnit() != null && !JdtFlags.isStatic(fMethod); 2854 } 2855 2856 2864 protected boolean isTargetAccess(final Name name) { 2865 Assert.isNotNull(name); 2866 final IBinding binding= name.resolveBinding(); 2867 if (Bindings.equals(fTarget, binding)) 2868 return true; 2869 if (name.getParent() instanceof FieldAccess) { 2870 final FieldAccess access= (FieldAccess) name.getParent(); 2871 final Expression expression= access.getExpression(); 2872 if (expression instanceof Name) 2873 return isTargetAccess((Name) expression); 2874 } else if (name instanceof QualifiedName) { 2875 final QualifiedName qualified= (QualifiedName) name; 2876 if (qualified.getQualifier() != null) 2877 return isTargetAccess(qualified.getQualifier()); 2878 } 2879 return false; 2880 } 2881 2882 2886 public final RefactoringParticipant[] loadParticipants(final RefactoringStatus status, final SharableParticipants participants) throws CoreException { 2887 return new RefactoringParticipant[0]; 2888 } 2889 2890 2896 public final boolean needsTargetNode() { 2897 return fTargetNode; 2898 } 2899 2900 2903 public void setComment(final String comment) { 2904 fComment= comment; 2905 } 2906 2907 2910 public final void setDelegateUpdating(final boolean updating) { 2911 fDelegatingUpdating= updating; 2912 setInlineDelegator(!updating); 2913 setRemoveDelegator(!updating); 2914 } 2915 2916 2919 public final void setDeprecateDelegates(final boolean deprecate) { 2920 fDelegateDeprecation= deprecate; 2921 } 2922 2923 2930 public final void setInlineDelegator(final boolean inline) { 2931 fInline= inline; 2932 } 2933 2934 2941 public final RefactoringStatus setMethodName(final String name) { 2942 Assert.isNotNull(name); 2943 RefactoringStatus status= Checks.checkMethodName(name); 2944 if (status.hasFatalError()) 2945 return status; 2946 fMethodName= name; 2947 return status; 2948 } 2949 2950 2959 public final void setRemoveDelegator(final boolean remove) { 2960 Assert.isTrue(!remove || fInline); 2961 fRemove= remove; 2962 } 2963 2964 2970 public final void setTarget(final IVariableBinding target) { 2971 Assert.isNotNull(target); 2972 fTarget= target; 2973 fTargetType= null; 2974 try { 2975 final MethodDeclaration declaration= ASTNodeSearchUtil.getMethodDeclarationNode(fMethod, fSourceRewrite.getRoot()); 2976 if (declaration != null) { 2977 final AstNodeFinder finder= new ThisReferenceFinder(); 2978 declaration.accept(finder); 2979 fTargetNode= !finder.getResult().isEmpty(); 2980 return; 2981 } 2982 } catch (JavaModelException exception) { 2983 JavaPlugin.log(exception); 2984 } 2985 fTargetNode= true; 2986 } 2987 2988 2995 public final RefactoringStatus setTargetName(final String name) { 2996 Assert.isNotNull(name); 2997 final RefactoringStatus status= Checks.checkTempName(name); 2998 if (status.hasFatalError()) 2999 return status; 3000 fTargetName= name; 3001 return status; 3002 } 3003 3004 3012 public final void setUseGetters(final boolean use) { 3013 fUseGetters= use; 3014 } 3015 3016 3024 public final void setUseSetters(final boolean use) { 3025 fUseSetters= use; 3026 } 3027 3028 3034 public final boolean shouldUseGetters() { 3035 return fUseGetters; 3036 } 3037 3038 3044 public final boolean shouldUseSetters() { 3045 return fUseSetters; 3046 } 3047 3048 3053 protected String suggestTargetName() { 3054 try { 3055 final String [] candidates= StubUtility.getArgumentNameSuggestions(fMethod.getDeclaringType(), computeReservedIdentifiers()); 3056 if (candidates.length > 0) { 3057 if (candidates[0].indexOf('$') < 0) 3058 return candidates[0]; 3059 } 3060 } catch (JavaModelException exception) { 3061 JavaPlugin.log(exception); 3062 } 3063 return "arg"; } 3065} 3066 | Popular Tags |