diff options
author | John Cortell | 2010-01-11 20:52:55 +0000 |
---|---|---|
committer | John Cortell | 2010-01-11 20:52:55 +0000 |
commit | 485b4d73de721068c4f8de7b52c0cea56a74a54b (patch) | |
tree | a7cc0e479502ed1faabdadb11cfdb699df7b2463 /debug | |
parent | 76547b995802accd3d571676e7eb34cd6edf4888 (diff) | |
download | org.eclipse.cdt-485b4d73de721068c4f8de7b52c0cea56a74a54b.tar.gz org.eclipse.cdt-485b4d73de721068c4f8de7b52c0cea56a74a54b.tar.xz org.eclipse.cdt-485b4d73de721068c4f8de7b52c0cea56a74a54b.zip |
[299317] Executables view source remapping does not take into account launch configurations
Diffstat (limited to 'debug')
12 files changed, 587 insertions, 88 deletions
diff --git a/debug/org.eclipse.cdt.debug.core/.settings/.api_filters b/debug/org.eclipse.cdt.debug.core/.settings/.api_filters index 3dbc6bccf2a..e7851004d85 100644 --- a/debug/org.eclipse.cdt.debug.core/.settings/.api_filters +++ b/debug/org.eclipse.cdt.debug.core/.settings/.api_filters @@ -1,10 +1,18 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<?xml version="1.0" encoding="UTF-8"?> <component id="org.eclipse.cdt.debug.core" version="2"> - <resource path="src/org/eclipse/cdt/debug/core/ICDTLaunchConfigurationConstants.java" type="org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants"> - <filter id="403853384"> - <message_arguments> - <message_argument value="org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants"/> - </message_arguments> - </filter> - </resource> +<resource path="src/org/eclipse/cdt/debug/core/ICDTLaunchConfigurationConstants.java" type="org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants"> +<filter id="403853384"> +<message_arguments> +<message_argument value="org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants"/> +</message_arguments> +</filter> +</resource> +<resource path="src/org/eclipse/cdt/debug/internal/core/srcfinder/CSourceFinder.java" type="org.eclipse.cdt.debug.internal.core.srcfinder.CSourceFinder"> +<filter id="574619656"> +<message_arguments> +<message_argument value="ISourceFinder"/> +<message_argument value="CSourceFinder"/> +</message_arguments> +</filter> +</resource> </component> diff --git a/debug/org.eclipse.cdt.debug.core/plugin.xml b/debug/org.eclipse.cdt.debug.core/plugin.xml index f29545570b0..0745c828ead 100644 --- a/debug/org.eclipse.cdt.debug.core/plugin.xml +++ b/debug/org.eclipse.cdt.debug.core/plugin.xml @@ -337,5 +337,14 @@ <sourceContainer id="org.eclipse.debug.core.containerType.project"/> </extension> - + <extension + point="org.eclipse.core.runtime.adapters"> + <factory + adaptableType="org.eclipse.cdt.core.model.IBinary" + class="org.eclipse.cdt.debug.internal.core.srcfinder.CSourceFinderFactory"> + <adapter + type="org.eclipse.cdt.core.ISourceFinder"> + </adapter> + </factory> + </extension> </plugin> diff --git a/debug/org.eclipse.cdt.debug.core/schema/SourceRemappingProvider.exsd b/debug/org.eclipse.cdt.debug.core/schema/SourceRemappingProvider.exsd index 97d9101e7cb..fad60fb6746 100644 --- a/debug/org.eclipse.cdt.debug.core/schema/SourceRemappingProvider.exsd +++ b/debug/org.eclipse.cdt.debug.core/schema/SourceRemappingProvider.exsd @@ -2,9 +2,9 @@ <!-- Schema file written by PDE --> <schema targetNamespace="org.eclipse.cdt.debug.core" xmlns="http://www.w3.org/2001/XMLSchema"> <annotation> - <appinfo> + <appInfo> <meta.schema plugin="org.eclipse.cdt.debug.core" id="SourceRemappingProvider" name="Source Remapping Provider"/> - </appinfo> + </appInfo> <documentation> This extension points allows you to extened the executables manager in CDT by providing your own source remapping provider. </documentation> @@ -12,9 +12,9 @@ <element name="extension"> <annotation> - <appinfo> + <appInfo> <meta.element /> - </appinfo> + </appInfo> </annotation> <complexType> <sequence> @@ -39,9 +39,9 @@ <documentation> </documentation> - <appinfo> + <appInfo> <meta.attribute translatable="true"/> - </appinfo> + </appInfo> </annotation> </attribute> </complexType> @@ -54,27 +54,27 @@ <documentation> </documentation> - <appinfo> - <meta.attribute kind="java" basedOn="org.eclipse.cdt.debug.core.executables.ISourceFileRemapping"/> - </appinfo> + <appInfo> + <meta.attribute kind="java" basedOn=":org.eclipse.cdt.debug.core.executables.ISourceFileRemappingFactory"/> + </appInfo> </annotation> </attribute> </complexType> </element> <annotation> - <appinfo> + <appInfo> <meta.section type="since"/> - </appinfo> + </appInfo> <documentation> CDT 7.0 </documentation> </annotation> <annotation> - <appinfo> + <appInfo> <meta.section type="examples"/> - </appinfo> + </appInfo> <documentation> <extension point="org.eclipse.cdt.debug.core.SourceRemappingProvider"> @@ -83,4 +83,7 @@ </documentation> </annotation> + + + </schema> diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/Executable.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/Executable.java index 7242eda6f18..08e85f93c39 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/Executable.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/Executable.java @@ -89,6 +89,7 @@ public class Executable extends PlatformObject { private final Map<ITranslationUnit, String> remappedPaths; private final ArrayList<ITranslationUnit> sourceFiles; private boolean refreshSourceFiles; + private ISourceFileRemapping[] remappers; public IPath getPath() { return executablePath; @@ -98,11 +99,15 @@ public class Executable extends PlatformObject { return project; } - public Executable(IPath path, IProject project, IResource resource) { + /** + * @since 7.0 + */ + public Executable(IPath path, IProject project, IResource resource, ISourceFileRemapping[] sourceFileRemappings) { this.executablePath = path; this.project = project; this.name = new File(path.toOSString()).getName(); this.resource = resource; + this.remappers = sourceFileRemappings; remappedPaths = new HashMap<ITranslationUnit, String>(); sourceFiles = new ArrayList<ITranslationUnit>(); refreshSourceFiles = true; @@ -121,7 +126,7 @@ public class Executable extends PlatformObject { return name; } - @SuppressWarnings("unchecked") + @SuppressWarnings("rawtypes") @Override public Object getAdapter(Class adapter) { if (adapter.equals(IResource.class)) @@ -131,6 +136,17 @@ public class Executable extends PlatformObject { return this.getProject(); return super.getAdapter(adapter); } + + private String remapSourceFile(String filename) { + for (ISourceFileRemapping remapper : remappers) { + String remapped = remapper.remapSourceFile(this.getPath(), filename); + if (!remapped.equals(filename)) { + return remapped; + } + } + return filename; + } + /** * @noreference This method is not intended to be referenced by clients. @@ -157,7 +173,7 @@ public class Executable extends PlatformObject { for (String filename : symReaderSources) { String orgPath = filename; - filename = ExecutablesManager.getExecutablesManager().remapSourceFile(this, filename); + filename = remapSourceFile(filename); // Sometimes the path in the symbolics will have a different // case than the actual file system path. Even if the file diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/ExecutablesManager.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/ExecutablesManager.java index 9f2e25da034..fabcf55bd9b 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/ExecutablesManager.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/ExecutablesManager.java @@ -27,7 +27,7 @@ import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.core.settings.model.ICProjectDescriptionListener; import org.eclipse.cdt.debug.core.CDebugCorePlugin; import org.eclipse.cdt.debug.internal.core.executables.StandardExecutableImporter; -import org.eclipse.cdt.debug.internal.core.executables.StandardSourceFileRemapping; +import org.eclipse.cdt.debug.internal.core.executables.StandardSourceFileRemappingFactory; import org.eclipse.cdt.debug.internal.core.executables.StandardSourceFilesProvider; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; @@ -73,7 +73,7 @@ public class ExecutablesManager extends PlatformObject implements IResourceChang private List<IExecutablesChangeListener> changeListeners = Collections.synchronizedList(new ArrayList<IExecutablesChangeListener>()); private List<IProjectExecutablesProvider> executableProviders; private List<ISourceFilesProvider> sourceFileProviders; - private List<ISourceFileRemapping> sourceFileRemappings; + private List<ISourceFileRemappingFactory> sourceFileRemappingFactories; private List<IExecutableImporter> executableImporters; private boolean DEBUG; @@ -164,7 +164,7 @@ public class ExecutablesManager extends PlatformObject implements IResourceChang // add the standard providers executableProviders.add(0, new StandardExecutableProvider()); sourceFileProviders.add(0, new StandardSourceFilesProvider()); - sourceFileRemappings.add(0, new StandardSourceFileRemapping()); + sourceFileRemappingFactories.add(0, new StandardSourceFileRemappingFactory()); executableImporters.add(0, new StandardExecutableImporter()); // listen for events we're interested in @@ -267,26 +267,6 @@ public class ExecutablesManager extends PlatformObject implements IResourceChang } /** - * Attempt to remap the path to the given source file in the given executable using - * source file mapping extensions - * @param executable the executable - * @param filePath the absolute path to the source file - * @return the new path to the source file, which was remapped if possible - * - * @since 6.0 - */ - public String remapSourceFile(Executable executable, String filePath) { - synchronized (sourceFileRemappings) { - for (ISourceFileRemapping remapping : sourceFileRemappings) { - String remappedPath = remapping.remapSourceFile(executable.getPath(), filePath); - if (!remappedPath.equals(filePath)) - return remappedPath; - } - } - return filePath; - } - - /** * Import the given executables into the manager * @param fileNames the absolute paths of the executables to import * @param monitor progress monitor @@ -650,6 +630,10 @@ public class ExecutablesManager extends PlatformObject implements IResourceChang return provider; } + + ISourceFileRemappingFactory[] getSourceFileRemappingFactories() { + return sourceFileRemappingFactories.toArray(new ISourceFileRemappingFactory[sourceFileRemappingFactories.size()]); + } private void loadExecutableProviderExtensions() { executableProviders = Collections.synchronizedList(new ArrayList<IProjectExecutablesProvider>()); @@ -714,7 +698,7 @@ public class ExecutablesManager extends PlatformObject implements IResourceChang } private void loadSoureRemappingExtensions() { - sourceFileRemappings = Collections.synchronizedList(new ArrayList<ISourceFileRemapping>()); + sourceFileRemappingFactories = Collections.synchronizedList(new ArrayList<ISourceFileRemappingFactory>()); IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry(); IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(CDebugCorePlugin.PLUGIN_ID + ".SourceRemappingProvider"); //$NON-NLS-1$ @@ -729,7 +713,7 @@ public class ExecutablesManager extends PlatformObject implements IResourceChang try { Object extObject = element.createExecutableExtension("class"); //$NON-NLS-1$ if (extObject instanceof ISourceFileRemapping) { - sourceFileRemappings.add((ISourceFileRemapping)extObject); + sourceFileRemappingFactories.add((ISourceFileRemappingFactory)extObject); } else { failed = true; } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/ISourceFileRemappingFactory.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/ISourceFileRemappingFactory.java new file mode 100644 index 00000000000..15783f24cc2 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/ISourceFileRemappingFactory.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2010 Freescale Semiconductor 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Freescale Semiconductor - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.core.executables; + +import org.eclipse.cdt.core.model.IBinary; + +/** + * Factory that creates an ISourceFileRemapping instance for a particular binary + * object + * + * @since 7.0 + */ +public interface ISourceFileRemappingFactory { + public ISourceFileRemapping createRemapper(IBinary binary); +} diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/StandardExecutableProvider.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/StandardExecutableProvider.java index 67ab7b1c2dc..c5047f5a3b6 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/StandardExecutableProvider.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/StandardExecutableProvider.java @@ -65,7 +65,15 @@ public class StandardExecutableProvider implements IProjectExecutablesProvider { IPath exePath = binary.getResource().getLocation(); if (exePath == null) exePath = binary.getPath(); - executables.add(new Executable(exePath, project, binary.getResource())); + List<ISourceFileRemapping> srcRemappers = new ArrayList<ISourceFileRemapping>(2); + ISourceFileRemappingFactory[] factories = ExecutablesManager.getExecutablesManager().getSourceFileRemappingFactories(); + for (ISourceFileRemappingFactory factory : factories) { + ISourceFileRemapping remapper = factory.createRemapper(binary); + if (remapper != null) { + srcRemappers.add(remapper); + } + } + executables.add(new Executable(exePath, project, binary.getResource(), srcRemappers.toArray(new ISourceFileRemapping[srcRemappers.size()]))); } progress.worked(1); diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/executables/StandardSourceFileRemapping.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/executables/StandardSourceFileRemapping.java index b5902c16687..5fe4fcfc644 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/executables/StandardSourceFileRemapping.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/executables/StandardSourceFileRemapping.java @@ -11,48 +11,25 @@ package org.eclipse.cdt.debug.internal.core.executables; -import org.eclipse.cdt.debug.core.CDebugCorePlugin; +import org.eclipse.cdt.core.ISourceFinder; +import org.eclipse.cdt.core.model.IBinary; import org.eclipse.cdt.debug.core.executables.ISourceFileRemapping; -import org.eclipse.cdt.debug.core.sourcelookup.ICSourceLocator; -import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; -import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; -import org.eclipse.debug.core.DebugPlugin; -import org.eclipse.debug.core.ILaunch; -import org.eclipse.debug.core.ILaunchManager; -import org.eclipse.debug.core.model.ISourceLocator; -import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage; public class StandardSourceFileRemapping implements ISourceFileRemapping { - public String remapSourceFile(IPath executable, String filePath) { - - try { - Object[] foundElements = CDebugCorePlugin.getDefault().getCommonSourceLookupDirector().findSourceElements(filePath); - - if (foundElements.length == 0) { - Object foundElement = null; - ILaunchManager launchMgr = DebugPlugin.getDefault().getLaunchManager(); - ILaunch[] launches = launchMgr.getLaunches(); - for (ILaunch launch : launches) { - ISourceLocator locator = launch.getSourceLocator(); - if (locator instanceof ICSourceLocator || locator instanceof CSourceLookupDirector) { - if (locator instanceof ICSourceLocator) - foundElement = ((ICSourceLocator) locator).findSourceElement(filePath); - else - foundElement = ((CSourceLookupDirector) locator).getSourceElement(filePath); - } - } - if (foundElement != null) - foundElements = new Object[] { foundElement }; - } + ISourceFinder srcFinder; - if (foundElements.length == 1 && foundElements[0] instanceof LocalFileStorage) { - LocalFileStorage newLocation = (LocalFileStorage) foundElements[0]; - filePath = newLocation.getFullPath().toOSString(); + public StandardSourceFileRemapping(IBinary binary) { + srcFinder = (ISourceFinder) binary.getAdapter(ISourceFinder.class); + } + + public String remapSourceFile(IPath executable, String filePath) { + if (srcFinder != null) { + String mappedPath = srcFinder.toLocalPath(filePath); + if (mappedPath != null) { + return mappedPath; } - - } catch (CoreException e) { } return filePath; } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/executables/StandardSourceFileRemappingFactory.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/executables/StandardSourceFileRemappingFactory.java new file mode 100644 index 00000000000..a8f6fb9c251 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/executables/StandardSourceFileRemappingFactory.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2010 Freescale Semiconductor 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Freescale Semiconductor - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.core.executables; + +import org.eclipse.cdt.core.model.IBinary; +import org.eclipse.cdt.debug.core.executables.ISourceFileRemapping; +import org.eclipse.cdt.debug.core.executables.ISourceFileRemappingFactory; + +public class StandardSourceFileRemappingFactory implements ISourceFileRemappingFactory{ + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.executables.ISourceFileRemappingFactory#createRemapper(org.eclipse.cdt.core.model.IBinary) + */ + public ISourceFileRemapping createRemapper(IBinary binary) { + return new StandardSourceFileRemapping(binary); + } + +} diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/srcfinder/CSourceFinder.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/srcfinder/CSourceFinder.java new file mode 100644 index 00000000000..e57805c716b --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/srcfinder/CSourceFinder.java @@ -0,0 +1,363 @@ +/******************************************************************************* + * Copyright (c) 2010 Freescale Semiconductor 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Freescale Semiconductor - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.core.srcfinder; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.core.ISourceFinder; +import org.eclipse.cdt.core.model.IBinary; +import org.eclipse.cdt.debug.core.CDebugCorePlugin; +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; +import org.eclipse.cdt.internal.core.model.ExternalTranslationUnit; +import org.eclipse.core.filesystem.URIUtil; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationListener; +import org.eclipse.debug.core.ILaunchManager; +import org.eclipse.debug.core.ILaunchesListener; +import org.eclipse.debug.core.model.IPersistableSourceLocator; +import org.eclipse.debug.core.model.ISourceLocator; +import org.eclipse.debug.core.sourcelookup.IPersistableSourceLocator2; +import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector; +import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage; + +public class CSourceFinder implements ISourceFinder, ILaunchConfigurationListener, ILaunchesListener { + + /** + * The binary we are searching files for. We need this reference to find a + * matching ILaunch or ILaunchConfiguration if the caller needs to search + * for files when it doesn't have a debug context. + */ + private IBinary fBinary; + + /** + * The locator tied to an ILaunch or an ILaunchConfiguration that is + * associated with the binary. Used for searching when the caller has no + * debug context. See {@link ISourceFinder#toLocalPath(String)} for + * performance considerations that dictate how the locator is chosen. Access + * this only from synchronized blocks as the field is subject to be changed + * by listener invocations. + */ + private ISourceLookupDirector fLaunchLocator; + + /** + * A launch configuration doesn't have a source locator instance tied to it. + * Instead, one is created on the fly as needed from attributes in the + * launch config. This is a heavy operation. As an optimization, we cache + * the locators we create and discard when the launch config changes or is + * disposed. Collection is subject to be changed by listener invocations. + * + * @see CSourceFinder#getLocator(ILaunchConfiguration) + */ + private Map<ILaunchConfiguration, ISourceLocator> fConfigLocators = Collections.synchronizedMap(new HashMap<ILaunchConfiguration, ISourceLocator>()); + + /** + * Constructor. + * + * @param binary + * the executable whose source files we will be asked to find + * locally + */ + public CSourceFinder(IBinary binary) { + assert(binary != null); + fBinary = binary; + + ILaunchManager lmgr = DebugPlugin.getDefault().getLaunchManager(); + lmgr.addLaunchConfigurationListener(this); + lmgr.addLaunchListener(this); + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.ISourceFinder#toLocalPath(java.lang.String) + */ + synchronized public String toLocalPath(String compilationPath) { + try { + Object foundElement = null; + + // Find a suitable launch/config locator if we haven't found one yet + if (fLaunchLocator == null) { + ILaunchManager lmgr = DebugPlugin.getDefault().getLaunchManager(); + + // See if there are any active debug sessions (running, or + // terminated but still in the Debug view) that are targeting + // our executable. If there are then use the first one to + // provide a locator + ILaunch[] launches = lmgr.getLaunches(); + for (ILaunch launch : launches) { + ILaunchConfiguration config = launch.getLaunchConfiguration(); + if (isMatch(config)) { + ISourceLocator launchLocator = launch.getSourceLocator(); + // in practice, a launch locator is always an ISourceLookupDirector + if (launchLocator instanceof ISourceLookupDirector) { + fLaunchLocator = (ISourceLookupDirector)launchLocator; + break; + } + } + } + + // If there were no matching launches or none of them + // provided a locator, search the launch configurations + if (fLaunchLocator == null) { + for (ILaunchConfiguration config : lmgr.getLaunchConfigurations()) { + if (isMatch(config)) { + // Search our cache of locators that we + // instantiate for configurations. Create one if + // not found + ISourceLocator configLocator = fConfigLocators.get(config); + if (configLocator == null) { + configLocator = getLocator(config); // heavy operation + fConfigLocators.put(config, configLocator); // cache to avoid next time + } + // In practice, a config's locator is always an ISourceLookupDirector + if (configLocator instanceof ISourceLookupDirector) { + fLaunchLocator = (ISourceLookupDirector)configLocator; + break; + } + } + } + } + } + + // Search for the file using the launch/config locator + if (fLaunchLocator != null) { + foundElement = fLaunchLocator.getSourceElement(compilationPath); + } + + // If not found, look in the global (common) locator + if (foundElement == null) { + CSourceLookupDirector locator = CDebugCorePlugin.getDefault().getCommonSourceLookupDirector(); + foundElement = locator.getSourceElement(compilationPath); + } + + return foundElementToPath(foundElement); + } + catch (CoreException exc) { + CDebugCorePlugin.log(exc); + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.ISourceFinder#toLocalPath(org.eclipse.core.runtime.IAdaptable, java.lang.String) + */ + public String toLocalPath(IAdaptable _launch, String compilationPath) { + Object foundElement = null; + + ILaunch launch = (ILaunch)_launch.getAdapter(ILaunch.class); + if (launch != null) { + ISourceLocator locator = launch.getSourceLocator(); + // in practice, a launch locator is always an ISourceLookupDirector + if (locator instanceof ISourceLookupDirector) { + foundElement = ((ISourceLookupDirector)locator).getSourceElement(compilationPath); + } + } + + // If not found, look in the global (common) locator + if (foundElement == null) { + CSourceLookupDirector locator = CDebugCorePlugin.getDefault().getCommonSourceLookupDirector(); + foundElement = locator.getSourceElement(compilationPath); + } + + return foundElementToPath(foundElement); + } + + /** + * Utility method to convert the element found by the source locators to a + * canonical file path + * + * @param foundElement + * the element found by the source locator, or null if not found + * @return the canonical file path of the element + */ + private static String foundElementToPath(Object foundElement) { + if (foundElement != null) { + try { + if (foundElement instanceof IFile) { + IPath path = ((IFile)foundElement).getLocation(); + if (path != null) { + File file = path.toFile(); + if (file != null) { + return file.getCanonicalPath(); + } + } + + } + else if (foundElement instanceof LocalFileStorage) { + File file = ((LocalFileStorage)foundElement).getFile(); + if (file != null) { + return file.getCanonicalPath(); + } + } + else if (foundElement instanceof ExternalTranslationUnit) { + URI uri = ((ExternalTranslationUnit)foundElement).getLocationURI(); + if (uri != null) { + IPath path = URIUtil.toPath(uri); + if (path != null) { + File file = path.toFile(); + if (file != null) { + return file.getCanonicalPath(); + } + } + } + } + } catch (IOException e) { + CDebugCorePlugin.log(e); + } + } + + return null; + } + + /** + * Utility method to determine if the given launch configuration targets the Binary we are associated with + * @param config + * @return true if the launch config targets our binary, false otherwise + */ + private boolean isMatch(ILaunchConfiguration config) { + IResource resource = (IResource)fBinary.getAdapter(IResource.class); + if (resource != null) { + String binaryPath = resource.getFullPath().toString(); + try { + String projectNameConfig = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""); //$NON-NLS-1$ + String programNameConfig = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, ""); //$NON-NLS-1$ + IProject project = resource.getProject(); + if (project != null && project.getName().equals(projectNameConfig)) { + Path path = new Path(programNameConfig); + if (!path.isEmpty()) { + IFile file = project.getFile(path); + if (file != null) { + String fullPath = file.getFullPath().toString(); + return fullPath.equals(binaryPath); + } + } + } + } catch (CoreException e) { + // Problem getting attribute from launch config? Not expecting that. + CDebugCorePlugin.log(e); + } + } + + return false; + } + + /** + * Utility method to instantiate a source locator for a launch + * configuration. A launch configuration doesn't have a source locator + * instance tied to it. Transient instances are created as needed. from + * attributes in the launch config. This is a heavy operation. + * + * @param config + * the launch configuration to create the locator for + * @return the source locator + * @throws CoreException + */ + static private ISourceLocator getLocator(ILaunchConfiguration config) throws CoreException { + String type = config.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, (String)null); + if (type == null) { + type = config.getType().getSourceLocatorId(); + } + if (type != null) { + IPersistableSourceLocator locator = DebugPlugin.getDefault().getLaunchManager().newSourceLocator(type); + String memento = config.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, (String)null); + if (memento == null) { + locator.initializeDefaults(config); + } else { + if(locator instanceof IPersistableSourceLocator2) + ((IPersistableSourceLocator2)locator).initializeFromMemento(memento, config); + else + locator.initializeFromMemento(memento); + } + return locator; + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.ILaunchConfigurationListener#launchConfigurationAdded(org.eclipse.debug.core.ILaunchConfiguration) + */ + public void launchConfigurationAdded(ILaunchConfiguration config) { + // Don't care. + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.ILaunchConfigurationListener#launchConfigurationChanged(org.eclipse.debug.core.ILaunchConfiguration) + */ + public void launchConfigurationChanged(ILaunchConfiguration config) { + // We don't care if it's a working copy. + if (config.isWorkingCopy()) { + return; + } + // the source locator attribute may have changed + fConfigLocators.remove(config); + if ((fLaunchLocator != null) && (fLaunchLocator.getLaunchConfiguration() == config)) { + fLaunchLocator = null; + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.ILaunchConfigurationListener#launchConfigurationRemoved(org.eclipse.debug.core.ILaunchConfiguration) + */ + public void launchConfigurationRemoved(ILaunchConfiguration config) { + fConfigLocators.remove(config); + if ((fLaunchLocator != null) && (fLaunchLocator.getLaunchConfiguration() == config)) { + fLaunchLocator = null; + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.ILaunchesListener#launchesRemoved(org.eclipse.debug.core.ILaunch[]) + */ + synchronized public void launchesRemoved(ILaunch[] launches) { + for (ILaunch launch : launches) { + if (launch.getSourceLocator() == fLaunchLocator) { + fLaunchLocator = null; + return; + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.ILaunchesListener#launchesAdded(org.eclipse.debug.core.ILaunch[]) + */ + synchronized public void launchesAdded(ILaunch[] launches) { + // If there's a new launch in town, we need to take it into + // consideration. E.g., if it targets our binary, and we're currently + // searching using an inactive launch configuration's locator, then the + // new launch's locator should take precedence + for (ILaunch launch : launches) { + if (isMatch(launch.getLaunchConfiguration())) { + fLaunchLocator = null; + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.ILaunchesListener#launchesChanged(org.eclipse.debug.core.ILaunch[]) + */ + public void launchesChanged(ILaunch[] launches) { + // don't care. I don't think setting a new locator in a launch would result in us getting notified + } +} diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/srcfinder/CSourceFinderFactory.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/srcfinder/CSourceFinderFactory.java new file mode 100644 index 00000000000..1e2df9c70de --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/srcfinder/CSourceFinderFactory.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2010 Freescale Semiconductor 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Freescale Semiconductor - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.core.srcfinder; + +import org.eclipse.cdt.core.ISourceFinder; +import org.eclipse.cdt.core.model.IBinary; +import org.eclipse.core.runtime.IAdapterFactory; + +/** + * Adapter factory that adapts an IBinary object to an ISourceFinder + */ +public class CSourceFinderFactory implements IAdapterFactory { + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object, java.lang.Class) + */ + @SuppressWarnings("rawtypes") + public Object getAdapter(Object adaptableObject, Class adapterType) { + if (adaptableObject instanceof IBinary) { + if (adapterType.equals(ISourceFinder.class)) { + return new CSourceFinder((IBinary)adaptableObject); + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList() + */ + @SuppressWarnings("rawtypes") + public Class[] getAdapterList() { + return new Class[] { ISourceFinder.class }; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesViewer.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesViewer.java index 51c582e7d7c..165d436ccac 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesViewer.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesViewer.java @@ -24,6 +24,9 @@ import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationListener; import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector; import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant; import org.eclipse.jface.viewers.IOpenListener; @@ -46,7 +49,7 @@ import org.eclipse.ui.progress.UIJob; * Displays the list of source files for the executable selected in the * ExecutablesViewer. */ -public class SourceFilesViewer extends BaseViewer implements ISourceLookupParticipant { +public class SourceFilesViewer extends BaseViewer implements ISourceLookupParticipant, ILaunchConfigurationListener { private static final String P_COLUMN_ORDER_KEY_SF = "columnOrderKeySF"; //$NON-NLS-1$ private static final String P_SORTED_COLUMN_INDEX_KEY_SF = "sortedColumnIndexKeySF"; //$NON-NLS-1$ @@ -79,6 +82,11 @@ public class SourceFilesViewer extends BaseViewer implements ISourceLookupPartic // source lookup as this viewer shows both original and remapped // locations CDebugCorePlugin.getDefault().getCommonSourceLookupDirector().addParticipants(new ISourceLookupParticipant[] { this }); + + // We also look for launch configuration changes, since their source + // locators are involved in source path remapping, too + DebugPlugin.getDefault().getLaunchManager().addLaunchConfigurationListener(this); + sourceFilesTree.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { @@ -169,7 +177,7 @@ public class SourceFilesViewer extends BaseViewer implements ISourceLookupPartic if (sortType == ExecutablesView.ORG_LOCATION) { return new ExecutablesViewerComparator(sortType, column_sort_order[ExecutablesView.ORG_LOCATION]) { - @SuppressWarnings("unchecked") //$NON-NLS-1$ + @SuppressWarnings("unchecked") public int compare(Viewer viewer, Object e1, Object e2) { if (e1 instanceof ITranslationUnit && e2 instanceof ITranslationUnit) { ITranslationUnit entry1 = (ITranslationUnit) e1; @@ -201,6 +209,10 @@ public class SourceFilesViewer extends BaseViewer implements ISourceLookupPartic } public void sourceContainersChanged(ISourceLookupDirector director) { + refreshContent(); + } + + private void refreshContent() { UIJob refreshJob = new UIJob(Messages.SourceFilesViewer_RefreshSourceFiles) { @Override @@ -241,4 +253,32 @@ public class SourceFilesViewer extends BaseViewer implements ISourceLookupPartic // default visible columns return "1,1,0,0,0,0"; //$NON-NLS-1$ } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.ILaunchConfigurationListener#launchConfigurationAdded(org.eclipse.debug.core.ILaunchConfiguration) + */ + public void launchConfigurationAdded(ILaunchConfiguration configuration) { + if (!configuration.isWorkingCopy()) { + refreshContent(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.ILaunchConfigurationListener#launchConfigurationChanged(org.eclipse.debug.core.ILaunchConfiguration) + */ + public void launchConfigurationChanged(ILaunchConfiguration configuration) { + if (!configuration.isWorkingCopy()) { + refreshContent(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.ILaunchConfigurationListener#launchConfigurationRemoved(org.eclipse.debug.core.ILaunchConfiguration) + */ + public void launchConfigurationRemoved(ILaunchConfiguration configuration) { + if (!configuration.isWorkingCopy()) { + refreshContent(); + } + } + }
\ No newline at end of file |