diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/PathUtil.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/PathUtil.java index 59f5b5cb674..aa704660836 100644 --- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/PathUtil.java +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/PathUtil.java @@ -108,26 +108,28 @@ public class PathUtil { 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 makeRelativePathToIncludes(fullPath, info.getIncludePaths()); } } return null; } + public static IPath makeRelativePathToIncludes(IPath fullPath, String[] includePaths) { + 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; + } + } + } + return relativePath; + } + public static IProject getEnclosingProject(IPath fullPath) { IWorkspaceRoot root = getWorkspaceRoot(); if (root != null) { diff --git a/core/org.eclipse.cdt.ui/ChangeLog b/core/org.eclipse.cdt.ui/ChangeLog index 90230985bda..8c1a78d7c34 100644 --- a/core/org.eclipse.cdt.ui/ChangeLog +++ b/core/org.eclipse.cdt.ui/ChangeLog @@ -1,3 +1,9 @@ +2004-09-09 Chris Wiebe + + limit base class selection to referenced projects + * src/org/eclipse/cdt/internal/ui/wizards/classwizard/NewClassCreationWizardPage.java + * src/org/eclipse/cdt/internal/ui/wizards/classwizard/NewClassWizardMessages.properties + 2004-09-08 Alain Magloire Fix For PR 73459 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 f7d5dbb0ea7..c2ea703d735 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 @@ -12,10 +12,12 @@ package org.eclipse.cdt.internal.ui.wizards.classwizard; import java.io.File; import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.cdt.core.CConventions; +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; @@ -32,6 +34,8 @@ import org.eclipse.cdt.core.model.ICElement; 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.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.cdt.internal.ui.dialogs.StatusInfo; @@ -133,7 +137,7 @@ public class NewClassCreationWizardPage extends NewElementWizardPage { private NewClassCodeGenerator fCodeGenerator = null; //TODO this should be a prefs option - private boolean fWarnIfBaseClassNotInPath = false; + private boolean fErrorIfBaseClassNotInPath = true; public NewClassCreationWizardPage() { super(PAGE_NAME); @@ -1220,27 +1224,59 @@ public class NewClassCreationWizardPage extends NewElementWizardPage { */ protected IStatus baseClassesChanged() { StatusInfo status = new StatusInfo(); - IProject project = getCurrentProject(); - if (project != null) { - if (fWarnIfBaseClassNotInPath) { + if (fErrorIfBaseClassNotInPath) { + IPath folderPath = getSourceFolderFullPath(); + if (folderPath != 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)) { - 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; + if (baseClasses != null && baseClasses.length > 0) { + // filter out classes not reachable from current source folder + IProject project = PathUtil.getEnclosingProject(folderPath); + IScannerInfoProvider provider = CCorePlugin.getDefault().getScannerInfoProvider(project); + if (provider != null) { + //TODO get the scanner info for the actual source folder + IScannerInfo info = provider.getScannerInformation(project); + if (info != null) { + String[] includePaths = info.getIncludePaths(); + for (int i = 0; i < baseClasses.length; ++i) { + ITypeInfo baseType = baseClasses[i].getType(); + if (!isTypeReachable(baseType, project, includePaths)) { + status.setError(NewClassWizardMessages.getFormattedString("NewClassCreationWizardPage.error.BaseClassNotExistsInProject", baseType.getQualifiedTypeName().toString())); //$NON-NLS-1$ + return status; + } + } } } - } + } } } return status; } + private boolean isTypeReachable(ITypeInfo type, IProject project, String[] includePaths) { + IProject baseProject = type.getEnclosingProject(); + if (baseProject != null) { + if (baseProject.equals(project)) { + return true; + } else { + ITypeReference ref = type.getResolvedReference(); + for (int i = 0; i < includePaths.length; ++i) { + IPath includePath = new Path(includePaths[i]); + if (ref != null) { + if (includePath.isPrefixOf(ref.getLocation())) + return true; + } else { + // we don't have the real location, so just check the project path + if (baseProject.getLocation().isPrefixOf(includePath)) + return true; + } + } + } + } + return false; + } + + /** * This method is a hook which gets called after the method stubs * input field has changed. This default implementation updates @@ -2074,12 +2110,10 @@ public class NewClassCreationWizardPage extends NewElementWizardPage { return null; } - private final int[] CLASS_TYPES = { ICElement.C_CLASS, ICElement.C_STRUCT }; - void chooseBaseClasses() { prepareTypeCache(); - ITypeInfo[] elements = AllTypesCache.getTypes(new TypeSearchScope(true), CLASS_TYPES); + ITypeInfo[] elements = getAllReachableTypes(); 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$ @@ -2101,6 +2135,36 @@ public class NewClassCreationWizardPage extends NewElementWizardPage { fBaseClassesDialogField.setElements(oldContents); } } + + private final int[] CLASS_TYPES = { ICElement.C_CLASS, ICElement.C_STRUCT }; + + private ITypeInfo[] getAllReachableTypes() { + ITypeInfo[] elements = AllTypesCache.getTypes(new TypeSearchScope(true), CLASS_TYPES); + if (elements != null && elements.length > 0) { + // filter out classes not reachable from current source folder + IPath folderPath = getSourceFolderFullPath(); + if (folderPath != null) { + IProject project = PathUtil.getEnclosingProject(folderPath); + IScannerInfoProvider provider = CCorePlugin.getDefault().getScannerInfoProvider(project); + if (provider != null) { + //TODO get the scanner info for the actual source folder + IScannerInfo info = provider.getScannerInformation(project); + if (info != null) { + String[] includePaths = info.getIncludePaths(); + List filteredTypes = new ArrayList(); + for (int i = 0; i < elements.length; ++i) { + ITypeInfo baseType = elements[i]; + if (isTypeReachable(baseType, project, includePaths)) { + filteredTypes.add(baseType); + } + } + return (ITypeInfo[]) filteredTypes.toArray(new ITypeInfo[filteredTypes.size()]); + } + } + } + } + return elements; + } IPath chooseHeaderFile() { SourceFileSelectionDialog dialog = new SourceFileSelectionDialog(getShell()); 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 f1609e6c9c1..e171e303fbf 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 @@ -71,7 +71,7 @@ NewClassCreationWizardPage.warning.ClassNameDiscouraged=Class name is discourage NewClassCreationWizardPage.baseClasses.label=&Base Classes: NewClassCreationWizardPage.error.InvalidBaseClassName=Base class name is not valid. {0}. -NewClassCreationWizardPage.warning.BaseClassNotExistsInProject=Base class ''{0}'' not in include paths for current project. +NewClassCreationWizardPage.error.BaseClassNotExistsInProject=Base class ''{0}'' not in include paths for current project. NewClassCreationWizardPage.methodStubs.label=Method &Stubs: