1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 17:05:26 +02:00

Added a test for renaming a source root folder.

This commit is contained in:
Sergey Prigogin 2015-01-08 16:12:57 -08:00
parent a44b1c9ba8
commit f0e6a286fb
8 changed files with 326 additions and 130 deletions

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2010 IBM Corporation and others. * Copyright (c) 2005, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -10,12 +10,16 @@
* Andrew Ferguson (Symbian) * Andrew Ferguson (Symbian)
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Anton Leherbauer (Wind River Systems) * Anton Leherbauer (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.testplugin; package org.eclipse.cdt.core.testplugin;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
import org.eclipse.cdt.core.CCProjectNature; import org.eclipse.cdt.core.CCProjectNature;
@ -30,6 +34,7 @@ import org.eclipse.cdt.core.model.IBinaryContainer;
import org.eclipse.cdt.core.model.ICContainer; import org.eclipse.cdt.core.model.ICContainer;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IPathEntry;
import org.eclipse.cdt.core.model.ISourceRoot; import org.eclipse.cdt.core.model.ISourceRoot;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.settings.model.ICConfigExtensionReference; import org.eclipse.cdt.core.settings.model.ICConfigExtensionReference;
@ -38,6 +43,7 @@ import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager; import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager;
import org.eclipse.cdt.core.settings.model.TestCfgDataProvider; import org.eclipse.cdt.core.settings.model.TestCfgDataProvider;
import org.eclipse.cdt.core.settings.model.util.CDataUtil; import org.eclipse.cdt.core.settings.model.util.CDataUtil;
import org.eclipse.cdt.internal.core.model.InternalCoreModelUtil;
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences; import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
@ -115,7 +121,7 @@ public class CProjectHelper {
} }
/** /**
* Add the default binary parser if no binary parser configured. * Adds the default binary parser if no binary parser configured.
* *
* @param project * @param project
* @throws CoreException * @throws CoreException
@ -293,6 +299,45 @@ public class CProjectHelper {
folder.delete(true, null); folder.delete(true, null);
} }
/**
* Adds a source root to a C/C++ project.
*
* @param cproject the project to add the source root to
* @param rootName the relative path of the source root
*/
public static void addSourceRoot(ICProject cproject, String rootName) throws CoreException {
IProject project = cproject.getProject();
IFolder rootFolder = project.getFolder(rootName);
if (!rootFolder.exists()) {
rootFolder.create(false, true, null);
}
IPath rootPath = rootFolder.getFullPath();
if (!CCorePlugin.getDefault().isNewStyleProject(project)) {
InternalCoreModelUtil.addSourceEntry(project, rootFolder, false, null);
} else {
IPathEntry[] entries = cproject.getRawPathEntries();
ArrayList<IPathEntry> newEntries= new ArrayList<>(entries.length + 1);
for (IPathEntry entry : entries) {
if (entry.getEntryKind() == IPathEntry.CDT_SOURCE) {
if (rootPath.equals(entry.getPath())) {
return; // The source root exists already.
}
}
newEntries.add(entry);
}
IPathEntry newEntry= CoreModel.newSourceEntry(rootPath);
Set<IPathEntry> modified= new HashSet<>();
InternalCoreModelUtil.addExclusionPatterns(newEntry, newEntries, modified);
newEntries.add(CoreModel.newSourceEntry(rootPath));
cproject.setRawPathEntries(newEntries.toArray(new IPathEntry[newEntries.size()]), null);
}
}
/** /**
* Attempts to find an archive with the given name in the workspace * Attempts to find an archive with the given name in the workspace
*/ */
@ -353,8 +398,7 @@ public class CProjectHelper {
} }
/** /**
* Attempts to find a TranslationUnit with the given name in the workspace * Attempts to find a TranslationUnit with the given name in the workspace.
* @throws InterruptedException
*/ */
public static ITranslationUnit findTranslationUnit(ICProject testProject, String name) throws CModelException, InterruptedException { public static ITranslationUnit findTranslationUnit(ICProject testProject, String name) throws CModelException, InterruptedException {
for (int j = 0; j < 20; j++) { for (int j = 0; j < 20; j++) {
@ -376,7 +420,7 @@ public class CProjectHelper {
} }
/** /**
* Attempts to find an element with the given name in the workspace * Attempts to find an element with the given name in the workspace.
*/ */
public static ICElement findElement(ICProject testProject, String name) throws CModelException { public static ICElement findElement(ICProject testProject, String name) throws CModelException {
ICElement[] sourceRoots = testProject.getChildren(); ICElement[] sourceRoots = testProject.getChildren();
@ -414,7 +458,6 @@ public class CProjectHelper {
} }
} }
public static void importSourcesFromPlugin(ICProject project, Bundle bundle, String sources) throws CoreException { public static void importSourcesFromPlugin(ICProject project, Bundle bundle, String sources) throws CoreException {
try { try {
String baseDir= FileLocator.toFileURL(FileLocator.find(bundle, new Path(sources), null)).getFile(); String baseDir= FileLocator.toFileURL(FileLocator.find(bundle, new Path(sources), null)).getFile();
@ -422,21 +465,18 @@ public class CProjectHelper {
new File(baseDir), FileSystemStructureProvider.INSTANCE, OVERWRITE_QUERY); new File(baseDir), FileSystemStructureProvider.INSTANCE, OVERWRITE_QUERY);
importOp.setCreateContainerStructure(false); importOp.setCreateContainerStructure(false);
importOp.run(new NullProgressMonitor()); importOp.run(new NullProgressMonitor());
} } catch (Exception e) {
catch (Exception e) {
throw new CoreException(new Status(IStatus.ERROR, CTestPlugin.PLUGIN_ID, 0, "Import Interrupted", e)); throw new CoreException(new Status(IStatus.ERROR, CTestPlugin.PLUGIN_ID, 0, "Import Interrupted", e));
} }
} }
/** /**
* @return the location of a newly created directory in temporary area. * Returns the location of a newly created directory in a temporary area.
* Note that cleanup should be done with {@link ResourceHelper#cleanUp()}. * Note that cleanup should be done with {@link ResourceHelper#cleanUp()}.
* @throws IOException
* @throws CoreException
*/ */
public static File freshDir() throws IOException, CoreException { public static File freshDir() throws IOException, CoreException {
IPath folderPath = ResourceHelper.createTemporaryFolder(); IPath folderPath = ResourceHelper.createTemporaryFolder();
File folder = new File(folderPath.toOSString()); File folder = folderPath.toFile();
Assert.assertTrue(folder.exists()); Assert.assertTrue(folder.exists());
Assert.assertTrue(folder.isDirectory()); Assert.assertTrue(folder.isDirectory());
Assert.assertTrue(folder.canWrite()); Assert.assertTrue(folder.canWrite());

View file

@ -0,0 +1,90 @@
/*******************************************************************************
* Copyright (c) 2010, 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.core.model;
import static org.eclipse.cdt.core.model.CoreModelUtil.isExcludedPath;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.IPathEntry;
import org.eclipse.cdt.core.model.ISourceEntry;
import org.eclipse.cdt.core.settings.model.CSourceEntry;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICSourceEntry;
import org.eclipse.cdt.core.settings.model.WriteAccessException;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
/**
* Non-API methods for manipulating C/C++ projects.
*/
public class InternalCoreModelUtil {
public static void addSourceEntry(IProject project, IFolder folder, boolean removeProject,
IProgressMonitor monitor) throws CoreException {
ICSourceEntry newEntry = new CSourceEntry(folder, null, 0);
ICProjectDescription des = CCorePlugin.getDefault().getProjectDescription(project, true);
addEntryToAllCfgs(des, newEntry, removeProject);
CCorePlugin.getDefault().setProjectDescription(project, des, false, monitor);
}
private static void addEntryToAllCfgs(ICProjectDescription des, ICSourceEntry entry,
boolean removeProject) throws WriteAccessException, CoreException {
ICConfigurationDescription cfgs[] = des.getConfigurations();
for (ICConfigurationDescription cfg : cfgs) {
ICSourceEntry[] entries = cfg.getSourceEntries();
entries = addEntry(entries, entry, removeProject);
cfg.setSourceEntries(entries);
}
}
private static ICSourceEntry[] addEntry(ICSourceEntry[] entries, ICSourceEntry sourceEntry,
boolean removeProject) {
Set<ICSourceEntry> set = new HashSet<>();
for (ICSourceEntry entry : entries) {
if (removeProject && new Path(entry.getValue()).segmentCount() == 1)
continue;
set.add(entry);
}
set.add(sourceEntry);
return set.toArray(new ICSourceEntry[set.size()]);
}
public static void addExclusionPatterns(IPathEntry newEntry, List<IPathEntry> existing,
Set<IPathEntry> modifiedEntries) {
IPath entryPath= newEntry.getPath();
for (int i= 0; i < existing.size(); i++) {
IPathEntry curr= existing.get(i);
IPath currPath= curr.getPath();
if (curr.getEntryKind() == IPathEntry.CDT_SOURCE && currPath.isPrefixOf(entryPath)) {
IPath[] exclusionFilters= ((ISourceEntry) curr).getExclusionPatterns();
if (!isExcludedPath(entryPath, exclusionFilters)) {
IPath pathToExclude= entryPath.removeFirstSegments(currPath.segmentCount()).addTrailingSeparator();
IPath[] newExclusionFilters= new IPath[exclusionFilters.length + 1];
System.arraycopy(exclusionFilters, 0, newExclusionFilters, 0, exclusionFilters.length);
newExclusionFilters[exclusionFilters.length]= pathToExclude;
IPathEntry updated= CoreModel.newSourceEntry(currPath, newExclusionFilters);
existing.set(i, updated);
modifiedEntries.add(updated);
}
}
}
}
}

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2014 Google, Inc and others. * Copyright (c) 2014, 2015 Google, Inc and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -21,6 +21,8 @@ import org.eclipse.ltk.core.refactoring.participants.RenameRefactoring;
import org.eclipse.ltk.internal.core.refactoring.resource.MoveResourcesProcessor; import org.eclipse.ltk.internal.core.refactoring.resource.MoveResourcesProcessor;
import org.eclipse.ltk.internal.core.refactoring.resource.RenameResourceProcessor; import org.eclipse.ltk.internal.core.refactoring.resource.RenameResourceProcessor;
import org.eclipse.cdt.core.model.ISourceRoot;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.ui.PreferenceConstants; import org.eclipse.cdt.ui.PreferenceConstants;
import org.eclipse.cdt.ui.tests.refactoring.RefactoringTestBase; import org.eclipse.cdt.ui.tests.refactoring.RefactoringTestBase;
@ -61,7 +63,6 @@ public class RenameMoveHeaderRefactoringTest extends RefactoringTestBase {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
protected CRenameRefactoring createRenameRefactoring(String newName) { protected CRenameRefactoring createRenameRefactoring(String newName) {
IFile file = getSelectedFile(); IFile file = getSelectedFile();
TextSelection selection = getSelection(); TextSelection selection = getSelection();
@ -189,7 +190,7 @@ public class RenameMoveHeaderRefactoringTest extends RefactoringTestBase {
// //
//#include "dir3/header1.h" //#include "dir3/header1.h"
// header2.cpp // source2.cpp
//#include "dir1/header1.h" //#include "dir1/header1.h"
//#include "dir2/header3.h" //#include "dir2/header3.h"
// //
@ -212,6 +213,61 @@ public class RenameMoveHeaderRefactoringTest extends RefactoringTestBase {
compareFiles(); compareFiles();
} }
// src1/header1.h
//#ifndef HEADER1_H_
//#define HEADER1_H_
//
//#include "src1/header2.h"
//
//#endif // HEADER1_H_
//====================
// src2/header1.h
//#ifndef HEADER1_H_
//#define HEADER1_H_
//
//#include "src2/header2.h"
//
//#endif // HEADER1_H_
// src1/header2.h
//#if !defined(HEADER2_H_)
//#define HEADER2_H_
//
//class A {};
//
//#endif /* HEADER2_H_ */
//====================
// src2/header2.h
//#if !defined(HEADER2_H_)
//#define HEADER2_H_
//
//class A {};
//
//#endif /* HEADER2_H_ */
// src1/source1.cpp
//#include <string>
//
//#include "src1/header1.h"
//====================
// src2/source1.cpp
//#include <string>
//
//#include "src2/header1.h"
public void testSourceRootRename() throws Exception {
CProjectHelper.addSourceRoot(getCProject(), "src1");
IFolder resource = getProject().getFolder("src1");
RenameResourceProcessor processor = new RenameResourceProcessor(resource);
processor.setNewResourceName("src2");
RenameRefactoring refactoring = new RenameRefactoring(processor);
executeRefactoring(refactoring, true);
ISourceRoot[] sourceRoots = getCProject().getAllSourceRoots();
assertEquals(2, sourceRoots.length);
assertEquals(getProject().getName(), sourceRoots[0].getElementName());
assertEquals("src2", sourceRoots[1].getElementName());
compareFiles();
}
// dir1/header1.h // dir1/header1.h
//#ifndef DIR1_HEADER1_H_ //#ifndef DIR1_HEADER1_H_
//#define DIR1_HEADER1_H_ //#define DIR1_HEADER1_H_
@ -254,7 +310,7 @@ public class RenameMoveHeaderRefactoringTest extends RefactoringTestBase {
// //
//#include "dir3/dir1/header1.h" //#include "dir3/dir1/header1.h"
// header2.cpp // source2.cpp
//#include "dir1/header1.h" //#include "dir1/header1.h"
//#include "dir2/header3.h" //#include "dir2/header3.h"
// //

View file

@ -10,11 +10,13 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.rename; package org.eclipse.cdt.internal.ui.refactoring.rename;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceProxy; import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.core.resources.IResourceProxyVisitor; import org.eclipse.core.resources.IResourceProxyVisitor;
@ -83,9 +85,10 @@ public class HeaderFileMoveParticipant extends MoveParticipant implements IShara
if (destinationLocation.equals(movedResource.getLocation().removeLastSegments(1))) if (destinationLocation.equals(movedResource.getLocation().removeLastSegments(1)))
continue; continue;
if (movedResource instanceof IContainer) { if (movedResource instanceof IFolder) {
final int prefixLength = movedResource.getFullPath().segmentCount() - 1; IFolder folder = (IFolder) movedResource;
((IContainer) movedResource).accept(new IResourceProxyVisitor() { final int prefixLength = folder.getFullPath().segmentCount() - 1;
folder.accept(new IResourceProxyVisitor() {
@Override @Override
public boolean visit(IResourceProxy proxy) throws CoreException { public boolean visit(IResourceProxy proxy) throws CoreException {
if (proxy.isLinked()) if (proxy.isLinked())
@ -103,9 +106,9 @@ public class HeaderFileMoveParticipant extends MoveParticipant implements IShara
movedFiles.put(file, destination.getFile(new Path(movedResource.getName()))); movedFiles.put(file, destination.getFile(new Path(movedResource.getName())));
} }
} }
HeaderFileReferenceAdjuster includeAdjuster = HeaderFileReferenceAdjuster includeAdjuster = new HeaderFileReferenceAdjuster(movedFiles,
new HeaderFileReferenceAdjuster(movedFiles, null, getProcessor()); Collections.<IContainer, IContainer>emptyMap(), getProcessor());
change = includeAdjuster.createChange(context, pm); change = includeAdjuster.createChange(context, pm);
} catch (CoreException e) { } catch (CoreException e) {
return RefactoringStatus.create(e.getStatus()); return RefactoringStatus.create(e.getStatus());

View file

@ -63,11 +63,13 @@ import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.index.IIndexInclude; import org.eclipse.cdt.core.index.IIndexInclude;
import org.eclipse.cdt.core.index.IIndexManager; import org.eclipse.cdt.core.index.IIndexManager;
import org.eclipse.cdt.core.index.IndexLocationFactory; import org.eclipse.cdt.core.index.IndexLocationFactory;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ISourceRoot; import org.eclipse.cdt.core.model.ISourceRoot;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.core.settings.model.ICSourceEntry;
import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.IWorkingCopyManager; import org.eclipse.cdt.ui.IWorkingCopyManager;
import org.eclipse.cdt.ui.PreferenceConstants; import org.eclipse.cdt.ui.PreferenceConstants;
@ -77,6 +79,7 @@ import org.eclipse.cdt.utils.PathUtil;
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.ASTCommenter; import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.ASTCommenter;
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap; import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
import org.eclipse.cdt.internal.core.dom.rewrite.util.ASTNodes; import org.eclipse.cdt.internal.core.dom.rewrite.util.ASTNodes;
import org.eclipse.cdt.internal.core.model.SourceRoot;
import org.eclipse.cdt.internal.core.util.TextUtil; import org.eclipse.cdt.internal.core.util.TextUtil;
import org.eclipse.cdt.internal.corext.codemanipulation.IncludeInfo; import org.eclipse.cdt.internal.corext.codemanipulation.IncludeInfo;
import org.eclipse.cdt.internal.corext.codemanipulation.StubUtility; import org.eclipse.cdt.internal.corext.codemanipulation.StubUtility;
@ -104,9 +107,10 @@ public class HeaderFileReferenceAdjuster {
private int indexLockCount; private int indexLockCount;
/** /**
* @param movedFiles keys are moved files, values are new, not yet existing, files * @param movedFiles keys are files being moved or renamed, values are new, not yet existing,
* files
* @param renamedContainers keys are folders and projects being renamed, values are new, * @param renamedContainers keys are folders and projects being renamed, values are new,
* not yet existing folders and projects. May be {@code null}. * not yet existing folders and projects.
* @param processor the refactoring processor * @param processor the refactoring processor
*/ */
public HeaderFileReferenceAdjuster(Map<IFile, IFile> movedFiles, public HeaderFileReferenceAdjuster(Map<IFile, IFile> movedFiles,
@ -114,7 +118,8 @@ public class HeaderFileReferenceAdjuster {
this.movedFiles = movedFiles; this.movedFiles = movedFiles;
this.movedFilesByLocation = new HashMap<>(); this.movedFilesByLocation = new HashMap<>();
for (Entry<IFile, IFile> entry : movedFiles.entrySet()) { for (Entry<IFile, IFile> entry : movedFiles.entrySet()) {
this.movedFilesByLocation.put(entry.getKey().getLocation().toOSString(), entry.getValue().getLocation()); this.movedFilesByLocation.put(entry.getKey().getLocation().toOSString(),
entry.getValue().getLocation());
} }
this.renamedContainers = renamedContainers; this.renamedContainers = renamedContainers;
this.astManager = getASTManager(processor); this.astManager = getASTManager(processor);
@ -458,11 +463,30 @@ public class HeaderFileReferenceAdjuster {
private String generateNewIncludeGuardSymbol(IResource resource, IFile newFile, ICProject cProject) { private String generateNewIncludeGuardSymbol(IResource resource, IFile newFile, ICProject cProject) {
switch (getIncludeGuardScheme(cProject.getProject())) { switch (getIncludeGuardScheme(cProject.getProject())) {
case PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME_FILE_PATH: case PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME_FILE_PATH:
ISourceRoot root = cProject.findSourceRoot(resource); IProject newProject = newFile.getProject();
IContainer base = root == null ? cProject.getProject() : root.getResource(); if (newProject.exists()) {
IContainer renamedBase = renamedContainers.get(base); // Move within the same or to a different existing project.
if (renamedBase != null) cProject = CoreModel.getDefault().create(newProject);
base = renamedBase; if (cProject == null)
break;
}
ISourceRoot[] roots;
try {
roots = cProject.getAllSourceRoots();
} catch (CModelException e) {
break;
}
IContainer base = null;
for (ISourceRoot root : roots) {
root = getModifiedSourceRoot(cProject, root);
if (root.isOnSourceEntry(newFile)) {
base = root.getResource();
break;
}
}
if (base == null)
break;
IPath path = PathUtil.makeRelativePath(newFile.getFullPath(), base.getFullPath()); IPath path = PathUtil.makeRelativePath(newFile.getFullPath(), base.getFullPath());
if (path == null) if (path == null)
break; break;
@ -477,6 +501,33 @@ public class HeaderFileReferenceAdjuster {
return null; return null;
} }
protected ISourceRoot getModifiedSourceRoot(ICProject cProject, ISourceRoot root) {
IContainer container = root.getResource();
ICSourceEntry sourceEntry = ((SourceRoot) root).getSourceEntry();
for (Entry<IContainer, IContainer> entry : renamedContainers.entrySet()) {
IPath oldFolderPath = entry.getKey().getFullPath();
IPath newFolderPath = entry.getValue().getFullPath();
sourceEntry = RenameCSourceFolderChange.renameSourceEntry(sourceEntry, oldFolderPath, newFolderPath);
}
IContainer newContainer = getModifiedContainer(container);
return new SourceRoot(cProject, newContainer, sourceEntry);
}
private IContainer getModifiedContainer(IContainer container) {
IPath relativePath = Path.EMPTY;
for (IContainer ancestor = container; ancestor.getType() != IResource.ROOT; ancestor = ancestor.getParent()) {
IContainer newContainer = renamedContainers.get(ancestor);
if (newContainer != null) {
if (relativePath.isEmpty()) {
return newContainer;
}
return newContainer.getFolder(relativePath);
}
relativePath = new Path(ancestor.getName()).append(relativePath);
}
return container;
}
private void flushEditBuffer(int offset, StringBuilder text, Deque<DeleteEdit> deletes, MultiTextEdit edit) { private void flushEditBuffer(int offset, StringBuilder text, Deque<DeleteEdit> deletes, MultiTextEdit edit) {
consumeDeletesUpTo(offset, deletes, edit); consumeDeletesUpTo(offset, deletes, edit);
if (text.length() != 0) { if (text.length() != 0) {

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009 Institute for Software, HSR Hochschule fuer Technik * Copyright (c) 2009, 2015 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others. * Rapperswil, University of applied sciences and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
@ -7,7 +7,8 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Institute for Software (IFS)- initial API and implementation * Institute for Software (IFS)- initial API and implementation
* Sergey Prigogin (Google)
******************************************************************************/ ******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.rename; package org.eclipse.cdt.internal.ui.refactoring.rename;
@ -39,27 +40,28 @@ import org.eclipse.cdt.ui.CUIPlugin;
* @author Emanuel Graf IFS * @author Emanuel Graf IFS
*/ */
public class RenameCSourceFolderChange extends Change { public class RenameCSourceFolderChange extends Change {
private IPath oldName; private final IPath oldFolderPath;
private IPath newName; private final IPath newFolderPath;
private IProject project; private final IProject project;
private IFolder folder; private final IFolder oldFolder;
public RenameCSourceFolderChange(IPath oldFolderPath, IPath newFolderPath, IProject project, IFolder oldFolder) { public RenameCSourceFolderChange(IFolder oldFolder, IPath newFolderPath) {
super(); super();
this.oldName = oldFolderPath; this.oldFolder = oldFolder;
this.newName = newFolderPath; this.newFolderPath = newFolderPath;
this.project = project; this.oldFolderPath = oldFolder.getFullPath();
folder = oldFolder; this.project = oldFolder.getProject();
} }
@Override @Override
public Object getModifiedElement() { public Object getModifiedElement() {
return folder; return oldFolder;
} }
@Override @Override
public String getName() { public String getName() {
return NLS.bind(RenameMessages.RenameCSourceFolderChange_Name0, oldName.lastSegment(), newName.lastSegment()); return NLS.bind(RenameMessages.RenameCSourceFolderChange_Name0,
oldFolderPath.lastSegment(), newFolderPath.lastSegment());
} }
@Override @Override
@ -68,51 +70,56 @@ public class RenameCSourceFolderChange extends Change {
@Override @Override
public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException, OperationCanceledException { public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException, OperationCanceledException {
if (folder.exists()) { if (oldFolder.exists()) {
return RefactoringStatus.create(Status.OK_STATUS); return RefactoringStatus.create(Status.OK_STATUS);
} else { } else {
return RefactoringStatus.create(new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, return RefactoringStatus.create(new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID,
NLS.bind(RenameMessages.RenameCSourceFolderChange_ErrorMsg, folder.getName()))); NLS.bind(RenameMessages.RenameCSourceFolderChange_ErrorMsg, oldFolder.getName())));
} }
} }
@Override @Override
public Change perform(IProgressMonitor pm) throws CoreException { public Change perform(IProgressMonitor pm) throws CoreException {
changeEntryInAllCfgs(CCorePlugin.getDefault().getProjectDescription(project, true)); changeEntryInAllCfgs(CCorePlugin.getDefault().getProjectDescription(project, true));
IFolder folder2 = project.getFolder(newName.lastSegment()); IFolder newFolder = project.getFolder(newFolderPath.removeFirstSegments(1));
return new RenameCSourceFolderChange(newName, oldName, project, folder2); return new RenameCSourceFolderChange(newFolder, oldFolderPath);
} }
private void changeEntryInAllCfgs(ICProjectDescription des) throws WriteAccessException, CoreException { private void changeEntryInAllCfgs(ICProjectDescription des) throws WriteAccessException, CoreException {
ICConfigurationDescription cfgs[] = des.getConfigurations(); ICConfigurationDescription cfgs[] = des.getConfigurations();
for (ICConfigurationDescription cfg : cfgs) { for (ICConfigurationDescription cfg : cfgs) {
ICSourceEntry[] entries = cfg.getSourceEntries(); ICSourceEntry[] entries = cfg.getSourceEntries();
entries = renameEntry(entries); entries = renameSourceEntries(entries);
cfg.setSourceEntries(entries); cfg.setSourceEntries(entries);
} }
CCorePlugin.getDefault().setProjectDescription(project, des, false, new NullProgressMonitor()); CCorePlugin.getDefault().setProjectDescription(project, des, false, new NullProgressMonitor());
} }
private ICSourceEntry[] renameEntry(ICSourceEntry[] entries) { private ICSourceEntry[] renameSourceEntries(ICSourceEntry[] sourceEntries) {
Set<ICSourceEntry> set = new HashSet<>(); Set<ICSourceEntry> set = new HashSet<>();
for (ICSourceEntry entry : entries) { for (ICSourceEntry entry : sourceEntries) {
String entryPath = entry.getName(); set.add(renameSourceEntry(entry, oldFolderPath, newFolderPath));
if (entryPath.equals(oldName.toString())) {
set.add(new CSourceEntry(newName, entry.getExclusionPatterns(), entry.getFlags()));
} else {
IPath oldSegments = oldName.removeFirstSegments(oldName.segmentCount() - 1);
Set<IPath> exclusionPatterns = new HashSet<>();
for (IPath pattern : entry.getExclusionPatterns()) {
if (pattern.equals(oldSegments)) {
exclusionPatterns.add(newName.removeFirstSegments(newName.segmentCount() - 1));
} else {
exclusionPatterns.add(pattern);
}
}
set.add(new CSourceEntry(entry.getValue(), exclusionPatterns.toArray(new IPath[exclusionPatterns.size()]), entry.getFlags()));
}
} }
return set.toArray(new ICSourceEntry[set.size()]); return set.toArray(new ICSourceEntry[set.size()]);
} }
static ICSourceEntry renameSourceEntry(ICSourceEntry sourceEntry, IPath oldFolderPath, IPath newFolderPath) {
String entryPath = sourceEntry.getName();
if (entryPath.equals(oldFolderPath.toString())) {
return new CSourceEntry(newFolderPath, sourceEntry.getExclusionPatterns(), sourceEntry.getFlags());
} else {
IPath oldSegments = oldFolderPath.removeFirstSegments(oldFolderPath.segmentCount() - 1);
Set<IPath> exclusionPatterns = new HashSet<>();
for (IPath pattern : sourceEntry.getExclusionPatterns()) {
if (pattern.equals(oldSegments)) {
exclusionPatterns.add(newFolderPath.removeFirstSegments(newFolderPath.segmentCount() - 1));
} else {
exclusionPatterns.add(pattern);
}
}
return new CSourceEntry(sourceEntry.getValue(),
exclusionPatterns.toArray(new IPath[exclusionPatterns.size()]), sourceEntry.getFlags());
}
}
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009, 2014 Institute for Software, HSR Hochschule fuer Technik * Copyright (c) 2009, 2015 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others. * Rapperswil, University of applied sciences and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
@ -41,10 +41,9 @@ public class SourceFolderRenameParticipant extends RenameParticipant {
@Override @Override
public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
IPath oldFolderPath = oldFolder.getFullPath();
String newName = getArguments().getNewName(); String newName = getArguments().getNewName();
IPath newFolderPath = oldFolderPath.removeLastSegments(1).append(newName); IPath newFolderPath = oldFolder.getFullPath().removeLastSegments(1).append(newName);
return new RenameCSourceFolderChange(oldFolderPath, newFolderPath, oldFolder.getProject(), oldFolder); return new RenameCSourceFolderChange(oldFolder, newFolderPath);
} }
@Override @Override

View file

@ -12,7 +12,6 @@ package org.eclipse.cdt.internal.ui.wizards.folderwizard;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IFolder;
@ -50,21 +49,15 @@ import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CProjectNature; import org.eclipse.cdt.core.CProjectNature;
import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.CoreModelUtil;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICModelStatus; import org.eclipse.cdt.core.model.ICModelStatus;
import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IPathEntry; import org.eclipse.cdt.core.model.IPathEntry;
import org.eclipse.cdt.core.model.ISourceEntry;
import org.eclipse.cdt.core.model.ISourceRoot; import org.eclipse.cdt.core.model.ISourceRoot;
import org.eclipse.cdt.core.settings.model.CSourceEntry;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICSourceEntry;
import org.eclipse.cdt.core.settings.model.WriteAccessException;
import org.eclipse.cdt.ui.CElementLabelProvider; import org.eclipse.cdt.ui.CElementLabelProvider;
import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.core.model.InternalCoreModelUtil;
import org.eclipse.cdt.internal.core.model.PathEntryManager; import org.eclipse.cdt.internal.core.model.PathEntryManager;
import org.eclipse.cdt.internal.ui.ICHelpContextIds; import org.eclipse.cdt.internal.ui.ICHelpContextIds;
@ -357,10 +350,10 @@ public class NewSourceFolderWizardPage extends NewElementWizardPage {
Set<IPathEntry> modified= new HashSet<>(); Set<IPathEntry> modified= new HashSet<>();
if (fExcludeInOthersFields.isSelected()) { if (fExcludeInOthersFields.isSelected()) {
addExclusionPatterns(newEntry, newEntries, modified); InternalCoreModelUtil.addExclusionPatterns(newEntry, newEntries, modified);
newEntries.add(CoreModel.newSourceEntry(path)); newEntries.add(CoreModel.newSourceEntry(path));
} else { } else {
if (projectEntryIndex != -1) { if (projectEntryIndex >= 0) {
fIsProjectAsSourceFolder= true; fIsProjectAsSourceFolder= true;
newEntries.set(projectEntryIndex, newEntry); newEntries.set(projectEntryIndex, newEntry);
} else { } else {
@ -390,27 +383,6 @@ public class NewSourceFolderWizardPage extends NewElementWizardPage {
} }
} }
private static void addExclusionPatterns(IPathEntry newEntry, List<IPathEntry> existing, Set<IPathEntry> modifiedEntries) {
IPath entryPath= newEntry.getPath();
for (int i= 0; i < existing.size(); i++) {
IPathEntry curr= existing.get(i);
IPath currPath= curr.getPath();
if (curr.getEntryKind() == IPathEntry.CDT_SOURCE && currPath.isPrefixOf(entryPath)) {
IPath[] exclusionFilters= ((ISourceEntry) curr).getExclusionPatterns();
if (!CoreModelUtil.isExcludedPath(entryPath, exclusionFilters)) {
IPath pathToExclude= entryPath.removeFirstSegments(currPath.segmentCount()).addTrailingSeparator();
IPath[] newExclusionFilters= new IPath[exclusionFilters.length + 1];
System.arraycopy(exclusionFilters, 0, newExclusionFilters, 0, exclusionFilters.length);
newExclusionFilters[exclusionFilters.length]= pathToExclude;
IPathEntry updated= CoreModel.newSourceEntry(currPath, newExclusionFilters);
existing.set(i, updated);
modifiedEntries.add(updated);
}
}
}
}
// ---- creation ---------------- // ---- creation ----------------
public ISourceRoot getNewSourceRoot() { public ISourceRoot getNewSourceRoot() {
@ -429,7 +401,8 @@ public class NewSourceFolderWizardPage extends NewElementWizardPage {
try { try {
String relPath= fRootDialogField.getText(); String relPath= fRootDialogField.getText();
IFolder folder= fCurrCProject.getProject().getFolder(relPath); IProject project = fCurrCProject.getProject();
IFolder folder= project.getFolder(relPath);
if (!folder.exists()) { if (!folder.exists()) {
CoreUtility.createFolder(folder, true, true, new SubProgressMonitor(monitor, 1)); CoreUtility.createFolder(folder, true, true, new SubProgressMonitor(monitor, 1));
} }
@ -437,11 +410,9 @@ public class NewSourceFolderWizardPage extends NewElementWizardPage {
throw new InterruptedException(); throw new InterruptedException();
} }
if (CCorePlugin.getDefault().isNewStyleProject(fCurrCProject.getProject())) { if (CCorePlugin.getDefault().isNewStyleProject(project)) {
ICSourceEntry newEntry = new CSourceEntry(folder, null, 0); InternalCoreModelUtil.addSourceEntry(project, folder, fIsProjectAsSourceFolder,
ICProjectDescription des = CCorePlugin.getDefault().getProjectDescription(fCurrCProject.getProject(), true); new SubProgressMonitor(monitor, 2));
addEntryToAllCfgs(des, newEntry, fIsProjectAsSourceFolder);
CCorePlugin.getDefault().setProjectDescription(fCurrCProject.getProject(), des, false, new SubProgressMonitor(monitor, 2));
} else { } else {
fCurrCProject.setRawPathEntries(fNewEntries, new SubProgressMonitor(monitor, 2)); fCurrCProject.setRawPathEntries(fNewEntries, new SubProgressMonitor(monitor, 2));
} }
@ -451,28 +422,7 @@ public class NewSourceFolderWizardPage extends NewElementWizardPage {
monitor.done(); monitor.done();
} }
} }
private void addEntryToAllCfgs(ICProjectDescription des, ICSourceEntry entry, boolean removeProj)
throws WriteAccessException, CoreException{
ICConfigurationDescription cfgs[] = des.getConfigurations();
for (ICConfigurationDescription cfg : cfgs) {
ICSourceEntry[] entries = cfg.getSourceEntries();
entries = addEntry(entries, entry, removeProj);
cfg.setSourceEntries(entries);
}
}
private ICSourceEntry[] addEntry(ICSourceEntry[] entries, ICSourceEntry sourceEntry, boolean removeProj) {
Set<ICSourceEntry> set = new HashSet<>();
for (ICSourceEntry entry : entries) {
if (removeProj && new Path(entry.getValue()).segmentCount() == 1)
continue;
set.add(entry);
}
set.add(sourceEntry);
return set.toArray(new ICSourceEntry[set.size()]);
}
// ------------- choose dialogs // ------------- choose dialogs
private IFolder chooseFolder(String title, String message, IPath initialPath) { private IFolder chooseFolder(String title, String message, IPath initialPath) {