Source Code Cross Referenced for MoveInstanceMethodProcessor.java in  » IDE-Eclipse » jdt » org » eclipse » jdt » internal » corext » refactoring » structure » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » jdt » org.eclipse.jdt.internal.corext.refactoring.structure 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Copyright (c) 2000, 2007 IBM Corporation and others.
0003:         * All rights reserved. This program and the accompanying materials
0004:         * are made available under the terms of the Eclipse Public License v1.0
0005:         * which accompanies this distribution, and is available at
0006:         * http://www.eclipse.org/legal/epl-v10.html
0007:         *
0008:         * Contributors:
0009:         *     IBM Corporation - initial API and implementation
0010:         *******************************************************************************/package org.eclipse.jdt.internal.corext.refactoring.structure;
0011:
0012:        import java.util.ArrayList;
0013:        import java.util.Arrays;
0014:        import java.util.HashMap;
0015:        import java.util.HashSet;
0016:        import java.util.Iterator;
0017:        import java.util.LinkedList;
0018:        import java.util.List;
0019:        import java.util.Map;
0020:        import java.util.Set;
0021:
0022:        import org.eclipse.text.edits.MultiTextEdit;
0023:        import org.eclipse.text.edits.RangeMarker;
0024:        import org.eclipse.text.edits.TextEdit;
0025:        import org.eclipse.text.edits.TextEditGroup;
0026:        import org.eclipse.text.edits.TextEditProcessor;
0027:
0028:        import org.eclipse.core.runtime.Assert;
0029:        import org.eclipse.core.runtime.CoreException;
0030:        import org.eclipse.core.runtime.IProgressMonitor;
0031:        import org.eclipse.core.runtime.IStatus;
0032:        import org.eclipse.core.runtime.OperationCanceledException;
0033:        import org.eclipse.core.runtime.Status;
0034:        import org.eclipse.core.runtime.SubProgressMonitor;
0035:
0036:        import org.eclipse.core.resources.IFile;
0037:
0038:        import org.eclipse.jface.text.BadLocationException;
0039:        import org.eclipse.jface.text.Document;
0040:        import org.eclipse.jface.text.IDocument;
0041:        import org.eclipse.jface.text.IRegion;
0042:        import org.eclipse.jface.text.Region;
0043:        import org.eclipse.jface.text.TextUtilities;
0044:
0045:        import org.eclipse.ltk.core.refactoring.Change;
0046:        import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
0047:        import org.eclipse.ltk.core.refactoring.RefactoringStatus;
0048:        import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry;
0049:        import org.eclipse.ltk.core.refactoring.TextChange;
0050:        import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
0051:        import org.eclipse.ltk.core.refactoring.participants.MoveProcessor;
0052:        import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments;
0053:        import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant;
0054:        import org.eclipse.ltk.core.refactoring.participants.SharableParticipants;
0055:
0056:        import org.eclipse.jdt.core.Flags;
0057:        import org.eclipse.jdt.core.ICompilationUnit;
0058:        import org.eclipse.jdt.core.IField;
0059:        import org.eclipse.jdt.core.IJavaElement;
0060:        import org.eclipse.jdt.core.IJavaProject;
0061:        import org.eclipse.jdt.core.IMethod;
0062:        import org.eclipse.jdt.core.IType;
0063:        import org.eclipse.jdt.core.ITypeHierarchy;
0064:        import org.eclipse.jdt.core.JavaCore;
0065:        import org.eclipse.jdt.core.JavaModelException;
0066:        import org.eclipse.jdt.core.dom.AST;
0067:        import org.eclipse.jdt.core.dom.ASTNode;
0068:        import org.eclipse.jdt.core.dom.ASTVisitor;
0069:        import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
0070:        import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
0071:        import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
0072:        import org.eclipse.jdt.core.dom.Assignment;
0073:        import org.eclipse.jdt.core.dom.Block;
0074:        import org.eclipse.jdt.core.dom.BodyDeclaration;
0075:        import org.eclipse.jdt.core.dom.ClassInstanceCreation;
0076:        import org.eclipse.jdt.core.dom.EnumDeclaration;
0077:        import org.eclipse.jdt.core.dom.Expression;
0078:        import org.eclipse.jdt.core.dom.FieldAccess;
0079:        import org.eclipse.jdt.core.dom.IBinding;
0080:        import org.eclipse.jdt.core.dom.IMethodBinding;
0081:        import org.eclipse.jdt.core.dom.ITypeBinding;
0082:        import org.eclipse.jdt.core.dom.IVariableBinding;
0083:        import org.eclipse.jdt.core.dom.Javadoc;
0084:        import org.eclipse.jdt.core.dom.MethodDeclaration;
0085:        import org.eclipse.jdt.core.dom.MethodInvocation;
0086:        import org.eclipse.jdt.core.dom.MethodRef;
0087:        import org.eclipse.jdt.core.dom.MethodRefParameter;
0088:        import org.eclipse.jdt.core.dom.Modifier;
0089:        import org.eclipse.jdt.core.dom.Name;
0090:        import org.eclipse.jdt.core.dom.NullLiteral;
0091:        import org.eclipse.jdt.core.dom.PostfixExpression;
0092:        import org.eclipse.jdt.core.dom.PrefixExpression;
0093:        import org.eclipse.jdt.core.dom.PrimitiveType;
0094:        import org.eclipse.jdt.core.dom.QualifiedName;
0095:        import org.eclipse.jdt.core.dom.SimpleName;
0096:        import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
0097:        import org.eclipse.jdt.core.dom.SuperFieldAccess;
0098:        import org.eclipse.jdt.core.dom.SuperMethodInvocation;
0099:        import org.eclipse.jdt.core.dom.TagElement;
0100:        import org.eclipse.jdt.core.dom.ThisExpression;
0101:        import org.eclipse.jdt.core.dom.TypeDeclaration;
0102:        import org.eclipse.jdt.core.dom.TypeParameter;
0103:        import org.eclipse.jdt.core.dom.VariableDeclaration;
0104:        import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
0105:        import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
0106:        import org.eclipse.jdt.core.refactoring.IJavaRefactorings;
0107:        import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor;
0108:        import org.eclipse.jdt.core.refactoring.descriptors.MoveMethodDescriptor;
0109:        import org.eclipse.jdt.core.search.IJavaSearchConstants;
0110:        import org.eclipse.jdt.core.search.SearchMatch;
0111:        import org.eclipse.jdt.core.search.SearchPattern;
0112:
0113:        import org.eclipse.jdt.internal.corext.SourceRange;
0114:        import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings;
0115:        import org.eclipse.jdt.internal.corext.codemanipulation.GetterSetterUtil;
0116:        import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
0117:        import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
0118:        import org.eclipse.jdt.internal.corext.dom.ASTNodes;
0119:        import org.eclipse.jdt.internal.corext.dom.Bindings;
0120:        import org.eclipse.jdt.internal.corext.dom.ModifierRewrite;
0121:        import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer;
0122:        import org.eclipse.jdt.internal.corext.refactoring.Checks;
0123:        import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment;
0124:        import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments;
0125:        import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringDescriptorUtil;
0126:        import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
0127:        import org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine2;
0128:        import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup;
0129:        import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;
0130:        import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange;
0131:        import org.eclipse.jdt.internal.corext.refactoring.code.ScriptableRefactoring;
0132:        import org.eclipse.jdt.internal.corext.refactoring.delegates.DelegateMethodCreator;
0133:        import org.eclipse.jdt.internal.corext.refactoring.structure.MemberVisibilityAdjustor.IVisibilityAdjustment;
0134:        import org.eclipse.jdt.internal.corext.refactoring.tagging.ICommentProvider;
0135:        import org.eclipse.jdt.internal.corext.refactoring.tagging.IDelegateUpdating;
0136:        import org.eclipse.jdt.internal.corext.refactoring.tagging.IScriptableRefactoring;
0137:        import org.eclipse.jdt.internal.corext.refactoring.util.JavadocUtil;
0138:        import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil;
0139:        import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager;
0140:        import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
0141:        import org.eclipse.jdt.internal.corext.util.JdtFlags;
0142:        import org.eclipse.jdt.internal.corext.util.Messages;
0143:        import org.eclipse.jdt.internal.corext.util.SearchUtils;
0144:        import org.eclipse.jdt.internal.corext.util.Strings;
0145:
0146:        import org.eclipse.jdt.ui.JavaElementLabels;
0147:
0148:        import org.eclipse.jdt.internal.ui.JavaPlugin;
0149:        import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings;
0150:        import org.eclipse.jdt.internal.ui.viewsupport.BindingLabelProvider;
0151:
0152:        /**
0153:         * Refactoring processor to move instance methods.
0154:         */
0155:        public final class MoveInstanceMethodProcessor extends MoveProcessor
0156:                implements  IScriptableRefactoring, IDelegateUpdating,
0157:                ICommentProvider {
0158:
0159:            /**
0160:             * AST visitor to find references to parameters occurring in anonymous
0161:             * classes of a method body.
0162:             */
0163:            public final class AnonymousClassReferenceFinder extends
0164:                    AstNodeFinder {
0165:
0166:                /** The anonymous class nesting counter */
0167:                protected int fAnonymousClass = 0;
0168:
0169:                /** The declaring type of the method declaration */
0170:                protected final ITypeBinding fDeclaringType;
0171:
0172:                /**
0173:                 * Creates a new anonymous class reference finder.
0174:                 * 
0175:                 * @param declaration
0176:                 *            the method declaration to search for references
0177:                 */
0178:                public AnonymousClassReferenceFinder(
0179:                        final MethodDeclaration declaration) {
0180:                    fDeclaringType = declaration.resolveBinding()
0181:                            .getDeclaringClass();
0182:                }
0183:
0184:                public final void endVisit(final AnonymousClassDeclaration node) {
0185:                    Assert.isNotNull(node);
0186:                    if (fAnonymousClass > 0)
0187:                        fAnonymousClass--;
0188:                    super .endVisit(node);
0189:                }
0190:
0191:                public final boolean visit(final AnonymousClassDeclaration node) {
0192:                    Assert.isNotNull(node);
0193:                    fAnonymousClass++;
0194:                    return super .visit(node);
0195:                }
0196:
0197:                public final boolean visit(final MethodInvocation node) {
0198:                    Assert.isNotNull(node);
0199:                    if (fAnonymousClass > 0) {
0200:                        final IMethodBinding binding = node
0201:                                .resolveMethodBinding();
0202:                        if (binding != null) {
0203:                            if (node.getExpression() == null
0204:                                    && !Modifier.isStatic(binding
0205:                                            .getModifiers()))
0206:                                fResult.add(node.getName());
0207:                        }
0208:                    }
0209:                    return true;
0210:                }
0211:
0212:                public boolean visit(final SimpleName node) {
0213:                    Assert.isNotNull(node);
0214:                    if (fAnonymousClass > 0) {
0215:                        if (!(node.getParent() instanceof  FieldAccess)) {
0216:                            final IBinding binding = node.resolveBinding();
0217:                            if (binding instanceof  IVariableBinding) {
0218:                                final IVariableBinding variable = (IVariableBinding) binding;
0219:                                final ITypeBinding declaring = variable
0220:                                        .getDeclaringClass();
0221:                                if (declaring != null
0222:                                        && Bindings.equals(declaring,
0223:                                                fDeclaringType))
0224:                                    fResult.add(node);
0225:                            }
0226:                        }
0227:                    }
0228:                    return false;
0229:                }
0230:            }
0231:
0232:            /**
0233:             * Partial implementation of an ast node finder.
0234:             */
0235:            protected static class AstNodeFinder extends ASTVisitor {
0236:
0237:                /** The found ast nodes */
0238:                protected final Set fResult = new HashSet();
0239:
0240:                /** The status of the find operation */
0241:                protected final RefactoringStatus fStatus = new RefactoringStatus();
0242:
0243:                /**
0244:                 * Returns the result set.
0245:                 * 
0246:                 * @return the result set
0247:                 */
0248:                public final Set getResult() {
0249:                    return fResult;
0250:                }
0251:
0252:                /**
0253:                 * Returns the status of the find operation.
0254:                 * 
0255:                 * @return the status of the operation
0256:                 */
0257:                public final RefactoringStatus getStatus() {
0258:                    return fStatus;
0259:                }
0260:            }
0261:
0262:            class DelegateInstanceMethodCreator extends DelegateMethodCreator {
0263:
0264:                private Map fAdjustments;
0265:
0266:                private boolean fNeededInsertion;
0267:
0268:                private Map fRewrites;
0269:
0270:                public DelegateInstanceMethodCreator(Map adjustments,
0271:                        Map rewrites) {
0272:                    super ();
0273:                    fAdjustments = adjustments;
0274:                    fRewrites = rewrites;
0275:                }
0276:
0277:                protected ASTNode createBody(BodyDeclaration bd)
0278:                        throws JavaModelException {
0279:                    MethodDeclaration methodDeclaration = (MethodDeclaration) bd;
0280:                    final MethodInvocation invocation = getAst()
0281:                            .newMethodInvocation();
0282:                    invocation.setName(getAst().newSimpleName(
0283:                            getNewElementName()));
0284:                    invocation
0285:                            .setExpression(createSimpleTargetAccessExpression(methodDeclaration));
0286:                    fNeededInsertion = createArgumentList(methodDeclaration,
0287:                            invocation.arguments(),
0288:                            new VisibilityAdjustingArgumentFactory(getAst(),
0289:                                    fRewrites, fAdjustments));
0290:                    final Block block = getAst().newBlock();
0291:                    block.statements().add(
0292:                            createMethodInvocation(methodDeclaration,
0293:                                    invocation));
0294:                    if (!fSourceRewrite.getCu().equals(
0295:                            fTargetType.getCompilationUnit()))
0296:                        fSourceRewrite.getImportRemover().registerRemovedNode(
0297:                                methodDeclaration.getBody());
0298:                    return block;
0299:                }
0300:
0301:                protected ASTNode createDocReference(
0302:                        final BodyDeclaration declaration)
0303:                        throws JavaModelException {
0304:                    return MoveInstanceMethodProcessor.this 
0305:                            .createMethodReference(
0306:                                    (MethodDeclaration) declaration, getAst());
0307:                }
0308:
0309:                protected boolean getNeededInsertion() {
0310:                    return fNeededInsertion;
0311:                }
0312:            }
0313:
0314:            /**
0315:             * AST visitor to find 'this' references to enclosing instances.
0316:             */
0317:            public final class EnclosingInstanceReferenceFinder extends
0318:                    AstNodeFinder {
0319:
0320:                /** The list of enclosing types */
0321:                private final List fEnclosingTypes = new ArrayList(3);
0322:
0323:                /**
0324:                 * Creates a new enclosing instance reference finder.
0325:                 * 
0326:                 * @param binding
0327:                 *            the declaring type
0328:                 */
0329:                public EnclosingInstanceReferenceFinder(
0330:                        final ITypeBinding binding) {
0331:                    Assert.isNotNull(binding);
0332:                    ITypeBinding declaring = binding.getDeclaringClass();
0333:                    while (declaring != null) {
0334:                        fEnclosingTypes.add(declaring);
0335:                        declaring = declaring.getDeclaringClass();
0336:                    }
0337:                }
0338:
0339:                public final boolean visit(final SimpleName node) {
0340:                    Assert.isNotNull(node);
0341:                    final IBinding binding = node.resolveBinding();
0342:                    ITypeBinding declaring = null;
0343:                    if (binding instanceof  IVariableBinding) {
0344:                        final IVariableBinding variable = (IVariableBinding) binding;
0345:                        if (Flags.isStatic(variable.getModifiers()))
0346:                            return false;
0347:                        declaring = variable.getDeclaringClass();
0348:                    } else if (binding instanceof  IMethodBinding) {
0349:                        final IMethodBinding method = (IMethodBinding) binding;
0350:                        if (Flags.isStatic(method.getModifiers()))
0351:                            return false;
0352:                        declaring = method.getDeclaringClass();
0353:                    }
0354:                    if (declaring != null) {
0355:                        ITypeBinding enclosing = null;
0356:                        for (final Iterator iterator = fEnclosingTypes
0357:                                .iterator(); iterator.hasNext();) {
0358:                            enclosing = (ITypeBinding) iterator.next();
0359:                            if (Bindings.equals(enclosing, declaring)) {
0360:                                fStatus
0361:                                        .merge(RefactoringStatus
0362:                                                .createFatalErrorStatus(
0363:                                                        RefactoringCoreMessages.MoveInstanceMethodProcessor_refers_enclosing_instances,
0364:                                                        JavaStatusContext
0365:                                                                .create(
0366:                                                                        fMethod
0367:                                                                                .getCompilationUnit(),
0368:                                                                        node)));
0369:                                fResult.add(node);
0370:                                break;
0371:                            }
0372:                        }
0373:                    }
0374:                    return false;
0375:                }
0376:
0377:                public final boolean visit(final ThisExpression node) {
0378:                    Assert.isNotNull(node);
0379:                    if (node.getQualifier() != null) {
0380:                        fStatus
0381:                                .merge(RefactoringStatus
0382:                                        .createFatalErrorStatus(
0383:                                                RefactoringCoreMessages.MoveInstanceMethodProcessor_refers_enclosing_instances,
0384:                                                JavaStatusContext
0385:                                                        .create(
0386:                                                                fMethod
0387:                                                                        .getCompilationUnit(),
0388:                                                                node)));
0389:                        fResult.add(node);
0390:                    }
0391:                    return false;
0392:                }
0393:            }
0394:
0395:            /**
0396:             * AST visitor to find references to type variables or generic types.
0397:             */
0398:            public final class GenericReferenceFinder extends AstNodeFinder {
0399:
0400:                /** The type parameter binding keys */
0401:                protected final Set fBindings = new HashSet();
0402:
0403:                /**
0404:                 * Creates a new generic reference finder.
0405:                 * 
0406:                 * @param declaration
0407:                 *            the method declaration
0408:                 */
0409:                public GenericReferenceFinder(
0410:                        final MethodDeclaration declaration) {
0411:                    Assert.isNotNull(declaration);
0412:                    ITypeBinding binding = null;
0413:                    TypeParameter parameter = null;
0414:                    for (final Iterator iterator = declaration.typeParameters()
0415:                            .iterator(); iterator.hasNext();) {
0416:                        parameter = (TypeParameter) iterator.next();
0417:                        binding = parameter.resolveBinding();
0418:                        if (binding != null)
0419:                            fBindings.add(binding.getKey());
0420:                    }
0421:                }
0422:
0423:                /*
0424:                 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SimpleName)
0425:                 */
0426:                public final boolean visit(final SimpleName node) {
0427:                    Assert.isNotNull(node);
0428:                    final IBinding binding = node.resolveBinding();
0429:                    if (binding instanceof  ITypeBinding) {
0430:                        final ITypeBinding type = (ITypeBinding) binding;
0431:                        if (!fBindings.contains(type.getKey())
0432:                                && type.isTypeVariable()) {
0433:                            fResult.add(node);
0434:                            fStatus
0435:                                    .merge(RefactoringStatus
0436:                                            .createFatalErrorStatus(
0437:                                                    RefactoringCoreMessages.MoveInstanceMethodProcessor_no_type_variables,
0438:                                                    JavaStatusContext
0439:                                                            .create(
0440:                                                                    fMethod
0441:                                                                            .getCompilationUnit(),
0442:                                                                    node)));
0443:                            return false;
0444:                        }
0445:                    }
0446:                    return true;
0447:                }
0448:            }
0449:
0450:            /**
0451:             * Factory for method argument declaration or expression nodes.
0452:             */
0453:            protected static interface IArgumentFactory {
0454:
0455:                /**
0456:                 * Returns a argument node for the specified variable binding.
0457:                 * 
0458:                 * @param binding
0459:                 *            the binding to create a argument node for
0460:                 * @param last
0461:                 *            <code>true</code> if the argument represented by this
0462:                 *            node is the last one in its declaring method
0463:                 * @return the corresponding node
0464:                 * @throws JavaModelException
0465:                 *             if an error occurs
0466:                 */
0467:                public ASTNode getArgumentNode(IVariableBinding binding,
0468:                        boolean last) throws JavaModelException;
0469:
0470:                /**
0471:                 * Returns a target node for the current target.
0472:                 * 
0473:                 * @return the corresponding node
0474:                 * @throws JavaModelException
0475:                 *             if an error occurs
0476:                 */
0477:                public ASTNode getTargetNode() throws JavaModelException;
0478:            }
0479:
0480:            /**
0481:             * AST visitor to rewrite the body of the moved method.
0482:             */
0483:            public final class MethodBodyRewriter extends ASTVisitor {
0484:
0485:                /** The anonymous class nesting counter */
0486:                protected int fAnonymousClass = 0;
0487:
0488:                /** The method declaration to rewrite */
0489:                protected final MethodDeclaration fDeclaration;
0490:
0491:                /** The set of handled method invocations */
0492:                protected final Set fMethodDeclarations = new HashSet();
0493:
0494:                /** The source ast rewrite to use */
0495:                protected final ASTRewrite fRewrite;
0496:
0497:                /** The existing static imports */
0498:                protected final Set fStaticImports = new HashSet();
0499:
0500:                /** The refactoring status */
0501:                protected final RefactoringStatus fStatus = new RefactoringStatus();
0502:
0503:                /** The target compilation unit rewrite to use */
0504:                protected final CompilationUnitRewrite fTargetRewrite;
0505:
0506:                /**
0507:                 * Creates a new method body rewriter.
0508:                 * 
0509:                 * @param targetRewrite
0510:                 *            the target compilation unit rewrite to use
0511:                 * @param rewrite
0512:                 *            the source ast rewrite to use
0513:                 * @param sourceDeclaration
0514:                 *            the source method declaration
0515:                 */
0516:                public MethodBodyRewriter(
0517:                        final CompilationUnitRewrite targetRewrite,
0518:                        final ASTRewrite rewrite,
0519:                        final MethodDeclaration sourceDeclaration) {
0520:                    Assert.isNotNull(targetRewrite);
0521:                    Assert.isNotNull(rewrite);
0522:                    Assert.isNotNull(sourceDeclaration);
0523:                    fTargetRewrite = targetRewrite;
0524:                    fRewrite = rewrite;
0525:                    fDeclaration = sourceDeclaration;
0526:                    fStaticImports.clear();
0527:                    ImportRewriteUtil.collectImports(fMethod.getJavaProject(),
0528:                            sourceDeclaration, new HashSet(), fStaticImports,
0529:                            false);
0530:                }
0531:
0532:                public final void endVisit(final AnonymousClassDeclaration node) {
0533:                    Assert.isNotNull(node);
0534:                    if (fAnonymousClass > 0)
0535:                        fAnonymousClass--;
0536:                    super .endVisit(node);
0537:                }
0538:
0539:                public final boolean visit(final AnonymousClassDeclaration node) {
0540:                    Assert.isNotNull(node);
0541:                    fAnonymousClass++;
0542:                    return super .visit(node);
0543:                }
0544:
0545:                public final boolean visit(final ClassInstanceCreation node) {
0546:                    Assert.isNotNull(node);
0547:                    if (node.getParent() instanceof  ClassInstanceCreation) {
0548:                        final AnonymousClassDeclaration declaration = node
0549:                                .getAnonymousClassDeclaration();
0550:                        if (declaration != null)
0551:                            visit(declaration);
0552:                        return false;
0553:                    }
0554:                    return super .visit(node);
0555:                }
0556:
0557:                public final boolean visit(final FieldAccess node) {
0558:                    Assert.isNotNull(node);
0559:                    final Expression expression = node.getExpression();
0560:                    final IVariableBinding variable = node
0561:                            .resolveFieldBinding();
0562:                    final AST ast = fRewrite.getAST();
0563:                    if (expression instanceof  ThisExpression) {
0564:                        if (Bindings.equals(fTarget, variable)) {
0565:                            if (fAnonymousClass > 0) {
0566:                                final ThisExpression target = ast
0567:                                        .newThisExpression();
0568:                                target.setQualifier(ast
0569:                                        .newSimpleName(fTargetType
0570:                                                .getElementName()));
0571:                                fRewrite.replace(node, target, null);
0572:                            } else
0573:                                fRewrite.replace(node, ast.newThisExpression(),
0574:                                        null);
0575:                            return false;
0576:                        }
0577:                    }
0578:                    if (expression instanceof  FieldAccess) {
0579:                        final FieldAccess access = (FieldAccess) expression;
0580:                        final IBinding binding = access.getName()
0581:                                .resolveBinding();
0582:                        if ((access.getExpression() instanceof  ThisExpression)
0583:                                && Bindings.equals(fTarget, binding)) {
0584:                            fRewrite.replace(node, ast.newSimpleName(node
0585:                                    .getName().getIdentifier()), null);
0586:                            return false;
0587:                        }
0588:                    } else if (expression != null) {
0589:                        final IMethodBinding method = fDeclaration
0590:                                .resolveBinding();
0591:                        if (variable != null
0592:                                && method != null
0593:                                && !JdtFlags.isStatic(variable)
0594:                                && Bindings.equals(method.getDeclaringClass(),
0595:                                        variable.getDeclaringClass())) {
0596:                            fRewrite.replace(expression, ast
0597:                                    .newSimpleName(fTargetName), null);
0598:                            return false;
0599:                        }
0600:                    }
0601:                    return true;
0602:                }
0603:
0604:                public final void visit(final List nodes) {
0605:                    Assert.isNotNull(nodes);
0606:                    ASTNode node = null;
0607:                    for (final Iterator iterator = nodes.iterator(); iterator
0608:                            .hasNext();) {
0609:                        node = (ASTNode) iterator.next();
0610:                        node.accept(this );
0611:                    }
0612:                }
0613:
0614:                public final boolean visit(final MethodInvocation node) {
0615:                    Assert.isNotNull(node);
0616:                    final Expression expression = node.getExpression();
0617:                    final IMethodBinding method = node.resolveMethodBinding();
0618:                    if (method != null) {
0619:                        final ASTRewrite rewrite = fRewrite;
0620:                        if (expression == null) {
0621:                            final AST ast = node.getAST();
0622:                            if (!JdtFlags.isStatic(method))
0623:                                rewrite.set(node,
0624:                                        MethodInvocation.EXPRESSION_PROPERTY,
0625:                                        ast.newSimpleName(fTargetName), null);
0626:                            else
0627:                                rewrite.set(node,
0628:                                        MethodInvocation.EXPRESSION_PROPERTY,
0629:                                        ast.newSimpleType(ast
0630:                                                .newSimpleName(fMethod
0631:                                                        .getDeclaringType()
0632:                                                        .getElementName())),
0633:                                        null);
0634:                            return true;
0635:                        } else {
0636:                            if (expression instanceof  FieldAccess) {
0637:                                final FieldAccess access = (FieldAccess) expression;
0638:                                if (Bindings.equals(access
0639:                                        .resolveFieldBinding(), fTarget)) {
0640:                                    rewrite.remove(expression, null);
0641:                                    visit(node.arguments());
0642:                                    return false;
0643:                                }
0644:                            } else if (expression instanceof  Name) {
0645:                                final Name name = (Name) expression;
0646:                                if (Bindings.equals(name.resolveBinding(),
0647:                                        fTarget)) {
0648:                                    rewrite.remove(expression, null);
0649:                                    visit(node.arguments());
0650:                                    return false;
0651:                                }
0652:                            }
0653:                        }
0654:                    }
0655:                    return true;
0656:                }
0657:
0658:                public final boolean visit(final QualifiedName node) {
0659:                    Assert.isNotNull(node);
0660:                    IBinding binding = node.resolveBinding();
0661:                    if (binding instanceof  ITypeBinding) {
0662:                        final ITypeBinding type = (ITypeBinding) binding;
0663:                        if (type.isClass() && type.getDeclaringClass() != null) {
0664:                            final String name = fTargetRewrite
0665:                                    .getImportRewrite().addImport(type);
0666:                            if (name != null && name.length() > 0) {
0667:                                fRewrite.replace(node, ASTNodeFactory.newName(
0668:                                        node.getAST(), name), null);
0669:                                return false;
0670:                            }
0671:                        }
0672:                    }
0673:                    binding = node.getQualifier().resolveBinding();
0674:                    if (Bindings.equals(binding, fTarget)) {
0675:                        fRewrite.replace(node, fRewrite.createCopyTarget(node
0676:                                .getName()), null);
0677:                        return false;
0678:                    }
0679:                    return true;
0680:                }
0681:
0682:                public final boolean visit(final SimpleName node) {
0683:                    Assert.isNotNull(node);
0684:                    final AST ast = node.getAST();
0685:                    final ASTRewrite rewrite = fRewrite;
0686:                    final IBinding binding = node.resolveBinding();
0687:                    if (binding instanceof  ITypeBinding) {
0688:                        final ITypeBinding type = (ITypeBinding) binding;
0689:                        if (type.isClass() && type.getDeclaringClass() != null) {
0690:                            final String name = fTargetRewrite
0691:                                    .getImportRewrite().addImport(type);
0692:                            if (name != null && name.length() > 0) {
0693:                                fRewrite.replace(node, ASTNodeFactory.newName(
0694:                                        ast, name), null);
0695:                                return false;
0696:                            }
0697:                        }
0698:                    }
0699:                    if (Bindings.equals(binding, fTarget))
0700:                        if (fAnonymousClass > 0) {
0701:                            final ThisExpression target = ast
0702:                                    .newThisExpression();
0703:                            target.setQualifier(ast.newSimpleName(fTargetType
0704:                                    .getElementName()));
0705:                            fRewrite.replace(node, target, null);
0706:                        } else
0707:                            rewrite
0708:                                    .replace(node, ast.newThisExpression(),
0709:                                            null);
0710:                    else if (binding instanceof  IVariableBinding) {
0711:                        final IVariableBinding variable = (IVariableBinding) binding;
0712:                        final IMethodBinding method = fDeclaration
0713:                                .resolveBinding();
0714:                        final ITypeBinding declaring = variable
0715:                                .getDeclaringClass();
0716:                        if (method != null) {
0717:                            if (Bindings.equals(method.getDeclaringClass(),
0718:                                    declaring)) {
0719:                                if (JdtFlags.isStatic(variable))
0720:                                    rewrite
0721:                                            .replace(
0722:                                                    node,
0723:                                                    ast
0724:                                                            .newQualifiedName(
0725:                                                                    ASTNodeFactory
0726:                                                                            .newName(
0727:                                                                                    ast,
0728:                                                                                    fTargetRewrite
0729:                                                                                            .getImportRewrite()
0730:                                                                                            .addImport(
0731:                                                                                                    declaring)),
0732:                                                                    ast
0733:                                                                            .newSimpleName(node
0734:                                                                                    .getFullyQualifiedName())),
0735:                                                    null);
0736:                                else {
0737:                                    final FieldAccess access = ast
0738:                                            .newFieldAccess();
0739:                                    access.setExpression(ast
0740:                                            .newSimpleName(fTargetName));
0741:                                    access.setName(ast.newSimpleName(node
0742:                                            .getFullyQualifiedName()));
0743:                                    rewrite.replace(node, access, null);
0744:                                }
0745:                            } else if (!(node.getParent() instanceof  QualifiedName)
0746:                                    && JdtFlags.isStatic(variable)
0747:                                    && !fStaticImports.contains(variable)) {
0748:                                rewrite.replace(node, ast.newQualifiedName(
0749:                                        ASTNodeFactory.newName(ast,
0750:                                                fTargetRewrite
0751:                                                        .getImportRewrite()
0752:                                                        .addImport(declaring)),
0753:                                        ast.newSimpleName(node
0754:                                                .getFullyQualifiedName())),
0755:                                        null);
0756:                            }
0757:                        }
0758:                    }
0759:                    return false;
0760:                }
0761:
0762:                public final boolean visit(final ThisExpression node) {
0763:                    Assert.isNotNull(node);
0764:                    fRewrite.replace(node, node.getAST().newSimpleName(
0765:                            fTargetName), null);
0766:                    return false;
0767:                }
0768:            }
0769:
0770:            /**
0771:             * AST visitor to find read-only fields of the declaring class of 'this'.
0772:             */
0773:            public static class ReadyOnlyFieldFinder extends ASTVisitor {
0774:
0775:                /**
0776:                 * Returns the field binding associated with this expression.
0777:                 * 
0778:                 * @param expression
0779:                 *            the expression to get the field binding for
0780:                 * @return the field binding, if the expression denotes a field access
0781:                 *         or a field name, <code>null</code> otherwise
0782:                 */
0783:                protected static IVariableBinding getFieldBinding(
0784:                        final Expression expression) {
0785:                    Assert.isNotNull(expression);
0786:                    if (expression instanceof  FieldAccess)
0787:                        return (IVariableBinding) ((FieldAccess) expression)
0788:                                .getName().resolveBinding();
0789:                    if (expression instanceof  Name) {
0790:                        final IBinding binding = ((Name) expression)
0791:                                .resolveBinding();
0792:                        if (binding instanceof  IVariableBinding) {
0793:                            final IVariableBinding variable = (IVariableBinding) binding;
0794:                            if (variable.isField())
0795:                                return variable;
0796:                        }
0797:                    }
0798:                    return null;
0799:                }
0800:
0801:                /**
0802:                 * Is the specified name a qualified entity, e.g. preceded by 'this',
0803:                 * 'super' or part of a method invocation?
0804:                 * 
0805:                 * @param name
0806:                 *            the name to check
0807:                 * @return <code>true</code> if this entity is qualified,
0808:                 *         <code>false</code> otherwise
0809:                 */
0810:                protected static boolean isQualifiedEntity(final Name name) {
0811:                    Assert.isNotNull(name);
0812:                    final ASTNode parent = name.getParent();
0813:                    if ((parent instanceof  QualifiedName && ((QualifiedName) parent)
0814:                            .getName().equals(name))
0815:                            || (parent instanceof  FieldAccess && ((FieldAccess) parent)
0816:                                    .getName().equals(name))
0817:                            || (parent instanceof  SuperFieldAccess))
0818:                        return true;
0819:                    else if (parent instanceof  MethodInvocation) {
0820:                        final MethodInvocation invocation = (MethodInvocation) parent;
0821:                        return invocation.getExpression() != null
0822:                                && invocation.getName().equals(name);
0823:                    }
0824:                    return false;
0825:                }
0826:
0827:                /** The list of found bindings */
0828:                protected final List fBindings = new LinkedList();
0829:
0830:                /** The keys of the found bindings */
0831:                protected final Set fFound = new HashSet();
0832:
0833:                /** The keys of the written bindings */
0834:                protected final Set fWritten = new HashSet();
0835:
0836:                /**
0837:                 * Creates a new read only field finder.
0838:                 * 
0839:                 * @param binding
0840:                 *            The declaring class of the method declaring to find fields
0841:                 *            for
0842:                 */
0843:                public ReadyOnlyFieldFinder(final ITypeBinding binding) {
0844:                    Assert.isNotNull(binding);
0845:                    final IVariableBinding[] bindings = binding
0846:                            .getDeclaredFields();
0847:                    IVariableBinding variable = null;
0848:                    for (int index = 0; index < bindings.length; index++) {
0849:                        variable = bindings[index];
0850:                        if (!variable.isSynthetic()
0851:                                && !fFound.contains(variable.getKey())) {
0852:                            fFound.add(variable.getKey());
0853:                            fBindings.add(variable);
0854:                        }
0855:                    }
0856:                }
0857:
0858:                /**
0859:                 * Returns all fields of the declaring class plus the ones references in
0860:                 * the visited method declaration.
0861:                 * 
0862:                 * @return all fields of the declaring class plus the references ones
0863:                 */
0864:                public final IVariableBinding[] getDeclaredFields() {
0865:                    final IVariableBinding[] result = new IVariableBinding[fBindings
0866:                            .size()];
0867:                    fBindings.toArray(result);
0868:                    return result;
0869:                }
0870:
0871:                /**
0872:                 * Returns all fields of the declaring class which are not written by
0873:                 * the visited method declaration.
0874:                 * 
0875:                 * @return all fields which are not written
0876:                 */
0877:                public final IVariableBinding[] getReadOnlyFields() {
0878:                    IVariableBinding binding = null;
0879:                    final List list = new LinkedList(fBindings);
0880:                    for (final Iterator iterator = list.iterator(); iterator
0881:                            .hasNext();) {
0882:                        binding = (IVariableBinding) iterator.next();
0883:                        if (fWritten.contains(binding.getKey()))
0884:                            iterator.remove();
0885:                    }
0886:                    final IVariableBinding[] result = new IVariableBinding[list
0887:                            .size()];
0888:                    list.toArray(result);
0889:                    return result;
0890:                }
0891:
0892:                public final boolean visit(final Assignment node) {
0893:                    Assert.isNotNull(node);
0894:                    final IVariableBinding binding = getFieldBinding(node
0895:                            .getLeftHandSide());
0896:                    if (binding != null)
0897:                        fWritten.add(binding.getKey());
0898:                    return true;
0899:                }
0900:
0901:                public final boolean visit(final FieldAccess node) {
0902:                    Assert.isNotNull(node);
0903:                    if (node.getExpression() instanceof  ThisExpression) {
0904:                        final IVariableBinding binding = (IVariableBinding) node
0905:                                .getName().resolveBinding();
0906:                        if (binding != null) {
0907:                            final String key = binding.getKey();
0908:                            if (!fFound.contains(key)) {
0909:                                fFound.add(key);
0910:                                fBindings.add(binding);
0911:                            }
0912:                        }
0913:                    }
0914:                    return true;
0915:                }
0916:
0917:                public final boolean visit(final PostfixExpression node) {
0918:                    final IVariableBinding binding = getFieldBinding(node
0919:                            .getOperand());
0920:                    if (binding != null)
0921:                        fWritten.add(binding.getKey());
0922:                    return true;
0923:                }
0924:
0925:                public final boolean visit(final PrefixExpression node) {
0926:                    final IVariableBinding binding = getFieldBinding(node
0927:                            .getOperand());
0928:                    if (binding != null)
0929:                        fWritten.add(binding.getKey());
0930:                    return false;
0931:                }
0932:
0933:                public final boolean visit(final SimpleName node) {
0934:                    Assert.isNotNull(node);
0935:                    final IBinding binding = node.resolveBinding();
0936:                    if (binding != null)
0937:                        if (isFieldAccess(node) && !isQualifiedEntity(node)) {
0938:                            final IVariableBinding variable = (IVariableBinding) binding;
0939:                            final String key = variable.getKey();
0940:                            if (!fFound.contains(key)) {
0941:                                fFound.add(key);
0942:                                fBindings.add(variable);
0943:                            }
0944:                        }
0945:                    return false;
0946:                }
0947:            }
0948:
0949:            /**
0950:             * AST visitor to find recursive calls to the method.
0951:             */
0952:            public final class RecursiveCallFinder extends AstNodeFinder {
0953:
0954:                /** The method binding */
0955:                protected final IMethodBinding fBinding;
0956:
0957:                /**
0958:                 * Creates a new recursive call finder.
0959:                 * 
0960:                 * @param declaration
0961:                 *            the method declaration
0962:                 */
0963:                public RecursiveCallFinder(final MethodDeclaration declaration) {
0964:                    Assert.isNotNull(declaration);
0965:                    fBinding = declaration.resolveBinding();
0966:                }
0967:
0968:                public final boolean visit(final MethodInvocation node) {
0969:                    Assert.isNotNull(node);
0970:                    final Expression expression = node.getExpression();
0971:                    final IMethodBinding binding = node.resolveMethodBinding();
0972:                    if (binding == null
0973:                            || (!Modifier.isStatic(binding.getModifiers())
0974:                                    && Bindings.equals(binding, fBinding) && (expression == null || expression instanceof  ThisExpression))) {
0975:                        fStatus
0976:                                .merge(RefactoringStatus
0977:                                        .createFatalErrorStatus(
0978:                                                RefactoringCoreMessages.MoveInstanceMethodProcessor_potentially_recursive,
0979:                                                JavaStatusContext
0980:                                                        .create(
0981:                                                                fMethod
0982:                                                                        .getCompilationUnit(),
0983:                                                                node)));
0984:                        fResult.add(node);
0985:                        return false;
0986:                    }
0987:                    return true;
0988:                }
0989:            }
0990:
0991:            /**
0992:             * AST visitor to find 'super' references.
0993:             */
0994:            public final class SuperReferenceFinder extends AstNodeFinder {
0995:
0996:                public final boolean visit(final AnnotationTypeDeclaration node) {
0997:                    return false;
0998:                }
0999:
1000:                public final boolean visit(final AnonymousClassDeclaration node) {
1001:                    return false;
1002:                }
1003:
1004:                public final boolean visit(final EnumDeclaration node) {
1005:                    return false;
1006:                }
1007:
1008:                public final boolean visit(final SuperFieldAccess node) {
1009:                    Assert.isNotNull(node);
1010:                    fStatus
1011:                            .merge(RefactoringStatus
1012:                                    .createFatalErrorStatus(
1013:                                            RefactoringCoreMessages.MoveInstanceMethodProcessor_uses_super ,
1014:                                            JavaStatusContext
1015:                                                    .create(
1016:                                                            fMethod
1017:                                                                    .getCompilationUnit(),
1018:                                                            node)));
1019:                    fResult.add(node);
1020:                    return false;
1021:                }
1022:
1023:                public final boolean visit(final SuperMethodInvocation node) {
1024:                    Assert.isNotNull(node);
1025:                    fStatus
1026:                            .merge(RefactoringStatus
1027:                                    .createFatalErrorStatus(
1028:                                            RefactoringCoreMessages.MoveInstanceMethodProcessor_uses_super ,
1029:                                            JavaStatusContext
1030:                                                    .create(
1031:                                                            fMethod
1032:                                                                    .getCompilationUnit(),
1033:                                                            node)));
1034:                    fResult.add(node);
1035:                    return false;
1036:                }
1037:
1038:                public final boolean visit(final TypeDeclaration node) {
1039:                    return false;
1040:                }
1041:            }
1042:
1043:            /**
1044:             * AST visitor to find references to 'this'.
1045:             */
1046:            public final class ThisReferenceFinder extends AstNodeFinder {
1047:
1048:                public final boolean visit(final MethodInvocation node) {
1049:                    Assert.isNotNull(node);
1050:                    final IMethodBinding binding = node.resolveMethodBinding();
1051:                    if (binding != null && !JdtFlags.isStatic(binding)
1052:                            && node.getExpression() == null) {
1053:                        fResult.add(node);
1054:                        fStatus
1055:                                .merge(RefactoringStatus
1056:                                        .createFatalErrorStatus(
1057:                                                RefactoringCoreMessages.MoveInstanceMethodProcessor_this _reference,
1058:                                                JavaStatusContext
1059:                                                        .create(
1060:                                                                fMethod
1061:                                                                        .getCompilationUnit(),
1062:                                                                node)));
1063:                    }
1064:                    return true;
1065:                }
1066:
1067:                public final boolean visit(final SimpleName node) {
1068:                    Assert.isNotNull(node);
1069:                    if (isFieldAccess(node) && !isTargetAccess(node)) {
1070:                        fResult.add(node);
1071:                        fStatus
1072:                                .merge(RefactoringStatus
1073:                                        .createFatalErrorStatus(
1074:                                                RefactoringCoreMessages.MoveInstanceMethodProcessor_this _reference,
1075:                                                JavaStatusContext
1076:                                                        .create(
1077:                                                                fMethod
1078:                                                                        .getCompilationUnit(),
1079:                                                                node)));
1080:                    }
1081:                    return false;
1082:                }
1083:
1084:                public final boolean visit(final ThisExpression node) {
1085:                    Assert.isNotNull(node);
1086:                    fResult.add(node);
1087:                    fStatus
1088:                            .merge(RefactoringStatus
1089:                                    .createFatalErrorStatus(
1090:                                            RefactoringCoreMessages.MoveInstanceMethodProcessor_this _reference,
1091:                                            JavaStatusContext
1092:                                                    .create(
1093:                                                            fMethod
1094:                                                                    .getCompilationUnit(),
1095:                                                            node)));
1096:                    return false;
1097:                }
1098:            }
1099:
1100:            /**
1101:             * Argument factory which adjusts the visibilities of the argument types.
1102:             */
1103:            public class VisibilityAdjustingArgumentFactory implements 
1104:                    IArgumentFactory {
1105:
1106:                /** The visibility adjustments */
1107:                private final Map fAdjustments;
1108:
1109:                /** The ast to use for new nodes */
1110:                private final AST fAst;
1111:
1112:                /** The compilation unit rewrites */
1113:                private final Map fRewrites;
1114:
1115:                /**
1116:                 * Creates a new visibility adjusting argument factory.
1117:                 * 
1118:                 * @param ast
1119:                 *            the ast to use for new nodes
1120:                 * @param rewrites
1121:                 *            the compilation unit rewrites
1122:                 * @param adjustments
1123:                 *            the map of elements to visibility adjustments
1124:                 */
1125:                public VisibilityAdjustingArgumentFactory(final AST ast,
1126:                        final Map rewrites, final Map adjustments) {
1127:                    Assert.isNotNull(ast);
1128:                    Assert.isNotNull(rewrites);
1129:                    Assert.isNotNull(adjustments);
1130:                    fAst = ast;
1131:                    fRewrites = rewrites;
1132:                    fAdjustments = adjustments;
1133:                }
1134:
1135:                protected final void adjustTypeVisibility(
1136:                        final ITypeBinding binding) throws JavaModelException {
1137:                    Assert.isNotNull(binding);
1138:                    final IJavaElement element = binding.getJavaElement();
1139:                    if (element instanceof  IType) {
1140:                        final IType type = (IType) element;
1141:                        if (!type.isBinary() && !type.isReadOnly()
1142:                                && !Flags.isPublic(type.getFlags())) {
1143:                            boolean same = false;
1144:                            final CompilationUnitRewrite rewrite = getCompilationUnitRewrite(
1145:                                    fRewrites, type.getCompilationUnit());
1146:                            final AbstractTypeDeclaration declaration = ASTNodeSearchUtil
1147:                                    .getAbstractTypeDeclarationNode(type,
1148:                                            rewrite.getRoot());
1149:                            if (declaration != null) {
1150:                                final ITypeBinding declaring = declaration
1151:                                        .resolveBinding();
1152:                                if (declaring != null
1153:                                        && Bindings
1154:                                                .equals(binding.getPackage(),
1155:                                                        fTarget.getType()
1156:                                                                .getPackage()))
1157:                                    same = true;
1158:                                final Modifier.ModifierKeyword keyword = same ? null
1159:                                        : Modifier.ModifierKeyword.PUBLIC_KEYWORD;
1160:                                final String modifier = same ? RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_default
1161:                                        : RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_public;
1162:                                if (MemberVisibilityAdjustor
1163:                                        .hasLowerVisibility(
1164:                                                binding.getModifiers(),
1165:                                                same ? Modifier.NONE
1166:                                                        : (keyword == null ? Modifier.NONE
1167:                                                                : keyword
1168:                                                                        .toFlagValue()))
1169:                                        && MemberVisibilityAdjustor
1170:                                                .needsVisibilityAdjustments(
1171:                                                        type, keyword,
1172:                                                        fAdjustments))
1173:                                    fAdjustments
1174:                                            .put(
1175:                                                    type,
1176:                                                    new MemberVisibilityAdjustor.OutgoingMemberVisibilityAdjustment(
1177:                                                            type,
1178:                                                            keyword,
1179:                                                            RefactoringStatus
1180:                                                                    .createWarningStatus(
1181:                                                                            Messages
1182:                                                                                    .format(
1183:                                                                                            RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_type_warning,
1184:                                                                                            new String[] {
1185:                                                                                                    BindingLabelProvider
1186:                                                                                                            .getBindingLabel(
1187:                                                                                                                    declaration
1188:                                                                                                                            .resolveBinding(),
1189:                                                                                                                    JavaElementLabels.ALL_FULLY_QUALIFIED),
1190:                                                                                                    modifier }),
1191:                                                                            JavaStatusContext
1192:                                                                                    .create(
1193:                                                                                            type
1194:                                                                                                    .getCompilationUnit(),
1195:                                                                                            declaration))));
1196:                            }
1197:                        }
1198:                    }
1199:                }
1200:
1201:                public ASTNode getArgumentNode(final IVariableBinding binding,
1202:                        final boolean last) throws JavaModelException {
1203:                    Assert.isNotNull(binding);
1204:                    adjustTypeVisibility(binding.getType());
1205:                    return fAst.newSimpleName(binding.getName());
1206:                }
1207:
1208:                public ASTNode getTargetNode() throws JavaModelException {
1209:                    return fAst.newThisExpression();
1210:                }
1211:            }
1212:
1213:            private static final String ATTRIBUTE_DEPRECATE = "deprecate"; //$NON-NLS-1$
1214:
1215:            private static final String ATTRIBUTE_INLINE = "inline"; //$NON-NLS-1$
1216:
1217:            private static final String ATTRIBUTE_REMOVE = "remove"; //$NON-NLS-1$
1218:
1219:            private static final String ATTRIBUTE_TARGET_INDEX = "targetIndex"; //$NON-NLS-1$
1220:
1221:            private static final String ATTRIBUTE_TARGET_NAME = "targetName"; //$NON-NLS-1$
1222:
1223:            private static final String ATTRIBUTE_USE_GETTER = "getter"; //$NON-NLS-1$
1224:
1225:            private static final String ATTRIBUTE_USE_SETTER = "setter"; //$NON-NLS-1$
1226:
1227:            /** The identifier of this processor */
1228:            public static final String IDENTIFIER = "org.eclipse.jdt.ui.moveInstanceMethodProcessor"; //$NON-NLS-1$
1229:
1230:            /**
1231:             * Returns the bindings of the method arguments of the specified
1232:             * declaration.
1233:             * 
1234:             * @param declaration
1235:             *            the method declaration
1236:             * @return the array of method argument variable bindings
1237:             */
1238:            protected static IVariableBinding[] getArgumentBindings(
1239:                    final MethodDeclaration declaration) {
1240:                Assert.isNotNull(declaration);
1241:                final List parameters = new ArrayList(declaration.parameters()
1242:                        .size());
1243:                VariableDeclaration variable = null;
1244:                IVariableBinding binding = null;
1245:                for (final Iterator iterator = declaration.parameters()
1246:                        .iterator(); iterator.hasNext();) {
1247:                    variable = (VariableDeclaration) iterator.next();
1248:                    binding = variable.resolveBinding();
1249:                    if (binding == null)
1250:                        return new IVariableBinding[0];
1251:                    parameters.add(binding);
1252:                }
1253:                final IVariableBinding[] result = new IVariableBinding[parameters
1254:                        .size()];
1255:                parameters.toArray(result);
1256:                return result;
1257:            }
1258:
1259:            /**
1260:             * Returns the bindings of the method argument types of the specified
1261:             * declaration.
1262:             * 
1263:             * @param declaration
1264:             *            the method declaration
1265:             * @return the array of method argument variable bindings
1266:             */
1267:            protected static ITypeBinding[] getArgumentTypes(
1268:                    final MethodDeclaration declaration) {
1269:                Assert.isNotNull(declaration);
1270:                final IVariableBinding[] parameters = getArgumentBindings(declaration);
1271:                final List types = new ArrayList(parameters.length);
1272:                IVariableBinding binding = null;
1273:                ITypeBinding type = null;
1274:                for (int index = 0; index < parameters.length; index++) {
1275:                    binding = parameters[index];
1276:                    type = binding.getType();
1277:                    if (type != null)
1278:                        types.add(type);
1279:                }
1280:                final ITypeBinding[] result = new ITypeBinding[types.size()];
1281:                types.toArray(result);
1282:                return result;
1283:            }
1284:
1285:            /**
1286:             * Is the specified name a field access?
1287:             * 
1288:             * @param name
1289:             *            the name to check
1290:             * @return <code>true</code> if this name is a field access,
1291:             *         <code>false</code> otherwise
1292:             */
1293:            protected static boolean isFieldAccess(final SimpleName name) {
1294:                Assert.isNotNull(name);
1295:                final IBinding binding = name.resolveBinding();
1296:                if (!(binding instanceof  IVariableBinding))
1297:                    return false;
1298:                final IVariableBinding variable = (IVariableBinding) binding;
1299:                if (!variable.isField())
1300:                    return false;
1301:                if ("length".equals(name.getIdentifier())) { //$NON-NLS-1$
1302:                    final ASTNode parent = name.getParent();
1303:                    if (parent instanceof  QualifiedName) {
1304:                        final QualifiedName qualified = (QualifiedName) parent;
1305:                        final ITypeBinding type = qualified.getQualifier()
1306:                                .resolveTypeBinding();
1307:                        if (type != null && type.isArray())
1308:                            return false;
1309:                    }
1310:                }
1311:                return !Modifier.isStatic(variable.getModifiers());
1312:            }
1313:
1314:            /** The candidate targets */
1315:            private IVariableBinding[] fCandidateTargets = new IVariableBinding[0];
1316:
1317:            /** The text change manager */
1318:            private TextChangeManager fChangeManager = null;
1319:
1320:            /** The comment */
1321:            private String fComment;
1322:
1323:            /** Should the delegator be deprecated? */
1324:            private boolean fDelegateDeprecation = true;
1325:
1326:            private boolean fDelegatingUpdating;
1327:
1328:            /** Should the delegator be inlined? */
1329:            private boolean fInline = false;
1330:
1331:            /** The method to move */
1332:            private IMethod fMethod;
1333:
1334:            /** The name of the new method to generate */
1335:            private String fMethodName;
1336:
1337:            /** The possible targets */
1338:            private IVariableBinding[] fPossibleTargets = new IVariableBinding[0];
1339:
1340:            /** Should the delegator be removed after inlining? */
1341:            private boolean fRemove = false;
1342:
1343:            /** The code generation settings to apply */
1344:            private CodeGenerationSettings fSettings;
1345:
1346:            /** The source compilation unit rewrite */
1347:            private CompilationUnitRewrite fSourceRewrite;
1348:
1349:            /** The new target */
1350:            private IVariableBinding fTarget = null;
1351:
1352:            /** The name of the new target */
1353:            private String fTargetName;
1354:
1355:            /** Does the move method need a target node? */
1356:            private boolean fTargetNode = true;
1357:
1358:            /** The target type */
1359:            private IType fTargetType = null;
1360:
1361:            /** Should getter methods be used to resolve visibility issues? */
1362:            private boolean fUseGetters = true;
1363:
1364:            /** Should setter methods be used to resolve visibility issues? */
1365:            private boolean fUseSetters = true;
1366:
1367:            /**
1368:             * Creates a new move instance method processor.
1369:             * 
1370:             * @param method
1371:             *            the method to move, or <code>null</code> if invoked by
1372:             *            scripting
1373:             * @param settings
1374:             *            the code generation settings to apply, or <code>null</code>
1375:             *            if invoked by scripting
1376:             */
1377:            public MoveInstanceMethodProcessor(final IMethod method,
1378:                    final CodeGenerationSettings settings) {
1379:                fSettings = settings;
1380:                fMethod = method;
1381:                if (method != null)
1382:                    initialize(method);
1383:            }
1384:
1385:            /**
1386:             * {@inheritDoc}
1387:             */
1388:            public boolean canEnableComment() {
1389:                return true;
1390:            }
1391:
1392:            /**
1393:             * {@inheritDoc}
1394:             */
1395:            public final boolean canEnableDelegateUpdating() {
1396:                return true;
1397:            }
1398:
1399:            /**
1400:             * Checks whether a method with the proposed name already exists in the
1401:             * target type.
1402:             * 
1403:             * @param monitor
1404:             *            the progress monitor to display progress
1405:             * @param status
1406:             *            the status of the condition checking
1407:             * @throws JavaModelException
1408:             *             if the declared methods of the target type could not be
1409:             *             retrieved
1410:             */
1411:            protected void checkConflictingMethod(
1412:                    final IProgressMonitor monitor,
1413:                    final RefactoringStatus status) throws JavaModelException {
1414:                Assert.isNotNull(monitor);
1415:                Assert.isNotNull(status);
1416:                final IMethod[] methods = fTargetType.getMethods();
1417:                try {
1418:                    monitor.beginTask("", methods.length); //$NON-NLS-1$
1419:                    monitor
1420:                            .setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking);
1421:                    IMethod method = null;
1422:                    for (int index = 0; index < methods.length; index++) {
1423:                        method = methods[index];
1424:                        if (method.getElementName().equals(fMethodName)
1425:                                && method.getParameterTypes().length == fMethod
1426:                                        .getParameterTypes().length - 1)
1427:                            status
1428:                                    .merge(RefactoringStatus
1429:                                            .createErrorStatus(
1430:                                                    Messages
1431:                                                            .format(
1432:                                                                    RefactoringCoreMessages.MoveInstanceMethodProcessor_method_already_exists,
1433:                                                                    new String[] {
1434:                                                                            fMethodName,
1435:                                                                            fTargetType
1436:                                                                                    .getElementName() }),
1437:                                                    JavaStatusContext
1438:                                                            .create(method)));
1439:                        monitor.worked(1);
1440:                    }
1441:                    if (fMethodName.equals(fTargetType.getElementName()))
1442:                        status
1443:                                .merge(RefactoringStatus
1444:                                        .createFatalErrorStatus(
1445:                                                Messages
1446:                                                        .format(
1447:                                                                RefactoringCoreMessages.MoveInstanceMethodProcessor_method_type_clash,
1448:                                                                fMethodName),
1449:                                                JavaStatusContext
1450:                                                        .create(fTargetType)));
1451:                } finally {
1452:                    monitor.done();
1453:                }
1454:            }
1455:
1456:            /**
1457:             * Checks whether the new target name conflicts with an already existing
1458:             * method parameter.
1459:             * 
1460:             * @param monitor
1461:             *            the progress monitor to display progress
1462:             * @param status
1463:             *            the status of the condition checking
1464:             * @throws JavaModelException
1465:             *             if the method declaration of the method to move could not be
1466:             *             found
1467:             */
1468:            protected void checkConflictingTarget(
1469:                    final IProgressMonitor monitor,
1470:                    final RefactoringStatus status) throws JavaModelException {
1471:                Assert.isNotNull(monitor);
1472:                Assert.isNotNull(status);
1473:                final MethodDeclaration declaration = ASTNodeSearchUtil
1474:                        .getMethodDeclarationNode(fMethod, fSourceRewrite
1475:                                .getRoot());
1476:                VariableDeclaration variable = null;
1477:                final List parameters = declaration.parameters();
1478:                try {
1479:                    monitor.beginTask("", parameters.size()); //$NON-NLS-1$
1480:                    monitor
1481:                            .setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking);
1482:                    for (final Iterator iterator = parameters.iterator(); iterator
1483:                            .hasNext();) {
1484:                        variable = (VariableDeclaration) iterator.next();
1485:                        if (fTargetName.equals(variable.getName()
1486:                                .getIdentifier())) {
1487:                            status
1488:                                    .merge(RefactoringStatus
1489:                                            .createErrorStatus(
1490:                                                    RefactoringCoreMessages.MoveInstanceMethodProcessor_target_name_already_used,
1491:                                                    JavaStatusContext
1492:                                                            .create(fMethod)));
1493:                            break;
1494:                        }
1495:                        monitor.worked(1);
1496:                    }
1497:                } finally {
1498:                    monitor.done();
1499:                }
1500:            }
1501:
1502:            /*
1503:             * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#checkFinalConditions(org.eclipse.core.runtime.IProgressMonitor,
1504:             *      org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext)
1505:             */
1506:            public final RefactoringStatus checkFinalConditions(
1507:                    final IProgressMonitor monitor,
1508:                    final CheckConditionsContext context) throws CoreException,
1509:                    OperationCanceledException {
1510:                Assert.isNotNull(monitor);
1511:                Assert.isNotNull(context);
1512:                Assert.isNotNull(fTarget);
1513:                final RefactoringStatus status = new RefactoringStatus();
1514:                fChangeManager = new TextChangeManager();
1515:                try {
1516:                    monitor.beginTask("", 4); //$NON-NLS-1$
1517:                    monitor
1518:                            .setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking);
1519:                    status.merge(Checks.checkIfCuBroken(fMethod));
1520:                    if (!status.hasError()) {
1521:                        checkGenericTarget(new SubProgressMonitor(monitor, 1),
1522:                                status);
1523:                        if (status.isOK()) {
1524:                            final IType type = getTargetType();
1525:                            if (type != null) {
1526:                                if (type.isBinary() || type.isReadOnly()
1527:                                        || !fMethod.exists()
1528:                                        || fMethod.isBinary()
1529:                                        || fMethod.isReadOnly())
1530:                                    status
1531:                                            .merge(RefactoringStatus
1532:                                                    .createFatalErrorStatus(
1533:                                                            RefactoringCoreMessages.MoveInstanceMethodProcessor_no_binary,
1534:                                                            JavaStatusContext
1535:                                                                    .create(fMethod)));
1536:                                else {
1537:                                    status.merge(Checks.checkIfCuBroken(type));
1538:                                    if (!status.hasError()) {
1539:                                        if (!type.exists() || type.isBinary()
1540:                                                || type.isReadOnly())
1541:                                            status
1542:                                                    .merge(RefactoringStatus
1543:                                                            .createFatalErrorStatus(
1544:                                                                    RefactoringCoreMessages.MoveInstanceMethodProcessor_no_binary,
1545:                                                                    JavaStatusContext
1546:                                                                            .create(fMethod)));
1547:                                        checkConflictingTarget(
1548:                                                new SubProgressMonitor(monitor,
1549:                                                        1), status);
1550:                                        checkConflictingMethod(
1551:                                                new SubProgressMonitor(monitor,
1552:                                                        1), status);
1553:                                        status
1554:                                                .merge(Checks
1555:                                                        .validateModifiesFiles(
1556:                                                                computeModifiedFiles(
1557:                                                                        fMethod
1558:                                                                                .getCompilationUnit(),
1559:                                                                        type
1560:                                                                                .getCompilationUnit()),
1561:                                                                null));
1562:                                        monitor.worked(1);
1563:                                        if (!status.hasFatalError())
1564:                                            fChangeManager = createChangeManager(
1565:                                                    status,
1566:                                                    new SubProgressMonitor(
1567:                                                            monitor, 1));
1568:                                    }
1569:                                }
1570:                            } else
1571:                                status
1572:                                        .merge(RefactoringStatus
1573:                                                .createFatalErrorStatus(
1574:                                                        RefactoringCoreMessages.MoveInstanceMethodProcessor_no_resolved_target,
1575:                                                        JavaStatusContext
1576:                                                                .create(fMethod)));
1577:                        }
1578:                    }
1579:                } finally {
1580:                    monitor.done();
1581:                }
1582:                return status;
1583:            }
1584:
1585:            /**
1586:             * Checks whether the target is a type variable or a generic type.
1587:             * 
1588:             * @param monitor
1589:             *            the progress monitor to display progress
1590:             * @param status
1591:             *            the refactoring status
1592:             */
1593:            protected void checkGenericTarget(final IProgressMonitor monitor,
1594:                    final RefactoringStatus status) {
1595:                Assert.isNotNull(monitor);
1596:                Assert.isNotNull(status);
1597:                try {
1598:                    monitor.beginTask("", 1); //$NON-NLS-1$
1599:                    monitor
1600:                            .setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking);
1601:                    final ITypeBinding binding = fTarget.getType();
1602:                    if (binding == null || binding.isTypeVariable())
1603:                        status
1604:                                .merge(RefactoringStatus
1605:                                        .createFatalErrorStatus(
1606:                                                RefactoringCoreMessages.MoveInstanceMethodProcessor_no_generic_targets,
1607:                                                JavaStatusContext
1608:                                                        .create(fMethod)));
1609:                } finally {
1610:                    monitor.done();
1611:                }
1612:            }
1613:
1614:            /**
1615:             * Checks whether the method has references to type variables or generic
1616:             * types.
1617:             * 
1618:             * @param monitor
1619:             *            the progress monitor to display progress
1620:             * @param declaration
1621:             *            the method declaration to check for generic types
1622:             * @param status
1623:             *            the status of the condition checking
1624:             */
1625:            protected void checkGenericTypes(final IProgressMonitor monitor,
1626:                    final MethodDeclaration declaration,
1627:                    final RefactoringStatus status) {
1628:                Assert.isNotNull(monitor);
1629:                Assert.isNotNull(declaration);
1630:                Assert.isNotNull(status);
1631:                try {
1632:                    monitor.beginTask("", 1); //$NON-NLS-1$
1633:                    monitor
1634:                            .setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking);
1635:                    final AstNodeFinder finder = new GenericReferenceFinder(
1636:                            declaration);
1637:                    declaration.accept(finder);
1638:                    if (!finder.getStatus().isOK())
1639:                        status.merge(finder.getStatus());
1640:                } finally {
1641:                    monitor.done();
1642:                }
1643:            }
1644:
1645:            /*
1646:             * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#checkInitialConditions(org.eclipse.core.runtime.IProgressMonitor)
1647:             */
1648:            public final RefactoringStatus checkInitialConditions(
1649:                    final IProgressMonitor monitor) throws CoreException,
1650:                    OperationCanceledException {
1651:                Assert.isNotNull(monitor);
1652:                final RefactoringStatus status = new RefactoringStatus();
1653:                try {
1654:                    monitor.beginTask("", 4); //$NON-NLS-1$
1655:                    monitor
1656:                            .setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking);
1657:                    status.merge(Checks.checkIfCuBroken(fMethod));
1658:                    if (!status.hasError()) {
1659:                        checkMethodDeclaration(new SubProgressMonitor(monitor,
1660:                                1), status);
1661:                        if (status.isOK()) {
1662:                            final MethodDeclaration declaration = ASTNodeSearchUtil
1663:                                    .getMethodDeclarationNode(fMethod,
1664:                                            fSourceRewrite.getRoot());
1665:                            checkGenericTypes(
1666:                                    new SubProgressMonitor(monitor, 1),
1667:                                    declaration, status);
1668:                            checkMethodBody(new SubProgressMonitor(monitor, 1),
1669:                                    declaration, status);
1670:                            checkPossibleTargets(new SubProgressMonitor(
1671:                                    monitor, 1), declaration, status);
1672:                        }
1673:                    }
1674:                } finally {
1675:                    monitor.done();
1676:                }
1677:                return status;
1678:            }
1679:
1680:            /**
1681:             * Checks whether the instance method body is compatible with this
1682:             * refactoring.
1683:             * 
1684:             * @param monitor
1685:             *            the progress monitor to display progress
1686:             * @param declaration
1687:             *            the method declaration whose body to check
1688:             * @param status
1689:             *            the status of the condition checking
1690:             */
1691:            protected void checkMethodBody(final IProgressMonitor monitor,
1692:                    final MethodDeclaration declaration,
1693:                    final RefactoringStatus status) {
1694:                Assert.isNotNull(monitor);
1695:                Assert.isNotNull(declaration);
1696:                Assert.isNotNull(status);
1697:                try {
1698:                    monitor.beginTask("", 3); //$NON-NLS-1$
1699:                    monitor
1700:                            .setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking);
1701:                    AstNodeFinder finder = new SuperReferenceFinder();
1702:                    declaration.accept(finder);
1703:                    if (!finder.getStatus().isOK())
1704:                        status.merge(finder.getStatus());
1705:                    monitor.worked(1);
1706:                    finder = null;
1707:                    final IMethodBinding binding = declaration.resolveBinding();
1708:                    if (binding != null) {
1709:                        final ITypeBinding declaring = binding
1710:                                .getDeclaringClass();
1711:                        if (declaring != null)
1712:                            finder = new EnclosingInstanceReferenceFinder(
1713:                                    declaring);
1714:                    }
1715:                    if (finder != null) {
1716:                        declaration.accept(finder);
1717:                        if (!finder.getStatus().isOK())
1718:                            status.merge(finder.getStatus());
1719:                        monitor.worked(1);
1720:                        finder = new RecursiveCallFinder(declaration);
1721:                        declaration.accept(finder);
1722:                        if (!finder.getStatus().isOK())
1723:                            status.merge(finder.getStatus());
1724:                        monitor.worked(1);
1725:                    }
1726:                } finally {
1727:                    monitor.done();
1728:                }
1729:            }
1730:
1731:            /**
1732:             * Checks whether the instance method declaration is compatible with this
1733:             * refactoring.
1734:             * 
1735:             * @param monitor
1736:             *            the progress monitor to display progress
1737:             * @param status
1738:             *            the status of the condition checking
1739:             * @throws JavaModelException
1740:             *             if the method does not exist
1741:             */
1742:            protected void checkMethodDeclaration(
1743:                    final IProgressMonitor monitor,
1744:                    final RefactoringStatus status) throws JavaModelException {
1745:                Assert.isNotNull(monitor);
1746:                Assert.isNotNull(status);
1747:                try {
1748:                    monitor.beginTask("", 5); //$NON-NLS-1$
1749:                    monitor
1750:                            .setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking);
1751:                    final int flags = fMethod.getFlags();
1752:                    if (Flags.isStatic(flags))
1753:                        status
1754:                                .merge(RefactoringStatus
1755:                                        .createFatalErrorStatus(
1756:                                                RefactoringCoreMessages.MoveInstanceMethodProcessor_no_static_methods,
1757:                                                JavaStatusContext
1758:                                                        .create(fMethod)));
1759:                    else if (Flags.isAbstract(flags))
1760:                        status
1761:                                .merge(RefactoringStatus
1762:                                        .createFatalErrorStatus(
1763:                                                RefactoringCoreMessages.MoveInstanceMethodProcessor_single_implementation,
1764:                                                JavaStatusContext
1765:                                                        .create(fMethod)));
1766:                    monitor.worked(1);
1767:                    if (Flags.isNative(flags))
1768:                        status
1769:                                .merge(RefactoringStatus
1770:                                        .createFatalErrorStatus(
1771:                                                RefactoringCoreMessages.MoveInstanceMethodProcessor_no_native_methods,
1772:                                                JavaStatusContext
1773:                                                        .create(fMethod)));
1774:                    monitor.worked(1);
1775:                    if (Flags.isSynchronized(flags))
1776:                        status
1777:                                .merge(RefactoringStatus
1778:                                        .createFatalErrorStatus(
1779:                                                RefactoringCoreMessages.MoveInstanceMethodProcessor_no_synchronized_methods,
1780:                                                JavaStatusContext
1781:                                                        .create(fMethod)));
1782:                    monitor.worked(1);
1783:                    if (fMethod.isConstructor())
1784:                        status
1785:                                .merge(RefactoringStatus
1786:                                        .createFatalErrorStatus(
1787:                                                RefactoringCoreMessages.MoveInstanceMethodProcessor_no_constructors,
1788:                                                JavaStatusContext
1789:                                                        .create(fMethod)));
1790:                    monitor.worked(1);
1791:                    if (fMethod.getDeclaringType().isAnnotation())
1792:                        status
1793:                                .merge(RefactoringStatus
1794:                                        .createFatalErrorStatus(
1795:                                                RefactoringCoreMessages.MoveInstanceMethodProcessor_no_annotation,
1796:                                                JavaStatusContext
1797:                                                        .create(fMethod)));
1798:                    else if (fMethod.getDeclaringType().isInterface())
1799:                        status
1800:                                .merge(RefactoringStatus
1801:                                        .createFatalErrorStatus(
1802:                                                RefactoringCoreMessages.MoveInstanceMethodProcessor_no_interface,
1803:                                                JavaStatusContext
1804:                                                        .create(fMethod)));
1805:                    monitor.worked(1);
1806:                } finally {
1807:                    monitor.done();
1808:                }
1809:            }
1810:
1811:            /**
1812:             * Checks whether the method has possible targets to be moved to
1813:             * 
1814:             * @param monitor
1815:             *            the progress monitor to display progress
1816:             * @param declaration
1817:             *            the method declaration to check
1818:             * @param status
1819:             *            the status of the condition checking
1820:             */
1821:            protected void checkPossibleTargets(final IProgressMonitor monitor,
1822:                    final MethodDeclaration declaration,
1823:                    final RefactoringStatus status) {
1824:                Assert.isNotNull(monitor);
1825:                Assert.isNotNull(declaration);
1826:                Assert.isNotNull(status);
1827:                try {
1828:                    monitor.beginTask("", 1); //$NON-NLS-1$
1829:                    monitor
1830:                            .setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking);
1831:                    if (computeTargetCategories(declaration).length < 1)
1832:                        status
1833:                                .merge(RefactoringStatus
1834:                                        .createFatalErrorStatus(
1835:                                                RefactoringCoreMessages.MoveInstanceMethodProcessor_cannot_be_moved,
1836:                                                JavaStatusContext
1837:                                                        .create(fMethod)));
1838:                } finally {
1839:                    monitor.done();
1840:                }
1841:            }
1842:
1843:            /**
1844:             * Searches for references to the original method.
1845:             * 
1846:             * @param monitor
1847:             *            the progress monitor to use
1848:             * @param status
1849:             *            the refactoring status to use
1850:             * @return the array of search result groups
1851:             * @throws CoreException
1852:             *             if an error occurred during search
1853:             */
1854:            protected SearchResultGroup[] computeMethodReferences(
1855:                    final IProgressMonitor monitor,
1856:                    final RefactoringStatus status) throws CoreException {
1857:                Assert.isNotNull(monitor);
1858:                Assert.isNotNull(status);
1859:                try {
1860:                    monitor.beginTask("", 1); //$NON-NLS-1$
1861:                    monitor
1862:                            .setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking);
1863:                    final RefactoringSearchEngine2 engine = new RefactoringSearchEngine2(
1864:                            SearchPattern.createPattern(fMethod,
1865:                                    IJavaSearchConstants.REFERENCES,
1866:                                    SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE));
1867:                    engine.setStatus(status);
1868:                    engine.searchPattern(new SubProgressMonitor(monitor, 1));
1869:                    return (SearchResultGroup[]) engine.getResults();
1870:                } finally {
1871:                    monitor.done();
1872:                }
1873:            }
1874:
1875:            /**
1876:             * Computes the files that are being modified by this refactoring.
1877:             * 
1878:             * @param source
1879:             *            the source compilation unit
1880:             * @param target
1881:             *            the target compilation unit
1882:             * @return the modified files
1883:             */
1884:            protected IFile[] computeModifiedFiles(
1885:                    final ICompilationUnit source, final ICompilationUnit target) {
1886:                Assert.isNotNull(source);
1887:                Assert.isNotNull(target);
1888:                if (source.equals(target))
1889:                    return ResourceUtil
1890:                            .getFiles(new ICompilationUnit[] { source });
1891:                return ResourceUtil.getFiles(new ICompilationUnit[] { source,
1892:                        target });
1893:            }
1894:
1895:            /**
1896:             * Returns the reserved identifiers in the method to move.
1897:             * 
1898:             * @return the reserved identifiers
1899:             * @throws JavaModelException
1900:             *             if the method declaration could not be found
1901:             */
1902:            protected String[] computeReservedIdentifiers()
1903:                    throws JavaModelException {
1904:                final List names = new ArrayList();
1905:                final MethodDeclaration declaration = ASTNodeSearchUtil
1906:                        .getMethodDeclarationNode(fMethod, fSourceRewrite
1907:                                .getRoot());
1908:                if (declaration != null) {
1909:                    final List parameters = declaration.parameters();
1910:                    VariableDeclaration variable = null;
1911:                    for (int index = 0; index < parameters.size(); index++) {
1912:                        variable = (VariableDeclaration) parameters.get(index);
1913:                        names.add(variable.getName().getIdentifier());
1914:                    }
1915:                    final Block body = declaration.getBody();
1916:                    if (body != null) {
1917:                        final IBinding[] bindings = new ScopeAnalyzer(
1918:                                fSourceRewrite.getRoot()).getDeclarationsAfter(
1919:                                body.getStartPosition(),
1920:                                ScopeAnalyzer.VARIABLES);
1921:                        for (int index = 0; index < bindings.length; index++)
1922:                            names.add(bindings[index].getName());
1923:                    }
1924:                }
1925:                final String[] result = new String[names.size()];
1926:                names.toArray(result);
1927:                return result;
1928:            }
1929:
1930:            /**
1931:             * Computes the target categories for the method to move.
1932:             * 
1933:             * @param declaration
1934:             *            the method declaration
1935:             * @return the possible targets as variable bindings of read-only fields and
1936:             *         parameters
1937:             */
1938:            protected IVariableBinding[] computeTargetCategories(
1939:                    final MethodDeclaration declaration) {
1940:                Assert.isNotNull(declaration);
1941:                if (fPossibleTargets.length == 0
1942:                        || fCandidateTargets.length == 0) {
1943:                    final List possibleTargets = new ArrayList(16);
1944:                    final List candidateTargets = new ArrayList(16);
1945:                    final IMethodBinding method = declaration.resolveBinding();
1946:                    if (method != null) {
1947:                        final ITypeBinding declaring = method
1948:                                .getDeclaringClass();
1949:                        IVariableBinding[] bindings = getArgumentBindings(declaration);
1950:                        ITypeBinding binding = null;
1951:                        for (int index = 0; index < bindings.length; index++) {
1952:                            binding = bindings[index].getType();
1953:                            if ((binding.isClass() || binding.isEnum())
1954:                                    && binding.isFromSource()) {
1955:                                possibleTargets.add(bindings[index]);
1956:                                candidateTargets.add(bindings[index]);
1957:                            }
1958:                        }
1959:                        final ReadyOnlyFieldFinder visitor = new ReadyOnlyFieldFinder(
1960:                                declaring);
1961:                        declaration.accept(visitor);
1962:                        bindings = visitor.getReadOnlyFields();
1963:                        for (int index = 0; index < bindings.length; index++) {
1964:                            binding = bindings[index].getType();
1965:                            if (binding.isClass() && binding.isFromSource())
1966:                                possibleTargets.add(bindings[index]);
1967:                        }
1968:                        bindings = visitor.getDeclaredFields();
1969:                        for (int index = 0; index < bindings.length; index++) {
1970:                            binding = bindings[index].getType();
1971:                            if (binding.isClass() && binding.isFromSource())
1972:                                candidateTargets.add(bindings[index]);
1973:                        }
1974:                    }
1975:                    fPossibleTargets = new IVariableBinding[possibleTargets
1976:                            .size()];
1977:                    possibleTargets.toArray(fPossibleTargets);
1978:                    fCandidateTargets = new IVariableBinding[candidateTargets
1979:                            .size()];
1980:                    candidateTargets.toArray(fCandidateTargets);
1981:                }
1982:                return fPossibleTargets;
1983:            }
1984:
1985:            /**
1986:             * Creates a visibility-adjusted target expression taking advantage of
1987:             * existing accessor methods.
1988:             * 
1989:             * @param enclosingElement
1990:             *            the java element which encloses the current method access.
1991:             * @param expression
1992:             *            the expression to access the target, or <code>null</code>
1993:             * @param adjustments
1994:             *            the map of elements to visibility adjustments
1995:             * @param rewrite
1996:             *            the ast rewrite to use
1997:             * @return an adjusted target expression, or <code>null</code> if the
1998:             *         access did not have to be changed
1999:             * @throws JavaModelException
2000:             *             if an error occurs while accessing the target expression
2001:             */
2002:            protected Expression createAdjustedTargetExpression(
2003:                    final IJavaElement enclosingElement,
2004:                    final Expression expression, final Map adjustments,
2005:                    final ASTRewrite rewrite) throws JavaModelException {
2006:                Assert.isNotNull(enclosingElement);
2007:                Assert.isNotNull(adjustments);
2008:                Assert.isNotNull(rewrite);
2009:                final IJavaElement element = fTarget.getJavaElement();
2010:                if (element != null
2011:                        && !Modifier.isPublic(fTarget.getModifiers())) {
2012:                    final IField field = (IField) fTarget.getJavaElement();
2013:                    if (field != null) {
2014:                        boolean same = field
2015:                                .getAncestor(IJavaElement.PACKAGE_FRAGMENT)
2016:                                .equals(
2017:                                        enclosingElement
2018:                                                .getAncestor(IJavaElement.PACKAGE_FRAGMENT));
2019:                        final Modifier.ModifierKeyword keyword = same ? null
2020:                                : Modifier.ModifierKeyword.PUBLIC_KEYWORD;
2021:                        final String modifier = same ? RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_default
2022:                                : RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_public;
2023:                        if (fUseGetters) {
2024:                            final IMethod getter = GetterSetterUtil
2025:                                    .getGetter(field);
2026:                            if (getter != null) {
2027:                                final MethodDeclaration method = ASTNodeSearchUtil
2028:                                        .getMethodDeclarationNode(getter,
2029:                                                fSourceRewrite.getRoot());
2030:                                if (method != null) {
2031:                                    final IMethodBinding binding = method
2032:                                            .resolveBinding();
2033:                                    if (binding != null
2034:                                            && MemberVisibilityAdjustor
2035:                                                    .hasLowerVisibility(
2036:                                                            getter.getFlags(),
2037:                                                            same ? Modifier.NONE
2038:                                                                    : (keyword == null ? Modifier.NONE
2039:                                                                            : keyword
2040:                                                                                    .toFlagValue()))
2041:                                            && MemberVisibilityAdjustor
2042:                                                    .needsVisibilityAdjustments(
2043:                                                            getter, keyword,
2044:                                                            adjustments))
2045:                                        adjustments
2046:                                                .put(
2047:                                                        getter,
2048:                                                        new MemberVisibilityAdjustor.OutgoingMemberVisibilityAdjustment(
2049:                                                                getter,
2050:                                                                keyword,
2051:                                                                RefactoringStatus
2052:                                                                        .createWarningStatus(
2053:                                                                                Messages
2054:                                                                                        .format(
2055:                                                                                                RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_method_warning,
2056:                                                                                                new String[] {
2057:                                                                                                        BindingLabelProvider
2058:                                                                                                                .getBindingLabel(
2059:                                                                                                                        binding,
2060:                                                                                                                        JavaElementLabels.ALL_FULLY_QUALIFIED),
2061:                                                                                                        modifier }),
2062:                                                                                JavaStatusContext
2063:                                                                                        .create(getter))));
2064:                                    final MethodInvocation invocation = rewrite
2065:                                            .getAST().newMethodInvocation();
2066:                                    invocation.setExpression(expression);
2067:                                    invocation.setName(rewrite.getAST()
2068:                                            .newSimpleName(
2069:                                                    getter.getElementName()));
2070:                                    return invocation;
2071:                                }
2072:                            }
2073:                        }
2074:                        if (MemberVisibilityAdjustor.hasLowerVisibility(field
2075:                                .getFlags(), (keyword == null ? Modifier.NONE
2076:                                : keyword.toFlagValue()))
2077:                                && MemberVisibilityAdjustor
2078:                                        .needsVisibilityAdjustments(field,
2079:                                                keyword, adjustments))
2080:                            adjustments
2081:                                    .put(
2082:                                            field,
2083:                                            new MemberVisibilityAdjustor.OutgoingMemberVisibilityAdjustment(
2084:                                                    field,
2085:                                                    keyword,
2086:                                                    RefactoringStatus
2087:                                                            .createWarningStatus(
2088:                                                                    Messages
2089:                                                                            .format(
2090:                                                                                    RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_field_warning,
2091:                                                                                    new String[] {
2092:                                                                                            BindingLabelProvider
2093:                                                                                                    .getBindingLabel(
2094:                                                                                                            fTarget,
2095:                                                                                                            JavaElementLabels.ALL_FULLY_QUALIFIED),
2096:                                                                                            modifier }),
2097:                                                                    JavaStatusContext
2098:                                                                            .create(field))));
2099:                    }
2100:                }
2101:                return null;
2102:            }
2103:
2104:            /**
2105:             * Creates a generic argument list of the refactored moved method
2106:             * 
2107:             * @param declaration
2108:             *            the method declaration of the method to move
2109:             * @param arguments
2110:             *            the argument list to create
2111:             * @param factory
2112:             *            the argument factory to use
2113:             * @return <code>true</code> if a target node had to be inserted as first
2114:             *         argument, <code>false</code> otherwise
2115:             * @throws JavaModelException
2116:             *             if an error occurs
2117:             */
2118:            protected boolean createArgumentList(
2119:                    final MethodDeclaration declaration, final List arguments,
2120:                    final IArgumentFactory factory) throws JavaModelException {
2121:                Assert.isNotNull(declaration);
2122:                Assert.isNotNull(arguments);
2123:                Assert.isNotNull(factory);
2124:                final AstNodeFinder finder = new ThisReferenceFinder();
2125:                declaration.accept(finder);
2126:                IVariableBinding binding = null;
2127:                VariableDeclaration variable = null;
2128:                boolean added = false;
2129:                final int size = declaration.parameters().size();
2130:                for (int index = 0; index < size; index++) {
2131:                    variable = (VariableDeclaration) declaration.parameters()
2132:                            .get(index);
2133:                    binding = variable.resolveBinding();
2134:                    if (binding != null) {
2135:                        if (!Bindings.equals(binding, fTarget))
2136:                            arguments.add(factory.getArgumentNode(binding,
2137:                                    index == size - 1));
2138:                        else if (!finder.getStatus().isOK()) {
2139:                            arguments.add(factory.getTargetNode());
2140:                            added = true;
2141:                        }
2142:                    } else
2143:                        arguments.add(factory.getArgumentNode(binding,
2144:                                index == size - 1));
2145:                }
2146:                if (!finder.getStatus().isOK() && !added) {
2147:                    arguments.add(0, factory.getTargetNode());
2148:                    added = true;
2149:                }
2150:                return added;
2151:            }
2152:
2153:            /*
2154:             * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#createChange(org.eclipse.core.runtime.IProgressMonitor)
2155:             */
2156:            public final Change createChange(final IProgressMonitor monitor)
2157:                    throws CoreException, OperationCanceledException {
2158:                Assert.isNotNull(monitor);
2159:                try {
2160:                    monitor.beginTask("", 6); //$NON-NLS-1$
2161:                    monitor
2162:                            .setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_creating);
2163:                    final TextChange[] changes = fChangeManager.getAllChanges();
2164:                    if (changes.length == 1)
2165:                        return changes[0];
2166:                    final List list = new ArrayList(changes.length);
2167:                    list.addAll(Arrays.asList(changes));
2168:                    final Map arguments = new HashMap();
2169:                    String project = null;
2170:                    final IJavaProject javaProject = fMethod.getJavaProject();
2171:                    if (javaProject != null)
2172:                        project = javaProject.getElementName();
2173:                    int flags = JavaRefactoringDescriptor.JAR_REFACTORING
2174:                            | JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT
2175:                            | RefactoringDescriptor.STRUCTURAL_CHANGE
2176:                            | RefactoringDescriptor.MULTI_CHANGE;
2177:                    final IType declaring = fMethod.getDeclaringType();
2178:                    try {
2179:                        if (declaring.isAnonymous() || declaring.isLocal())
2180:                            flags |= JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT;
2181:                    } catch (JavaModelException exception) {
2182:                        JavaPlugin.log(exception);
2183:                    }
2184:                    final String description = Messages
2185:                            .format(
2186:                                    RefactoringCoreMessages.MoveInstanceMethodProcessor_descriptor_description_short,
2187:                                    fMethod.getElementName());
2188:                    final String header = Messages
2189:                            .format(
2190:                                    RefactoringCoreMessages.MoveInstanceMethodProcessor_descriptor_description,
2191:                                    new String[] {
2192:                                            JavaElementLabels
2193:                                                    .getElementLabel(
2194:                                                            fMethod,
2195:                                                            JavaElementLabels.ALL_FULLY_QUALIFIED),
2196:                                            BindingLabelProvider
2197:                                                    .getBindingLabel(
2198:                                                            fTarget,
2199:                                                            JavaElementLabels.ALL_FULLY_QUALIFIED) });
2200:                    final JDTRefactoringDescriptorComment comment = new JDTRefactoringDescriptorComment(
2201:                            project, this , header);
2202:                    comment
2203:                            .addSetting(Messages
2204:                                    .format(
2205:                                            RefactoringCoreMessages.MoveInstanceMethodProcessor_moved_element_pattern,
2206:                                            RefactoringCoreMessages.JavaRefactoringDescriptor_not_available));
2207:                    comment
2208:                            .addSetting(Messages
2209:                                    .format(
2210:                                            RefactoringCoreMessages.MoveInstanceMethodProcessor_target_element_pattern,
2211:                                            BindingLabelProvider
2212:                                                    .getBindingLabel(
2213:                                                            fTarget,
2214:                                                            JavaElementLabels.ALL_FULLY_QUALIFIED)));
2215:                    comment
2216:                            .addSetting(Messages
2217:                                    .format(
2218:                                            RefactoringCoreMessages.MoveInstanceMethodProcessor_method_name_pattern,
2219:                                            getMethodName()));
2220:                    if (needsTargetNode())
2221:                        comment
2222:                                .addSetting(Messages
2223:                                        .format(
2224:                                                RefactoringCoreMessages.MoveInstanceMethodProcessor_parameter_name_pattern,
2225:                                                getTargetName()));
2226:                    final MoveMethodDescriptor descriptor = new MoveMethodDescriptor(
2227:                            project, description, comment.asString(),
2228:                            arguments, flags);
2229:                    arguments.put(
2230:                            JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT,
2231:                            JavaRefactoringDescriptorUtil.elementToHandle(
2232:                                    project, fMethod));
2233:                    arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME,
2234:                            fMethodName);
2235:                    arguments.put(ATTRIBUTE_TARGET_NAME, fTargetName);
2236:                    arguments.put(ATTRIBUTE_DEPRECATE, Boolean.valueOf(
2237:                            fDelegateDeprecation).toString());
2238:                    arguments.put(ATTRIBUTE_REMOVE, Boolean.valueOf(fRemove)
2239:                            .toString());
2240:                    arguments.put(ATTRIBUTE_INLINE, Boolean.valueOf(fInline)
2241:                            .toString());
2242:                    arguments.put(ATTRIBUTE_USE_GETTER, Boolean.valueOf(
2243:                            fUseGetters).toString());
2244:                    arguments.put(ATTRIBUTE_USE_SETTER, Boolean.valueOf(
2245:                            fUseSetters).toString());
2246:                    arguments.put(ATTRIBUTE_TARGET_INDEX, new Integer(
2247:                            getTargetIndex()).toString());
2248:                    return new DynamicValidationRefactoringChange(
2249:                            descriptor,
2250:                            RefactoringCoreMessages.MoveInstanceMethodRefactoring_name,
2251:                            (Change[]) list.toArray(new Change[list.size()]));
2252:                } finally {
2253:                    monitor.done();
2254:                }
2255:            }
2256:
2257:            /**
2258:             * Creates the text change manager for this processor.
2259:             * 
2260:             * @param status
2261:             *            the refactoring status
2262:             * @param monitor
2263:             *            the progress monitor to display progress
2264:             * @return the created text change manager
2265:             * @throws JavaModelException
2266:             *             if the method declaration could not be found
2267:             * @throws CoreException
2268:             *             if the changes could not be generated
2269:             */
2270:            protected TextChangeManager createChangeManager(
2271:                    final RefactoringStatus status,
2272:                    final IProgressMonitor monitor) throws JavaModelException,
2273:                    CoreException {
2274:                Assert.isNotNull(status);
2275:                Assert.isNotNull(monitor);
2276:                try {
2277:                    monitor.beginTask("", 7); //$NON-NLS-1$
2278:                    monitor
2279:                            .setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_creating);
2280:                    fSourceRewrite.clearASTAndImportRewrites();
2281:                    final TextChangeManager manager = new TextChangeManager();
2282:                    final CompilationUnitRewrite targetRewrite = fMethod
2283:                            .getCompilationUnit().equals(
2284:                                    getTargetType().getCompilationUnit()) ? fSourceRewrite
2285:                            : new CompilationUnitRewrite(getTargetType()
2286:                                    .getCompilationUnit());
2287:                    final MethodDeclaration declaration = ASTNodeSearchUtil
2288:                            .getMethodDeclarationNode(fMethod, fSourceRewrite
2289:                                    .getRoot());
2290:                    final SearchResultGroup[] references = computeMethodReferences(
2291:                            new SubProgressMonitor(monitor, 1), status);
2292:                    final Map rewrites = new HashMap(2);
2293:                    rewrites.put(fSourceRewrite.getCu(), fSourceRewrite);
2294:                    if (!fSourceRewrite.getCu().equals(targetRewrite.getCu()))
2295:                        rewrites.put(targetRewrite.getCu(), targetRewrite);
2296:                    final ASTRewrite sourceRewrite = ASTRewrite
2297:                            .create(fSourceRewrite.getRoot().getAST());
2298:                    final MemberVisibilityAdjustor adjustor = new MemberVisibilityAdjustor(
2299:                            fTargetType, fMethod);
2300:                    adjustor.setStatus(status);
2301:                    adjustor.setVisibilitySeverity(RefactoringStatus.WARNING);
2302:                    adjustor.setFailureSeverity(RefactoringStatus.WARNING);
2303:                    adjustor.setRewrites(rewrites);
2304:                    adjustor
2305:                            .setRewrite(sourceRewrite, fSourceRewrite.getRoot());
2306:                    adjustor
2307:                            .adjustVisibility(new SubProgressMonitor(monitor, 1));
2308:                    final IDocument document = new Document(fMethod
2309:                            .getCompilationUnit().getBuffer().getContents());
2310:                    final boolean target = createMethodCopy(document,
2311:                            declaration, sourceRewrite, rewrites, adjustor
2312:                                    .getAdjustments(), status,
2313:                            new SubProgressMonitor(monitor, 1));
2314:                    createMethodJavadocReferences(rewrites, declaration,
2315:                            references, target, status, new SubProgressMonitor(
2316:                                    monitor, 1));
2317:                    if (!fSourceRewrite.getCu().equals(targetRewrite.getCu()))
2318:                        createMethodImports(targetRewrite, declaration,
2319:                                new SubProgressMonitor(monitor, 1), status);
2320:                    boolean removable = false;
2321:                    if (fInline) {
2322:                        removable = createMethodDelegator(rewrites,
2323:                                declaration, references, adjustor
2324:                                        .getAdjustments(), target, status,
2325:                                new SubProgressMonitor(monitor, 1));
2326:                        if (fRemove && removable) {
2327:                            fSourceRewrite
2328:                                    .getASTRewrite()
2329:                                    .remove(
2330:                                            declaration,
2331:                                            fSourceRewrite
2332:                                                    .createGroupDescription(RefactoringCoreMessages.MoveInstanceMethodProcessor_remove_original_method));
2333:                            if (!fSourceRewrite.getCu().equals(
2334:                                    fTargetType.getCompilationUnit()))
2335:                                fSourceRewrite.getImportRemover()
2336:                                        .registerRemovedNode(declaration);
2337:                        }
2338:                    }
2339:                    if (!fRemove || !removable)
2340:                        createMethodDelegation(declaration, rewrites, adjustor
2341:                                .getAdjustments(), status,
2342:                                new SubProgressMonitor(monitor, 1));
2343:
2344:                    // Do not adjust visibility of a target field; references to the
2345:                    // field will be removed anyway.
2346:                    final IJavaElement targetElement = fTarget.getJavaElement();
2347:                    if (targetElement != null
2348:                            && targetElement instanceof  IField
2349:                            && (Flags.isPrivate(fMethod.getFlags()) || !fInline)) {
2350:                        final IVisibilityAdjustment adjustmentForTarget = (IVisibilityAdjustment) adjustor
2351:                                .getAdjustments().get(targetElement);
2352:                        if (adjustmentForTarget != null)
2353:                            adjustor.getAdjustments().remove(targetElement);
2354:                    }
2355:
2356:                    adjustor.rewriteVisibility(new SubProgressMonitor(monitor,
2357:                            1));
2358:                    sourceRewrite.rewriteAST(document, fMethod.getJavaProject()
2359:                            .getOptions(true));
2360:                    createMethodSignature(document, declaration, sourceRewrite,
2361:                            rewrites);
2362:                    ICompilationUnit unit = null;
2363:                    CompilationUnitRewrite rewrite = null;
2364:                    for (final Iterator iterator = rewrites.keySet().iterator(); iterator
2365:                            .hasNext();) {
2366:                        unit = (ICompilationUnit) iterator.next();
2367:                        rewrite = (CompilationUnitRewrite) rewrites.get(unit);
2368:                        manager.manage(unit, rewrite.createChange());
2369:                    }
2370:                    return manager;
2371:                } finally {
2372:                    monitor.done();
2373:                }
2374:            }
2375:
2376:            /**
2377:             * Creates the necessary change to inline a method invocation represented by
2378:             * a search match.
2379:             * 
2380:             * @param rewriter
2381:             *            the current compilation unit rewrite
2382:             * @param declaration
2383:             *            the source method declaration
2384:             * @param match
2385:             *            the search match representing the method invocation
2386:             * @param adjustments
2387:             *            the map of elements to visibility adjustments
2388:             * @param target
2389:             *            <code>true</code> if a target node had to be inserted as
2390:             *            first argument, <code>false</code> otherwise
2391:             * @param status
2392:             *            the refactoring status
2393:             * @return <code>true</code> if the inline change could be performed,
2394:             *         <code>false</code> otherwise
2395:             * @throws JavaModelException
2396:             *             if a problem occurred while creating the inlined target
2397:             *             expression for field targets
2398:             */
2399:            protected boolean createInlinedMethodInvocation(
2400:                    final CompilationUnitRewrite rewriter,
2401:                    final MethodDeclaration declaration,
2402:                    final SearchMatch match, final Map adjustments,
2403:                    final boolean target, final RefactoringStatus status)
2404:                    throws JavaModelException {
2405:                Assert.isNotNull(rewriter);
2406:                Assert.isNotNull(declaration);
2407:                Assert.isNotNull(match);
2408:                Assert.isNotNull(adjustments);
2409:                Assert.isNotNull(status);
2410:                boolean result = true;
2411:                final ASTRewrite rewrite = rewriter.getASTRewrite();
2412:                final ASTNode node = ASTNodeSearchUtil.findNode(match, rewriter
2413:                        .getRoot());
2414:                final TextEditGroup group = rewriter
2415:                        .createGroupDescription(RefactoringCoreMessages.MoveInstanceMethodProcessor_inline_method_invocation);
2416:                if (node instanceof  MethodInvocation) {
2417:                    final MethodInvocation invocation = (MethodInvocation) node;
2418:                    final ListRewrite list = rewrite.getListRewrite(invocation,
2419:                            MethodInvocation.ARGUMENTS_PROPERTY);
2420:                    if (fTarget.isField()) {
2421:                        Expression access = null;
2422:                        if (invocation.getExpression() != null) {
2423:                            access = createInlinedTargetExpression(rewriter,
2424:                                    (IJavaElement) match.getElement(),
2425:                                    invocation.getExpression(), adjustments,
2426:                                    status);
2427:                            rewrite.set(invocation,
2428:                                    MethodInvocation.EXPRESSION_PROPERTY,
2429:                                    access, group);
2430:                        } else
2431:                            rewrite.set(invocation,
2432:                                    MethodInvocation.EXPRESSION_PROPERTY,
2433:                                    rewrite.getAST().newSimpleName(
2434:                                            fTarget.getName()), group);
2435:                        if (target) {
2436:                            if (access == null
2437:                                    || !(access instanceof  FieldAccess))
2438:                                list.insertFirst(rewrite.getAST()
2439:                                        .newThisExpression(), null);
2440:                            else
2441:                                list.insertLast(rewrite
2442:                                        .createCopyTarget(invocation
2443:                                                .getExpression()), null);
2444:                        }
2445:                    } else {
2446:                        final IVariableBinding[] bindings = getArgumentBindings(declaration);
2447:                        if (bindings.length > 0) {
2448:                            int index = 0;
2449:                            for (; index < bindings.length; index++)
2450:                                if (Bindings.equals(bindings[index], fTarget))
2451:                                    break;
2452:                            if (index < bindings.length
2453:                                    && invocation.arguments().size() > index) {
2454:                                final Expression argument = (Expression) invocation
2455:                                        .arguments().get(index);
2456:                                if (argument instanceof  NullLiteral) {
2457:                                    status
2458:                                            .merge(RefactoringStatus
2459:                                                    .createErrorStatus(
2460:                                                            Messages
2461:                                                                    .format(
2462:                                                                            RefactoringCoreMessages.MoveInstanceMethodProcessor_no_null_argument,
2463:                                                                            BindingLabelProvider
2464:                                                                                    .getBindingLabel(
2465:                                                                                            declaration
2466:                                                                                                    .resolveBinding(),
2467:                                                                                            JavaElementLabels.ALL_FULLY_QUALIFIED)),
2468:                                                            JavaStatusContext
2469:                                                                    .create(
2470:                                                                            rewriter
2471:                                                                                    .getCu(),
2472:                                                                            invocation)));
2473:                                    result = false;
2474:                                } else {
2475:                                    if (argument instanceof  ThisExpression)
2476:                                        rewrite.remove(invocation
2477:                                                .getExpression(), null);
2478:                                    else
2479:                                        rewrite
2480:                                                .set(
2481:                                                        invocation,
2482:                                                        MethodInvocation.EXPRESSION_PROPERTY,
2483:                                                        rewrite
2484:                                                                .createCopyTarget(argument),
2485:                                                        group);
2486:                                    if (target) {
2487:                                        if (invocation.getExpression() != null)
2488:                                            list
2489:                                                    .replace(
2490:                                                            argument,
2491:                                                            rewrite
2492:                                                                    .createCopyTarget(invocation
2493:                                                                            .getExpression()),
2494:                                                            group);
2495:                                        else {
2496:                                            final ThisExpression expression = rewrite
2497:                                                    .getAST()
2498:                                                    .newThisExpression();
2499:                                            final AbstractTypeDeclaration member = (AbstractTypeDeclaration) ASTNodes
2500:                                                    .getParent(
2501:                                                            invocation,
2502:                                                            AbstractTypeDeclaration.class);
2503:                                            if (member != null) {
2504:                                                final ITypeBinding resolved = member
2505:                                                        .resolveBinding();
2506:                                                if (ASTNodes
2507:                                                        .getParent(
2508:                                                                invocation,
2509:                                                                AnonymousClassDeclaration.class) != null
2510:                                                        || (resolved != null && resolved
2511:                                                                .isMember())) {
2512:                                                    final IMethodBinding method = declaration
2513:                                                            .resolveBinding();
2514:                                                    if (method != null) {
2515:                                                        final ITypeBinding declaring = method
2516:                                                                .getDeclaringClass();
2517:                                                        if (declaring != null)
2518:                                                            expression
2519:                                                                    .setQualifier(rewrite
2520:                                                                            .getAST()
2521:                                                                            .newSimpleName(
2522:                                                                                    declaring
2523:                                                                                            .getName()));
2524:                                                    }
2525:                                                }
2526:                                            }
2527:                                            list.replace(argument, expression,
2528:                                                    group);
2529:                                        }
2530:                                    } else
2531:                                        list.remove(argument, group);
2532:                                }
2533:                            }
2534:                        }
2535:                    }
2536:                    if (result)
2537:                        rewrite.set(invocation, MethodInvocation.NAME_PROPERTY,
2538:                                rewrite.getAST().newSimpleName(fMethodName),
2539:                                group);
2540:                }
2541:                return result;
2542:            }
2543:
2544:            /**
2545:             * Creates the target field expression for the inline method invocation.
2546:             * 
2547:             * @param rewriter
2548:             *            the current compilation unit rewrite
2549:             * @param enclosingElement
2550:             *            the enclosing java element of the method invocation.
2551:             * @param original
2552:             *            the original method invocation expression
2553:             * @param adjustments
2554:             *            the map of elements to visibility adjustments
2555:             * @param status
2556:             *            the refactoring status
2557:             * @return
2558:             * 			   returns the target expression
2559:             * @throws JavaModelException
2560:             *             if a problem occurred while retrieving potential getter
2561:             *             methods of the target
2562:             */
2563:            protected Expression createInlinedTargetExpression(
2564:                    final CompilationUnitRewrite rewriter,
2565:                    final IJavaElement enclosingElement,
2566:                    final Expression original, final Map adjustments,
2567:                    final RefactoringStatus status) throws JavaModelException {
2568:                Assert.isNotNull(rewriter);
2569:                Assert.isNotNull(enclosingElement);
2570:                Assert.isNotNull(original);
2571:                Assert.isNotNull(adjustments);
2572:                Assert.isNotNull(status);
2573:                Assert.isTrue(fTarget.isField());
2574:                final Expression expression = (Expression) ASTNode.copySubtree(
2575:                        fSourceRewrite.getASTRewrite().getAST(), original);
2576:                final Expression result = createAdjustedTargetExpression(
2577:                        enclosingElement, expression, adjustments,
2578:                        fSourceRewrite.getASTRewrite());
2579:                if (result == null) {
2580:                    final FieldAccess access = fSourceRewrite.getASTRewrite()
2581:                            .getAST().newFieldAccess();
2582:                    access.setExpression(expression);
2583:                    access.setName(fSourceRewrite.getASTRewrite().getAST()
2584:                            .newSimpleName(fTarget.getName()));
2585:                    return access;
2586:                }
2587:                return result;
2588:            }
2589:
2590:            /**
2591:             * Creates the method arguments for the target method declaration.
2592:             * 
2593:             * @param rewrites
2594:             *            the compilation unit rewrites
2595:             * @param rewrite
2596:             *            the source ast rewrite
2597:             * @param declaration
2598:             *            the source method declaration
2599:             * @param adjustments
2600:             *            the map of elements to visibility adjustments
2601:             * @param status
2602:             *            the refactoring status
2603:             * @return <code>true</code> if a target node had to be inserted as method
2604:             *         argument, <code>false</code> otherwise
2605:             * @throws JavaModelException
2606:             *             if an error occurs while accessing the types of the arguments
2607:             */
2608:            protected boolean createMethodArguments(final Map rewrites,
2609:                    final ASTRewrite rewrite,
2610:                    final MethodDeclaration declaration, final Map adjustments,
2611:                    final RefactoringStatus status) throws JavaModelException {
2612:                Assert.isNotNull(rewrites);
2613:                Assert.isNotNull(declaration);
2614:                Assert.isNotNull(rewrite);
2615:                Assert.isNotNull(adjustments);
2616:                Assert.isNotNull(status);
2617:                final CompilationUnitRewrite rewriter = getCompilationUnitRewrite(
2618:                        rewrites, getTargetType().getCompilationUnit());
2619:                final AST ast = rewriter.getRoot().getAST();
2620:                final AstNodeFinder finder = new AnonymousClassReferenceFinder(
2621:                        declaration);
2622:                declaration.accept(finder);
2623:                final List arguments = new ArrayList(declaration.parameters()
2624:                        .size() + 1);
2625:                final boolean result = createArgumentList(declaration,
2626:                        arguments, new VisibilityAdjustingArgumentFactory(ast,
2627:                                rewrites, adjustments) {
2628:
2629:                            public final ASTNode getArgumentNode(
2630:                                    final IVariableBinding binding,
2631:                                    final boolean last)
2632:                                    throws JavaModelException {
2633:                                Assert.isNotNull(binding);
2634:                                final SingleVariableDeclaration variable = ast
2635:                                        .newSingleVariableDeclaration();
2636:                                final ITypeBinding type = binding.getType();
2637:                                adjustTypeVisibility(type);
2638:                                variable.setName(ast.newSimpleName(binding
2639:                                        .getName()));
2640:                                variable.modifiers().addAll(
2641:                                        ast
2642:                                                .newModifiers(binding
2643:                                                        .getModifiers()));
2644:                                final IMethodBinding method = binding
2645:                                        .getDeclaringMethod();
2646:                                if (last && method != null
2647:                                        && method.isVarargs()) {
2648:                                    variable.setVarargs(true);
2649:                                    String name = null;
2650:                                    if (type.isArray()) {
2651:                                        name = type.getElementType().getName();
2652:                                        if (PrimitiveType.toCode(name) != null)
2653:                                            variable
2654:                                                    .setType(ast
2655:                                                            .newPrimitiveType(PrimitiveType
2656:                                                                    .toCode(name)));
2657:                                        else
2658:                                            variable
2659:                                                    .setType(ast
2660:                                                            .newSimpleType(ast
2661:                                                                    .newSimpleName(name)));
2662:                                    } else {
2663:                                        name = type.getName();
2664:                                        if (PrimitiveType.toCode(name) != null)
2665:                                            variable
2666:                                                    .setType(ast
2667:                                                            .newPrimitiveType(PrimitiveType
2668:                                                                    .toCode(name)));
2669:                                        else
2670:                                            variable
2671:                                                    .setType(ast
2672:                                                            .newSimpleType(ast
2673:                                                                    .newSimpleName(name)));
2674:                                    }
2675:                                } else
2676:                                    variable.setType(rewriter
2677:                                            .getImportRewrite().addImport(type,
2678:                                                    ast));
2679:                                return variable;
2680:                            }
2681:
2682:                            public final ASTNode getTargetNode()
2683:                                    throws JavaModelException {
2684:                                final SingleVariableDeclaration variable = ast
2685:                                        .newSingleVariableDeclaration();
2686:                                final IMethodBinding method = declaration
2687:                                        .resolveBinding();
2688:                                if (method != null) {
2689:                                    final ITypeBinding declaring = method
2690:                                            .getDeclaringClass();
2691:                                    if (declaring != null) {
2692:                                        adjustTypeVisibility(declaring);
2693:                                        variable.setType(rewriter
2694:                                                .getImportRewrite().addImport(
2695:                                                        declaring, ast));
2696:                                        variable.setName(ast
2697:                                                .newSimpleName(fTargetName));
2698:                                        if (finder.getResult().size() > 0)
2699:                                            variable
2700:                                                    .modifiers()
2701:                                                    .add(
2702:                                                            ast
2703:                                                                    .newModifier(Modifier.ModifierKeyword.FINAL_KEYWORD));
2704:                                    }
2705:                                }
2706:                                return variable;
2707:                            }
2708:                        });
2709:                final ListRewrite list = rewrite.getListRewrite(declaration,
2710:                        MethodDeclaration.PARAMETERS_PROPERTY);
2711:                ASTNode node = null;
2712:                for (final Iterator iterator = declaration.parameters()
2713:                        .iterator(); iterator.hasNext();) {
2714:                    node = (ASTNode) iterator.next();
2715:                    list.remove(node, null);
2716:                }
2717:                for (final Iterator iterator = arguments.iterator(); iterator
2718:                        .hasNext();) {
2719:                    node = (ASTNode) iterator.next();
2720:                    list.insertLast(node, null);
2721:                }
2722:                return result;
2723:            }
2724:
2725:            /**
2726:             * Creates the method body for the target method declaration.
2727:             * 
2728:             * @param rewriter
2729:             *            the target compilation unit rewrite
2730:             * @param rewrite
2731:             *            the source ast rewrite
2732:             * @param declaration
2733:             *            the source method declaration
2734:             */
2735:            protected void createMethodBody(
2736:                    final CompilationUnitRewrite rewriter,
2737:                    final ASTRewrite rewrite,
2738:                    final MethodDeclaration declaration) {
2739:                Assert.isNotNull(declaration);
2740:                declaration.getBody().accept(
2741:                        new MethodBodyRewriter(rewriter, rewrite, declaration));
2742:            }
2743:
2744:            /**
2745:             * Creates the method comment for the target method declaration.
2746:             * 
2747:             * @param rewrite
2748:             *            the source ast rewrite
2749:             * @param declaration
2750:             *            the source method declaration
2751:             * @throws JavaModelException
2752:             *             if the argument references could not be generated
2753:             */
2754:            protected void createMethodComment(final ASTRewrite rewrite,
2755:                    final MethodDeclaration declaration)
2756:                    throws JavaModelException {
2757:                Assert.isNotNull(rewrite);
2758:                Assert.isNotNull(declaration);
2759:                final Javadoc comment = declaration.getJavadoc();
2760:                if (comment != null) {
2761:                    final List tags = new LinkedList(comment.tags());
2762:                    final IVariableBinding[] bindings = getArgumentBindings(declaration);
2763:                    final Map elements = new HashMap(bindings.length);
2764:                    String name = null;
2765:                    List fragments = null;
2766:                    TagElement element = null;
2767:                    TagElement reference = null;
2768:                    IVariableBinding binding = null;
2769:                    for (int index = 0; index < bindings.length; index++) {
2770:                        binding = bindings[index];
2771:                        for (final Iterator iterator = comment.tags()
2772:                                .iterator(); iterator.hasNext();) {
2773:                            element = (TagElement) iterator.next();
2774:                            name = element.getTagName();
2775:                            fragments = element.fragments();
2776:                            if (name != null) {
2777:                                if (name.equals(TagElement.TAG_PARAM)
2778:                                        && !fragments.isEmpty()
2779:                                        && fragments.get(0) instanceof  SimpleName) {
2780:                                    final SimpleName simple = (SimpleName) fragments
2781:                                            .get(0);
2782:                                    if (binding.getName().equals(
2783:                                            simple.getIdentifier())) {
2784:                                        elements.put(binding.getKey(), element);
2785:                                        tags.remove(element);
2786:                                    }
2787:                                } else if (reference == null)
2788:                                    reference = element;
2789:                            }
2790:                        }
2791:                    }
2792:                    if (bindings.length == 0 && reference == null) {
2793:                        for (final Iterator iterator = comment.tags()
2794:                                .iterator(); iterator.hasNext();) {
2795:                            element = (TagElement) iterator.next();
2796:                            name = element.getTagName();
2797:                            fragments = element.fragments();
2798:                            if (name != null
2799:                                    && !name.equals(TagElement.TAG_PARAM))
2800:                                reference = element;
2801:                        }
2802:                    }
2803:                    final List arguments = new ArrayList(bindings.length + 1);
2804:                    createArgumentList(declaration, arguments,
2805:                            new IArgumentFactory() {
2806:
2807:                                public final ASTNode getArgumentNode(
2808:                                        final IVariableBinding argument,
2809:                                        final boolean last)
2810:                                        throws JavaModelException {
2811:                                    Assert.isNotNull(argument);
2812:                                    if (elements.containsKey(argument.getKey()))
2813:                                        return rewrite
2814:                                                .createCopyTarget((ASTNode) elements
2815:                                                        .get(argument.getKey()));
2816:                                    return JavadocUtil.createParamTag(argument
2817:                                            .getName(), declaration.getAST(),
2818:                                            fMethod.getJavaProject());
2819:                                }
2820:
2821:                                public final ASTNode getTargetNode()
2822:                                        throws JavaModelException {
2823:                                    return JavadocUtil.createParamTag(
2824:                                            fTargetName, declaration.getAST(),
2825:                                            fMethod.getJavaProject());
2826:                                }
2827:                            });
2828:                    final ListRewrite rewriter = rewrite.getListRewrite(
2829:                            comment, Javadoc.TAGS_PROPERTY);
2830:                    ASTNode tag = null;
2831:                    for (final Iterator iterator = comment.tags().iterator(); iterator
2832:                            .hasNext();) {
2833:                        tag = (ASTNode) iterator.next();
2834:                        if (!tags.contains(tag))
2835:                            rewriter.remove(tag, null);
2836:                    }
2837:                    for (final Iterator iterator = arguments.iterator(); iterator
2838:                            .hasNext();) {
2839:                        tag = (ASTNode) iterator.next();
2840:                        if (reference != null)
2841:                            rewriter.insertBefore(tag, reference, null);
2842:                        else
2843:                            rewriter.insertLast(tag, null);
2844:                    }
2845:                }
2846:            }
2847:
2848:            /**
2849:             * Creates the method content of the moved method.
2850:             * 
2851:             * @param document
2852:             *            the document representing the source compilation unit
2853:             * @param declaration
2854:             *            the source method declaration
2855:             * @param rewrite
2856:             *            the ast rewrite to use
2857:             * @return the string representing the moved method body
2858:             * @throws BadLocationException
2859:             *             if an offset into the document is invalid
2860:             */
2861:            protected String createMethodContent(final IDocument document,
2862:                    final MethodDeclaration declaration,
2863:                    final ASTRewrite rewrite) throws BadLocationException {
2864:                Assert.isNotNull(document);
2865:                Assert.isNotNull(declaration);
2866:                Assert.isNotNull(rewrite);
2867:                final IRegion range = new Region(
2868:                        declaration.getStartPosition(), declaration.getLength());
2869:                final RangeMarker marker = new RangeMarker(range.getOffset(),
2870:                        range.getLength());
2871:                final IJavaProject project = fMethod.getJavaProject();
2872:                final TextEdit[] edits = rewrite.rewriteAST(document,
2873:                        project.getOptions(true)).removeChildren();
2874:                for (int index = 0; index < edits.length; index++)
2875:                    marker.addChild(edits[index]);
2876:                final MultiTextEdit result = new MultiTextEdit();
2877:                result.addChild(marker);
2878:                final TextEditProcessor processor = new TextEditProcessor(
2879:                        document, new MultiTextEdit(0, document.getLength()),
2880:                        TextEdit.UPDATE_REGIONS);
2881:                processor.getRoot().addChild(result);
2882:                processor.performEdits();
2883:                final IRegion region = document.getLineInformation(document
2884:                        .getLineOfOffset(marker.getOffset()));
2885:                return Strings.changeIndent(document.get(marker.getOffset(),
2886:                        marker.getLength()), Strings.computeIndentUnits(
2887:                        document.get(region.getOffset(), region.getLength()),
2888:                        project), project,
2889:                        "", TextUtilities.getDefaultLineDelimiter(document)); //$NON-NLS-1$
2890:            }
2891:
2892:            /**
2893:             * Creates the necessary changes to create the delegate method with the
2894:             * original method body.
2895:             * 
2896:             * @param document
2897:             *            the buffer containing the source of the source compilation
2898:             *            unit
2899:             * @param declaration
2900:             *            the method declaration to use as source
2901:             * @param rewrite
2902:             *            the ast rewrite to use for the copy of the method body
2903:             * @param rewrites
2904:             *            the compilation unit rewrites
2905:             * @param adjustments
2906:             *            the map of elements to visibility adjustments
2907:             * @param status
2908:             *            the refactoring status
2909:             * @param monitor
2910:             *            the progress monitor to display progress
2911:             * @throws CoreException
2912:             *             if an error occurs
2913:             * @return <code>true</code> if a target node had to be inserted as first
2914:             *         argument, <code>false</code> otherwise
2915:             */
2916:            protected boolean createMethodCopy(final IDocument document,
2917:                    final MethodDeclaration declaration,
2918:                    final ASTRewrite rewrite, final Map rewrites,
2919:                    final Map adjustments, final RefactoringStatus status,
2920:                    final IProgressMonitor monitor) throws CoreException {
2921:                Assert.isNotNull(document);
2922:                Assert.isNotNull(declaration);
2923:                Assert.isNotNull(rewrite);
2924:                Assert.isNotNull(rewrites);
2925:                Assert.isNotNull(adjustments);
2926:                Assert.isNotNull(status);
2927:                Assert.isNotNull(monitor);
2928:                boolean target = false;
2929:                final CompilationUnitRewrite rewriter = getCompilationUnitRewrite(
2930:                        rewrites, getTargetType().getCompilationUnit());
2931:                try {
2932:                    rewrite.set(declaration, MethodDeclaration.NAME_PROPERTY,
2933:                            rewrite.getAST().newSimpleName(fMethodName), null);
2934:                    boolean same = false;
2935:                    final IMethodBinding binding = declaration.resolveBinding();
2936:                    if (binding != null) {
2937:                        final ITypeBinding declaring = binding
2938:                                .getDeclaringClass();
2939:                        if (declaring != null
2940:                                && Bindings.equals(declaring.getPackage(),
2941:                                        fTarget.getType().getPackage()))
2942:                            same = true;
2943:                        final Modifier.ModifierKeyword keyword = same ? null
2944:                                : Modifier.ModifierKeyword.PUBLIC_KEYWORD;
2945:                        if (MemberVisibilityAdjustor.hasLowerVisibility(binding
2946:                                .getModifiers(), same ? Modifier.NONE
2947:                                : (keyword == null ? Modifier.NONE : keyword
2948:                                        .toFlagValue()))
2949:                                && MemberVisibilityAdjustor
2950:                                        .needsVisibilityAdjustments(fMethod,
2951:                                                keyword, adjustments)) {
2952:                            final MemberVisibilityAdjustor.IncomingMemberVisibilityAdjustment adjustment = new MemberVisibilityAdjustor.IncomingMemberVisibilityAdjustment(
2953:                                    fMethod,
2954:                                    keyword,
2955:                                    RefactoringStatus
2956:                                            .createStatus(
2957:                                                    RefactoringStatus.WARNING,
2958:                                                    Messages
2959:                                                            .format(
2960:                                                                    RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_method_warning,
2961:                                                                    new String[] {
2962:                                                                            MemberVisibilityAdjustor
2963:                                                                                    .getLabel(fMethod),
2964:                                                                            MemberVisibilityAdjustor
2965:                                                                                    .getLabel(keyword) }),
2966:                                                    JavaStatusContext
2967:                                                            .create(fMethod),
2968:                                                    null,
2969:                                                    RefactoringStatusEntry.NO_CODE,
2970:                                                    null));
2971:                            ModifierRewrite.create(rewrite, declaration)
2972:                                    .setVisibility(
2973:                                            keyword == null ? Modifier.NONE
2974:                                                    : keyword.toFlagValue(),
2975:                                            null);
2976:                            adjustment.setNeedsRewriting(false);
2977:                            adjustments.put(fMethod, adjustment);
2978:                        }
2979:                    }
2980:                    target = createMethodArguments(rewrites, rewrite,
2981:                            declaration, adjustments, status);
2982:                    createMethodTypeParameters(rewrite, declaration, status);
2983:                    createMethodComment(rewrite, declaration);
2984:                    createMethodBody(rewriter, rewrite, declaration);
2985:                } finally {
2986:                    if (fMethod.getCompilationUnit().equals(
2987:                            getTargetType().getCompilationUnit()))
2988:                        rewriter.clearImportRewrites();
2989:                }
2990:                return target;
2991:            }
2992:
2993:            /**
2994:             * Creates the necessary changes to replace the body of the method
2995:             * declaration with an expression to invoke the delegate.
2996:             * 
2997:             * @param declaration
2998:             *            the method declaration to replace its body
2999:             * @param rewrites
3000:             *            the compilation unit rewrites
3001:             * @param adjustments
3002:             *            the map of elements to visibility adjustments
3003:             * @param status
3004:             *            the refactoring status
3005:             * @param monitor
3006:             *            the progress monitor to display progress
3007:             * @throws CoreException
3008:             *             if the change could not be generated
3009:             * @return <code>true</code> if a target node had to be inserted as first
3010:             *         argument, <code>false</code> otherwise
3011:             */
3012:            protected boolean createMethodDelegation(
3013:                    final MethodDeclaration declaration, final Map rewrites,
3014:                    final Map adjustments, final RefactoringStatus status,
3015:                    final IProgressMonitor monitor) throws CoreException {
3016:                Assert.isNotNull(declaration);
3017:                Assert.isNotNull(monitor);
3018:
3019:                final DelegateInstanceMethodCreator creator = new DelegateInstanceMethodCreator(
3020:                        adjustments, rewrites);
3021:                creator.setSourceRewrite(fSourceRewrite);
3022:                creator.setCopy(false);
3023:                creator.setDeclareDeprecated(fDelegateDeprecation);
3024:                creator.setDeclaration(declaration);
3025:                creator.setNewElementName(fMethodName);
3026:                creator.prepareDelegate();
3027:                creator.createEdit();
3028:
3029:                return creator.getNeededInsertion();
3030:            }
3031:
3032:            /**
3033:             * Creates the necessary changes to inline the method invocations to the
3034:             * original method.
3035:             * 
3036:             * @param rewrites
3037:             *            the map of compilation units to compilation unit rewrites
3038:             * @param declaration
3039:             *            the source method declaration
3040:             * @param groups
3041:             *            the search result groups representing all references to the
3042:             *            moved method, including references in comments
3043:             * @param adjustments
3044:             *            the map of elements to visibility adjustments
3045:             * @param target
3046:             *            <code>true</code> if a target node must be inserted as first
3047:             *            argument, <code>false</code> otherwise
3048:             * @param status
3049:             *            the refactoring status
3050:             * @param monitor
3051:             *            the progress monitor to use
3052:             * @return <code>true</code> if all method invocations to the original
3053:             *         method declaration could be inlined, <code>false</code>
3054:             *         otherwise
3055:             */
3056:            protected boolean createMethodDelegator(final Map rewrites,
3057:                    final MethodDeclaration declaration,
3058:                    final SearchResultGroup[] groups, final Map adjustments,
3059:                    final boolean target, final RefactoringStatus status,
3060:                    final IProgressMonitor monitor) {
3061:                Assert.isNotNull(rewrites);
3062:                Assert.isNotNull(declaration);
3063:                Assert.isNotNull(groups);
3064:                Assert.isNotNull(adjustments);
3065:                Assert.isNotNull(status);
3066:                Assert.isNotNull(monitor);
3067:                try {
3068:                    monitor.beginTask("", groups.length); //$NON-NLS-1$
3069:                    monitor
3070:                            .setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_creating);
3071:                    try {
3072:                        boolean result = true;
3073:                        boolean found = false;
3074:                        final ITypeHierarchy hierarchy = fMethod
3075:                                .getDeclaringType().newTypeHierarchy(
3076:                                        new SubProgressMonitor(monitor, 1));
3077:                        IType type = null;
3078:                        IMethod method = null;
3079:                        IType[] types = hierarchy.getAllSubtypes(fMethod
3080:                                .getDeclaringType());
3081:                        for (int index = 0; index < types.length && !found; index++) {
3082:                            type = types[index];
3083:                            method = JavaModelUtil.findMethod(fMethod
3084:                                    .getElementName(), fMethod
3085:                                    .getParameterTypes(), false, type);
3086:                            if (method != null)
3087:                                found = true;
3088:                        }
3089:                        types = hierarchy.getAllSupertypes(fMethod
3090:                                .getDeclaringType());
3091:                        for (int index = 0; index < types.length && !found; index++) {
3092:                            type = types[index];
3093:                            method = JavaModelUtil.findMethod(fMethod
3094:                                    .getElementName(), fMethod
3095:                                    .getParameterTypes(), false, type);
3096:                            if (method != null)
3097:                                found = true;
3098:                        }
3099:                        if (found) {
3100:                            status
3101:                                    .merge(RefactoringStatus
3102:                                            .createWarningStatus(
3103:                                                    Messages
3104:                                                            .format(
3105:                                                                    RefactoringCoreMessages.MoveInstanceMethodProcessor_inline_overridden,
3106:                                                                    BindingLabelProvider
3107:                                                                            .getBindingLabel(
3108:                                                                                    declaration
3109:                                                                                            .resolveBinding(),
3110:                                                                                    JavaElementLabels.ALL_FULLY_QUALIFIED)),
3111:                                                    JavaStatusContext
3112:                                                            .create(fMethod)));
3113:                            result = false;
3114:                        } else {
3115:                            monitor.worked(1);
3116:                            SearchMatch[] matches = null;
3117:                            IJavaElement element = null;
3118:                            ICompilationUnit unit = null;
3119:                            CompilationUnitRewrite rewrite = null;
3120:                            SearchResultGroup group = null;
3121:                            for (int index = 0; index < groups.length; index++) {
3122:                                group = groups[index];
3123:                                element = JavaCore.create(group.getResource());
3124:                                if (element instanceof  ICompilationUnit) {
3125:                                    matches = group.getSearchResults();
3126:                                    unit = (ICompilationUnit) element;
3127:                                    rewrite = getCompilationUnitRewrite(
3128:                                            rewrites, unit);
3129:                                    SearchMatch match = null;
3130:                                    for (int offset = 0; offset < matches.length; offset++) {
3131:                                        match = matches[offset];
3132:                                        if (match.getAccuracy() == SearchMatch.A_INACCURATE) {
3133:                                            status
3134:                                                    .merge(RefactoringStatus
3135:                                                            .createWarningStatus(
3136:                                                                    Messages
3137:                                                                            .format(
3138:                                                                                    RefactoringCoreMessages.MoveInstanceMethodProcessor_inline_inaccurate,
3139:                                                                                    unit
3140:                                                                                            .getCorrespondingResource()
3141:                                                                                            .getName()),
3142:                                                                    JavaStatusContext
3143:                                                                            .create(
3144:                                                                                    unit,
3145:                                                                                    new SourceRange(
3146:                                                                                            match
3147:                                                                                                    .getOffset(),
3148:                                                                                            match
3149:                                                                                                    .getLength()))));
3150:                                            result = false;
3151:                                        } else if (!createInlinedMethodInvocation(
3152:                                                rewrite, declaration, match,
3153:                                                adjustments, target, status))
3154:                                            result = false;
3155:                                    }
3156:                                } else if (element != null) {
3157:                                    status
3158:                                            .merge(RefactoringStatus
3159:                                                    .createWarningStatus(Messages
3160:                                                            .format(
3161:                                                                    RefactoringCoreMessages.MoveInstanceMethodProcessor_inline_binary_project,
3162:                                                                    element
3163:                                                                            .getJavaProject()
3164:                                                                            .getElementName())));
3165:                                    result = false;
3166:                                } else {
3167:                                    status
3168:                                            .merge(RefactoringStatus
3169:                                                    .createWarningStatus(Messages
3170:                                                            .format(
3171:                                                                    RefactoringCoreMessages.MoveInstanceMethodProcessor_inline_binary_resource,
3172:                                                                    group
3173:                                                                            .getResource()
3174:                                                                            .getName())));
3175:                                    result = false;
3176:                                }
3177:                            }
3178:                            monitor.worked(1);
3179:                        }
3180:                        return result;
3181:                    } catch (CoreException exception) {
3182:                        status.merge(RefactoringStatus.create(exception
3183:                                .getStatus()));
3184:                        return false;
3185:                    }
3186:                } finally {
3187:                    monitor.done();
3188:                }
3189:            }
3190:
3191:            /**
3192:             * Creates the necessary imports for the copied method in the target
3193:             * compilation unit.
3194:             * 
3195:             * @param rewrite
3196:             *            the target compilation unit rewrite
3197:             * @param declaration
3198:             *            the source method declaration
3199:             * @param monitor
3200:             *            the progress monitor to use
3201:             * @param status
3202:             *            the refactoring status to use
3203:             * @throws CoreException
3204:             *             if an error occurs
3205:             */
3206:            protected void createMethodImports(
3207:                    final CompilationUnitRewrite rewrite,
3208:                    final MethodDeclaration declaration,
3209:                    final IProgressMonitor monitor,
3210:                    final RefactoringStatus status) throws CoreException {
3211:                Assert.isNotNull(rewrite);
3212:                Assert.isNotNull(declaration);
3213:                Assert.isNotNull(monitor);
3214:                Assert.isNotNull(status);
3215:                monitor.beginTask("", 1); //$NON-NLS-1$
3216:                monitor
3217:                        .setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_creating);
3218:                try {
3219:                    ImportRewriteUtil.addImports(rewrite, declaration,
3220:                            new HashMap(), new HashMap(), false);
3221:                } finally {
3222:                    monitor.done();
3223:                }
3224:            }
3225:
3226:            /**
3227:             * Creates the necessary change to updated a comment reference represented
3228:             * by a search match.
3229:             * 
3230:             * @param rewrite
3231:             *            the current compilation unit rewrite
3232:             * @param declaration
3233:             *            the source method declaration
3234:             * @param match
3235:             *            the search match representing the method reference
3236:             * @param targetNode
3237:             *            <code>true</code> if a target node had to be inserted as
3238:             *            first argument, <code>false</code> otherwise
3239:             * @param status
3240:             *            the refactoring status
3241:             */
3242:            protected void createMethodJavadocReference(
3243:                    final CompilationUnitRewrite rewrite,
3244:                    final MethodDeclaration declaration,
3245:                    final SearchMatch match, final boolean targetNode,
3246:                    final RefactoringStatus status) {
3247:                Assert.isNotNull(rewrite);
3248:                Assert.isNotNull(declaration);
3249:                Assert.isNotNull(match);
3250:                Assert.isNotNull(status);
3251:                final ASTNode node = ASTNodeSearchUtil.findNode(match, rewrite
3252:                        .getRoot());
3253:                if (node instanceof  MethodRef) {
3254:                    final AST ast = node.getAST();
3255:                    final MethodRef successor = ast.newMethodRef();
3256:
3257:                    rewrite.getASTRewrite().replace(node, successor, null);
3258:                }
3259:            }
3260:
3261:            /**
3262:             * Creates the necessary changes to update tag references to the original
3263:             * method.
3264:             * 
3265:             * @param rewrites
3266:             *            the map of compilation units to compilation unit rewrites
3267:             * @param declaration
3268:             *            the source method declaration
3269:             * @param groups
3270:             *            the search result groups representing all references to the
3271:             *            moved method, including references in comments
3272:             * @param target
3273:             *            <code>true</code> if a target node must be inserted as first
3274:             *            argument, <code>false</code> otherwise
3275:             * @param status
3276:             *            the refactoring status
3277:             * @param monitor
3278:             *            the progress monitor to use
3279:             */
3280:            protected void createMethodJavadocReferences(final Map rewrites,
3281:                    final MethodDeclaration declaration,
3282:                    final SearchResultGroup[] groups, final boolean target,
3283:                    final RefactoringStatus status,
3284:                    final IProgressMonitor monitor) {
3285:                Assert.isNotNull(rewrites);
3286:                Assert.isNotNull(declaration);
3287:                Assert.isNotNull(status);
3288:                Assert.isNotNull(monitor);
3289:                try {
3290:                    monitor.beginTask("", groups.length); //$NON-NLS-1$
3291:                    monitor
3292:                            .setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_creating);
3293:                    try {
3294:                        SearchMatch[] matches = null;
3295:                        IJavaElement element = null;
3296:                        ICompilationUnit unit = null;
3297:                        CompilationUnitRewrite rewrite = null;
3298:                        SearchResultGroup group = null;
3299:                        for (int index = 0; index < groups.length; index++) {
3300:                            group = groups[index];
3301:                            element = JavaCore.create(group.getResource());
3302:                            unit = group.getCompilationUnit();
3303:                            if (element instanceof  ICompilationUnit) {
3304:                                matches = group.getSearchResults();
3305:                                unit = (ICompilationUnit) element;
3306:                                rewrite = getCompilationUnitRewrite(rewrites,
3307:                                        unit);
3308:                                SearchMatch match = null;
3309:                                for (int offset = 0; offset < matches.length; offset++) {
3310:                                    match = matches[offset];
3311:                                    if (match.getAccuracy() == SearchMatch.A_INACCURATE) {
3312:                                        status
3313:                                                .merge(RefactoringStatus
3314:                                                        .createWarningStatus(
3315:                                                                Messages
3316:                                                                        .format(
3317:                                                                                RefactoringCoreMessages.MoveInstanceMethodProcessor_inline_inaccurate,
3318:                                                                                unit
3319:                                                                                        .getCorrespondingResource()
3320:                                                                                        .getName()),
3321:                                                                JavaStatusContext
3322:                                                                        .create(
3323:                                                                                unit,
3324:                                                                                new SourceRange(
3325:                                                                                        match
3326:                                                                                                .getOffset(),
3327:                                                                                        match
3328:                                                                                                .getLength()))));
3329:                                    } else
3330:                                        createMethodJavadocReference(rewrite,
3331:                                                declaration, match, target,
3332:                                                status);
3333:                                }
3334:                            } else if (element != null) {
3335:                                status
3336:                                        .merge(RefactoringStatus
3337:                                                .createWarningStatus(Messages
3338:                                                        .format(
3339:                                                                RefactoringCoreMessages.MoveInstanceMethodProcessor_javadoc_binary_project,
3340:                                                                element
3341:                                                                        .getJavaProject()
3342:                                                                        .getElementName())));
3343:                            } else {
3344:                                status
3345:                                        .merge(RefactoringStatus
3346:                                                .createWarningStatus(Messages
3347:                                                        .format(
3348:                                                                RefactoringCoreMessages.MoveInstanceMethodProcessor_javadoc_binary_resource,
3349:                                                                group
3350:                                                                        .getResource()
3351:                                                                        .getName())));
3352:                            }
3353:                            monitor.worked(1);
3354:                        }
3355:                    } catch (CoreException exception) {
3356:                        status.merge(RefactoringStatus.create(exception
3357:                                .getStatus()));
3358:                    }
3359:                } finally {
3360:                    monitor.done();
3361:                }
3362:            }
3363:
3364:            /**
3365:             * Creates a comment method reference to the moved method
3366:             * 
3367:             * @param declaration
3368:             *            the method declaration of the original method
3369:             * @param ast
3370:             *            the ast to create the method reference for
3371:             * @return the created link tag to reference the method
3372:             * @throws JavaModelException
3373:             *             if an error occurs
3374:             */
3375:            protected ASTNode createMethodReference(
3376:                    final MethodDeclaration declaration, final AST ast)
3377:                    throws JavaModelException {
3378:                Assert.isNotNull(ast);
3379:                Assert.isNotNull(declaration);
3380:                final MethodRef reference = ast.newMethodRef();
3381:                reference.setName(ast.newSimpleName(fMethodName));
3382:                reference.setQualifier(ASTNodeFactory.newName(ast,
3383:                        JavaModelUtil.getFullyQualifiedName(fTargetType)));
3384:                createArgumentList(declaration, reference.parameters(),
3385:                        new IArgumentFactory() {
3386:
3387:                            public final ASTNode getArgumentNode(
3388:                                    final IVariableBinding binding,
3389:                                    final boolean last) {
3390:                                Assert.isNotNull(binding);
3391:                                final MethodRefParameter parameter = ast
3392:                                        .newMethodRefParameter();
3393:                                parameter.setType(ASTNodeFactory.newType(ast,
3394:                                        binding.getType().getName()));
3395:                                return parameter;
3396:                            }
3397:
3398:                            public final ASTNode getTargetNode() {
3399:                                final MethodRefParameter parameter = ast
3400:                                        .newMethodRefParameter();
3401:                                final IMethodBinding method = declaration
3402:                                        .resolveBinding();
3403:                                if (method != null) {
3404:                                    final ITypeBinding declaring = method
3405:                                            .getDeclaringClass();
3406:                                    if (declaring != null)
3407:                                        parameter
3408:                                                .setType(ASTNodeFactory
3409:                                                        .newType(
3410:                                                                ast,
3411:                                                                Bindings
3412:                                                                        .getFullyQualifiedName(declaring)));
3413:                                }
3414:                                return parameter;
3415:                            }
3416:                        });
3417:                return reference;
3418:            }
3419:
3420:            /**
3421:             * @param document
3422:             *            the buffer containing the source of the source compilation
3423:             *            unit
3424:             * @param declaration
3425:             *            the method declaration to use as source
3426:             * @param rewrite
3427:             *            the ast rewrite to use for the copy of the method body
3428:             * @param rewrites
3429:             *            the compilation unit rewrites
3430:             * @throws JavaModelException
3431:             *             if the insertion point cannot be found
3432:             */
3433:            protected void createMethodSignature(final IDocument document,
3434:                    final MethodDeclaration declaration,
3435:                    final ASTRewrite rewrite, final Map rewrites)
3436:                    throws JavaModelException {
3437:                Assert.isNotNull(document);
3438:                Assert.isNotNull(declaration);
3439:                Assert.isNotNull(rewrite);
3440:                Assert.isNotNull(rewrites);
3441:                try {
3442:                    final CompilationUnitRewrite rewriter = getCompilationUnitRewrite(
3443:                            rewrites, getTargetType().getCompilationUnit());
3444:                    final MethodDeclaration stub = (MethodDeclaration) rewriter
3445:                            .getASTRewrite().createStringPlaceholder(
3446:                                    createMethodContent(document, declaration,
3447:                                            rewrite),
3448:                                    ASTNode.METHOD_DECLARATION);
3449:                    final AbstractTypeDeclaration type = ASTNodeSearchUtil
3450:                            .getAbstractTypeDeclarationNode(getTargetType(),
3451:                                    rewriter.getRoot());
3452:                    rewriter
3453:                            .getASTRewrite()
3454:                            .getListRewrite(type,
3455:                                    type.getBodyDeclarationsProperty())
3456:                            .insertAt(
3457:                                    stub,
3458:                                    ASTNodes.getInsertionIndex(stub, type
3459:                                            .bodyDeclarations()),
3460:                                    rewriter
3461:                                            .createGroupDescription(RefactoringCoreMessages.MoveInstanceMethodProcessor_add_moved_method));
3462:                } catch (BadLocationException exception) {
3463:                    JavaPlugin.log(exception);
3464:                }
3465:            }
3466:
3467:            /**
3468:             * Creates the necessary changes to remove method type parameters if they
3469:             * match with enclosing type parameters.
3470:             * 
3471:             * @param rewrite
3472:             *            the ast rewrite to use
3473:             * @param declaration
3474:             *            the method declaration to remove type parameters
3475:             * @param status
3476:             *            the refactoring status
3477:             */
3478:            protected void createMethodTypeParameters(final ASTRewrite rewrite,
3479:                    final MethodDeclaration declaration,
3480:                    final RefactoringStatus status) {
3481:                ITypeBinding binding = fTarget.getType();
3482:                if (binding != null && binding.isParameterizedType()) {
3483:                    final IMethodBinding method = declaration.resolveBinding();
3484:                    if (method != null) {
3485:                        final ITypeBinding[] parameters = method
3486:                                .getTypeParameters();
3487:                        if (parameters.length > 0) {
3488:                            final ListRewrite rewriter = rewrite
3489:                                    .getListRewrite(
3490:                                            declaration,
3491:                                            MethodDeclaration.TYPE_PARAMETERS_PROPERTY);
3492:                            boolean foundStatic = false;
3493:                            while (binding != null && !foundStatic) {
3494:                                if (Flags.isStatic(binding.getModifiers()))
3495:                                    foundStatic = true;
3496:                                final ITypeBinding[] bindings = binding
3497:                                        .getTypeArguments();
3498:                                for (int index = 0; index < bindings.length; index++) {
3499:                                    for (int offset = 0; offset < parameters.length; offset++) {
3500:                                        if (parameters[offset].getName()
3501:                                                .equals(
3502:                                                        bindings[index]
3503:                                                                .getName())) {
3504:                                            rewriter.remove((ASTNode) rewriter
3505:                                                    .getOriginalList().get(
3506:                                                            offset), null);
3507:                                            status
3508:                                                    .addWarning(
3509:                                                            Messages
3510:                                                                    .format(
3511:                                                                            RefactoringCoreMessages.MoveInstanceMethodProcessor_present_type_parameter_warning,
3512:                                                                            new Object[] {
3513:                                                                                    parameters[offset]
3514:                                                                                            .getName(),
3515:                                                                                    BindingLabelProvider
3516:                                                                                            .getBindingLabel(
3517:                                                                                                    binding,
3518:                                                                                                    JavaElementLabels.ALL_FULLY_QUALIFIED) }),
3519:                                                            JavaStatusContext
3520:                                                                    .create(fMethod));
3521:                                        }
3522:                                    }
3523:                                }
3524:                                binding = binding.getDeclaringClass();
3525:                            }
3526:                        }
3527:                    }
3528:                }
3529:            }
3530:
3531:            /**
3532:             * Creates the expression to access the new target.
3533:             * 
3534:             * @param declaration
3535:             *            the method declaration where to access the target
3536:             * @return the corresponding expression
3537:             */
3538:            protected Expression createSimpleTargetAccessExpression(
3539:                    final MethodDeclaration declaration) {
3540:                Assert.isNotNull(declaration);
3541:                Expression expression = null;
3542:                final AST ast = declaration.getAST();
3543:                final ITypeBinding type = fTarget.getDeclaringClass();
3544:                if (type != null) {
3545:                    boolean shadows = false;
3546:                    final IVariableBinding[] bindings = getArgumentBindings(declaration);
3547:                    IVariableBinding variable = null;
3548:                    for (int index = 0; index < bindings.length; index++) {
3549:                        variable = bindings[index];
3550:                        if (fMethod.getDeclaringType().getField(
3551:                                variable.getName()).exists()) {
3552:                            shadows = true;
3553:                            break;
3554:                        }
3555:                    }
3556:                    if (fSettings.useKeywordThis || shadows) {
3557:                        final FieldAccess access = ast.newFieldAccess();
3558:                        access.setName(ast.newSimpleName(fTarget.getName()));
3559:                        access.setExpression(ast.newThisExpression());
3560:                        expression = access;
3561:                    } else
3562:                        expression = ast.newSimpleName(fTarget.getName());
3563:                } else
3564:                    expression = ast.newSimpleName(fTarget.getName());
3565:                return expression;
3566:            }
3567:
3568:            /**
3569:             * Returns the candidate targets for the method to move.
3570:             * 
3571:             * @return the candidate targets as variable bindings of fields and
3572:             *         parameters
3573:             */
3574:            public final IVariableBinding[] getCandidateTargets() {
3575:                Assert.isNotNull(fCandidateTargets);
3576:                return fCandidateTargets;
3577:            }
3578:
3579:            /**
3580:             * {@inheritDoc}
3581:             */
3582:            public String getComment() {
3583:                return fComment;
3584:            }
3585:
3586:            /**
3587:             * Returns a compilation unit rewrite for the specified compilation unit.
3588:             * 
3589:             * @param rewrites
3590:             *            the compilation unit rewrite map
3591:             * @param unit
3592:             *            the compilation unit
3593:             * @return the corresponding compilation unit rewrite
3594:             */
3595:            protected CompilationUnitRewrite getCompilationUnitRewrite(
3596:                    final Map rewrites, final ICompilationUnit unit) {
3597:                Assert.isNotNull(rewrites);
3598:                Assert.isNotNull(unit);
3599:                CompilationUnitRewrite rewrite = (CompilationUnitRewrite) rewrites
3600:                        .get(unit);
3601:                if (rewrite == null) {
3602:                    rewrite = new CompilationUnitRewrite(unit);
3603:                    rewrites.put(unit, rewrite);
3604:                }
3605:                return rewrite;
3606:            }
3607:
3608:            /**
3609:             * {@inheritDoc}
3610:             */
3611:            public final boolean getDelegateUpdating() {
3612:                return fDelegatingUpdating;
3613:            }
3614:
3615:            /**
3616:             * {@inheritDoc}
3617:             */
3618:            public String getDelegateUpdatingTitle(boolean plural) {
3619:                if (plural)
3620:                    return RefactoringCoreMessages.DelegateMethodCreator_keep_original_moved_plural;
3621:                else
3622:                    return RefactoringCoreMessages.DelegateMethodCreator_keep_original_moved_singular;
3623:            }
3624:
3625:            /**
3626:             * {@inheritDoc}
3627:             */
3628:            public final boolean getDeprecateDelegates() {
3629:                return fDelegateDeprecation;
3630:            }
3631:
3632:            /**
3633:             * {@inheritDoc}
3634:             */
3635:            public final Object[] getElements() {
3636:                return new Object[] { fMethod };
3637:            }
3638:
3639:            /**
3640:             * {@inheritDoc}
3641:             */
3642:            public final String getIdentifier() {
3643:                return IDENTIFIER;
3644:            }
3645:
3646:            /**
3647:             * Returns the method to be moved.
3648:             * 
3649:             * @return the method to be moved
3650:             */
3651:            public final IMethod getMethod() {
3652:                return fMethod;
3653:            }
3654:
3655:            /**
3656:             * Returns the new method name.
3657:             * 
3658:             * @return the name of the new method
3659:             */
3660:            public final String getMethodName() {
3661:                return fMethodName;
3662:            }
3663:
3664:            /**
3665:             * Returns the possible targets for the method to move.
3666:             * 
3667:             * @return the possible targets as variable bindings of read-only fields and
3668:             *         parameters
3669:             */
3670:            public final IVariableBinding[] getPossibleTargets() {
3671:                Assert.isNotNull(fPossibleTargets);
3672:                return fPossibleTargets;
3673:            }
3674:
3675:            /*
3676:             * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#getProcessorName()
3677:             */
3678:            public final String getProcessorName() {
3679:                return RefactoringCoreMessages.MoveInstanceMethodProcessor_name;
3680:            }
3681:
3682:            /**
3683:             * Returns the index of the chosen target.
3684:             * 
3685:             * @return the target index
3686:             */
3687:            protected final int getTargetIndex() {
3688:                final IVariableBinding[] targets = getPossibleTargets();
3689:                int result = -1;
3690:                for (int index = 0; index < targets.length; index++) {
3691:                    if (Bindings.equals(fTarget, targets[index])) {
3692:                        result = index;
3693:                        break;
3694:                    }
3695:                }
3696:                return result;
3697:            }
3698:
3699:            /**
3700:             * Returns the new target name.
3701:             * 
3702:             * @return the name of the new target
3703:             */
3704:            public final String getTargetName() {
3705:                return fTargetName;
3706:            }
3707:
3708:            /**
3709:             * Returns the type of the new target.
3710:             * 
3711:             * @return the type of the new target
3712:             * @throws JavaModelException
3713:             *             if the type does not exist
3714:             */
3715:            protected IType getTargetType() throws JavaModelException {
3716:                Assert.isNotNull(fTarget);
3717:                if (fTargetType == null) {
3718:                    final ITypeBinding binding = fTarget.getType();
3719:                    if (binding != null)
3720:                        fTargetType = (IType) binding.getJavaElement();
3721:                    else
3722:                        throw new JavaModelException(
3723:                                new CoreException(
3724:                                        new Status(
3725:                                                IStatus.ERROR,
3726:                                                JavaPlugin.getPluginId(),
3727:                                                0,
3728:                                                RefactoringCoreMessages.MoveInstanceMethodProcessor_cannot_be_moved,
3729:                                                null)));
3730:                }
3731:                return fTargetType;
3732:            }
3733:
3734:            /**
3735:             * Initializes the refactoring with the given input.
3736:             * 
3737:             * @param method
3738:             *            the method to move
3739:             */
3740:            protected void initialize(final IMethod method) {
3741:                Assert.isNotNull(method);
3742:                fSourceRewrite = new CompilationUnitRewrite(fMethod
3743:                        .getCompilationUnit());
3744:                fMethodName = method.getElementName();
3745:                fTargetName = suggestTargetName();
3746:                if (fSettings == null)
3747:                    fSettings = JavaPreferencesSettings
3748:                            .getCodeGenerationSettings(fMethod.getJavaProject());
3749:            }
3750:
3751:            /**
3752:             * {@inheritDoc}
3753:             */
3754:            public RefactoringStatus initialize(
3755:                    final RefactoringArguments arguments) {
3756:                if (arguments instanceof  JavaRefactoringArguments) {
3757:                    final JavaRefactoringArguments extended = (JavaRefactoringArguments) arguments;
3758:                    final String handle = extended
3759:                            .getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT);
3760:                    if (handle != null) {
3761:                        final IJavaElement element = JavaRefactoringDescriptorUtil
3762:                                .handleToElement(extended.getProject(), handle,
3763:                                        false);
3764:                        if (element == null
3765:                                || !element.exists()
3766:                                || element.getElementType() != IJavaElement.METHOD)
3767:                            return ScriptableRefactoring
3768:                                    .createInputFatalStatus(element,
3769:                                            getRefactoring().getName(),
3770:                                            IJavaRefactorings.MOVE_METHOD);
3771:                        else {
3772:                            fMethod = (IMethod) element;
3773:                            initialize(fMethod);
3774:                        }
3775:                    } else
3776:                        return RefactoringStatus
3777:                                .createFatalErrorStatus(Messages
3778:                                        .format(
3779:                                                RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
3780:                                                JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT));
3781:                    final String name = extended
3782:                            .getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME);
3783:                    if (name != null) {
3784:                        final RefactoringStatus status = setMethodName(name);
3785:                        if (status.hasError())
3786:                            return status;
3787:                    } else
3788:                        return RefactoringStatus
3789:                                .createFatalErrorStatus(Messages
3790:                                        .format(
3791:                                                RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
3792:                                                JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME));
3793:                    final String deprecate = extended
3794:                            .getAttribute(ATTRIBUTE_DEPRECATE);
3795:                    if (deprecate != null) {
3796:                        fDelegateDeprecation = Boolean.valueOf(deprecate)
3797:                                .booleanValue();
3798:                    } else
3799:                        return RefactoringStatus
3800:                                .createFatalErrorStatus(Messages
3801:                                        .format(
3802:                                                RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
3803:                                                ATTRIBUTE_DEPRECATE));
3804:                    final String remove = extended
3805:                            .getAttribute(ATTRIBUTE_REMOVE);
3806:                    if (remove != null) {
3807:                        fRemove = Boolean.valueOf(remove).booleanValue();
3808:                    } else
3809:                        return RefactoringStatus
3810:                                .createFatalErrorStatus(Messages
3811:                                        .format(
3812:                                                RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
3813:                                                ATTRIBUTE_REMOVE));
3814:                    final String inline = extended
3815:                            .getAttribute(ATTRIBUTE_INLINE);
3816:                    if (inline != null) {
3817:                        fInline = Boolean.valueOf(inline).booleanValue();
3818:                    } else
3819:                        return RefactoringStatus
3820:                                .createFatalErrorStatus(Messages
3821:                                        .format(
3822:                                                RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
3823:                                                ATTRIBUTE_INLINE));
3824:                    final String getter = extended
3825:                            .getAttribute(ATTRIBUTE_USE_GETTER);
3826:                    if (getter != null)
3827:                        fUseGetters = Boolean.valueOf(getter).booleanValue();
3828:                    else
3829:                        return RefactoringStatus
3830:                                .createFatalErrorStatus(Messages
3831:                                        .format(
3832:                                                RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
3833:                                                ATTRIBUTE_USE_GETTER));
3834:                    final String setter = extended
3835:                            .getAttribute(ATTRIBUTE_USE_SETTER);
3836:                    if (setter != null)
3837:                        fUseSetters = Boolean.valueOf(setter).booleanValue();
3838:                    else
3839:                        return RefactoringStatus
3840:                                .createFatalErrorStatus(Messages
3841:                                        .format(
3842:                                                RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
3843:                                                ATTRIBUTE_USE_SETTER));
3844:                    final String target = extended
3845:                            .getAttribute(ATTRIBUTE_TARGET_NAME);
3846:                    if (target != null) {
3847:                        final RefactoringStatus status = setTargetName(target);
3848:                        if (status.hasError())
3849:                            return status;
3850:                    } else
3851:                        return RefactoringStatus
3852:                                .createFatalErrorStatus(Messages
3853:                                        .format(
3854:                                                RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
3855:                                                ATTRIBUTE_TARGET_NAME));
3856:                    final String value = extended
3857:                            .getAttribute(ATTRIBUTE_TARGET_INDEX);
3858:                    if (value != null) {
3859:                        try {
3860:                            final int index = Integer.valueOf(value).intValue();
3861:                            if (index >= 0) {
3862:                                final MethodDeclaration declaration = ASTNodeSearchUtil
3863:                                        .getMethodDeclarationNode(fMethod,
3864:                                                fSourceRewrite.getRoot());
3865:                                if (declaration != null) {
3866:                                    final IVariableBinding[] bindings = computeTargetCategories(declaration);
3867:                                    if (bindings != null
3868:                                            && index < bindings.length)
3869:                                        setTarget(bindings[index]);
3870:                                }
3871:                            }
3872:                        } catch (NumberFormatException exception) {
3873:                            return RefactoringStatus
3874:                                    .createFatalErrorStatus(Messages
3875:                                            .format(
3876:                                                    RefactoringCoreMessages.InitializableRefactoring_illegal_argument,
3877:                                                    new String[] { value,
3878:                                                            ATTRIBUTE_TARGET_INDEX }));
3879:                        } catch (JavaModelException exception) {
3880:                            return RefactoringStatus
3881:                                    .createFatalErrorStatus(Messages
3882:                                            .format(
3883:                                                    RefactoringCoreMessages.InitializableRefactoring_illegal_argument,
3884:                                                    new String[] { value,
3885:                                                            ATTRIBUTE_TARGET_INDEX }));
3886:                        }
3887:                    } else
3888:                        return RefactoringStatus
3889:                                .createFatalErrorStatus(Messages
3890:                                        .format(
3891:                                                RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
3892:                                                ATTRIBUTE_TARGET_INDEX));
3893:                } else
3894:                    return RefactoringStatus
3895:                            .createFatalErrorStatus(RefactoringCoreMessages.InitializableRefactoring_inacceptable_arguments);
3896:                return new RefactoringStatus();
3897:            }
3898:
3899:            /*
3900:             * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#isApplicable()
3901:             */
3902:            public final boolean isApplicable() throws CoreException {
3903:                return fMethod.exists() && !fMethod.isConstructor()
3904:                        && !fMethod.isBinary() && !fMethod.isReadOnly()
3905:                        && fMethod.getCompilationUnit() != null
3906:                        && !JdtFlags.isStatic(fMethod);
3907:            }
3908:
3909:            /**
3910:             * Is the specified name a target access?
3911:             * 
3912:             * @param name
3913:             *            the name to check
3914:             * @return <code>true</code> if this name is a target access,
3915:             *         <code>false</code> otherwise
3916:             */
3917:            protected boolean isTargetAccess(final Name name) {
3918:                Assert.isNotNull(name);
3919:                final IBinding binding = name.resolveBinding();
3920:                if (Bindings.equals(fTarget, binding))
3921:                    return true;
3922:                if (name.getParent() instanceof  FieldAccess) {
3923:                    final FieldAccess access = (FieldAccess) name.getParent();
3924:                    final Expression expression = access.getExpression();
3925:                    if (expression instanceof  Name)
3926:                        return isTargetAccess((Name) expression);
3927:                } else if (name instanceof  QualifiedName) {
3928:                    final QualifiedName qualified = (QualifiedName) name;
3929:                    if (qualified.getQualifier() != null)
3930:                        return isTargetAccess(qualified.getQualifier());
3931:                }
3932:                return false;
3933:            }
3934:
3935:            /*
3936:             * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#loadParticipants(org.eclipse.ltk.core.refactoring.RefactoringStatus,
3937:             *      org.eclipse.ltk.core.refactoring.participants.SharableParticipants)
3938:             */
3939:            public final RefactoringParticipant[] loadParticipants(
3940:                    final RefactoringStatus status,
3941:                    final SharableParticipants participants)
3942:                    throws CoreException {
3943:                return new RefactoringParticipant[0];
3944:            }
3945:
3946:            /**
3947:             * Does the moved method need a target node?
3948:             * 
3949:             * @return <code>true</code> if it needs a target node, <code>false</code>
3950:             *         otherwise
3951:             */
3952:            public final boolean needsTargetNode() {
3953:                return fTargetNode;
3954:            }
3955:
3956:            /**
3957:             * {@inheritDoc}
3958:             */
3959:            public void setComment(final String comment) {
3960:                fComment = comment;
3961:            }
3962:
3963:            /**
3964:             * {@inheritDoc}
3965:             */
3966:            public final void setDelegateUpdating(final boolean updating) {
3967:                fDelegatingUpdating = updating;
3968:                setInlineDelegator(!updating);
3969:                setRemoveDelegator(!updating);
3970:            }
3971:
3972:            /**
3973:             * {@inheritDoc}
3974:             */
3975:            public final void setDeprecateDelegates(final boolean deprecate) {
3976:                fDelegateDeprecation = deprecate;
3977:            }
3978:
3979:            /**
3980:             * Determines whether the delegator has to be inlined.
3981:             * 
3982:             * @param inline
3983:             *            <code>true</code> to inline the delegator,
3984:             *            <code>false</code> otherwise
3985:             */
3986:            public final void setInlineDelegator(final boolean inline) {
3987:                fInline = inline;
3988:            }
3989:
3990:            /**
3991:             * Sets the new method name.
3992:             * 
3993:             * @param name
3994:             *            the name to set
3995:             * @return the status of the operation
3996:             */
3997:            public final RefactoringStatus setMethodName(final String name) {
3998:                Assert.isNotNull(name);
3999:                RefactoringStatus status = Checks.checkMethodName(name,
4000:                        fTargetType);
4001:                if (status.hasFatalError())
4002:                    return status;
4003:                fMethodName = name;
4004:                return status;
4005:            }
4006:
4007:            /**
4008:             * Determines whether the delegator has to be removed after inlining. Note
4009:             * that the option to inline the delegator has to be enabled if this method
4010:             * is called with the argument <code>true</code>.
4011:             * 
4012:             * @param remove
4013:             *            <code>true</code> if it should be removed,
4014:             *            <code>false</code> otherwise
4015:             */
4016:            public final void setRemoveDelegator(final boolean remove) {
4017:                Assert.isTrue(!remove || fInline);
4018:                fRemove = remove;
4019:            }
4020:
4021:            /**
4022:             * Sets the new target.
4023:             * 
4024:             * @param target
4025:             *            the target to set
4026:             */
4027:            public final void setTarget(final IVariableBinding target) {
4028:                Assert.isNotNull(target);
4029:                fTarget = target;
4030:                fTargetType = null;
4031:                try {
4032:                    final MethodDeclaration declaration = ASTNodeSearchUtil
4033:                            .getMethodDeclarationNode(fMethod, fSourceRewrite
4034:                                    .getRoot());
4035:                    if (declaration != null) {
4036:                        final AstNodeFinder finder = new ThisReferenceFinder();
4037:                        declaration.accept(finder);
4038:                        fTargetNode = !finder.getResult().isEmpty();
4039:                        return;
4040:                    }
4041:                } catch (JavaModelException exception) {
4042:                    JavaPlugin.log(exception);
4043:                }
4044:                fTargetNode = true;
4045:            }
4046:
4047:            /**
4048:             * Sets the new target name.
4049:             * 
4050:             * @param name
4051:             *            the name to set
4052:             * @return the status of the operation
4053:             */
4054:            public final RefactoringStatus setTargetName(final String name) {
4055:                Assert.isNotNull(name);
4056:                final RefactoringStatus status = Checks.checkTempName(name,
4057:                        fMethod);
4058:                if (status.hasFatalError())
4059:                    return status;
4060:                fTargetName = name;
4061:                return status;
4062:            }
4063:
4064:            /**
4065:             * Determines whether getter methods should be used to resolve visibility
4066:             * issues.
4067:             * 
4068:             * @param use
4069:             *            <code>true</code> if getter methods should be used,
4070:             *            <code>false</code> otherwise
4071:             */
4072:            public final void setUseGetters(final boolean use) {
4073:                fUseGetters = use;
4074:            }
4075:
4076:            /**
4077:             * Determines whether setter methods should be used to resolve visibility
4078:             * issues.
4079:             * 
4080:             * @param use
4081:             *            <code>true</code> if setter methods should be used,
4082:             *            <code>false</code> otherwise
4083:             */
4084:            public final void setUseSetters(final boolean use) {
4085:                fUseSetters = use;
4086:            }
4087:
4088:            /**
4089:             * Should getter methods be used to resolve visibility issues?
4090:             * 
4091:             * @return <code>true</code> if getter methods should be used,
4092:             *         <code>false</code> otherwise
4093:             */
4094:            public final boolean shouldUseGetters() {
4095:                return fUseGetters;
4096:            }
4097:
4098:            /**
4099:             * Should setter methods be used to resolve visibility issues?
4100:             * 
4101:             * @return <code>true</code> if setter methods should be used,
4102:             *         <code>false</code> otherwise
4103:             */
4104:            public final boolean shouldUseSetters() {
4105:                return fUseSetters;
4106:            }
4107:
4108:            /**
4109:             * Returns a best guess for the name of the new target.
4110:             * 
4111:             * @return a best guess for the name
4112:             */
4113:            protected String suggestTargetName() {
4114:                try {
4115:                    final String[] candidates = StubUtility
4116:                            .getArgumentNameSuggestions(fMethod
4117:                                    .getDeclaringType(),
4118:                                    computeReservedIdentifiers());
4119:                    if (candidates.length > 0) {
4120:                        if (candidates[0].indexOf('$') < 0)
4121:                            return candidates[0];
4122:                    }
4123:                } catch (JavaModelException exception) {
4124:                    JavaPlugin.log(exception);
4125:                }
4126:                return "arg"; //$NON-NLS-1$
4127:            }
4128:        }
www._ja_va___2___s_.___co___m_ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.