diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/classwizard/NewClassWizardUtil.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/classwizard/NewClassWizardUtil.java index dc8b59c5ba5..de56d43510d 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/classwizard/NewClassWizardUtil.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/classwizard/NewClassWizardUtil.java @@ -12,12 +12,17 @@ package org.eclipse.cdt.internal.ui.wizards.classwizard; import java.util.ArrayList; import java.util.List; +import java.util.regex.Pattern; import org.eclipse.cdt.core.CCorePlugin; 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.TypeSearchScope; +import org.eclipse.cdt.core.dom.IPDOMManager; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ICContainer; @@ -26,6 +31,10 @@ import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ISourceRoot; import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfoProvider; +import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.cdt.internal.core.pdom.dom.cpp.PDOMCPPLinkage; import org.eclipse.cdt.internal.ui.editor.CEditor; import org.eclipse.cdt.internal.ui.viewsupport.IViewPartInputProvider; import org.eclipse.cdt.internal.ui.wizards.filewizard.NewSourceFileGenerator; @@ -35,6 +44,7 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; @@ -342,5 +352,102 @@ public class NewClassWizardUtil { } return false; } - + + public static final int SEARCH_MATCH_ERROR = -1; // some error, search failed + public static final int SEARCH_MATCH_NOTFOUND = 0; // no match found + public static final int SEARCH_MATCH_FOUND_EXACT = 1; // exact match + public static final int SEARCH_MATCH_FOUND_EXACT_ANOTHER_TYPE = 2; // same name found, by different type + public static final int SEARCH_MATCH_FOUND_ANOTHER_NAMESPACE = 3; // same type name exits in different scope + public static final int SEARCH_MATCH_FOUND_ANOTHER_TYPE = 4; // same name used by another type in different scope + + /** + * Search for the given qualified name of the give + * @param typeName qualified name of the type to search + * @param project + * @param pdomNodeType PDOMCPPLinkage type + * @return + */ + public static int searchForCppType(IQualifiedTypeName typeName, ICProject project, int pdomNodeType) { + if(project == null) { + return SEARCH_MATCH_ERROR; + } + + String fullyQualifiedTypeName = typeName.getFullyQualifiedName(); + + IPDOMManager pdomManager = CCorePlugin.getPDOMManager(); + try { + PDOM pdom = (PDOM)pdomManager.getPDOM(project); + IBinding[] bindings = pdom.findBindings(Pattern.compile(typeName.getName())); + boolean sameTypeNameExists = false; + boolean sameNameDifferentTypeExists = false; + + for (int i = 0; i < bindings.length; ++i) + { + PDOMBinding binding = (PDOMBinding)bindings[i]; + PDOMBinding pdomBinding = pdom.getLinkage(GPPLanguage.getDefault()).adaptBinding(binding); + + //get the fully qualified name of this binding + String bindingFullName = getBindingQualifiedName(pdomBinding); + + int currentNodeType = pdomBinding.getNodeType(); + // full binding + if (currentNodeType == pdomNodeType) + { + if (bindingFullName.equals(fullyQualifiedTypeName)) + { + return SEARCH_MATCH_FOUND_EXACT; + } else { + // same type , same name , but different name space + // see if there is an exact match; + sameTypeNameExists = true; + } + } + else if(currentNodeType == PDOMCPPLinkage.CPPCLASSTYPE || + currentNodeType == PDOMCPPLinkage.CPPENUMERATION || + currentNodeType == PDOMCPPLinkage.CPPNAMESPACE || + currentNodeType == PDOMCPPLinkage.CPPTYPEDEF || + currentNodeType == PDOMCPPLinkage.CPPBASICTYPE) + { + if (bindingFullName.equals(fullyQualifiedTypeName)) + { + return SEARCH_MATCH_FOUND_EXACT_ANOTHER_TYPE; + } else { + // different type , same name , but different name space + sameNameDifferentTypeExists = true; + } + } + } + if(sameTypeNameExists){ + return SEARCH_MATCH_FOUND_ANOTHER_NAMESPACE; + } + + if(sameNameDifferentTypeExists){ + return SEARCH_MATCH_FOUND_ANOTHER_TYPE; + } + } catch (CoreException e) { + return SEARCH_MATCH_ERROR; + } + return SEARCH_MATCH_NOTFOUND; + } + + /** + * Get the fully qualified name for a given PDOMBinding + * @param pdomBinding + * @return binding's fully qualified name + * @throws CoreException + */ + public static String getBindingQualifiedName(PDOMBinding pdomBinding) throws CoreException + { + StringBuffer buf = new StringBuffer(pdomBinding.getName()); + PDOMNode parent = pdomBinding.getParentNode(); + while (parent != null) + { + if (parent instanceof PDOMBinding) + { + buf.insert(0, ((PDOMBinding)parent).getName() + "::"); + } + parent = parent.getParentNode(); + } + return buf.toString(); + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/wizards/NewClassCreationWizardPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/wizards/NewClassCreationWizardPage.java index 9d47beec2aa..3b0080724ef 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/wizards/NewClassCreationWizardPage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/wizards/NewClassCreationWizardPage.java @@ -74,6 +74,7 @@ import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.cdt.internal.core.pdom.dom.cpp.PDOMCPPClassType; +import org.eclipse.cdt.internal.core.pdom.dom.cpp.PDOMCPPLinkage; import org.eclipse.cdt.internal.core.pdom.dom.cpp.PDOMCPPNamespace; import org.eclipse.cdt.internal.ui.dialogs.StatusInfo; @@ -1492,108 +1493,34 @@ public class NewClassCreationWizardPage extends NewElementWizardPage { IQualifiedTypeName typeName = new QualifiedTypeName(namespace); ICProject project = getCurrentProject(); + if (project != null) { - - List patternList = new ArrayList(); //for binding search - - if (typeName.isQualified()) { - /* make sure enclosing namespace exists */ - String[] enclosingNames = typeName.getEnclosingNames(); - - if (enclosingNames.length > 0) - { - //build the pattern list, for qualified enclosing names - for (int j = 0; j < enclosingNames.length; j++) - { - patternList.add(Pattern.compile(enclosingNames[j])); - } - Pattern[] patterns = (Pattern[])patternList.toArray(new Pattern[patternList.size()]); - - IPDOMManager pdomManager = CCorePlugin.getPDOMManager(); - boolean found = false; - try { - PDOM pdom = (PDOM)pdomManager.getPDOM(project); - IBinding[] bindings = pdom.findBindings(patterns); - - //go through the list of bindings found and check if the fully qualified name of each binding - //matches the enclosing name - for (int i = 0; i < bindings.length; ++i) { - PDOMBinding binding = (PDOMBinding)bindings[i]; - PDOMBinding pdomBinding = pdom.getLinkage(GPPLanguage.getDefault()).adaptBinding(binding); - - //get the fully qualified name of the binding - String fullyQualifiedName = getBindingQualifiedName(pdomBinding); - if (pdomBinding instanceof PDOMCPPNamespace) - { - if (fullyQualifiedName.equals(new QualifiedTypeName(enclosingNames).getFullyQualifiedName())) - { - found = true; - break; - } - } - } - - if (!found) - { - status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.EnclosingNamespaceNotExists")); //$NON-NLS-1$ - return status; - } - - } catch (CoreException e) { - return e.getStatus(); - } - } - } - - //look for namespace - IPDOMManager pdomManager = CCorePlugin.getPDOMManager(); - try { - PDOM pdom = (PDOM)pdomManager.getPDOM(project); - //add the namespace name to the list of patterns - patternList.add(Pattern.compile(typeName.getName())); - Pattern[] patterns = (Pattern[])patternList.toArray(new Pattern[patternList.size()]); - IBinding[] bindings = pdom.findBindings(patterns); - - for (int i = 0; i < bindings.length; ++i) { - PDOMBinding binding = (PDOMBinding)bindings[i]; - PDOMBinding pdomBinding = pdom.getLinkage(GPPLanguage.getDefault()).adaptBinding(binding); - - //get the fully qualified name of this binding - String bindingFullName = getBindingQualifiedName(pdomBinding); - - if (pdomBinding instanceof PDOMCPPNamespace) - { - if (bindingFullName.equals(namespace)) - { - status.setOK(); //found an exact match - } - else - { - status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.NamespaceExistsDifferentCase")); //$NON-NLS-1$ - } - return status; - } - else //a binding is found but it is not a namespace - { - if (bindingFullName.equals(namespace)) - { - status.setWarning(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.TypeMatchingNamespaceExists")); //$NON-NLS-1$ - } - else - { - status.setWarning(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.TypeMatchingNamespaceExistsDifferentCase")); //$NON-NLS-1$ - } - return status; - } + /* search for parent name space first */ + int searchResult; + if (typeName.isQualified()) { + searchResult = NewClassWizardUtil.searchForCppType(typeName.getEnclosingTypeName(),project, PDOMCPPLinkage.CPPNAMESPACE); + if (searchResult != NewClassWizardUtil.SEARCH_MATCH_FOUND_EXACT) { + status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.EnclosingNamespaceNotExists")); //$NON-NLS-1$ + return status; } - - if (bindings.length == 0) - { - //no namespaces found with the specified name - status.setWarning(NewClassWizardMessages.getString("NewClassCreationWizardPage.warning.NamespaceNotExists")); //$NON-NLS-1$ - } - } catch (CoreException e) { - return e.getStatus(); + } + searchResult = NewClassWizardUtil.searchForCppType(typeName, project, PDOMCPPLinkage.CPPNAMESPACE); + switch(searchResult) { + case NewClassWizardUtil.SEARCH_MATCH_FOUND_EXACT: + status.setOK(); + return status; + case NewClassWizardUtil.SEARCH_MATCH_FOUND_EXACT_ANOTHER_TYPE: + status.setWarning(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.TypeMatchingNamespaceExists")); //$NON-NLS-1$ + return status; + case NewClassWizardUtil.SEARCH_MATCH_FOUND_ANOTHER_NAMESPACE: + status.setWarning(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.NamespaceExistsDifferentCase")); //$NON-NLS-1$ + return status; + case NewClassWizardUtil.SEARCH_MATCH_FOUND_ANOTHER_TYPE: + status.setWarning(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.TypeMatchingNamespaceExistsDifferentCase")); //$NON-NLS-1$ + return status; + case NewClassWizardUtil.SEARCH_MATCH_NOTFOUND: + status.setWarning(NewClassWizardMessages.getString("NewClassCreationWizardPage.warning.NamespaceNotExists")); //$NON-NLS-1$ + break; } } @@ -1605,27 +1532,6 @@ public class NewClassCreationWizardPage extends NewElementWizardPage { return status; } - /** - * Get the fully qualified name for a given PDOMBinding - * @param pdomBinding - * @return binding's fully qualified name - * @throws CoreException - */ - private String getBindingQualifiedName(PDOMBinding pdomBinding) throws CoreException - { - StringBuffer buf = new StringBuffer(pdomBinding.getName()); - PDOMNode parent = pdomBinding.getParentNode(); - while (parent != null) - { - if (parent instanceof PDOMBinding) - { - buf.insert(0, ((PDOMBinding)parent).getName() + "::"); //$NON-NLS-1$ - } - parent = parent.getParentNode(); - } - return buf.toString(); - } - /** * Hook method that gets called when the class name has changed. The method validates the * class name and returns the status of the validation. @@ -1667,53 +1573,23 @@ public class NewClassCreationWizardPage extends NewElementWizardPage { fullyQualifiedName = new QualifiedTypeName(namespace).append(typeName); } } - - String fullyQualifiedClassName = fullyQualifiedName.getFullyQualifiedName(); - - //build the pattern list, for qualified enclosing names - String[] enclosingNames = fullyQualifiedName.getEnclosingNames(); - List patternList = new ArrayList(); - for (int j = 0; j < enclosingNames.length; j++) - { - patternList.add(Pattern.compile(enclosingNames[j])); - } - //add class name to pattern - patternList.add(Pattern.compile(className)); - Pattern[] patterns = (Pattern[])patternList.toArray(new Pattern[patternList.size()]); - - //look for conflicting class/struct - IPDOMManager pdomManager = CCorePlugin.getPDOMManager(); - try { - PDOM pdom = (PDOM)pdomManager.getPDOM(project); - IBinding[] bindings = pdom.findBindings(patterns); - for (int i = 0; i < bindings.length; ++i) - { - PDOMBinding binding = (PDOMBinding)bindings[i]; - PDOMBinding pdomBinding = pdom.getLinkage(GPPLanguage.getDefault()).adaptBinding(binding); - - //get the fully qualified name of this binding - String bindingFullName = getBindingQualifiedName(pdomBinding); - - if (pdomBinding instanceof PDOMCPPClassType) - { - if (bindingFullName.equals(fullyQualifiedClassName)) - { - status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.ClassNameExists")); //$NON-NLS-1$ - } - return status; - } - else //a binding is found but it is not a class/struct - { - if (bindingFullName.equals(fullyQualifiedClassName)) - { - status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.TypeMatchingClassExists")); //$NON-NLS-1$ - } - return status; - } - } - } catch (CoreException e) { - return e.getStatus(); - } + int searchResult = NewClassWizardUtil.searchForCppType(fullyQualifiedName, project,PDOMCPPLinkage.CPPCLASSTYPE); + switch(searchResult) { + case NewClassWizardUtil.SEARCH_MATCH_FOUND_EXACT: + status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.ClassNameExists")); //$NON-NLS-1$ + return status; + case NewClassWizardUtil.SEARCH_MATCH_FOUND_EXACT_ANOTHER_TYPE: + status.setError(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.TypeMatchingClassExists")); //$NON-NLS-1$ + return status; + case NewClassWizardUtil.SEARCH_MATCH_FOUND_ANOTHER_NAMESPACE: + status.setWarning(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.ClassNameExistsDifferentCase")); //$NON-NLS-1$ + return status; + case NewClassWizardUtil.SEARCH_MATCH_FOUND_ANOTHER_TYPE: + status.setWarning(NewClassWizardMessages.getString("NewClassCreationWizardPage.error.TypeMatchingClassExistsDifferentCase")); //$NON-NLS-1$ + return status; + case NewClassWizardUtil.SEARCH_MATCH_NOTFOUND: + break; + } } return status; }