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

2004-08-20 Chris Wiebe

class wizard now adds include paths dynamically
	* src/org/eclipse/cdt/internal/ui/wizards/classwizard/NewClassCreationWizardPage.java
	* src/org/eclipse/cdt/internal/ui/wizards/classwizard/NewClassCreationWizardMessages.properties
	* src/org/eclipse/cdt/internal/ui/wizards/classwizard/NewClassCodeGenerator.java
This commit is contained in:
Chris Wiebe 2004-08-21 01:24:29 +00:00
parent 05068c307d
commit 010c8c429a
5 changed files with 417 additions and 206 deletions

View file

@ -1,3 +1,10 @@
2004-08-20 Chris Wiebe
class wizard now adds include paths dynamically
* src/org/eclipse/cdt/internal/ui/wizards/classwizard/NewClassCreationWizardPage.java
* src/org/eclipse/cdt/internal/ui/wizards/classwizard/NewClassCreationWizardMessages.properties
* src/org/eclipse/cdt/internal/ui/wizards/classwizard/NewClassCodeGenerator.java
2004-08-19 Alain Magloire
Match the changing API of the Resolver Model.

View file

@ -16,13 +16,20 @@ import java.util.List;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.browser.ITypeReference;
import org.eclipse.cdt.core.browser.PathUtil;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICContainer;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IIncludeEntry;
import org.eclipse.cdt.core.model.IPathEntry;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.IScannerInfoProvider;
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
import org.eclipse.cdt.internal.corext.util.CModelUtil;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
@ -30,6 +37,7 @@ import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubProgressMonitor;
public class NewClassCodeGenerator {
@ -43,6 +51,16 @@ public class NewClassCodeGenerator {
private ITranslationUnit fCreatedHeaderTU = null;
private ITranslationUnit fCreatedSourceTU = null;
private ICElement fCreatedClass = null;
//TODO this should be a prefs option
private boolean fCreateIncludePaths = true;
public static class CodeGeneratorException extends Exception {
public CodeGeneratorException(String message) {
}
public CodeGeneratorException(Throwable e) {
}
}
public NewClassCodeGenerator(IPath headerPath, IPath sourcePath, String className, String namespace, IBaseClassInfo[] baseClasses, IMethodStub[] methodStubs) {
fHeaderPath = headerPath;
@ -76,33 +94,30 @@ public class NewClassCodeGenerator {
* @throws InterruptedException
* Thrown when the operation was cancelled.
*/
public ICElement createClass(IProgressMonitor monitor) throws CoreException, InterruptedException {
public ICElement createClass(IProgressMonitor monitor) throws CodeGeneratorException, CoreException, InterruptedException {
if (monitor == null)
monitor = new NullProgressMonitor();
monitor.beginTask(NewClassWizardMessages.getString("NewClassCodeGeneration.createType.task"), 10); //$NON-NLS-1$
monitor.beginTask(NewClassWizardMessages.getString("NewClassCodeGeneration.createType.mainTask"), 400); //$NON-NLS-1$
ITranslationUnit headerTU = null;
ITranslationUnit headerTU = null;
ITranslationUnit sourceTU = null;
ICElement createdClass = null;
IWorkingCopy headerWorkingCopy = null;
IWorkingCopy sourceWorkingCopy = null;
try {
monitor.worked(1);
if (fHeaderPath != null) {
IFile headerFile = NewSourceFileGenerator.createHeaderFile(fHeaderPath, true, monitor);
IFile headerFile = NewSourceFileGenerator.createHeaderFile(fHeaderPath, true, new SubProgressMonitor(monitor, 50));
if (headerFile != null) {
headerTU = (ITranslationUnit) CoreModel.getDefault().create(headerFile);
}
monitor.worked(1);
// create a working copy with a new owner
headerWorkingCopy = headerTU.getWorkingCopy();
// headerWorkingCopy = headerTU.getSharedWorkingCopy(null, CUIPlugin.getDefault().getBufferFactory());
String headerContent = constructHeaderFileContent(headerTU, headerWorkingCopy.getBuffer().getContents());
String headerContent = constructHeaderFileContent(headerTU, headerWorkingCopy.getBuffer().getContents(), new SubProgressMonitor(monitor, 100));
headerWorkingCopy.getBuffer().setContents(headerContent);
if (monitor.isCanceled()) {
@ -111,6 +126,7 @@ public class NewClassCodeGenerator {
headerWorkingCopy.reconcile();
headerWorkingCopy.commit(true, monitor);
monitor.worked(50);
createdClass = headerWorkingCopy.getElement(fClassName);
fCreatedClass = createdClass;
@ -118,16 +134,16 @@ public class NewClassCodeGenerator {
}
if (fSourcePath != null) {
IFile sourceFile = NewSourceFileGenerator.createHeaderFile(fSourcePath, true, monitor);
IFile sourceFile = NewSourceFileGenerator.createHeaderFile(fSourcePath, true, new SubProgressMonitor(monitor, 50));
if (sourceFile != null) {
sourceTU = (ITranslationUnit) CoreModel.getDefault().create(sourceFile);
}
monitor.worked(1);
monitor.worked(50);
// create a working copy with a new owner
sourceWorkingCopy = sourceTU.getWorkingCopy();
String sourceContent = constructSourceFileContent(sourceTU, headerTU);
String sourceContent = constructSourceFileContent(sourceTU, headerTU, new SubProgressMonitor(monitor, 100));
sourceWorkingCopy.getBuffer().setContents(sourceContent);
if (monitor.isCanceled()) {
@ -136,6 +152,7 @@ public class NewClassCodeGenerator {
sourceWorkingCopy.reconcile();
sourceWorkingCopy.commit(true, monitor);
monitor.worked(50);
fCreatedSourceTU = sourceTU;
}
@ -152,7 +169,10 @@ public class NewClassCodeGenerator {
return fCreatedClass;
}
public String constructHeaderFileContent(ITranslationUnit headerTU, String oldContents) {
public String constructHeaderFileContent(ITranslationUnit headerTU, String oldContents, IProgressMonitor monitor) throws CodeGeneratorException {
monitor.beginTask(NewClassWizardMessages.getString("NewClassCodeGeneration.createType.task.header"), 100); //$NON-NLS-1$
//TODO should use code templates
StringBuffer text = new StringBuffer();
@ -179,7 +199,7 @@ public class NewClassCodeGenerator {
}
if (fBaseClasses != null && fBaseClasses.length > 0) {
addBaseClassIncludes(headerTU, text);
addBaseClassIncludes(headerTU, text, new SubProgressMonitor(monitor, 50));
text.append(fLineDelimiter);
}
@ -227,8 +247,10 @@ public class NewClassCodeGenerator {
text.append(oldContents.substring(appendFirstCharPos));
}
}
return text.toString();
String newContents = text.toString();
monitor.done();
return newContents;
}
private int getInsertionPos(String contents) {
@ -334,49 +356,210 @@ public class NewClassCodeGenerator {
}
}
private void addBaseClassIncludes(ITranslationUnit headerTU, StringBuffer text) {
IProject project = headerTU.getCProject().getProject();
private void addBaseClassIncludes(ITranslationUnit headerTU, StringBuffer text, IProgressMonitor monitor) throws CodeGeneratorException {
monitor.beginTask(NewClassWizardMessages.getString("NewClassCodeGeneration.createType.task.header.includePaths"), 100); //$NON-NLS-1$
ICProject cProject = headerTU.getCProject();
IProject project = cProject.getProject();
IPath projectLocation = project.getLocation();
IPath headerLocation = headerTU.getResource().getLocation();
for (int i = 0; i < fBaseClasses.length; ++i) {
String baseClassFileName = null;
boolean isSystemIncludePath = false;
IBaseClassInfo baseClass = fBaseClasses[i];
ITypeReference ref = baseClass.getType().getResolvedReference();
if (ref != null) {
IPath baseClassLocation = ref.getLocation();
IPath includePath = makeRelativePathToProjectIncludes(baseClassLocation, project);
if (includePath != null && !projectLocation.isPrefixOf(baseClassLocation)) {
isSystemIncludePath = true;
} else if (projectLocation.isPrefixOf(baseClassLocation)
&& projectLocation.isPrefixOf(headerLocation)) {
includePath = makeRelativePath(baseClassLocation, headerLocation);
}
if (includePath == null)
includePath = baseClassLocation;
baseClassFileName = includePath.toString();
}
if (baseClassFileName == null) {
baseClassFileName = NewSourceFileGenerator.generateHeaderFileNameFromClass(baseClass.getType().getName());
}
// add the include statement if we are extending a base class
// and we are not already in the base class header file
// (enclosing type)
if (!(headerTU.getElementName().equals(baseClassFileName))) {
String include = getIncludeString(baseClassFileName, isSystemIncludePath);
text.append(include);
text.append(fLineDelimiter);
}
List includePaths = getIncludePaths(headerTU);
List baseClassPaths = getBaseClassPaths();
// add the missing include paths to the project
if (fCreateIncludePaths) {
List newIncludePaths = getMissingIncludePaths(projectLocation, includePaths, baseClassPaths);
if (!newIncludePaths.isEmpty()) {
addIncludePaths(cProject, newIncludePaths, monitor);
}
}
List systemIncludes = new ArrayList();
List localIncludes = new ArrayList();
// sort the include paths into system and local
for (Iterator bcIter = baseClassPaths.iterator(); bcIter.hasNext(); ) {
IPath baseClassLocation = (IPath) bcIter.next();
boolean isSystemIncludePath = false;
IPath includePath = PathUtil.makeRelativePathToProjectIncludes(baseClassLocation, project);
if (includePath != null && !projectLocation.isPrefixOf(baseClassLocation)) {
isSystemIncludePath = true;
} else if (projectLocation.isPrefixOf(baseClassLocation)
&& projectLocation.isPrefixOf(headerLocation)) {
includePath = PathUtil.makeRelativePath(baseClassLocation, headerLocation);
}
if (includePath == null)
includePath = baseClassLocation;
if (isSystemIncludePath)
systemIncludes.add(includePath);
else
localIncludes.add(includePath);
}
// write the system include paths, e.g. #include <header.h>
for (Iterator i = systemIncludes.iterator(); i.hasNext(); ) {
IPath includePath = (IPath) i.next();
if (!(headerTU.getElementName().equals(includePath.toString()))) {
String include = getIncludeString(includePath.toString(), true);
text.append(include);
text.append(fLineDelimiter);
}
}
// write the local include paths, e.g. #include "header.h"
for (Iterator i = localIncludes.iterator(); i.hasNext(); ) {
IPath includePath = (IPath) i.next();
if (!(headerTU.getElementName().equals(includePath.toString()))) {
String include = getIncludeString(includePath.toString(), false);
text.append(include);
text.append(fLineDelimiter);
}
}
monitor.done();
}
public String constructSourceFileContent(ITranslationUnit sourceTU, ITranslationUnit headerTU) {
private void addIncludePaths(ICProject cProject, List newIncludePaths, IProgressMonitor monitor) throws CodeGeneratorException {
monitor.beginTask(NewClassWizardMessages.getString("NewClassCodeGeneration.createType.task.header.addIncludePaths"), 100); //$NON-NLS-1$
//TODO prefs option whether to add to project or parent source folder?
IPath addToResourcePath = cProject.getPath();
try {
List pathEntryList = new ArrayList();
IPathEntry[] pathEntries = cProject.getRawPathEntries();
if (pathEntries != null) {
for (int i = 0; i < pathEntries.length; ++i) {
pathEntryList.add(pathEntries[i]);
}
}
for (Iterator ipIter = newIncludePaths.iterator(); ipIter.hasNext(); ) {
IPath folderToAdd = (IPath) ipIter.next();
IPath basePath = null;
IPath includePath = folderToAdd;
IProject includeProject = PathUtil.getEnclosingProject(folderToAdd);
boolean isSystemInclude = (includeProject == null);
if (includeProject != null) {
includePath = PathUtil.makeRelativePath(folderToAdd, includeProject.getLocation());
basePath = includeProject.getFullPath().makeRelative();
}
IIncludeEntry entry = CoreModel.newIncludeEntry(addToResourcePath, basePath, includePath, isSystemInclude);
pathEntryList.add(entry);
}
pathEntries = (IPathEntry[]) pathEntryList.toArray(new IPathEntry[pathEntryList.size()]);
cProject.setRawPathEntries(pathEntries, new SubProgressMonitor(monitor, 80));
} catch (CModelException e) {
throw new CodeGeneratorException(e);
}
monitor.done();
}
private List getMissingIncludePaths(IPath projectLocation, List includePaths, List baseClassPaths) {
// check for missing include paths
List newIncludePaths = new ArrayList();
for (Iterator bcIter = baseClassPaths.iterator(); bcIter.hasNext(); ) {
IPath baseClassLocation = (IPath) bcIter.next();
// skip any paths inside the same project
//TODO possibly a preferences option?
if (projectLocation.isPrefixOf(baseClassLocation)) {
continue;
}
IPath folderToAdd = baseClassLocation.removeLastSegments(1);
IPath canonPath = PathUtil.getCanonicalPath(folderToAdd);
if (canonPath != null)
folderToAdd = canonPath;
// see if folder or its parent hasn't already been added
for (Iterator newIter = newIncludePaths.iterator(); newIter.hasNext(); ) {
IPath newFolder = (IPath) newIter.next();
if (newFolder.isPrefixOf(folderToAdd)) {
folderToAdd = null;
break;
}
}
if (folderToAdd != null) {
// search include paths
boolean foundPath = false;
for (Iterator ipIter = includePaths.iterator(); ipIter.hasNext(); ) {
IPath includePath = (IPath) ipIter.next();
if (includePath.isPrefixOf(folderToAdd)) {
foundPath = true;
break;
}
}
if (!foundPath) {
// remove any children of this folder
for (Iterator newIter = newIncludePaths.iterator(); newIter.hasNext(); ) {
IPath newFolder = (IPath) newIter.next();
if (folderToAdd.isPrefixOf(newFolder)) {
newIter.remove();
}
}
newIncludePaths.add(folderToAdd);
}
}
}
return newIncludePaths;
}
private List getIncludePaths(ITranslationUnit headerTU) throws CodeGeneratorException {
IProject project = headerTU.getCProject().getProject();
// get the parent source folder
ICContainer sourceFolder = CModelUtil.getSourceFolder(headerTU);
if (sourceFolder == null) {
throw new CodeGeneratorException("Could not find source folder"); //$NON-NLS-1$
}
// get the include paths
IScannerInfoProvider provider = CCorePlugin.getDefault().getScannerInfoProvider(project);
if (provider != null) {
IScannerInfo info = provider.getScannerInformation(sourceFolder.getResource());
if (info != null) {
String[] includePaths = info.getIncludePaths();
if (includePaths != null) {
List list = new ArrayList();
for (int i = 0; i < includePaths.length; ++i) {
//TODO do we need to canonicalize these paths first?
list.add(new Path(includePaths[i]));
}
return list;
}
}
}
return null;
}
private List getBaseClassPaths() throws CodeGeneratorException {
List list = new ArrayList();
for (int i = 0; i < fBaseClasses.length; ++i) {
IBaseClassInfo baseClass = fBaseClasses[i];
ITypeReference ref = baseClass.getType().getResolvedReference();
IPath baseClassLocation = null;
if (ref != null)
baseClassLocation = ref.getLocation();
if (baseClassLocation == null) {
throw new CodeGeneratorException("Could not find base class " + baseClass.toString()); //$NON-NLS-1$
}
list.add(baseClassLocation);
}
return list;
}
public String constructSourceFileContent(ITranslationUnit sourceTU, ITranslationUnit headerTU, IProgressMonitor monitor) {
monitor.beginTask(NewClassWizardMessages.getString("NewClassCodeGeneration.createType.task.source"), 150); //$NON-NLS-1$
//TODO should use code templates
StringBuffer text = new StringBuffer();
if (headerTU != null) {
addHeaderInclude(sourceTU, headerTU, text);
addHeaderInclude(sourceTU, headerTU, text, new SubProgressMonitor(monitor, 50));
text.append(fLineDelimiter);
}
@ -394,29 +577,31 @@ public class NewClassCodeGenerator {
beginNamespace(text);
}
addMethodBodies(publicMethods, protectedMethods, privateMethods, text);
addMethodBodies(publicMethods, protectedMethods, privateMethods, text, new SubProgressMonitor(monitor, 50));
if (fNamespace != null && fNamespace.length() > 0) {
endNamespace(text);
}
}
return text.toString();
String newContents = text.toString();
monitor.done();
return newContents;
}
private void addHeaderInclude(ITranslationUnit sourceTU, ITranslationUnit headerTU, StringBuffer text) {
private void addHeaderInclude(ITranslationUnit sourceTU, ITranslationUnit headerTU, StringBuffer text, IProgressMonitor monitor) {
IProject project = headerTU.getCProject().getProject();
IPath projectLocation = project.getLocation();
IPath headerLocation = headerTU.getResource().getLocation();
IPath sourceLocation = sourceTU.getResource().getLocation();
IPath includePath = makeRelativePathToProjectIncludes(headerLocation, project);
IPath includePath = PathUtil.makeRelativePathToProjectIncludes(headerLocation, project);
boolean isSystemIncludePath = false;
if (includePath != null && !projectLocation.isPrefixOf(headerLocation)) {
isSystemIncludePath = true;
} else if (projectLocation.isPrefixOf(headerLocation)
&& projectLocation.isPrefixOf(sourceLocation)) {
includePath = makeRelativePath(headerLocation, sourceLocation);
includePath = PathUtil.makeRelativePath(headerLocation, sourceLocation);
}
if (includePath == null)
includePath = headerLocation;
@ -426,7 +611,7 @@ public class NewClassCodeGenerator {
text.append(fLineDelimiter);
}
private void addMethodBodies(List publicMethods, List protectedMethods, List privateMethods, StringBuffer text) {
private void addMethodBodies(List publicMethods, List protectedMethods, List privateMethods, StringBuffer text, IProgressMonitor monitor) {
if (!publicMethods.isEmpty()) {
for (Iterator i = publicMethods.iterator(); i.hasNext();) {
IMethodStub stub = (IMethodStub) i.next();
@ -461,45 +646,6 @@ public class NewClassCodeGenerator {
}
}
public static IPath makeRelativePathToProjectIncludes(IPath fullPath, IProject project) {
IScannerInfoProvider provider = CCorePlugin.getDefault().getScannerInfoProvider(project);
if (provider != null) {
IScannerInfo info = provider.getScannerInformation(project);
if (info != null) {
String[] includePaths = info.getIncludePaths();
IPath relativePath = null;
int mostSegments = 0;
for (int i = 0; i < includePaths.length; ++i) {
IPath includePath = new Path(includePaths[i]);
if (includePath.isPrefixOf(fullPath)) {
int segments = includePath.matchingFirstSegments(fullPath);
if (segments > mostSegments) {
relativePath = fullPath.removeFirstSegments(segments).setDevice(null);
mostSegments = segments;
}
}
}
if (relativePath != null)
return relativePath;
}
}
return null;
}
public static IPath makeRelativePath(IPath path, IPath relativeTo) {
int segments = relativeTo.matchingFirstSegments(path);
if (segments > 0) {
IPath prefix = relativeTo.removeFirstSegments(segments).removeLastSegments(1);
IPath suffix = path.removeFirstSegments(segments);
IPath relativePath = new Path(""); //$NON-NLS-1$
for (int i = 0; i < prefix.segmentCount(); ++i) {
relativePath = relativePath.append(".." + IPath.SEPARATOR); //$NON-NLS-1$
}
return relativePath.append(suffix);
}
return null;
}
private static String getIncludeString(String fileName, boolean isSystemInclude) {
StringBuffer buf = new StringBuffer();
buf.append("#include "); //$NON-NLS-1$

View file

@ -18,7 +18,9 @@ import org.eclipse.cdt.core.CConventions;
import org.eclipse.cdt.core.browser.AllTypesCache;
import org.eclipse.cdt.core.browser.IQualifiedTypeName;
import org.eclipse.cdt.core.browser.ITypeInfo;
import org.eclipse.cdt.core.browser.ITypeReference;
import org.eclipse.cdt.core.browser.ITypeSearchScope;
import org.eclipse.cdt.core.browser.PathUtil;
import org.eclipse.cdt.core.browser.QualifiedTypeName;
import org.eclipse.cdt.core.browser.TypeSearchScope;
import org.eclipse.cdt.core.model.CModelException;
@ -39,6 +41,7 @@ import org.eclipse.cdt.internal.ui.wizards.NewElementWizardPage;
import org.eclipse.cdt.internal.ui.wizards.TypedElementSelectionValidator;
import org.eclipse.cdt.internal.ui.wizards.TypedViewerFilter;
import org.eclipse.cdt.internal.ui.wizards.classwizard.NewBaseClassSelectionDialog.ITypeSelectionListener;
import org.eclipse.cdt.internal.ui.wizards.classwizard.NewClassCodeGenerator.CodeGeneratorException;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.DialogField;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.IListAdapter;
@ -142,13 +145,17 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
protected final static String SOURCEFILE = PAGE_NAME + ".sourcefile"; //$NON-NLS-1$
StringButtonDialogField fSourceFileDialogField;
protected IStatus fSourceFileStatus;
IPath fCurrentSourceFile;
protected final IStatus STATUS_OK = new StatusInfo();
protected String fLastFocusedField = null;
private NewClassCodeGenerator fCodeGenerator = null;
//TODO this should be a prefs option
private boolean fCreateIncludePathsAsNeeded = false;
private boolean fWarnIfBaseClassNotInPath = true;
public NewClassCreationWizardPage() {
super(PAGE_NAME);
@ -216,7 +223,6 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
fCanModifyNamespace = true;
fCurrentEnclosingClass = null;
fCurrentHeaderFile = null;
fCurrentSourceFile = null;
fCanModifyEnclosingClass = true;
updateEnableState();
}
@ -622,7 +628,6 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
ICElement folder = chooseSourceFolder(fCurrentSourceFolder);
if (folder != null) {
setSourceFolder(folder, true);
prepareTypeCache();
}
}
@ -701,23 +706,61 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
private class ClassNameFieldAdapter implements IDialogFieldListener {
public void dialogFieldChanged(DialogField field) {
if (isUseDefaultSelected()) {
String className = fClassNameDialogField.getText();
if (className.length() > 0) {
fHeaderFileDialogField.setText(NewSourceFileGenerator.generateHeaderFileNameFromClass(className));
fSourceFileDialogField.setText(NewSourceFileGenerator.generateSourceFileNameFromClass(className));
} else {
fHeaderFileDialogField.setText(""); //$NON-NLS-1$
fSourceFileDialogField.setText(""); //$NON-NLS-1$
}
}
fClassNameStatus = classNameChanged();
if (isUseDefaultSelected()) {
updateFilesFromClassName(fClassNameDialogField.getText());
fHeaderFileStatus = headerFileChanged();
fSourceFileStatus = sourceFileChanged();
}
// tell all others
updateEnableState();
handleFieldChanged(CLASSNAME);
}
}
private static final int MAX_UNIQUE_CLASSNAME = 99;
private String findUniqueName(String className) {
IPath folderPath = getSourceFolderFullPath();
if (folderPath == null)
return className;
String currName = className;
int count = 0;
String separator = ""; //$NON-NLS-1$
//TODO could have a prefs option for how unique file names are generated
if (Character.isDigit(className.charAt(className.length()-1)))
separator = "_"; //$NON-NLS-1$
while (count < MAX_UNIQUE_CLASSNAME) {
String headerfileName = NewSourceFileGenerator.generateHeaderFileNameFromClass(currName);
String sourcefileName = NewSourceFileGenerator.generateSourceFileNameFromClass(currName);
IPath path = folderPath.append(headerfileName);
if (!path.toFile().exists()) {
path = folderPath.append(sourcefileName);
if (!path.toFile().exists()) {
return currName;
}
}
++count;
currName = className + separator + count; //$NON-NLS-1$
}
return null;
}
private void updateFilesFromClassName(String className) {
String headerName = ""; //$NON-NLS-1$
String sourceName = ""; //$NON-NLS-1$
if (className.length() > 0) {
className = findUniqueName(className);
if (className != null) {
headerName = NewSourceFileGenerator.generateHeaderFileNameFromClass(className);
sourceName = NewSourceFileGenerator.generateSourceFileNameFromClass(className);
}
}
fHeaderFileDialogField.setTextWithoutUpdate(headerName);
fSourceFileDialogField.setTextWithoutUpdate(sourceName);
}
private final class BaseClassesFieldAdapter implements IListAdapter {
public void customButtonPressed(ListDialogField field, int index) {
if (index == 0) {
@ -750,12 +793,12 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
private class FileGroupFieldAdapter implements IStringButtonAdapter, IDialogFieldListener {
public void changeControlPressed(DialogField field) {
if (field == fHeaderFileDialogField) {
IPath filePath = chooseSourceFile(getHeaderFilePath(), NewClassWizardMessages.getString("NewClassCreationWizardPage.ChooseHeaderFileDialog.title")); //$NON-NLS-1$
IPath filePath = chooseSourceFile(getHeaderFileFullPath(), NewClassWizardMessages.getString("NewClassCreationWizardPage.ChooseHeaderFileDialog.title")); //$NON-NLS-1$
if (filePath != null) {
setHeaderFile(filePath, true);
}
} else if (field == fSourceFileDialogField) {
IPath filePath = chooseSourceFile(getSourceFilePath(), NewClassWizardMessages.getString("NewClassCreationWizardPage.ChooseSourceFileDialog.title")); //$NON-NLS-1$
IPath filePath = chooseSourceFile(getSourceFileFullPath(), NewClassWizardMessages.getString("NewClassCreationWizardPage.ChooseSourceFileDialog.title")); //$NON-NLS-1$
if (filePath != null) {
setSourceFile(filePath, true);
}
@ -767,6 +810,9 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
boolean enabled = !isUseDefaultSelected();
fHeaderFileDialogField.setEnabled(enabled);
fSourceFileDialogField.setEnabled(enabled);
if (!enabled) {
updateFilesFromClassName(fClassNameDialogField.getText());
}
}
fHeaderFileStatus = headerFileChanged();
fSourceFileStatus = sourceFileChanged();
@ -861,12 +907,6 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
IProject project = getCurrentProject();
if (project != null) {
ITypeSearchScope scope = prepareTypeCache();
if (scope == null) {
status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.noTypeCache")); //$NON-NLS-1$
return status;
}
IQualifiedTypeName qualName = new QualifiedTypeName(namespace);
ITypeInfo[] types = AllTypesCache.getTypes(project, qualName, false);
@ -921,12 +961,6 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
IProject project = getCurrentProject();
if (project != null) {
ITypeSearchScope scope = prepareTypeCache();
if (scope == null) {
status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.noTypeCache")); //$NON-NLS-1$
return status;
}
IQualifiedTypeName qualName = new QualifiedTypeName(enclosing);
ITypeInfo[] types = AllTypesCache.getTypes(project, qualName, false);
@ -992,12 +1026,6 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
IProject project = getCurrentProject();
if (project != null) {
ITypeSearchScope scope = prepareTypeCache();
if (scope == null) {
status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.noTypeCache")); //$NON-NLS-1$
return status;
}
IQualifiedTypeName qualName = new QualifiedTypeName(className);
// must not exist
@ -1058,19 +1086,23 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
*/
protected IStatus baseClassesChanged() {
StatusInfo status = new StatusInfo();
IProject project = getCurrentProject();
if (project != null) {
// make sure all classes belong to the project
IBaseClassInfo[] baseClasses = getBaseClasses();
for (int i = 0; i < baseClasses.length; ++i) {
ITypeInfo baseType = baseClasses[i].getType();
IProject baseProject = baseType.getEnclosingProject();
if (baseProject != null && !baseProject.equals(project)) {
status.setError(NewClassWizardMessages.getFormattedString("NewClassCreationWizardPage.error.BaseClassNotExistsInProject", baseType.getQualifiedTypeName().toString())); //$NON-NLS-1$
return status;
}
}
if (!fCreateIncludePathsAsNeeded && fWarnIfBaseClassNotInPath) {
// make sure all classes belong to the project
IBaseClassInfo[] baseClasses = getBaseClasses();
for (int i = 0; i < baseClasses.length; ++i) {
ITypeInfo baseType = baseClasses[i].getType();
IProject baseProject = baseType.getEnclosingProject();
if (baseProject == null || !baseProject.equals(project)) {
ITypeReference ref = baseType.getResolvedReference();
if (ref == null || PathUtil.makeRelativePathToProjectIncludes(ref.getLocation(), project) == null) {
status.setWarning(NewClassWizardMessages.getFormattedString("NewClassCreationWizardPage.warning.BaseClassNotExistsInProject", baseType.getQualifiedTypeName().toString())); //$NON-NLS-1$
return status;
}
}
}
}
}
return status;
}
@ -1112,7 +1144,7 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
return status;
}
IPath path = getHeaderFilePath();
IPath path = getHeaderFileFullPath();
IResource res = fWorkspaceRoot.findMember(path);
if (res != null && res.exists()) {
int resType = res.getType();
@ -1154,7 +1186,6 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
protected IStatus sourceFileChanged() {
StatusInfo status = new StatusInfo();
fCurrentSourceFile = null;
String str = getSourceFileName();
if (str.length() == 0) {
status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.EnterSourceFileName")); //$NON-NLS-1$
@ -1167,24 +1198,29 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
return status;
}
IPath path = getSourceFilePath();
IResource res = fWorkspaceRoot.findMember(path);
if (res != null && res.exists()) {
int resType = res.getType();
if (resType == IResource.FILE) {
IProject proj = res.getProject();
if (!proj.isOpen()) {
IPath path = getSourceFileFullPath();
if (path == null)
return status;
if (path.toFile().exists()) {
IResource res = fWorkspaceRoot.findMember(path);
if (res != null && res.exists()) {
int resType = res.getType();
if (resType == IResource.FILE) {
IProject proj = res.getProject();
if (!proj.isOpen()) {
status.setError(NewClassWizardMessages.getFormattedString("NewClassCreationWizardPage.error.NotAFile", str)); //$NON-NLS-1$
return status;
}
if (!CoreModel.hasCCNature(proj) && !CoreModel.hasCNature(proj)) {
status.setWarning(NewClassWizardMessages.getString("NewClassCreationWizardPage.warning.NotInACProject")); //$NON-NLS-1$
} else {
status.setWarning(NewClassWizardMessages.getString("NewClassCreationWizardPage.warning.SourceFileExists")); //$NON-NLS-1$
}
} else {
status.setError(NewClassWizardMessages.getFormattedString("NewClassCreationWizardPage.error.NotAFile", str)); //$NON-NLS-1$
return status;
}
if (!CoreModel.hasCCNature(proj) && !CoreModel.hasCNature(proj)) {
status.setWarning(NewClassWizardMessages.getString("NewClassCreationWizardPage.warning.NotInACProject")); //$NON-NLS-1$
} else {
status.setWarning(NewClassWizardMessages.getString("NewClassCreationWizardPage.warning.SourceFileExists")); //$NON-NLS-1$
}
} else {
status.setError(NewClassWizardMessages.getFormattedString("NewClassCreationWizardPage.error.NotAFile", str)); //$NON-NLS-1$
return status;
}
} else {
IStatus val = validateSourceFileName(project, path.lastSegment());
@ -1328,6 +1364,13 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
return fSourceFolderDialogField.getText();
}
public IPath getSourceFolderFullPath() {
if (fCurrentSourceFolder != null) {
return fCurrentSourceFolder.getPath();
}
return null;
}
/**
* Returns the namespace entered into the namespace input field.
*
@ -1409,14 +1452,16 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
return fHeaderFileDialogField.getText();
}
public IPath getHeaderFilePath() {
public IPath getHeaderFileFullPath() {
String name = getHeaderFileName();
if (name.length() > 0) {
IPath headerPath = new Path(name);
if (headerPath.isAbsolute()) {
return headerPath;
} else if (fCurrentSourceFolder != null) {
return fCurrentSourceFolder.getPath().append(headerPath);
IPath path = new Path(name);
if (path.isAbsolute()) {
return path;
} else {
IPath folderPath = getSourceFolderFullPath();
if (folderPath != null)
return folderPath.append(path);
}
}
return null;
@ -1431,14 +1476,16 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
return fSourceFileDialogField.getText();
}
public IPath getSourceFilePath() {
public IPath getSourceFileFullPath() {
String name = getSourceFileName();
if (name.length() > 0) {
IPath headerPath = new Path(name);
if (headerPath.isAbsolute()) {
return headerPath;
} else if (fCurrentSourceFolder != null) {
return fCurrentSourceFolder.getPath().append(headerPath);
IPath path = new Path(name);
if (path.isAbsolute()) {
return path;
} else {
IPath folderPath = getSourceFolderFullPath();
if (folderPath != null)
return folderPath.append(path);
}
}
return null;
@ -1466,6 +1513,7 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
public void setVisible(boolean visible) {
super.setVisible(visible);
if (visible) {
prepareTypeCache();
setFocus();
}
}
@ -1503,7 +1551,6 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
}
}
if (!classExists) {
prepareTypeCache();
// resolve location of base class
if (newBaseClass.getResolvedReference() == null) {
final ITypeInfo[] typesToResolve = new ITypeInfo[] { newBaseClass };
@ -1536,14 +1583,8 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
fMethodStubsDialogField.addMethodStub(methodStub, checked);
}
ITypeSearchScope prepareTypeCache() {
IProject project = getCurrentProject();
if (project == null)
return null;
final ITypeSearchScope scope = new TypeSearchScope();
scope.add(project);
void prepareTypeCache() {
final ITypeSearchScope scope = new TypeSearchScope(true);
if (!AllTypesCache.isCacheUpToDate(scope)) {
IRunnableWithProgress runnable = new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
@ -1560,13 +1601,10 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
String title = NewClassWizardMessages.getString("NewClassCreationWizardPage.getClasses.exception.title"); //$NON-NLS-1$
String message = NewClassWizardMessages.getString("NewClassCreationWizardPage.getClasses.exception.message"); //$NON-NLS-1$
ExceptionHandler.handle(e, title, message);
return null;
} catch (InterruptedException e) {
// cancelled by user
return null;
}
}
return scope;
}
/**
@ -1664,7 +1702,7 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
fCurrentHeaderFile = headerPath;
if (fCurrentSourceFolder != null) {
IPath sourcePath = fCurrentSourceFolder.getPath();
IPath relPath = NewClassCodeGenerator.makeRelativePath(headerPath, sourcePath);
IPath relPath = PathUtil.makeRelativePath(headerPath, sourcePath);
if (relPath != null)
headerPath = relPath;
}
@ -1681,12 +1719,18 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
* not be changed by the user. If <code>true</code> the field is editable
*/
public void setSourceFile(IPath sourcePath, boolean canBeModified) {
fCurrentSourceFile = sourcePath;
String pathString = ""; //$NON-NLS-1$
IPath folderPath = getSourceFolderFullPath();
if (folderPath != null) {
IPath relativePath = PathUtil.makeRelativePath(sourcePath, folderPath);
if (relativePath != null) {
}
}
if (fCurrentSourceFolder != null && fCurrentSourceFolder.getPath().isPrefixOf(sourcePath)) {
sourcePath = sourcePath.removeFirstSegments(fCurrentSourceFolder.getPath().segmentCount());
}
String str = (sourcePath == null) ? "" : sourcePath.makeRelative().toString(); //$NON-NLS-1$
fSourceFileDialogField.setText(str);
pathString = (sourcePath == null) ? "" : sourcePath.makeRelative().toString(); //$NON-NLS-1$
fSourceFileDialogField.setText(pathString);
fSourceFileDialogField.setEnabled(!isUseDefaultSelected() && canBeModified);
}
@ -1775,11 +1819,12 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
}
ITypeInfo chooseNamespace() {
ITypeSearchScope scope = prepareTypeCache();
if (scope == null)
IProject project = getCurrentProject();
if (project == null) {
return null;
}
ITypeInfo[] elements = AllTypesCache.getNamespaces(scope, false);
ITypeInfo[] elements = AllTypesCache.getNamespaces(new TypeSearchScope(project), false);
if (elements == null || elements.length == 0) {
String title = NewClassWizardMessages.getString("NewClassCreationWizardPage.getClasses.noclasses.title"); //$NON-NLS-1$
String message = NewClassWizardMessages.getString("NewClassCreationWizardPage.getClasses.noclasses.message"); //$NON-NLS-1$
@ -1827,11 +1872,12 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
private final int[] ENCLOSING_CLASS_TYPES = { ICElement.C_CLASS };
ITypeInfo chooseEnclosingClass() {
ITypeSearchScope scope = prepareTypeCache();
if (scope == null)
IProject project = getCurrentProject();
if (project == null) {
return null;
ITypeInfo[] elements = AllTypesCache.getTypes(scope, ENCLOSING_CLASS_TYPES);
}
ITypeInfo[] elements = AllTypesCache.getTypes(new TypeSearchScope(project), ENCLOSING_CLASS_TYPES);
if (elements == null || elements.length == 0) {
String title = NewClassWizardMessages.getString("NewClassCreationWizardPage.getClasses.noclasses.title"); //$NON-NLS-1$
String message = NewClassWizardMessages.getString("NewClassCreationWizardPage.getClasses.noclasses.message"); //$NON-NLS-1$
@ -1879,11 +1925,7 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
private final int[] CLASS_TYPES = { ICElement.C_CLASS, ICElement.C_STRUCT };
void chooseBaseClasses() {
ITypeSearchScope scope = prepareTypeCache();
if (scope == null)
return;
ITypeInfo[] elements = AllTypesCache.getTypes(scope, CLASS_TYPES);
ITypeInfo[] elements = AllTypesCache.getTypes(new TypeSearchScope(true), CLASS_TYPES);
if (elements == null || elements.length == 0) {
String title = NewClassWizardMessages.getString("NewClassCreationWizardPage.getClasses.noclasses.title"); //$NON-NLS-1$
String message = NewClassWizardMessages.getString("NewClassCreationWizardPage.getClasses.noclasses.message"); //$NON-NLS-1$
@ -1937,15 +1979,26 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
* @throws CoreException Thrown when the creation failed.
* @throws InterruptedException Thrown when the operation was cancelled.
*/
public void createClass(IProgressMonitor monitor) throws CoreException, InterruptedException {
fCodeGenerator = new NewClassCodeGenerator(
getHeaderFilePath(),
getSourceFilePath(),
getClassName(),
getNamespace(),
getBaseClasses(),
getCheckedMethodStubs());
fCodeGenerator.createClass(monitor);
public void createClass(IProgressMonitor monitor) {
try {
fCodeGenerator = new NewClassCodeGenerator(
getHeaderFileFullPath(),
getSourceFileFullPath(),
getClassName(),
getNamespace(),
getBaseClasses(),
getCheckedMethodStubs());
fCodeGenerator.createClass(monitor);
} catch (CodeGeneratorException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**

View file

@ -64,7 +64,7 @@ NewClassCreationWizardPage.warning.ClassNameDiscouraged=Class name is discourage
NewClassCreationWizardPage.baseClasses.label=&Base Classes:
NewClassCreationWizardPage.error.InvalidBaseClassName=Base class name is not valid. {0}
NewClassCreationWizardPage.error.BaseClassNotExistsInProject=Base class ''{0}'' does not exist in the current project.
NewClassCreationWizardPage.warning.BaseClassNotExistsInProject=Base class ''{0}'' not in include paths for current project.
NewClassCreationWizardPage.methodStubs.label=Method &Stubs:
@ -161,7 +161,11 @@ SourceFileSelectionDialog.error.NotASourceFile=''{0}'' is not a valid source fil
SourceFileSelectionDialog.warning.SourceFileExists=New class contents will be appended to existing file ''{0}''.
# -----------NewClassCodeGeneration -------------
NewClassCodeGeneration.createType.task=Creating type....
NewClassCodeGeneration.createType.mainTask=Creating type....
NewClassCodeGeneration.createType.task.header=Creating header file....
NewClassCodeGeneration.createType.task.header.includePaths=Adding include paths....
NewClassCodeGeneration.createType.task.header.addIncludePaths=Adding new include paths to project....
NewClassCodeGeneration.createType.task.source=Creating source file....
NewClassCodeGeneration.createFile.task=Creating
NewClassCodeGeneration.stub.constructor.name=Constructor
NewClassCodeGeneration.stub.destructor.name=Destructor

View file

@ -27,6 +27,7 @@ import org.eclipse.ui.dialogs.ContainerGenerator;
public class NewSourceFileGenerator {
//TODO these should all be configurable in prefs
private static final String HEADER_EXT = ".h"; //$NON-NLS-1$
private static final String SOURCE_EXT = ".cpp"; //$NON-NLS-1$
private static boolean fUseIncludeGuard = true;