1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-06 09:16:02 +02:00

Bug 449391 - Include guard name style

This commit is contained in:
Sergey Prigogin 2015-01-06 21:03:55 -08:00
parent 693185186e
commit 0498b96805
6 changed files with 96 additions and 55 deletions

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2000, 2009 QNX Software Systems and others. * Copyright (c) 2000, 2015 QNX Software Systems 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
@ -7,11 +7,14 @@
* *
* Contributors: * Contributors:
* QNX Software Systems - Initial API and implementation * QNX Software Systems - Initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.model; package org.eclipse.cdt.core.model;
import org.eclipse.core.resources.IContainer;
/** /**
* A C Folder Resource. * A C folder resource.
* *
* @noextend This interface is not intended to be extended by clients. * @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients. * @noimplement This interface is not intended to be implemented by clients.
@ -22,12 +25,12 @@ public interface ICContainer extends ICElement, IParent, IOpenable {
* It does not transitively answer non-C resources contained in folders; * It does not transitively answer non-C resources contained in folders;
* these would have to be explicitly iterated over. * these would have to be explicitly iterated over.
* <p> * <p>
* Non-C resources includes files, folders, projects not accounted for. * Non-C resources includes files, folders, projects not accounted for.
* </p> * </p>
* *
* @return an array of non-C resources directly contained in this project * @return an array of non-C resources directly contained in this project
* @exception CModelException if this element does not exist or if an * @exception CModelException if this element does not exist or if an
* exception occurs while accessing its corresponding resource * exception occurs while accessing its corresponding resource
*/ */
Object[] getNonCResources() throws CModelException; Object[] getNonCResources() throws CModelException;
@ -41,11 +44,9 @@ public interface ICContainer extends ICElement, IParent, IOpenable {
ITranslationUnit[] getTranslationUnits() throws CModelException; ITranslationUnit[] getTranslationUnits() throws CModelException;
/** /**
* Returns the translation unit with the specified name * Returns the translation unit with the specified name in this container
* in this container (for example, <code>"foobar.c"</code>). * (for example, {@code "foobar.c"}). The name has to be a valid translation unit name.
* The name has to be a valid translation unit name. * This is a handle-only operation. The celement may or may not exist.
* This is a handle-only operation. The celement
* may or may not exist.
* *
* @param name the given name * @param name the given name
* @return the translation unit with the specified name in this container * @return the translation unit with the specified name in this container
@ -54,46 +55,43 @@ public interface ICContainer extends ICElement, IParent, IOpenable {
/** /**
* Returns the all the binaries of this container. * Returns the all the binaries of this container.
*
* @throws CModelException
*/ */
IBinary[] getBinaries() throws CModelException; IBinary[] getBinaries() throws CModelException;
/** /**
* Return the binary for this name, it must be a * Returns the binary for this name, it must be a valid binary.
* valid binary
* This is a handle-only operation. The container may or may not exist. * This is a handle-only operation. The container may or may not exist.
*/ */
IBinary getBinary(String name); IBinary getBinary(String name);
/** /**
* Returns all the archive of this container * Returns all the archives of this container.
*
* @throws CModelException
*/ */
IArchive[] getArchives() throws CModelException; IArchive[] getArchives() throws CModelException;
/** /**
* This is a handle-only operation. The container * This is a handle-only operation. The container may or may not exist.
* may or may not exist.
*/ */
IArchive getArchive(String name); IArchive getArchive(String name);
/** /**
* Return al the child containers of this container. * Returns all the child containers of this container.
*
* @throws CModelException
*/ */
ICContainer[] getCContainers() throws CModelException; ICContainer[] getCContainers() throws CModelException;
/** /**
* Returns the container with the given name. * Returns the container with the given name. An empty string indicates the default package.
* An empty string indicates the default package. * This is a handle-only operation. The celement may or may not exist.
* This is a handle-only operation. The celement
* may or may not exist.
* *
* @param name the given container * @param name the name of a nested container
* @return the container with the given name * @return the container with the given name
*/ */
ICContainer getCContainer(String name); ICContainer getCContainer(String name);
/**
* Returns the corresponding IContainer.
* @since 5.9
*/
@Override
IContainer getResource();
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2000, 2008 QNX Software Systems and others. * Copyright (c) 2000, 2015 QNX Software Systems 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
@ -282,4 +282,9 @@ public class CContainer extends Openable implements ICContainer {
protected char getHandleMementoDelimiter() { protected char getHandleMementoDelimiter() {
return CElement.CEM_SOURCEFOLDER; return CElement.CEM_SOURCEFOLDER;
} }
@Override
public IContainer getResource() {
return (IContainer) super.getResource();
}
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2001, 2011 IBM Corporation and others. * Copyright (c) 2001, 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
@ -677,11 +677,8 @@ public class StubUtility {
return null; return null;
IPath path = file.getFullPath(); IPath path = file.getFullPath();
ISourceRoot root = cproject.findSourceRoot(file); ISourceRoot root = cproject.findSourceRoot(file);
if (root != null) { IPath basePath = root == null ? cproject.getPath() : root.getPath();
path = PathUtil.makeRelativePath(path, root.getPath()); path = PathUtil.makeRelativePath(path, basePath);
} else {
path = PathUtil.makeRelativePath(path, cproject.getPath());
}
return generateIncludeGuardSymbolFromFilePath(path.toString()); return generateIncludeGuardSymbolFromFilePath(path.toString());
default: default:
@ -697,7 +694,7 @@ public class StubUtility {
} }
} }
private static String generateIncludeGuardSymbolFromFilePath(String filename) { public static String generateIncludeGuardSymbolFromFilePath(String filename) {
// Convert to upper case and replace invalid characters with underscores, // Convert to upper case and replace invalid characters with underscores,
// e.g. convert some/directory/foo-bar.h to SOME_DIRECTORY_FOO_BAR_H_ // e.g. convert some/directory/foo-bar.h to SOME_DIRECTORY_FOO_BAR_H_
StringBuilder buf = new StringBuilder(filename.length() + 1); StringBuilder buf = new StringBuilder(filename.length() + 1);

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
@ -105,7 +105,7 @@ public class HeaderFileMoveParticipant extends MoveParticipant implements IShara
} }
HeaderFileReferenceAdjuster includeAdjuster = HeaderFileReferenceAdjuster includeAdjuster =
new HeaderFileReferenceAdjuster(movedFiles, getProcessor()); new HeaderFileReferenceAdjuster(movedFiles, null, 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

@ -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
@ -10,6 +10,7 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.rename; package org.eclipse.cdt.internal.ui.refactoring.rename;
import java.io.File;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -22,6 +23,7 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResource;
@ -31,6 +33,7 @@ import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubMonitor; import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.preferences.IPreferencesService; import org.eclipse.core.runtime.preferences.IPreferencesService;
@ -62,12 +65,14 @@ 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.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.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.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;
import org.eclipse.cdt.ui.refactoring.CTextFileChange; import org.eclipse.cdt.ui.refactoring.CTextFileChange;
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;
@ -93,20 +98,25 @@ public class HeaderFileReferenceAdjuster {
private final Map<IFile, IFile> movedFiles; private final Map<IFile, IFile> movedFiles;
private final Map<String, IPath> movedFilesByLocation; private final Map<String, IPath> movedFilesByLocation;
private final Map<IContainer, IContainer> renamedContainers;
private ASTManager astManager; private ASTManager astManager;
private IIndex index; private IIndex index;
private int indexLockCount; private int indexLockCount;
/** /**
* @param movedFiles keys are moved files, values are new, not yet existing, files * @param movedFiles keys are moved files, values are new, not yet existing, files
* @param renamedContainers keys are folders and projects being renamed, values are new,
* not yet existing folders and projects. May be {@code null}.
* @param processor the refactoring processor * @param processor the refactoring processor
*/ */
public HeaderFileReferenceAdjuster(Map<IFile, IFile> movedFiles, RefactoringProcessor processor) { public HeaderFileReferenceAdjuster(Map<IFile, IFile> movedFiles,
Map<IContainer, IContainer> renamedContainers, RefactoringProcessor processor) {
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.astManager = getASTManager(processor); this.astManager = getASTManager(processor);
} }
@ -237,6 +247,10 @@ public class HeaderFileReferenceAdjuster {
location = include.getPath(); location = include.getPath();
if (location.isEmpty()) if (location.isEmpty())
continue; // Unresolved include. continue; // Unresolved include.
if (File.separatorChar == '\\') {
// Normalize path separators on Windows.
location = new Path(location).toString();
}
} else { } else {
String name = new String(include.getName().getSimpleID()); String name = new String(include.getName().getSimpleID());
IncludeInfo includeInfo = new IncludeInfo(name, include.isSystemInclude()); IncludeInfo includeInfo = new IncludeInfo(name, include.isSystemInclude());
@ -429,12 +443,8 @@ public class HeaderFileReferenceAdjuster {
return null; return null;
if (!oldGuard.equals(StubUtility.generateIncludeGuardSymbol(resource, tu.getCProject()))) if (!oldGuard.equals(StubUtility.generateIncludeGuardSymbol(resource, tu.getCProject())))
return null; return null;
IProject newProject = newFile.getProject(); String guard = generateNewIncludeGuardSymbol(resource, newFile, tu.getCProject());
ICProject newCProject = CoreModel.getDefault().create(newProject); if (guard == null || guard.equals(oldGuard))
if (newCProject == null)
return null;
String guard = StubUtility.generateIncludeGuardSymbol(newFile, newCProject);
if (guard.equals(oldGuard))
return null; return null;
MultiTextEdit rootEdit = new MultiTextEdit(); MultiTextEdit rootEdit = new MultiTextEdit();
for (IRegion region : includeGuardPositions) { for (IRegion region : includeGuardPositions) {
@ -443,6 +453,28 @@ public class HeaderFileReferenceAdjuster {
return rootEdit; return rootEdit;
} }
private String generateNewIncludeGuardSymbol(IResource resource, IFile newFile, ICProject cProject) {
switch (getIncludeGuardScheme(cProject.getProject())) {
case PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME_FILE_PATH:
ISourceRoot root = cProject.findSourceRoot(resource);
IContainer base = root == null ? cProject.getProject() : root.getResource();
IContainer renamedBase = renamedContainers.get(base);
if (renamedBase != null)
base = renamedBase;
IPath path = PathUtil.makeRelativePath(newFile.getFullPath(), base.getFullPath());
if (path == null)
break;
return StubUtility.generateIncludeGuardSymbolFromFilePath(path.toString());
case PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME_FILE_NAME:
return StubUtility.generateIncludeGuardSymbolFromFilePath(newFile.getName());
default:
break;
}
return null;
}
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) {
@ -512,12 +544,7 @@ public class HeaderFileReferenceAdjuster {
String filename = oldfile.getLocation().lastSegment(); String filename = oldfile.getLocation().lastSegment();
if (!CoreModel.isValidHeaderUnitName(project, filename)) if (!CoreModel.isValidHeaderUnitName(project, filename))
return false; return false;
IPreferencesService preferences = Platform.getPreferencesService(); switch (getIncludeGuardScheme(project)) {
IScopeContext[] scopes = PreferenceConstants.getPreferenceScopes(project);
int scheme = preferences.getInt(CUIPlugin.PLUGIN_ID,
PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME,
PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME_FILE_NAME, scopes);
switch (scheme) {
case PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME_FILE_PATH: case PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME_FILE_PATH:
return true; return true;
@ -528,4 +555,13 @@ public class HeaderFileReferenceAdjuster {
return false; return false;
} }
} }
private static int getIncludeGuardScheme(IProject project) {
IPreferencesService preferences = Platform.getPreferencesService();
IScopeContext[] scopes = PreferenceConstants.getPreferenceScopes(project);
int scheme = preferences.getInt(CUIPlugin.PLUGIN_ID,
PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME,
PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME_FILE_NAME, scopes);
return scheme;
}
} }

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
@ -67,6 +67,7 @@ public class HeaderFileRenameParticipant extends RenameParticipant implements IS
// Maps the affected files to new, not yet existing, files. // Maps the affected files to new, not yet existing, files.
final Map<IFile, IFile> movedFiles = new HashMap<>(); final Map<IFile, IFile> movedFiles = new HashMap<>();
final Map<IContainer, IContainer> renamedContainers = new HashMap<>();
for (Map.Entry<IResource, RenameArguments> entry : renamedResources.entrySet()) { for (Map.Entry<IResource, RenameArguments> entry : renamedResources.entrySet()) {
IResource renamedResource = entry.getKey(); IResource renamedResource = entry.getKey();
@ -78,10 +79,14 @@ public class HeaderFileRenameParticipant extends RenameParticipant implements IS
String newName = args.getNewName(); String newName = args.getNewName();
if (renamedResource instanceof IContainer) { if (renamedResource instanceof IContainer) {
final IPath oldPath = renamedResource.getFullPath(); IContainer container = (IContainer) renamedResource;
final IPath oldPath = container.getFullPath();
final IPath newPath = oldPath.removeLastSegments(1).append(newName); final IPath newPath = oldPath.removeLastSegments(1).append(newName);
final IWorkspaceRoot workspaceRoot = renamedResource.getWorkspace().getRoot(); final IWorkspaceRoot workspaceRoot = container.getWorkspace().getRoot();
((IContainer) renamedResource).accept(new IResourceProxyVisitor() { IContainer newContainer = container.getType() == IResource.FOLDER ?
workspaceRoot.getFolder(newPath) : workspaceRoot.getProject(newName);
renamedContainers.put(container, newContainer);
container.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())
@ -101,7 +106,7 @@ public class HeaderFileRenameParticipant extends RenameParticipant implements IS
} }
} }
HeaderFileReferenceAdjuster includeAdjuster = HeaderFileReferenceAdjuster includeAdjuster =
new HeaderFileReferenceAdjuster(movedFiles, getProcessor()); new HeaderFileReferenceAdjuster(movedFiles, renamedContainers, 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());