From bc76b0a7c3bfa9dbd80a2a9b07c6c8577a199a04 Mon Sep 17 00:00:00 2001 From: Marc-Andre Laperle Date: Fri, 9 Oct 2020 22:20:29 -0400 Subject: [PATCH] Bug 567778 - [Include Browser] Cannot open the Include Browser on file outside source folder CoreModelUtil.findTranslationUnit only returns CElement in the populated CModel of a project. This shouldn't change as a large majority of client code need to see the model this way and not consider files that are outside source folders. So for a file not under a source folder (and therefore not in the CModel), we can just create a new translation unit instance for it. This is actually how the editor deals with it too. Change-Id: I8898822e94cac8562edcc0a726fdd8680119faca Signed-off-by: Marc-Andre Laperle --- .../BasicIncludeBrowserTest.java | 38 +++++++++++++++++++ .../IncludeBrowserBaseTest.java | 10 +++-- .../ui/includebrowser/IBConversions.java | 27 ++++++++++++- .../includebrowser/IBDropTargetListener.java | 14 +++---- 4 files changed, 76 insertions(+), 13 deletions(-) diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/includebrowser/BasicIncludeBrowserTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/includebrowser/BasicIncludeBrowserTest.java index 231a76af2db..f21ca23eaf7 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/includebrowser/BasicIncludeBrowserTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/includebrowser/BasicIncludeBrowserTest.java @@ -16,7 +16,10 @@ package org.eclipse.cdt.ui.tests.includebrowser; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.IPDOMManager; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICContainer; import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.IPathEntry; import org.eclipse.cdt.core.testplugin.CProjectHelper; import org.eclipse.cdt.core.testplugin.TestScannerProvider; import org.eclipse.core.resources.IFile; @@ -104,4 +107,39 @@ public class BasicIncludeBrowserTest extends IncludeBrowserBaseTest { CProjectHelper.delete(op); } } + + // // source + // #include "user.h" + public void testInclusionOutsideSourceFolder() throws Exception { + ICProject cproject = CProjectHelper.createCCProject("__ibTest_outside_src__", "bin", + IPDOMManager.ID_FAST_INDEXER); + try { + ICContainer srcFolder = CProjectHelper.addCContainer(cproject, "src"); + IPathEntry newEntry = CoreModel.newSourceEntry(srcFolder.getPath()); + + IPathEntry[] entries = new IPathEntry[] { CoreModel.newSourceEntry(srcFolder.getPath()) }; + cproject.setRawPathEntries(entries, null); + + StringBuilder[] contents = getContentsForTest(1); + IProject project = cproject.getProject(); + IFile user = createFile(project, "user.h", ""); + IFile source = createFile(srcFolder.getResource(), "source.cpp", contents[0].toString()); + CCorePlugin.getIndexManager().reindex(cproject); + waitForIndexer(cproject); + + openIncludeBrowser(source); + Tree tree = getIBTree(); + TreeItem node = checkTreeNode(tree, 0, "source.cpp"); + checkTreeNode(tree, 0, 0, "user.h"); + assertEquals(1, node.getItemCount()); + + // The tree has to be reversed + openIncludeBrowser(user, true); + checkTreeNode(tree, 0, "user.h"); + checkTreeNode(tree, 0, 0, "source.cpp"); + + } finally { + CProjectHelper.delete(cproject); + } + } } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/includebrowser/IncludeBrowserBaseTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/includebrowser/IncludeBrowserBaseTest.java index 62594194730..e8a7dc243e0 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/includebrowser/IncludeBrowserBaseTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/includebrowser/IncludeBrowserBaseTest.java @@ -13,13 +13,15 @@ *******************************************************************************/ package org.eclipse.cdt.ui.tests.includebrowser; +import java.util.Optional; + import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.IPDOMManager; import org.eclipse.cdt.core.index.IIndex; -import org.eclipse.cdt.core.model.CoreModelUtil; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.testplugin.CProjectHelper; +import org.eclipse.cdt.internal.ui.includebrowser.IBConversions; import org.eclipse.cdt.internal.ui.includebrowser.IBViewPart; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.tests.BaseUITestCase; @@ -77,13 +79,13 @@ public abstract class IncludeBrowserBaseTest extends BaseUITestCase { } private IBViewPart doOpenIncludeBrowser(IFile file) throws PartInitException { - ITranslationUnit tu = CoreModelUtil.findTranslationUnit(file); - if (tu == null) { + Optional tu = IBConversions.fileToTU(file); + if (tu.isEmpty()) { fail(file.getFullPath().toString() + " is no translation unit!"); } IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); IBViewPart result = (IBViewPart) page.showView(CUIPlugin.ID_INCLUDE_BROWSER); - result.setInput(tu); + result.setInput(tu.get()); return result; } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBConversions.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBConversions.java index c5db6d3a0d2..b0d75d1ae82 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBConversions.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBConversions.java @@ -15,10 +15,14 @@ package org.eclipse.cdt.internal.ui.includebrowser; import java.util.ArrayList; import java.util.Iterator; +import java.util.Optional; import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.CoreModelUtil; +import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.internal.core.model.TranslationUnit; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IAdaptable; @@ -75,12 +79,31 @@ public class IBConversions { return StructuredSelection.EMPTY; } + /** + * Returns an optional ITranslationUnit for the given IFile. + * The ITranslationUnit can be outside a source folder. + */ + public static Optional fileToTU(IFile file) { + ITranslationUnit tu = CoreModelUtil.findTranslationUnit(file); + if (tu == null) { + // Handle header not under a source folder + ICProject cproject = CoreModel.getDefault().create(file.getProject()); + if (cproject != null) { + String contentTypeId = CoreModel.getRegistedContentTypeId(file.getProject(), file.getName()); + if (contentTypeId != null) { + tu = new TranslationUnit(cproject, file, contentTypeId); + } + } + } + return Optional.ofNullable(tu); + } + public static ITranslationUnit objectToTU(Object object) { if (object instanceof ITranslationUnit) { return (ITranslationUnit) object; } if (object instanceof IFile) { - return CoreModelUtil.findTranslationUnit((IFile) object); + return fileToTU((IFile) object).orElse(null); } if (object instanceof IAdaptable) { IAdaptable adaptable = (IAdaptable) object; @@ -90,7 +113,7 @@ public class IBConversions { } IFile file = adaptable.getAdapter(IFile.class); if (file != null) { - return CoreModelUtil.findTranslationUnit(file); + return fileToTU(file).orElse(null); } ILocationProvider locProvider = adaptable.getAdapter(ILocationProvider.class); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBDropTargetListener.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBDropTargetListener.java index d816aa88af2..70e9bff0d4b 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBDropTargetListener.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBDropTargetListener.java @@ -15,8 +15,8 @@ package org.eclipse.cdt.internal.ui.includebrowser; import java.util.Iterator; +import java.util.Optional; -import org.eclipse.cdt.core.model.CoreModelUtil; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.internal.core.resources.ResourceLookup; import org.eclipse.core.resources.IFile; @@ -125,7 +125,7 @@ public class IBDropTargetListener implements DropTargetListener { String[] filePaths = (String[]) o; for (int i = 0; i < filePaths.length; i++) { String filePath = filePaths[i]; - ITranslationUnit tu = findTranslationUnit( + ITranslationUnit tu = extractFirstTranslationUnit( ResourceLookup.findFilesForLocation(Path.fromOSString(filePath))); if (tu != null) { return tu; @@ -134,18 +134,18 @@ public class IBDropTargetListener implements DropTargetListener { return null; } if (o instanceof IResource[]) { - return findTranslationUnit((IResource[]) o); + return extractFirstTranslationUnit((IResource[]) o); } return null; } - private ITranslationUnit findTranslationUnit(IResource[] files) { + private ITranslationUnit extractFirstTranslationUnit(IResource[] files) { for (int i = 0; i < files.length; i++) { IResource resource = files[i]; if (resource.getType() == IResource.FILE) { - ITranslationUnit tu = CoreModelUtil.findTranslationUnit((IFile) resource); - if (tu != null) { - return tu; + Optional tu = IBConversions.fileToTU((IFile) resource); + if (tu.isPresent()) { + return tu.get(); } } }