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:
parent
0ecc12f363
commit
fb9f6f5b59
16 changed files with 206 additions and 90 deletions
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -27,22 +27,16 @@ 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()) {
|
||||||
|
@ -52,11 +46,8 @@ public class ImplementMethodInputPage extends UserInputWizardPage{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@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;
|
||||||
}
|
}
|
||||||
|
@ -158,5 +152,4 @@ public class ImplementMethodInputPage extends UserInputWizardPage{
|
||||||
setPageComplete(false);
|
setPageComplete(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,13 +25,14 @@ 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);
|
||||||
|
setDefaultPageTitle(Messages.ImplementMethodInputPage_PageTitle);
|
||||||
this.refactoring = refactoring;
|
this.refactoring = refactoring;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -36,7 +36,6 @@ public class ImplementMethodAction extends RefactoringAction {
|
||||||
|
|
||||||
public ImplementMethodAction() {
|
public ImplementMethodAction() {
|
||||||
super(Messages.ImplementMethodAction_label);
|
super(Messages.ImplementMethodAction_label);
|
||||||
setSaveRequired(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue