mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 14:42:11 +02:00
Bug 299087, Executables manager overhaul.
This commit is contained in:
parent
ee9e75b76f
commit
4692c67a86
22 changed files with 1238 additions and 635 deletions
|
@ -6,6 +6,10 @@
|
||||||
<extension-point id="BreakpointActionType" name="%BreakpointAction" schema="schema/BreakpointAction.exsd"/>
|
<extension-point id="BreakpointActionType" name="%BreakpointAction" schema="schema/BreakpointAction.exsd"/>
|
||||||
<extension-point id="BreakpointExtension" name="%BreakpointAction" schema="schema/BreakpointExtension.exsd"/>
|
<extension-point id="BreakpointExtension" name="%BreakpointAction" schema="schema/BreakpointExtension.exsd"/>
|
||||||
<extension-point id="supportedSourceContainerTypes" name="%SupportedSourceContainerTypes.name" schema="schema/SupportedSourceContainerTypes.exsd"/>
|
<extension-point id="supportedSourceContainerTypes" name="%SupportedSourceContainerTypes.name" schema="schema/SupportedSourceContainerTypes.exsd"/>
|
||||||
|
<extension-point id="ExecutablesProvider" name="Executables Provider" schema="schema/ExecutablesProvider.exsd"/>
|
||||||
|
<extension-point id="SourceFilesProvider" name="Source Files Provider" schema="schema/SourceFilesProvider.exsd"/>
|
||||||
|
<extension-point id="SourceRemappingProvider" name="Source Remapping Provider" schema="schema/SourceRemappingProvider.exsd"/>
|
||||||
|
<extension-point id="ExecutablesImporter" name="Executables Importer" schema="schema/ExecutablesImporter.exsd"/>
|
||||||
|
|
||||||
<extension
|
<extension
|
||||||
point="org.eclipse.debug.core.launchConfigurationTypes">
|
point="org.eclipse.debug.core.launchConfigurationTypes">
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<!-- Schema file written by PDE -->
|
||||||
|
<schema targetNamespace="org.eclipse.cdt.debug.core" xmlns="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<annotation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.schema plugin="org.eclipse.cdt.debug.core" id="ExecutablesImporter" name="Executables Importer"/>
|
||||||
|
</appinfo>
|
||||||
|
<documentation>
|
||||||
|
This extension points allows you to extened the executables manager in CDT by providing your own executables importer.
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
|
||||||
|
<element name="extension">
|
||||||
|
<annotation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.element />
|
||||||
|
</appinfo>
|
||||||
|
</annotation>
|
||||||
|
<complexType>
|
||||||
|
<sequence>
|
||||||
|
<element ref="provider"/>
|
||||||
|
</sequence>
|
||||||
|
<attribute name="point" type="string" use="required">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="id" type="string">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="name" type="string">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.attribute translatable="true"/>
|
||||||
|
</appinfo>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
</complexType>
|
||||||
|
</element>
|
||||||
|
|
||||||
|
<element name="importer">
|
||||||
|
<complexType>
|
||||||
|
<attribute name="class" type="string" use="required">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.attribute kind="java" basedOn="org.eclipse.cdt.debug.core.executables.IExecutableImporter"/>
|
||||||
|
</appinfo>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
</complexType>
|
||||||
|
</element>
|
||||||
|
|
||||||
|
<annotation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.section type="since"/>
|
||||||
|
</appinfo>
|
||||||
|
<documentation>
|
||||||
|
CDT 7.0
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
|
||||||
|
<annotation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.section type="examples"/>
|
||||||
|
</appinfo>
|
||||||
|
<documentation>
|
||||||
|
<extension
|
||||||
|
point="org.eclipse.cdt.debug.core.ExecutablesImporter">
|
||||||
|
<modifier class="com.xyz.MyExecutablesImporter"/>
|
||||||
|
</extension>
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
|
||||||
|
</schema>
|
|
@ -0,0 +1,86 @@
|
||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<!-- Schema file written by PDE -->
|
||||||
|
<schema targetNamespace="org.eclipse.cdt.debug.core" xmlns="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<annotation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.schema plugin="org.eclipse.cdt.debug.core" id="ExecutablesProvider" name="Executables Provider"/>
|
||||||
|
</appinfo>
|
||||||
|
<documentation>
|
||||||
|
This extension points allows you to extened the executables manager in CDT by providing your own executables provider for certain types of projects.
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
|
||||||
|
<element name="extension">
|
||||||
|
<annotation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.element />
|
||||||
|
</appinfo>
|
||||||
|
</annotation>
|
||||||
|
<complexType>
|
||||||
|
<sequence>
|
||||||
|
<element ref="provider"/>
|
||||||
|
</sequence>
|
||||||
|
<attribute name="point" type="string" use="required">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="id" type="string">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="name" type="string">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.attribute translatable="true"/>
|
||||||
|
</appinfo>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
</complexType>
|
||||||
|
</element>
|
||||||
|
|
||||||
|
<element name="provider">
|
||||||
|
<complexType>
|
||||||
|
<attribute name="class" type="string" use="required">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.attribute kind="java" basedOn="org.eclipse.cdt.debug.core.executables.IProjectExecutablesProvider"/>
|
||||||
|
</appinfo>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
</complexType>
|
||||||
|
</element>
|
||||||
|
|
||||||
|
<annotation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.section type="since"/>
|
||||||
|
</appinfo>
|
||||||
|
<documentation>
|
||||||
|
CDT 7.0
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
|
||||||
|
<annotation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.section type="examples"/>
|
||||||
|
</appinfo>
|
||||||
|
<documentation>
|
||||||
|
<extension
|
||||||
|
point="org.eclipse.cdt.debug.core.ExecutablesProvider">
|
||||||
|
<modifier class="com.xyz.MyExecutablesProvider"/>
|
||||||
|
</extension>
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
|
||||||
|
</schema>
|
|
@ -0,0 +1,86 @@
|
||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<!-- Schema file written by PDE -->
|
||||||
|
<schema targetNamespace="org.eclipse.cdt.debug.core" xmlns="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<annotation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.schema plugin="org.eclipse.cdt.debug.core" id="SourceFilesProvider" name="Source Files Provider"/>
|
||||||
|
</appinfo>
|
||||||
|
<documentation>
|
||||||
|
This extension points allows you to extened the executables manager in CDT by providing your own source files provider for certain types of executables.
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
|
||||||
|
<element name="extension">
|
||||||
|
<annotation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.element />
|
||||||
|
</appinfo>
|
||||||
|
</annotation>
|
||||||
|
<complexType>
|
||||||
|
<sequence>
|
||||||
|
<element ref="provider"/>
|
||||||
|
</sequence>
|
||||||
|
<attribute name="point" type="string" use="required">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="id" type="string">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="name" type="string">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.attribute translatable="true"/>
|
||||||
|
</appinfo>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
</complexType>
|
||||||
|
</element>
|
||||||
|
|
||||||
|
<element name="provider">
|
||||||
|
<complexType>
|
||||||
|
<attribute name="class" type="string" use="required">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.attribute kind="java" basedOn="org.eclipse.cdt.debug.core.executables.ISourceFilesProvider"/>
|
||||||
|
</appinfo>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
</complexType>
|
||||||
|
</element>
|
||||||
|
|
||||||
|
<annotation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.section type="since"/>
|
||||||
|
</appinfo>
|
||||||
|
<documentation>
|
||||||
|
CDT 7.0
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
|
||||||
|
<annotation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.section type="examples"/>
|
||||||
|
</appinfo>
|
||||||
|
<documentation>
|
||||||
|
<extension
|
||||||
|
point="org.eclipse.cdt.debug.core.SourceFilesProvider">
|
||||||
|
<modifier class="com.xyz.MySourceFilesProvider"/>
|
||||||
|
</extension>
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
|
||||||
|
</schema>
|
|
@ -0,0 +1,86 @@
|
||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<!-- Schema file written by PDE -->
|
||||||
|
<schema targetNamespace="org.eclipse.cdt.debug.core" xmlns="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<annotation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.schema plugin="org.eclipse.cdt.debug.core" id="SourceRemappingProvider" name="Source Remapping Provider"/>
|
||||||
|
</appinfo>
|
||||||
|
<documentation>
|
||||||
|
This extension points allows you to extened the executables manager in CDT by providing your own source remapping provider.
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
|
||||||
|
<element name="extension">
|
||||||
|
<annotation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.element />
|
||||||
|
</appinfo>
|
||||||
|
</annotation>
|
||||||
|
<complexType>
|
||||||
|
<sequence>
|
||||||
|
<element ref="provider"/>
|
||||||
|
</sequence>
|
||||||
|
<attribute name="point" type="string" use="required">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="id" type="string">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="name" type="string">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.attribute translatable="true"/>
|
||||||
|
</appinfo>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
</complexType>
|
||||||
|
</element>
|
||||||
|
|
||||||
|
<element name="provider">
|
||||||
|
<complexType>
|
||||||
|
<attribute name="class" type="string" use="required">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.attribute kind="java" basedOn="org.eclipse.cdt.debug.core.executables.ISourceFileRemapping"/>
|
||||||
|
</appinfo>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
</complexType>
|
||||||
|
</element>
|
||||||
|
|
||||||
|
<annotation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.section type="since"/>
|
||||||
|
</appinfo>
|
||||||
|
<documentation>
|
||||||
|
CDT 7.0
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
|
||||||
|
<annotation>
|
||||||
|
<appinfo>
|
||||||
|
<meta.section type="examples"/>
|
||||||
|
</appinfo>
|
||||||
|
<documentation>
|
||||||
|
<extension
|
||||||
|
point="org.eclipse.cdt.debug.core.SourceRemappingProvider">
|
||||||
|
<modifier class="com.xyz.MySourceRemappingProvider"/>
|
||||||
|
</extension>
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
|
||||||
|
</schema>
|
|
@ -136,7 +136,7 @@ public class Executable extends PlatformObject {
|
||||||
* @noreference This method is not intended to be referenced by clients.
|
* @noreference This method is not intended to be referenced by clients.
|
||||||
* @since 6.0
|
* @since 6.0
|
||||||
*/
|
*/
|
||||||
public ITranslationUnit[] getSourceFiles(IProgressMonitor monitor) {
|
public synchronized ITranslationUnit[] getSourceFiles(IProgressMonitor monitor) {
|
||||||
|
|
||||||
if (!refreshSourceFiles)
|
if (!refreshSourceFiles)
|
||||||
return sourceFiles.toArray(new TranslationUnit[sourceFiles.size()]) ;
|
return sourceFiles.toArray(new TranslationUnit[sourceFiles.size()]) ;
|
||||||
|
@ -166,6 +166,7 @@ public class Executable extends PlatformObject {
|
||||||
// breakpoints won't be resolved, etc.. Also check for relative
|
// breakpoints won't be resolved, etc.. Also check for relative
|
||||||
// path names and attempt to resolve them relative to the
|
// path names and attempt to resolve them relative to the
|
||||||
// executable.
|
// executable.
|
||||||
|
|
||||||
boolean fileExists = false;
|
boolean fileExists = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -215,7 +216,6 @@ public class Executable extends PlatformObject {
|
||||||
// "/src/home" to "c:\source\home" on Windows. See
|
// "/src/home" to "c:\source\home" on Windows. See
|
||||||
// bugzilla 297781
|
// bugzilla 297781
|
||||||
URI uri = (sourcePath.toFile().exists()) ? URIUtil.toURI(sourcePath) : URIUtil.toURI(filename);
|
URI uri = (sourcePath.toFile().exists()) ? URIUtil.toURI(sourcePath) : URIUtil.toURI(filename);
|
||||||
|
|
||||||
tu = new ExternalTranslationUnit(cproject, uri, id);
|
tu = new ExternalTranslationUnit(cproject, uri, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +239,7 @@ public class Executable extends PlatformObject {
|
||||||
this.refreshSourceFiles = refreshSourceFiles;
|
this.refreshSourceFiles = refreshSourceFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOriginalLocation(ITranslationUnit tu) {
|
public synchronized String getOriginalLocation(ITranslationUnit tu) {
|
||||||
String orgLocation = remappedPaths.get(tu);
|
String orgLocation = remappedPaths.get(tu);
|
||||||
if (orgLocation == null)
|
if (orgLocation == null)
|
||||||
orgLocation = tu.getLocation().toOSString();
|
orgLocation = tu.getLocation().toOSString();
|
||||||
|
|
|
@ -11,29 +11,50 @@
|
||||||
|
|
||||||
package org.eclipse.cdt.debug.core.executables;
|
package org.eclipse.cdt.debug.core.executables;
|
||||||
|
|
||||||
|
import java.text.DateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.model.CoreModel;
|
||||||
|
import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent;
|
||||||
|
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.core.CDebugCorePlugin;
|
||||||
import org.eclipse.cdt.debug.internal.core.executables.ExecutablesChangeEvent;
|
|
||||||
import org.eclipse.cdt.debug.internal.core.executables.StandardExecutableImporter;
|
import org.eclipse.cdt.debug.internal.core.executables.StandardExecutableImporter;
|
||||||
import org.eclipse.cdt.debug.internal.core.executables.StandardExecutableProvider;
|
|
||||||
import org.eclipse.cdt.debug.internal.core.executables.StandardSourceFileRemapping;
|
import org.eclipse.cdt.debug.internal.core.executables.StandardSourceFileRemapping;
|
||||||
import org.eclipse.cdt.debug.internal.core.executables.StandardSourceFilesProvider;
|
import org.eclipse.cdt.debug.internal.core.executables.StandardSourceFilesProvider;
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.resources.IProjectDescription;
|
||||||
|
import org.eclipse.core.resources.IResource;
|
||||||
|
import org.eclipse.core.resources.IResourceChangeEvent;
|
||||||
|
import org.eclipse.core.resources.IResourceChangeListener;
|
||||||
|
import org.eclipse.core.resources.IResourceDelta;
|
||||||
|
import org.eclipse.core.resources.IResourceDeltaVisitor;
|
||||||
|
import org.eclipse.core.resources.ResourcesPlugin;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.core.runtime.IConfigurationElement;
|
||||||
|
import org.eclipse.core.runtime.IExtension;
|
||||||
|
import org.eclipse.core.runtime.IExtensionPoint;
|
||||||
|
import org.eclipse.core.runtime.IExtensionRegistry;
|
||||||
import org.eclipse.core.runtime.IPath;
|
import org.eclipse.core.runtime.IPath;
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
import org.eclipse.core.runtime.IStatus;
|
import org.eclipse.core.runtime.IStatus;
|
||||||
import org.eclipse.core.runtime.MultiStatus;
|
import org.eclipse.core.runtime.MultiStatus;
|
||||||
|
import org.eclipse.core.runtime.Platform;
|
||||||
import org.eclipse.core.runtime.PlatformObject;
|
import org.eclipse.core.runtime.PlatformObject;
|
||||||
import org.eclipse.core.runtime.Status;
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.core.runtime.SubMonitor;
|
||||||
import org.eclipse.core.runtime.SubProgressMonitor;
|
import org.eclipse.core.runtime.SubProgressMonitor;
|
||||||
import org.eclipse.core.runtime.jobs.Job;
|
import org.eclipse.core.runtime.jobs.Job;
|
||||||
import org.eclipse.debug.core.DebugPlugin;
|
import org.eclipse.osgi.service.debug.DebugOptions;
|
||||||
|
import org.osgi.framework.BundleContext;
|
||||||
|
import org.osgi.framework.ServiceReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Executables Manager maintains a collection of executables built by all of
|
* The Executables Manager maintains a collection of executables built by all of
|
||||||
|
@ -43,28 +64,70 @@ import org.eclipse.debug.core.DebugPlugin;
|
||||||
* @author Ken Ryall
|
* @author Ken Ryall
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ExecutablesManager extends PlatformObject {
|
public class ExecutablesManager extends PlatformObject implements IResourceChangeListener, ICProjectDescriptionListener {
|
||||||
|
|
||||||
private final HashMap<String, Executable> executables = new HashMap<String, Executable>();
|
private static final String EXECUTABLES_MANAGER_DEBUG_TRACING = CDebugCorePlugin.PLUGIN_ID + "EXECUTABLES_MANAGER_DEBUG_TRACING"; //$NON-NLS-1$
|
||||||
private final List<IExecutablesChangeListener> changeListeners = Collections.synchronizedList(new ArrayList<IExecutablesChangeListener>());
|
|
||||||
private final List<ISourceFileRemapping> sourceFileRemappings = Collections.synchronizedList(new ArrayList<ISourceFileRemapping>());
|
|
||||||
private final List<IExecutableProvider> executableProviders = Collections.synchronizedList(new ArrayList<IExecutableProvider>());
|
|
||||||
private final List<ISourceFilesProvider> sourceFileProviders = Collections.synchronizedList(new ArrayList<ISourceFilesProvider>());
|
|
||||||
private final List<IExecutableImporter> executableImporters = Collections.synchronizedList(new ArrayList<IExecutableImporter>());
|
|
||||||
private boolean refreshNeeded = true;
|
|
||||||
private boolean tempDisableRefresh = false;
|
|
||||||
|
|
||||||
private final Job refreshJob = new Job("Get Executables") {
|
private Map<IProject, IProjectExecutablesProvider> executablesProviderMap = new HashMap<IProject, IProjectExecutablesProvider>();
|
||||||
|
private Map<IProject, List<Executable>> executablesMap = new HashMap<IProject, List<Executable>>();
|
||||||
|
private List<IExecutablesChangeListener> changeListeners = Collections.synchronizedList(new ArrayList<IExecutablesChangeListener>());
|
||||||
|
private List<IProjectExecutablesProvider> executableProviders;
|
||||||
|
private List<ISourceFilesProvider> sourceFileProviders;
|
||||||
|
private List<ISourceFileRemapping> sourceFileRemappings;
|
||||||
|
private List<IExecutableImporter> executableImporters;
|
||||||
|
|
||||||
|
private boolean DEBUG;
|
||||||
|
|
||||||
|
private Job refreshJob = new Job("Get Executables") { //$NON-NLS-1$
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IStatus run(IProgressMonitor monitor) {
|
public IStatus run(IProgressMonitor monitor) {
|
||||||
refreshExecutables(monitor);
|
|
||||||
|
trace("Get Executables job started at " + getStringFromTimestamp(System.currentTimeMillis())); //$NON-NLS-1$
|
||||||
|
|
||||||
|
List<IProject> projects = getProjectsToCheck();
|
||||||
|
|
||||||
|
SubMonitor subMonitor = SubMonitor.convert(monitor, projects.size());
|
||||||
|
|
||||||
|
for (IProject project : projects) {
|
||||||
|
if (subMonitor.isCanceled()) {
|
||||||
|
trace("Get Executables job cancelled at " + getStringFromTimestamp(System.currentTimeMillis())); //$NON-NLS-1$
|
||||||
|
return Status.CANCEL_STATUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
subMonitor.subTask("Checking project: " + project.getName()); //$NON-NLS-1$
|
||||||
|
|
||||||
|
// get the executables provider for this project
|
||||||
|
IProjectExecutablesProvider provider = getExecutablesProviderForProject(project);
|
||||||
|
if (provider != null) {
|
||||||
|
trace("Getting executables for project: " + project.getName() + " using " + provider.toString()); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
|
|
||||||
|
// store the list of executables for this project
|
||||||
|
synchronized (executablesMap) {
|
||||||
|
executablesMap.put(project, provider.getExecutables(project, subMonitor.newChild(1, SubMonitor.SUPPRESS_NONE)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// notify the listeners
|
||||||
|
synchronized (changeListeners) {
|
||||||
|
for (IExecutablesChangeListener listener : changeListeners) {
|
||||||
|
listener.executablesListChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trace("Get Executables job finished at " + getStringFromTimestamp(System.currentTimeMillis())); //$NON-NLS-1$
|
||||||
|
|
||||||
return Status.OK_STATUS;
|
return Status.OK_STATUS;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static ExecutablesManager executablesManager = null;
|
private static ExecutablesManager executablesManager = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the executables manager instance
|
||||||
|
* @return the executables manager
|
||||||
|
*/
|
||||||
public static ExecutablesManager getExecutablesManager() {
|
public static ExecutablesManager getExecutablesManager() {
|
||||||
if (executablesManager == null)
|
if (executablesManager == null)
|
||||||
executablesManager = new ExecutablesManager();
|
executablesManager = new ExecutablesManager();
|
||||||
|
@ -72,130 +135,150 @@ public class ExecutablesManager extends PlatformObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExecutablesManager() {
|
public ExecutablesManager() {
|
||||||
addSourceFileRemapping(new StandardSourceFileRemapping());
|
|
||||||
addExecutableImporter(new StandardExecutableImporter());
|
// check if debugging is enabled
|
||||||
addExecutablesProvider(new StandardExecutableProvider());
|
BundleContext context = CDebugCorePlugin.getDefault().getBundle().getBundleContext();
|
||||||
addSourceFilesProvider(new StandardSourceFilesProvider());
|
if (context != null) {
|
||||||
|
ServiceReference reference = CDebugCorePlugin.getDefault().getBundle().getBundleContext().getServiceReference(DebugOptions.class.getName());
|
||||||
|
if (reference != null) {
|
||||||
|
DebugOptions service = (DebugOptions) context.getService(reference);
|
||||||
|
if (service != null) {
|
||||||
|
try {
|
||||||
|
DEBUG = service.getBooleanOption(EXECUTABLES_MANAGER_DEBUG_TRACING, false);
|
||||||
|
} finally {
|
||||||
|
// we have what we want - release the service
|
||||||
|
context.ungetService(reference);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshJob.setPriority(Job.SHORT);
|
||||||
|
|
||||||
|
// load the extension points
|
||||||
|
loadExecutableProviderExtensions();
|
||||||
|
loadSoureFileProviderExtensions();
|
||||||
|
loadSoureRemappingExtensions();
|
||||||
|
loadExecutableImporterExtensions();
|
||||||
|
|
||||||
|
// add the standard providers
|
||||||
|
executableProviders.add(0, new StandardExecutableProvider());
|
||||||
|
sourceFileProviders.add(0, new StandardSourceFilesProvider());
|
||||||
|
sourceFileRemappings.add(0, new StandardSourceFileRemapping());
|
||||||
|
executableImporters.add(0, new StandardExecutableImporter());
|
||||||
|
|
||||||
|
// listen for events we're interested in
|
||||||
|
ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE | IResourceChangeEvent.POST_BUILD);
|
||||||
|
CoreModel.getDefault().getProjectDescriptionManager().addCProjectDescriptionListener(this,
|
||||||
|
CProjectDescriptionEvent.APPLIED);
|
||||||
|
|
||||||
|
// schedule a refresh so we get up to date
|
||||||
|
scheduleRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an executable listener
|
||||||
|
* @param listener the listener to add
|
||||||
|
*/
|
||||||
public void addExecutablesChangeListener(IExecutablesChangeListener listener) {
|
public void addExecutablesChangeListener(IExecutablesChangeListener listener) {
|
||||||
changeListeners.add(listener);
|
changeListeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an executable listener
|
||||||
|
* @param listener the listener to remove
|
||||||
|
*/
|
||||||
public void removeExecutablesChangeListener(IExecutablesChangeListener listener) {
|
public void removeExecutablesChangeListener(IExecutablesChangeListener listener) {
|
||||||
changeListeners.remove(listener);
|
changeListeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addSourceFileRemapping(ISourceFileRemapping remapping) {
|
|
||||||
sourceFileRemappings.add(remapping);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeSourceFileRemapping(ISourceFileRemapping remapping) {
|
|
||||||
sourceFileRemappings.remove(remapping);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addExecutableImporter(IExecutableImporter importer) {
|
|
||||||
executableImporters.add(importer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeExecutableImporter(IExecutableImporter importer) {
|
|
||||||
executableImporters.remove(importer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addExecutablesProvider(IExecutableProvider provider) {
|
|
||||||
executableProviders.add(provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 6.0
|
* Gets the list of executables in the workspace.
|
||||||
|
* @param wait whether or not to wait if the list is being refreshed when this
|
||||||
|
* method is called. when true, this call will not return until the list is
|
||||||
|
* complete. when false, it will return with the last known list. if calling
|
||||||
|
* from any UI, you should not block the UI waiting for this to return, but rather
|
||||||
|
* register as an {@link IExecutablesChangeListener} to get notifications when the
|
||||||
|
* list changes.
|
||||||
|
* @return the list of executables which may be empty
|
||||||
|
* @since 7.0
|
||||||
*/
|
*/
|
||||||
public void addSourceFilesProvider(ISourceFilesProvider provider) {
|
public Collection<Executable> getExecutables(boolean wait) {
|
||||||
sourceFileProviders.add(provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
trace("getExecutables called at " + getStringFromTimestamp(System.currentTimeMillis())); //$NON-NLS-1$
|
||||||
* @since 6.0
|
|
||||||
*/
|
|
||||||
public void removeSourceFilesProvider(ISourceFilesProvider provider) {
|
|
||||||
sourceFileProviders.remove(provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeExecutablesProvider(IExecutableProvider provider) {
|
List<Executable> executables = new ArrayList<Executable>();
|
||||||
executableProviders.remove(provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IStatus refreshExecutables(IProgressMonitor monitor) {
|
if (wait && refreshJob.getState() != Job.NONE) {
|
||||||
if (tempDisableRefresh) {
|
trace("waiting for refresh job to finish at " + getStringFromTimestamp(System.currentTimeMillis())); //$NON-NLS-1$
|
||||||
return Status.OK_STATUS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
synchronized (executables) {
|
|
||||||
HashMap<String, Executable> oldList = new HashMap<String, Executable>(executables);
|
|
||||||
executables.clear();
|
|
||||||
|
|
||||||
IExecutableProvider[] exeProviders = getExecutableProviders();
|
|
||||||
|
|
||||||
Arrays.sort(exeProviders, new Comparator<IExecutableProvider>() {
|
|
||||||
|
|
||||||
public int compare(IExecutableProvider arg0, IExecutableProvider arg1) {
|
|
||||||
int p0 = arg0.getPriority();
|
|
||||||
int p1 = arg1.getPriority();
|
|
||||||
if (p0 > p1)
|
|
||||||
return 1;
|
|
||||||
if (p0 < p1)
|
|
||||||
return -1;
|
|
||||||
return 0;
|
|
||||||
}});
|
|
||||||
|
|
||||||
refreshNeeded = false;
|
|
||||||
monitor.beginTask("Refresh Executables", exeProviders.length);
|
|
||||||
for (IExecutableProvider provider : exeProviders) {
|
|
||||||
Executable[] exes = provider.getExecutables(new SubProgressMonitor(monitor, 1));
|
|
||||||
for (Executable executable : exes) {
|
|
||||||
executables.put(executable.getPath().toOSString(), executable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
monitor.done();
|
|
||||||
|
|
||||||
synchronized (changeListeners) {
|
|
||||||
Collection<Executable> newExes = executables.values();
|
|
||||||
Executable[] exeArray = newExes.toArray(new Executable[newExes.size()]);
|
|
||||||
Collection<Executable> oldExes = oldList.values();
|
|
||||||
Executable[] oldArray = oldExes.toArray(new Executable[oldExes.size()]);
|
|
||||||
for (IExecutablesChangeListener listener : changeListeners) {
|
|
||||||
listener.executablesChanged(new ExecutablesChangeEvent(oldArray, exeArray));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return monitor.isCanceled() ? Status.CANCEL_STATUS : Status.OK_STATUS;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Executable[] getExecutables() {
|
|
||||||
if (refreshNeeded) {
|
|
||||||
try {
|
try {
|
||||||
refreshJob.schedule();
|
|
||||||
refreshJob.join();
|
refreshJob.join();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
DebugPlugin.log( e );
|
}
|
||||||
|
trace("refresh job finished at " + getStringFromTimestamp(System.currentTimeMillis())); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (executablesMap) {
|
||||||
|
for (List<Executable> exes : executablesMap.values()) {
|
||||||
|
for (Executable exe : exes) {
|
||||||
|
if (!executables.contains(exe)) {
|
||||||
|
executables.add(exe);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized (executables)
|
trace("getExecutables returned at " + getStringFromTimestamp(System.currentTimeMillis())); //$NON-NLS-1$
|
||||||
{
|
|
||||||
Collection<Executable> exes = executables.values();
|
return executables;
|
||||||
return exes.toArray(new Executable[exes.size()]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Gets the list of executables in the workspace. Equivalent to {@link ExecutablesManager}{@link #getExecutables(false)}.
|
||||||
|
* Just kept for older API compatibility.
|
||||||
|
* @return the list of executables which may be empty
|
||||||
|
* @since 7.0
|
||||||
|
*/
|
||||||
|
public Collection<Executable> getExecutables() {
|
||||||
|
return getExecutables(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 7.0
|
||||||
|
* Gets the collection of executables for the given project
|
||||||
|
* @param project the project
|
||||||
|
* @return collection of executables which may be empty
|
||||||
|
*/
|
||||||
|
public Collection<Executable> getExecutablesForProject(IProject project) {
|
||||||
|
List<Executable> executables = new ArrayList<Executable>();
|
||||||
|
|
||||||
|
synchronized (executablesMap) {
|
||||||
|
List<Executable> exes = executablesMap.get(project);
|
||||||
|
if (exes != null) {
|
||||||
|
for (Executable exe : exes) {
|
||||||
|
if (!executables.contains(exe)) {
|
||||||
|
executables.add(exe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return executables;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
* @since 6.0
|
||||||
*/
|
*/
|
||||||
public String remapSourceFile(Executable executable, String filePath) {
|
public String remapSourceFile(Executable executable, String filePath) {
|
||||||
synchronized (sourceFileRemappings) {
|
synchronized (sourceFileRemappings) {
|
||||||
for (ISourceFileRemapping remapping : sourceFileRemappings) {
|
for (ISourceFileRemapping remapping : sourceFileRemappings) {
|
||||||
String remappedPath = remapping.remapSourceFile(executable, filePath);
|
String remappedPath = remapping.remapSourceFile(executable.getPath(), filePath);
|
||||||
if (!remappedPath.equals(filePath))
|
if (!remappedPath.equals(filePath))
|
||||||
return remappedPath;
|
return remappedPath;
|
||||||
}
|
}
|
||||||
|
@ -203,82 +286,70 @@ public class ExecutablesManager extends PlatformObject {
|
||||||
return filePath;
|
return filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import the given executables into the manager
|
||||||
|
* @param fileNames the absolute paths of the executables to import
|
||||||
|
* @param monitor progress monitor
|
||||||
|
*/
|
||||||
public void importExecutables(final String[] fileNames, IProgressMonitor monitor) {
|
public void importExecutables(final String[] fileNames, IProgressMonitor monitor) {
|
||||||
|
|
||||||
boolean handled = false;
|
boolean handled = false;
|
||||||
try {
|
monitor.beginTask("Import Executables", executableImporters.size()); //$NON-NLS-1$
|
||||||
|
synchronized (executableImporters) {
|
||||||
|
Collections.sort(executableImporters, new Comparator<IExecutableImporter>() {
|
||||||
|
|
||||||
tempDisableRefresh = true;
|
public int compare(IExecutableImporter arg0, IExecutableImporter arg1) {
|
||||||
monitor.beginTask("Import Executables", executableImporters.size());
|
int p0 = arg0.getPriority(fileNames);
|
||||||
synchronized (executableImporters) {
|
int p1 = arg1.getPriority(fileNames);
|
||||||
Collections.sort(executableImporters, new Comparator<IExecutableImporter>() {
|
if (p0 < p1)
|
||||||
|
return 1;
|
||||||
|
if (p0 > p1)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}});
|
||||||
|
|
||||||
public int compare(IExecutableImporter arg0, IExecutableImporter arg1) {
|
for (IExecutableImporter importer : executableImporters) {
|
||||||
int p0 = arg0.getPriority(fileNames);
|
handled = importer.importExecutables(fileNames, new SubProgressMonitor(monitor, 1));
|
||||||
int p1 = arg1.getPriority(fileNames);
|
if (handled || monitor.isCanceled()) {
|
||||||
if (p0 < p1)
|
break;
|
||||||
return 1;
|
|
||||||
if (p0 > p1)
|
|
||||||
return -1;
|
|
||||||
return 0;
|
|
||||||
}});
|
|
||||||
|
|
||||||
for (IExecutableImporter importer : executableImporters) {
|
|
||||||
handled = importer.importExecutables(fileNames, new SubProgressMonitor(monitor, 1));
|
|
||||||
if (handled || monitor.isCanceled()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} finally {
|
|
||||||
tempDisableRefresh = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handled)
|
if (handled)
|
||||||
refreshExecutables(monitor);
|
scheduleRefresh();
|
||||||
monitor.done();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ISourceFileRemapping[] getSourceFileRemappings() {
|
|
||||||
return sourceFileRemappings.toArray(new ISourceFileRemapping[sourceFileRemappings.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IExecutableProvider[] getExecutableProviders() {
|
|
||||||
return executableProviders.toArray(new IExecutableProvider[executableProviders.size()]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 6.0
|
* Determines if the given executable is currently known by the manager
|
||||||
|
* @param exePath the absolute path to the executable
|
||||||
|
* @return true if the manager knows about it, false otherwise
|
||||||
*/
|
*/
|
||||||
public ISourceFilesProvider[] getSourceFileProviders() {
|
|
||||||
return sourceFileProviders.toArray(new ISourceFilesProvider[sourceFileProviders.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IExecutableImporter[] getExecutableImporters() {
|
|
||||||
return executableImporters.toArray(new IExecutableImporter[executableImporters.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void scheduleRefresh(IExecutableProvider provider, long delay) {
|
|
||||||
refreshNeeded = true;
|
|
||||||
refreshJob.schedule(delay);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean refreshNeeded() {
|
|
||||||
return refreshNeeded;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean executableExists(IPath exePath) {
|
public boolean executableExists(IPath exePath) {
|
||||||
synchronized (executables) {
|
synchronized (executablesMap) {
|
||||||
return executables.containsKey(exePath.toOSString());
|
for (List<Executable> exes : executablesMap.values()) {
|
||||||
|
for (Executable exe : exes) {
|
||||||
|
if (exe.getPath().equals(exePath)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 6.0
|
* Get the list of source files for the given executable
|
||||||
|
* @param executable the executable
|
||||||
|
* @param monitor progress monitor
|
||||||
|
* @return an array of source files which may be empty
|
||||||
*/
|
*/
|
||||||
public String[] getSourceFiles(final Executable executable,
|
public String[] getSourceFiles(final Executable executable, IProgressMonitor monitor) {
|
||||||
IProgressMonitor monitor) {
|
|
||||||
String[] result = new String[0];
|
String[] result = new String[0];
|
||||||
|
|
||||||
|
trace("getSourceFiles called at " + getStringFromTimestamp(System.currentTimeMillis()) + " for " + executable.getPath().toOSString()); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
|
|
||||||
synchronized (sourceFileProviders) {
|
synchronized (sourceFileProviders) {
|
||||||
Collections.sort(sourceFileProviders, new Comparator<ISourceFilesProvider>() {
|
Collections.sort(sourceFileProviders, new Comparator<ISourceFilesProvider>() {
|
||||||
|
|
||||||
|
@ -292,70 +363,426 @@ public class ExecutablesManager extends PlatformObject {
|
||||||
return 0;
|
return 0;
|
||||||
}});
|
}});
|
||||||
|
|
||||||
monitor.beginTask("Finding source files in " + executable.getName(), sourceFileProviders.size());
|
monitor.beginTask("Finding source files in " + executable.getName(), sourceFileProviders.size()); //$NON-NLS-1$
|
||||||
for (ISourceFilesProvider provider : sourceFileProviders) {
|
for (ISourceFilesProvider provider : sourceFileProviders) {
|
||||||
String[] sourceFiles = provider.getSourceFiles(executable, new SubProgressMonitor(monitor, 1));
|
String[] sourceFiles = provider.getSourceFiles(executable, new SubProgressMonitor(monitor, 1));
|
||||||
if (sourceFiles.length > 0)
|
if (sourceFiles.length > 0) {
|
||||||
{
|
|
||||||
result = sourceFiles;
|
result = sourceFiles;
|
||||||
|
|
||||||
|
trace("getSourceFiles got " + sourceFiles.length + " files from " + provider.toString()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
monitor.done();
|
monitor.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace("getSourceFiles returned at " + getStringFromTimestamp(System.currentTimeMillis())); //$NON-NLS-1$
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Removes the given executables
|
||||||
|
* @param executables the array of executables to be removed
|
||||||
|
* @param monitor progress monitor
|
||||||
|
* @return IStatus of the operation
|
||||||
|
*
|
||||||
* @since 6.0
|
* @since 6.0
|
||||||
*/
|
*/
|
||||||
public IStatus removeExecutables(Executable[] executables, IProgressMonitor monitor) {
|
public IStatus removeExecutables(Executable[] executables, IProgressMonitor monitor) {
|
||||||
IExecutableProvider[] exeProviders = getExecutableProviders();
|
MultiStatus status = new MultiStatus(CDebugCorePlugin.PLUGIN_ID, IStatus.WARNING, "Couldn't remove all of the selected executables", null); //$NON-NLS-1$
|
||||||
|
|
||||||
IStatus result = Status.OK_STATUS;
|
monitor.beginTask("Remove Executables", executables.length); //$NON-NLS-1$
|
||||||
|
|
||||||
Arrays.sort(exeProviders, new Comparator<IExecutableProvider>() {
|
|
||||||
|
|
||||||
public int compare(IExecutableProvider arg0, IExecutableProvider arg1) {
|
|
||||||
int p0 = arg0.getPriority();
|
|
||||||
int p1 = arg1.getPriority();
|
|
||||||
if (p0 > p1)
|
|
||||||
return 1;
|
|
||||||
if (p0 < p1)
|
|
||||||
return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
MultiStatus combinedStatus = new MultiStatus(CDebugCorePlugin.PLUGIN_ID, IStatus.WARNING, "Couldn't remove all of the selected executables", null);
|
|
||||||
refreshNeeded = false;
|
|
||||||
monitor.beginTask("Remove Executables", exeProviders.length);
|
|
||||||
for (Executable executable : executables) {
|
for (Executable executable : executables) {
|
||||||
boolean handled = false;
|
|
||||||
IStatus rmvStatus = Status.OK_STATUS;;
|
IProjectExecutablesProvider provider = getExecutablesProviderForProject(executable.getProject());
|
||||||
for (IExecutableProvider provider : exeProviders) {
|
if (provider != null) {
|
||||||
if (!handled)
|
IStatus result = provider.removeExecutable(executable, new SubProgressMonitor(monitor, 1));
|
||||||
{
|
if (result.isOK()) {
|
||||||
rmvStatus = provider.removeExecutable(executable, new SubProgressMonitor(monitor, 1));
|
// remove the exe from the list
|
||||||
handled = rmvStatus.getSeverity() == IStatus.OK;
|
List<Executable> exes = executablesMap.get(executable.getProject());
|
||||||
|
if (exes != null) {
|
||||||
|
exes.remove(executable);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
status.add(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!handled)
|
}
|
||||||
{
|
|
||||||
combinedStatus.add(rmvStatus);
|
// notify listeners that the list has changed. only do this if at least one delete succeeded.
|
||||||
result = combinedStatus;
|
if (status.getChildren().length != executables.length) {
|
||||||
|
synchronized (changeListeners) {
|
||||||
|
for (IExecutablesChangeListener listener : changeListeners) {
|
||||||
|
listener.executablesListChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
monitor.done();
|
|
||||||
|
|
||||||
return result;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 6.0
|
* Refresh the list of executables for the given projects
|
||||||
|
* @param projects the list of projects, or null. if null or the list
|
||||||
|
* is empty, all projects will be refreshed.
|
||||||
|
* @since 7.0
|
||||||
*/
|
*/
|
||||||
public void setRefreshNeeded(boolean refresh) {
|
public void refresh(List<IProject> projects) {
|
||||||
refreshNeeded = true;
|
if (projects == null || projects.size() == 0) {
|
||||||
|
// clear the entire cache
|
||||||
|
executablesMap.clear();
|
||||||
|
} else {
|
||||||
|
for (IProject project : projects) {
|
||||||
|
executablesMap.remove(project);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scheduleRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 7.0
|
||||||
|
*/
|
||||||
|
public void resourceChanged(IResourceChangeEvent event) {
|
||||||
|
|
||||||
|
synchronized (executablesMap) {
|
||||||
|
// project needs to be refreshed after a build/clean as the binary may
|
||||||
|
// be added/removed/renamed etc.
|
||||||
|
if (event.getType() == IResourceChangeEvent.POST_BUILD) {
|
||||||
|
Object obj = event.getSource();
|
||||||
|
if (obj != null && obj instanceof IProject) {
|
||||||
|
try {
|
||||||
|
// make sure there's at least one builder for the project. this gets called even
|
||||||
|
// when there are no builder (e.g. the Executables project for imported executables).
|
||||||
|
IProject project = (IProject)obj;
|
||||||
|
if (project.getDescription().getBuildSpec().length > 0) {
|
||||||
|
if (executablesMap.containsKey(obj)) {
|
||||||
|
List<Executable> executables = executablesMap.remove(obj);
|
||||||
|
|
||||||
|
trace("Scheduling refresh because project " + ((IProject)obj).getName() + " built or cleaned"); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
|
|
||||||
|
scheduleRefresh();
|
||||||
|
|
||||||
|
// notify the listeners that these executables have possibly changed
|
||||||
|
if (executables != null && executables.size() > 0) {
|
||||||
|
synchronized (changeListeners) {
|
||||||
|
for (IExecutablesChangeListener listener : changeListeners) {
|
||||||
|
listener.executablesChanged(executables);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (CoreException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// refresh when projects are opened or closed. note that deleted
|
||||||
|
// projects are handled later in this method. new projects are handled
|
||||||
|
// in handleEvent. resource changed events always start at the workspace
|
||||||
|
// root, so projects are the next level down
|
||||||
|
boolean refreshNeeded = false;
|
||||||
|
IResourceDelta[] projects = event.getDelta().getAffectedChildren();
|
||||||
|
for (IResourceDelta projectDelta : projects) {
|
||||||
|
if ((projectDelta.getFlags() & IResourceDelta.OPEN) != 0) {
|
||||||
|
if (projectDelta.getKind() == IResourceDelta.CHANGED) {
|
||||||
|
// project was opened or closed
|
||||||
|
if (executablesMap.containsKey(projectDelta.getResource())) {
|
||||||
|
executablesMap.remove(projectDelta.getResource());
|
||||||
|
}
|
||||||
|
refreshNeeded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refreshNeeded) {
|
||||||
|
trace("Scheduling refresh because project(s) opened or closed"); //$NON-NLS-1$
|
||||||
|
|
||||||
|
scheduleRefresh();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
event.getDelta().accept(new IResourceDeltaVisitor() {
|
||||||
|
|
||||||
|
public boolean visit(IResourceDelta delta) throws CoreException {
|
||||||
|
if (delta.getKind() == IResourceDelta.ADDED || delta.getKind() == IResourceDelta.REMOVED) {
|
||||||
|
IResource deltaResource = delta.getResource();
|
||||||
|
if (deltaResource != null) {
|
||||||
|
boolean refresh = false;
|
||||||
|
if (delta.getKind() == IResourceDelta.REMOVED && deltaResource instanceof IProject) {
|
||||||
|
// project deleted
|
||||||
|
if (executablesMap.containsKey(deltaResource)) {
|
||||||
|
executablesMap.remove(deltaResource);
|
||||||
|
refresh = true;
|
||||||
|
|
||||||
|
trace("Scheduling refresh because project " + deltaResource.getName() + " deleted"); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// see if a binary has been added/removed
|
||||||
|
IPath resourcePath = deltaResource.getLocation();
|
||||||
|
if (resourcePath != null && Executable.isExecutableFile(resourcePath)) {
|
||||||
|
if (executablesMap.containsKey(deltaResource.getProject())) {
|
||||||
|
executablesMap.remove(deltaResource.getProject());
|
||||||
|
refresh = true;
|
||||||
|
|
||||||
|
trace("Scheduling refresh because a binary was added/removed"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refresh) {
|
||||||
|
scheduleRefresh();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (CoreException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 7.0
|
||||||
|
*/
|
||||||
|
public void handleEvent(CProjectDescriptionEvent event) {
|
||||||
|
// this handles the cases where the active build configuration changes,
|
||||||
|
// and when new projects are created or loaded at startup.
|
||||||
|
boolean refresh = false;
|
||||||
|
|
||||||
|
int eventType = event.getEventType();
|
||||||
|
|
||||||
|
if (eventType == CProjectDescriptionEvent.APPLIED) {
|
||||||
|
|
||||||
|
synchronized (executablesMap) {
|
||||||
|
// see if the active build config has changed
|
||||||
|
ICProjectDescription newDesc = event.getNewCProjectDescription();
|
||||||
|
ICProjectDescription oldDesc = event.getOldCProjectDescription();
|
||||||
|
if (oldDesc != null && newDesc != null) {
|
||||||
|
String newConfigName = newDesc.getActiveConfiguration().getName();
|
||||||
|
String oldConfigName = oldDesc.getActiveConfiguration().getName();
|
||||||
|
if (!newConfigName.equals(oldConfigName)) {
|
||||||
|
if (executablesMap.containsKey(newDesc.getProject())) {
|
||||||
|
executablesMap.remove(newDesc.getProject());
|
||||||
|
refresh = true;
|
||||||
|
|
||||||
|
trace("Scheduling refresh because active build configuration changed"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (newDesc != null && oldDesc == null) {
|
||||||
|
// project just created
|
||||||
|
refresh = true;
|
||||||
|
|
||||||
|
trace("Scheduling refresh because project " + newDesc.getProject().getName() + " created"); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refresh) {
|
||||||
|
scheduleRefresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<IProject> getProjectsToCheck() {
|
||||||
|
|
||||||
|
List<IProject> projects = new ArrayList<IProject>();
|
||||||
|
|
||||||
|
synchronized (executablesMap) {
|
||||||
|
// look for any CDT projects not in our cache
|
||||||
|
for (IProject project : ResourcesPlugin.getWorkspace().getRoot().getProjects()) {
|
||||||
|
if (!executablesMap.containsKey(project)) {
|
||||||
|
if (CoreModel.hasCNature(project)) {
|
||||||
|
projects.add(project);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return projects;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scheduleRefresh() {
|
||||||
|
trace("scheduleRefresh called at " + getStringFromTimestamp(System.currentTimeMillis())); //$NON-NLS-1$
|
||||||
|
|
||||||
|
refreshJob.cancel();
|
||||||
|
refreshJob.schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
private IProjectExecutablesProvider getExecutablesProviderForProject(IProject project) {
|
||||||
|
IProjectExecutablesProvider provider = executablesProviderMap.get(project);
|
||||||
|
if (provider == null) {
|
||||||
|
// not cached yet. get the list of project natures from the providers and
|
||||||
|
// pick the one with the closest match
|
||||||
|
try {
|
||||||
|
IProjectDescription description = project.getDescription();
|
||||||
|
int mostNaturesMatched = 0;
|
||||||
|
for (IProjectExecutablesProvider exeProvider : executableProviders) {
|
||||||
|
List<String> natures = exeProvider.getProjectNatures();
|
||||||
|
|
||||||
|
int naturesMatched = 0;
|
||||||
|
for (String nature : description.getNatureIds()) {
|
||||||
|
if (natures.contains(nature)) {
|
||||||
|
naturesMatched++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (naturesMatched > mostNaturesMatched) {
|
||||||
|
provider = exeProvider;
|
||||||
|
mostNaturesMatched = naturesMatched;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// cache it
|
||||||
|
executablesProviderMap.put(project, provider);
|
||||||
|
|
||||||
|
} catch (CoreException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadExecutableProviderExtensions() {
|
||||||
|
executableProviders = Collections.synchronizedList(new ArrayList<IProjectExecutablesProvider>());
|
||||||
|
|
||||||
|
IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
|
||||||
|
IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(CDebugCorePlugin.PLUGIN_ID + ".ExecutablesProvider"); //$NON-NLS-1$
|
||||||
|
IExtension[] extensions = extensionPoint.getExtensions();
|
||||||
|
|
||||||
|
for (int i = 0; i < extensions.length; i++) {
|
||||||
|
IExtension extension = extensions[i];
|
||||||
|
IConfigurationElement[] elements = extension.getConfigurationElements();
|
||||||
|
IConfigurationElement element = elements[0];
|
||||||
|
|
||||||
|
boolean failed = false;
|
||||||
|
try {
|
||||||
|
Object extObject = element.createExecutableExtension("class"); //$NON-NLS-1$
|
||||||
|
if (extObject instanceof IProjectExecutablesProvider) {
|
||||||
|
executableProviders.add((IProjectExecutablesProvider)extObject);
|
||||||
|
} else {
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (CoreException e) {
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failed) {
|
||||||
|
CDebugCorePlugin.log("Unable to load ExecutablesProvider extension from " + extension.getContributor().getName()); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadSoureFileProviderExtensions() {
|
||||||
|
sourceFileProviders = Collections.synchronizedList(new ArrayList<ISourceFilesProvider>());
|
||||||
|
|
||||||
|
IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
|
||||||
|
IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(CDebugCorePlugin.PLUGIN_ID + ".SourceFilesProvider"); //$NON-NLS-1$
|
||||||
|
IExtension[] extensions = extensionPoint.getExtensions();
|
||||||
|
|
||||||
|
for (int i = 0; i < extensions.length; i++) {
|
||||||
|
IExtension extension = extensions[i];
|
||||||
|
IConfigurationElement[] elements = extension.getConfigurationElements();
|
||||||
|
IConfigurationElement element = elements[0];
|
||||||
|
|
||||||
|
boolean failed = false;
|
||||||
|
try {
|
||||||
|
Object extObject = element.createExecutableExtension("class"); //$NON-NLS-1$
|
||||||
|
if (extObject instanceof ISourceFilesProvider) {
|
||||||
|
sourceFileProviders.add((ISourceFilesProvider)extObject);
|
||||||
|
} else {
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (CoreException e) {
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failed) {
|
||||||
|
CDebugCorePlugin.log("Unable to load SourceFilesProvider extension from " + extension.getContributor().getName()); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadSoureRemappingExtensions() {
|
||||||
|
sourceFileRemappings = Collections.synchronizedList(new ArrayList<ISourceFileRemapping>());
|
||||||
|
|
||||||
|
IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
|
||||||
|
IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(CDebugCorePlugin.PLUGIN_ID + ".SourceRemappingProvider"); //$NON-NLS-1$
|
||||||
|
IExtension[] extensions = extensionPoint.getExtensions();
|
||||||
|
|
||||||
|
for (int i = 0; i < extensions.length; i++) {
|
||||||
|
IExtension extension = extensions[i];
|
||||||
|
IConfigurationElement[] elements = extension.getConfigurationElements();
|
||||||
|
IConfigurationElement element = elements[0];
|
||||||
|
|
||||||
|
boolean failed = false;
|
||||||
|
try {
|
||||||
|
Object extObject = element.createExecutableExtension("class"); //$NON-NLS-1$
|
||||||
|
if (extObject instanceof ISourceFileRemapping) {
|
||||||
|
sourceFileRemappings.add((ISourceFileRemapping)extObject);
|
||||||
|
} else {
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (CoreException e) {
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failed) {
|
||||||
|
CDebugCorePlugin.log("Unable to load SourceRemappingProvider extension from " + extension.getContributor().getName()); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadExecutableImporterExtensions() {
|
||||||
|
executableImporters = Collections.synchronizedList(new ArrayList<IExecutableImporter>());
|
||||||
|
|
||||||
|
IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
|
||||||
|
IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(CDebugCorePlugin.PLUGIN_ID + ".ExecutablesImporter"); //$NON-NLS-1$
|
||||||
|
IExtension[] extensions = extensionPoint.getExtensions();
|
||||||
|
|
||||||
|
for (int i = 0; i < extensions.length; i++) {
|
||||||
|
IExtension extension = extensions[i];
|
||||||
|
IConfigurationElement[] elements = extension.getConfigurationElements();
|
||||||
|
IConfigurationElement element = elements[0];
|
||||||
|
|
||||||
|
boolean failed = false;
|
||||||
|
try {
|
||||||
|
Object extObject = element.createExecutableExtension("class"); //$NON-NLS-1$
|
||||||
|
if (extObject instanceof IExecutableImporter) {
|
||||||
|
executableImporters.add((IExecutableImporter)extObject);
|
||||||
|
} else {
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (CoreException e) {
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failed) {
|
||||||
|
CDebugCorePlugin.log("Unable to load ExecutablesImporter extension from " + extension.getContributor().getName()); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void trace(String msg) {
|
||||||
|
if (DEBUG) {
|
||||||
|
// TODO use Logger?
|
||||||
|
System.out.println(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getStringFromTimestamp(long timestamp) {
|
||||||
|
return DateFormat.getTimeInstance(DateFormat.MEDIUM).format(new Date(timestamp));
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -42,6 +42,6 @@ public interface IExecutableImporter {
|
||||||
/**
|
/**
|
||||||
* @since 6.0
|
* @since 6.0
|
||||||
*/
|
*/
|
||||||
public abstract boolean importExecutables(String[] fileNames, IProgressMonitor monitor);
|
public boolean importExecutables(String[] fileNames, IProgressMonitor monitor);
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,59 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2008 Nokia 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:
|
|
||||||
* Nokia - Initial API and implementation
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.eclipse.cdt.debug.core.executables;
|
|
||||||
|
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
|
||||||
import org.eclipse.core.runtime.IStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IExecutablesProvider supplies a list of executables to the Executables
|
|
||||||
* Manager.
|
|
||||||
*
|
|
||||||
* @author Ken Ryall
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface IExecutableProvider {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @since 6.0
|
|
||||||
*/
|
|
||||||
public static final int LOW_PRIORITY = 25;
|
|
||||||
/**
|
|
||||||
* @since 6.0
|
|
||||||
*/
|
|
||||||
public static final int NORMAL_PRIORITY = 50;
|
|
||||||
/**
|
|
||||||
* @since 6.0
|
|
||||||
*/
|
|
||||||
public static final int HIGH_PRIORITY = 75;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the priority to be used when providing a list of executables.
|
|
||||||
* The priority is used by the Executables Manager when multiple IExecutableProvider are available.
|
|
||||||
* IExecutableImporter.importExecutables will be called for each one in priority order.
|
|
||||||
*
|
|
||||||
* @param executable
|
|
||||||
* @return the priority level to be used for this ISourceFilesProvider
|
|
||||||
* @since 6.0
|
|
||||||
*/
|
|
||||||
int getPriority();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @since 6.0
|
|
||||||
*/
|
|
||||||
Executable[] getExecutables(IProgressMonitor monitor);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @since 6.0
|
|
||||||
*/
|
|
||||||
IStatus removeExecutable(Executable executable, IProgressMonitor monitor);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2008 Nokia 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:
|
|
||||||
* Nokia - Initial API and implementation
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
package org.eclipse.cdt.debug.core.executables;
|
|
||||||
|
|
||||||
|
|
||||||
public interface IExecutablesChangeEvent {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @since 6.0
|
|
||||||
*/
|
|
||||||
public Executable[] getCurrentExecutables();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @since 6.0
|
|
||||||
*/
|
|
||||||
public Executable[] getPreviousExecutables();
|
|
||||||
}
|
|
|
@ -12,9 +12,23 @@
|
||||||
package org.eclipse.cdt.debug.core.executables;
|
package org.eclipse.cdt.debug.core.executables;
|
||||||
|
|
||||||
import java.util.EventListener;
|
import java.util.EventListener;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public interface IExecutablesChangeListener extends EventListener {
|
public interface IExecutablesChangeListener extends EventListener {
|
||||||
|
|
||||||
public void executablesChanged(IExecutablesChangeEvent event);
|
/**
|
||||||
|
* Called whenever the list of executables in the workspace changes, e.g. a
|
||||||
|
* project was opened/closed/created/deleted
|
||||||
|
* @since 7.0
|
||||||
|
*/
|
||||||
|
public void executablesListChanged();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called whenever some executables have changed, e.g. when a project is rebuilt or
|
||||||
|
* cleaned. The content may have changed for example, so the list of source files
|
||||||
|
* may be different.
|
||||||
|
* @param executables
|
||||||
|
* @since 7.0
|
||||||
|
*/
|
||||||
|
public void executablesChanged(List<Executable> executables);
|
||||||
}
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2009 Nokia 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:
|
||||||
|
* Nokia - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.debug.core.executables;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IProjectExecutablesProvider supplies a list of executables for a project
|
||||||
|
* to the Executables Manager.
|
||||||
|
*
|
||||||
|
* @author Warren Paul
|
||||||
|
* @since 7.0
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface IProjectExecutablesProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of project natures that should be present in projects that
|
||||||
|
* this provider will get the list of executables for. Since there could
|
||||||
|
* be any number of executable providers, the one that matches the given
|
||||||
|
* project natures the closest will be chosen.
|
||||||
|
* @return the list of project nature id's
|
||||||
|
*/
|
||||||
|
List<String> getProjectNatures();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of executables for the given project
|
||||||
|
* @param project the project to get the executables for
|
||||||
|
* @param monitor progress monitor
|
||||||
|
* @return the list of executables (which may be empty)
|
||||||
|
*/
|
||||||
|
List<Executable> getExecutables(IProject project, IProgressMonitor monitor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the given executable. Note that the project can be obtained from Executable.
|
||||||
|
* @param executable the executable to remove
|
||||||
|
* @param monitor progress monitor
|
||||||
|
* @return the status of the remove operation
|
||||||
|
*/
|
||||||
|
IStatus removeExecutable(Executable executable, IProgressMonitor monitor);
|
||||||
|
|
||||||
|
}
|
|
@ -10,6 +10,7 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.debug.core.executables;
|
package org.eclipse.cdt.debug.core.executables;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ISourceFileRemapping is used by the Executables Manager when finding missing
|
* ISourceFileRemapping is used by the Executables Manager when finding missing
|
||||||
|
@ -21,8 +22,8 @@ package org.eclipse.cdt.debug.core.executables;
|
||||||
public interface ISourceFileRemapping {
|
public interface ISourceFileRemapping {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 6.0
|
* @since 7.0
|
||||||
*/
|
*/
|
||||||
String remapSourceFile(Executable executable, String filePath);
|
String remapSourceFile(IPath executable, String filePath);
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 Nokia 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:
|
||||||
|
* Nokia - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.debug.core.executables;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.CCProjectNature;
|
||||||
|
import org.eclipse.cdt.core.CProjectNature;
|
||||||
|
import org.eclipse.cdt.core.model.CModelException;
|
||||||
|
import org.eclipse.cdt.core.model.IBinary;
|
||||||
|
import org.eclipse.cdt.core.model.ICProject;
|
||||||
|
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
|
||||||
|
import org.eclipse.cdt.internal.core.model.CModelManager;
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.resources.IResource;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
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.core.runtime.SubMonitor;
|
||||||
|
import org.eclipse.debug.core.DebugPlugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 7.0
|
||||||
|
*/
|
||||||
|
public class StandardExecutableProvider implements IProjectExecutablesProvider {
|
||||||
|
|
||||||
|
List<String> supportedNatureIds = new ArrayList<String>();
|
||||||
|
|
||||||
|
public StandardExecutableProvider() {
|
||||||
|
supportedNatureIds.add(CProjectNature.C_NATURE_ID);
|
||||||
|
supportedNatureIds.add(CCProjectNature.CC_NATURE_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getProjectNatures() {
|
||||||
|
return supportedNatureIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Executable> getExecutables(IProject project, IProgressMonitor monitor) {
|
||||||
|
List<Executable> executables = new ArrayList<Executable>();
|
||||||
|
|
||||||
|
ICProject cproject = CModelManager.getDefault().create(project);
|
||||||
|
try {
|
||||||
|
IBinary[] binaries = cproject.getBinaryContainer().getBinaries();
|
||||||
|
|
||||||
|
SubMonitor progress = SubMonitor.convert(monitor, binaries.length);
|
||||||
|
|
||||||
|
for (IBinary binary : binaries) {
|
||||||
|
if (progress.isCanceled()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binary.isExecutable() || binary.isSharedLib()) {
|
||||||
|
IPath exePath = binary.getResource().getLocation();
|
||||||
|
if (exePath == null)
|
||||||
|
exePath = binary.getPath();
|
||||||
|
executables.add(new Executable(exePath, project, binary.getResource()));
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.worked(1);
|
||||||
|
}
|
||||||
|
} catch (CModelException e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
return executables;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IStatus removeExecutable(Executable executable, IProgressMonitor monitor) {
|
||||||
|
IResource exeResource = executable.getResource();
|
||||||
|
if (exeResource != null) {
|
||||||
|
try {
|
||||||
|
exeResource.delete(true, monitor);
|
||||||
|
} catch (CoreException e) {
|
||||||
|
DebugPlugin.log( e );
|
||||||
|
}
|
||||||
|
return Status.OK_STATUS;
|
||||||
|
}
|
||||||
|
return new Status(IStatus.WARNING, CDebugCorePlugin.PLUGIN_ID, "Can't remove " + executable.getName() + ": it is built by project \"" + executable.getProject().getName() + "\""); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,35 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2008 Nokia 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:
|
|
||||||
* Nokia - Initial API and implementation
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.eclipse.cdt.debug.internal.core.executables;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.debug.core.executables.Executable;
|
|
||||||
import org.eclipse.cdt.debug.core.executables.IExecutablesChangeEvent;
|
|
||||||
import org.eclipse.core.runtime.PlatformObject;
|
|
||||||
|
|
||||||
public class ExecutablesChangeEvent extends PlatformObject implements IExecutablesChangeEvent {
|
|
||||||
|
|
||||||
private Executable[] oldExecutables;
|
|
||||||
private Executable[] newExecutables;
|
|
||||||
|
|
||||||
public ExecutablesChangeEvent(Executable[] oldList, Executable[] newList) {
|
|
||||||
oldExecutables = oldList;
|
|
||||||
newExecutables = newList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Executable[] getCurrentExecutables() {
|
|
||||||
return newExecutables;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Executable[] getPreviousExecutables() {
|
|
||||||
return oldExecutables;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -59,7 +59,7 @@ public class StandardExecutableImporter implements IExecutableImporter {
|
||||||
* org.eclipse.core.runtime.IProgressMonitor)
|
* org.eclipse.core.runtime.IProgressMonitor)
|
||||||
*/
|
*/
|
||||||
public boolean importExecutables(String[] fileNames, IProgressMonitor monitor) {
|
public boolean importExecutables(String[] fileNames, IProgressMonitor monitor) {
|
||||||
monitor.beginTask("Import Executables", fileNames.length);
|
monitor.beginTask("Import Executables", fileNames.length); //$NON-NLS-1$
|
||||||
|
|
||||||
IProject exeProject = null;
|
IProject exeProject = null;
|
||||||
boolean checkProject = false;
|
boolean checkProject = false;
|
||||||
|
@ -74,7 +74,7 @@ public class StandardExecutableImporter implements IExecutableImporter {
|
||||||
if (AllowImport(Path.fromOSString(path))) {
|
if (AllowImport(Path.fromOSString(path))) {
|
||||||
if (!checkProject) {
|
if (!checkProject) {
|
||||||
// See if the default project exists
|
// See if the default project exists
|
||||||
String defaultProjectName = "Executables";
|
String defaultProjectName = "Executables"; //$NON-NLS-1$
|
||||||
ICProject cProject = CoreModel.getDefault().getCModel().getCProject(defaultProjectName);
|
ICProject cProject = CoreModel.getDefault().getCModel().getCProject(defaultProjectName);
|
||||||
if (cProject.exists()) {
|
if (cProject.exists()) {
|
||||||
exeProject = cProject.getProject();
|
exeProject = cProject.getProject();
|
||||||
|
@ -184,8 +184,8 @@ public class StandardExecutableImporter implements IExecutableImporter {
|
||||||
|
|
||||||
private boolean isExtensionVisible(IExtension ext) {
|
private boolean isExtensionVisible(IExtension ext) {
|
||||||
IConfigurationElement[] elements = ext.getConfigurationElements();
|
IConfigurationElement[] elements = ext.getConfigurationElements();
|
||||||
for (int i = 0; i < elements.length; i++) {
|
for (IConfigurationElement element : elements) {
|
||||||
IConfigurationElement[] children = elements[i].getChildren("filter"); //$NON-NLS-1$
|
IConfigurationElement[] children = element.getChildren("filter"); //$NON-NLS-1$
|
||||||
for (int j = 0; j < children.length; j++) {
|
for (int j = 0; j < children.length; j++) {
|
||||||
String name = children[j].getAttribute("name"); //$NON-NLS-1$
|
String name = children[j].getAttribute("name"); //$NON-NLS-1$
|
||||||
if (name != null && name.equals("visibility")) { //$NON-NLS-1$
|
if (name != null && name.equals("visibility")) { //$NON-NLS-1$
|
||||||
|
@ -208,7 +208,7 @@ public class StandardExecutableImporter implements IExecutableImporter {
|
||||||
IConfigurationElement[] children = elements[i].getChildren("run"); //$NON-NLS-1$
|
IConfigurationElement[] children = elements[i].getChildren("run"); //$NON-NLS-1$
|
||||||
for (int j = 0; j < children.length; j++) {
|
for (int j = 0; j < children.length; j++) {
|
||||||
try {
|
try {
|
||||||
parser = (IBinaryParser) children[j].createExecutableExtension("class");
|
parser = (IBinaryParser) children[j].createExecutableExtension("class"); //$NON-NLS-1$
|
||||||
} catch (CoreException e) {
|
} catch (CoreException e) {
|
||||||
CDebugCorePlugin.log(e);
|
CDebugCorePlugin.log(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,194 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2008 Nokia 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:
|
|
||||||
* Nokia - Initial API and implementation
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
package org.eclipse.cdt.debug.internal.core.executables;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.core.model.CModelException;
|
|
||||||
import org.eclipse.cdt.core.model.CoreModel;
|
|
||||||
import org.eclipse.cdt.core.model.IBinary;
|
|
||||||
import org.eclipse.cdt.core.model.ICProject;
|
|
||||||
import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent;
|
|
||||||
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.core.executables.Executable;
|
|
||||||
import org.eclipse.cdt.debug.core.executables.ExecutablesManager;
|
|
||||||
import org.eclipse.cdt.debug.core.executables.IExecutableProvider;
|
|
||||||
import org.eclipse.cdt.internal.core.model.CModelManager;
|
|
||||||
import org.eclipse.core.resources.IProject;
|
|
||||||
import org.eclipse.core.resources.IResource;
|
|
||||||
import org.eclipse.core.resources.IResourceChangeEvent;
|
|
||||||
import org.eclipse.core.resources.IResourceChangeListener;
|
|
||||||
import org.eclipse.core.resources.IResourceDelta;
|
|
||||||
import org.eclipse.core.resources.IResourceDeltaVisitor;
|
|
||||||
import org.eclipse.core.resources.IWorkspaceRoot;
|
|
||||||
import org.eclipse.core.resources.ResourcesPlugin;
|
|
||||||
import org.eclipse.core.runtime.CoreException;
|
|
||||||
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;
|
|
||||||
|
|
||||||
public class StandardExecutableProvider implements IResourceChangeListener, ICProjectDescriptionListener, IExecutableProvider {
|
|
||||||
|
|
||||||
private ArrayList<Executable> executables = new ArrayList<Executable>();
|
|
||||||
|
|
||||||
public StandardExecutableProvider() {
|
|
||||||
ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE);
|
|
||||||
CoreModel.getDefault().getProjectDescriptionManager().addCProjectDescriptionListener(this,
|
|
||||||
CProjectDescriptionEvent.DATA_APPLIED | CProjectDescriptionEvent.LOADED);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resourceChanged(IResourceChangeEvent event) {
|
|
||||||
|
|
||||||
// refresh when projects are opened or closed. note that deleted
|
|
||||||
// projects are handled later
|
|
||||||
// in this method. new projects are handled in handleEvent.
|
|
||||||
// resource changed events always start at the workspace root, so
|
|
||||||
// projects
|
|
||||||
// are the next level down
|
|
||||||
IResourceDelta[] projects = event.getDelta().getAffectedChildren();
|
|
||||||
for (IResourceDelta projectDelta : projects) {
|
|
||||||
if ((projectDelta.getFlags() & IResourceDelta.OPEN) != 0) {
|
|
||||||
if (projectDelta.getKind() == IResourceDelta.CHANGED) {
|
|
||||||
// project was opened or closed
|
|
||||||
ExecutablesManager.getExecutablesManager().scheduleRefresh(this, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
final StandardExecutableProvider provider = this;
|
|
||||||
event.getDelta().accept(new IResourceDeltaVisitor() {
|
|
||||||
|
|
||||||
public boolean visit(IResourceDelta delta) throws CoreException {
|
|
||||||
if (delta.getKind() == IResourceDelta.ADDED || delta.getKind() == IResourceDelta.REMOVED) {
|
|
||||||
IResource deltaResource = delta.getResource();
|
|
||||||
if (deltaResource != null) {
|
|
||||||
boolean refresh = false;
|
|
||||||
if (delta.getKind() == IResourceDelta.REMOVED && deltaResource instanceof IProject) {
|
|
||||||
// project deleted
|
|
||||||
refresh = true;
|
|
||||||
} else {
|
|
||||||
// see if a binary has been added/removed
|
|
||||||
IPath resourcePath = delta.getResource().getLocation();
|
|
||||||
if (resourcePath != null && Executable.isExecutableFile(resourcePath)) {
|
|
||||||
refresh = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (refresh) {
|
|
||||||
ExecutablesManager.getExecutablesManager().scheduleRefresh(provider, 0);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (CoreException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleEvent(CProjectDescriptionEvent event) {
|
|
||||||
// this handles the cases where the active build configuration changes,
|
|
||||||
// and when new
|
|
||||||
// projects are created.
|
|
||||||
boolean refresh = false;
|
|
||||||
|
|
||||||
int eventType = event.getEventType();
|
|
||||||
|
|
||||||
if (eventType == CProjectDescriptionEvent.DATA_APPLIED) {
|
|
||||||
// see if the active build config has changed
|
|
||||||
ICProjectDescription newDesc = event.getNewCProjectDescription();
|
|
||||||
ICProjectDescription oldDesc = event.getOldCProjectDescription();
|
|
||||||
if (oldDesc != null && newDesc != null) {
|
|
||||||
String newConfigName = newDesc.getActiveConfiguration().getName();
|
|
||||||
String oldConfigName = oldDesc.getActiveConfiguration().getName();
|
|
||||||
refresh = (!newConfigName.equals(oldConfigName));
|
|
||||||
} else if (newDesc != null && oldDesc == null) {
|
|
||||||
// project just created
|
|
||||||
refresh = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (refresh) {
|
|
||||||
ExecutablesManager.getExecutablesManager().scheduleRefresh(this, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Executable[] getExecutables(IProgressMonitor monitor) {
|
|
||||||
synchronized (executables) {
|
|
||||||
executables.clear();
|
|
||||||
|
|
||||||
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
|
|
||||||
IProject[] projects = root.getProjects();
|
|
||||||
|
|
||||||
monitor.beginTask("Checking C/C++ Projects", projects.length);
|
|
||||||
|
|
||||||
for (IProject project : projects) {
|
|
||||||
|
|
||||||
if (monitor.isCanceled())
|
|
||||||
break;
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (CoreModel.hasCNature(project)) {
|
|
||||||
CModelManager manager = CModelManager.getDefault();
|
|
||||||
ICProject cproject = manager.create(project);
|
|
||||||
try {
|
|
||||||
IBinary[] binaries = cproject.getBinaryContainer().getBinaries();
|
|
||||||
for (IBinary binary : binaries) {
|
|
||||||
if (binary.isExecutable() || binary.isSharedLib()) {
|
|
||||||
IPath exePath = binary.getResource().getLocation();
|
|
||||||
if (exePath == null)
|
|
||||||
exePath = binary.getPath();
|
|
||||||
Executable exe = new Executable(exePath, project, binary.getResource());
|
|
||||||
executables.add(exe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (CModelException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
DebugPlugin.log( e );
|
|
||||||
}
|
|
||||||
monitor.worked(1);
|
|
||||||
}
|
|
||||||
monitor.done();
|
|
||||||
}
|
|
||||||
return executables.toArray(new Executable[executables.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPriority() {
|
|
||||||
return NORMAL_PRIORITY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IStatus removeExecutable(Executable executable, IProgressMonitor monitor) {
|
|
||||||
IResource exeResource = executable.getResource();
|
|
||||||
if (exeResource != null)
|
|
||||||
{
|
|
||||||
if (exeResource.isLinked())
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
exeResource.delete(true, monitor);
|
|
||||||
} catch (CoreException e) {
|
|
||||||
DebugPlugin.log( e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Status.OK_STATUS;
|
|
||||||
}
|
|
||||||
return new Status(IStatus.WARNING, CDebugCorePlugin.PLUGIN_ID, "Can't remove " + executable.getName() + ": it is built by project \"" + executable.getProject().getName() + "\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -12,11 +12,11 @@
|
||||||
package org.eclipse.cdt.debug.internal.core.executables;
|
package org.eclipse.cdt.debug.internal.core.executables;
|
||||||
|
|
||||||
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
|
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
|
||||||
import org.eclipse.cdt.debug.core.executables.Executable;
|
|
||||||
import org.eclipse.cdt.debug.core.executables.ISourceFileRemapping;
|
import org.eclipse.cdt.debug.core.executables.ISourceFileRemapping;
|
||||||
import org.eclipse.cdt.debug.core.sourcelookup.ICSourceLocator;
|
import org.eclipse.cdt.debug.core.sourcelookup.ICSourceLocator;
|
||||||
import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector;
|
import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
import org.eclipse.debug.core.DebugPlugin;
|
import org.eclipse.debug.core.DebugPlugin;
|
||||||
import org.eclipse.debug.core.ILaunch;
|
import org.eclipse.debug.core.ILaunch;
|
||||||
import org.eclipse.debug.core.ILaunchManager;
|
import org.eclipse.debug.core.ILaunchManager;
|
||||||
|
@ -25,7 +25,7 @@ import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage;
|
||||||
|
|
||||||
public class StandardSourceFileRemapping implements ISourceFileRemapping {
|
public class StandardSourceFileRemapping implements ISourceFileRemapping {
|
||||||
|
|
||||||
public String remapSourceFile(Executable executable, String filePath) {
|
public String remapSourceFile(IPath executable, String filePath) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Object[] foundElements = CDebugCorePlugin.getDefault().getCommonSourceLookupDirector().findSourceElements(filePath);
|
Object[] foundElements = CDebugCorePlugin.getDefault().getCommonSourceLookupDirector().findSourceElements(filePath);
|
||||||
|
|
|
@ -17,9 +17,6 @@ import java.util.Date;
|
||||||
import org.eclipse.cdt.debug.core.executables.Executable;
|
import org.eclipse.cdt.debug.core.executables.Executable;
|
||||||
import org.eclipse.cdt.debug.core.executables.ExecutablesManager;
|
import org.eclipse.cdt.debug.core.executables.ExecutablesManager;
|
||||||
import org.eclipse.core.runtime.IPath;
|
import org.eclipse.core.runtime.IPath;
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
|
||||||
import org.eclipse.core.runtime.IStatus;
|
|
||||||
import org.eclipse.core.runtime.jobs.Job;
|
|
||||||
import org.eclipse.jface.viewers.ColumnLabelProvider;
|
import org.eclipse.jface.viewers.ColumnLabelProvider;
|
||||||
import org.eclipse.jface.viewers.IStructuredContentProvider;
|
import org.eclipse.jface.viewers.IStructuredContentProvider;
|
||||||
import org.eclipse.jface.viewers.ITreeContentProvider;
|
import org.eclipse.jface.viewers.ITreeContentProvider;
|
||||||
|
@ -29,10 +26,7 @@ import org.eclipse.jface.viewers.ViewerCell;
|
||||||
|
|
||||||
class ExecutablesContentProvider extends ColumnLabelProvider implements IStructuredContentProvider, ITreeContentProvider {
|
class ExecutablesContentProvider extends ColumnLabelProvider implements IStructuredContentProvider, ITreeContentProvider {
|
||||||
|
|
||||||
private TreeViewer viewer;
|
|
||||||
|
|
||||||
public ExecutablesContentProvider(TreeViewer viewer) {
|
public ExecutablesContentProvider(TreeViewer viewer) {
|
||||||
this.viewer = viewer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
|
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
|
||||||
|
@ -43,42 +37,8 @@ class ExecutablesContentProvider extends ColumnLabelProvider implements IStructu
|
||||||
|
|
||||||
public Object[] getElements(final Object inputElement) {
|
public Object[] getElements(final Object inputElement) {
|
||||||
if (inputElement instanceof ExecutablesManager) {
|
if (inputElement instanceof ExecutablesManager) {
|
||||||
final ExecutablesManager em = (ExecutablesManager) inputElement;
|
ExecutablesManager em = (ExecutablesManager) inputElement;
|
||||||
if (em.refreshNeeded()) {
|
return em.getExecutables().toArray();
|
||||||
// do this asynchronously. just return an empty array
|
|
||||||
// immediately, and then refresh the view
|
|
||||||
// once the list of executables has been calculated. this can
|
|
||||||
// take a while and we don't want
|
|
||||||
// to block the UI.
|
|
||||||
Job refreshJob = new Job(Messages.ExecutablesContentProvider_FetchingExecutables) {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected IStatus run(IProgressMonitor monitor) {
|
|
||||||
IStatus status = em.refreshExecutables(monitor);
|
|
||||||
|
|
||||||
// Are we in the UIThread? If so spin it until we are done
|
|
||||||
if (!viewer.getControl().isDisposed()) {
|
|
||||||
if (viewer.getControl().getDisplay().getThread() == Thread.currentThread()) {
|
|
||||||
viewer.refresh(inputElement);
|
|
||||||
} else {
|
|
||||||
viewer.getControl().getDisplay().asyncExec(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
viewer.refresh(inputElement);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
monitor.done();
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
refreshJob.schedule();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return em.getExecutables();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return new Object[] {};
|
return new Object[] {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,6 +226,8 @@ public class ExecutablesView extends ViewPart {
|
||||||
|
|
||||||
private IMemento memento;
|
private IMemento memento;
|
||||||
|
|
||||||
|
private IStructuredSelection oldSelection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create contents of the Executables View
|
* Create contents of the Executables View
|
||||||
*
|
*
|
||||||
|
@ -239,9 +241,9 @@ public class ExecutablesView extends ViewPart {
|
||||||
final SashForm sashForm = new SashForm(container, SWT.NONE);
|
final SashForm sashForm = new SashForm(container, SWT.NONE);
|
||||||
|
|
||||||
// Create the two sub viewers.
|
// Create the two sub viewers.
|
||||||
executablesViewer = new ExecutablesViewer(this, sashForm, SWT.FULL_SELECTION + SWT.BORDER + SWT.MULTI);
|
executablesViewer = new ExecutablesViewer(this, sashForm, SWT.FULL_SELECTION | SWT.BORDER | SWT.MULTI);
|
||||||
ExecutablesManager.getExecutablesManager().addExecutablesChangeListener(executablesViewer);
|
ExecutablesManager.getExecutablesManager().addExecutablesChangeListener(executablesViewer);
|
||||||
sourceFilesViewer = new SourceFilesViewer(this, sashForm, SWT.BORDER);
|
sourceFilesViewer = new SourceFilesViewer(this, sashForm, SWT.BORDER | SWT.MULTI);
|
||||||
|
|
||||||
sashForm.setWeights(new int[] { 1, 1 });
|
sashForm.setWeights(new int[] { 1, 1 });
|
||||||
|
|
||||||
|
@ -271,30 +273,39 @@ public class ExecutablesView extends ViewPart {
|
||||||
public void selectionChanged(SelectionChangedEvent event) {
|
public void selectionChanged(SelectionChangedEvent event) {
|
||||||
ISelection newSelection = event.getSelection();
|
ISelection newSelection = event.getSelection();
|
||||||
if (newSelection instanceof IStructuredSelection) {
|
if (newSelection instanceof IStructuredSelection) {
|
||||||
final Object firstElement = ((IStructuredSelection) newSelection).getFirstElement();
|
|
||||||
|
|
||||||
Job setectExeJob = new Job(Messages.ExecutablesView_Select_Executable) {
|
if (oldSelection == null || !oldSelection.equals(newSelection))
|
||||||
|
{
|
||||||
|
// update the remove action
|
||||||
|
removeAction.setEnabled(!newSelection.isEmpty());
|
||||||
|
|
||||||
@Override
|
final Object firstElement = ((IStructuredSelection) newSelection).getFirstElement();
|
||||||
protected IStatus run(IProgressMonitor monitor) {
|
|
||||||
if (firstElement instanceof Executable) {
|
Job setectExeJob = new Job(Messages.ExecutablesView_Select_Executable) {
|
||||||
Executable executable = (Executable)firstElement;
|
|
||||||
this.setName(Messages.ExecutablesView_Finding_Sources_Job_Name + executable.getName());
|
@Override
|
||||||
executable.getSourceFiles(monitor);
|
protected IStatus run(IProgressMonitor monitor) {
|
||||||
}
|
if (firstElement instanceof Executable) {
|
||||||
UIJob selectExeUIJob = new UIJob(Messages.ExecutablesView_Select_Executable){
|
Executable executable = (Executable)firstElement;
|
||||||
@Override
|
this.setName(Messages.ExecutablesView_Finding_Sources_Job_Name + executable.getName());
|
||||||
public IStatus runInUIThread(IProgressMonitor monitor) {
|
executable.getSourceFiles(monitor);
|
||||||
sourceFilesViewer.setInput(firstElement);
|
}
|
||||||
if (firstElement instanceof Executable) {
|
// selection could be empty, so do this no matter what to update the source
|
||||||
|
// files viewer
|
||||||
|
UIJob selectExeUIJob = new UIJob(Messages.ExecutablesView_Select_Executable){
|
||||||
|
@Override
|
||||||
|
public IStatus runInUIThread(IProgressMonitor monitor) {
|
||||||
|
sourceFilesViewer.setInput(firstElement);
|
||||||
sourceFilesViewer.packColumns();
|
sourceFilesViewer.packColumns();
|
||||||
}
|
return Status.OK_STATUS;
|
||||||
return Status.OK_STATUS;
|
}};
|
||||||
}};
|
|
||||||
selectExeUIJob.schedule();
|
selectExeUIJob.schedule();
|
||||||
return Status.OK_STATUS;
|
return Status.OK_STATUS;
|
||||||
}};
|
}};
|
||||||
setectExeJob.schedule();
|
setectExeJob.schedule();
|
||||||
|
oldSelection = (IStructuredSelection) newSelection;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -360,6 +371,7 @@ public class ExecutablesView extends ViewPart {
|
||||||
|
|
||||||
private Action createRemoveAction() {
|
private Action createRemoveAction() {
|
||||||
Action action = new Action("Remove") {
|
Action action = new Action("Remove") {
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
ISelection selection = getExecutablesViewer().getSelection();
|
ISelection selection = getExecutablesViewer().getSelection();
|
||||||
if (selection instanceof IStructuredSelection)
|
if (selection instanceof IStructuredSelection)
|
||||||
|
@ -404,7 +416,7 @@ public class ExecutablesView extends ViewPart {
|
||||||
action.setToolTipText("Remove the selected executables");
|
action.setToolTipText("Remove the selected executables");
|
||||||
action.setImageDescriptor(ExecutablesView.DESC_REMOVE);
|
action.setImageDescriptor(ExecutablesView.DESC_REMOVE);
|
||||||
action.setDisabledImageDescriptor(ExecutablesView.DESC_REMOVE_DISABLED);
|
action.setDisabledImageDescriptor(ExecutablesView.DESC_REMOVE_DISABLED);
|
||||||
action.setEnabled(true);
|
action.setEnabled(false);
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,7 +472,7 @@ public class ExecutablesView extends ViewPart {
|
||||||
private Action createRefreshAction() {
|
private Action createRefreshAction() {
|
||||||
Action action = new Action(Messages.ExecutablesView_Refresh) {
|
Action action = new Action(Messages.ExecutablesView_Refresh) {
|
||||||
public void run() {
|
public void run() {
|
||||||
ExecutablesManager.getExecutablesManager().scheduleRefresh(null, 0);
|
ExecutablesManager.getExecutablesManager().refresh(null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
action.setToolTipText(Messages.ExecutablesView_RefreshList);
|
action.setToolTipText(Messages.ExecutablesView_RefreshList);
|
||||||
|
|
|
@ -10,9 +10,10 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.debug.internal.ui.views.executables;
|
package org.eclipse.cdt.debug.internal.ui.views.executables;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.cdt.debug.core.executables.Executable;
|
import org.eclipse.cdt.debug.core.executables.Executable;
|
||||||
import org.eclipse.cdt.debug.core.executables.ExecutablesManager;
|
import org.eclipse.cdt.debug.core.executables.ExecutablesManager;
|
||||||
import org.eclipse.cdt.debug.core.executables.IExecutablesChangeEvent;
|
|
||||||
import org.eclipse.cdt.debug.core.executables.IExecutablesChangeListener;
|
import org.eclipse.cdt.debug.core.executables.IExecutablesChangeListener;
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
import org.eclipse.core.runtime.IStatus;
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
@ -166,39 +167,6 @@ public class ExecutablesViewer extends BaseViewer implements IExecutablesChangeL
|
||||||
return new ExecutablesViewerComparator(sortType, column_sort_order[sortType]);
|
return new ExecutablesViewerComparator(sortType, column_sort_order[sortType]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.eclipse.cdt.debug.core.executables.IExecutablesChangeListener#executablesChanged(org.eclipse.cdt.debug.core.executables.IExecutablesChangeEvent)
|
|
||||||
*/
|
|
||||||
public void executablesChanged(IExecutablesChangeEvent event) {
|
|
||||||
// Executables have changed so refresh the view.
|
|
||||||
final ExecutablesViewer viewer = this;
|
|
||||||
UIJob refreshJob = new UIJob(Messages.ExecutablesViewer_RefreshExecutablesView) {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IStatus runInUIThread(IProgressMonitor monitor) {
|
|
||||||
// if the user has selected an executable, they expect its
|
|
||||||
// list of source files to be refreshed automatically
|
|
||||||
if (viewer.getSelection() != null &&
|
|
||||||
viewer.getSelection() instanceof IStructuredSelection) {
|
|
||||||
IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
|
|
||||||
|
|
||||||
Object firstElement = selection.getFirstElement();
|
|
||||||
if (firstElement instanceof Executable) {
|
|
||||||
Executable executable = (Executable)firstElement;
|
|
||||||
executable.setRefreshSourceFiles(true);
|
|
||||||
viewer.setSelection(selection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
viewer.refresh(null);
|
|
||||||
viewer.packColumns();
|
|
||||||
return Status.OK_STATUS;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
refreshJob.schedule();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getColumnOrderKey() {
|
protected String getColumnOrderKey() {
|
||||||
return P_COLUMN_ORDER_KEY_EXE;
|
return P_COLUMN_ORDER_KEY_EXE;
|
||||||
|
@ -224,4 +192,46 @@ public class ExecutablesViewer extends BaseViewer implements IExecutablesChangeL
|
||||||
// default visible columns
|
// default visible columns
|
||||||
return "1,1,1,0,0,0"; //$NON-NLS-1$
|
return "1,1,1,0,0,0"; //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void executablesChanged(final List<Executable> executables) {
|
||||||
|
// some executables have been updated. if one of them is currently
|
||||||
|
// selected, we need to update the source file list
|
||||||
|
UIJob refreshJob = new UIJob(Messages.ExecutablesViewer_RefreshExecutablesView) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IStatus runInUIThread(IProgressMonitor monitor) {
|
||||||
|
// if the user has selected an executable, they expect its
|
||||||
|
// list of source files to be refreshed automatically
|
||||||
|
if (getSelection() != null &&
|
||||||
|
getSelection() instanceof IStructuredSelection) {
|
||||||
|
IStructuredSelection selection = (IStructuredSelection)getSelection();
|
||||||
|
|
||||||
|
Object firstElement = selection.getFirstElement();
|
||||||
|
if (firstElement instanceof Executable) {
|
||||||
|
Executable executable = (Executable) firstElement;
|
||||||
|
if (executables.contains(executable)) {
|
||||||
|
executable.setRefreshSourceFiles(true);
|
||||||
|
setSelection(selection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Status.OK_STATUS;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
refreshJob.schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void executablesListChanged() {
|
||||||
|
// Executables list has changed so refresh the view.
|
||||||
|
UIJob refreshJob = new UIJob(Messages.ExecutablesViewer_RefreshExecutablesView) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IStatus runInUIThread(IProgressMonitor monitor) {
|
||||||
|
refresh(null);
|
||||||
|
packColumns();
|
||||||
|
return Status.OK_STATUS;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
refreshJob.schedule();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -70,7 +70,7 @@ public class SourceFilesLabelProvider extends TreeColumnViewerLabelProvider {
|
||||||
if (cell.getElement() instanceof ITranslationUnit) {
|
if (cell.getElement() instanceof ITranslationUnit) {
|
||||||
Executable executable = (Executable) viewer.getInput();
|
Executable executable = (Executable) viewer.getInput();
|
||||||
Path path = new Path(executable.getOriginalLocation((ITranslationUnit) cell.getElement()));
|
Path path = new Path(executable.getOriginalLocation((ITranslationUnit) cell.getElement()));
|
||||||
cell.setText(executable.getOriginalLocation((ITranslationUnit) cell.getElement()));
|
cell.setText(path.toOSString());
|
||||||
if (path.toFile().exists())
|
if (path.toFile().exists())
|
||||||
cell.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
|
cell.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
|
||||||
else
|
else
|
||||||
|
|
Loading…
Add table
Reference in a new issue