diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/sourcelookup/AbsolutePathSourceContainer.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/sourcelookup/AbsolutePathSourceContainer.java index bad09e453cf..b0a562033fd 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/sourcelookup/AbsolutePathSourceContainer.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/sourcelookup/AbsolutePathSourceContainer.java @@ -20,7 +20,9 @@ import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.debug.core.CDebugCorePlugin; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.internal.core.model.ExternalTranslationUnit; +import org.eclipse.cdt.internal.core.resources.ResourceLookup; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; @@ -39,16 +41,20 @@ public class AbsolutePathSourceContainer extends AbstractSourceContainer { public static final String TYPE_ID = CDebugCorePlugin.getUniqueIdentifier() + ".containerType.absolutePath"; //$NON-NLS-1$ private Object[] findSourceElementByFile(File file) { - IFile[] wfiles = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(new Path(file.getAbsolutePath())); - if (wfiles.length > 0) + IFile[] wfiles = ResourceLookup.findFilesForLocation(new Path(file.getAbsolutePath())); + if (wfiles.length > 0) { + ResourceLookup.sortFilesByRelevance(wfiles, getProject()); return wfiles; + } try { // Check the canonical path as well to support case insensitive file // systems like Windows. - wfiles = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(new Path(file.getCanonicalPath())); - if (wfiles.length > 0) + wfiles = ResourceLookup.findFilesForLocation(new Path(file.getCanonicalPath())); + if (wfiles.length > 0) { + ResourceLookup.sortFilesByRelevance(wfiles, getProject()); return wfiles; + } // The file is not already in the workspace so try to create an external translation unit for it. ISourceLookupDirector director = getDirector(); @@ -77,6 +83,24 @@ public class AbsolutePathSourceContainer extends AbstractSourceContainer { return new LocalFileStorage[] { new LocalFileStorage(file) }; } + /** + * Find the project associated with the current launch configuration + * @return IProject or null + */ + private IProject getProject() { + ILaunchConfiguration config = getDirector().getLaunchConfiguration(); + if (config != null) { + try { + String name = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""); + if (name.length() > 0) + return ResourcesPlugin.getWorkspace().getRoot().getProject(name); + } catch (CoreException e) { + // Don't care carry on search using other heuristics + } + } + return null; + } + public boolean isValidAbsoluteFilePath( String name ) { return isValidAbsoluteFilePath( new File(name) ); diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/CSourceLookupParticipant.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/CSourceLookupParticipant.java index 76270d05625..cd51bc68b5e 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/CSourceLookupParticipant.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/CSourceLookupParticipant.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2006, 2007 QNX Software Systems and others. + * Copyright (c) 2004, 2008 QNX Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,20 +10,32 @@ * Ken Ryall (Nokia) - Added support for AbsoluteSourceContainer( 159833 ) * Ken Ryall (Nokia) - Added support for CSourceNotFoundElement ( 167305 ) * Ken Ryall (Nokia) - Option to open disassembly view when no source ( 81353 ) + * James Blackburn (Broadcom Corp.) - Linked Resources / Nested Projects ( 247948 ) *******************************************************************************/ package org.eclipse.cdt.debug.internal.core.sourcelookup; import java.io.File; +import org.eclipse.cdt.debug.core.cdi.ICDIBreakpointHit; +import org.eclipse.cdt.debug.core.model.ICDebugTarget; import org.eclipse.cdt.debug.core.model.ICStackFrame; import org.eclipse.cdt.debug.core.sourcelookup.AbsolutePathSourceContainer; import org.eclipse.cdt.debug.core.sourcelookup.ISourceLookupChangeListener; +import org.eclipse.cdt.debug.internal.core.CBreakpointManager; import org.eclipse.cdt.debug.internal.core.ListenerList; +import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.model.IBreakpoint; import org.eclipse.debug.core.model.IDebugElement; +import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupParticipant; +import org.eclipse.debug.core.sourcelookup.ISourceContainer; +import org.eclipse.debug.core.sourcelookup.ISourceContainerType; import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector; +import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant; +import org.eclipse.debug.core.sourcelookup.ISourcePathComputer; /** * A source lookup participant that searches for C/C++ source code. @@ -66,8 +78,14 @@ public class CSourceLookupParticipant extends AbstractSourceLookupParticipant { * @see org.eclipse.debug.core.sourcelookup.AbstractSourceLookupParticipant#findSourceElements(java.lang.Object) */ public Object[] findSourceElements( Object object ) throws CoreException { + + // Workaround for BUG247977 + // FIXME: Remove having switched to 3.5 platform + initContainersSourceDirector(); + // Workaround for cases when the stack frame doesn't contain the source file name String name = null; + IBreakpoint breakpoint = null; if ( object instanceof IAdaptable ) { ICStackFrame frame = (ICStackFrame)((IAdaptable)object).getAdapter( ICStackFrame.class ); if ( frame != null ) { @@ -80,11 +98,23 @@ public class CSourceLookupParticipant extends AbstractSourceLookupParticipant { return new Object[] { gfNoSource }; } } - } - else if ( object instanceof String ) { + // See if findSourceElements(...) is the result of a Breakpoint Hit Event + ICDebugTarget target = (ICDebugTarget)((IAdaptable)object).getAdapter( ICDebugTarget.class ); + if (target != null) { + CBreakpointManager bmanager = (CBreakpointManager)target.getAdapter(CBreakpointManager.class); + Object stateInfo = target.getCurrentStateInfo(); + if (bmanager != null && stateInfo instanceof ICDIBreakpointHit) { + breakpoint = bmanager.getBreakpoint(((ICDIBreakpointHit)stateInfo).getBreakpoint()); + } + } + } else if ( object instanceof String ) { name = (String)object; } - Object[] foundElements = super.findSourceElements( object ); + + // Actually query the source containers for the requested resource + Object[] foundElements = super.findSourceElements(object); + + // If none found, invoke the absolute path container directly if (foundElements.length == 0 && (object instanceof IDebugElement)) { // debugger could have resolved it itself and "name" is an absolute path if (new File(name).exists()) { @@ -93,9 +123,39 @@ public class CSourceLookupParticipant extends AbstractSourceLookupParticipant { foundElements = new Object[] { new CSourceNotFoundElement((IDebugElement) object) }; } } + + // Source lookup participant order is preserved where possible except for one case: + // - If we've stopped at a breakpoint the user has made on an IResource, we definitely want to show + // that IResource before others + if (breakpoint != null && breakpoint.getMarker() != null && breakpoint.getMarker().getResource() != null) { + IResource breakpointResource = breakpoint.getMarker().getResource(); + for (int i = 0; i < foundElements.length; i++) { + if (foundElements[i].equals(breakpointResource)) { + Object temp = foundElements[0]; + foundElements[0] = foundElements[i]; + foundElements[i] = temp; + break; + } + } + } + + // FIXME: remove when BUG247977 is fixed + endContainersSourceDirector(); + return foundElements; } + /** + * Override default. We want all the source elements we can get from the source containers + * so we can select the 'correct' element on the user's behalf. + * {@link https://bugs.eclipse.org/bugs/show_bug.cgi?id=247948} + * @see CSourceLookupParticipant#findSourceElements(Object) + */ + @Override + protected boolean isFindDuplicates() { + return true; + } + /* (non-Javadoc) * @see org.eclipse.debug.core.sourcelookup.AbstractSourceLookupParticipant#dispose() */ @@ -121,4 +181,114 @@ public class CSourceLookupParticipant extends AbstractSourceLookupParticipant { ((ISourceLookupChangeListener)listeners[i]).sourceContainersChanged( director ); super.sourceContainersChanged( director ); } + + /** + * FIXME: Workaround for BUG247977 + * Remove before 3.5 + * Remove when ISourceLocator.isFindDuplicates() queries the source lookup participant + * instead of the ISourceLookupDirector + */ + private ISourceContainer[] containers; + private void initContainersSourceDirector() { + ISourceLookupDirector dummySourceDirector = new ISourceLookupDirector() { + + public void addParticipants(ISourceLookupParticipant[] participants) { + getDirector().addParticipants(participants); + } + + public void clearSourceElements(Object element) { + getDirector().clearSourceElements(element); + } + + public Object[] findSourceElements(Object object) throws CoreException { + return getDirector().findSourceElements(object); + } + + public String getId() { + return getDirector().getId(); + } + + public ILaunchConfiguration getLaunchConfiguration() { + return getDirector().getLaunchConfiguration(); + } + + public ISourceLookupParticipant[] getParticipants() { + return getDirector().getParticipants(); + } + + public ISourceContainer[] getSourceContainers() { + return getDirector().getSourceContainers(); + } + + public Object getSourceElement(Object element) { + return getDirector().getSourceElement(element); + } + + public ISourcePathComputer getSourcePathComputer() { + return getDirector().getSourcePathComputer(); + } + + public void initializeParticipants() { + getDirector().initializeParticipants(); + } + + public boolean isFindDuplicates() { + return CSourceLookupParticipant.this.isFindDuplicates(); + } + + public void removeParticipants(ISourceLookupParticipant[] participants) { + getDirector().removeParticipants(participants); + } + + public void setFindDuplicates(boolean findDuplicates) { + getDirector().setFindDuplicates(findDuplicates); + } + + public void setSourceContainers(ISourceContainer[] containers) { + getDirector().setSourceContainers(containers); + } + + public void setSourcePathComputer(ISourcePathComputer computer) { + getDirector().setSourcePathComputer(computer); + } + + public boolean supportsSourceContainerType(ISourceContainerType type) { + return getDirector().supportsSourceContainerType(type); + } + + public void dispose() { + getDirector().dispose(); + } + + public void initializeFromMemento(String memento, ILaunchConfiguration configuration) throws CoreException { + getDirector().initializeFromMemento(memento, configuration); + } + + public String getMemento() throws CoreException { + return getDirector().getMemento(); + } + + public void initializeDefaults(ILaunchConfiguration configuration) throws CoreException { + getDirector().initializeDefaults(configuration); + } + + public void initializeFromMemento(String memento) throws CoreException { + getDirector().initializeFromMemento(memento); + } + + public Object getSourceElement(IStackFrame stackFrame) { + return getDirector().getSourceElement(stackFrame); + } + + }; + containers = getSourceContainers(); + for (ISourceContainer cont : containers) + cont.init(dummySourceDirector); + } + + private void endContainersSourceDirector() { + for (ISourceContainer cont : containers) + cont.init(getDirector()); + containers = null; + } }