From ad9112a59be3d500c004cd5ffe1fa8b09232c077 Mon Sep 17 00:00:00 2001 From: Chris Wiebe Date: Sat, 14 Aug 2004 00:14:37 +0000 Subject: [PATCH] 2004-08-13 Chris Wiebe add namespace to new class wizard. * src/org/eclipse/cdt/internal/ui/wizards/classwizard/* --- core/org.eclipse.cdt.ui/ChangeLog | 9 +- core/org.eclipse.cdt.ui/plugin.xml | 2 - .../classwizard/ConstructorMethodStub.java | 5 +- .../classwizard/DestructorMethodStub.java | 5 +- .../classwizard/NewClassCodeGenerator.java | 129 +++++++----- .../NewClassCreationWizardPage.java | 197 ++++++++++++++---- .../NewClassWizardMessages.properties | 7 + 7 files changed, 263 insertions(+), 91 deletions(-) diff --git a/core/org.eclipse.cdt.ui/ChangeLog b/core/org.eclipse.cdt.ui/ChangeLog index cfaa3e065ad..f6810941ffe 100644 --- a/core/org.eclipse.cdt.ui/ChangeLog +++ b/core/org.eclipse.cdt.ui/ChangeLog @@ -1,10 +1,15 @@ -2004-08-012 Chris Wiebe +2004-08-13 Chris Wiebe + + add namespace to class wizard. + * src/org/eclipse/cdt/internal/ui/wizards/classwizard/* + +2004-08-12 Chris Wiebe Initial draft of new class wizard. * src/org/eclipse/cdt/ui/wizards/NewClassCreationWizard.java * src/org/eclipse/cdt/internal/ui/wizards/classwizard/* -2004-08-012 Chris Wiebe +2004-08-12 Chris Wiebe * src/org/eclipse/cdt/internal/ui/wizards/dialogsfields/ListDialogField.java * src/org/eclipse/cdt/internal/ui/wizards/dialogsfields/CheckedListDialogField.java diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index 5cf6ae54247..4fff28ba79c 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -324,7 +324,6 @@ %NewWizards.class.description - 0) { + addBaseClassIncludes(headerTU, text); + text.append(fLineDelimiter); + } + + if (fNamespace != null && fNamespace.length() > 0) { + beginNamespace(text); + } + text.append("class "); //$NON-NLS-1$ text.append(fClassName); - addBaseClassInheritance(text); text.append(fLineDelimiter); text.append('{'); + text.append(fLineDelimiter); //TODO sort methods (eg constructor always first?) List publicMethods = getStubs(ASTAccessVisibility.PUBLIC, false); @@ -188,6 +198,10 @@ public class NewClassCodeGenerator { text.append("};"); //$NON-NLS-1$ text.append(fLineDelimiter); + if (fNamespace != null && fNamespace.length() > 0) { + endNamespace(text); + } + if (oldContents != null && insertionPos != -1) { text.append(fLineDelimiter); text.append(oldContents.substring(insertionPos)); @@ -195,7 +209,7 @@ public class NewClassCodeGenerator { return text.toString(); } - + private int getInsertionPos(String contents) { //TODO temporary hack int insertPos = contents.lastIndexOf("#endif"); //$NON-NLS-1$ @@ -208,10 +222,24 @@ public class NewClassCodeGenerator { } return insertPos; } + + private void beginNamespace(StringBuffer text) { + text.append("namespace "); //$NON-NLS-1$ + text.append(fNamespace); + text.append(fLineDelimiter); + text.append('{'); + text.append(fLineDelimiter); + text.append(fLineDelimiter); + } + + private void endNamespace(StringBuffer text) { + text.append(fLineDelimiter); + text.append("};"); //$NON-NLS-1$ + text.append(fLineDelimiter); + } private void addMethodDeclarations(List publicMethods, List protectedMethods, List privateMethods, StringBuffer text) { if (!publicMethods.isEmpty()) { - text.append(fLineDelimiter); text.append("public:"); //$NON-NLS-1$ text.append(fLineDelimiter); for (Iterator i = publicMethods.iterator(); i.hasNext();) { @@ -224,7 +252,6 @@ public class NewClassCodeGenerator { } if (!protectedMethods.isEmpty()) { - text.append(fLineDelimiter); text.append("protected:"); //$NON-NLS-1$ text.append(fLineDelimiter); for (Iterator i = protectedMethods.iterator(); i.hasNext();) { @@ -237,7 +264,6 @@ public class NewClassCodeGenerator { } if (!privateMethods.isEmpty()) { - text.append(fLineDelimiter); text.append("private:"); //$NON-NLS-1$ text.append(fLineDelimiter); for (Iterator i = privateMethods.iterator(); i.hasNext();) { @@ -288,42 +314,39 @@ public class NewClassCodeGenerator { } private void addBaseClassIncludes(ITranslationUnit headerTU, StringBuffer text) { - if (fBaseClasses != null && fBaseClasses.length > 0) { - IProject project = headerTU.getCProject().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); + IProject project = headerTU.getCProject().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); } - text.append(fLineDelimiter); } } @@ -333,8 +356,9 @@ public class NewClassCodeGenerator { if (headerTU != null) { addHeaderInclude(sourceTU, headerTU, text); + text.append(fLineDelimiter); } - + //TODO sort methods (eg constructor always first?) List publicMethods = getStubs(ASTAccessVisibility.PUBLIC, true); List protectedMethods = getStubs(ASTAccessVisibility.PROTECTED, true); @@ -343,9 +367,17 @@ public class NewClassCodeGenerator { if (publicMethods.isEmpty() && protectedMethods.isEmpty() && privateMethods.isEmpty()) { - text.append(' '); + // no methods } else { + if (fNamespace != null && fNamespace.length() > 0) { + beginNamespace(text); + } + addMethodBodies(publicMethods, protectedMethods, privateMethods, text); + + if (fNamespace != null && fNamespace.length() > 0) { + endNamespace(text); + } } return text.toString(); @@ -378,9 +410,10 @@ public class NewClassCodeGenerator { for (Iterator i = publicMethods.iterator(); i.hasNext();) { IMethodStub stub = (IMethodStub) i.next(); String code = stub.createMethodImplementation(fClassName, fBaseClasses, fLineDelimiter); - text.append(fLineDelimiter); text.append(code); text.append(fLineDelimiter); + if (i.hasNext()) + text.append(fLineDelimiter); } } @@ -388,9 +421,10 @@ public class NewClassCodeGenerator { for (Iterator i = protectedMethods.iterator(); i.hasNext();) { IMethodStub stub = (IMethodStub) i.next(); String code = stub.createMethodImplementation(fClassName, fBaseClasses, fLineDelimiter); - text.append(fLineDelimiter); text.append(code); text.append(fLineDelimiter); + if (i.hasNext()) + text.append(fLineDelimiter); } } @@ -398,9 +432,10 @@ public class NewClassCodeGenerator { for (Iterator i = privateMethods.iterator(); i.hasNext();) { IMethodStub stub = (IMethodStub) i.next(); String code = stub.createMethodImplementation(fClassName, fBaseClasses, fLineDelimiter); - text.append(fLineDelimiter); text.append(code); text.append(fLineDelimiter); + if (i.hasNext()) + text.append(fLineDelimiter); } } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/classwizard/NewClassCreationWizardPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/classwizard/NewClassCreationWizardPage.java index 951f695f746..05f003d3751 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/classwizard/NewClassCreationWizardPage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/classwizard/NewClassCreationWizardPage.java @@ -101,6 +101,7 @@ public class NewClassCreationWizardPage extends NewElementWizardPage { StringButtonDialogField fNamespaceDialogField; private boolean fCanModifyNamespace; protected IStatus fNamespaceStatus; + ITypeInfo fCurrentNamespace; /** ID of the enclosing class input field. */ protected final static String ENCLOSING_CLASS = PAGE_NAME + ".enclosingclass"; //$NON-NLS-1$ @@ -590,6 +591,7 @@ public class NewClassCreationWizardPage extends NewElementWizardPage { public void changeControlPressed(DialogField field) { ITypeInfo namespace = chooseNamespace(); if (namespace != null) { + fCurrentNamespace = namespace; String name = namespace.getQualifiedTypeName().getFullyQualifiedName(); // this will trigger dialogFieldChanged @@ -641,9 +643,9 @@ public class NewClassCreationWizardPage extends NewElementWizardPage { boolean enclosing = isEnclosingClassSelected(); String name = ""; //$NON-NLS-1$ if (enclosing && fCurrentEnclosingClass != null) { - ITypeInfo namespace = fCurrentEnclosingClass.getEnclosingNamespace(); - if (namespace != null) { - IQualifiedTypeName qualNSName = namespace.getQualifiedTypeName(); + fCurrentNamespace = fCurrentEnclosingClass.getEnclosingNamespace(); + if (fCurrentNamespace != null) { + IQualifiedTypeName qualNSName = fCurrentNamespace.getQualifiedTypeName(); name = qualNSName.getFullyQualifiedName(); } } @@ -785,7 +787,54 @@ public class NewClassCreationWizardPage extends NewElementWizardPage { * @return the model's error status */ protected IStatus namespaceChanged() { - StatusInfo status = new StatusInfo(); + StatusInfo status = new StatusInfo(); + fCurrentNamespace = null; + + String namespace = getNamespace(); + + // check if empty + if (namespace.length() == 0) { + return status; + } + + IStatus val = CConventions.validateClassName(namespace); + if (val.getSeverity() == IStatus.ERROR) { + status.setError(NewClassWizardMessages.getFormattedString("NewClassCreationWizardPage.error.InvalidNamespace", val.getMessage())); //$NON-NLS-1$ + return status; + } else if (val.getSeverity() == IStatus.WARNING) { + status.setWarning(NewClassWizardMessages.getFormattedString("NewClassCreationWizardPage.warning.NamespaceDiscouraged", val.getMessage())); //$NON-NLS-1$ + // continue checking + } + + 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); + for (int i = 0; i < types.length; ++i) { + if (types[i].getCElementType() == ICElement.C_NAMESPACE) { + fCurrentNamespace = types[i]; + break; + } + } + if (fCurrentNamespace == null) { + types = AllTypesCache.getTypes(project, qualName, true); + for (int i = 0; i < types.length; ++i) { + if (types[i].getCElementType() == ICElement.C_NAMESPACE) { + status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.NamespaceExistsDifferentCase")); //$NON-NLS-1$ + return status; + } + } + status.setWarning(NewClassWizardMessages.getString("NewClassCreationWizardPage.warning.NamespaceNotExists")); //$NON-NLS-1$ + return status; + } + } return status; } @@ -802,7 +851,53 @@ public class NewClassCreationWizardPage extends NewElementWizardPage { if (!isEnclosingClassSelected()) { return status; } - //TODO check if enclosing class exists + fCurrentEnclosingClass = null; + + String enclosing = getEnclosingClass(); + // must not be empty + if (enclosing.length() == 0) { + status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.EnterClassName")); //$NON-NLS-1$ + return status; + } + + IStatus val = CConventions.validateClassName(enclosing); + if (val.getSeverity() == IStatus.ERROR) { + status.setError(NewClassWizardMessages.getFormattedString("NewClassCreationWizardPage.error.InvalidClassName", val.getMessage())); //$NON-NLS-1$ + return status; + } else if (val.getSeverity() == IStatus.WARNING) { + status.setWarning(NewClassWizardMessages.getFormattedString("NewClassCreationWizardPage.warning.ClassNameDiscouraged", val.getMessage())); //$NON-NLS-1$ + // continue checking + } + + 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); + for (int i = 0; i < types.length; ++i) { + if (types[i].getCElementType() == ICElement.C_CLASS) { + fCurrentEnclosingClass = types[i]; + break; + } + } + if (fCurrentEnclosingClass == null) { + types = AllTypesCache.getTypes(project, qualName, true); + for (int i = 0; i < types.length; ++i) { + if (types[i].getCElementType() == ICElement.C_CLASS) { + status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.ClassNameExistsDifferentCase")); //$NON-NLS-1$ + return status; + } + } + status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.ClassNameNotExists")); //$NON-NLS-1$ + return status; + } + } return status; } @@ -834,45 +929,56 @@ public class NewClassCreationWizardPage extends NewElementWizardPage { // continue checking } - IQualifiedTypeName qualName = new QualifiedTypeName(className); - // must not exist - if (!isEnclosingClassSelected()) { - IProject project = getCurrentProject(); - if (project == null) - return null; + IProject project = getCurrentProject(); + if (project != null) { ITypeSearchScope scope = prepareTypeCache(); - if (scope == null) - return null; - - ITypeInfo[] types = AllTypesCache.getTypes(project, qualName, false); - if (types.length != 0) { - status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.ClassNameExists")); //$NON-NLS-1$ + if (scope == null) { + status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.noTypeCache")); //$NON-NLS-1$ return status; } - types = AllTypesCache.getTypes(project, qualName, true); - if (types.length != 0) { - status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.ClassNameExistsDifferentCase")); //$NON-NLS-1$ - return status; - } - } else { - ITypeSearchScope scope = prepareTypeCache(); - if (scope == null) - return null; - - if (fCurrentEnclosingClass != null) { + + IQualifiedTypeName qualName = new QualifiedTypeName(className); + + // must not exist + if (!isEnclosingClassSelected()) { + if (fCurrentNamespace != null) { + ITypeInfo[] types = fCurrentNamespace.getEnclosedTypes(); + for (int i = 0; i < types.length; ++i) { + IQualifiedTypeName typeName = types[i].getQualifiedTypeName().removeFirstSegments(1); + if (typeName.equalsIgnoreCase(qualName)) { + if (typeName.equals(qualName)) + status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.ClassNameExists")); //$NON-NLS-1$ + else + status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.ClassNameExistsDifferentCase")); //$NON-NLS-1$ + return status; + } + } + } else { + ITypeInfo[] types = AllTypesCache.getTypes(project, qualName, false); + if (types.length != 0) { + status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.ClassNameExists")); //$NON-NLS-1$ + return status; + } + types = AllTypesCache.getTypes(project, qualName, true); + if (types.length != 0) { + status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.ClassNameExistsDifferentCase")); //$NON-NLS-1$ + return status; + } + } + } else if (fCurrentEnclosingClass != null) { ITypeInfo[] types = fCurrentEnclosingClass.getEnclosedTypes(); for (int i = 0; i < types.length; ++i) { - ITypeInfo type = types[i]; - if (type.getQualifiedTypeName().equalsIgnoreCase(qualName)) { - if (type.getQualifiedTypeName().equals(qualName)) + IQualifiedTypeName typeName = types[i].getQualifiedTypeName().removeFirstSegments(1); + if (typeName.equalsIgnoreCase(qualName)) { + if (typeName.equals(qualName)) status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.ClassNameExists")); //$NON-NLS-1$ else status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.ClassNameExistsDifferentCase")); //$NON-NLS-1$ return status; } } - } - } + } + } return status; } @@ -949,6 +1055,24 @@ public class NewClassCreationWizardPage extends NewElementWizardPage { return fSourceFolderDialogField.getText(); } + /** + * Returns the namespace entered into the namespace input field. + * + * @return the namespace + */ + public String getNamespace() { + return fNamespaceDialogField.getText(); + } + + /** + * Returns the enclosing class name entered into the enclosing class input field. + * + * @return the enclosing class name + */ + public String getEnclosingClass() { + return fEnclosingClassDialogField.getText(); + } + /** * Returns the selection state of the enclosing class checkbox. * @@ -959,9 +1083,9 @@ public class NewClassCreationWizardPage extends NewElementWizardPage { } /** - * Returns the type name entered into the type input field. + * Returns the class name entered into the class input field. * - * @return the type name + * @return the class name */ public String getClassName() { return fClassNameDialogField.getText(); @@ -1152,7 +1276,7 @@ public class NewClassCreationWizardPage extends NewElementWizardPage { * editable; otherwise it is read-only. */ public void setNamespace(ITypeInfo namespace, boolean canBeModified) { -// fCurrNamespace = namespace; + fCurrentNamespace = namespace; fCanModifyNamespace = canBeModified; if (namespace != null) { String name = namespace.getQualifiedTypeName().getFullyQualifiedName(); @@ -1404,6 +1528,7 @@ public class NewClassCreationWizardPage extends NewElementWizardPage { headerPath, sourcePath, getClassName(), + getNamespace(), getBaseClasses(), getCheckedMethodStubs()); fCodeGenerator.createClass(monitor); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/classwizard/NewClassWizardMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/classwizard/NewClassWizardMessages.properties index 63dd9098a1f..d0a697a8c49 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/classwizard/NewClassWizardMessages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/classwizard/NewClassWizardMessages.properties @@ -37,13 +37,20 @@ NewClassCreationWizardPage.warning.NotInACProject=Folder is not in a C/C++ proje NewClassCreationWizardPage.namespace.label=Namespace: NewClassCreationWizardPage.namespace.button=Bro&wse... +NewClassCreationWizardPage.warning.NamespaceNotExists=Namespace does not exist. A new namespace will be created. +NewClassCreationWizardPage.error.NamespaceExistsDifferentCase=Namespace with same name but different case exists. +NewClassCreationWizardPage.error.InvalidNamespace=Namespace is not valid. {0} +NewClassCreationWizardPage.warning.NamespaceDiscouraged=Namespace is discouraged. {0} NewClassCreationWizardPage.enclosingClass.label=&Enclosing Class: NewClassCreationWizardPage.enclosingClass.button=Br&owse... +NewClassCreationWizardPage.error.noTypeCache=Unable to access type cache. + NewClassCreationWizardPage.className.label=Class &Name: NewClassCreationWizardPage.error.EnterClassName=Class name is empty. NewClassCreationWizardPage.error.ClassNameExists=Class already exists. +NewClassCreationWizardPage.error.ClassNameNotExists=Class does not exist. NewClassCreationWizardPage.error.ClassNameExistsDifferentCase=Class with same name but different case exists. NewClassCreationWizardPage.error.InvalidClassName=Class name is not valid. {0} NewClassCreationWizardPage.error.QualifiedName=Class name must not be qualified.