1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 456099 - Renaming a class should also rename related files

This commit is contained in:
Sergey Prigogin 2014-12-23 10:30:06 -08:00
parent f86ee9bbf7
commit b74feb2c3d
41 changed files with 1598 additions and 381 deletions

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2011 QNX Software Systems and others.
* Copyright (c) 2000, 2014 QNX Software Systems 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
@ -8,6 +8,7 @@
* Contributors:
* QNX Software Systems - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.core.model;
@ -21,6 +22,7 @@ import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.parser.FileContent;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.internal.core.model.IBufferFactory;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
@ -419,6 +421,15 @@ public interface ITranslationUnit extends ICElement, IParent, IOpenable, ISource
*/
public IPath getLocation();
/**
* Returns the corresponding file for this translation unit, or {@code null} if this translation
* unit does not have a corresponding file.
*
* @return the corresponding file, or {@code null} if none
* @since 5.9
*/
IFile getFile();
/**
* Returns the scanner info associated with this translation unit. May return {@code null}
* if no configuration is available.

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2013 QNX Software Systems and others.
* Copyright (c) 2000, 2014 QNX Software Systems 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
@ -354,8 +354,9 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
return location;
}
@Override
public IFile getFile() {
IResource res = getResource();
IResource res = super.getResource();
if (res instanceof IFile) {
return (IFile) res;
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2013 IBM Corporation and others.
* Copyright (c) 2004, 2014 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
@ -345,7 +345,8 @@ public abstract class ArrayUtil {
}
/**
* Adds all elements of an array to a collection.
* Adds all elements of an array to a collection. For an {@link ArrayList} this method is
* slightly more efficient than {@link java.util.Collections#addAll(Collection, T...)}.
* @since 5.4
*/
@SafeVarargs

View file

@ -12,8 +12,10 @@ package org.eclipse.cdt.ui.tests.refactoring.rename;
import junit.framework.Test;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.ltk.core.refactoring.participants.MoveRefactoring;
import org.eclipse.ltk.core.refactoring.participants.RenameRefactoring;
import org.eclipse.ltk.internal.core.refactoring.resource.MoveResourcesProcessor;
@ -23,6 +25,10 @@ import org.eclipse.cdt.ui.PreferenceConstants;
import org.eclipse.cdt.ui.tests.refactoring.RefactoringTestBase;
import org.eclipse.cdt.internal.ui.refactoring.CRefactoring;
import org.eclipse.cdt.internal.ui.refactoring.rename.CRefactoringArgument;
import org.eclipse.cdt.internal.ui.refactoring.rename.CRefactory;
import org.eclipse.cdt.internal.ui.refactoring.rename.CRenameProcessor;
import org.eclipse.cdt.internal.ui.refactoring.rename.CRenameRefactoring;
/**
* Tests for
@ -55,6 +61,27 @@ public class RenameMoveHeaderRefactoringTest extends RefactoringTestBase {
throw new UnsupportedOperationException();
}
protected CRenameRefactoring createRenameRefactoring(String newName) {
IFile file = getSelectedFile();
TextSelection selection = getSelection();
CRefactoringArgument arg = new CRefactoringArgument(file, selection.getOffset(), selection.getLength());
CRenameProcessor processor = new CRenameProcessor(CRefactory.getInstance(), arg);
processor.setReplacementText(newName);
processor.setSelectedOptions(0xFFFF & ~CRefactory.OPTION_EXHAUSTIVE_FILE_SEARCH);
return new CRenameRefactoring(processor);
}
protected void executeRenameRefactoring(String newName, boolean expectedSuccess) throws Exception {
CRenameRefactoring refactoring = createRenameRefactoring(newName);
refactoring.getProcessor().lockIndex();
try {
executeRefactoring(refactoring, expectedSuccess);
} finally {
refactoring.getProcessor().unlockIndex();
}
}
// test1.h
//#ifndef TEST1_H_
//#define TEST1_H_
@ -249,4 +276,44 @@ public class RenameMoveHeaderRefactoringTest extends RefactoringTestBase {
executeRefactoring(refactoring, true);
compareFiles();
}
// OriginalClass.h
//#ifndef ORIGINALCLASS_H_
//#define ORIGINALCLASS_H_
//
//class OriginalClass {};
//
//#endif // ORIGINALCLASS_H_
//====================
// RenamedClass.h
//#ifndef RENAMEDCLASS_H_
//#define RENAMEDCLASS_H_
//
//class RenamedClass {};
//
//#endif // RENAMEDCLASS_H_
// OriginalClass.cpp
//#include "OriginalClass.h"
//====================
// RenamedClass.cpp
//#include "RenamedClass.h"
// OriginalClass_test.cpp
//#include "OriginalClass.h"
//====================
// RenamedClass_test.cpp
//#include "RenamedClass.h"
// SomeOtherFile.cpp
//#include "OriginalClass.h"
///*$*/OriginalClass/*$$*/ a;
//====================
// SomeOtherFile.cpp
//#include "RenamedClass.h"
//RenamedClass a;
public void testClassRename() throws Exception {
executeRenameRefactoring("RenamedClass", true);
compareFiles();
}
}

View file

@ -47,7 +47,7 @@ public class RenameTestBase extends RefactoringTests {
protected Change getRefactorChanges(IFile file, int offset, String newName) throws Exception {
CRenameRefactoring refactoring = createRefactoring(file, offset, newName);
((CRenameProcessor) refactoring.getProcessor()).lockIndex();
refactoring.getProcessor().lockIndex();
try {
RefactoringStatus rs = checkConditions(refactoring);
if (!rs.hasError()) {
@ -62,7 +62,7 @@ public class RenameTestBase extends RefactoringTests {
// is shown.
return null;
} finally {
((CRenameProcessor) refactoring.getProcessor()).unlockIndex();
refactoring.getProcessor().unlockIndex();
}
}
@ -78,7 +78,7 @@ public class RenameTestBase extends RefactoringTests {
protected String[] getRefactorMessages(IFile file, int offset, String newName) throws Exception {
String[] result;
CRenameRefactoring refactoring = createRefactoring(file, offset, newName);
((CRenameProcessor) refactoring.getProcessor()).lockIndex();
refactoring.getProcessor().lockIndex();
try {
RefactoringStatus rs = checkConditions(refactoring);
if (!rs.hasWarning()) {
@ -94,17 +94,17 @@ public class RenameTestBase extends RefactoringTests {
}
return result;
} finally {
((CRenameProcessor) refactoring.getProcessor()).unlockIndex();
refactoring.getProcessor().unlockIndex();
}
}
protected RefactoringStatus checkConditions(IFile file, int offset, String newName) throws Exception {
CRenameRefactoring refactoring = createRefactoring(file, offset, newName);
((CRenameProcessor) refactoring.getProcessor()).lockIndex();
refactoring.getProcessor().lockIndex();
try {
return checkConditions(refactoring);
} finally {
((CRenameProcessor) refactoring.getProcessor()).unlockIndex();
refactoring.getProcessor().unlockIndex();
}
}
@ -118,12 +118,12 @@ public class RenameTestBase extends RefactoringTests {
protected int getRefactorSeverity(IFile file, int offset, String newName) throws Exception {
CRenameRefactoring refactoring = createRefactoring(file, offset, newName);
((CRenameProcessor) refactoring.getProcessor()).lockIndex();
refactoring.getProcessor().lockIndex();
try {
RefactoringStatus rs = checkConditions(refactoring);
return rs.getSeverity();
} finally {
((CRenameProcessor) refactoring.getProcessor()).unlockIndex();
refactoring.getProcessor().unlockIndex();
}
}

View file

@ -4225,7 +4225,7 @@
class="org.eclipse.cdt.internal.ui.refactoring.dialogs.CreateFileChangePreview"
id="org.eclipse.cdt.internal.ui.refactoring.createFileChangePreviewhangePreview">
<enablement>
<instanceof value="org.eclipse.cdt.internal.ui.refactoring.CreateFileChange"/>
<instanceof value="org.eclipse.cdt.internal.ui.refactoring.changes.CreateFileChange"/>
</enablement>
</changePreviewViewer>
<changePreviewViewer

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2013 Google, Inc and others.
* Copyright (c) 2013, 2014 Google, Inc 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
@ -31,6 +31,7 @@ import org.eclipse.cdt.internal.core.parser.scanner.IncludeSearchPathElement;
import org.eclipse.cdt.internal.core.parser.scanner.ScannerUtility;
import org.eclipse.cdt.internal.core.resources.ResourceLookup;
import org.eclipse.cdt.internal.ui.editor.SourceHeaderPartnerFinder;
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle;
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle.IncludeKind;
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludePreferences;
@ -244,24 +245,8 @@ public class InclusionContext {
* used for test files.
*/
public boolean isPartnerFile(IPath path) {
String headerName = path.removeFileExtension().lastSegment();
String sourceName = getTranslationUnit().getLocation().removeFileExtension().lastSegment();
if (headerName.equals(sourceName))
return true;
if (sourceName.startsWith(headerName)) {
int pos = headerName.length();
while (pos < sourceName.length() && !Character.isLetterOrDigit(sourceName.charAt(pos))) {
pos++;
}
if (pos == sourceName.length())
return true;
String suffix = sourceName.substring(pos);
for (String s : fPreferences.partnerFileSuffixes) {
if (suffix.equalsIgnoreCase(s))
return true;
}
}
return false;
return SourceHeaderPartnerFinder.isPartnerFile(getTranslationUnit().getLocation(), path,
fPreferences.partnerFileSuffixes);
}
public IncludeInfo createIncludeInfo(IPath header, IncludeGroupStyle style) {

View file

@ -0,0 +1,384 @@
/*******************************************************************************
* Copyright (c) 2000, 2014 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
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.corext.refactoring.participants;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IPath;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.participants.CopyArguments;
import org.eclipse.ltk.core.refactoring.participants.CopyParticipant;
import org.eclipse.ltk.core.refactoring.participants.CreateArguments;
import org.eclipse.ltk.core.refactoring.participants.CreateParticipant;
import org.eclipse.ltk.core.refactoring.participants.DeleteArguments;
import org.eclipse.ltk.core.refactoring.participants.DeleteParticipant;
import org.eclipse.ltk.core.refactoring.participants.MoveArguments;
import org.eclipse.ltk.core.refactoring.participants.MoveParticipant;
import org.eclipse.ltk.core.refactoring.participants.ParticipantManager;
import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant;
import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor;
import org.eclipse.ltk.core.refactoring.participants.RenameArguments;
import org.eclipse.ltk.core.refactoring.participants.RenameParticipant;
import org.eclipse.ltk.core.refactoring.participants.SharableParticipants;
/**
* A data structure to collect resource modifications.
*/
public class ResourceModifications {
private List<IResource> fCreate;
private List<IResource> fDelete;
private List<IResource> fMove;
private List<MoveArguments> fMoveArguments;
private List<IResource> fRename;
private List<RenameArguments> fRenameArguments;
private List<IResource> fCopy;
private List<CopyArguments> fCopyArguments;
private int fIgnoreCount;
private List<DeltaDescription> fDeltaDescriptions;
public static abstract class DeltaDescription {
protected IResource fResource;
public DeltaDescription(IResource resource) {
fResource= resource;
}
public abstract void buildDelta(IResourceChangeDescriptionFactory builder);
public abstract IPath getDestinationPath();
}
public static class DeleteDescription extends DeltaDescription {
public DeleteDescription(IResource resource) {
super(resource);
}
@Override
public void buildDelta(IResourceChangeDescriptionFactory builder) {
builder.delete(fResource);
}
@Override
public IPath getDestinationPath() {
return null;
}
}
public static class ChangedDescription extends DeltaDescription {
public ChangedDescription(IFile resource) {
super(resource);
}
@Override
public void buildDelta(IResourceChangeDescriptionFactory builder) {
builder.change((IFile)fResource);
}
@Override
public IPath getDestinationPath() {
return null;
}
}
public static class CreateDescription extends DeltaDescription {
public CreateDescription(IResource resource) {
super(resource);
}
@Override
public void buildDelta(IResourceChangeDescriptionFactory builder) {
builder.create(fResource);
}
@Override
public IPath getDestinationPath() {
return fResource.getFullPath();
}
}
public static class MoveDescription extends DeltaDescription {
private IPath fDestination;
public MoveDescription(IResource resource, IPath destination) {
super(resource);
fDestination= destination;
}
@Override
public void buildDelta(IResourceChangeDescriptionFactory builder) {
IResource existing= ResourcesPlugin.getWorkspace().getRoot().findMember(fDestination);
if (existing != null && !existing.equals(fResource)) {
builder.delete(existing);
}
builder.move(fResource, fDestination);
}
@Override
public IPath getDestinationPath() {
return fDestination;
}
}
public static class CopyDescription extends DeltaDescription {
private IPath fDestination;
public CopyDescription(IResource resource, IPath destination) {
super(resource);
fDestination= destination;
}
@Override
public void buildDelta(IResourceChangeDescriptionFactory builder) {
IResource existing= ResourcesPlugin.getWorkspace().getRoot().findMember(fDestination);
if (existing != null && !existing.equals(fResource)) {
builder.delete(existing);
}
builder.copy(fResource, fDestination);
}
@Override
public IPath getDestinationPath() {
return fDestination;
}
}
/**
* Adds the given file to the list of changed files.
*
* @param file the changed file
*/
public void addChanged(IFile file) {
if (fIgnoreCount == 0) {
internalAdd(new ChangedDescription(file));
}
}
/**
* Adds the given resource to the list of resources to be created.
*
* @param create the resource to be add to the list of resources to be created
*/
public void addCreate(IResource create) {
if (fCreate == null)
fCreate= new ArrayList<>(2);
fCreate.add(create);
if (fIgnoreCount == 0) {
internalAdd(new CreateDescription(create));
}
}
/**
* Adds the given resource to the list of resources to be deleted.
*
* @param delete the resource to be deleted
*/
public void addDelete(IResource delete) {
if (fDelete == null)
fDelete= new ArrayList<>(2);
fDelete.add(delete);
if (fIgnoreCount == 0) {
internalAdd(new DeleteDescription(delete));
}
}
/**
* Adds the given resource to the list of resources to be moved.
*
* @param move the resource to be moved
* @param arguments the move arguments
*/
public void addMove(IResource move, MoveArguments arguments) {
if (fMove == null) {
fMove= new ArrayList<>(2);
fMoveArguments= new ArrayList<>(2);
}
fMove.add(move);
fMoveArguments.add(arguments);
if (fIgnoreCount == 0) {
IPath destination= ((IResource)arguments.getDestination()).getFullPath().append(move.getName());
internalAdd(new MoveDescription(move, destination));
}
}
/**
* Adds the given resource to the list of resources to be copied.
*
* @param copy the resource to be copied
* @param arguments the copy arguments
*/
public void addCopy(IResource copy, CopyArguments arguments) {
if (fCopy == null) {
fCopy= new ArrayList<>(2);
fCopyArguments= new ArrayList<>(2);
}
fCopy.add(copy);
fCopyArguments.add(arguments);
addCopyDelta(copy, arguments);
}
/**
* Adds the given resource to the list of renamed resources.
*
* @param rename the resource to be renamed
* @param arguments the arguments of the rename
*/
public void addRename(IResource rename, RenameArguments arguments) {
Assert.isNotNull(rename);
Assert.isNotNull(arguments);
if (fRename == null) {
fRename= new ArrayList<>(2);
fRenameArguments= new ArrayList<>(2);
}
fRename.add(rename);
fRenameArguments.add(arguments);
if (fIgnoreCount == 0) {
IPath newPath= rename.getFullPath().removeLastSegments(1).append(arguments.getNewName());
internalAdd(new MoveDescription(rename, newPath));
}
}
public RefactoringParticipant[] getParticipants(RefactoringStatus status,
RefactoringProcessor processor, String[] natures, SharableParticipants shared) {
List<RefactoringParticipant> result= new ArrayList<>(5);
if (fDelete != null) {
DeleteArguments arguments= new DeleteArguments();
for (Iterator<IResource> iter= fDelete.iterator(); iter.hasNext();) {
DeleteParticipant[] deletes= ParticipantManager.loadDeleteParticipants(status,
processor, iter.next(),
arguments, natures, shared);
result.addAll(Arrays.asList(deletes));
}
}
if (fCreate != null) {
CreateArguments arguments= new CreateArguments();
for (Iterator<IResource> iter= fCreate.iterator(); iter.hasNext();) {
CreateParticipant[] creates= ParticipantManager.loadCreateParticipants(status,
processor, iter.next(),
arguments, natures, shared);
result.addAll(Arrays.asList(creates));
}
}
if (fMove != null) {
for (int i= 0; i < fMove.size(); i++) {
Object element= fMove.get(i);
MoveArguments arguments= fMoveArguments.get(i);
MoveParticipant[] moves= ParticipantManager.loadMoveParticipants(status,
processor, element,
arguments, natures, shared);
result.addAll(Arrays.asList(moves));
}
}
if (fCopy != null) {
for (int i= 0; i < fCopy.size(); i++) {
Object element= fCopy.get(i);
CopyArguments arguments= fCopyArguments.get(i);
CopyParticipant[] copies= ParticipantManager.loadCopyParticipants(status,
processor, element,
arguments, natures, shared);
result.addAll(Arrays.asList(copies));
}
}
if (fRename != null) {
for (int i= 0; i < fRename.size(); i++) {
Object resource= fRename.get(i);
RenameArguments arguments= fRenameArguments.get(i);
RenameParticipant[] renames= ParticipantManager.loadRenameParticipants(status,
processor, resource,
arguments, natures, shared);
result.addAll(Arrays.asList(renames));
}
}
return result.toArray(new RefactoringParticipant[result.size()]);
}
public void ignoreForDelta() {
fIgnoreCount++;
}
public void trackForDelta() {
fIgnoreCount--;
}
public void addDelta(DeltaDescription description) {
if (fIgnoreCount > 0)
return;
internalAdd(description);
}
public void addCopyDelta(IResource copy, CopyArguments arguments) {
if (fIgnoreCount == 0) {
IPath destination= ((IResource) arguments.getDestination()).getFullPath().append(copy.getName());
internalAdd(new CopyDescription(copy, destination));
}
}
/**
* Checks if the resource will exist in the future based on
* the recorded resource modifications.
*
* @param resource the resource to check
* @return whether the resource will exist or not
*/
public boolean willExist(IResource resource) {
if (fDeltaDescriptions == null)
return false;
IPath fullPath= resource.getFullPath();
for (Iterator<DeltaDescription> iter= fDeltaDescriptions.iterator(); iter.hasNext();) {
DeltaDescription delta= iter.next();
if (fullPath.equals(delta.getDestinationPath()))
return true;
}
return false;
}
public void buildDelta(IResourceChangeDescriptionFactory builder) {
if (fDeltaDescriptions == null)
return;
for (Iterator<DeltaDescription> iter= fDeltaDescriptions.iterator(); iter.hasNext();) {
iter.next().buildDelta(builder);
}
}
public static void buildMoveDelta(IResourceChangeDescriptionFactory builder, IResource resource, RenameArguments args) {
IPath newPath= resource.getFullPath().removeLastSegments(1).append(args.getNewName());
new MoveDescription(resource, newPath).buildDelta(builder);
}
public static void buildMoveDelta(IResourceChangeDescriptionFactory builder, IResource resource, MoveArguments args) {
IPath destination= ((IResource)args.getDestination()).getFullPath().append(resource.getName());
new MoveDescription(resource, destination).buildDelta(builder);
}
public static void buildCopyDelta(IResourceChangeDescriptionFactory builder, IResource resource, CopyArguments args) {
IPath destination= ((IResource)args.getDestination()).getFullPath().append(resource.getName());
new CopyDescription(resource, destination).buildDelta(builder);
}
private void internalAdd(DeltaDescription description) {
if (fDeltaDescriptions == null)
fDeltaDescriptions= new ArrayList<>();
fDeltaDescriptions.add(description);
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2011 Wind River Systems, Inc. and others.
* Copyright (c) 2007, 2014 Wind River Systems, Inc. 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
@ -9,6 +9,7 @@
* Anton Leherbauer (Wind River Systems) - initial API and implementation
* Markus Schorn (Wind River Systems)
* Marc-Andre Laperle - Extracted Util class from ToggleSourceHeaderAction
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.editor;
@ -355,4 +356,36 @@ public final class SourceHeaderPartnerFinder {
}
return partnerUnit;
}
/**
* Checks if the given path points to a partner source of the given header file. A source file
* is considered a partner if its name without extension is the same as the name of the header,
* or its name differs by one of the suffixes used for partner, e.g. test, files.
*
* @param partnerCandidate the file system path of the file to check
* @param header the file system path of the header file
* @param partnerFileSuffixes name suffixes allowed for partner files
* @return {@code true} if {@code partnerCandidate} is a partner of {@code header}
*/
public static boolean isPartnerFile(IPath partnerCandidate, IPath header, String[] partnerFileSuffixes) {
String headerName = header.removeFileExtension().lastSegment();
String sourceName = partnerCandidate.removeFileExtension().lastSegment();
if (headerName.equals(sourceName))
return true;
if (sourceName.startsWith(headerName)) {
int pos = headerName.length();
// Skip a delimiter before the suffix, e.g. an underscore or a dash.
while (pos < sourceName.length() && !Character.isLetterOrDigit(sourceName.charAt(pos))) {
pos++;
}
if (pos == sourceName.length())
return true;
String suffix = sourceName.substring(pos);
for (String s : partnerFileSuffixes) {
if (suffix.equalsIgnoreCase(s))
return true;
}
}
return false;
}
}

View file

@ -60,6 +60,7 @@ import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.corext.util.CModelUtil;
import org.eclipse.cdt.internal.ui.refactoring.changes.CCompositeChange;
import org.eclipse.cdt.internal.ui.refactoring.utils.SelectionHelper;
/**

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2011 Institute for Software, HSR Hochschule fuer Technik
* Copyright (c) 2011, 2014 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@ -34,7 +34,8 @@ public class IndexToASTNameHelper {
return visitor.getMatches();
}
public static IASTName findMatchingASTName(IASTTranslationUnit tu, IName name, IIndex index) throws CoreException {
public static IASTName findMatchingASTName(IASTTranslationUnit tu, IName name, IIndex index)
throws CoreException {
if (name instanceof IASTName) {
return (IASTName) name;
} else if (!(name instanceof IIndexName)) {
@ -65,85 +66,86 @@ public class IndexToASTNameHelper {
private static boolean isQualifiedName(IASTName name) {
return name instanceof ICPPASTQualifiedName;
}
}
class IndexNameToAstNameMatcher extends ASTVisitor {
private IASTName result;
private IBinding bindingToFind;
private char[] charNameToFind;
private IIndex index;
private IASTFileLocation locationToFind;
private static class BindingToAstNameMatcher extends ASTVisitor {
private List<IASTName> results = new ArrayList<>();
private IBinding bindingToFind;
private char[] toFindName;
private IIndex index;
public IndexNameToAstNameMatcher(IASTTranslationUnit tu, IIndexName indexName, IIndex index) throws CoreException {
super(true);
locationToFind = indexName.getFileLocation();
bindingToFind = index.findBinding(indexName);
this.index = index;
charNameToFind = bindingToFind.getNameCharArray();
shouldVisitImplicitNames = true;
shouldVisitImplicitNameAlternates = true;
}
public BindingToAstNameMatcher(IBinding binding, IIndex index) {
super(true);
bindingToFind = index.adaptBinding(binding);
this.index = index;
toFindName = binding.getNameCharArray();
shouldVisitImplicitNames = true;
shouldVisitImplicitNameAlternates = true;
}
@Override
public int visit(IASTName candidate) {
if (!IndexToASTNameHelper.shouldConsiderName(candidate)) {
@Override
public int visit(IASTName candidate) {
if (!IndexToASTNameHelper.shouldConsiderName(candidate)) {
return PROCESS_CONTINUE;
}
if (isEquivalent(candidate)) {
results.add(candidate);
}
return PROCESS_CONTINUE;
}
if (isEquivalent(candidate)) {
result = candidate;
return PROCESS_ABORT;
private boolean isEquivalent(IASTName candidate) {
return CharArrayUtils.equals(candidate.getSimpleID(), toFindName) && bindingToFind.equals(index.adaptBinding(candidate.resolveBinding()));
}
public List<IASTName> getMatches() {
return results;
}
return PROCESS_CONTINUE;
}
private boolean isEquivalent(IASTName candidate) {
return matchesIndexName(candidate) && bindingToFind.equals(index.adaptBinding(candidate.resolveBinding()));
}
private static class IndexNameToAstNameMatcher extends ASTVisitor {
private IASTName result;
private IBinding bindingToFind;
private char[] charNameToFind;
private IIndex index;
private IASTFileLocation locationToFind;
private boolean matchesIndexName(IASTName candidate) {
IASTFileLocation candidateLocation = candidate.getFileLocation();
return locationToFind.getNodeOffset() == candidateLocation.getNodeOffset() &&
locationToFind.getNodeLength() == candidateLocation.getNodeLength() &&
locationToFind.getFileName().equals(candidateLocation.getFileName()) &&
CharArrayUtils.equals(candidate.getLookupKey(), charNameToFind);
}
public IndexNameToAstNameMatcher(IASTTranslationUnit tu, IIndexName indexName, IIndex index)
throws CoreException {
super(true);
locationToFind = indexName.getFileLocation();
bindingToFind = index.findBinding(indexName);
this.index = index;
charNameToFind = bindingToFind.getNameCharArray();
shouldVisitImplicitNames = true;
shouldVisitImplicitNameAlternates = true;
}
public IASTName getMatch() {
return result;
}
}
class BindingToAstNameMatcher extends ASTVisitor {
private List<IASTName> results = new ArrayList<>();
private IBinding bindingToFind;
private char[] toFindName;
private IIndex index;
public BindingToAstNameMatcher(IBinding binding, IIndex index) {
super(true);
bindingToFind = index.adaptBinding(binding);
this.index = index;
toFindName = binding.getNameCharArray();
shouldVisitImplicitNames = true;
shouldVisitImplicitNameAlternates = true;
}
@Override
public int visit(IASTName candidate) {
if (!IndexToASTNameHelper.shouldConsiderName(candidate)) {
@Override
public int visit(IASTName candidate) {
if (!IndexToASTNameHelper.shouldConsiderName(candidate)) {
return PROCESS_CONTINUE;
}
if (isEquivalent(candidate)) {
result = candidate;
return PROCESS_ABORT;
}
return PROCESS_CONTINUE;
}
if (isEquivalent(candidate)) {
results.add(candidate);
private boolean isEquivalent(IASTName candidate) {
return matchesIndexName(candidate) && bindingToFind.equals(index.adaptBinding(candidate.resolveBinding()));
}
return PROCESS_CONTINUE;
}
private boolean isEquivalent(IASTName candidate) {
return CharArrayUtils.equals(candidate.getSimpleID(), toFindName) && bindingToFind.equals(index.adaptBinding(candidate.resolveBinding()));
}
private boolean matchesIndexName(IASTName candidate) {
IASTFileLocation candidateLocation = candidate.getFileLocation();
return locationToFind.getNodeOffset() == candidateLocation.getNodeOffset() &&
locationToFind.getNodeLength() == candidateLocation.getNodeLength() &&
locationToFind.getFileName().equals(candidateLocation.getFileName()) &&
CharArrayUtils.equals(candidate.getSimpleID(), charNameToFind);
}
public List<IASTName> getMatches() {
return results;
public IASTName getMatch() {
return result;
}
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik
* Copyright (c) 2008, 2014 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@ -15,8 +15,6 @@ package org.eclipse.cdt.internal.ui.refactoring;
import org.eclipse.osgi.util.NLS;
final class Messages extends NLS {
public static String DeleteFileChange_0;
public static String DeleteFileChange_1;
public static String Refactoring_name;
public static String Refactoring_PM_LoadTU;
public static String Refactoring_PM_CheckTU;

View file

@ -1,5 +1,5 @@
###############################################################################
# Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik
# Copyright (c) 2008, 2014 Institute for Software, HSR Hochschule fuer Technik
# Rapperswil, University of applied sciences and others
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
@ -10,8 +10,6 @@
# Institute for Software - initial API and implementation
# Sergey Prigogin (Google)
###############################################################################
DeleteFileChange_0=Delete File
DeleteFileChange_1=File doesn't exist.
Refactoring_name=Refactoring
Refactoring_PM_LoadTU=Load Translation Unit
Refactoring_PM_CheckTU=Check Translation Unit
@ -21,9 +19,6 @@ Refactoring_PM_MergeComments=Merge Comments
Refactoring_CanceledByUser=Refactoring canceled by user.
Refactoring_CompileErrorInTU=The translation unit contains one or several problems. This can be caused by a syntax error in the code or a parser flaw. The refactoring will possibly fail.
AddDeclarationNodeToClassChange_AddDeclaration=Add Declaration to Class {0}.
CreateFileChange_CreateFile=Create file: {0}
CreateFileChange_UnknownLoc=Unknown location: {0}
CreateFileChange_FileExists=File already exists: {0}
CRefactoring_FileNotFound=The file {0} is not on the build path of a C/C++ project.
CRefactoring_checking_final_conditions=Checking preconditions...
CRefactoringDescriptor_unknown_project=Project ''{0}'' does not exist or is not a C/C++ project.

View file

@ -25,6 +25,9 @@ import org.eclipse.ltk.core.refactoring.CompositeChange;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.cdt.internal.ui.refactoring.changes.CCompositeChange;
import org.eclipse.cdt.internal.ui.refactoring.changes.CreateFileChange;
/**
* A ModificationCollector can be passed through a refactoring and manages the rewriters
* and additional changes a refactoring can create.

View file

@ -0,0 +1,94 @@
/*******************************************************************************
* Copyright (c) 2000, 2014 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
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.changes;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.resource.ResourceChange;
import org.eclipse.cdt.core.model.CoreModel;
public abstract class AbstractCElementRenameChange extends ResourceChange {
private final String fNewName;
private final String fOldName;
private final IPath fResourcePath;
private final long fStampToRestore;
protected AbstractCElementRenameChange(IPath resourcePath, String oldName, String newName) {
this(resourcePath, oldName, newName, IResource.NULL_STAMP);
}
protected AbstractCElementRenameChange(IPath resourcePath, String oldName, String newName, long stampToRestore) {
Assert.isNotNull(newName, "new name"); //$NON-NLS-1$
Assert.isNotNull(oldName, "old name"); //$NON-NLS-1$
fResourcePath= resourcePath;
fOldName= oldName;
fNewName= newName;
fStampToRestore= stampToRestore;
}
protected abstract IPath createNewPath();
protected abstract Change createUndoChange(long stampToRestore) throws CoreException;
protected abstract void doRename(IProgressMonitor pm) throws CoreException;
@Override
public Object getModifiedElement() {
return CoreModel.getDefault().create(getResource());
}
@Override
protected IResource getModifiedResource() {
return getResource();
}
public String getNewName() {
return fNewName;
}
public String getOldName() {
return fOldName;
}
protected final IResource getResource() {
return ResourcesPlugin.getWorkspace().getRoot().findMember(fResourcePath);
}
protected IPath getResourcePath() {
return fResourcePath;
}
@Override
public final Change perform(IProgressMonitor pm) throws CoreException {
try {
pm.beginTask(Messages.AbstractCElementRenameChange_renaming, 1);
IResource resource= getResource();
IPath newPath= createNewPath();
Change result= createUndoChange(resource.getModificationStamp());
doRename(new SubProgressMonitor(pm, 1));
if (fStampToRestore != IResource.NULL_STAMP) {
IResource newResource= ResourcesPlugin.getWorkspace().getRoot().findMember(newPath);
newResource.revertModificationStamp(fStampToRestore);
}
return result;
} finally {
pm.done();
}
}
}

View file

@ -9,7 +9,7 @@
* Contributors:
* Institute for Software (IFS)- initial API and implementation
******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring;
package org.eclipse.cdt.internal.ui.refactoring.changes;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.ChangeDescriptor;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik
* Copyright (c) 2008, 2014 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@ -10,7 +10,7 @@
* Institute for Software - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring;
package org.eclipse.cdt.internal.ui.refactoring.changes;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
@ -30,7 +30,8 @@ import org.eclipse.ltk.core.refactoring.resource.ResourceChange;
import org.eclipse.osgi.util.NLS;
/**
* A Change for creating a new file with the given name, content and encoding at the specified path.
* A {@link Change} for creating a new file with the given name, content and encoding at
* the specified path.
*
* @author Emanuel Graf
*/
@ -60,7 +61,7 @@ public class CreateFileChange extends ResourceChange {
@Override
public String getName() {
if (name == null) {
return NLS.bind(Messages.CreateFileChange_CreateFile, path.toOSString());
return NLS.bind(Messages.CreateFileChange_create_file, path.toOSString());
}
return name;
}
@ -70,19 +71,18 @@ public class CreateFileChange extends ResourceChange {
}
@Override
public RefactoringStatus isValid(IProgressMonitor pm)
throws CoreException, OperationCanceledException {
public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException, OperationCanceledException {
RefactoringStatus result= new RefactoringStatus();
IFile file= ResourcesPlugin.getWorkspace().getRoot().getFile(path);
URI location= file.getLocationURI();
if (location == null) {
result.addFatalError(NLS.bind(Messages.CreateFileChange_UnknownLoc, file.getFullPath().toString()));
result.addFatalError(NLS.bind(Messages.CreateFileChange_unknown_location, file.getFullPath().toString()));
return result;
}
if (file.exists()) {
result.addFatalError(NLS.bind(Messages.CreateFileChange_FileExists, file.getFullPath().toString()));
result.addFatalError(NLS.bind(Messages.CreateFileChange_file_exists, file.getFullPath().toString()));
return result;
}
return result;
@ -94,7 +94,7 @@ public class CreateFileChange extends ResourceChange {
InputStream is = new ByteArrayInputStream(source.getBytes());
file.create(is, false, new SubProgressMonitor(pm, 1));
if (encoding != null) {
file.setCharset(encoding, new SubProgressMonitor(pm,1));
file.setCharset(encoding, new SubProgressMonitor(pm, 1));
}
return new DeleteFileChange(file.getFullPath());
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik
* Copyright (c) 2008, 2014 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@ -7,9 +7,10 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Institute for Software - initial API and implementation
* Institute for Software - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring;
package org.eclipse.cdt.internal.ui.refactoring.changes;
import java.io.BufferedReader;
import java.io.IOException;
@ -24,15 +25,14 @@ import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.osgi.util.NLS;
/**
* The counterpart to the CreateFileChange, a change to delete a file.
* The counterpart to the {@link CreateFileChange}, a change to delete a file.
*
* @author Emanuel Graf
*
*/
public class DeleteFileChange extends Change {
private final IPath path;
private String source;
@ -45,25 +45,22 @@ public class DeleteFileChange extends Change {
return path;
}
@Override
public String getName() {
return Messages.DeleteFileChange_0 + path.toOSString();
return NLS.bind(Messages.DeleteFileChange_delete_file, path.toOSString());
}
@Override
public void initializeValidationData(IProgressMonitor pm) {
// Nothing to do
}
@Override
public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException,
OperationCanceledException {
public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException, OperationCanceledException {
RefactoringStatus status = new RefactoringStatus();
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
if(!file.exists()) {
status.addFatalError(Messages.DeleteFileChange_1 + path.toString());
if (!file.exists()) {
status.addFatalError(NLS.bind(Messages.DeleteFileChange_file_does_not_exist, path.toString()));
}
return status;
}
@ -72,7 +69,7 @@ public class DeleteFileChange extends Change {
String encoding= null;
try {
encoding= file.getCharset();
} catch (CoreException ex) {
} catch (CoreException e) {
// fall through. Take default encoding.
}
StringBuffer sb= new StringBuffer();
@ -80,10 +77,11 @@ public class DeleteFileChange extends Change {
InputStream in= null;
try {
in= file.getContents();
if (encoding != null)
if (encoding != null) {
br= new BufferedReader(new InputStreamReader(in, encoding));
else
br= new BufferedReader(new InputStreamReader(in));
} else {
br= new BufferedReader(new InputStreamReader(in));
}
int read= 0;
while ((read= br.read()) != -1) {
sb.append((char) read);
@ -100,8 +98,7 @@ public class DeleteFileChange extends Change {
IFile file= ResourcesPlugin.getWorkspace().getRoot().getFile(path);
source = getSource(file);
Change undo = new CreateFileChange(file.getFullPath(), source, file.getCharset());
file.delete(true,true, pm);
file.delete(true, true, pm);
return undo;
}
}

View file

@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright (c) 2014 Google, Inc 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:
* Sergey Prigogin (Google) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.changes;
import org.eclipse.osgi.util.NLS;
final class Messages extends NLS {
public static String AbstractCElementRenameChange_renaming;
public static String CreateFileChange_create_file;
public static String CreateFileChange_unknown_location;
public static String CreateFileChange_file_exists;
public static String DeleteFileChange_delete_file;
public static String DeleteFileChange_file_does_not_exist;
public static String RenameTranslationUnitChange_name;
static {
NLS.initializeMessages(Messages.class.getName(), Messages.class);
}
// Do not instantiate.
private Messages() {
}
}

View file

@ -0,0 +1,17 @@
###############################################################################
# Copyright (c) 2014 Google, Inc 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:
# Sergey Prigogin (Google) - initial API and implementation
###############################################################################
AbstractCElementRenameChange_renaming=Renaming...
CreateFileChange_create_file=Create file: {0}
CreateFileChange_unknown_location=Unknown location: {0}
CreateFileChange_file_exists=File already exists: {0}
DeleteFileChange_delete_file=Delete file: {0}
DeleteFileChange_file_does_not_exist=File {0} does not exist.
RenameTranslationUnitChange_name=Rename file ''{0}'' to ''{1}''

View file

@ -0,0 +1,64 @@
/*******************************************************************************
* Copyright (c) 2000, 2014 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
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.changes;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.osgi.util.NLS;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.ui.viewsupport.BasicElementLabels;
public final class RenameTranslationUnitChange extends AbstractCElementRenameChange {
public RenameTranslationUnitChange(ITranslationUnit tu, String newName) {
this(tu.getResource().getFullPath(), tu.getElementName(), newName, IResource.NULL_STAMP);
Assert.isTrue(!tu.isReadOnly(), "Translation unit must not be read-only"); //$NON-NLS-1$
}
private RenameTranslationUnitChange(IPath resourcePath, String oldName, String newName, long stampToRestore) {
super(resourcePath, oldName, newName, stampToRestore);
setValidationMethod(VALIDATE_NOT_READ_ONLY | SAVE_IF_DIRTY);
}
@Override
protected IPath createNewPath() {
IPath path= getResourcePath();
return path.removeLastSegments(1).append(getNewName());
}
@Override
protected Change createUndoChange(long stampToRestore) throws CModelException {
return new RenameTranslationUnitChange(createNewPath(), getNewName(), getOldName(), stampToRestore);
}
@Override
protected void doRename(IProgressMonitor pm) throws CoreException {
ITranslationUnit tu= (ITranslationUnit) getModifiedElement();
if (tu != null)
tu.rename(getNewName(), false, pm);
}
@Override
public String getName() {
return NLS.bind(Messages.RenameTranslationUnitChange_name,
BasicElementLabels.getCElementName(getOldName()),
BasicElementLabels.getCElementName(getNewName()));
}
}

View file

@ -1,15 +1,15 @@
/*******************************************************************************
* Copyright (c) 2006, 2009 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
* Copyright (c) 2006, 2014 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
* Markus Schorn (Wind River Systems)
* Contributors:
* IBM Corporation - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring;
package org.eclipse.cdt.internal.ui.refactoring.changes;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
@ -32,6 +32,8 @@ import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.core.model.TranslationUnit;
import org.eclipse.cdt.internal.ui.refactoring.DocumentAdapter;
/**
* UndoCTextFileChange that uses a working copy in order to generate CModel events.
* @author janees

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2009 Institute for Software, HSR Hochschule fuer Technik
* Copyright (c) 2008, 2014 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@ -7,7 +7,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Institute for Software - initial API and implementation
* Institute for Software - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.dialogs;
@ -27,26 +27,19 @@ import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.text.CSourceViewerConfiguration;
import org.eclipse.cdt.internal.ui.editor.CSourceViewer;
import org.eclipse.cdt.internal.ui.refactoring.CreateFileChange;
import org.eclipse.cdt.internal.ui.refactoring.changes.CreateFileChange;
import org.eclipse.cdt.internal.ui.text.CTextTools;
import org.eclipse.cdt.internal.ui.util.ViewerPane;
/**
* @author Emanuel Graf
*
*/
public class CreateFileChangePreview implements IChangePreviewViewer {
private static class CreateFileChangePane extends ViewerPane{
/**
* @param parent
* @param style
*/
private static class CreateFileChangePane extends ViewerPane {
public CreateFileChangePane(Composite parent, int style) {
super(parent, style);
}
}
private CreateFileChangePane control;
@ -57,11 +50,14 @@ public class CreateFileChangePreview implements IChangePreviewViewer {
public void createControl(Composite parent) {
control = new CreateFileChangePane(parent, SWT.BORDER | SWT.FLAT);
Dialog.applyDialogFont(control);
srcViewer= new CSourceViewer(control, null, null, false, SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.FULL_SELECTION, CUIPlugin.getDefault().getPreferenceStore());
srcViewer= new CSourceViewer(control, null, null, false,
SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.FULL_SELECTION,
CUIPlugin.getDefault().getPreferenceStore());
textTools = CUIPlugin.getDefault().getTextTools();
IPreferenceStore store= CUIPlugin.getDefault().getCombinedPreferenceStore();
CSourceViewerConfiguration sourceViewerConfiguration = new CSourceViewerConfiguration(textTools.getColorManager(), store, null, textTools.getDocumentPartitioning());
srcViewer.configure(sourceViewerConfiguration);
CSourceViewerConfiguration configuration =
new CSourceViewerConfiguration(textTools.getColorManager(), store, null, textTools.getDocumentPartitioning());
srcViewer.configure(configuration);
srcViewer.setEditable(false);
control.setContent(srcViewer.getControl());
}
@ -85,5 +81,4 @@ public class CreateFileChangePreview implements IChangePreviewViewer {
}
}
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik
* Copyright (c) 2008, 2014 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@ -28,6 +28,9 @@ import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.TextEdit;
@ -36,18 +39,16 @@ import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.refactoring.CTextFileChange;
import org.eclipse.cdt.internal.ui.preferences.formatter.TranslationUnitPreview;
import org.eclipse.cdt.internal.ui.refactoring.CCompositeChange;
import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector;
import org.eclipse.cdt.internal.ui.refactoring.changes.CCompositeChange;
import org.eclipse.cdt.internal.ui.refactoring.dialogs.ValidatingLabeledTextField;
/**
* InputPage used by the ImplementMethod refactoring if its necessary to enter additional parameter names.
*
* @author Mirko Stocker
*
*/
public class ParameterNamesInputPage extends UserInputWizardPage {
private static final int PREVIEW_UPDATE_DELAY = 500;
private MethodToImplementConfig config;
private TranslationUnitPreview translationUnitPreview;
@ -62,7 +63,6 @@ public class ParameterNamesInputPage extends UserInputWizardPage {
@Override
public void createControl(Composite parent) {
Composite superComposite = new Composite(parent, SWT.NONE);
superComposite.setLayout(new GridLayout());
@ -74,13 +74,11 @@ public class ParameterNamesInputPage extends UserInputWizardPage {
validatingLabeledTextField.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
for (final ParameterInfo actParameterInfo : config.getParaHandler().getParameterInfos()) {
String type = actParameterInfo.getTypeName();
String content = actParameterInfo.getParameterName();
boolean readOnly = !actParameterInfo.hasNewName();
validatingLabeledTextField.addElement(type, content, readOnly, new ValidatingLabeledTextField.Validator(){
@Override
public void hasErrors() {
setPageComplete(false);
@ -100,7 +98,6 @@ public class ParameterNamesInputPage extends UserInputWizardPage {
}
createPreview(superComposite);
setControl(superComposite);
}
@ -141,7 +138,6 @@ public class ParameterNamesInputPage extends UserInputWizardPage {
if (insertEdit == null) {
return Messages.ImplementMethodRefactoringPage_PreviewGenerationNotPossible;
}
return insertEdit.getText().trim();
} catch (OperationCanceledException e) {
return Messages.ImplementMethodRefactoringPage_PreviewCanceled;
@ -165,15 +161,22 @@ public class ParameterNamesInputPage extends UserInputWizardPage {
setPreviewText(functionDefinitionSignature);
return Status.OK_STATUS;
}
private void setPreviewText(final String text) {
if (getShell() != null && getShell().getDisplay() != null) {
getShell().getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
if (translationUnitPreview.getControl() != null && !translationUnitPreview.getControl().isDisposed()) {
translationUnitPreview.setPreviewText(text);
Shell shell = getShell();
if (shell != null) {
Display display = shell.getDisplay();
if (display != null) {
display.asyncExec(new Runnable() {
@Override
public void run() {
Control control = translationUnitPreview.getControl();
if (control != null && !control.isDisposed()) {
translationUnitPreview.setPreviewText(text);
}
}
}});
});
}
}
}
};
@ -214,21 +217,20 @@ public class ParameterNamesInputPage extends UserInputWizardPage {
}
protected void joinPreviewJob() {
if (delayedPreviewUpdater == null) {
if (delayedPreviewUpdater == null)
return;
}
try {
delayedPreviewUpdater.join();
} catch (InterruptedException e1) {
CUIPlugin.log(e1);
} catch (InterruptedException e) {
CUIPlugin.log(e);
}
}
private void updatePreview() {
if (translationUnitPreview == null) {
if (translationUnitPreview == null)
return;
}
delayedPreviewUpdater.schedule(PREVIEW_UPDATE_DELAY);
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2012 Wind River Systems, Inc. and others.
* Copyright (c) 2005, 2014 Wind River Systems, Inc. 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
@ -132,9 +132,10 @@ public class ASTManager implements IDisposable {
public final static int FALSE= 0;
public final static int UNKNOWN= -1;
// TODO(sprigogin): Replace fSharedAST and fTranslationUnits with CRefactoringContext.
private IASTTranslationUnit fSharedAST;
private Map<IFile, IASTTranslationUnit> fTranslationUnits= new HashMap<>();
private HashSet<String> fProblemUnits= new HashSet<>();
private Set<String> fProblemUnits= new HashSet<>();
private CRefactoringArgument fArgument;
private IBinding[] fValidBindings;
private String fRenameTo;
@ -836,7 +837,7 @@ public class ASTManager implements IDisposable {
return;
pm.beginTask(RenameMessages.ASTManager_task_analyze, 2);
IASTTranslationUnit tu= getTranslationUnit(index, fArgument.getSourceFile(), true, status);
IASTTranslationUnit tu= getAST(index, fArgument.getSourceFile(), true, status);
pm.worked(1);
if (tu != null) {
final IASTNodeSelector nodeSelector = tu.getNodeSelector(tu.getFilePath());
@ -912,8 +913,20 @@ public class ASTManager implements IDisposable {
return rawSignature.substring(offset, end);
}
private IASTTranslationUnit getTranslationUnit(IIndex index, IFile sourceFile, boolean cacheit,
RefactoringStatus status) {
/**
* Returns an AST for the given file.
*
* @param index the index to use for the AST
* @param sourceFile the source file to obtain an AST for
* @param astStyle the style to pass to {@link ITranslationUnit#getAST(IIndex, int)} method.
* If a previously cached AST is returned, the style is not guaranteed to match
* the requested one.
* @param cacheIt if {@code true}, the AST will be cached for later reuse
* @return the requested AST or {@code null}
* @throws CoreException
*/
public synchronized IASTTranslationUnit getAST(IIndex index, IFile sourceFile, int astStyle,
boolean cacheIt) throws CoreException {
IASTTranslationUnit ast= fTranslationUnits.get(sourceFile);
if (ast == null) {
ICElement celem= CoreModel.getDefault().create(sourceFile);
@ -925,20 +938,16 @@ public class ASTManager implements IDisposable {
// Try to get a shared AST before creating our own.
ast = ASTProvider.getASTProvider().acquireSharedAST(tu, index,
ASTProvider.WAIT_ACTIVE_ONLY, null);
if (ast == null) {
try {
ast= tu.getAST(index, PARSE_MODE);
} catch (CoreException e) {
status.addError(e.getMessage());
}
if (cacheit) {
fTranslationUnits.put(sourceFile, ast);
}
} else {
if (ast != null) {
if (fSharedAST != null) {
ASTProvider.getASTProvider().releaseSharedAST(fSharedAST);
}
fSharedAST = ast;
} else {
ast= tu.getAST(index, astStyle);
if (cacheIt) {
fTranslationUnits.put(sourceFile, ast);
}
}
}
}
@ -946,7 +955,17 @@ public class ASTManager implements IDisposable {
return ast;
}
public void analyzeTextMatches(IIndex index, Collection<CRefactoringMatch> matches,
private IASTTranslationUnit getAST(IIndex index, IFile sourceFile, boolean cacheIt,
RefactoringStatus status) {
try {
return getAST(index, sourceFile, PARSE_MODE, cacheIt);
} catch (CoreException e) {
status.addError(e.getMessage());
return null;
}
}
public void analyzeTextMatches(IIndex index, Collection<CRefactoringMatch> matches,
IProgressMonitor monitor, RefactoringStatus status) {
CRefactoringMatchStore store= new CRefactoringMatchStore();
for (CRefactoringMatch match : matches) {
@ -986,7 +1005,7 @@ public class ASTManager implements IDisposable {
}
if (doParse) {
IASTTranslationUnit tu= getTranslationUnit(index, file, false, status);
IASTTranslationUnit tu= getAST(index, file, false, status);
monitor.worked(1);
analyzeTextMatchesOfTranslationUnit(tu, store, status);
if (status.hasFatalError()) {

View file

@ -1,57 +1,206 @@
/*******************************************************************************
* Copyright (c) 2005, 2010 Wind River Systems, Inc. and others.
* Copyright (c) 2005, 2014 Wind River Systems, Inc. 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:
* Markus Schorn - initial API and implementation
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.rename;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CompositeChange;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.participants.RenameArguments;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.index.IIndexInclude;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.PreferenceConstants;
import org.eclipse.cdt.internal.ui.editor.SourceHeaderPartnerFinder;
import org.eclipse.cdt.internal.ui.refactoring.changes.CCompositeChange;
import org.eclipse.cdt.internal.ui.refactoring.changes.RenameTranslationUnitChange;
import org.eclipse.cdt.internal.ui.wizards.filewizard.NewSourceFileGenerator;
/**
* Processor adding constructor and destructor to the bindings to be renamed.
*/
public class CRenameClassProcessor extends CRenameTypeProcessor {
private final List<Change> tuRenames = new ArrayList<>();
public CRenameClassProcessor(CRenameProcessor processor, String kind) {
super(processor, kind);
}
@Override
public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
Change change = super.createChange(pm);
if (tuRenames.isEmpty())
return change;
CompositeChange compositeChange;
if (change instanceof CompositeChange) {
compositeChange = (CompositeChange) change;
} else {
compositeChange = new CCompositeChange(""); //$NON-NLS-1$
compositeChange.markAsSynthetic();
compositeChange.add(change);
}
for (Change tuRename : tuRenames) {
compositeChange.add(tuRename);
}
return compositeChange;
}
@Override
protected IBinding[] getBindingsToBeRenamed(RefactoringStatus status) {
tuRenames.clear();
CRefactoringArgument argument= getArgument();
IBinding binding= argument.getBinding();
ArrayList<IBinding> bindings= new ArrayList<>();
if (binding != null) {
recordRename(binding);
bindings.add(binding);
}
if (binding instanceof ICPPClassType) {
ICPPClassType ctype= (ICPPClassType) binding;
ICPPConstructor[] ctors= ctype.getConstructors();
if (ctors != null) {
bindings.addAll(Arrays.asList(ctors));
ArrayUtil.addAll(bindings, ctors);
}
IScope scope= ctype.getCompositeScope();
if (scope != null) {
IBinding[] dtors= scope.find("~" + argument.getName()); //$NON-NLS-1$
if (dtors != null) {
bindings.addAll(Arrays.asList(dtors));
ArrayUtil.addAll(bindings, dtors);
}
}
renameCompilationUnits(ctype);
}
return bindings.toArray(new IBinding[bindings.size()]);
}
private void renameCompilationUnits(ICPPBinding binding) {
IIndex index = getIndex();
if (index == null) {
return;
}
try {
index.acquireReadLock();
Set<IIndexFileLocation> locations = new HashSet<>();
IIndexName[] names = index.findNames(binding, IIndex.FIND_DEFINITIONS);
for (IIndexName name : names) {
locations.add(name.getFile().getLocation());
}
if (locations.size() != 1)
return;
IIndexFileLocation location = locations.iterator().next();
String fullPath = location.getFullPath();
if (fullPath == null)
return;
IPath headerPath = new Path(fullPath);
String className = binding.getName();
String headerName = NewSourceFileGenerator.generateHeaderFileNameFromClass(className);
if (!headerPath.lastSegment().equals(headerName))
return;
IResource file = ResourcesPlugin.getWorkspace().getRoot().findMember(headerPath);
if (file == null || file.getType() != IResource.FILE)
return;
String newClassName = getReplacementText();
String newHeaderName = NewSourceFileGenerator.generateHeaderFileNameFromClass(newClassName);
if (!newHeaderName.equals(headerName)) {
renameTranslationUnit((IFile) file, newHeaderName);
}
String sourceName = NewSourceFileGenerator.generateSourceFileNameFromClass(className);
String testName = NewSourceFileGenerator.generateTestFileNameFromClass(className);
String[] partnerFileSuffixes = getPartnerFileSuffixes();
IIndexInclude[] includedBy = index.findIncludedBy(names[0].getFile());
for (IIndexInclude include : includedBy) {
location = include.getIncludedByLocation();
fullPath = location.getFullPath();
if (fullPath == null)
continue;
IPath sourcePath = new Path(fullPath);
file = ResourcesPlugin.getWorkspace().getRoot().findMember(sourcePath);
if (file != null && file.getType() == IResource.FILE) {
if (sourcePath.lastSegment().equals(sourceName)) {
String newName = NewSourceFileGenerator.generateSourceFileNameFromClass(newClassName);
if (!newName.equals(sourceName)) {
renameTranslationUnit((IFile) file, newName);
}
} else if (sourcePath.lastSegment().equals(testName)) {
String newName = NewSourceFileGenerator.generateTestFileNameFromClass(newClassName);
file = ResourcesPlugin.getWorkspace().getRoot().findMember(sourcePath);
if (!newName.equals(testName)) {
renameTranslationUnit((IFile) file, newName);
}
} else if (SourceHeaderPartnerFinder.isPartnerFile(sourcePath, headerPath, partnerFileSuffixes)) {
String name = sourcePath.lastSegment();
String baseName = headerPath.removeFileExtension().lastSegment();
if (name.startsWith(baseName)) {
String newBaseName = new Path(headerName).removeFileExtension().lastSegment();
String newName = newBaseName + name.substring(baseName.length());
if (!newName.equals(name)) {
renameTranslationUnit((IFile) file, newName);
}
}
}
}
}
} catch (CoreException e) {
CUIPlugin.log(e);
return;
} catch (InterruptedException e) {
return; // Ignore.
} finally {
index.releaseReadLock();
}
}
protected void renameTranslationUnit(IFile file, String newName) {
ICElement elem = CoreModel.getDefault().create(file);
if (elem instanceof ITranslationUnit) {
tuRenames.add(new RenameTranslationUnitChange((ITranslationUnit) elem, newName));
getRenameModifications().rename(file, new RenameArguments(newName, true));
}
}
private String[] getPartnerFileSuffixes() {
IFile file= getArgument().getSourceFile();
IProject project = file == null ? null : file.getProject();
String value = PreferenceConstants.getPreference(
PreferenceConstants.INCLUDES_PARTNER_FILE_SUFFIXES, project, ""); //$NON-NLS-1$
return value.split(","); //$NON-NLS-1$
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2010 Wind River Systems, Inc. and others.
* Copyright (c) 2005, 2014 Wind River Systems, Inc. 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
@ -102,6 +102,7 @@ public class CRenameMethodProcessor extends CRenameGlobalProcessor {
IBinding binding= argument.getBinding();
ArrayList<IBinding> bindings= new ArrayList<>();
if (binding != null) {
recordRename(binding);
bindings.add(binding);
}
if (binding instanceof ICPPMethod) {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2011 Wind River Systems, Inc. and others.
* Copyright (c) 2004, 2014 Wind River Systems, Inc. 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
@ -11,10 +11,6 @@
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.rename;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
@ -24,10 +20,7 @@ import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
import org.eclipse.ltk.core.refactoring.participants.ParticipantManager;
import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant;
import org.eclipse.ltk.core.refactoring.participants.RenameArguments;
import org.eclipse.ltk.core.refactoring.participants.RenameParticipant;
import org.eclipse.ltk.core.refactoring.participants.RenameProcessor;
import org.eclipse.ltk.core.refactoring.participants.SharableParticipants;
import org.eclipse.osgi.util.NLS;
@ -37,7 +30,6 @@ import org.eclipse.ui.PlatformUI;
import org.eclipse.cdt.core.CCProjectNature;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CProjectNature;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexManager;
import org.eclipse.cdt.core.model.CoreModel;
@ -48,7 +40,10 @@ import org.eclipse.cdt.core.model.ICProject;
* use and forwards further calls to the delegate.
*/
public class CRenameProcessor extends RenameProcessor {
public static final String IDENTIFIER= "org.eclips.cdt.refactoring.RenameProcessor"; //$NON-NLS-1$
public static final String IDENTIFIER= "org.eclips.cdt.refactoring.RenameProcessor"; //$NON-NLS-1$
private static final String[] AFFECTED_PROJECT_NATURES =
{ CCProjectNature.CC_NATURE_ID, CProjectNature.C_NATURE_ID };
private final CRefactoringArgument fArgument;
private CRenameProcessorDelegate fDelegate;
@ -61,8 +56,6 @@ public class CRenameProcessor extends RenameProcessor {
private IIndex fIndex;
private int fIndexLockCount;
private RefactoringStatus fInitialConditionsStatus;
private Change fChange;
public CRenameProcessor(CRefactory refactoringManager, CRefactoringArgument arg) {
fManager= refactoringManager;
@ -186,38 +179,22 @@ public class CRenameProcessor extends RenameProcessor {
@Override
public RefactoringStatus checkFinalConditions(IProgressMonitor pm, CheckConditionsContext context)
throws CoreException, OperationCanceledException {
return fDelegate.checkFinalConditions(pm, context);
return fDelegate.checkFinalConditions(pm, context);
}
@Override
public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
fChange = fDelegate.createChange(pm);
return fChange;
}
/**
* @return the change if it has been created, or <code>null</code> otherwise.
*/
Change getChange() {
return fChange;
return fDelegate.createChange(pm);
}
@Override
public RefactoringParticipant[] loadParticipants(RefactoringStatus status,
SharableParticipants sharedParticipants) throws CoreException {
RenameArguments arguments= new RenameArguments(getReplacementText(), true);
final String[] natures= {CCProjectNature.CC_NATURE_ID, CProjectNature.C_NATURE_ID};
List<RenameParticipant> result= new ArrayList<RenameParticipant>();
IBinding binding= getArgument().getBinding();
if (binding != null) {
result.addAll(Arrays.asList(ParticipantManager.loadRenameParticipants(status,
this, binding, arguments, natures, sharedParticipants)));
}
return result.toArray(new RefactoringParticipant[result.size()]);
}
public final RefactoringParticipant[] loadParticipants(RefactoringStatus status,
SharableParticipants shared) throws CoreException {
return fDelegate.getRenameModifications().loadParticipants(status, this, AFFECTED_PROJECT_NATURES, shared);
}
/**
* Options for the input page in the refactoring wizard
* Options for the input page in the refactoring wizard.
*/
public int getAvailableOptions() {
if (fDelegate == null) {
@ -227,7 +204,7 @@ public class CRenameProcessor extends RenameProcessor {
}
/**
* Options for the input page that trigger the preview
* Options for the input page that trigger the preview.
*/
public int getOptionsForcingPreview() {
if (fDelegate == null) {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2010 Wind River Systems, Inc. and others.
* Copyright (c) 2004, 2014 Wind River Systems, Inc. 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
@ -24,6 +24,7 @@ import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
@ -35,6 +36,8 @@ import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.TextEditChangeGroup;
import org.eclipse.ltk.core.refactoring.TextFileChange;
import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
import org.eclipse.ltk.core.refactoring.participants.RenameArguments;
import org.eclipse.ltk.core.refactoring.participants.ResourceChangeChecker;
import org.eclipse.ltk.core.refactoring.participants.ValidateEditChecker;
import org.eclipse.osgi.util.NLS;
import org.eclipse.text.edits.MultiTextEdit;
@ -53,6 +56,7 @@ import org.eclipse.cdt.ui.refactoring.CTextFileChange;
public abstract class CRenameProcessorDelegate {
private CRenameProcessor fTopProcessor;
private ArrayList<CRefactoringMatch> fMatches;
private final RenameModifications fRenameModifications = new RenameModifications();
protected String fProcessorBaseName;
private int fAvailableOptions=
CRefactory.OPTION_IN_CODE_REFERENCES |
@ -88,7 +92,7 @@ public abstract class CRenameProcessorDelegate {
}
final public int getSelectedOptions() {
return fTopProcessor.getSelectedOptions();
return fTopProcessor.getSelectedOptions() & fAvailableOptions;
}
final public String getSelectedWorkingSet() {
@ -181,9 +185,7 @@ public abstract class CRenameProcessorDelegate {
locations.add(name.getFile().getLocation());
}
}
} catch (InterruptedException e) {
return files;
} catch (CoreException e) {
} catch (CoreException | InterruptedException e) {
return files;
} finally {
index.releaseReadLock();
@ -283,11 +285,17 @@ public abstract class CRenameProcessorDelegate {
}
result.addWarning(msg);
}
IFile[] files= fileset.toArray(new IFile[fileset.size()]);
if (context != null) {
ResourceChangeChecker checker = (ResourceChangeChecker) context.getChecker(ResourceChangeChecker.class);
IResourceChangeDescriptionFactory deltaFactory = checker.getDeltaFactory();
ValidateEditChecker editChecker=
(ValidateEditChecker) context.getChecker(ValidateEditChecker.class);
editChecker.addFiles(files);
for (IFile changedFile : fileset) {
deltaFactory.change(changedFile);
editChecker.addFile(changedFile);
}
fRenameModifications.buildDelta(deltaFactory);
fRenameModifications.buildValidateEdits(editChecker);
}
monitor.done();
return result;
@ -373,15 +381,38 @@ public abstract class CRenameProcessorDelegate {
return overallChange;
}
/**
/**
* Returns the array of bindings that must be renamed.
*/
protected IBinding[] getBindingsToBeRenamed(RefactoringStatus status) {
return new IBinding[] { getArgument().getBinding() };
IBinding binding = getArgument().getBinding();
recordRename(binding);
return new IBinding[] { binding };
}
/**
* Returns the modifications associated with the refactoring.
*/
public RenameModifications getRenameModifications() {
return fRenameModifications;
}
protected void recordRename(IBinding binding) {
RenameArguments args = new RenameArguments(getReplacementText(), true);
RenameModifications renameModifications = getRenameModifications();
renameModifications.rename(binding, args);
}
protected void recordRename(IBinding[] bindings) {
RenameArguments args = new RenameArguments(getReplacementText(), true);
RenameModifications renameModifications = getRenameModifications();
for (IBinding binding : bindings) {
renameModifications.rename(binding, args);
}
}
/**
* @return a save mode from {@link org.eclipse.cdt.internal.ui.refactoring.RefactoringSaveHelper}
* Returns a save mode from {@link org.eclipse.cdt.internal.ui.refactoring.RefactoringSaveHelper}
*/
public abstract int getSaveMode();
}

View file

@ -1,16 +1,20 @@
/*******************************************************************************
* Copyright (c) 2004, 2010 Wind River Systems, Inc. and others.
* Copyright (c) 2004, 2014 Wind River Systems, Inc. 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:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.rename;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.participants.ProcessorBasedRefactoring;
/**
@ -18,8 +22,27 @@ import org.eclipse.ltk.core.refactoring.participants.ProcessorBasedRefactoring;
*/
public class CRenameRefactoring extends ProcessorBasedRefactoring {
public static final String ID = "org.eclipse.cdt.internal.ui.refactoring.rename.CRenameRefactoring"; //$NON-NLS-1$
private Change fChange;
public CRenameRefactoring(CRenameProcessor processor) {
super(processor);
}
@Override
public CRenameProcessor getProcessor() {
return (CRenameProcessor) super.getProcessor();
}
@Override
public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
fChange = super.createChange(pm);
return fChange;
}
/**
* Returns the change if it has been created, or {@code null} otherwise.
*/
Change getChange() {
return fChange;
}
}

View file

@ -493,8 +493,8 @@ public class CRenameRefactoringInputPage extends UserInputWizardPage {
}
}
}
private CRenameProcessor getRenameProcessor() {
return (CRenameProcessor) ((CRenameRefactoring) getRefactoring()).getProcessor();
return ((CRenameRefactoring) getRefactoring()).getProcessor();
}
}

View file

@ -27,14 +27,16 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
import org.eclipse.ltk.core.refactoring.participants.ISharableParticipant;
import org.eclipse.ltk.core.refactoring.participants.MoveArguments;
import org.eclipse.ltk.core.refactoring.participants.MoveParticipant;
import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments;
/**
* Updates include statements and include guards in response to a file or a folder move.
*/
public class HeaderFileMoveParticipant extends MoveParticipant {
private IResource movedResource;
public class HeaderFileMoveParticipant extends MoveParticipant implements ISharableParticipant {
private Map<IResource, MoveArguments> movedResources;
private Change change;
public HeaderFileMoveParticipant() {
@ -42,63 +44,80 @@ public class HeaderFileMoveParticipant extends MoveParticipant {
@Override
protected boolean initialize(Object element) {
if (element instanceof IResource) {
this.movedResource = (IResource) element;
return true;
addElement(element, getArguments());
return movedResources != null;
}
@Override
public void addElement(Object element, RefactoringArguments arguments) {
if (element instanceof IResource && arguments instanceof MoveArguments) {
if (movedResources == null)
movedResources = new HashMap<>();
movedResources.put((IResource) element, (MoveArguments) arguments);
}
return false;
}
@Override
public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context)
throws OperationCanceledException {
MoveArguments args = getArguments();
if (!args.getUpdateReferences())
return null;
if (movedResource.isLinked())
return null;
Object destinationResource = args.getDestination();
if (!(destinationResource instanceof IContainer))
return null;
final IContainer destination = (IContainer) destinationResource;
final IPath destinationLocation = destination.getLocation();
if (destinationLocation.equals(movedResource.getLocation().removeLastSegments(1)))
return null;
try {
if (movedResources == null)
return RefactoringStatus.create(Status.OK_STATUS);
// Maps the affected files to new, not yet existing, files.
final Map<IFile, IFile> movedFiles = new HashMap<>();
if (movedResource instanceof IContainer) {
final int prefixLength = movedResource.getFullPath().segmentCount() - 1;
((IContainer) movedResource).accept(new IResourceProxyVisitor() {
@Override
public boolean visit(IResourceProxy proxy) throws CoreException {
if (proxy.isLinked())
return false;
if (proxy.getType() == IResource.FILE) {
IFile file = (IFile) proxy.requestResource();
movedFiles.put(file, destination.getFile(file.getFullPath().removeFirstSegments(prefixLength)));
return false;
for (Map.Entry<IResource, MoveArguments> entry : movedResources.entrySet()) {
IResource movedResource = entry.getKey();
MoveArguments args = entry.getValue();
if (!args.getUpdateReferences())
continue;
if (movedResource.isLinked())
continue;
Object destinationResource = args.getDestination();
if (!(destinationResource instanceof IContainer))
continue;
final IContainer destination = (IContainer) destinationResource;
final IPath destinationLocation = destination.getLocation();
if (destinationLocation.equals(movedResource.getLocation().removeLastSegments(1)))
continue;
if (movedResource instanceof IContainer) {
final int prefixLength = movedResource.getFullPath().segmentCount() - 1;
((IContainer) movedResource).accept(new IResourceProxyVisitor() {
@Override
public boolean visit(IResourceProxy proxy) throws CoreException {
if (proxy.isLinked())
return false;
if (proxy.getType() == IResource.FILE) {
IFile file = (IFile) proxy.requestResource();
movedFiles.put(file, destination.getFile(file.getFullPath().removeFirstSegments(prefixLength)));
return false;
}
return true;
}
return true;
}
}, IResource.NONE);
} else if (movedResource instanceof IFile) {
IFile file = (IFile) movedResource;
movedFiles.put(file, destination.getFile(new Path(movedResource.getName())));
}, IResource.NONE);
} else if (movedResource instanceof IFile) {
IFile file = (IFile) movedResource;
movedFiles.put(file, destination.getFile(new Path(movedResource.getName())));
}
}
HeaderFileReferenceAdjuster includeAdjuster = new HeaderFileReferenceAdjuster(movedFiles);
HeaderFileReferenceAdjuster includeAdjuster =
new HeaderFileReferenceAdjuster(movedFiles, getProcessor());
change = includeAdjuster.createChange(context, pm);
} catch (CoreException e) {
return RefactoringStatus.create(e.getStatus());
} finally {
pm.done();
}
return RefactoringStatus.create(Status.OK_STATUS);
}
@Override
public Change createPreChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
change = RenameParticipantHelper.postprocessParticipantChange(change, this);
pm.done();
return change;
}

View file

@ -10,9 +10,6 @@
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.rename;
import static org.eclipse.cdt.internal.ui.editor.ASTProvider.WAIT_ACTIVE_ONLY;
import static org.eclipse.cdt.internal.ui.editor.ASTProvider.getASTProvider;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
@ -42,6 +39,7 @@ import org.eclipse.jface.text.IRegion;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CompositeChange;
import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor;
import org.eclipse.ltk.core.refactoring.participants.ValidateEditChecker;
import org.eclipse.text.edits.DeleteEdit;
import org.eclipse.text.edits.InsertEdit;
@ -94,18 +92,21 @@ public class HeaderFileReferenceAdjuster {
private final Map<IFile, IFile> movedFiles;
private final Map<String, IPath> movedFilesByLocation;
private ASTManager astManager;
private IIndex index;
private int indexLockCount;
/**
* @param movedFiles keys are moved files, values are new, not yet existing, files
* @param processor the refactoring processor
*/
public HeaderFileReferenceAdjuster(Map<IFile, IFile> movedFiles) {
public HeaderFileReferenceAdjuster(Map<IFile, IFile> movedFiles, RefactoringProcessor processor) {
this.movedFiles = movedFiles;
this.movedFilesByLocation = new HashMap<>();
for (Entry<IFile, IFile> entry : movedFiles.entrySet()) {
this.movedFilesByLocation.put(entry.getKey().getLocation().toOSString(), entry.getValue().getLocation());
}
this.astManager = getASTManager(processor);
}
public Change createChange(CheckConditionsContext context, IProgressMonitor pm)
@ -116,6 +117,11 @@ public class HeaderFileReferenceAdjuster {
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
lockIndex();
ASTManager sharedASTManager = astManager;
if (astManager == null)
astManager = new ASTManager(null);
try {
for (Entry<IFile, IFile> entry : movedFiles.entrySet()) {
IFile oldFile = entry.getKey();
@ -156,7 +162,7 @@ public class HeaderFileReferenceAdjuster {
for (IFile file : affectedFiles) {
ITranslationUnit tu = (ITranslationUnit) coreModel.create(file);
if (workingCopyManager.findSharedWorkingCopy(tu) != null)
continue;
continue; // Shared working copies have already been processed.
addFileChange(tu, changes, checker, progress.newChild(1));
}
@ -165,6 +171,10 @@ public class HeaderFileReferenceAdjuster {
change.markAsSynthetic();
}
} finally {
if (astManager != sharedASTManager) {
astManager.dispose();
astManager = null;
}
unlockIndex();
pm.done();
}
@ -186,25 +196,11 @@ public class HeaderFileReferenceAdjuster {
throws CoreException, OperationCanceledException {
checkCanceled(pm);
IASTTranslationUnit sharedAst = null;
SubMonitor progress = SubMonitor.convert(pm, 2);
try {
IASTTranslationUnit ast =
getASTProvider().acquireSharedAST(tu, index, WAIT_ACTIVE_ONLY, progress.newChild(1));
if (ast == null) {
checkCanceled(pm);
ast= tu.getAST(index, PARSE_MODE);
if (ast == null)
return null;
} else {
sharedAst = ast;
}
IASTTranslationUnit ast = astManager.getAST(index, tu.getFile(), PARSE_MODE, false);
return createEdit(ast, tu, progress.newChild(1));
} finally {
if (sharedAst != null) {
getASTProvider().releaseSharedAST(sharedAst);
}
pm.done();
}
}
@ -463,6 +459,13 @@ public class HeaderFileReferenceAdjuster {
}
}
private static ASTManager getASTManager(RefactoringProcessor processor) {
if (processor instanceof CRenameProcessor) {
return ((CRenameProcessor) processor).getAstManager();
}
return null;
}
private static void checkCanceled(IProgressMonitor pm) throws OperationCanceledException {
if (pm != null && pm.isCanceled())
throw new OperationCanceledException();
@ -474,10 +477,10 @@ public class HeaderFileReferenceAdjuster {
return false;
IPreferencesService preferences = Platform.getPreferencesService();
IScopeContext[] scopes = PreferenceConstants.getPreferenceScopes(oldfile.getProject());
int schema = preferences.getInt(CUIPlugin.PLUGIN_ID,
int scheme = preferences.getInt(CUIPlugin.PLUGIN_ID,
PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME,
PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME_FILE_NAME, scopes);
switch (schema) {
switch (scheme) {
case PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME_FILE_PATH:
return true;

View file

@ -28,14 +28,16 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
import org.eclipse.ltk.core.refactoring.participants.ISharableParticipant;
import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments;
import org.eclipse.ltk.core.refactoring.participants.RenameArguments;
import org.eclipse.ltk.core.refactoring.participants.RenameParticipant;
/**
* Updates include statements and include guards in response to a file or a folder rename.
*/
public class HeaderFileRenameParticipant extends RenameParticipant {
private IResource renamedResource;
public class HeaderFileRenameParticipant extends RenameParticipant implements ISharableParticipant {
private Map<IResource, RenameArguments> renamedResources;
private Change change;
public HeaderFileRenameParticipant() {
@ -43,60 +45,75 @@ public class HeaderFileRenameParticipant extends RenameParticipant {
@Override
protected boolean initialize(Object element) {
if (element instanceof IResource) {
this.renamedResource = (IResource) element;
return true;
addElement(element, getArguments());
return renamedResources != null;
}
@Override
public void addElement(Object element, RefactoringArguments arguments) {
if (element instanceof IResource && arguments instanceof RenameArguments) {
if (renamedResources == null)
renamedResources = new HashMap<>();
renamedResources.put((IResource) element, (RenameArguments) arguments);
}
return false;
}
@Override
public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context)
throws OperationCanceledException {
RenameArguments args = getArguments();
if (!args.getUpdateReferences())
return null;
if (renamedResource.isLinked())
return null;
String newName = args.getNewName();
try {
if (renamedResources == null)
return RefactoringStatus.create(Status.OK_STATUS);
// Maps the affected files to new, not yet existing, files.
final Map<IFile, IFile> movedFiles = new HashMap<>();
if (renamedResource instanceof IContainer) {
final IPath oldPath = renamedResource.getFullPath();
final IPath newPath = oldPath.removeLastSegments(1).append(newName);
final IWorkspaceRoot workspaceRoot = renamedResource.getWorkspace().getRoot();
((IContainer) renamedResource).accept(new IResourceProxyVisitor() {
@Override
public boolean visit(IResourceProxy proxy) throws CoreException {
if (proxy.isLinked())
return false;
if (proxy.getType() == IResource.FILE) {
IFile file = (IFile) proxy.requestResource();
IPath path = replacePrefix(file.getFullPath(), oldPath.segmentCount(), newPath);
movedFiles.put(file, workspaceRoot.getFile(path));
return false;
for (Map.Entry<IResource, RenameArguments> entry : renamedResources.entrySet()) {
IResource renamedResource = entry.getKey();
RenameArguments args = entry.getValue();
if (!args.getUpdateReferences())
continue;
if (renamedResource.isLinked())
continue;
String newName = args.getNewName();
if (renamedResource instanceof IContainer) {
final IPath oldPath = renamedResource.getFullPath();
final IPath newPath = oldPath.removeLastSegments(1).append(newName);
final IWorkspaceRoot workspaceRoot = renamedResource.getWorkspace().getRoot();
((IContainer) renamedResource).accept(new IResourceProxyVisitor() {
@Override
public boolean visit(IResourceProxy proxy) throws CoreException {
if (proxy.isLinked())
return false;
if (proxy.getType() == IResource.FILE) {
IFile file = (IFile) proxy.requestResource();
IPath path = replacePrefix(file.getFullPath(), oldPath.segmentCount(), newPath);
movedFiles.put(file, workspaceRoot.getFile(path));
return false;
}
return true;
}
return true;
}
}, IResource.NONE);
} else if (renamedResource instanceof IFile) {
IFile file = (IFile) renamedResource;
movedFiles.put(file, file.getParent().getFile(new Path(newName)));
}, IResource.NONE);
} else if (renamedResource instanceof IFile) {
IFile file = (IFile) renamedResource;
movedFiles.put(file, file.getParent().getFile(new Path(newName)));
}
}
HeaderFileReferenceAdjuster includeAdjuster = new HeaderFileReferenceAdjuster(movedFiles);
HeaderFileReferenceAdjuster includeAdjuster =
new HeaderFileReferenceAdjuster(movedFiles, getProcessor());
change = includeAdjuster.createChange(context, pm);
} catch (CoreException e) {
return RefactoringStatus.create(e.getStatus());
} finally {
pm.done();
}
return RefactoringStatus.create(Status.OK_STATUS);
}
@Override
public Change createPreChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
change = RenameParticipantHelper.postprocessParticipantChange(change, this);
pm.done();
return change;
}
@ -113,13 +130,12 @@ public class HeaderFileRenameParticipant extends RenameParticipant {
}
/**
* Replaces first few segments of the given path by the contents of another path.
* Replaces first few segments of the given path with the contents of another path.
*
* @param path the original path
* @param prefixLength the number of segments of {@code path} to replace
* @param newPrefix the replacement path
* @return the modified path
* @since 5.8
*/
private static IPath replacePrefix(IPath path, int prefixLength, IPath newPrefix) {
return newPrefix.append(path.removeFirstSegments(prefixLength));

View file

@ -0,0 +1,126 @@
/*******************************************************************************
* Copyright (c) 2000, 2014 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
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.rename;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory;
import org.eclipse.core.runtime.Assert;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.participants.IParticipantDescriptorFilter;
import org.eclipse.ltk.core.refactoring.participants.ParticipantManager;
import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments;
import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant;
import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor;
import org.eclipse.ltk.core.refactoring.participants.RenameArguments;
import org.eclipse.ltk.core.refactoring.participants.SharableParticipants;
import org.eclipse.ltk.core.refactoring.participants.ValidateEditChecker;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.model.ISourceRoot;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.corext.refactoring.participants.ResourceModifications;
import org.eclipse.cdt.internal.ui.refactoring.reorg.RefactoringModifications;
/**
* Stores objects renamed by the rename refactoring.
*/
public class RenameModifications extends RefactoringModifications {
private List<Object> fRename;
private List<RefactoringArguments> fRenameArguments;
private List<IParticipantDescriptorFilter> fParticipantDescriptorFilter;
public RenameModifications() {
fRename = new ArrayList<>();
fRenameArguments = new ArrayList<>();
fParticipantDescriptorFilter = new ArrayList<>();
}
public void rename(IBinding binding, RenameArguments args) {
add(binding, args, null);
}
public void rename(IResource resource, RenameArguments args) {
add(resource, args, null);
}
public void rename(ISourceRoot sourceFolder, RenameArguments arguments) {
add(sourceFolder, arguments, null);
if (sourceFolder.getResource() != null) {
getResourceModifications().addRename(sourceFolder.getResource(), arguments);
}
}
public void rename(ITranslationUnit unit, RenameArguments args) {
add(unit, args, null);
if (unit.getResource() != null) {
getResourceModifications().addRename(unit.getResource(), new RenameArguments(args.getNewName(), args.getUpdateReferences()));
}
}
@Override
public void buildDelta(IResourceChangeDescriptionFactory builder) {
for (int i = 0; i < fRename.size(); i++) {
Object element= fRename.get(i);
if (element instanceof IResource) {
ResourceModifications.buildMoveDelta(builder, (IResource) element,
(RenameArguments) fRenameArguments.get(i));
}
}
getResourceModifications().buildDelta(builder);
}
@Override
public void buildValidateEdits(ValidateEditChecker checker) {
for (Iterator<Object> iter = fRename.iterator(); iter.hasNext();) {
Object element = iter.next();
if (element instanceof ITranslationUnit) {
ITranslationUnit unit = (ITranslationUnit) element;
IResource resource = unit.getResource();
if (resource != null && resource.getType() == IResource.FILE) {
checker.addFile((IFile) resource);
}
}
}
}
@Override
public RefactoringParticipant[] loadParticipants(RefactoringStatus status, RefactoringProcessor owner,
String[] natures, SharableParticipants shared) {
List<RefactoringParticipant> result = new ArrayList<>();
for (int i = 0; i < fRename.size(); i++) {
ArrayUtil.addAll(result,
ParticipantManager.loadRenameParticipants(status,
owner, fRename.get(i),
(RenameArguments) fRenameArguments.get(i),
fParticipantDescriptorFilter.get(i),
natures, shared));
}
ArrayUtil.addAll(result, getResourceModifications().getParticipants(status, owner, natures, shared));
return result.toArray(new RefactoringParticipant[result.size()]);
}
private void add(Object element, RefactoringArguments args, IParticipantDescriptorFilter filter) {
Assert.isNotNull(element);
Assert.isNotNull(args);
fRename.add(element);
fRenameArguments.add(args);
fParticipantDescriptorFilter.add(filter);
}
}

View file

@ -0,0 +1,75 @@
/*******************************************************************************
* Copyright (c) 2014 Google, Inc 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:
* Sergey Prigogin (Google) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.rename;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CompositeChange;
import org.eclipse.ltk.core.refactoring.TextChange;
import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.TextEdit;
/**
* Static methods used by rename and move participants.
*/
public class RenameParticipantHelper {
/**
* Consolidates the change produced by a refactoring participant with the one produced by
* the refactoring processor. If the two changes are be affecting the same files, the part of
* the refactoring participant's change that affects the files also modified by the refactoring
* processor is merged into the processor's change. The remaining part, if any, is returned from
* the method.
*
* @param change the change produced by a refactoring participant
* @param participant the refactoring participant
* @return the resulting change, or {@code null}
*/
public static Change postprocessParticipantChange(Change change, RefactoringParticipant participant) {
if (change == null)
return null;
CompositeChange compositeChange = change instanceof CompositeChange ?
(CompositeChange) change : null;
Change[] changes = compositeChange != null ?
compositeChange.getChildren() : new Change[] { change };
for (Change ch : changes) {
if (ch instanceof TextChange) {
TextChange textChange = (TextChange) ch;
Object element = textChange.getModifiedElement();
TextChange primaryChange = participant.getTextChange(element);
if (primaryChange != null) {
TextEdit edit = textChange.getEdit();
addExplodedTextEdit(edit, primaryChange);
if (compositeChange != null) {
compositeChange.remove(ch);
} else {
change = null;
}
}
}
}
if (compositeChange != null && compositeChange.getChildren().length == 0)
change = null;
return change;
}
private static void addExplodedTextEdit(TextEdit textEdit, TextChange primaryChange) {
if (textEdit instanceof MultiTextEdit) {
TextEdit[] children = ((MultiTextEdit) textEdit).removeChildren();
for (TextEdit edit : children) {
addExplodedTextEdit(edit, primaryChange);
}
} else {
primaryChange.addEdit(textEdit);
}
}
private RenameParticipantHelper() {}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2010 IBM Corporation and others.
* Copyright (c) 2000, 2014 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
@ -188,7 +188,7 @@ public class RenameSupport {
wizard.setForcePreviewReview(mode != DialogMode.ALL_PAGES);
}
RefactoringStarter starter = new RefactoringStarter();
CRenameProcessor processor = (CRenameProcessor) refactoring.getProcessor();
CRenameProcessor processor = refactoring.getProcessor();
processor.lockIndex();
try {
RefactoringStatus status = processor.checkInitialConditions(new NullProgressMonitor());
@ -244,7 +244,7 @@ public class RenameSupport {
return false;
}
CRenameProcessor renameProcessor = getRenameProcessor();
CRenameProcessor renameProcessor = fRefactoring.getProcessor();
renameProcessor.lockIndex();
try {
fPreCheckStatus = renameProcessor.checkInitialConditions(new NullProgressMonitor());
@ -261,7 +261,7 @@ public class RenameSupport {
RefactoringExecutionHelper helper= new RefactoringExecutionHelper(fRefactoring,
RefactoringCore.getConditionCheckingFailedSeverity(),
renameProcessor.getSaveMode(), parent, context);
Change change = renameProcessor.getChange();
Change change = fRefactoring.getChange();
Assert.isNotNull(change);
helper.performChange(change, true);
return true;
@ -280,10 +280,6 @@ public class RenameSupport {
fRefactoring= new CRenameRefactoring(processor);
}
private CRenameProcessor getRenameProcessor() {
return (CRenameProcessor) fRefactoring.getProcessor();
}
/**
* Creates a new rename support for the given {@link ICProject}.
*

View file

@ -0,0 +1,47 @@
/*******************************************************************************
* Copyright (c) 2000, 2014 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
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.reorg;
import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant;
import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor;
import org.eclipse.ltk.core.refactoring.participants.SharableParticipants;
import org.eclipse.ltk.core.refactoring.participants.ValidateEditChecker;
import org.eclipse.cdt.internal.corext.refactoring.participants.ResourceModifications;
public abstract class RefactoringModifications {
private ResourceModifications fResourceModifications;
public RefactoringModifications() {
fResourceModifications= new ResourceModifications();
}
public ResourceModifications getResourceModifications() {
return fResourceModifications;
}
public abstract RefactoringParticipant[] loadParticipants(RefactoringStatus status,
RefactoringProcessor owner, String[] natures, SharableParticipants shared);
public abstract void buildDelta(IResourceChangeDescriptionFactory builder);
/**
* Implementors add all resources that need a validate edit.
*
* @param checker the validate edit checker
*/
public void buildValidateEdits(ValidateEditChecker checker) {
// Default implementation does nothing.
}
}

View file

@ -24,7 +24,7 @@ import org.eclipse.ui.PlatformUI;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.ui.refactoring.CreateFileChange;
import org.eclipse.cdt.internal.ui.refactoring.changes.CreateFileChange;
public class ToggleFileCreator {
private static final String EMPTY_STRING = ""; //$NON-NLS-1$

View file

@ -2326,11 +2326,11 @@ public class PreferenceConstants {
* the workspace setting should be taken. Note that passing {@code null} should be avoided.
* @return Returns the node matching the given context.
*/
private static IEclipsePreferences getPreferenceNode(String key, ICProject project) {
private static IEclipsePreferences getPreferenceNode(String key, IProject project) {
IEclipsePreferences node = null;
if (project != null) {
node = new ProjectScope(project.getProject()).getNode(CUIPlugin.PLUGIN_ID);
node = new ProjectScope(project).getNode(CUIPlugin.PLUGIN_ID);
if (node.get(key, null) != null) {
return node;
}
@ -2348,6 +2348,19 @@ public class PreferenceConstants {
return DefaultScope.INSTANCE.getNode(CUIPlugin.PLUGIN_ID);
}
/**
* Returns the string value for the given key in the given context.
*
* @param key The preference key
* @param project The current context or {@code null} if no context is available and
* the workspace setting should be taken. Note that passing {@code null} should be avoided.
* @return Returns the current value for the string.
* @since 5.9
*/
public static String getPreference(String key, IProject project) {
return getPreference(key, project, null);
}
/**
* Returns the string value for the given key in the given context.
*
@ -2358,7 +2371,21 @@ public class PreferenceConstants {
* @since 5.0
*/
public static String getPreference(String key, ICProject project) {
return getPreference(key, project, null);
return getPreference(key, project.getProject());
}
/**
* Returns the string value for the given key in the given context.
*
* @param key The preference key
* @param project The current context or {@code null} if no context is available and
* the workspace setting should be taken. Note that passing {@code null} should be avoided.
* @param defaultValue The default value if not specified in the preferences.
* @return Returns the current value of the preference.
* @since 5.9
*/
public static String getPreference(String key, IProject project, String defaultValue) {
return getPreferenceNode(key, project).get(key, defaultValue);
}
/**
@ -2372,7 +2399,22 @@ public class PreferenceConstants {
* @since 5.6
*/
public static String getPreference(String key, ICProject project, String defaultValue) {
return getPreferenceNode(key, project).get(key, defaultValue);
return getPreference(key, project.getProject(), defaultValue);
}
/**
* Returns the integer value for the given key in the given context.
*
* @param key The preference key
* @param project The current context or {@code null} if no context is available and
* the workspace setting should be taken. Note that passing {@code null} should
* be avoided.
* @param defaultValue The default value if not specified in the preferences.
* @return Returns the current value of the preference.
* @since 5.9
*/
public static int getPreference(String key, IProject project, int defaultValue) {
return getPreferenceNode(key, project).getInt(key, defaultValue);
}
/**
@ -2387,7 +2429,21 @@ public class PreferenceConstants {
* @since 5.1
*/
public static int getPreference(String key, ICProject project, int defaultValue) {
return getPreferenceNode(key, project).getInt(key, defaultValue);
return getPreference(key, project.getProject(), defaultValue);
}
/**
* Returns the boolean value for the given key in the given context.
*
* @param key The preference key
* @param project The current context or {@code null} if no context is available and
* the workspace setting should be taken. Note that passing {@code null} should be avoided.
* @param defaultValue The default value if not specified in the preferences.
* @return Returns the current value of the preference.
* @since 5.9
*/
public static boolean getPreference(String key, IProject project, boolean defaultValue) {
return getPreferenceNode(key, project).getBoolean(key, defaultValue);
}
/**
@ -2401,7 +2457,7 @@ public class PreferenceConstants {
* @since 5.1
*/
public static boolean getPreference(String key, ICProject project, boolean defaultValue) {
return getPreferenceNode(key, project).getBoolean(key, defaultValue);
return getPreference(key, project.getProject(), defaultValue);
}
/**

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2009 Wind River Systems and others.
* Copyright (c) 2006, 2014 Wind River Systems 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
@ -29,7 +29,7 @@ import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.internal.core.model.TranslationUnit;
import org.eclipse.cdt.internal.ui.refactoring.DocumentAdapter;
import org.eclipse.cdt.internal.ui.refactoring.UndoCTextFileChange;
import org.eclipse.cdt.internal.ui.refactoring.changes.UndoCTextFileChange;
/**
* A TextFileChange that uses a working copy in order to generate CModel events.
@ -57,7 +57,7 @@ public class CTextFileChange extends TextFileChange {
* @since 5.1
*/
public CTextFileChange(String name, ITranslationUnit tu) {
super(name, getFile(tu));
super(name, tu.getFile());
fTranslationUnit = tu;
if (tu instanceof IWorkingCopy)
fWorkingCopy = (IWorkingCopy) tu;
@ -102,8 +102,4 @@ public class CTextFileChange extends TextFileChange {
protected Change createUndoChange(UndoEdit edit, ContentStamp stampToRestore) {
return new UndoCTextFileChange(getName(), getFile(), edit, stampToRestore, getSaveMode());
}
private static IFile getFile(ITranslationUnit tu) {
return (IFile) tu.getResource();
}
}