]> git.uio.no Git - ifi-stolz-refaktor.git/blobdiff - case-study/jdt-after/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/TargetProvider.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-after / core refactoring / org / eclipse / jdt / internal / corext / refactoring / code / TargetProvider.java
diff --git a/case-study/jdt-after/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/TargetProvider.java b/case-study/jdt-after/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/TargetProvider.java
new file mode 100644 (file)
index 0000000..1bed1b4
--- /dev/null
@@ -0,0 +1,672 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Dmitry Stalnov (dstalnov@fusionone.com) - contributed fixes for:
+ *       o Allow 'this' constructor to be inlined
+ *         (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=38093)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.corext.refactoring.code;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Stack;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.SubProgressMonitor;
+
+import org.eclipse.core.resources.IFile;
+
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.TextEdit;
+import org.eclipse.text.edits.TextEditGroup;
+
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.core.refactoring.participants.ResourceChangeChecker;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.SourceRange;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
+import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
+import org.eclipse.jdt.core.dom.Block;
+import org.eclipse.jdt.core.dom.BodyDeclaration;
+import org.eclipse.jdt.core.dom.ClassInstanceCreation;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.ConstructorInvocation;
+import org.eclipse.jdt.core.dom.EnumDeclaration;
+import org.eclipse.jdt.core.dom.FieldDeclaration;
+import org.eclipse.jdt.core.dom.IBinding;
+import org.eclipse.jdt.core.dom.IMethodBinding;
+import org.eclipse.jdt.core.dom.ITypeBinding;
+import org.eclipse.jdt.core.dom.Initializer;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.MethodInvocation;
+import org.eclipse.jdt.core.dom.SuperMethodInvocation;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
+import org.eclipse.jdt.core.refactoring.CompilationUnitChange;
+import org.eclipse.jdt.core.search.IJavaSearchConstants;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.core.search.SearchMatch;
+import org.eclipse.jdt.core.search.SearchPattern;
+
+import org.eclipse.jdt.internal.corext.dom.ASTNodes;
+import org.eclipse.jdt.internal.corext.refactoring.Checks;
+import org.eclipse.jdt.internal.corext.refactoring.CollectingSearchRequestor;
+import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
+import org.eclipse.jdt.internal.corext.refactoring.RefactoringScopeFactory;
+import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;
+import org.eclipse.jdt.internal.corext.refactoring.base.ReferencesInBinaryContext;
+import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
+import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager;
+import org.eclipse.jdt.internal.corext.util.Messages;
+import org.eclipse.jdt.internal.corext.util.SearchUtils;
+
+import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;
+import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;
+
+/**
+ * A TargetProvider provides all targets that have to be adapted, i.e. all method invocations that should be inlined.
+ */
+abstract class TargetProvider {
+
+       public abstract void initialize();
+
+       public abstract ICompilationUnit[] getAffectedCompilationUnits(RefactoringStatus status, ReferencesInBinaryContext binaryRefs, IProgressMonitor pm)  throws CoreException;
+
+       public abstract BodyDeclaration[] getAffectedBodyDeclarations(ICompilationUnit unit, IProgressMonitor pm);
+
+       // constructor invocation is not an expression but a statement
+       public abstract ASTNode[] getInvocations(BodyDeclaration declaration, IProgressMonitor pm);
+
+       public abstract RefactoringStatus checkActivation() throws JavaModelException;
+
+       public abstract int getStatusSeverity();
+
+       public boolean isSingle() {
+               return false;
+       }
+
+       public CallInliner generated_6059156261379860052(InlineMethodRefactoring inlinemethodrefactoring, RefactoringStatus result, IProgressMonitor sub, ICompilationUnit unit, boolean added, MultiTextEdit root, CompilationUnitChange change, BodyDeclaration[] bodies) throws CoreException {
+               CallInliner inliner;
+               inliner= new CallInliner(unit, (CompilationUnit) bodies[0].getRoot(), inlinemethodrefactoring.fSourceProvider);
+               for (int b= 0; b < bodies.length; b++) {
+                       BodyDeclaration body= bodies[b];
+                       inliner.initialize(body);
+                       RefactoringStatus nestedInvocations= new RefactoringStatus();
+                       ASTNode[] invocations= inlinemethodrefactoring.removeNestedCalls(nestedInvocations, unit,
+                               getInvocations(body, new SubProgressMonitor(sub, 2)));
+                       for (int i= 0; i < invocations.length; i++) {
+                               ASTNode invocation= invocations[i];
+                               result.merge(inliner.initialize(invocation, getStatusSeverity()));
+                               if (result.hasFatalError())
+                                       break;
+                               if (result.getSeverity() < getStatusSeverity()) {
+                                       added= true;
+                                       TextEditGroup group= new TextEditGroup(RefactoringCoreMessages.InlineMethodRefactoring_edit_inline);
+                                       change.addTextEditGroup(group);
+                                       result.merge(inliner.perform(group));
+                               } else {
+                                       inlinemethodrefactoring.fDeleteSource= false;
+                               }
+                       }
+                       // do this after we have inlined the method calls. We still want
+                       // to generate the modifications.
+                       if (!nestedInvocations.isOK()) {
+                               result.merge(nestedInvocations);
+                               inlinemethodrefactoring.fDeleteSource= false;
+                       }
+               }
+               if (!added) {
+                       inlinemethodrefactoring.fChangeManager.remove(unit);
+               } else {
+                       root.addChild(inliner.getModifications());
+                       ImportRewrite rewrite= inliner.getImportEdit();
+                       if (rewrite.hasRecordedChanges()) {
+                               TextEdit edit= rewrite.rewriteImports(null);
+                               if (edit instanceof MultiTextEdit ? ((MultiTextEdit)edit).getChildrenSize() > 0 : true) {
+                                       root.addChild(edit);
+                                       change.addTextEditGroup(
+                                               new TextEditGroup(RefactoringCoreMessages.InlineMethodRefactoring_edit_import, new TextEdit[] {edit}));
+                               }
+                       }
+               }
+               return inliner;
+       }
+
+       public RefactoringStatus generated_5911805691094672032(ReplaceInvocationsRefactoring replaceinvocationsrefactoring, IProgressMonitor pm) throws JavaModelException, CoreException {
+               replaceinvocationsrefactoring.fChangeManager= new TextChangeManager();
+               RefactoringStatus result= new RefactoringStatus();
+       
+               replaceinvocationsrefactoring.fSourceProvider= replaceinvocationsrefactoring.resolveSourceProvider(replaceinvocationsrefactoring.fMethodBinding, result);
+               if (result.hasFatalError())
+                       return result;
+       
+               result.merge(replaceinvocationsrefactoring.fSourceProvider.checkActivation());
+               if (result.hasFatalError())
+                       return result;
+       
+               replaceinvocationsrefactoring.fSourceProvider.initialize();
+               initialize();
+       
+               pm.setTaskName(RefactoringCoreMessages.InlineMethodRefactoring_searching);
+               RefactoringStatus searchStatus= new RefactoringStatus();
+               String binaryRefsDescription= Messages.format(RefactoringCoreMessages.ReferencesInBinaryContext_ref_in_binaries_description , BasicElementLabels.getJavaElementName(replaceinvocationsrefactoring.fSourceProvider.getMethodName()));
+               ReferencesInBinaryContext binaryRefs= new ReferencesInBinaryContext(binaryRefsDescription);
+               ICompilationUnit[] units= getAffectedCompilationUnits(searchStatus, binaryRefs, new SubProgressMonitor(pm, 1));
+               binaryRefs.addErrorIfNecessary(searchStatus);
+       
+               if (searchStatus.hasFatalError()) {
+                       result.merge(searchStatus);
+                       return result;
+               }
+               IFile[] filesToBeModified= replaceinvocationsrefactoring.getFilesToBeModified(units);
+               result.merge(Checks.validateModifiesFiles(filesToBeModified, replaceinvocationsrefactoring.getValidationContext()));
+               if (result.hasFatalError())
+                       return result;
+               result.merge(ResourceChangeChecker.checkFilesToBeChanged(filesToBeModified, new SubProgressMonitor(pm, 1)));
+               replaceinvocationsrefactoring.checkOverridden(result, new SubProgressMonitor(pm, 4));
+               IProgressMonitor sub= new SubProgressMonitor(pm, 15);
+               sub.beginTask("", units.length * 3); //$NON-NLS-1$
+               for (int c= 0; c < units.length; c++) {
+                       ICompilationUnit unit= units[c];
+                       sub.subTask(Messages.format(RefactoringCoreMessages.InlineMethodRefactoring_processing,  BasicElementLabels.getFileName(unit)));
+                       CallInliner inliner= null;
+                       try {
+                               boolean added= false;
+                               MultiTextEdit root= new MultiTextEdit();
+                               CompilationUnitChange change= (CompilationUnitChange)replaceinvocationsrefactoring.fChangeManager.get(unit);
+                               change.setEdit(root);
+                               BodyDeclaration[] bodies= getAffectedBodyDeclarations(unit, new SubProgressMonitor(pm, 1));
+                               if (bodies.length == 0)
+                                       continue;
+                               inliner= new CallInliner(unit, (CompilationUnit) bodies[0].getRoot(), replaceinvocationsrefactoring.fSourceProvider);
+                               for (int b= 0; b < bodies.length; b++) {
+                                       BodyDeclaration body= bodies[b];
+                                       inliner.initialize(body);
+                                       RefactoringStatus nestedInvocations= new RefactoringStatus();
+                                       ASTNode[] invocations= replaceinvocationsrefactoring.removeNestedCalls(nestedInvocations, unit,
+                                               getInvocations(body, new SubProgressMonitor(sub, 2)));
+                                       for (int i= 0; i < invocations.length; i++) {
+                                               ASTNode invocation= invocations[i];
+                                               result.merge(inliner.initialize(invocation, getStatusSeverity()));
+                                               if (result.hasFatalError())
+                                                       break;
+                                               if (result.getSeverity() < getStatusSeverity()) {
+                                                       added= true;
+                                                       TextEditGroup group= new TextEditGroup(RefactoringCoreMessages.InlineMethodRefactoring_edit_inline);
+                                                       change.addTextEditGroup(group);
+                                                       result.merge(inliner.perform(group));
+                                               }
+                                       }
+                                       // do this after we have inlined the method calls. We still want
+                                       // to generate the modifications.
+                                       result.merge(nestedInvocations);
+                               }
+                               if (!added) {
+                                       replaceinvocationsrefactoring.fChangeManager.remove(unit);
+                               } else {
+                                       root.addChild(inliner.getModifications());
+                                       ImportRewrite rewrite= inliner.getImportEdit();
+                                       if (rewrite.hasRecordedChanges()) {
+                                               TextEdit edit= rewrite.rewriteImports(null);
+                                               if (edit instanceof MultiTextEdit ? ((MultiTextEdit)edit).getChildrenSize() > 0 : true) {
+                                                       root.addChild(edit);
+                                                       change.addTextEditGroup(
+                                                               new TextEditGroup(RefactoringCoreMessages.InlineMethodRefactoring_edit_import, new TextEdit[] {edit}));
+                                               }
+                                       }
+                               }
+                       } finally {
+                               if (inliner != null)
+                                       inliner.dispose();
+                       }
+                       sub.worked(1);
+                       if (sub.isCanceled())
+                               throw new OperationCanceledException();
+               }
+               result.merge(searchStatus);
+               sub.done();
+               pm.done();
+               return result;
+       }
+
+       public static TargetProvider create(ICompilationUnit cu, MethodInvocation invocation) {
+               return new SingleCallTargetProvider(cu, invocation);
+       }
+
+       public static TargetProvider create(ICompilationUnit cu, SuperMethodInvocation invocation) {
+               return new SingleCallTargetProvider(cu, invocation);
+       }
+
+       public static TargetProvider create(ICompilationUnit cu, ConstructorInvocation invocation) {
+               return new SingleCallTargetProvider(cu, invocation);
+       }
+
+       public static TargetProvider create(MethodDeclaration declaration) {
+               IMethodBinding method= declaration.resolveBinding();
+               if (method == null)
+                       return new ErrorTargetProvider(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.TargetProvider_method_declaration_not_unique));
+               ITypeBinding type= method.getDeclaringClass();
+               if (type.isLocal()) {
+                       if (((IType) type.getJavaElement()).isBinary()) {
+                               return new ErrorTargetProvider(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.TargetProvider_cannot_local_method_in_binary));
+                       } else {
+                               IType declaringClassOfLocal= (IType) type.getDeclaringClass().getJavaElement();
+                               return new LocalTypeTargetProvider(declaringClassOfLocal.getCompilationUnit(), declaration);
+                       }
+               } else {
+                       return new MemberTypeTargetProvider(declaration.resolveBinding());
+               }
+       }
+
+       public static TargetProvider create(IMethodBinding methodBinding) {
+               return new MemberTypeTargetProvider(methodBinding);
+       }
+
+       static void fastDone(IProgressMonitor pm) {
+               if (pm == null)
+                       return;
+               pm.beginTask("", 1); //$NON-NLS-1$
+               pm.worked(1);
+               pm.done();
+       }
+
+       static class ErrorTargetProvider extends TargetProvider {
+               private RefactoringStatus fErrorStatus;
+               public ErrorTargetProvider(RefactoringStatus status) {
+                       fErrorStatus= status;
+               }
+               @Override
+               public RefactoringStatus checkActivation() throws JavaModelException {
+                       return fErrorStatus;
+               }
+               @Override
+               public void initialize() {
+               }
+               @Override
+               public ICompilationUnit[] getAffectedCompilationUnits(RefactoringStatus status, ReferencesInBinaryContext binaryRefs, IProgressMonitor pm) throws JavaModelException {
+                       return null;
+               }
+               @Override
+               public BodyDeclaration[] getAffectedBodyDeclarations(ICompilationUnit unit, IProgressMonitor pm) {
+                       return null;
+               }
+               @Override
+               public ASTNode[] getInvocations(BodyDeclaration declaration, IProgressMonitor pm) {
+                       return null;
+               }
+               @Override
+               public int getStatusSeverity() {
+                       return 0;
+               }
+       }
+
+       static class SingleCallTargetProvider extends TargetProvider {
+               private ICompilationUnit fCUnit;
+               private ASTNode fInvocation;
+               private boolean fIterated;
+               public SingleCallTargetProvider(ICompilationUnit cu, ASTNode invocation) {
+                       Assert.isNotNull(cu);
+                       Assert.isNotNull(invocation);
+                       Assert.isTrue(Invocations.isInvocation(invocation));
+                       fCUnit= cu;
+                       fInvocation= invocation;
+               }
+               @Override
+               public void initialize() {
+                       fIterated= false;
+               }
+               @Override
+               public ICompilationUnit[] getAffectedCompilationUnits(RefactoringStatus status, ReferencesInBinaryContext binaryRefs, IProgressMonitor pm) {
+                       return new ICompilationUnit[] { fCUnit };
+               }
+               @Override
+               public BodyDeclaration[] getAffectedBodyDeclarations(ICompilationUnit unit, IProgressMonitor pm) {
+                       Assert.isTrue(unit == fCUnit);
+                       if (fIterated)
+                               return new BodyDeclaration[0];
+                       fastDone(pm);
+                       return new BodyDeclaration[] {
+                               (BodyDeclaration)ASTNodes.getParent(fInvocation, BodyDeclaration.class)
+                       };
+               }
+
+               @Override
+               public ASTNode[] getInvocations(BodyDeclaration declaration, IProgressMonitor pm) {
+                       fastDone(pm);
+                       if (fIterated)
+                               return null;
+                       fIterated= true;
+                       return new ASTNode[] { fInvocation };
+               }
+               @Override
+               public RefactoringStatus checkActivation() throws JavaModelException {
+                       return new RefactoringStatus();
+               }
+               @Override
+               public int getStatusSeverity() {
+                       return RefactoringStatus.FATAL;
+               }
+               @Override
+               public boolean isSingle() {
+                       return true;
+               }
+       }
+
+       static class BodyData {
+               private List<ASTNode> fInvocations;
+
+               public BodyData() {
+               }
+               public void addInvocation(ASTNode node) {
+                       if (fInvocations == null)
+                               fInvocations= new ArrayList<ASTNode>(2);
+                       fInvocations.add(node);
+               }
+               public ASTNode[] getInvocations() {
+                       return fInvocations.toArray(new ASTNode[fInvocations.size()]);
+               }
+               public boolean hasInvocations() {
+                       return fInvocations != null && !fInvocations.isEmpty();
+               }
+               public void generated_6763071243383047141(InvocationFinder invocationfinder, FieldDeclaration node) {
+                       if (hasInvocations()) {
+                               invocationfinder.result.put(node, this);
+                       }
+               }
+               public void generated_8313752434182455133(InvocationFinder invocationfinder, MethodDeclaration node) {
+                       if (hasInvocations()) {
+                               invocationfinder.result.put(node, this);
+                       }
+               }
+               public void generated_5620006719401115627(InvocationFinder invocationfinder, Initializer node) {
+                       if (hasInvocations()) {
+                               invocationfinder.result.put(node, this);
+                       }
+               }
+               public void generated_851015221530301005(InvocationFinder arg, Block node) {
+                       if (hasInvocations()) {
+                               arg.result.put((BodyDeclaration) ASTNodes.getParent(node, BodyDeclaration.class), this);
+                       }
+               }
+       }
+
+       static class InvocationFinder extends ASTVisitor {
+               Map<BodyDeclaration, BodyData> result= new HashMap<BodyDeclaration, BodyData>(2);
+               Stack<BodyData> fBodies= new Stack<BodyData>();
+               BodyData fCurrent;
+               private IMethodBinding fBinding;
+               public InvocationFinder(IMethodBinding binding) {
+                       Assert.isNotNull(binding);
+                       fBinding= binding.getMethodDeclaration();
+                       Assert.isNotNull(fBinding);
+               }
+               @Override
+               public boolean visit(MethodInvocation node) {
+                       if (node.resolveTypeBinding() != null && matches(node.resolveMethodBinding()) && fCurrent != null) {
+                               fCurrent.addInvocation(node);
+                       }
+                       return true;
+               }
+               @Override
+               public boolean visit(SuperMethodInvocation node) {
+                       if (matches(node.getName().resolveBinding()) && fCurrent != null) {
+                               fCurrent.addInvocation(node);
+                       }
+                       return true;
+               }
+               @Override
+               public boolean visit(ConstructorInvocation node) {
+                       if (matches(node.resolveConstructorBinding()) && fCurrent != null) {
+                               fCurrent.addInvocation(node);
+                       }
+                       return true;
+               }
+               @Override
+               public boolean visit(ClassInstanceCreation node) {
+                       if (matches(node.resolveConstructorBinding()) && fCurrent != null) {
+                               fCurrent.addInvocation(node);
+                       }
+                       return true;
+               }
+               @Override
+               public boolean visit(TypeDeclaration node) {
+                       return visitType();
+               }
+               @Override
+               public void endVisit(TypeDeclaration node) {
+                       endVisitBodyDeclaration();
+               }
+               @Override
+               public boolean visit(EnumDeclaration node) {
+                       return visitType();
+               }
+               @Override
+               public void endVisit(EnumDeclaration node) {
+                       endVisitBodyDeclaration();
+               }
+               @Override
+               public boolean visit(AnnotationTypeDeclaration node) {
+                       return visitType();
+               }
+               @Override
+               public void endVisit(AnnotationTypeDeclaration node) {
+                       endVisitBodyDeclaration();
+               }
+               private boolean visitType() {
+                       fBodies.add(fCurrent);
+                       fCurrent= null;
+                       return true;
+               }
+               protected boolean visitNonTypeBodyDeclaration() {
+                       fBodies.add(fCurrent);
+                       fCurrent= new BodyData();
+                       return true;
+               }
+               protected void endVisitBodyDeclaration() {
+                       fCurrent= fBodies.remove(fBodies.size() - 1);
+               }
+               @Override
+               public boolean visit(FieldDeclaration node) {
+                       return visitNonTypeBodyDeclaration();
+               }
+               @Override
+               public void endVisit(FieldDeclaration node) {
+                       fCurrent.generated_6763071243383047141(this, node);
+                       endVisitBodyDeclaration();
+               }
+               @Override
+               public boolean visit(MethodDeclaration node) {
+                       return visitNonTypeBodyDeclaration();
+               }
+               @Override
+               public void endVisit(MethodDeclaration node) {
+                       fCurrent.generated_8313752434182455133(this, node);
+                       endVisitBodyDeclaration();
+
+               }
+               @Override
+               public boolean visit(Initializer node) {
+                       return visitNonTypeBodyDeclaration();
+               }
+               @Override
+               public void endVisit(Initializer node) {
+                       fCurrent.generated_5620006719401115627(this, node);
+                       endVisitBodyDeclaration();
+               }
+               private boolean matches(IBinding binding) {
+                       if (!(binding instanceof IMethodBinding))
+                               return false;
+                       return fBinding.isEqualTo(((IMethodBinding)binding).getMethodDeclaration());
+               }
+               public void generated_8913200629792015113(ASTNode root, MemberTypeTargetProvider membertypetargetprovider) {
+                       root.accept(this);
+                       membertypetargetprovider.fCurrentBodies= result;
+               }
+       }
+
+       private static class LocalTypeTargetProvider extends TargetProvider {
+               private ICompilationUnit fCUnit;
+               private MethodDeclaration fDeclaration;
+               private Map<BodyDeclaration, BodyData> fBodies;
+               public LocalTypeTargetProvider(ICompilationUnit unit, MethodDeclaration declaration) {
+                       Assert.isNotNull(unit);
+                       Assert.isNotNull(declaration);
+                       fCUnit= unit;
+                       fDeclaration= declaration;
+               }
+               @Override
+               public void initialize() {
+                       IMethodBinding methodBinding= fDeclaration.resolveBinding();
+                       InvocationFinder finder;
+                       ASTNode type= ASTNodes.getParent(fDeclaration, AbstractTypeDeclaration.class);
+                       if (methodBinding.getDeclaringClass().isAnonymous()) {
+                               finder= new InvocationFinder(methodBinding);
+                               type.accept(finder);
+                       } else {
+                               //scope of local class is enclosing block
+                               ASTNode block= type.getParent().getParent();
+                               finder= new InvocationFinder(methodBinding) {
+                                       @Override
+                                       public boolean visit(Block node) {
+                                               return visitNonTypeBodyDeclaration();
+                                       }
+                                       @Override
+                                       public void endVisit(Block node) {
+                                               fCurrent.generated_851015221530301005(this, node);
+                                               endVisitBodyDeclaration();
+                                       }
+                               };
+                               block.accept(finder);
+                       }
+                       fBodies= finder.result;
+               }
+               @Override
+               public ICompilationUnit[] getAffectedCompilationUnits(RefactoringStatus status, ReferencesInBinaryContext binaryRefs, IProgressMonitor pm) {
+                       fastDone(pm);
+                       return new ICompilationUnit[] { fCUnit };
+               }
+
+               @Override
+               public BodyDeclaration[] getAffectedBodyDeclarations(ICompilationUnit unit, IProgressMonitor pm) {
+                       Assert.isTrue(unit == fCUnit);
+                       Set<BodyDeclaration> result= fBodies.keySet();
+                       fastDone(pm);
+                       return result.toArray(new BodyDeclaration[result.size()]);
+               }
+
+               @Override
+               public ASTNode[] getInvocations(BodyDeclaration declaration, IProgressMonitor pm) {
+                       BodyData data= fBodies.get(declaration);
+                       Assert.isNotNull(data);
+                       fastDone(pm);
+                       return data.getInvocations();
+               }
+
+               @Override
+               public RefactoringStatus checkActivation() throws JavaModelException {
+                       return new RefactoringStatus();
+               }
+
+               @Override
+               public int getStatusSeverity() {
+                       return RefactoringStatus.ERROR;
+               }
+       }
+
+       static class MemberTypeTargetProvider extends TargetProvider {
+               private final IMethodBinding fMethodBinding;
+               private Map<BodyDeclaration, BodyData> fCurrentBodies;
+               public MemberTypeTargetProvider(IMethodBinding methodBinding) {
+                       Assert.isNotNull(methodBinding);
+                       fMethodBinding= methodBinding;
+               }
+               @Override
+               public void initialize() {
+                       // do nothing.
+               }
+
+               @Override
+               public ICompilationUnit[] getAffectedCompilationUnits(final RefactoringStatus status, ReferencesInBinaryContext binaryRefs, IProgressMonitor pm) throws CoreException {
+                       IMethod method= (IMethod)fMethodBinding.getJavaElement();
+                       Assert.isTrue(method != null);
+
+                       SearchPattern pattern= SearchPattern.createPattern(method, IJavaSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE);
+                       IJavaSearchScope scope= RefactoringScopeFactory.create(method, true, false);
+                       final HashSet<ICompilationUnit> affectedCompilationUnits= new HashSet<ICompilationUnit>();
+                       CollectingSearchRequestor requestor= new CollectingSearchRequestor(binaryRefs) {
+                               private ICompilationUnit fLastCU;
+                               @Override
+                               public void acceptSearchMatch(SearchMatch match) throws CoreException {
+                                       if (filterMatch(match))
+                                               return;
+                                       if (match.isInsideDocComment())
+                                               return; // TODO: should warn user (with something like a ReferencesInBinaryContext)
+
+                                       ICompilationUnit unit= SearchUtils.getCompilationUnit(match);
+                                       if (match.getAccuracy() == SearchMatch.A_INACCURATE) {
+                                               if (unit != null) {
+                                                       status.addError(RefactoringCoreMessages.TargetProvider_inaccurate_match,
+                                                               JavaStatusContext.create(unit, new SourceRange(match.getOffset(), match.getLength())));
+                                               } else {
+                                                       status.addError(RefactoringCoreMessages.TargetProvider_inaccurate_match);
+                                               }
+                                       } else if (unit != null) {
+                                               if (! unit.equals(fLastCU)) {
+                                                       fLastCU= unit;
+                                                       affectedCompilationUnits.add(unit);
+                                               }
+                                       }
+                               }
+                       };
+                       new SearchEngine().search(pattern, SearchUtils.getDefaultSearchParticipants(), scope, requestor, new SubProgressMonitor(pm, 1));
+                       return affectedCompilationUnits.toArray(new ICompilationUnit[affectedCompilationUnits.size()]);
+               }
+
+               @Override
+               public BodyDeclaration[] getAffectedBodyDeclarations(ICompilationUnit unit, IProgressMonitor pm) {
+                       ASTNode root= new RefactoringASTParser(ASTProvider.SHARED_AST_LEVEL).parse(unit, true);
+                       InvocationFinder finder= new InvocationFinder(fMethodBinding);
+                       finder.generated_8913200629792015113(root, MemberTypeTargetProvider.this);
+                       Set<BodyDeclaration> result= fCurrentBodies.keySet();
+                       fastDone(pm);
+                       return result.toArray(new BodyDeclaration[result.size()]);
+               }
+               @Override
+               public ASTNode[] getInvocations(BodyDeclaration declaration, IProgressMonitor pm) {
+                       BodyData data= fCurrentBodies.get(declaration);
+                       Assert.isNotNull(data);
+                       fastDone(pm);
+                       return data.getInvocations();
+               }
+
+               @Override
+               public RefactoringStatus checkActivation() throws JavaModelException {
+                       return new RefactoringStatus();
+               }
+
+               @Override
+               public int getStatusSeverity() {
+                       return RefactoringStatus.ERROR;
+               }
+       }
+}