1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-02 22:05:44 +02:00

Bug 369333 - Implement method requires files to be saved,

and other assorted refactoring fixes.
This commit is contained in:
Sergey Prigogin 2012-02-24 16:30:37 -08:00
parent 0ecc12f363
commit fb9f6f5b59
16 changed files with 206 additions and 90 deletions

View file

@ -19,7 +19,7 @@ import org.eclipse.cdt.ui.CUIPlugin;
public class ExtractFunctionWizard extends RefactoringWizard { public class ExtractFunctionWizard extends RefactoringWizard {
public ExtractFunctionWizard(ExtractFunctionRefactoring refactoring) { public ExtractFunctionWizard(ExtractFunctionRefactoring refactoring) {
super(refactoring, DIALOG_BASED_USER_INTERFACE | PREVIEW_EXPAND_FIRST_NODE); super(refactoring, DIALOG_BASED_USER_INTERFACE | PREVIEW_EXPAND_FIRST_NODE);
setDefaultPageTitle(Messages.ExtractFunctionWizard_extract_function); setDefaultPageTitle(Messages.ExtractFunctionRefactoring_ExtractFunction);
setDialogSettings(CUIPlugin.getDefault().getDialogSettings()); setDialogSettings(CUIPlugin.getDefault().getDialogSettings());
} }

View file

@ -15,7 +15,6 @@ package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
import org.eclipse.osgi.util.NLS; import org.eclipse.osgi.util.NLS;
public final class Messages extends NLS { public final class Messages extends NLS {
public static String ExtractFunctionWizard_extract_function;
public static String ExtractFunctionRefactoring_ExtractFunction; public static String ExtractFunctionRefactoring_ExtractFunction;
public static String ExtractFunctionRefactoring_NoStmtSelected; public static String ExtractFunctionRefactoring_NoStmtSelected;
public static String ExtractFunctionRefactoring_TooManySelected; public static String ExtractFunctionRefactoring_TooManySelected;

View file

@ -10,7 +10,6 @@
# Institute for Software - initial API and implementation # Institute for Software - initial API and implementation
# Sergey Prigogin (Google) # Sergey Prigogin (Google)
############################################################################### ###############################################################################
ExtractFunctionWizard_extract_function=Extract Function
ExtractFunctionRefactoring_ExtractFunction=Extract Function ExtractFunctionRefactoring_ExtractFunction=Extract Function
ExtractFunctionRefactoring_NoStmtSelected=No statement selected ExtractFunctionRefactoring_NoStmtSelected=No statement selected
ExtractFunctionRefactoring_TooManySelected=Too many declarations in selection. ExtractFunctionRefactoring_TooManySelected=Too many declarations in selection.

View file

@ -41,7 +41,7 @@ public class GenerateGettersAndSettersRefactoringRunner extends RefactoringRunne
GenerateGettersAndSettersRefactoring refactoring = GenerateGettersAndSettersRefactoring refactoring =
new GenerateGettersAndSettersRefactoring(element, selection, project); new GenerateGettersAndSettersRefactoring(element, selection, project);
RefactoringWizard wizard = RefactoringWizard wizard =
new GenerateGettersAndSettersRefactoringWizard(refactoring); new GenerateGettersAndSettersWizard(refactoring);
run(wizard, refactoring, RefactoringSaveHelper.SAVE_REFACTORING); run(wizard, refactoring, RefactoringSaveHelper.SAVE_REFACTORING);
} }
} }

View file

@ -17,10 +17,11 @@ import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
/** /**
* @author Thomas Corbat * @author Thomas Corbat
*/ */
public class GenerateGettersAndSettersRefactoringWizard extends RefactoringWizard { public class GenerateGettersAndSettersWizard extends RefactoringWizard {
public GenerateGettersAndSettersRefactoringWizard( public GenerateGettersAndSettersWizard(
GenerateGettersAndSettersRefactoring refactoring) { GenerateGettersAndSettersRefactoring refactoring) {
super(refactoring, WIZARD_BASED_USER_INTERFACE); super(refactoring, DIALOG_BASED_USER_INTERFACE | PREVIEW_EXPAND_FIRST_NODE);
setDefaultPageTitle(Messages.GenerateGettersAndSettersInputPage_Name);
} }
@Override @Override

View file

@ -13,7 +13,7 @@ GenerateGettersAndSettersInputPage_DeselectAll=Deselect All
GenerateGettersAndSettersInputPage_Header=Select getters and setters to create: GenerateGettersAndSettersInputPage_Header=Select getters and setters to create:
GenerateGettersAndSettersInputPage_LinkDescription=The names of getters and setters may be configured on the <a>Name Style</a> preference page. GenerateGettersAndSettersInputPage_LinkDescription=The names of getters and setters may be configured on the <a>Name Style</a> preference page.
GenerateGettersAndSettersInputPage_LinkTooltip=Show the name style preferences. GenerateGettersAndSettersInputPage_LinkTooltip=Show the name style preferences.
GenerateGettersAndSettersInputPage_Name=Generate getters and setters GenerateGettersAndSettersInputPage_Name=Generate Getters and Setters
GenerateGettersAndSettersInputPage_SeparateDefinition=Definition separate from declaration GenerateGettersAndSettersInputPage_SeparateDefinition=Definition separate from declaration
GenerateGettersAndSettersInputPage_SelectAll=Select All GenerateGettersAndSettersInputPage_SelectAll=Select All
GenerateGettersAndSettersInputPage_SelectGetters=Select Getters GenerateGettersAndSettersInputPage_SelectGetters=Select Getters

View file

@ -7,7 +7,7 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Institute for Software (IFS)- initial API and implementation * Institute for Software (IFS)- initial API and implementation
******************************************************************************/ ******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.implementmethod; package org.eclipse.cdt.internal.ui.refactoring.implementmethod;
@ -27,36 +27,27 @@ import org.eclipse.ui.dialogs.ContainerCheckedTreeViewer;
/** /**
* @author Emanuel Graf IFS * @author Emanuel Graf IFS
*
*/ */
public class ImplementMethodInputPage extends UserInputWizardPage{ public class ImplementMethodInputPage extends UserInputWizardPage {
private ImplementMethodData data; private ImplementMethodData data;
private ImplementMethodRefactoringWizard wizard;
private ContainerCheckedTreeViewer tree; private ContainerCheckedTreeViewer tree;
public ImplementMethodInputPage(ImplementMethodData data, ImplementMethodRefactoringWizard implementMethodRefactoringWizard) { public ImplementMethodInputPage(ImplementMethodData data, ImplementMethodWizard implementMethodRefactoringWizard) {
super(Messages.ImplementMethodInputPage_PageTitle); super(Messages.ImplementMethodInputPage_PageTitle);
this.setData(data); this.setData(data);
wizard = implementMethodRefactoringWizard;
} }
@Override @Override
public boolean canFlipToNextPage() { public boolean canFlipToNextPage() {
if(data.needParameterInput()) { if (data.needParameterInput()) {
return super.canFlipToNextPage(); return super.canFlipToNextPage();
}else {//getNextPage call is too expensive in this case. } else { // getNextPage call is too expensive in this case.
return isPageComplete(); return isPageComplete();
} }
} }
@Override @Override
public void createControl(Composite parent) { public void createControl(Composite parent) {
setTitle(Messages.ImplementMethodInputPage_PageTitle); setTitle(Messages.ImplementMethodInputPage_PageTitle);
setMessage(Messages.ImplementMethodInputPage_Header); setMessage(Messages.ImplementMethodInputPage_Header);
@ -120,7 +111,6 @@ public class ImplementMethodInputPage extends UserInputWizardPage{
tree.getTree().setLayoutData(new GridData(GridData.FILL_BOTH)); tree.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));
tree.addCheckStateListener(new ICheckStateListener() { tree.addCheckStateListener(new ICheckStateListener() {
@Override @Override
public void checkStateChanged(CheckStateChangedEvent event) { public void checkStateChanged(CheckStateChangedEvent event) {
MethodToImplementConfig config = ((MethodToImplementConfig)event.getElement()); MethodToImplementConfig config = ((MethodToImplementConfig)event.getElement());
@ -131,18 +121,22 @@ public class ImplementMethodInputPage extends UserInputWizardPage{
for (MethodToImplementConfig config : data.getMethodsToImplement()) { for (MethodToImplementConfig config : data.getMethodsToImplement()) {
tree.setChecked(config, config.isChecked()); tree.setChecked(config, config.isChecked());
} }
} }
@Override @Override
public IWizardPage getNextPage() { public IWizardPage getNextPage() {
if(data.needParameterInput()) { if (data.needParameterInput()) {
return wizard.getPageForConfig(data.getFirstConfigNeedingParameterNames()); return getWizard().getPageForConfig(data.getFirstConfigNeedingParameterNames());
}else { } else {
return computeSuccessorPage(); return computeSuccessorPage();
} }
} }
@Override
public ImplementMethodWizard getWizard() {
return (ImplementMethodWizard) super.getWizard();
}
public void setData(ImplementMethodData data) { public void setData(ImplementMethodData data) {
this.data = data; this.data = data;
} }
@ -152,11 +146,10 @@ public class ImplementMethodInputPage extends UserInputWizardPage{
} }
private void checkPage() { private void checkPage() {
if(data.getMethodsToImplement().size() > 0) { if (data.getMethodsToImplement().size() > 0) {
setPageComplete(true); setPageComplete(true);
}else { } else {
setPageComplete(false); setPageComplete(false);
} }
} }
} }

View file

@ -52,8 +52,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNodeFactory; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNodeFactory;
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite; import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.CUIPlugin;
@ -63,6 +61,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.ui.refactoring.CRefactoring; import org.eclipse.cdt.internal.ui.refactoring.CRefactoring;
import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector; import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector;
import org.eclipse.cdt.internal.ui.refactoring.utils.Checks; import org.eclipse.cdt.internal.ui.refactoring.utils.Checks;
import org.eclipse.cdt.internal.ui.refactoring.utils.DefinitionFinder;
import org.eclipse.cdt.internal.ui.refactoring.utils.NameHelper; import org.eclipse.cdt.internal.ui.refactoring.utils.NameHelper;
import org.eclipse.cdt.internal.ui.refactoring.utils.NodeHelper; import org.eclipse.cdt.internal.ui.refactoring.utils.NodeHelper;
import org.eclipse.cdt.internal.ui.refactoring.utils.SelectionHelper; import org.eclipse.cdt.internal.ui.refactoring.utils.SelectionHelper;
@ -120,7 +119,8 @@ public class ImplementMethodRefactoring extends CRefactoring {
private List<IASTSimpleDeclaration> findUnimplementedMethodDeclarations(IProgressMonitor pm) private List<IASTSimpleDeclaration> findUnimplementedMethodDeclarations(IProgressMonitor pm)
throws OperationCanceledException, CoreException { throws OperationCanceledException, CoreException {
IASTTranslationUnit ast = getAST(tu, pm); final SubMonitor sm = SubMonitor.convert(pm, 2);
IASTTranslationUnit ast = getAST(tu, sm.newChild(1));
final List<IASTSimpleDeclaration> list = new ArrayList<IASTSimpleDeclaration>(); final List<IASTSimpleDeclaration> list = new ArrayList<IASTSimpleDeclaration>();
ast.accept(new ASTVisitor() { ast.accept(new ASTVisitor() {
{ {
@ -134,7 +134,7 @@ public class ImplementMethodRefactoring extends CRefactoring {
if (NodeHelper.isMethodDeclaration(simpleDeclaration)) { if (NodeHelper.isMethodDeclaration(simpleDeclaration)) {
IASTDeclarator[] declarators = simpleDeclaration.getDeclarators(); IASTDeclarator[] declarators = simpleDeclaration.getDeclarators();
IBinding binding = declarators[0].getName().resolveBinding(); IBinding binding = declarators[0].getName().resolveBinding();
if (isUnimplementedMethodBinding(binding)) { if (isUnimplementedMethodBinding(binding, sm.newChild(0))) {
list.add(simpleDeclaration); list.add(simpleDeclaration);
return ASTVisitor.PROCESS_SKIP; return ASTVisitor.PROCESS_SKIP;
} }
@ -146,7 +146,7 @@ public class ImplementMethodRefactoring extends CRefactoring {
return list; return list;
} }
private boolean isUnimplementedMethodBinding(IBinding binding) { private boolean isUnimplementedMethodBinding(IBinding binding, IProgressMonitor pm) {
if (binding instanceof ICPPFunction) { if (binding instanceof ICPPFunction) {
if (binding instanceof ICPPMethod) { if (binding instanceof ICPPMethod) {
ICPPMethod methodBinding = (ICPPMethod) binding; ICPPMethod methodBinding = (ICPPMethod) binding;
@ -156,11 +156,7 @@ public class ImplementMethodRefactoring extends CRefactoring {
} }
try { try {
IIndexName[] indexNames = getIndex().findNames(binding, return !DefinitionFinder.hasDefinition(binding, refactoringContext, pm);
IIndex.FIND_DEFINITIONS | IIndex.SEARCH_ACROSS_LANGUAGE_BOUNDARIES);
if (indexNames.length == 0) {
return true;
}
} catch (CoreException e) { } catch (CoreException e) {
CUIPlugin.log(e); CUIPlugin.log(e);
} }

View file

@ -36,7 +36,7 @@ public class ImplementMethodRefactoringRunner extends RefactoringRunner {
public void run() { public void run() {
ImplementMethodRefactoring refactoring = ImplementMethodRefactoring refactoring =
new ImplementMethodRefactoring(element, selection, project); new ImplementMethodRefactoring(element, selection, project);
ImplementMethodRefactoringWizard wizard = new ImplementMethodRefactoringWizard(refactoring); ImplementMethodWizard wizard = new ImplementMethodWizard(refactoring);
run(wizard, refactoring, RefactoringSaveHelper.SAVE_REFACTORING); run(wizard, refactoring, RefactoringSaveHelper.SAVE_REFACTORING);
} }
} }

View file

@ -25,14 +25,15 @@ import org.eclipse.cdt.ui.CUIPlugin;
/** /**
* @author Mirko Stocker * @author Mirko Stocker
*/ */
public class ImplementMethodRefactoringWizard extends RefactoringWizard { public class ImplementMethodWizard extends RefactoringWizard {
private final ImplementMethodRefactoring refactoring; private final ImplementMethodRefactoring refactoring;
private Map<MethodToImplementConfig, ParameterNamesInputPage> pagesMap = private Map<MethodToImplementConfig, ParameterNamesInputPage> pagesMap =
new HashMap<MethodToImplementConfig, ParameterNamesInputPage>(); new HashMap<MethodToImplementConfig, ParameterNamesInputPage>();
public ImplementMethodRefactoringWizard(ImplementMethodRefactoring refactoring) { public ImplementMethodWizard(ImplementMethodRefactoring refactoring) {
super(refactoring, WIZARD_BASED_USER_INTERFACE); super(refactoring, DIALOG_BASED_USER_INTERFACE | PREVIEW_EXPAND_FIRST_NODE);
this.refactoring = refactoring; setDefaultPageTitle(Messages.ImplementMethodInputPage_PageTitle);
this.refactoring = refactoring;
} }
@Override @Override

View file

@ -52,9 +52,9 @@ public class ParameterNamesInputPage extends UserInputWizardPage {
private MethodToImplementConfig config; private MethodToImplementConfig config;
private TranslationUnitPreview translationUnitPreview; private TranslationUnitPreview translationUnitPreview;
private Job delayedPreviewUpdater; private Job delayedPreviewUpdater;
private ImplementMethodRefactoringWizard wizard; private ImplementMethodWizard wizard;
public ParameterNamesInputPage(MethodToImplementConfig config, ImplementMethodRefactoringWizard wizard) { public ParameterNamesInputPage(MethodToImplementConfig config, ImplementMethodWizard wizard) {
super(Messages.ParameterNamesInputPage_Title); super(Messages.ParameterNamesInputPage_Title);
this.config = config; this.config = config;
this.wizard = wizard; this.wizard = wizard;

View file

@ -37,7 +37,6 @@ import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.corext.util.CModelUtil;
import org.eclipse.cdt.internal.ui.editor.ITranslationUnitEditorInput; import org.eclipse.cdt.internal.ui.editor.ITranslationUnitEditorInput;
import org.eclipse.cdt.internal.ui.refactoring.CRefactoringContext; import org.eclipse.cdt.internal.ui.refactoring.CRefactoringContext;
@ -47,47 +46,53 @@ import org.eclipse.cdt.internal.ui.util.EditorUtility;
* Helper class for finding definitions and class member declarations * Helper class for finding definitions and class member declarations
*/ */
public class DefinitionFinder { public class DefinitionFinder {
/**
* Finds the definition for the given name. The definition and the original name may belong
* to a different ASTs. The search is done in the index and in the ASTs of dirty editors.
*
* @param name the name to find the definition for
* @param context the refactoring context
* @param pm the progress monitor
* @return the definition name, or {@code null} if there is no definition or if it is
* not unique.
* @throws CoreException thrown in case of errors
*/
public static IASTName getDefinition(IASTName name, CRefactoringContext context, public static IASTName getDefinition(IASTName name, CRefactoringContext context,
IProgressMonitor pm) throws CoreException { IProgressMonitor pm) throws CoreException, OperationCanceledException {
IIndex index = context.getIndex();
if (index == null) {
return null;
}
IBinding binding = name.resolveBinding(); IBinding binding = name.resolveBinding();
if (binding == null) { if (binding == null) {
return null; return null;
} }
return getDefinition(binding, context, index, pm); return getDefinition(binding, context, pm);
} }
private static IASTName getDefinition(IBinding binding, CRefactoringContext context, /**
IIndex index, IProgressMonitor pm) throws CoreException { * Finds the definition for the given binding. The search is done in the index and in the ASTs
* of dirty editors.
*
* @param binding the binding to find the definition for
* @param context the refactoring context
* @param pm the progress monitor
* @return the definition name, or {@code null} if there is no definition or if it is
* not unique.
* @throws CoreException thrown in case of errors
*/
public static IASTName getDefinition(IBinding binding, CRefactoringContext context,
IProgressMonitor pm) throws CoreException {
SubMonitor sm = SubMonitor.convert(pm, 10); SubMonitor sm = SubMonitor.convert(pm, 10);
IIndex index = context.getIndex();
if (index == null) {
return null;
}
IIndexBinding indexBinding = index.adaptBinding(binding); IIndexBinding indexBinding = index.adaptBinding(binding);
if (binding == null) if (binding == null)
return null; return null;
Set<String> searchedFiles = new HashSet<String>(); Set<String> searchedFiles = new HashSet<String>();
List<IASTName> definitions = new ArrayList<IASTName>(); List<IASTName> definitions = new ArrayList<IASTName>();
// TODO(sprigogin): Check index before dirty editors. IIndexName[] definitionsFromIndex =
IEditorPart[] dirtyEditors = EditorUtility.getDirtyEditors(true); index.findNames(indexBinding, IIndex.FIND_DEFINITIONS | IIndex.SEARCH_ACROSS_LANGUAGE_BOUNDARIES);
SubMonitor loopProgress = sm.newChild(3).setWorkRemaining(dirtyEditors.length);
for (IEditorPart editor : dirtyEditors) {
if (sm.isCanceled()) {
throw new OperationCanceledException();
}
IEditorInput editorInput = editor.getEditorInput();
if (editorInput instanceof ITranslationUnitEditorInput) {
ITranslationUnit tu =
CModelUtil.toWorkingCopy(((ITranslationUnitEditorInput) editorInput).getTranslationUnit());
findDefinitionsInTranslationUnit(indexBinding, tu, context, definitions, loopProgress.newChild(1));
searchedFiles.add(tu.getLocation().toOSString());
}
}
IIndexName[] definitionsFromIndex = index.findDefinitions(indexBinding);
int remainingCount = definitionsFromIndex.length; int remainingCount = definitionsFromIndex.length;
loopProgress = sm.newChild(6).setWorkRemaining(remainingCount); SubMonitor loopProgress = sm.newChild(6).setWorkRemaining(remainingCount);
for (IIndexName name : definitionsFromIndex) { for (IIndexName name : definitionsFromIndex) {
if (sm.isCanceled()) { if (sm.isCanceled()) {
throw new OperationCanceledException(); throw new OperationCanceledException();
@ -96,39 +101,162 @@ public class DefinitionFinder {
name.getFile().getLocation(), null); name.getFile().getLocation(), null);
if (searchedFiles.add(tu.getLocation().toOSString())) { if (searchedFiles.add(tu.getLocation().toOSString())) {
findDefinitionsInTranslationUnit(indexBinding, tu, context, definitions, pm); findDefinitionsInTranslationUnit(indexBinding, tu, context, definitions, pm);
if (definitions.size() > 1)
return null;
} }
loopProgress.setWorkRemaining(--remainingCount); loopProgress.setWorkRemaining(--remainingCount);
} }
if (definitions.isEmpty()) {
// Check dirty editors in case definition has just been introduced but not saved yet.
IEditorPart[] dirtyEditors = EditorUtility.getDirtyEditors(true);
loopProgress = sm.newChild(3).setWorkRemaining(dirtyEditors.length);
for (IEditorPart editor : dirtyEditors) {
if (sm.isCanceled()) {
throw new OperationCanceledException();
}
IEditorInput editorInput = editor.getEditorInput();
if (editorInput instanceof ITranslationUnitEditorInput) {
ITranslationUnit tu = ((ITranslationUnitEditorInput) editorInput).getTranslationUnit();
if (searchedFiles.add(tu.getLocation().toOSString())) {
findDefinitionsInTranslationUnit(indexBinding, tu, context, definitions, loopProgress.newChild(1));
if (definitions.size() > 1)
return null;
}
}
}
}
return definitions.size() == 1 ? definitions.get(0) : null; return definitions.size() == 1 ? definitions.get(0) : null;
} }
/**
* Checks if the given binding has a definition The search is done in the index and in the ASTs
* of dirty editors.
*
* @param binding the binding to find the definition for
* @param context the refactoring context
* @param pm the progress monitor
* @return <code>true</code> if the binding has a definition.
* @throws CoreException thrown in case of errors
*/
public static boolean hasDefinition(IBinding binding, CRefactoringContext context,
IProgressMonitor pm) throws CoreException, OperationCanceledException {
SubMonitor sm = SubMonitor.convert(pm, 10);
IIndex index = context.getIndex();
if (index == null) {
return false;
}
IIndexBinding indexBinding = index.adaptBinding(binding);
if (binding == null)
return false;
Set<String> dirtyFiles = new HashSet<String>();
IEditorPart[] dirtyEditors = EditorUtility.getDirtyEditors(true);
for (IEditorPart editor : dirtyEditors) {
IEditorInput editorInput = editor.getEditorInput();
if (editorInput instanceof ITranslationUnitEditorInput) {
ITranslationUnit tu = ((ITranslationUnitEditorInput) editorInput).getTranslationUnit();
dirtyFiles.add(tu.getLocation().toOSString());
}
}
Set<String> searchedFiles = new HashSet<String>();
IIndexName[] definitionsFromIndex =
index.findNames(indexBinding, IIndex.FIND_DEFINITIONS | IIndex.SEARCH_ACROSS_LANGUAGE_BOUNDARIES);
int remainingCount = definitionsFromIndex.length;
SubMonitor loopProgress = sm.newChild(6).setWorkRemaining(remainingCount);
for (IIndexName name : definitionsFromIndex) {
if (sm.isCanceled()) {
throw new OperationCanceledException();
}
ITranslationUnit tu = CoreModelUtil.findTranslationUnitForLocation(
name.getFile().getLocation(), null);
String filename = tu.getLocation().toOSString();
if (searchedFiles.add(filename) &&
(!dirtyFiles.contains(filename) ||
hasDefinitionsInTranslationUnit(indexBinding, tu, context, loopProgress.newChild(1)))) {
return true;
}
loopProgress.setWorkRemaining(--remainingCount);
}
// Check dirty editors in case definition has just been introduced but not saved yet.
loopProgress = sm.newChild(3).setWorkRemaining(dirtyEditors.length);
for (IEditorPart editor : dirtyEditors) {
if (sm.isCanceled()) {
throw new OperationCanceledException();
}
IEditorInput editorInput = editor.getEditorInput();
if (editorInput instanceof ITranslationUnitEditorInput) {
ITranslationUnit tu = ((ITranslationUnitEditorInput) editorInput).getTranslationUnit();
String filename = tu.getLocation().toOSString();
if (searchedFiles.add(filename) &&
hasDefinitionsInTranslationUnit(indexBinding, tu, context, loopProgress.newChild(1))) {
return true;
}
}
}
return false;
}
private static void findDefinitionsInTranslationUnit(IIndexBinding binding, ITranslationUnit tu, private static void findDefinitionsInTranslationUnit(IIndexBinding binding, ITranslationUnit tu,
CRefactoringContext context, List<IASTName> definitions, IProgressMonitor pm) CRefactoringContext context, List<IASTName> definitions, IProgressMonitor pm)
throws OperationCanceledException, CoreException { throws CoreException, OperationCanceledException {
IASTTranslationUnit ast = context.getAST(tu, pm); IASTTranslationUnit ast = context.getAST(tu, pm);
ArrayUtil.addAll(definitions, ast.getDefinitionsInAST(binding)); ArrayUtil.addAll(definitions, ast.getDefinitionsInAST(binding));
} }
private static boolean hasDefinitionsInTranslationUnit(IIndexBinding binding, ITranslationUnit tu,
CRefactoringContext context, IProgressMonitor pm)
throws CoreException, OperationCanceledException {
IASTTranslationUnit ast = context.getAST(tu, pm);
return ast.getDefinitionsInAST(binding).length != 0;
}
/**
* Finds the declaration for the given class member. The declaration and the original member
* name may belong to a different ASTs. The search is done in the index and in the ASTs of dirty
* editors.
*
* @param memberName the name of the class member to find the declaration for
* @param context the refactoring context
* @param pm the progress monitor
* @return the declaration name, or {@code null} if there is no declaration or if it is
* not unique.
* @throws CoreException thrown in case of errors
*/
public static IASTName getMemberDeclaration(IASTName memberName, CRefactoringContext context, public static IASTName getMemberDeclaration(IASTName memberName, CRefactoringContext context,
IProgressMonitor pm) throws CoreException { IProgressMonitor pm) throws CoreException, OperationCanceledException {
IIndex index = context.getIndex();
if (index == null)
return null;
IBinding binding = memberName.resolveBinding(); IBinding binding = memberName.resolveBinding();
if (!(binding instanceof ICPPMember)) if (!(binding instanceof ICPPMember))
return null; return null;
return getMemberDeclaration((ICPPMember) binding, context, index, pm); return getMemberDeclaration((ICPPMember) binding, context, pm);
} }
private static IASTName getMemberDeclaration(ICPPMember member, CRefactoringContext context, /**
IIndex index, IProgressMonitor pm) throws CoreException { * Finds the declaration for the given class member. The declaration and the original member
IASTName classDefintionName = getDefinition(member.getClassOwner(), context, index, pm); * name may belong to a different ASTs. The search is done in the index and in the ASTs of dirty
* editors.
*
* @param member the class member binding to find the declaration for
* @param context the refactoring context
* @param pm the progress monitor
* @return the declaration name, or {@code null} if there is no declaration or if it is
* not unique.
* @throws CoreException thrown in case of errors
*/
public static IASTName getMemberDeclaration(ICPPMember member, CRefactoringContext context,
IProgressMonitor pm) throws CoreException, OperationCanceledException {
IASTName classDefintionName = getDefinition(member.getClassOwner(), context, pm);
if (classDefintionName == null) if (classDefintionName == null)
return null; return null;
IASTCompositeTypeSpecifier compositeTypeSpecifier = IASTCompositeTypeSpecifier compositeTypeSpecifier =
CPPVisitor.findAncestorWithType(classDefintionName, IASTCompositeTypeSpecifier.class); CPPVisitor.findAncestorWithType(classDefintionName, IASTCompositeTypeSpecifier.class);
IASTTranslationUnit ast = classDefintionName.getTranslationUnit(); IASTTranslationUnit ast = classDefintionName.getTranslationUnit();
IIndex index = context.getIndex();
if (index == null) {
return null;
}
IASTName[] memberDeclarationNames = ast.getDeclarationsInAST(index.adaptBinding(member)); IASTName[] memberDeclarationNames = ast.getDeclarationsInAST(index.adaptBinding(member));
for (IASTName name : memberDeclarationNames) { for (IASTName name : memberDeclarationNames) {
if (name.getPropertyInParent() == IASTDeclarator.DECLARATOR_NAME) { if (name.getPropertyInParent() == IASTDeclarator.DECLARATOR_NAME) {

View file

@ -32,7 +32,6 @@ public class HideMethodAction extends RefactoringAction {
public HideMethodAction() { public HideMethodAction() {
super(Messages.HideMethodAction_label); super(Messages.HideMethodAction_label);
setSaveRequired(true);
} }
@Override @Override

View file

@ -36,7 +36,6 @@ public class ImplementMethodAction extends RefactoringAction {
public ImplementMethodAction() { public ImplementMethodAction() {
super(Messages.ImplementMethodAction_label); super(Messages.ImplementMethodAction_label);
setSaveRequired(true);
} }
/** /**

View file

@ -26,7 +26,7 @@ import org.eclipse.cdt.internal.ui.editor.CEditor;
import org.eclipse.cdt.internal.ui.refactoring.utils.EclipseObjects; import org.eclipse.cdt.internal.ui.refactoring.utils.EclipseObjects;
/** /**
* Common base class for refactoring actions * Common base class for refactoring actions.
* @since 5.0 * @since 5.0
* @noextend This class is not intended to be subclassed by clients. * @noextend This class is not intended to be subclassed by clients.
*/ */
@ -38,14 +38,16 @@ public abstract class RefactoringAction extends Action {
public RefactoringAction(String label) { public RefactoringAction(String label) {
super(label); super(label);
saveRequired = false;
} }
/** /**
* Sets behavior with respect to saving dirty editors. * Sets behavior with respect to saving dirty editors.
* @param saveRequired if <code>true</code>, dirty editors will be saved before refactoring. * @param saveRequired if <code>true</code>, dirty editors will be saved before refactoring.
*
* @deprecated saving of editors should be controlled by refactoring runner, not by the action.
* @since 5.3 * @since 5.3
*/ */
@Deprecated
public void setSaveRequired(boolean saveRequired) { public void setSaveRequired(boolean saveRequired) {
this.saveRequired = saveRequired; this.saveRequired = saveRequired;
} }

View file

@ -33,7 +33,6 @@ public class ToggleFunctionAction extends RefactoringAction {
public ToggleFunctionAction() { public ToggleFunctionAction() {
super(Messages.ToggleFunctionAction_label); super(Messages.ToggleFunctionAction_label);
setSaveRequired(true);
} }
@Override @Override