1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Merge remote-tracking branch 'cdt/master' into sd90

This commit is contained in:
Andrew Gvozdev 2012-05-11 15:55:57 -04:00
commit ada458c4b3
61 changed files with 920 additions and 362 deletions

View file

@ -446,6 +446,8 @@ public class GCCBuildCommandParserTest extends BaseTestCase {
IFile file6=ResourceHelper.createFile(project, "file6.cpp"); IFile file6=ResourceHelper.createFile(project, "file6.cpp");
IFile file7=ResourceHelper.createFile(project, "file7.cpp"); IFile file7=ResourceHelper.createFile(project, "file7.cpp");
IFile file8=ResourceHelper.createFile(project, "file8.cpp"); IFile file8=ResourceHelper.createFile(project, "file8.cpp");
IFile file9=ResourceHelper.createFile(project, "file9.cpp");
IFile file10=ResourceHelper.createFile(project, "file10.cpp");
ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file1.getProjectRelativePath(), true); ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file1.getProjectRelativePath(), true);
String languageId = ls.getLanguageId(); String languageId = ls.getLanguageId();
@ -462,6 +464,8 @@ public class GCCBuildCommandParserTest extends BaseTestCase {
parser.processLine("/absolute/path/gcc -I/path0 file6.cpp"); parser.processLine("/absolute/path/gcc -I/path0 file6.cpp");
parser.processLine(" \"/absolute/path/gcc\" -I/path0 file7.cpp"); parser.processLine(" \"/absolute/path/gcc\" -I/path0 file7.cpp");
parser.processLine("../relative/path/gcc -I/path0 file8.cpp"); parser.processLine("../relative/path/gcc -I/path0 file8.cpp");
parser.processLine("clang -I/path0 file9.cpp");
parser.processLine("clang++ -I/path0 file10.cpp");
parser.shutdown(); parser.shutdown();
// check populated entries // check populated entries
@ -498,6 +502,14 @@ public class GCCBuildCommandParserTest extends BaseTestCase {
List<ICLanguageSettingEntry> entries = parser.getSettingEntries(cfgDescription, file8, languageId); List<ICLanguageSettingEntry> entries = parser.getSettingEntries(cfgDescription, file8, languageId);
assertEquals(new CIncludePathEntry(path0, 0), entries.get(0)); assertEquals(new CIncludePathEntry(path0, 0), entries.get(0));
} }
{
List<ICLanguageSettingEntry> entries = parser.getSettingEntries(cfgDescription, file9, languageId);
assertEquals(new CIncludePathEntry(path0, 0), entries.get(0));
}
{
List<ICLanguageSettingEntry> entries = parser.getSettingEntries(cfgDescription, file10, languageId);
assertEquals(new CIncludePathEntry(path0, 0), entries.get(0));
}
} }
/** /**

View file

@ -308,13 +308,13 @@
</managedBuildRevision> </managedBuildRevision>
<configuration <configuration
id="org.eclipse.cdt.build.core.emptycfg" id="org.eclipse.cdt.build.core.emptycfg"
languageSettingsProviders="org.eclipse.cdt.ui.UserLanguageSettingsProvider;${Toolchain}" languageSettingsProviders="org.eclipse.cdt.ui.UserLanguageSettingsProvider;${Toolchain};org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider"
name="%cfg1_empty"> name="%cfg1_empty">
</configuration> </configuration>
<configuration <configuration
id="org.eclipse.cdt.build.core.prefbase.cfg" id="org.eclipse.cdt.build.core.prefbase.cfg"
languageSettingsProviders="org.eclipse.cdt.ui.UserLanguageSettingsProvider;${Toolchain}" languageSettingsProviders="org.eclipse.cdt.ui.UserLanguageSettingsProvider;${Toolchain};org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider"
name="%cfg1_base"> name="%cfg1_base">
<toolChain <toolChain
id="org.eclipse.cdt.build.core.prefbase.toolchain" id="org.eclipse.cdt.build.core.prefbase.toolchain"
@ -625,7 +625,7 @@
class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuildCommandParser" class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuildCommandParser"
id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser"
name="CDT GCC Build Output Parser" name="CDT GCC Build Output Parser"
parameter="(gcc)|([gc]\+\+)" parameter="(gcc)|([gc]\+\+)|(clang)"
prefer-non-shared="true"> prefer-non-shared="true">
</provider> </provider>
</extension> </extension>

View file

@ -374,7 +374,7 @@ public class DiscoveryTab extends AbstractCBuildPropertyTab implements IBuildInf
status = new Status(IStatus.WARNING, CUIPlugin.PLUGIN_ID, "This discovery method is deprecated, use 'Preprocessor Include Paths' instead."); status = new Status(IStatus.WARNING, CUIPlugin.PLUGIN_ID, "This discovery method is deprecated, use 'Preprocessor Include Paths' instead.");
} }
} else { } else {
status = new Status(IStatus.INFO, CUIPlugin.PLUGIN_ID, "Managed Build language settings provider is not enabled (see 'Preprocessor Include Paths' page)."); status = new Status(IStatus.INFO, CUIPlugin.PLUGIN_ID, org.eclipse.cdt.internal.ui.newui.Messages.AbstractLangsListTab_MbsProviderNotEnabled);
} }
fStatusLine.setErrorStatus(status); fStatusLine.setErrorStatus(status);
} }

View file

@ -93,6 +93,7 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab {
HashMap<IResource, List<RefreshExclusion>> resourceMap = fConfigurationToResourcesToExclusionsMap.get(configName); HashMap<IResource, List<RefreshExclusion>> resourceMap = fConfigurationToResourcesToExclusionsMap.get(configName);
if (resourceMap == null) { if (resourceMap == null) {
resourceMap = new HashMap<IResource, List<RefreshExclusion>>(); resourceMap = new HashMap<IResource, List<RefreshExclusion>>();
resourceMap.put(fProject, new ArrayList<RefreshExclusion>());
fConfigurationToResourcesToExclusionsMap.put(configName, resourceMap); fConfigurationToResourcesToExclusionsMap.put(configName, resourceMap);
} }
@ -107,8 +108,8 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab {
HashMap<String, HashMap<IResource, List<RefreshExclusion>>> target = new HashMap<String, HashMap<IResource, List<RefreshExclusion>>>(); HashMap<String, HashMap<IResource, List<RefreshExclusion>>> target = new HashMap<String, HashMap<IResource, List<RefreshExclusion>>>();
if (source.size() == 0) if (source.isEmpty())
return null; return target;
Iterator<String> config_iterator = source.keySet().iterator(); Iterator<String> config_iterator = source.keySet().iterator();
// for each Configuration ... // for each Configuration ...
@ -135,13 +136,15 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab {
// ADD each resource. // ADD each resource.
target.put(configName, target_resourceMap); target.put(configName, target_resourceMap);
} }
return target; return target;
} }
private void loadInfo() { private void loadInfo() {
HashMap<String, HashMap<IResource, List<RefreshExclusion>>> configMap = fManager.getConfigurationToResourcesMap(fProject); HashMap<String, HashMap<IResource, List<RefreshExclusion>>> configMap = fManager.getConfigurationToResourcesMap(fProject);
if ( (configMap != null) && !(configMap.isEmpty())) if (configMap != null)
fConfigurationToResourcesToExclusionsMap = copyHashMap(configMap); fConfigurationToResourcesToExclusionsMap = copyHashMap(configMap);
} }
@ -151,6 +154,7 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab {
if(exclusions == null) { if(exclusions == null) {
exclusions = new LinkedList<RefreshExclusion>(); exclusions = new LinkedList<RefreshExclusion>();
resourceMap.put(resource, exclusions); resourceMap.put(resource, exclusions);
} }
return resourceMap.get(resource); return resourceMap.get(resource);
} }
@ -159,10 +163,10 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab {
* Wrapper for IResource/RefreshExclusion * Wrapper for IResource/RefreshExclusion
*/ */
class _Entry { class _Entry {
//if this is a refresh exclusion, resourceToRefresh will be null //if this is not a resource to refresh, resourceToRefresh will be null
IResource resourceToRefresh = null; IResource resourceToRefresh = null;
//if this is a resource to refresh, exclusion will be null //if this is not a refresh exclusion, exclusion will be null
RefreshExclusion exclusion = null; RefreshExclusion exclusion = null;
//if this is a refresh exclusion, parent is the Exceptions node this is a child of //if this is a refresh exclusion, parent is the Exceptions node this is a child of
@ -300,6 +304,7 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab {
if (exclusions == null) { if (exclusions == null) {
exclusions = new LinkedList<RefreshExclusion>(); exclusions = new LinkedList<RefreshExclusion>();
getResourcesToExclusionsMap(getConfigName()).put(parent.resourceToRefresh, exclusions); getResourcesToExclusionsMap(getConfigName()).put(parent.resourceToRefresh, exclusions);
} }
exclusions.add(exclusion); exclusions.add(exclusion);
} }
@ -349,6 +354,8 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab {
} }
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.ui.newui.AbstractCPropertyTab#createControls(org.eclipse.swt.widgets.Composite) * @see org.eclipse.cdt.ui.newui.AbstractCPropertyTab#createControls(org.eclipse.swt.widgets.Composite)
*/ */
@ -505,6 +512,7 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab {
@Override @Override
protected void performDefaults() { protected void performDefaults() {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
@ -514,6 +522,7 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab {
setAllVisible(false, null); setAllVisible(false, null);
return; return;
} else { } else {
setAllVisible(true, null);
clearTreeContent(); clearTreeContent();
generateTreeContent(); generateTreeContent();
fTree.refresh(); fTree.refresh();
@ -521,6 +530,7 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab {
} }
} }
@Override @Override
protected void updateButtons() { protected void updateButtons() {
TreeItem[] sel = fTree.getTree().getSelection(); TreeItem[] sel = fTree.getTree().getSelection();
@ -538,7 +548,7 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab {
@Override @Override
public Object[] getChildren(Object element) { public Object[] getChildren(Object element) {
ArrayList<Object> filteredChildren = new ArrayList<Object>(Arrays.asList(super.getChildren(element))); ArrayList<Object> filteredChildren = new ArrayList<Object>(Arrays.asList(super.getChildren(element)));
Iterator<IResource> iterator = getResourcesToExclusionsMap(getConfigName()).keySet().iterator(); //fResourcesToRefresh.iterator(); Iterator<IResource> iterator = getResourcesToExclusionsMap(getConfigName()).keySet().iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
filteredChildren.remove(iterator.next()); filteredChildren.remove(iterator.next());
@ -676,12 +686,15 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab {
*/ */
@Override @Override
protected void performOK() { protected void performOK() {
Iterator<String> config_iterator = fConfigurationToResourcesToExclusionsMap.keySet().iterator(); Iterator<String> config_iterator = fConfigurationToResourcesToExclusionsMap.keySet().iterator();
while (config_iterator.hasNext()) { while (config_iterator.hasNext()) {
String configName = config_iterator.next(); String configName = config_iterator.next();
fManager.setResourcesToExclusionsMap(fProject, configName, getResourcesToExclusionsMap(configName)); fManager.setResourcesToExclusionsMap(fProject, configName, getResourcesToExclusionsMap(configName));
} }
try { try {
fManager.persistSettings(getResDesc().getConfiguration().getProjectDescription()); fManager.persistSettings(getResDesc().getConfiguration().getProjectDescription());

View file

@ -8,5 +8,5 @@
# Contributors: # Contributors:
# Sergey Prigogin (Google) - initial API and implementation # Sergey Prigogin (Google) - initial API and implementation
############################################################################### ###############################################################################
Activatior_InternalError=Error Activatior_Error=Error
Startup_AnalyzingFile=Analizing ''{0}'' Startup_AnalyzingFile=Analyzing ''{0}''

View file

@ -27,10 +27,12 @@ import org.eclipse.cdt.core.resources.ExclusionInstance;
import org.eclipse.cdt.core.resources.ExclusionType; import org.eclipse.cdt.core.resources.ExclusionType;
import org.eclipse.cdt.core.resources.RefreshExclusion; import org.eclipse.cdt.core.resources.RefreshExclusion;
import org.eclipse.cdt.core.resources.RefreshScopeManager; import org.eclipse.cdt.core.resources.RefreshScopeManager;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.testplugin.CProjectHelper; import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.core.testplugin.CTestPlugin; import org.eclipse.cdt.core.testplugin.CTestPlugin;
import org.eclipse.cdt.internal.core.resources.ResourceExclusion; import org.eclipse.cdt.internal.core.resources.ResourceExclusion;
import org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager;
import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResource;
@ -406,7 +408,12 @@ public class RefreshScopeTests extends TestCase {
IResource config1_resource = fProject; IResource config1_resource = fProject;
manager.addResourceToRefresh(fProject, config1, config1_resource); CProjectDescriptionManager descriptionManager = CProjectDescriptionManager.getInstance();
ICProjectDescription projectDescription = descriptionManager.getProjectDescription(fProject, false);
ICConfigurationDescription conf = projectDescription.getActiveConfiguration();
String conf_name = conf.getName();
manager.addResourceToRefresh(fProject, conf_name, config1_resource);
// create a series of nested exclusions that include/exclude certain folders // create a series of nested exclusions that include/exclude certain folders
// will be included/excluded as follows // will be included/excluded as follows
@ -428,7 +435,8 @@ public class RefreshScopeTests extends TestCase {
ExclusionInstance instance2 = new ExclusionInstance(); ExclusionInstance instance2 = new ExclusionInstance();
instance2.setResource(fFolder2); instance2.setResource(fFolder2);
exclusion1.addExclusionInstance(instance2); exclusion1.addExclusionInstance(instance2);
manager.addExclusion(fProject, config1, config1_resource, exclusion1); manager.addExclusion(fProject, conf_name, config1_resource, exclusion1);
ResourceExclusion exclusion2 = new ResourceExclusion(); ResourceExclusion exclusion2 = new ResourceExclusion();
ExclusionInstance instance3 = new ExclusionInstance(); ExclusionInstance instance3 = new ExclusionInstance();
@ -444,13 +452,14 @@ public class RefreshScopeTests extends TestCase {
// now check and see if the right folders are included/excluded // now check and see if the right folders are included/excluded
assertEquals(true, manager.shouldResourceBeRefreshed(config1, config1_resource)); assertEquals(true, manager.shouldResourceBeRefreshed(conf_name, config1_resource));
assertEquals(false, manager.shouldResourceBeRefreshed(config1, fFolder1)); assertEquals(false, manager.shouldResourceBeRefreshed(conf_name, fFolder1));
assertEquals(false, manager.shouldResourceBeRefreshed(config1, fFolder2)); assertEquals(false, manager.shouldResourceBeRefreshed(conf_name, fFolder2));
assertEquals(true, manager.shouldResourceBeRefreshed(config1, fFolder3)); assertEquals(true, manager.shouldResourceBeRefreshed(conf_name, fFolder3));
assertEquals(false, manager.shouldResourceBeRefreshed(config1, fFolder4)); assertEquals(false, manager.shouldResourceBeRefreshed(conf_name, fFolder4));
assertEquals(true, manager.shouldResourceBeRefreshed(config1, fFolder5)); assertEquals(true, manager.shouldResourceBeRefreshed(conf_name, fFolder5));
assertEquals(false, manager.shouldResourceBeRefreshed(config1, fFolder6)); assertEquals(false, manager.shouldResourceBeRefreshed(conf_name, fFolder6));
// now let's create a bunch of files in these directories using java.io.File (so that we don't get // now let's create a bunch of files in these directories using java.io.File (so that we don't get
// resource deltas happening), and refresh the project according to the policy. We should only see the files // resource deltas happening), and refresh the project according to the policy. We should only see the files

View file

@ -178,11 +178,22 @@ public class EmptyIndexFragment implements IIndexFragment {
public IIndexFragmentFileSet createFileSet() { public IIndexFragmentFileSet createFileSet() {
return null; return null;
} }
@Override @Override
public IIndexFragmentFile[] getAllFiles() { public IIndexFragmentFile[] getAllFiles() {
return IIndexFragmentFile.EMPTY_ARRAY; return IIndexFragmentFile.EMPTY_ARRAY;
} }
@Override
public IIndexFragmentFile[] getDefectiveFiles() {
return IIndexFragmentFile.EMPTY_ARRAY;
}
@Override
public IIndexFragmentFile[] getFilesWithUnresolvedIncludes() {
return IIndexFragmentFile.EMPTY_ARRAY;
}
@Override @Override
public Object getCachedResult(Object key) { public Object getCachedResult(Object key) {
return null; return null;

View file

@ -18,6 +18,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.HashSet; import java.util.HashSet;
import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -62,6 +63,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexFile; import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.index.IIndexInclude; import org.eclipse.cdt.core.index.IIndexInclude;
import org.eclipse.cdt.core.index.IIndexMacro; import org.eclipse.cdt.core.index.IIndexMacro;
@ -85,6 +87,7 @@ import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
import org.eclipse.cdt.core.testplugin.util.TestSourceReader; import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.pdom.CModelListener; import org.eclipse.cdt.internal.core.pdom.CModelListener;
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IFolder;
@ -105,7 +108,7 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.Job;
public class IndexBugsTests extends BaseTestCase { public class IndexBugsTests extends BaseTestCase {
private static final int INDEX_WAIT_TIME = 8000; private static final int INDEX_WAIT_TIME = 800000; //XXX
private ICProject fCProject; private ICProject fCProject;
protected IIndex fIndex; protected IIndex fIndex;
@ -2470,4 +2473,58 @@ public class IndexBugsTests extends BaseTestCase {
fIndex.releaseReadLock(); fIndex.releaseReadLock();
} }
} }
// // test.cpp
// #include "a.h"
// using ns::INT;
// // a.h
// #include "b.h"
// // b.h
// namespace ns { typedef int INT; }
public void testUpdateUnresolvedIncludes_378317() throws Exception {
// Turn off indexing of unused headers.
IndexerPreferences.set(fCProject.getProject(), IndexerPreferences.KEY_INDEX_UNUSED_HEADERS_WITH_DEFAULT_LANG, "false");
// Turn off automatic index update.
IndexerPreferences.setUpdatePolicy(fCProject.getProject(), IndexerPreferences.UPDATE_POLICY_MANUAL);
try {
String[] contents= getContentsForTest(3);
final IIndexManager indexManager = CCorePlugin.getIndexManager();
TestSourceReader.createFile(fCProject.getProject(), "test.c", contents[0]);
IFile ah= TestSourceReader.createFile(fCProject.getProject(), "a.h", contents[1]);
// b.h is not created yet, so #include "b.h" in a.h is unresolved.
indexManager.reindex(fCProject);
waitForIndexer();
fIndex.acquireReadLock();
try {
IIndexFile[] files = fIndex.getFilesWithUnresolvedIncludes();
assertEquals(1, files.length);
assertEquals(IndexLocationFactory.getWorkspaceIFL(ah), files[0].getLocation());
} finally {
fIndex.releaseReadLock();
}
IFile bh= TestSourceReader.createFile(fCProject.getProject(), "b.h", contents[2]);
indexManager.update(new ICElement[] { fCProject }, IIndexManager.UPDATE_UNRESOLVED_INCLUDES);
waitForIndexer();
fIndex.acquireReadLock();
try {
IIndexFile[] files = fIndex.getFilesWithUnresolvedIncludes();
assertEquals(0, files.length);
IIndexFileLocation location = IndexLocationFactory.getWorkspaceIFL(bh);
files = fIndex.getFiles(IndexLocationFactory.getWorkspaceIFL(bh));
assertEquals(1, files.length);
} finally {
fIndex.releaseReadLock();
}
} finally {
// Restore default indexer preferences.
Properties defaults = IndexerPreferences.getDefaultIndexerProperties();
IndexerPreferences.set(fCProject.getProject(), IndexerPreferences.KEY_INDEX_UNUSED_HEADERS_WITH_DEFAULT_LANG,
defaults.getProperty(IndexerPreferences.KEY_INDEX_UNUSED_HEADERS_WITH_DEFAULT_LANG));
IndexerPreferences.setUpdatePolicy(fCProject.getProject(), IndexerPreferences.getDefaultUpdatePolicy());
}
}
} }

View file

@ -133,7 +133,7 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang
/** /**
* Set of elements which are out of sync with their buffers. * Set of elements which are out of sync with their buffers.
*/ */
protected Map<ICElement,ICElement> elementsOutOfSynchWithBuffers = new HashMap<ICElement, ICElement>(11); protected Map<ICElement, ICElement> elementsOutOfSynchWithBuffers = new HashMap<ICElement, ICElement>(11);
/* /*
* Temporary cache of newly opened elements * Temporary cache of newly opened elements
@ -378,11 +378,11 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang
if (bin.getType() == IBinaryFile.ARCHIVE) { if (bin.getType() == IBinaryFile.ARCHIVE) {
ArchiveContainer vlib = (ArchiveContainer)cproject.getArchiveContainer(); ArchiveContainer vlib = (ArchiveContainer)cproject.getArchiveContainer();
celement = new Archive(cfolder, file, (IBinaryArchive)bin); celement = new Archive(cfolder, file, (IBinaryArchive) bin);
vlib.addChild(celement); vlib.addChild(celement);
} else { } else {
BinaryContainer vbin = (BinaryContainer)cproject.getBinaryContainer(); BinaryContainer vbin = (BinaryContainer)cproject.getBinaryContainer();
celement = new Binary(cfolder, file, (IBinaryObject)bin); celement = new Binary(cfolder, file, (IBinaryObject) bin);
vbin.addChild(celement); vbin.addChild(celement);
} }
} }
@ -421,7 +421,7 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang
} catch (CModelException e) { } catch (CModelException e) {
} }
// if the file exists and it has a known C/C++ file extension then just create // If the file exists and it has a known C/C++ file extension then just create
// an external translation unit for it. // an external translation unit for it.
if (contentTypeId != null && path.toFile().exists()) { if (contentTypeId != null && path.toFile().exists()) {
// TODO: use URI // TODO: use URI
@ -470,8 +470,8 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang
IFileStore fileStore = null; IFileStore fileStore = null;
try { try {
fileStore = EFS.getStore(locationURI); fileStore = EFS.getStore(locationURI);
} catch (CoreException e1) { } catch (CoreException e) {
CCorePlugin.log(e1); CCorePlugin.log(e);
return null; return null;
} }
@ -489,7 +489,8 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang
if (path != null && includeReference.isOnIncludeEntry(path)) { if (path != null && includeReference.isOnIncludeEntry(path)) {
String headerContentTypeId= contentTypeId; String headerContentTypeId= contentTypeId;
if (headerContentTypeId == null) { if (headerContentTypeId == null) {
headerContentTypeId= CoreModel.hasCCNature(project) ? CCorePlugin.CONTENT_TYPE_CXXHEADER : CCorePlugin.CONTENT_TYPE_CHEADER; headerContentTypeId= CoreModel.hasCCNature(project) ?
CCorePlugin.CONTENT_TYPE_CXXHEADER : CCorePlugin.CONTENT_TYPE_CHEADER;
} }
return new ExternalTranslationUnit(includeReference, locationURI, headerContentTypeId); return new ExternalTranslationUnit(includeReference, locationURI, headerContentTypeId);
@ -663,11 +664,11 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang
} }
URI fileUri = file.getLocationURI(); URI fileUri = file.getLocationURI();
//Avoid name special devices, empty files and the like // Avoid name special devices, empty files and the like
if (!Util.isNonZeroLengthFile(fileUri)) { if (!Util.isNonZeroLengthFile(fileUri)) {
// PR:xxx the EFS does not seem to work for newly created file // PR:xxx the EFS does not seem to work for newly created file
// so before bailing out give another try? // so before bailing out give another try?
//Avoid name special devices, empty files and the like // Avoid name special devices, empty files and the like
if("file".equals(fileUri.getScheme())) { //$NON-NLS-1$ if("file".equals(fileUri.getScheme())) { //$NON-NLS-1$
File f = new File(fileUri); File f = new File(fileUri);
if (f.length() == 0) { if (f.length() == 0) {
@ -770,14 +771,14 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang
runner = binaryRunners.get(project); runner = binaryRunners.get(project);
} }
if (runner == null) { if (runner == null) {
// creation of BinaryRunner must occur outside the synchronized block // Creation of BinaryRunner must occur outside the synchronized block
runner = new BinaryRunner(project); runner = new BinaryRunner(project);
synchronized (binaryRunners) { synchronized (binaryRunners) {
if (binaryRunners.get(project) == null) { if (binaryRunners.get(project) == null) {
binaryRunners.put(project, runner); binaryRunners.put(project, runner);
runner.start(); runner.start();
} else { } else {
// another thread was faster // Another thread was faster
runner = binaryRunners.get(project); runner = binaryRunners.get(project);
} }
} }
@ -920,12 +921,12 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang
} }
} }
if ((flags & ICDescriptionDelta.EXT_REF) != 0) { if ((flags & ICDescriptionDelta.EXT_REF) != 0) {
// update binary parsers // Update binary parsers
IProject project = newDes.getProject(); IProject project = newDes.getProject();
try { try {
ICConfigExtensionReference[] newExts = CCorePlugin.getDefault().getDefaultBinaryParserExtensions(project); ICConfigExtensionReference[] newExts = CCorePlugin.getDefault().getDefaultBinaryParserExtensions(project);
BinaryParserConfig[] currentConfigs = binaryParsersMap.get(project); BinaryParserConfig[] currentConfigs = binaryParsersMap.get(project);
// anything added/removed // Anything added/removed
if (currentConfigs != null) { if (currentConfigs != null) {
if (newExts.length != currentConfigs.length) { if (newExts.length != currentConfigs.length) {
resetBinaryParser(project); resetBinaryParser(project);
@ -959,9 +960,6 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang
return null; return null;
} }
/* (non-Javadoc)
* @see org.eclipse.core.runtime.content.IContentTypeManager.IContentTypeListener#contentTypeChanged()
*/
@Override @Override
public void contentTypeChanged(ContentTypeChangeEvent event) { public void contentTypeChanged(ContentTypeChangeEvent event) {
ContentTypeProcessor.processContentTypeChanges(new ContentTypeChangeEvent[]{ event }); ContentTypeProcessor.processContentTypeChanges(new ContentTypeChangeEvent[]{ event });
@ -1061,7 +1059,7 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang
System.out.println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$ System.out.println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$
} }
if (deltaToNotify != null) { if (deltaToNotify != null) {
// flush now so as to keep listener reactions to post their own deltas for subsequent iteration // Flush now so as to keep listener reactions to post their own deltas for subsequent iteration
this.reconcileDeltas = new HashMap<IWorkingCopy, ICElementDelta>(); this.reconcileDeltas = new HashMap<IWorkingCopy, ICElementDelta>();
notifyListeners(deltaToNotify, ElementChangedEvent.POST_RECONCILE, listeners, listenerMask, listenerCount); notifyListeners(deltaToNotify, ElementChangedEvent.POST_RECONCILE, listeners, listenerMask, listenerCount);
} }
@ -1069,7 +1067,7 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang
private void fireShiftEvent(ICElementDelta deltaToNotify, IElementChangedListener[] listeners, private void fireShiftEvent(ICElementDelta deltaToNotify, IElementChangedListener[] listeners,
int[] listenerMask, int listenerCount) { int[] listenerMask, int listenerCount) {
// post change deltas // Post change deltas
if (Util.VERBOSE_DELTA) { if (Util.VERBOSE_DELTA) {
System.out.println("FIRING POST_SHIFT event [" + Thread.currentThread() + "]:"); //$NON-NLS-1$//$NON-NLS-2$ System.out.println("FIRING POST_SHIFT event [" + Thread.currentThread() + "]:"); //$NON-NLS-1$//$NON-NLS-2$
System.out.println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$ System.out.println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$
@ -1092,7 +1090,7 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang
System.out.print("Listener #" + (i + 1) + "=" + listener.toString());//$NON-NLS-1$//$NON-NLS-2$ System.out.print("Listener #" + (i + 1) + "=" + listener.toString());//$NON-NLS-1$//$NON-NLS-2$
start = System.currentTimeMillis(); start = System.currentTimeMillis();
} }
// wrap callbacks with Safe runnable for subsequent listeners to be called when some are causing grief // Wrap callbacks with Safe runnable for subsequent listeners to be called when some are causing grief
SafeRunner.run(new ISafeRunnable() { SafeRunner.run(new ISafeRunnable() {
@Override @Override
public void handleException(Throwable exception) { public void handleException(Throwable exception) {

View file

@ -10,7 +10,6 @@
* Anton Leherbauer (Wind River Systems) * Anton Leherbauer (Wind River Systems)
* Warren Paul (Nokia) - Bug 218266 * Warren Paul (Nokia) - Bug 218266
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.model; package org.eclipse.cdt.internal.core.model;
import java.net.URI; import java.net.URI;

View file

@ -95,6 +95,13 @@ public interface IASTPreprocessorIncludeStatement extends IASTPreprocessorStatem
*/ */
public long getIncludedFileContentsHash(); public long getIncludedFileContentsHash();
/**
* Returns time when the included file was read. Corresponds to the start of reading.
* @return time before reading started in milliseconds since epoch
* @since 5.4
*/
public long getIncludedFileReadTime();
/** /**
* Returns <code>true</code> if I/O errors were encountered while reading the included file. * Returns <code>true</code> if I/O errors were encountered while reading the included file.
* @since 5.4 * @since 5.4

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2006, 2011 Wind River Systems, Inc. and others. * Copyright (c) 2006, 2012 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -436,6 +436,20 @@ public interface IIndex {
*/ */
public IIndexFile[] getAllFiles() throws CoreException; public IIndexFile[] getAllFiles() throws CoreException;
/**
* Returns an array of files that were indexed with I/O errors.
* @noreference This method is not intended to be referenced by clients.
* @since 5.4
*/
public IIndexFile[] getDefectiveFiles() throws CoreException;
/**
* Returns an array of files containg unresolved includes.
* @noreference This method is not intended to be referenced by clients.
* @since 5.4
*/
public IIndexFile[] getFilesWithUnresolvedIncludes() throws CoreException;
/** /**
* Returns the global inline c++ namespaces. * Returns the global inline c++ namespaces.
* @throws CoreException * @throws CoreException

View file

@ -62,6 +62,14 @@ public interface IIndexFile extends IFileNomination {
*/ */
long getTimestamp() throws CoreException; long getTimestamp() throws CoreException;
/**
* Time when the file was read during indexing. Corresponds to the start of reading.
* @return time of indexing in milliseconds since epoch
* @throws CoreException
* @since 5.4
*/
long getSourceReadTime() throws CoreException;
/** /**
* Hash of the file contents when the file was indexed. * Hash of the file contents when the file was indexed.
* @return 64-bit hash of the file content. * @return 64-bit hash of the file content.

View file

@ -113,32 +113,31 @@ public interface IIndexManager extends IPDOMManager {
public final static int ADD_EXTENSION_FRAGMENTS_SEARCH = 0x200; public final static int ADD_EXTENSION_FRAGMENTS_SEARCH = 0x200;
/** /**
* Constant for indicating there is no time out period for joining the indexer job. * Constant for indicating that there is no time out period for joining the indexer job.
* @see IIndexManager#joinIndexer(int, IProgressMonitor) * @see IIndexManager#joinIndexer(int, IProgressMonitor)
*/ */
public final static int FOREVER= -1; public final static int FOREVER= -1;
/** /**
* Constant for indicating to update all translation units. * Constant for requesting an update of all translation units.
*/ */
public final static int UPDATE_ALL= 0x1; public final static int UPDATE_ALL= 0x1;
/** /**
* Constant for indicating to update translation units if their timestamp * Constant for requesting an update of translation units if theit timestamps have changed.
* has changed.
*/ */
public final static int UPDATE_CHECK_TIMESTAMPS= 0x2; public final static int UPDATE_CHECK_TIMESTAMPS= 0x2;
/** /**
* Constant for indicating to update translation units if their configuration * Constant for requesting an update of translation units if their configurations
* has changed. The flag currently has no effect. * have changed. The flag currently has no effect.
*/ */
public final static int UPDATE_CHECK_CONFIGURATION= 0x4; public final static int UPDATE_CHECK_CONFIGURATION= 0x4;
/** /**
* Constant for requesting to update the external files for a project, also. This flag works only * Constant for requesting to update the external files for a project, also. This flag works
* if it is used to update one or more projects. It shall be used together with {@link #UPDATE_ALL} * only if it is used to update one or more projects. It shall be used together with
* or {@link #UPDATE_CHECK_TIMESTAMPS}. * {@link #UPDATE_ALL} or {@link #UPDATE_CHECK_TIMESTAMPS}.
* @since 5.1 * @since 5.1
*/ */
public final static int UPDATE_EXTERNAL_FILES_FOR_PROJECT= 0x8; public final static int UPDATE_EXTERNAL_FILES_FOR_PROJECT= 0x8;
@ -168,6 +167,12 @@ public interface IIndexManager extends IPDOMManager {
*/ */
public final static int RESET_INDEX_INCLUSION= 0x40; public final static int RESET_INDEX_INCLUSION= 0x40;
/**
* Constant for requesting an update of translation units that had unresolved includes.
* @since 5.4
*/
public final static int UPDATE_UNRESOLVED_INCLUDES= 0x80;
/** /**
* Returns the index for the given project. * Returns the index for the given project.
* @param project the project to get the index for * @param project the project to get the index for

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009, 2010 Wind River Systems, Inc. and others. * Copyright (c) 2009, 2012 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -40,13 +40,20 @@ public abstract class FileContent {
public abstract String getFileLocation(); public abstract String getFileLocation();
/** /**
* Returns the modification time of the file containing the content or NULL_TIMESTAMP if * Returns the modification time of the file containing the content, or NULL_TIMESTAMP if
* the content does not originate from a file. A zero value may be returned if there was * the content does not originate from a file. A zero value may be returned if there was
* an I/O error. * an I/O error.
* @since 5.4 * @since 5.4
*/ */
public abstract long getTimestamp(); public abstract long getTimestamp();
/**
* Returns time when the file was read. Corresponds to the start of reading.
* @return time before reading started in milliseconds since epoch
* @since 5.4
*/
public abstract long getReadTime();
/** /**
* Returns the size of the file, or NULL_FILE_SIZE if the content does not originate from * Returns the size of the file, or NULL_FILE_SIZE if the content does not originate from
* a file. A zero value may be returned if there was an I/O error. * a file. A zero value may be returned if there was an I/O error.

View file

@ -758,6 +758,32 @@ public class CIndex implements IIndex {
return result.values().toArray(new IIndexFile[result.size()]); return result.values().toArray(new IIndexFile[result.size()]);
} }
@Override
public IIndexFile[] getDefectiveFiles() throws CoreException {
HashMap<IIndexFileLocation, IIndexFile> result= new HashMap<IIndexFileLocation, IIndexFile>();
for (IIndexFragment fragment : fFragments) {
for (IIndexFragmentFile file : fragment.getDefectiveFiles()) {
if (file.hasContent()) {
result.put(file.getLocation(), file);
}
}
}
return result.values().toArray(new IIndexFile[result.size()]);
}
@Override
public IIndexFile[] getFilesWithUnresolvedIncludes() throws CoreException {
HashMap<IIndexFileLocation, IIndexFile> result= new HashMap<IIndexFileLocation, IIndexFile>();
for (IIndexFragment fragment : fFragments) {
for (IIndexFragmentFile file : fragment.getFilesWithUnresolvedIncludes()) {
if (file.hasContent()) {
result.put(file.getLocation(), file);
}
}
}
return result.values().toArray(new IIndexFile[result.size()]);
}
@Override @Override
public IIndexScope[] getInlineNamespaces() throws CoreException { public IIndexScope[] getInlineNamespaces() throws CoreException {
if (SPECIALCASE_SINGLES && fFragments.length == 1) { if (SPECIALCASE_SINGLES && fFragments.length == 1) {

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2006, 2011 Wind River Systems, Inc. and others. * Copyright (c) 2006, 2012 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -189,6 +189,16 @@ final public class EmptyCIndex implements IIndex {
return IIndexFile.EMPTY_FILE_ARRAY; return IIndexFile.EMPTY_FILE_ARRAY;
} }
@Override
public IIndexFile[] getDefectiveFiles() {
return IIndexFile.EMPTY_FILE_ARRAY;
}
@Override
public IIndexFile[] getFilesWithUnresolvedIncludes() {
return IIndexFile.EMPTY_FILE_ARRAY;
}
@Override @Override
public IIndexBinding[] findBindings(char[] name, boolean fileScopeOnly, IndexFilter filter, IProgressMonitor monitor) { public IIndexBinding[] findBindings(char[] name, boolean fileScopeOnly, IndexFilter filter, IProgressMonitor monitor) {
return IIndexBinding.EMPTY_INDEX_BINDING_ARRAY; return IIndexBinding.EMPTY_INDEX_BINDING_ARRAY;

View file

@ -325,6 +325,16 @@ public interface IIndexFragment {
*/ */
IIndexFragmentFile[] getAllFiles() throws CoreException; IIndexFragmentFile[] getAllFiles() throws CoreException;
/**
* @return an array of files that were indexed with I/O errors.
*/
IIndexFragmentFile[] getDefectiveFiles() throws CoreException;
/**
* @return an array of files containg unresolved includes.
*/
IIndexFragmentFile[] getFilesWithUnresolvedIncludes() throws CoreException;
/** /**
* Caches an object with the key, the cache must be cleared at latest when the fragment no * Caches an object with the key, the cache must be cleared at latest when the fragment no
* longer holds a locks. * longer holds a locks.

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2006, 2011 Wind River Systems, Inc. and others. * Copyright (c) 2006, 2012 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -24,10 +24,15 @@ public interface IIndexFragmentFile extends IIndexFile {
IIndexFragment getIndexFragment(); IIndexFragment getIndexFragment();
/** /**
* Sets the timestamp of the file * Sets the timestamp of the file.
*/ */
void setTimestamp(long timestamp) throws CoreException; void setTimestamp(long timestamp) throws CoreException;
/**
* Sets the file read time.
*/
void setSourceReadTime(long time) throws CoreException;
/** /**
* Sets the hash of the file content. * Sets the hash of the file content.
*/ */
@ -57,6 +62,12 @@ public interface IIndexFragmentFile extends IIndexFile {
*/ */
boolean hasContent() throws CoreException; boolean hasContent() throws CoreException;
/**
* Checks if the file contains at least one unresolved include.
* @return {@code true} if the file contains an unresolved include
*/
boolean hasUnresolvedInclude() throws CoreException;
/** /**
* Returns the id of the linkage this file belongs to. * Returns the id of the linkage this file belongs to.
*/ */
@ -74,4 +85,5 @@ public interface IIndexFragmentFile extends IIndexFile {
* The file 'source' must belong to the same fragment as this file. * The file 'source' must belong to the same fragment as this file.
*/ */
void transferContext(IIndexFragmentFile source) throws CoreException; void transferContext(IIndexFragmentFile source) throws CoreException;
} }

View file

@ -155,6 +155,7 @@ public class InternalParserUtil extends ParserFactory {
InputStream input; InputStream input;
try { try {
long fileReadTime = System.currentTimeMillis();
IFileStore store = EFS.getStore(file.getLocationURI()); IFileStore store = EFS.getStore(file.getLocationURI());
IFileInfo fileInfo = store.fetchInfo(); IFileInfo fileInfo = store.fetchInfo();
input= file.getContents(true); input= file.getContents(true);
@ -173,7 +174,7 @@ public class InternalParserUtil extends ParserFactory {
} }
try { try {
return createFileContent(path, file.getCharset(), input, return createFileContent(path, file.getCharset(), input,
fileInfo.getLastModified(), fileInfo.getLength()); fileInfo.getLastModified(), fileInfo.getLength(), fileReadTime);
} finally { } finally {
try { try {
input.close(); input.close();
@ -201,6 +202,7 @@ public class InternalParserUtil extends ParserFactory {
* canonical path. * canonical path.
*/ */
public static InternalFileContent createExternalFileContent(String externalLocation, String encoding) { public static InternalFileContent createExternalFileContent(String externalLocation, String encoding) {
long fileReadTime = System.currentTimeMillis();
File includeFile = null; File includeFile = null;
String path = null; String path = null;
if (!UNCPathConverter.isUNC(externalLocation)) { if (!UNCPathConverter.isUNC(externalLocation)) {
@ -228,7 +230,7 @@ public class InternalParserUtil extends ParserFactory {
return null; return null;
} }
try { try {
return createFileContent(path, encoding, in, timestamp, fileSize); return createFileContent(path, encoding, in, timestamp, fileSize, fileReadTime);
} finally { } finally {
try { try {
in.close(); in.close();
@ -240,13 +242,13 @@ public class InternalParserUtil extends ParserFactory {
} }
private static InternalFileContent createFileContent(String path, String charset, InputStream in, private static InternalFileContent createFileContent(String path, String charset, InputStream in,
long fileTimestamp, long fileSize) { long fileTimestamp, long fileSize, long fileReadTime) {
try { try {
AbstractCharArray chars= FileCharArray.create(path, charset, in); AbstractCharArray chars= FileCharArray.create(path, charset, in);
if (chars == null) if (chars == null)
return null; return null;
return new InternalFileContent(path, chars, fileTimestamp, fileSize); return new InternalFileContent(path, chars, fileTimestamp, fileSize, fileReadTime);
} catch (IOException e) { } catch (IOException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
} }

View file

@ -298,6 +298,7 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
private long fIncludedFileContentsHash; private long fIncludedFileContentsHash;
private long fIncludedFileTimestamp = -1; private long fIncludedFileTimestamp = -1;
private long fIncludedFileSize; private long fIncludedFileSize;
private long fIncludedFileReadTime;
private boolean fErrorInIncludedFile; private boolean fErrorInIncludedFile;
public ASTInclusionStatement(IASTTranslationUnit parent, public ASTInclusionStatement(IASTTranslationUnit parent,
@ -404,6 +405,19 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
fIncludedFileTimestamp= timestamp; fIncludedFileTimestamp= timestamp;
} }
@Override
public long getIncludedFileReadTime() {
if (fNominationDelegate != null) {
return 0;
}
return fIncludedFileReadTime;
}
public void setIncludedFileReadTime(long time) {
assert fNominationDelegate == null;
fIncludedFileReadTime= time;
}
@Override @Override
public long getIncludedFileSize() { public long getIncludedFileSize() {
if (fNominationDelegate != null) { if (fNominationDelegate != null) {

View file

@ -302,7 +302,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
if (contextPath == null) { if (contextPath == null) {
contextPath= fRootContent.getFileLocation(); contextPath= fRootContent.getFileLocation();
} }
configureIncludeSearchPath(new File(contextPath).getParentFile(), info); fIncludeSearchPath = configureIncludeSearchPath(new File(contextPath).getParentFile(), info);
setupMacroDictionary(configuration, info, language); setupMacroDictionary(configuration, info, language);
ILocationCtx ctx= fLocationMap.pushTranslationUnit(fRootContent.getFileLocation(), fRootContent.getSource()); ILocationCtx ctx= fLocationMap.pushTranslationUnit(fRootContent.getFileLocation(), fRootContent.getSource());
@ -396,37 +396,39 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
return array == null ? CharArrayUtils.EMPTY_CHAR_ARRAY : array; return array == null ? CharArrayUtils.EMPTY_CHAR_ARRAY : array;
} }
private void configureIncludeSearchPath(File directory, IScannerInfo info) { public static IncludeSearchPathElement[] configureIncludeSearchPath(File directory, IScannerInfo info) {
IncludeSearchPathElement[] includeSearchPath = null;
String[] searchPath= info.getIncludePaths(); String[] searchPath= info.getIncludePaths();
int idx= 0; int idx= 0;
if (info instanceof IExtendedScannerInfo) { if (info instanceof IExtendedScannerInfo) {
final IExtendedScannerInfo einfo= (IExtendedScannerInfo) info; final IExtendedScannerInfo einfo= (IExtendedScannerInfo) info;
final String[] quoteIncludeSearchPath= einfo.getLocalIncludePath(); final String[] quoteIncludeSearchPath= einfo.getLocalIncludePath();
if (quoteIncludeSearchPath != null && quoteIncludeSearchPath.length > 0) { if (quoteIncludeSearchPath != null && quoteIncludeSearchPath.length > 0) {
fIncludeSearchPath= new IncludeSearchPathElement[quoteIncludeSearchPath.length + searchPath.length]; includeSearchPath= new IncludeSearchPathElement[quoteIncludeSearchPath.length + searchPath.length];
for (String qip : quoteIncludeSearchPath) { for (String path : quoteIncludeSearchPath) {
fIncludeSearchPath[idx++]= new IncludeSearchPathElement(makeAbsolute(directory, qip), true); includeSearchPath[idx++]= new IncludeSearchPathElement(makeAbsolute(directory, path), true);
} }
} }
} }
if (fIncludeSearchPath == null) { if (includeSearchPath == null) {
fIncludeSearchPath= new IncludeSearchPathElement[searchPath.length]; includeSearchPath= new IncludeSearchPathElement[searchPath.length];
} }
for (String path : searchPath) { for (String path : searchPath) {
fIncludeSearchPath[idx++]= new IncludeSearchPathElement(makeAbsolute(directory, path), false); includeSearchPath[idx++]= new IncludeSearchPathElement(makeAbsolute(directory, path), false);
} }
return includeSearchPath;
} }
private String makeAbsolute(File directory, String inlcudePath) { private static String makeAbsolute(File directory, String includePath) {
if (directory == null || new File(inlcudePath).isAbsolute()) { if (directory == null || new File(includePath).isAbsolute()) {
return inlcudePath; return includePath;
} }
return ScannerUtility.createReconciledPath(directory.getAbsolutePath(), inlcudePath); return ScannerUtility.createReconciledPath(directory.getAbsolutePath(), includePath);
} }
private void setupMacroDictionary(IScannerExtensionConfiguration config, IScannerInfo info, private void setupMacroDictionary(IScannerExtensionConfiguration config, IScannerInfo info,
ParserLanguage lang) { ParserLanguage lang) {
// built in macros // Built-in macros
fMacroDictionary.put(__CDT_PARSER__.getNameCharArray(), __CDT_PARSER__); fMacroDictionary.put(__CDT_PARSER__.getNameCharArray(), __CDT_PARSER__);
fMacroDictionary.put(__STDC__.getNameCharArray(), __STDC__); fMacroDictionary.put(__STDC__.getNameCharArray(), __STDC__);
fMacroDictionary.put(__FILE__.getNameCharArray(), __FILE__); fMacroDictionary.put(__FILE__.getNameCharArray(), __FILE__);
@ -1066,19 +1068,9 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
private <T> T findInclusion(final String includeDirective, final boolean quoteInclude, private <T> T findInclusion(final String includeDirective, final boolean quoteInclude,
final boolean includeNext, final String currentFile, final IIncludeFileTester<T> tester) { final boolean includeNext, final String currentFile, final IIncludeFileTester<T> tester) {
T reader = null; T reader = null;
// Filename is an absolute path String absoluteInclusionPath = getAbsoluteInclusionPath(includeDirective, currentFile);
if (new File(includeDirective).isAbsolute()) { if (absoluteInclusionPath != null) {
return tester.checkFile(includeDirective, false, null); return tester.checkFile(absoluteInclusionPath, false, null);
}
// Filename is a Linux absolute path on a windows machine
if (File.separatorChar == '\\' && includeDirective.length() > 0) {
final char firstChar = includeDirective.charAt(0);
if (firstChar == '\\' || firstChar == '/') {
if (currentFile != null && currentFile.length() > 1 && currentFile.charAt(1) == ':') {
return tester.checkFile(currentFile.substring(0, 2) + includeDirective, false, null);
}
return tester.checkFile(includeDirective, false, null);
}
} }
if (currentFile != null && quoteInclude && !includeNext) { if (currentFile != null && quoteInclude && !includeNext) {
@ -1134,6 +1126,24 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
return null; return null;
} }
public static String getAbsoluteInclusionPath(String includeDirective, String currentFile) {
// Filename is an absolute path
if (new File(includeDirective).isAbsolute()) {
return includeDirective;
}
// Filename is a Linux absolute path on a Windows machine
if (File.separatorChar == '\\' && includeDirective.length() > 0) {
final char firstChar = includeDirective.charAt(0);
if (firstChar == '\\' || firstChar == '/') {
if (currentFile != null && currentFile.length() > 1 && currentFile.charAt(1) == ':') {
return currentFile.substring(0, 2) + includeDirective;
}
return includeDirective;
}
}
return null;
}
private IncludeSearchPathElement findFileInIncludePath(String file, String includeDirective) { private IncludeSearchPathElement findFileInIncludePath(String file, String includeDirective) {
for (IncludeSearchPathElement path : fIncludeSearchPath) { for (IncludeSearchPathElement path : fIncludeSearchPath) {
String fileLocation = path.getLocation(includeDirective); String fileLocation = path.getLocation(includeDirective);
@ -1490,6 +1500,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
stmt.setIncludedFileTimestamp(fi.getTimestamp()); stmt.setIncludedFileTimestamp(fi.getTimestamp());
stmt.setIncludedFileSize(fi.getFileSize()); stmt.setIncludedFileSize(fi.getFileSize());
stmt.setIncludedFileContentsHash(source.getContentsHash()); stmt.setIncludedFileContentsHash(source.getContentsHash());
stmt.setIncludedFileReadTime(fi.getReadTime());
stmt.setErrorInIncludedFile(source.hasError()); stmt.setErrorInIncludedFile(source.hasError());
if (!fCurrentContext.isPragmaOnce()) { if (!fCurrentContext.isPragmaOnce()) {
// Track the loaded version count, even in a non-pragma-once context. // Track the loaded version count, even in a non-pragma-once context.

View file

@ -186,6 +186,7 @@ public class FileCharArray extends LazyCharArray {
decode(channel, chunk.fSourceOffset, chunk.fSourceEndOffset, CharBuffer.wrap(dest)); decode(channel, chunk.fSourceOffset, chunk.fSourceEndOffset, CharBuffer.wrap(dest));
} catch (IOException e) { } catch (IOException e) {
// File cannot be read // File cannot be read
CCorePlugin.log(e);
fHasError = true; fHasError = true;
} finally { } finally {
try { try {

View file

@ -15,7 +15,7 @@ import java.io.File;
/** /**
* Represents an entry of the include search path * Represents an entry of the include search path
*/ */
final class IncludeSearchPathElement { public final class IncludeSearchPathElement {
private static final boolean NON_SLASH_SEPARATOR = File.separatorChar != '/'; private static final boolean NON_SLASH_SEPARATOR = File.separatorChar != '/';
public static final String FRAMEWORK_VAR = "__framework__"; //$NON-NLS-1$ public static final String FRAMEWORK_VAR = "__framework__"; //$NON-NLS-1$
public static final String FILE_VAR = "__header__"; //$NON-NLS-1$ public static final String FILE_VAR = "__header__"; //$NON-NLS-1$

View file

@ -60,6 +60,7 @@ public class InternalFileContent extends FileContent {
private IncludeSearchPathElement fFoundOnPath; private IncludeSearchPathElement fFoundOnPath;
private final long fTimestamp; private final long fTimestamp;
private final long fFileSize; private final long fFileSize;
private final long fReadTime;
/** /**
* For skipping include files. * For skipping include files.
@ -79,7 +80,8 @@ public class InternalFileContent extends FileContent {
fSource= null; fSource= null;
fNonPragmaOnceFiles= null; fNonPragmaOnceFiles= null;
fTimestamp= NULL_TIMESTAMP; fTimestamp= NULL_TIMESTAMP;
fFileSize = NULL_FILE_SIZE; fFileSize= NULL_FILE_SIZE;
fReadTime= 0;
} }
/** /**
@ -87,7 +89,7 @@ public class InternalFileContent extends FileContent {
* @throws IllegalArgumentException in case the codeReader or its location is <code>null</code>. * @throws IllegalArgumentException in case the codeReader or its location is <code>null</code>.
*/ */
public InternalFileContent(String filePath, AbstractCharArray content, long timestamp, public InternalFileContent(String filePath, AbstractCharArray content, long timestamp,
long fileSize) throws IllegalArgumentException { long fileSize, long fileReadTime) throws IllegalArgumentException {
if (content == null) { if (content == null) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
@ -101,7 +103,8 @@ public class InternalFileContent extends FileContent {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
fTimestamp= timestamp; fTimestamp= timestamp;
fFileSize = fileSize; fFileSize= fileSize;
fReadTime= fileReadTime;
} }
/** /**
@ -123,6 +126,7 @@ public class InternalFileContent extends FileContent {
} }
fTimestamp= NULL_TIMESTAMP; fTimestamp= NULL_TIMESTAMP;
fFileSize = NULL_FILE_SIZE; fFileSize = NULL_FILE_SIZE;
fReadTime= 0;
} }
/** /**
@ -144,6 +148,7 @@ public class InternalFileContent extends FileContent {
fNonPragmaOnceFiles= nonPragmaOnceVersions; fNonPragmaOnceFiles= nonPragmaOnceVersions;
fTimestamp= NULL_TIMESTAMP; fTimestamp= NULL_TIMESTAMP;
fFileSize = NULL_FILE_SIZE; fFileSize = NULL_FILE_SIZE;
fReadTime= 0;
} }
/** /**
@ -166,6 +171,11 @@ public class InternalFileContent extends FileContent {
return fTimestamp; return fTimestamp;
} }
@Override
public long getReadTime() {
return fReadTime;
}
@Override @Override
public long getFileSize() { public long getFileSize() {
return fFileSize; return fFileSize;

View file

@ -14,10 +14,8 @@ import java.io.File;
/** /**
* @author jcamelon * @author jcamelon
*
*/ */
public class ScannerUtility { public class ScannerUtility {
static final char DOT = '.'; static final char DOT = '.';
static final char SLASH = '/'; static final char SLASH = '/';
static final char BSLASH = '\\'; static final char BSLASH = '\\';
@ -68,8 +66,7 @@ public class ScannerUtility {
} }
} }
for (int i= 0; i < len; i++) {
for (int i=0; i<len; i++) {
char c = ein[i]; char c = ein[i];
switch (c) { switch (c) {
case QUOTE: // quotes are removed case QUOTE: // quotes are removed
@ -83,35 +80,24 @@ public class ScannerUtility {
} }
break; break;
case DOT: case DOT:
// no separator before, not a 1st string symbol. // No separator before, not a 1st string symbol.
if (noSepBefore && j>0) if (noSepBefore && j > 0) {
aus[j++] = c; aus[j++] = c;
else { // separator before "." ! } else { // Separator before "."
if (i < len1) { if (i < len1) {
c = ein[i+1]; // check for next symbol c = ein[i + 1]; // Check for next symbol
// check for "/./" case // Check for "/./" case
if (c == SLASH || c == BSLASH) { if (c == SLASH || c == BSLASH) {
// write nothing to output // Write nothing to output, skip the next symbol
// skip the next symbol
i++; i++;
noSepBefore = false; noSepBefore = false;
} } else { // Process as usual
// symbol other than "." - write it also
else if (c != DOT) {
i++; i++;
noSepBefore = true; noSepBefore = true;
aus[j++] = DOT; aus[j++] = DOT;
aus[j++] = c; aus[j++] = c;
} }
// Processed as usual
else {
i++;
noSepBefore = true;
aus[j++] = DOT;
aus[j++] = DOT;
} }
} else
{} // do nothing when "." is last symbol
} }
break; break;
default: default:
@ -125,10 +111,10 @@ public class ScannerUtility {
/** /**
* @param path - include path * @param path - include path
* @param fileName - include file name * @param fileName - include file name
* @return - reconsiled path * @return - reconciled path
*/ */
public static String createReconciledPath(String path, String fileName) { public static String createReconciledPath(String path, String fileName) {
boolean pathEmpty = (path == null || path.length() == 0); boolean pathEmpty = (path == null || path.length() == 0);
return (pathEmpty ? fileName : reconcilePath(path + File.separatorChar + fileName)); return pathEmpty ? fileName : reconcilePath(path + File.separatorChar + fileName);
} }
} }

View file

@ -307,6 +307,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
private final LinkedList<AbstractIndexerTask> fUrgentTasks; private final LinkedList<AbstractIndexerTask> fUrgentTasks;
boolean fTaskCompleted; boolean fTaskCompleted;
private IndexerProgress fInfo= new IndexerProgress(); private IndexerProgress fInfo= new IndexerProgress();
public AbstractIndexerTask(Object[] filesToUpdate, Object[] filesToRemove, public AbstractIndexerTask(Object[] filesToUpdate, Object[] filesToRemove,
IndexerInputAdapter resolver, boolean fastIndexer) { IndexerInputAdapter resolver, boolean fastIndexer) {
super(resolver); super(resolver);
@ -384,6 +385,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
protected abstract IWritableIndex createIndex(); protected abstract IWritableIndex createIndex();
protected abstract IIncludeFileResolutionHeuristics createIncludeHeuristics(); protected abstract IIncludeFileResolutionHeuristics createIncludeHeuristics();
protected abstract IncludeFileContentProvider createReaderFactory(); protected abstract IncludeFileContentProvider createReaderFactory();
protected ITodoTaskUpdater createTodoTaskUpdater() { protected ITodoTaskUpdater createTodoTaskUpdater() {
return null; return null;
} }
@ -582,6 +584,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
final boolean forceAll= (fUpdateFlags & IIndexManager.UPDATE_ALL) != 0; final boolean forceAll= (fUpdateFlags & IIndexManager.UPDATE_ALL) != 0;
final boolean checkTimestamps= (fUpdateFlags & IIndexManager.UPDATE_CHECK_TIMESTAMPS) != 0; final boolean checkTimestamps= (fUpdateFlags & IIndexManager.UPDATE_CHECK_TIMESTAMPS) != 0;
final boolean checkFileContentsHash = (fUpdateFlags & IIndexManager.UPDATE_CHECK_CONTENTS_HASH) != 0; final boolean checkFileContentsHash = (fUpdateFlags & IIndexManager.UPDATE_CHECK_CONTENTS_HASH) != 0;
final boolean forceUnresolvedIncludes = (fUpdateFlags & IIndexManager.UPDATE_UNRESOLVED_INCLUDES) != 0;
final boolean both = fIndexHeadersWithoutContext == UnusedHeaderStrategy.useBoth; final boolean both = fIndexHeadersWithoutContext == UnusedHeaderStrategy.useBoth;
int count= 0; int count= 0;
int forceFirst= fForceNumberFiles; int forceFirst= fForceNumberFiles;
@ -614,7 +617,9 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
if (ifile != null && ifile.getLinkageID() == linkageID && ifile.hasContent()) { if (ifile != null && ifile.getLinkageID() == linkageID && ifile.hasContent()) {
foundInLinkage = true; foundInLinkage = true;
indexFiles[i]= null; // Take the file. indexFiles[i]= null; // Take the file.
boolean update= force || isModified(checkTimestamps, checkFileContentsHash, ifl, tu, ifile); boolean update= force ||
(forceUnresolvedIncludes && ifile.hasUnresolvedInclude()) ||
isModified(checkTimestamps, checkFileContentsHash, ifl, tu, ifile);
if (update && requestUpdate(linkageID, ifl, ifile, tu, updateKind)) { if (update && requestUpdate(linkageID, ifl, ifile, tu, updateKind)) {
count++; count++;
linkages.set(linkageID); linkages.set(linkageID);
@ -637,7 +642,9 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
iFilesToRemove.add(ifile); iFilesToRemove.add(ifile);
count++; count++;
} else { } else {
boolean update= force || isModified(checkTimestamps, checkFileContentsHash, ifl, tu, ifile); boolean update= force ||
(forceUnresolvedIncludes && ifile.hasUnresolvedInclude()) ||
isModified(checkTimestamps, checkFileContentsHash, ifl, tu, ifile);
final int linkageID = ifile.getLinkageID(); final int linkageID = ifile.getLinkageID();
if (update && requestUpdate(linkageID, ifl, ifile, tu, UpdateKind.OTHER_HEADER)) { if (update && requestUpdate(linkageID, ifl, ifile, tu, UpdateKind.OTHER_HEADER)) {
count++; count++;
@ -646,7 +653,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
} }
} }
} }
for (int lid = linkages.nextSetBit(0); lid >= 0; lid= linkages.nextSetBit(lid+1)) { for (int lid = linkages.nextSetBit(0); lid >= 0; lid= linkages.nextSetBit(lid + 1)) {
addPerLinkage(lid, ifl, files); addPerLinkage(lid, ifl, files);
} }
} }

View file

@ -142,8 +142,7 @@ public class IndexUpdatePolicy {
task= new PDOMUpdateTask(fIndexer, task= new PDOMUpdateTask(fIndexer,
IIndexManager.UPDATE_CHECK_TIMESTAMPS | IIndexManager.UPDATE_CHECK_CONTENTS_HASH); IIndexManager.UPDATE_CHECK_TIMESTAMPS | IIndexManager.UPDATE_CHECK_CONTENTS_HASH);
clearTUs(); clearTUs();
} } else if (fKind == POST_CHANGE) {
else if (fKind == POST_CHANGE) {
task= createTask(); task= createTask();
} }
} }

View file

@ -72,6 +72,7 @@ import org.eclipse.cdt.internal.core.pdom.db.BTree;
import org.eclipse.cdt.internal.core.pdom.db.ChunkCache; import org.eclipse.cdt.internal.core.pdom.db.ChunkCache;
import org.eclipse.cdt.internal.core.pdom.db.DBProperties; import org.eclipse.cdt.internal.core.pdom.db.DBProperties;
import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator;
import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor; import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
import org.eclipse.cdt.internal.core.pdom.dom.BindingCollector; import org.eclipse.cdt.internal.core.pdom.dom.BindingCollector;
import org.eclipse.cdt.internal.core.pdom.dom.FindBinding; import org.eclipse.cdt.internal.core.pdom.dom.FindBinding;
@ -215,10 +216,11 @@ public class PDOM extends PlatformObject implements IPDOM {
* 122.0 - Compacting strings * 122.0 - Compacting strings
* 123.0 - Combined file size and encoding hash code. * 123.0 - Combined file size and encoding hash code.
* 124.0 - GCC attributes and NO_RETURN flag for functions. * 124.0 - GCC attributes and NO_RETURN flag for functions.
* 125.0 - Indexes for unresolved includes and files indexed with I/O errors.
*/ */
private static final int MIN_SUPPORTED_VERSION= version(124, 0); private static final int MIN_SUPPORTED_VERSION= version(125, 0);
private static final int MAX_SUPPORTED_VERSION= version(124, Short.MAX_VALUE); private static final int MAX_SUPPORTED_VERSION= version(125, Short.MAX_VALUE);
private static final int DEFAULT_VERSION = version(124, 0); private static final int DEFAULT_VERSION = version(125, 0);
private static int version(int major, int minor) { private static int version(int major, int minor) {
return (major << 16) + minor; return (major << 16) + minor;
@ -251,8 +253,10 @@ public class PDOM extends PlatformObject implements IPDOM {
public static final int LINKAGES = Database.DATA_AREA; public static final int LINKAGES = Database.DATA_AREA;
public static final int FILE_INDEX = Database.DATA_AREA + 4; public static final int FILE_INDEX = Database.DATA_AREA + 4;
public static final int PROPERTIES = Database.DATA_AREA + 8; public static final int INDEX_OF_DEFECTIVE_FILES = Database.DATA_AREA + 8;
public static final int END= Database.DATA_AREA + 12; public static final int INDEX_OF_FILES_WITH_UNRESOLVED_INCLUDES = Database.DATA_AREA + 12;
public static final int PROPERTIES = Database.DATA_AREA + 16;
public static final int END= Database.DATA_AREA + 20;
static { static {
assert END <= Database.CHUNK_SIZE; assert END <= Database.CHUNK_SIZE;
} }
@ -303,9 +307,19 @@ public class PDOM extends PlatformObject implements IPDOM {
public void handleChange(PDOM pdom, ChangeEvent event); public void handleChange(PDOM pdom, ChangeEvent event);
} }
// Primitive comparator that compares database offsets of two records.
private static final IBTreeComparator offsetComparator = new IBTreeComparator() {
@Override
public int compare(long record1, long record2) throws CoreException {
return record1 < record2 ? -1 : record1 == record2 ? 0 : 1;
}
};
// Local caches // Local caches
protected Database db; protected Database db;
private BTree fileIndex; private BTree fileIndex;
private BTree indexOfDefectiveFiles;
private BTree indexOfFiledWithUnresolvedIncludes;
private Map<Integer, PDOMLinkage> fLinkageIDCache = new HashMap<Integer, PDOMLinkage>(); private Map<Integer, PDOMLinkage> fLinkageIDCache = new HashMap<Integer, PDOMLinkage>();
private File fPath; private File fPath;
private IIndexLocationConverter locationConverter; private IIndexLocationConverter locationConverter;
@ -432,6 +446,26 @@ public class PDOM extends PlatformObject implements IPDOM {
return fileIndex; return fileIndex;
} }
/**
* Returns the index of files that were read with I/O errors.
*/
public BTree getIndexOfDefectiveFiles() throws CoreException {
if (indexOfDefectiveFiles == null)
indexOfDefectiveFiles = new BTree(getDB(), INDEX_OF_DEFECTIVE_FILES, offsetComparator);
return indexOfDefectiveFiles;
}
/**
* Returns the index of files containg unresolved includes.
*/
public BTree getIndexOfFilesWithUnresolvedIncludes() throws CoreException {
if (indexOfFiledWithUnresolvedIncludes == null) {
indexOfFiledWithUnresolvedIncludes =
new BTree(getDB(), INDEX_OF_FILES_WITH_UNRESOLVED_INCLUDES, offsetComparator);
}
return indexOfFiledWithUnresolvedIncludes;
}
@Deprecated @Deprecated
@Override @Override
public PDOMFile getFile(int linkageID, IIndexFileLocation location) throws CoreException { public PDOMFile getFile(int linkageID, IIndexFileLocation location) throws CoreException {
@ -471,8 +505,22 @@ public class PDOM extends PlatformObject implements IPDOM {
@Override @Override
public IIndexFragmentFile[] getAllFiles() throws CoreException { public IIndexFragmentFile[] getAllFiles() throws CoreException {
final List<PDOMFile> locations = new ArrayList<PDOMFile>(); return getFiles(getFileIndex());
getFileIndex().accept(new IBTreeVisitor() { }
@Override
public IIndexFragmentFile[] getDefectiveFiles() throws CoreException {
return getFiles(getIndexOfDefectiveFiles());
}
@Override
public IIndexFragmentFile[] getFilesWithUnresolvedIncludes() throws CoreException {
return getFiles(getIndexOfFilesWithUnresolvedIncludes());
}
private IIndexFragmentFile[] getFiles(BTree index) throws CoreException {
final List<PDOMFile> files = new ArrayList<PDOMFile>();
index.accept(new IBTreeVisitor() {
@Override @Override
public int compare(long record) throws CoreException { public int compare(long record) throws CoreException {
return 0; return 0;
@ -481,11 +529,11 @@ public class PDOM extends PlatformObject implements IPDOM {
@Override @Override
public boolean visit(long record) throws CoreException { public boolean visit(long record) throws CoreException {
PDOMFile file = PDOMFile.recreateFile(PDOM.this, record); PDOMFile file = PDOMFile.recreateFile(PDOM.this, record);
locations.add(file); files.add(file);
return true; return true;
} }
}); });
return locations.toArray(new IIndexFragmentFile[locations.size()]); return files.toArray(new IIndexFragmentFile[files.size()]);
} }
protected IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location, protected IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location,
@ -1296,6 +1344,8 @@ public class PDOM extends PlatformObject implements IPDOM {
private void clearCaches() { private void clearCaches() {
fileIndex= null; fileIndex= null;
indexOfDefectiveFiles= null;
indexOfFiledWithUnresolvedIncludes= null;
fLinkageIDCache.clear(); fLinkageIDCache.clear();
clearResultCache(); clearResultCache();
} }

View file

@ -20,11 +20,11 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
@ -139,17 +139,17 @@ public class PDOMManager implements IWritableIndexManager, IListener {
ILinkage.C_LINKAGE_ID, ILinkage.CPP_LINKAGE_ID, ILinkage.FORTRAN_LINKAGE_ID ILinkage.C_LINKAGE_ID, ILinkage.CPP_LINKAGE_ID, ILinkage.FORTRAN_LINKAGE_ID
}; };
private final LinkedList<ICProject> fProjectQueue= new LinkedList<ICProject>(); private final ArrayDeque<ICProject> fProjectQueue= new ArrayDeque<ICProject>();
private final PDOMSetupJob fSetupJob; private final PDOMSetupJob fSetupJob;
/** /**
* Protects fIndexerJob, fCurrentTask and fTaskQueue. * Protects fIndexerJob, fCurrentTask and fTaskQueue.
*/ */
private final LinkedList<IPDOMIndexerTask> fTaskQueue = new LinkedList<IPDOMIndexerTask>(); private final ArrayDeque<IPDOMIndexerTask> fTaskQueue = new ArrayDeque<IPDOMIndexerTask>();
private final PDOMIndexerJob fIndexerJob; private final PDOMIndexerJob fIndexerJob;
private IPDOMIndexerTask fCurrentTask; private IPDOMIndexerTask fCurrentTask;
private int fSourceCount, fHeaderCount, fTickCount; private int fSourceCount, fHeaderCount, fTickCount;
private final LinkedList<Runnable> fChangeEvents= new LinkedList<Runnable>(); private final ArrayDeque<Runnable> fChangeEvents= new ArrayDeque<Runnable>();
private final Job fNotificationJob; private final Job fNotificationJob;
private final AtomicMultiSet<IIndexFileLocation> fFilesIndexedUnconditionlly= new AtomicMultiSet<IIndexFileLocation>(); private final AtomicMultiSet<IIndexFileLocation> fFilesIndexedUnconditionlly= new AtomicMultiSet<IIndexFileLocation>();
@ -1513,10 +1513,10 @@ public class PDOMManager implements IWritableIndexManager, IListener {
IIndex index= getIndex(cproject); IIndex index= getIndex(cproject);
index.acquireReadLock(); index.acquireReadLock();
try { try {
for(ITranslationUnit tu : sources) { for (ITranslationUnit tu : sources) {
IResource resource= tu.getResource(); IResource resource= tu.getResource();
if (resource instanceof IFile && isSubjectToIndexing(tu.getLanguage())) { if (resource instanceof IFile && isSubjectToIndexing(tu.getLanguage())) {
IIndexFileLocation location= IndexLocationFactory.getWorkspaceIFL((IFile)resource); IIndexFileLocation location= IndexLocationFactory.getWorkspaceIFL((IFile) resource);
if (!areSynchronized(new HashSet<IIndexFileLocation>(), index, resource, location)) { if (!areSynchronized(new HashSet<IIndexFileLocation>(), index, resource, location)) {
return false; return false;
} }
@ -1566,7 +1566,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
// if it is up-to-date, the includes have not changed and may // if it is up-to-date, the includes have not changed and may
// be read from the index. // be read from the index.
IIndexInclude[] includes= index.findIncludes(file[0]); IIndexInclude[] includes= index.findIncludes(file[0]);
for(IIndexInclude inc : includes) { for (IIndexInclude inc : includes) {
IIndexFileLocation newLocation= inc.getIncludesLocation(); IIndexFileLocation newLocation= inc.getIncludesLocation();
if (newLocation != null) { if (newLocation != null) {
String path= newLocation.getFullPath(); String path= newLocation.getFullPath();

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007, 2010 Wind River Systems, Inc. and others. * Copyright (c) 2007, 2012 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -41,7 +41,7 @@ import org.eclipse.core.runtime.IProgressMonitor;
/** /**
* The PDOMProxy is returned by the PDOMManager before the indexer kicks in. Also and more * The PDOMProxy is returned by the PDOMManager before the indexer kicks in. Also and more
* importantly it is returned when the indexer has been shut down (clients may not be aware * importantly it is returned when the indexer has been shut down (clients may not be aware
* of this yet). Doing that prevents the creation of empty pdoms for deleted projects. * of this yet). Doing that prevents the creation of empty PDOMs for deleted projects.
*/ */
public class PDOMProxy implements IPDOM { public class PDOMProxy implements IPDOM {
private PDOM fDelegate; private PDOM fDelegate;
@ -318,6 +318,20 @@ public class PDOMProxy implements IPDOM {
return IIndexFragmentFile.EMPTY_ARRAY; return IIndexFragmentFile.EMPTY_ARRAY;
} }
@Override
public synchronized IIndexFragmentFile[] getDefectiveFiles() throws CoreException {
if (fDelegate != null)
return fDelegate.getDefectiveFiles();
return IIndexFragmentFile.EMPTY_ARRAY;
}
@Override
public synchronized IIndexFragmentFile[] getFilesWithUnresolvedIncludes() throws CoreException {
if (fDelegate != null)
return fDelegate.getFilesWithUnresolvedIncludes();
return IIndexFragmentFile.EMPTY_ARRAY;
}
@Override @Override
public synchronized IIndexFragmentBinding[] findMacroContainers(Pattern pattern, IndexFilter filter, public synchronized IIndexFragmentBinding[] findMacroContainers(Pattern pattern, IndexFilter filter,
IProgressMonitor monitor) throws CoreException { IProgressMonitor monitor) throws CoreException {

View file

@ -79,6 +79,7 @@ abstract public class PDOMWriter {
final long timestamp; final long timestamp;
final long fileSize; final long fileSize;
final long contentsHash; final long contentsHash;
final long sourceReadTime;
final boolean hasError; final boolean hasError;
public FileInAST(IASTPreprocessorIncludeStatement includeStmt, FileContentKey key) { public FileInAST(IASTPreprocessorIncludeStatement includeStmt, FileContentKey key) {
@ -87,6 +88,7 @@ abstract public class PDOMWriter {
timestamp= includeStmt.getIncludedFileTimestamp(); timestamp= includeStmt.getIncludedFileTimestamp();
fileSize = includeStmt.getIncludedFileSize(); fileSize = includeStmt.getIncludedFileSize();
contentsHash= includeStmt.getIncludedFileContentsHash(); contentsHash= includeStmt.getIncludedFileContentsHash();
sourceReadTime= includeStmt.getIncludedFileReadTime();
hasError= includeStmt.isErrorInIncludedFile(); hasError= includeStmt.isErrorInIncludedFile();
} }
@ -96,6 +98,7 @@ abstract public class PDOMWriter {
timestamp= codeReader.getTimestamp(); timestamp= codeReader.getTimestamp();
fileSize= codeReader.getFileSize(); fileSize= codeReader.getFileSize();
contentsHash= codeReader.getContentsHash(); contentsHash= codeReader.getContentsHash();
sourceReadTime= codeReader.getReadTime();
hasError= codeReader.hasError(); hasError= codeReader.hasError();
} }
@ -577,6 +580,7 @@ abstract public class PDOMWriter {
index.setFileContent(file, linkageID, includeInfoArray, macros, names, fResolver, lock); index.setFileContent(file, linkageID, includeInfoArray, macros, names, fResolver, lock);
} }
file.setTimestamp(astFile.hasError ? 0 : astFile.timestamp); file.setTimestamp(astFile.hasError ? 0 : astFile.timestamp);
file.setSourceReadTime(astFile.sourceReadTime);
file.setSizeAndEncodingHashcode(computeFileSizeAndEncodingHashcode(astFile.fileSize, location)); file.setSizeAndEncodingHashcode(computeFileSizeAndEncodingHashcode(astFile.fileSize, location));
file.setContentsHash(astFile.contentsHash); file.setContentsHash(astFile.contentsHash);
file = index.commitUncommittedFile(); file = index.commitUncommittedFile();

View file

@ -87,6 +87,10 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
public IIndexFragmentFile commitUncommittedFile() throws CoreException { public IIndexFragmentFile commitUncommittedFile() throws CoreException {
if (uncommittedFile == null) if (uncommittedFile == null)
return null; return null;
int defectiveStateChange = uncommittedFile.getTimestamp() == 0 ? 1 : 0;
int unresolvedIncludeStateChange = uncommittedFile.hasUnresolvedInclude() ? 1 : 0;
PDOMFile file; PDOMFile file;
if (fileBeingUpdated == null) { if (fileBeingUpdated == null) {
// New file, insert it into the index. // New file, insert it into the index.
@ -94,10 +98,25 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
getFileIndex().insert(file.getRecord()); getFileIndex().insert(file.getRecord());
} else { } else {
// Existing file. // Existing file.
if (fileBeingUpdated.getTimestamp() == 0)
defectiveStateChange -= 1;
if (fileBeingUpdated.hasUnresolvedInclude())
unresolvedIncludeStateChange -= 1;
fileBeingUpdated.replaceContentsFrom(uncommittedFile); fileBeingUpdated.replaceContentsFrom(uncommittedFile);
file = fileBeingUpdated; file = fileBeingUpdated;
fileBeingUpdated = null; fileBeingUpdated = null;
} }
if (defectiveStateChange > 0) {
getIndexOfDefectiveFiles().insert(file.getRecord());
} else if (defectiveStateChange < 0) {
getIndexOfDefectiveFiles().delete(file.getRecord());
}
if (unresolvedIncludeStateChange > 0) {
getIndexOfFilesWithUnresolvedIncludes().insert(file.getRecord());
} else if (unresolvedIncludeStateChange < 0) {
getIndexOfFilesWithUnresolvedIncludes().delete(file.getRecord());
}
fEvent.fFilesWritten.add(uncommittedKey.getLocation()); fEvent.fFilesWritten.add(uncommittedKey.getLocation());
uncommittedFile = null; uncommittedFile = null;
uncommittedKey = null; uncommittedKey = null;

View file

@ -72,13 +72,14 @@ public class PDOMFile implements IIndexFragmentFile {
private static final int LOCATION_REPRESENTATION = FIRST_MACRO + Database.PTR_SIZE; private static final int LOCATION_REPRESENTATION = FIRST_MACRO + Database.PTR_SIZE;
private static final int LINKAGE_ID= LOCATION_REPRESENTATION + Database.PTR_SIZE; // size 3 private static final int LINKAGE_ID= LOCATION_REPRESENTATION + Database.PTR_SIZE; // size 3
private static final int FLAGS= LINKAGE_ID + 3; // size 1 private static final int FLAGS= LINKAGE_ID + 3; // size 1
private static final int TIME_STAMP = FLAGS + 1; // long private static final int TIME_STAMP= FLAGS + 1; // long
private static final int CONTENT_HASH= TIME_STAMP + 8; // long private static final int SOURCE_READ_TIME= TIME_STAMP + 8; // long
private static final int CONTENT_HASH= SOURCE_READ_TIME + 8; // long
private static final int SIZE_AND_ENCODING_HASH= CONTENT_HASH + 8; private static final int SIZE_AND_ENCODING_HASH= CONTENT_HASH + 8;
private static final int LAST_USING_DIRECTIVE= SIZE_AND_ENCODING_HASH + 4; private static final int LAST_USING_DIRECTIVE= SIZE_AND_ENCODING_HASH + 4;
private static final int FIRST_MACRO_REFERENCE= LAST_USING_DIRECTIVE + Database.PTR_SIZE; private static final int FIRST_MACRO_REFERENCE= LAST_USING_DIRECTIVE + Database.PTR_SIZE;
private static final int SIGNIFICANT_MACROS= FIRST_MACRO_REFERENCE + Database.PTR_SIZE; private static final int SIGNIFICANT_MACROS= FIRST_MACRO_REFERENCE + Database.PTR_SIZE;
private static final int RECORD_SIZE= SIGNIFICANT_MACROS + Database.PTR_SIZE; // 8*PTR_SIZE + 3+1+8+8+4 = 56 private static final int RECORD_SIZE= SIGNIFICANT_MACROS + Database.PTR_SIZE; // 8*PTR_SIZE + 3+1+8+8+8+4 = 64
private static final int FLAG_PRAGMA_ONCE_SEMANTICS = 0x01; private static final int FLAG_PRAGMA_ONCE_SEMANTICS = 0x01;
@ -205,6 +206,7 @@ public class PDOMFile implements IIndexFragmentFile {
} }
setTimestamp(sourceFile.getTimestamp()); setTimestamp(sourceFile.getTimestamp());
setSourceReadTime(sourceFile.getSourceReadTime());
setSizeAndEncodingHashcode(sourceFile.getSizeAndEncodingHashcode()); setSizeAndEncodingHashcode(sourceFile.getSizeAndEncodingHashcode());
setContentsHash(sourceFile.getContentsHash()); setContentsHash(sourceFile.getContentsHash());
@ -309,6 +311,18 @@ public class PDOMFile implements IIndexFragmentFile {
db.putLong(record + TIME_STAMP, timestamp); db.putLong(record + TIME_STAMP, timestamp);
} }
@Override
public long getSourceReadTime() throws CoreException {
Database db = fLinkage.getDB();
return db.getLong(record + SOURCE_READ_TIME);
}
@Override
public void setSourceReadTime(long time) throws CoreException {
Database db= fLinkage.getDB();
db.putLong(record + SOURCE_READ_TIME, time);
}
@Override @Override
public long getContentsHash() throws CoreException { public long getContentsHash() throws CoreException {
Database db = fLinkage.getDB(); Database db = fLinkage.getDB();
@ -571,6 +585,7 @@ public class PDOMFile implements IIndexFragmentFile {
m.delete(); m.delete();
} }
setFirstMacroReference(null); setFirstMacroReference(null);
setSourceReadTime(0);
setTimestamp(-1); setTimestamp(-1);
} }
@ -644,6 +659,17 @@ public class PDOMFile implements IIndexFragmentFile {
return result.toArray(new IIndexInclude[result.size()]); return result.toArray(new IIndexInclude[result.size()]);
} }
@Override
public boolean hasUnresolvedInclude() throws CoreException {
PDOMInclude include = getFirstInclude();
while (include != null) {
if (!include.isResolved() && include.isActive())
return true;
include = include.getNextInIncludes();
}
return false;
}
@Override @Override
public IIndexMacro[] getMacros() throws CoreException { public IIndexMacro[] getMacros() throws CoreException {
List<PDOMMacro> result= new ArrayList<PDOMMacro>(); List<PDOMMacro> result= new ArrayList<PDOMMacro>();

View file

@ -188,9 +188,7 @@ public class IndexerPreferences {
} }
public static int getDefaultUpdatePolicy() { public static int getDefaultUpdatePolicy() {
Preferences[] prefs = new Preferences[] { Preferences[] prefs = new Preferences[] { getDefaultPreferences() };
getDefaultPreferences()
};
return getUpdatePolicy(prefs); return getUpdatePolicy(prefs);
} }
@ -203,7 +201,7 @@ public class IndexerPreferences {
} }
private static void setProperties(Preferences prefs, Properties props) { private static void setProperties(Preferences prefs, Properties props) {
for (Map.Entry<Object,Object> entry : props.entrySet()) { for (Map.Entry<Object, Object> entry : props.entrySet()) {
String key = (String) entry.getKey(); String key = (String) entry.getKey();
String val = (String) entry.getValue(); String val = (String) entry.getValue();
prefs.put(key, val); prefs.put(key, val);

View file

@ -9,7 +9,6 @@
* QNX - Initial API and implementation * QNX - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.indexer; package org.eclipse.cdt.internal.core.pdom.indexer;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
@ -20,6 +19,7 @@ import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics;
* Configures the abstract indexer to return tasks suitable for fast indexing. * Configures the abstract indexer to return tasks suitable for fast indexing.
*/ */
class PDOMFastIndexerTask extends PDOMIndexerTask { class PDOMFastIndexerTask extends PDOMIndexerTask {
public PDOMFastIndexerTask(PDOMFastIndexer indexer, ITranslationUnit[] added, public PDOMFastIndexerTask(PDOMFastIndexer indexer, ITranslationUnit[] added,
ITranslationUnit[] changed, ITranslationUnit[] removed) { ITranslationUnit[] changed, ITranslationUnit[] removed) {
super(added, changed, removed, indexer, true); super(added, changed, removed, indexer, true);

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007, 2010 Wind River Systems, Inc. and others. * Copyright (c) 2007, 2012 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -11,6 +11,7 @@
******************************************************************************/ ******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.indexer; package org.eclipse.cdt.internal.core.pdom.indexer;
import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -22,13 +23,18 @@ import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexFile; import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexFileLocation; import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.index.IIndexInclude;
import org.eclipse.cdt.core.index.IIndexManager; import org.eclipse.cdt.core.index.IIndexManager;
import org.eclipse.cdt.core.index.IndexLocationFactory; import org.eclipse.cdt.core.index.IndexLocationFactory;
import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.internal.core.model.ExternalTranslationUnit; import org.eclipse.cdt.internal.core.model.ExternalTranslationUnit;
import org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor;
import org.eclipse.cdt.internal.core.parser.scanner.IncludeSearchPathElement;
import org.eclipse.cdt.internal.core.parser.scanner.ScannerUtility;
import org.eclipse.cdt.internal.core.pdom.IndexerProgress; import org.eclipse.cdt.internal.core.pdom.IndexerProgress;
import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResource;
@ -42,19 +48,18 @@ import org.eclipse.osgi.util.NLS;
* A task for updating an index, suitable for all indexers. * A task for updating an index, suitable for all indexers.
*/ */
public class PDOMUpdateTask implements IPDOMIndexerTask { public class PDOMUpdateTask implements IPDOMIndexerTask {
protected static final String TRUE= String.valueOf(true); private static final ITranslationUnit[] NO_TUS = {};
protected static final ITranslationUnit[] NO_TUS = new ITranslationUnit[0];
private final IPDOMIndexer fIndexer; private final IPDOMIndexer fIndexer;
private final IndexerProgress fProgress;
private final int fUpdateOptions; private final int fUpdateOptions;
private final IndexerProgress fProgress;
private volatile IPDOMIndexerTask fDelegate; private volatile IPDOMIndexerTask fDelegate;
private ArrayList<ICElement> fFilesAndFolders; private ArrayList<ICElement> fFilesAndFolders;
public PDOMUpdateTask(IPDOMIndexer indexer, int updateOptions) { public PDOMUpdateTask(IPDOMIndexer indexer, int updateOptions) {
fIndexer= indexer; fIndexer= indexer;
fProgress= createProgress();
fUpdateOptions= updateOptions; fUpdateOptions= updateOptions;
fProgress= createProgress();
} }
private IndexerProgress createProgress() { private IndexerProgress createProgress() {
@ -89,8 +94,10 @@ public class PDOMUpdateTask implements IPDOMIndexerTask {
} }
} }
private void createDelegate(ICProject project, IProgressMonitor monitor) throws CoreException, InterruptedException { private void createDelegate(ICProject project, IProgressMonitor monitor)
throws CoreException, InterruptedException {
HashSet<ITranslationUnit> set= new HashSet<ITranslationUnit>(); HashSet<ITranslationUnit> set= new HashSet<ITranslationUnit>();
if ((fUpdateOptions & (IIndexManager.UPDATE_ALL | IIndexManager.UPDATE_CHECK_TIMESTAMPS)) != 0) {
TranslationUnitCollector collector= new TranslationUnitCollector(set, set, monitor); TranslationUnitCollector collector= new TranslationUnitCollector(set, set, monitor);
boolean haveProject= false; boolean haveProject= false;
if (fFilesAndFolders == null) { if (fFilesAndFolders == null) {
@ -113,18 +120,42 @@ public class PDOMUpdateTask implements IPDOMIndexerTask {
IIndexFileLocation floc= indexFile.getLocation(); IIndexFileLocation floc= indexFile.getLocation();
final String fullPath = floc.getFullPath(); final String fullPath = floc.getFullPath();
if (fullPath == null || !fullPath.startsWith(projectPrefix)) { if (fullPath == null || !fullPath.startsWith(projectPrefix)) {
IPath path= IndexLocationFactory.getAbsolutePath(floc); ITranslationUnit tu = getTranslationUnit(floc, project);
if (path != null) {
ITranslationUnit tu= CoreModel.getDefault().createTranslationUnitFrom(project, path);
if (tu != null) { if (tu != null) {
if (fullPath != null) { set.add(tu);
if (tu instanceof ExternalTranslationUnit) {
IResource file= ResourcesPlugin.getWorkspace().getRoot().findMember(fullPath);
if (file instanceof IFile) {
((ExternalTranslationUnit) tu).setResource((IFile) file);
} }
} }
} }
} finally {
index.releaseReadLock();
}
}
}
if ((fUpdateOptions & IIndexManager.UPDATE_UNRESOLVED_INCLUDES) != 0) {
IIndex index= CCorePlugin.getIndexManager().getIndex(project);
index.acquireReadLock();
try {
// Files that were indexed with I/O errors.
IIndexFile[] files= index.getDefectiveFiles();
for (IIndexFile file : files) {
ITranslationUnit tu = getTranslationUnit(file.getLocation(), project);
if (tu != null) {
set.add(tu);
}
}
// Files with unresolved includes.
files= index.getFilesWithUnresolvedIncludes();
if (files.length > 0) {
ProjectIndexerInputAdapter inputAdapter = new ProjectIndexerInputAdapter(project, true);
ProjectIndexerIncludeResolutionHeuristics includeResolutionHeuristics =
new ProjectIndexerIncludeResolutionHeuristics(project.getProject(), inputAdapter);
for (IIndexFile file : files) {
ITranslationUnit tu = getTranslationUnit(file.getLocation(), project);
if (tu != null) {
IScannerInfo scannerInfo = tu.getScannerInfo(true);
if (canResolveUnresolvedInclude(file, scannerInfo, includeResolutionHeuristics)) {
set.add(tu); set.add(tu);
} }
} }
@ -134,15 +165,108 @@ public class PDOMUpdateTask implements IPDOMIndexerTask {
index.releaseReadLock(); index.releaseReadLock();
} }
} }
ITranslationUnit[] tus= set.toArray(new ITranslationUnit[set.size()]); ITranslationUnit[] tus= set.toArray(new ITranslationUnit[set.size()]);
IPDOMIndexerTask delegate= fIndexer.createTask(NO_TUS, tus, NO_TUS); IPDOMIndexerTask delegate= fIndexer.createTask(NO_TUS, tus, NO_TUS);
if (delegate instanceof PDOMIndexerTask) { if (delegate instanceof PDOMIndexerTask) {
final PDOMIndexerTask task = (PDOMIndexerTask) delegate; final PDOMIndexerTask task = (PDOMIndexerTask) delegate;
task.setUpdateFlags(fUpdateOptions); task.setUpdateFlags(fUpdateOptions);
} }
synchronized (this) { setDelegate(delegate);
fDelegate= delegate;
} }
private ITranslationUnit getTranslationUnit(IIndexFileLocation location, ICProject project) {
IPath path= IndexLocationFactory.getAbsolutePath(location);
if (path == null)
return null;
ITranslationUnit tu= CoreModel.getDefault().createTranslationUnitFrom(project, path);
if (tu != null) {
final String fullPath = location.getFullPath();
if (fullPath != null) {
if (tu instanceof ExternalTranslationUnit) {
IResource file= ResourcesPlugin.getWorkspace().getRoot().findMember(fullPath);
if (file instanceof IFile) {
((ExternalTranslationUnit) tu).setResource((IFile) file);
}
}
}
}
return tu;
}
private boolean canResolveUnresolvedInclude(IIndexFile file, IScannerInfo scannerInfo,
ProjectIndexerIncludeResolutionHeuristics includeResolutionHeuristics) {
try {
String filePath = IndexLocationFactory.getAbsolutePath(file.getLocation()).toOSString();
long fileReadTime = file.getSourceReadTime();
IncludeSearchPathElement[] includeSearchPath =
CPreprocessor.configureIncludeSearchPath(new File(filePath).getParentFile(), scannerInfo);
for (IIndexInclude include : file.getIncludes()) {
if (!include.isResolved() && include.isActive() &&
canResolveInclude(include, filePath, fileReadTime, includeSearchPath, includeResolutionHeuristics)) {
return true;
}
}
} catch (CoreException e) {
CCorePlugin.log(e);
}
return false;
}
private boolean canResolveInclude(IIndexInclude include, String currentFile, long timestamp,
IncludeSearchPathElement[] includeSearchPath,
ProjectIndexerIncludeResolutionHeuristics includeResolutionHeuristics) throws CoreException {
String includeName = include.getFullName();
String filePath = CPreprocessor.getAbsoluteInclusionPath(includeName, currentFile);
if (filePath != null && fileIsNotOlderThanTimestamp(filePath, timestamp)) {
return true;
}
if (currentFile != null && !include.isSystemInclude()) {
// Check to see if we find a match in the current directory
final File currentDir= new File(currentFile).getParentFile();
if (currentDir != null) {
filePath = ScannerUtility.createReconciledPath(currentDir.getAbsolutePath(), includeName);
if (!filePath.equals(currentFile) && fileIsNotOlderThanTimestamp(filePath, timestamp)) {
return true;
}
}
}
// Unlike CPreprocessor.findInclusion we are searching include path from the beginning.
// This simplification may produce false positives, but by checking file modification time
// we guarantee that any false positive won't be produced again when this task runs
// next time.
for (IncludeSearchPathElement path : includeSearchPath) {
if (!include.isSystemInclude() || !path.isForQuoteIncludesOnly()) {
filePath = path.getLocation(includeName);
if (filePath != null && fileIsNotOlderThanTimestamp(filePath, timestamp)) {
return true;
}
}
}
if (includeResolutionHeuristics != null) {
filePath= includeResolutionHeuristics.findInclusion(includeName, currentFile);
if (filePath != null && fileIsNotOlderThanTimestamp(filePath, timestamp)) {
return true;
}
}
return false;
}
/**
* Returns true if the file exists and is not older than the given timestamp.
*/
private boolean fileIsNotOlderThanTimestamp(String filename, long timestamp) {
// We are subtracting 1 second from the timestamp to account for limited precision
// of File.lastModified() method and possible asynchrony between clocks on multi-CPU
// systems. This may produce false positives, but they are pretty harmless.
return new File(filename).lastModified() >= timestamp - 1000;
}
private synchronized void setDelegate(IPDOMIndexerTask delegate) {
fDelegate= delegate;
} }
@Override @Override

View file

@ -30,7 +30,7 @@ import org.eclipse.core.runtime.Path;
* Heuristics for picking up includes from the project * Heuristics for picking up includes from the project
*/ */
public class ProjectIndexerIncludeResolutionHeuristics implements IIncludeFileResolutionHeuristics { public class ProjectIndexerIncludeResolutionHeuristics implements IIncludeFileResolutionHeuristics {
private static final String TRUE = "true"; //$NON-NLS-1$ private static final String TRUE = String.valueOf(true);
private IProject fProject; private IProject fProject;
private IProject[] fProjects; private IProject[] fProjects;
@ -53,7 +53,6 @@ public class ProjectIndexerIncludeResolutionHeuristics implements IIncludeFileRe
if (fProject == null) if (fProject == null)
return null; return null;
if (fProjects == null) { if (fProjects == null) {
if (fProject.isOpen()) { if (fProject.isOpen()) {
String val= IndexerPreferences.get(fProject, IndexerPreferences.KEY_INCLUDE_HEURISTICS, TRUE); String val= IndexerPreferences.get(fProject, IndexerPreferences.KEY_INCLUDE_HEURISTICS, TRUE);
@ -78,7 +77,6 @@ public class ProjectIndexerIncludeResolutionHeuristics implements IIncludeFileRe
return bestLocation.toString(); return bestLocation.toString();
} }
private IResource selectBest(IFile[] files, char[] currentFullPath) { private IResource selectBest(IFile[] files, char[] currentFullPath) {
IFile best= files[0]; IFile best= files[0];
int bestScore= computeScore(best.getFullPath().toString().toCharArray(), currentFullPath); int bestScore= computeScore(best.getFullPath().toString().toCharArray(), currentFullPath);
@ -96,14 +94,14 @@ public class ProjectIndexerIncludeResolutionHeuristics implements IIncludeFileRe
private int computeScore(char[] path1, char[] path2) { private int computeScore(char[] path1, char[] path2) {
final int limit= Math.min(path1.length, path2.length); final int limit= Math.min(path1.length, path2.length);
int match=0; int match= 0;
for (int i = 0; i < limit; i++) { for (int i = 0; i < limit; i++) {
if (path1[i] != path2[i]) if (path1[i] != path2[i])
break; break;
if (path1[i] == '/') if (path1[i] == '/')
match= i; match= i;
} }
// prefer shortest path with longest matches with // Prefer shortest path with longest matches with.
return (match << 16) - path1.length; return (match << 16) - path1.length;
} }
@ -115,7 +113,7 @@ public class ProjectIndexerIncludeResolutionHeuristics implements IIncludeFileRe
List<IProject> projectsToSearch= new ArrayList<IProject>(); List<IProject> projectsToSearch= new ArrayList<IProject>();
projectsToSearch.add(prj); projectsToSearch.add(prj);
for (int i=0; i<projectsToSearch.size(); i++) { for (int i= 0; i < projectsToSearch.size(); i++) {
IProject project= projectsToSearch.get(i); IProject project= projectsToSearch.get(i);
IProject[] nextLevel; IProject[] nextLevel;
try { try {

View file

@ -148,8 +148,10 @@ public class RefreshScopeManager {
|| (delta.getKind() == IResourceDelta.CHANGED && ((delta || (delta.getKind() == IResourceDelta.CHANGED && ((delta
.getFlags() & IResourceDelta.OPEN) != 0))) { .getFlags() & IResourceDelta.OPEN) != 0))) {
fIsLoading = true;
loadSettings(ResourcesPlugin.getWorkspace() loadSettings(ResourcesPlugin.getWorkspace()
.getRoot(), project); .getRoot(), project);
fIsLoading = false;
return false; return false;
} }
@ -344,16 +346,16 @@ public class RefreshScopeManager {
@Override @Override
public void run(IProgressMonitor monitor) throws CoreException { public void run(IProgressMonitor monitor) throws CoreException {
HashMap<String,HashMap<IResource, List<RefreshExclusion>>> configMap = getConfigurationToResourcesMap(project);
Iterator<String> it = configMap.keySet().iterator(); CProjectDescriptionManager descriptionManager = CProjectDescriptionManager
while (it.hasNext()) { .getInstance();
String configName = it.next(); ICProjectDescription projectDescription = descriptionManager.getProjectDescription(project, false);
List<IResource> resourcesToRefresh = getResourcesToRefresh(project,configName); ICConfigurationDescription active_conf = projectDescription.getActiveConfiguration();
String name = active_conf.getName();
List<IResource> resourcesToRefresh = getResourcesToRefresh(project,name);
for (IResource resource : resourcesToRefresh) { for (IResource resource : resourcesToRefresh) {
List<RefreshExclusion> exclusions = getExclusions(project,configName,resource); List<RefreshExclusion> exclusions = getExclusions(project,name,resource);
refreshResources(configName, resource, exclusions, monitor); refreshResources(name, resource, exclusions, monitor);
}
} }
} }
}; };
@ -723,8 +725,7 @@ public class RefreshScopeManager {
/** /**
* @since 5.4 * @since 5.4
*/ */
public synchronized void setResourcesToExclusionsMap(IProject project, String configName, HashMap<IResource, List<RefreshExclusion>> source_resourceMap) { // List<IResource> resources) { public synchronized void setResourcesToExclusionsMap(IProject project, String configName, HashMap<IResource, List<RefreshExclusion>> source_resourceMap) {
HashMap<IResource, List<RefreshExclusion>> target_resourceMap = getResourcesToExclusionsMap(project,configName); HashMap<IResource, List<RefreshExclusion>> target_resourceMap = getResourcesToExclusionsMap(project,configName);
target_resourceMap.clear(); target_resourceMap.clear();

View file

@ -14,6 +14,9 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core; package org.eclipse.cdt.internal.core;
import java.util.HashSet;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CCorePreferenceConstants; import org.eclipse.cdt.core.CCorePreferenceConstants;
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants; import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
@ -24,9 +27,6 @@ import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
import org.eclipse.core.runtime.preferences.DefaultScope; import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import java.util.HashSet;
import java.util.Map;
public class CCorePreferenceInitializer extends AbstractPreferenceInitializer { public class CCorePreferenceInitializer extends AbstractPreferenceInitializer {
/* (non-Javadoc) /* (non-Javadoc)
@ -51,7 +51,7 @@ public class CCorePreferenceInitializer extends AbstractPreferenceInitializer {
// Store default values to default preferences // Store default values to default preferences
IEclipsePreferences defaultPreferences = DefaultScope.INSTANCE.getNode(CCorePlugin.PLUGIN_ID); IEclipsePreferences defaultPreferences = DefaultScope.INSTANCE.getNode(CCorePlugin.PLUGIN_ID);
for (Map.Entry<String,String> entry : defaultOptionsMap.entrySet()) { for (Map.Entry<String, String> entry : defaultOptionsMap.entrySet()) {
String optionName = entry.getKey(); String optionName = entry.getKey();
defaultPreferences.put(optionName, entry.getValue()); defaultPreferences.put(optionName, entry.getValue());
optionNames.add(optionName); optionNames.add(optionName);

View file

@ -460,8 +460,9 @@ CDTIndexer.fastindexer=C/C++ Indexer
IndexView.name=C/C++ Index IndexView.name=C/C++ Index
RebuildIndex.name=&Rebuild RebuildIndex.name=&Rebuild
SyncIndex.name=&Update with Modified Files
FreshenIndex.name=&Freshen All Files FreshenIndex.name=&Freshen All Files
SyncIndex.name=&Update with Modified Files
UpdateUnresolvedIncludes.name=R&e-resolve Unresolved Includes
SearchUnresolvedIncludes.name=Search for Unresolved &Includes SearchUnresolvedIncludes.name=Search for Unresolved &Includes
CreateParserLog.name=Create Parser &Log File CreateParserLog.name=Create Parser &Log File

View file

@ -28,7 +28,7 @@
<extension-point id="workingSetConfigurations" name="%workingSetConfigurationsExtensionPoint" schema="schema/workingSetConfigurations.exsd"/> <extension-point id="workingSetConfigurations" name="%workingSetConfigurationsExtensionPoint" schema="schema/workingSetConfigurations.exsd"/>
<extension-point id="LanguageSettingsProviderAssociation" name="%LanguageSettingsProviderAssociationExtensionPoint" schema="schema/LanguageSettingsProviderAssociation.exsd"/> <extension-point id="LanguageSettingsProviderAssociation" name="%LanguageSettingsProviderAssociationExtensionPoint" schema="schema/LanguageSettingsProviderAssociation.exsd"/>
<extension-point id="RefreshExclusionContributor" name="%extension-point.name" schema="schema/RefreshExclusionContributor.exsd"/> <extension-point id="RefreshExclusionContributor" name="%extension-point.name" schema="schema/RefreshExclusionContributor.exsd"/>
<extension-point id="projectTypePages" name="%ProjectTypePages" schema="schema/projectTypePages.exsd"/> <extension-point id="projectTypePages" name="%projectTypePages" schema="schema/projectTypePages.exsd"/>
<extension <extension
point="org.eclipse.core.runtime.adapters"> point="org.eclipse.core.runtime.adapters">
@ -1372,15 +1372,20 @@
</or> </or>
</visibility> </visibility>
<action <action
class="org.eclipse.cdt.internal.ui.actions.FreshenIndexAction" class="org.eclipse.cdt.internal.ui.actions.UpdateUnresolvedIncludesAction"
id="org.eclipse.cdt.ui.updateIndexAction" id="org.eclipse.cdt.ui.updateUnresolvedIncludesAction"
label="%FreshenIndex.name" label="%UpdateUnresolvedIncludes.name"
menubarPath="org.eclipse.cdt.ui.indexmenu/update"/> menubarPath="org.eclipse.cdt.ui.indexmenu/update"/>
<action <action
class="org.eclipse.cdt.internal.ui.actions.UpdateIndexWithModifiedFilesAction" class="org.eclipse.cdt.internal.ui.actions.UpdateIndexWithModifiedFilesAction"
id="org.eclipse.cdt.ui.syncIndexWithDiskAction" id="org.eclipse.cdt.ui.syncIndexWithDiskAction"
label="%SyncIndex.name" label="%SyncIndex.name"
menubarPath="org.eclipse.cdt.ui.indexmenu/update"/> menubarPath="org.eclipse.cdt.ui.indexmenu/update"/>
<action
class="org.eclipse.cdt.internal.ui.actions.FreshenIndexAction"
id="org.eclipse.cdt.ui.updateIndexAction"
label="%FreshenIndex.name"
menubarPath="org.eclipse.cdt.ui.indexmenu/update"/>
<menu <menu
id="org.eclipse.cdt.ui.indexmenu" id="org.eclipse.cdt.ui.indexmenu"
label="%Index.menu" label="%Index.menu"
@ -1445,15 +1450,20 @@
value="org.eclipse.cdt.core.cnature"/> value="org.eclipse.cdt.core.cnature"/>
</visibility> </visibility>
<action <action
class="org.eclipse.cdt.internal.ui.actions.FreshenIndexAction" class="org.eclipse.cdt.internal.ui.actions.UpdateUnresolvedIncludesAction"
id="org.eclipse.cdt.ui.updateIndexAction" id="org.eclipse.cdt.ui.updateUnresolvedIncludesAction"
label="%FreshenIndex.name" label="%UpdateUnresolvedIncludes.name"
menubarPath="org.eclipse.cdt.ui.indexmenu/update"/> menubarPath="org.eclipse.cdt.ui.indexmenu/update"/>
<action <action
class="org.eclipse.cdt.internal.ui.actions.UpdateIndexWithModifiedFilesAction" class="org.eclipse.cdt.internal.ui.actions.UpdateIndexWithModifiedFilesAction"
id="org.eclipse.cdt.ui.syncIndexWithDiskAction" id="org.eclipse.cdt.ui.syncIndexWithDiskAction"
label="%SyncIndex.name" label="%SyncIndex.name"
menubarPath="org.eclipse.cdt.ui.indexmenu/update"/> menubarPath="org.eclipse.cdt.ui.indexmenu/update"/>
<action
class="org.eclipse.cdt.internal.ui.actions.FreshenIndexAction"
id="org.eclipse.cdt.ui.updateIndexAction"
label="%FreshenIndex.name"
menubarPath="org.eclipse.cdt.ui.indexmenu/update"/>
<action <action
class="org.eclipse.cdt.internal.ui.actions.RebuildIndexAction" class="org.eclipse.cdt.internal.ui.actions.RebuildIndexAction"
id="org.eclipse.cdt.ui.rebuildIndexAction" id="org.eclipse.cdt.ui.rebuildIndexAction"

View file

@ -9,7 +9,6 @@
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Anton Leherbauer (Wind River Systems) * Anton Leherbauer (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.ui.actions; package org.eclipse.cdt.internal.ui.actions;
import java.util.ArrayList; import java.util.ArrayList;
@ -32,7 +31,6 @@ import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.CUIPlugin;
public abstract class AbstractUpdateIndexAction implements IObjectActionDelegate { public abstract class AbstractUpdateIndexAction implements IObjectActionDelegate {
private ISelection fSelection; private ISelection fSelection;
@Override @Override
@ -45,9 +43,8 @@ public abstract class AbstractUpdateIndexAction implements IObjectActionDelegate
return; return;
IStructuredSelection cElements= SelectionConverter.convertSelectionToCElements(fSelection); IStructuredSelection cElements= SelectionConverter.convertSelectionToCElements(fSelection);
Iterator<?> i= cElements.iterator();
ArrayList<ICElement> tuSelection= new ArrayList<ICElement>(); ArrayList<ICElement> tuSelection= new ArrayList<ICElement>();
while (i.hasNext()) { for (Iterator<?> i= cElements.iterator(); i.hasNext();) {
Object o= i.next(); Object o= i.next();
if (o instanceof ICProject || o instanceof ICContainer || o instanceof ITranslationUnit) { if (o instanceof ICProject || o instanceof ICContainer || o instanceof ITranslationUnit) {
tuSelection.add((ICElement) o); tuSelection.add((ICElement) o);
@ -57,8 +54,7 @@ public abstract class AbstractUpdateIndexAction implements IObjectActionDelegate
try { try {
CCorePlugin.getIndexManager().update(tuArray, getUpdateOptions()); CCorePlugin.getIndexManager().update(tuArray, getUpdateOptions());
} } catch (CoreException e) {
catch (CoreException e) {
CUIPlugin.log(e); CUIPlugin.log(e);
} }
} }

View file

@ -8,7 +8,6 @@
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.ui.actions; package org.eclipse.cdt.internal.ui.actions;
import java.util.Iterator; import java.util.Iterator;
@ -24,7 +23,6 @@ import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ICProject;
public class RebuildIndexAction implements IObjectActionDelegate { public class RebuildIndexAction implements IObjectActionDelegate {
private ISelection fSelection; private ISelection fSelection;
@Override @Override

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007, 2010 Wind River Systems, Inc. and others. * Copyright (c) 2007, 2012 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.ui.actions; package org.eclipse.cdt.internal.ui.actions;
@ -18,6 +19,7 @@ public class UpdateIndexWithModifiedFilesAction extends AbstractUpdateIndexActio
return IIndexManager.UPDATE_CHECK_TIMESTAMPS | return IIndexManager.UPDATE_CHECK_TIMESTAMPS |
IIndexManager.UPDATE_CHECK_CONFIGURATION | IIndexManager.UPDATE_CHECK_CONFIGURATION |
IIndexManager.UPDATE_EXTERNAL_FILES_FOR_PROJECT | IIndexManager.UPDATE_EXTERNAL_FILES_FOR_PROJECT |
IIndexManager.UPDATE_CHECK_CONTENTS_HASH; IIndexManager.UPDATE_CHECK_CONTENTS_HASH |
IIndexManager.UPDATE_UNRESOLVED_INCLUDES;
} }
} }

View file

@ -0,0 +1,20 @@
/*******************************************************************************
* Copyright (c) 2012 Google, Inc 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:
* Sergey Prigogin (Google) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.actions;
import org.eclipse.cdt.core.index.IIndexManager;
public class UpdateUnresolvedIncludesAction extends AbstractUpdateIndexAction {
@Override
protected int getUpdateOptions() {
return IIndexManager.UPDATE_UNRESOLVED_INCLUDES;
}
}

View file

@ -112,6 +112,9 @@ public class LanguageSettingsEntriesTab extends AbstractCPropertyTab {
@Override @Override
protected String[] getOverlayKeys(ILanguageSettingsProvider provider) { protected String[] getOverlayKeys(ILanguageSettingsProvider provider) {
String[] overlayKeys = super.getOverlayKeys(provider); String[] overlayKeys = super.getOverlayKeys(provider);
if (provider.getName() == null) {
return overlayKeys;
}
if (currentLanguageId != null) { if (currentLanguageId != null) {
IResource rc = getResource(); IResource rc = getResource();

View file

@ -115,14 +115,11 @@ public class LanguageSettingsProviderTab extends AbstractCPropertyTab {
private class ProvidersTableLabelProvider extends LanguageSettingsProvidersLabelProvider { private class ProvidersTableLabelProvider extends LanguageSettingsProvidersLabelProvider {
@Override @Override
protected String[] getOverlayKeys(ILanguageSettingsProvider provider) { protected String[] getOverlayKeys(ILanguageSettingsProvider provider) {
String[] overlayKeys = super.getOverlayKeys(provider);
if (provider.getName() == null) { if (provider.getName() == null) {
String[] overlayKeys = new String[5];
overlayKeys[IDecoration.TOP_RIGHT] = CDTSharedImages.IMG_OVR_ERROR;
return overlayKeys; return overlayKeys;
} }
String[] overlayKeys = super.getOverlayKeys(provider);
if (page.isForProject()) { if (page.isForProject()) {
if (isEditedForProject(provider)) { if (isEditedForProject(provider)) {
overlayKeys[IDecoration.TOP_RIGHT] = CDTSharedImages.IMG_OVR_EDITED; overlayKeys[IDecoration.TOP_RIGHT] = CDTSharedImages.IMG_OVR_EDITED;
@ -1095,9 +1092,11 @@ public class LanguageSettingsProviderTab extends AbstractCPropertyTab {
} else if (page.isForPrefs()) { } else if (page.isForPrefs()) {
presentedProviders = new ArrayList<ILanguageSettingsProvider>(); presentedProviders = new ArrayList<ILanguageSettingsProvider>();
for (ILanguageSettingsProvider provider : LanguageSettingsManager.getWorkspaceProviders()) { for (String id : LanguageSettingsManager.getExtensionProviderIds()) {
if (!LanguageSettingsManager.isEqualExtensionProvider(provider, true)) { ILanguageSettingsProvider provider = LanguageSettingsManager.getWorkspaceProvider(id);
ILanguageSettingsProvider extProvider = LanguageSettingsManager.getExtensionProviderCopy(provider.getId(), true); ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(provider);
if (!LanguageSettingsManager.isEqualExtensionProvider(rawProvider, true)) {
ILanguageSettingsProvider extProvider = LanguageSettingsManager.getExtensionProviderCopy(id, true);
if (extProvider != null) { if (extProvider != null) {
provider = extProvider; provider = extProvider;
} }
@ -1112,9 +1111,11 @@ public class LanguageSettingsProviderTab extends AbstractCPropertyTab {
updateData(rcDescription); updateData(rcDescription);
// update other tabs // update other tabs
if (masterPropertyPage != null) {
masterPropertyPage.informAll(UPDATE, rcDescription); masterPropertyPage.informAll(UPDATE, rcDescription);
} }
} }
}
@Override @Override
protected void performApply(ICResourceDescription srcRcDescription, ICResourceDescription destRcDescription) { protected void performApply(ICResourceDescription srcRcDescription, ICResourceDescription destRcDescription) {

View file

@ -12,6 +12,7 @@ package org.eclipse.cdt.internal.ui.language.settings.providers;
import java.net.URL; import java.net.URL;
import org.eclipse.jface.viewers.IDecoration;
import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.osgi.util.NLS; import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Image;
@ -63,7 +64,11 @@ public class LanguageSettingsProvidersLabelProvider extends LabelProvider {
* Returns keys for image overlays. Returning {@code null} is not allowed. * Returns keys for image overlays. Returning {@code null} is not allowed.
*/ */
protected String[] getOverlayKeys(ILanguageSettingsProvider provider) { protected String[] getOverlayKeys(ILanguageSettingsProvider provider) {
return new String[5]; String[] overlayKeys = new String[5];
if (provider.getName() == null) {
overlayKeys[IDecoration.BOTTOM_LEFT] = CDTSharedImages.IMG_OVR_ERROR;
}
return overlayKeys;
} }
@Override @Override

View file

@ -28,6 +28,7 @@ public class Messages extends NLS {
public static String AbstractLangsListTab_Unexport; public static String AbstractLangsListTab_Unexport;
public static String AbstractLangsListTab_Conjunction; public static String AbstractLangsListTab_Conjunction;
public static String AbstractLangsListTab_Disjunction; public static String AbstractLangsListTab_Disjunction;
public static String AbstractLangsListTab_MbsProviderNotEnabled;
public static String AbstractLangsListTab_Modify; public static String AbstractLangsListTab_Modify;
public static String AbstractLangsListTab_MultiConfigStringListModeLinkHint; public static String AbstractLangsListTab_MultiConfigStringListModeLinkHint;
public static String AbstractLangsListTab_Replace; public static String AbstractLangsListTab_Replace;

View file

@ -107,6 +107,7 @@ AbstractLangsListTab_ExportIndicator=\ [exp]
AbstractLangsListTab_Unexport=Unexport AbstractLangsListTab_Unexport=Unexport
AbstractLangsListTab_Conjunction=Conjunction AbstractLangsListTab_Conjunction=Conjunction
AbstractLangsListTab_Disjunction=Disjunction AbstractLangsListTab_Disjunction=Disjunction
AbstractLangsListTab_MbsProviderNotEnabled=The settings are not used by indexer (MBS provider is disabled on 'Preprocessor Include Paths' page).
AbstractLangsListTab_Modify=Modify AbstractLangsListTab_Modify=Modify
AbstractLangsListTab_MultiConfigStringListModeLinkHint=Multiple configurations string list mode. Click on link to change or for more info. AbstractLangsListTab_MultiConfigStringListModeLinkHint=Multiple configurations string list mode. Click on link to change or for more info.
AbstractLangsListTab_Replace=Replace AbstractLangsListTab_Replace=Replace

View file

@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.ui.search; package org.eclipse.cdt.internal.ui.search;
@ -37,7 +38,7 @@ public class CSearchUnresolvedIncludesQuery extends CSearchQuery {
@Override @Override
protected IStatus runWithIndex(final IIndex index, IProgressMonitor monitor) { protected IStatus runWithIndex(final IIndex index, IProgressMonitor monitor) {
try { try {
for (IIndexFile file : index.getAllFiles()) { for (IIndexFile file : index.getFilesWithUnresolvedIncludes()) {
for (IIndexInclude include : file.getIncludes()) { for (IIndexInclude include : file.getIncludes()) {
if (include.isActive() && !include.isResolved()) { if (include.isActive() && !include.isResolved()) {
result.addMatch(new CSearchMatch(new ProblemSearchElement( result.addMatch(new CSearchMatch(new ProblemSearchElement(

View file

@ -98,7 +98,6 @@ import org.eclipse.cdt.internal.ui.viewsupport.CElementLabels;
import org.eclipse.cdt.internal.ui.viewsupport.IndexUI; import org.eclipse.cdt.internal.ui.viewsupport.IndexUI;
class OpenDeclarationsJob extends Job implements ASTRunnable { class OpenDeclarationsJob extends Job implements ASTRunnable {
private enum NameKind { REFERENCE, DECLARATION, USING_DECL, DEFINITION } private enum NameKind { REFERENCE, DECLARATION, USING_DECL, DEFINITION }
private final SelectionParseAction fAction; private final SelectionParseAction fAction;

View file

@ -19,6 +19,9 @@ import java.util.Comparator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.IFontProvider; import org.eclipse.jface.viewers.IFontProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredContentProvider;
@ -49,6 +52,7 @@ import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn; import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem; import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport;
import org.eclipse.cdt.core.model.ILanguageDescriptor; import org.eclipse.cdt.core.model.ILanguageDescriptor;
import org.eclipse.cdt.core.model.LanguageManager; import org.eclipse.cdt.core.model.LanguageManager;
import org.eclipse.cdt.core.model.util.CDTListComparator; import org.eclipse.cdt.core.model.util.CDTListComparator;
@ -66,7 +70,9 @@ import org.eclipse.cdt.core.settings.model.ICSettingBase;
import org.eclipse.cdt.core.settings.model.ICSettingEntry; import org.eclipse.cdt.core.settings.model.ICSettingEntry;
import org.eclipse.cdt.core.settings.model.MultiLanguageSetting; import org.eclipse.cdt.core.settings.model.MultiLanguageSetting;
import org.eclipse.cdt.core.settings.model.util.CDataUtil; import org.eclipse.cdt.core.settings.model.util.CDataUtil;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.ui.language.settings.providers.LanguageSettingsProvidersPage;
import org.eclipse.cdt.internal.ui.newui.LanguageSettingsImages; import org.eclipse.cdt.internal.ui.newui.LanguageSettingsImages;
import org.eclipse.cdt.internal.ui.newui.Messages; import org.eclipse.cdt.internal.ui.newui.Messages;
import org.eclipse.cdt.internal.ui.newui.StatusMessageLine; import org.eclipse.cdt.internal.ui.newui.StatusMessageLine;
@ -259,8 +265,18 @@ public abstract class AbstractLangsListTab extends AbstractCPropertyTab {
* Displays warning message - if any - for selected language settings entry. * Displays warning message - if any - for selected language settings entry.
* Multiline selection is not supported. * Multiline selection is not supported.
*/ */
private void updateStatusLine() { protected void updateStatusLine() {
fStatusLine.setErrorStatus(LanguageSettingsImages.getStatus(getSelectedEntry(), getResDesc().getConfiguration())); ICConfigurationDescription cfgDescription = page.getResDesc().getConfiguration();
IStatus status = LanguageSettingsImages.getStatus(getSelectedEntry(), cfgDescription);
if (cfgDescription != null && (status == null || status.isOK())) {
IProject project = cfgDescription.getProjectDescription().getProject();
boolean isEnabled = !LanguageSettingsProvidersPage.isLanguageSettingsProvidersEnabled(project) || ScannerDiscoveryLegacySupport.isMbsLanguageSettingsProviderOn(cfgDescription);
if (!isEnabled) {
status = new Status(IStatus.INFO, CUIPlugin.PLUGIN_ID, Messages.AbstractLangsListTab_MbsProviderNotEnabled);
}
}
fStatusLine.setErrorStatus(status);
} }
/** /**

View file

@ -95,6 +95,7 @@ public class SymbolTab extends AbstractLangsListTab {
table.setSelection(0); table.setSelection(0);
} }
updateStringListModeControl(); updateStringListModeControl();
updateStatusLine();
updateButtons(); updateButtons();
} }

View file

@ -11,7 +11,6 @@
package org.eclipse.cdt.debug.mi.core; package org.eclipse.cdt.debug.mi.core;
import java.io.File; import java.io.File;
import com.ibm.icu.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -19,11 +18,13 @@ import java.util.List;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.debug.core.cdi.CDIException; import org.eclipse.cdt.debug.core.cdi.CDIException;
import org.eclipse.cdt.debug.core.cdi.model.ICDITarget; import org.eclipse.cdt.debug.core.cdi.model.ICDITarget;
import org.eclipse.cdt.debug.mi.core.cdi.CdiResources;
import org.eclipse.cdt.debug.mi.core.cdi.Session; import org.eclipse.cdt.debug.mi.core.cdi.Session;
import org.eclipse.cdt.debug.mi.core.cdi.SharedLibraryManager; import org.eclipse.cdt.debug.mi.core.cdi.SharedLibraryManager;
import org.eclipse.cdt.debug.mi.core.cdi.model.Target; import org.eclipse.cdt.debug.mi.core.cdi.model.Target;
import org.eclipse.cdt.debug.mi.core.command.CLITargetAttach; import org.eclipse.cdt.debug.mi.core.command.CLITargetAttach;
import org.eclipse.cdt.debug.mi.core.command.CommandFactory; import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
import org.eclipse.cdt.debug.mi.core.command.MIGDBSet;
import org.eclipse.cdt.debug.mi.core.command.MIGDBSetNewConsole; import org.eclipse.cdt.debug.mi.core.command.MIGDBSetNewConsole;
import org.eclipse.cdt.debug.mi.core.output.MIInfo; import org.eclipse.cdt.debug.mi.core.output.MIInfo;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
@ -37,6 +38,8 @@ import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfiguration;
import com.ibm.icu.text.MessageFormat;
/** /**
* Implementing the cdebugger extension point for basic launch configurations. * Implementing the cdebugger extension point for basic launch configurations.
*/ */
@ -107,6 +110,7 @@ public class GDBCDIDebugger2 extends AbstractGDBCDIDebugger {
@Override @Override
protected void doStartSession( ILaunch launch, Session session, IProgressMonitor monitor ) throws CoreException { protected void doStartSession( ILaunch launch, Session session, IProgressMonitor monitor ) throws CoreException {
ILaunchConfiguration config = launch.getLaunchConfiguration(); ILaunchConfiguration config = launch.getLaunchConfiguration();
setAsyncMode( config, session );
initializeLibraries( config, session ); initializeLibraries( config, session );
if ( monitor.isCanceled() ) { if ( monitor.isCanceled() ) {
throw new OperationCanceledException(); throw new OperationCanceledException();
@ -261,4 +265,25 @@ public class GDBCDIDebugger2 extends AbstractGDBCDIDebugger {
String gdbinit = config.getAttribute( IMILaunchConfigurationConstants.ATTR_GDB_INIT, IMILaunchConfigurationConstants.DEBUGGER_GDB_INIT_DEFAULT ); String gdbinit = config.getAttribute( IMILaunchConfigurationConstants.ATTR_GDB_INIT, IMILaunchConfigurationConstants.DEBUGGER_GDB_INIT_DEFAULT );
return (gdbinit != null && gdbinit.length() > 0) ? "--command=" + gdbinit : "--nx"; //$NON-NLS-1$ //$NON-NLS-2$ return (gdbinit != null && gdbinit.length() > 0) ? "--command=" + gdbinit : "--nx"; //$NON-NLS-1$ //$NON-NLS-2$
} }
private void setAsyncMode( ILaunchConfiguration config, Session session ) throws CoreException {
ICDITarget[] dtargets = session.getTargets();
for( int i = 0; i < dtargets.length; ++i ) {
MISession miSession = ((Target)dtargets[i]).getMISession();
try {
MIGDBSet setAsyncMode = miSession.getCommandFactory().createMIGDBSet(
new String[] {
"target-async", //$NON-NLS-1$
"0" //$NON-NLS-1$
} );
miSession.postCommand( setAsyncMode );
MIInfo info = setAsyncMode.getMIInfo();
if (info == null) {
throw newCoreException(new CDIException(CdiResources.getString( "cdi.Common.No_answer"))); //$NON-NLS-1$
}
} catch (MIException e) {
// Earlier versions of GDB don't support "target-async".
}
}
}
} }

View file

@ -11,7 +11,9 @@
package org.eclipse.cdt.debug.mi.core; package org.eclipse.cdt.debug.mi.core;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.debug.core.cdi.CDIException;
import org.eclipse.cdt.debug.core.cdi.model.ICDITarget; import org.eclipse.cdt.debug.core.cdi.model.ICDITarget;
import org.eclipse.cdt.debug.mi.core.cdi.CdiResources;
import org.eclipse.cdt.debug.mi.core.cdi.Session; import org.eclipse.cdt.debug.mi.core.cdi.Session;
import org.eclipse.cdt.debug.mi.core.cdi.model.Target; import org.eclipse.cdt.debug.mi.core.cdi.model.Target;
import org.eclipse.cdt.debug.mi.core.command.CommandFactory; import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
@ -35,6 +37,7 @@ public class GDBServerCDIDebugger2 extends GDBCDIDebugger2 {
@Override @Override
protected void doStartSession( ILaunch launch, Session session, IProgressMonitor monitor ) throws CoreException { protected void doStartSession( ILaunch launch, Session session, IProgressMonitor monitor ) throws CoreException {
ILaunchConfiguration config = launch.getLaunchConfiguration(); ILaunchConfiguration config = launch.getLaunchConfiguration();
setAsyncMode( config, session );
initializeLibraries( config, session ); initializeLibraries( config, session );
if ( monitor.isCanceled() ) { if ( monitor.isCanceled() ) {
throw new OperationCanceledException(); throw new OperationCanceledException();
@ -134,4 +137,25 @@ public class GDBServerCDIDebugger2 extends GDBCDIDebugger2 {
protected boolean usePty( ILaunchConfiguration config ) throws CoreException { protected boolean usePty( ILaunchConfiguration config ) throws CoreException {
return false; return false;
} }
private void setAsyncMode( ILaunchConfiguration config, Session session ) throws CoreException {
ICDITarget[] dtargets = session.getTargets();
for( int i = 0; i < dtargets.length; ++i ) {
MISession miSession = ((Target)dtargets[i]).getMISession();
try {
MIGDBSet setAsyncMode = miSession.getCommandFactory().createMIGDBSet(
new String[] {
"target-async", //$NON-NLS-1$
"0" //$NON-NLS-1$
} );
miSession.postCommand( setAsyncMode );
MIInfo info = setAsyncMode.getMIInfo();
if (info == null) {
throw newCoreException(new CDIException(CdiResources.getString( "cdi.Common.No_answer"))); //$NON-NLS-1$
}
} catch (MIException e) {
// Earlier versions of GDB don't support "target-async".
}
}
}
} }

View file

@ -2250,7 +2250,7 @@
</command> </command>
</menuContribution> </menuContribution>
<menuContribution <menuContribution
locationURI="menu:org.eclipse.ui.run?before=threadGroup"> locationURI="menu:org.eclipse.ui.run?after=stepGroup">
<command <command
commandId="org.eclipse.cdt.debug.ui.command.reverseResume" commandId="org.eclipse.cdt.debug.ui.command.reverseResume"
icon="icons/obj16/reverse_resume.gif" icon="icons/obj16/reverse_resume.gif"
@ -2359,6 +2359,8 @@
</visibleWhen> </visibleWhen>
</command> </command>
</menuContribution> </menuContribution>
<!-- Tracepoint contributions to Debug view popup -->
<menuContribution <menuContribution
locationURI="popup:org.eclipse.debug.ui.DebugView?before=renderGroup"> locationURI="popup:org.eclipse.debug.ui.DebugView?before=renderGroup">
<command <command

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2006, 2010 Wind River Systems and others. * Copyright (c) 2006, 2012 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -13,9 +13,6 @@ package org.eclipse.cdt.dsf.gdb.internal.ui.actions;
import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.eclipse.cdt.dsf.concurrent.DsfExecutor; import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable; import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
@ -31,76 +28,12 @@ import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession; import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.service.DsfSession.SessionEndedListener; import org.eclipse.cdt.dsf.service.DsfSession.SessionEndedListener;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.commands.IDebugCommandRequest; import org.eclipse.debug.core.commands.IDebugCommandRequest;
import org.eclipse.debug.core.commands.IEnabledStateRequest; import org.eclipse.debug.core.commands.IEnabledStateRequest;
import org.eclipse.debug.core.commands.ITerminateHandler; import org.eclipse.debug.core.commands.ITerminateHandler;
public class DsfTerminateCommand implements ITerminateHandler { public class DsfTerminateCommand implements ITerminateHandler {
private class WaitForTerminationJob extends Job implements SessionEndedListener {
final private IDebugCommandRequest fRequest;
final private String fSessionId;
final private Lock fLock = new ReentrantLock();
final private Condition fTerminated = fLock.newCondition();
public WaitForTerminationJob(String sessionId, IDebugCommandRequest request) {
super("Wait for termination job"); //$NON-NLS-1$
setUser(false);
setSystem(true);
fSessionId = sessionId;
fRequest = request;
DsfSession.addSessionEndedListener(WaitForTerminationJob.this);
}
@Override
protected IStatus run(IProgressMonitor monitor) {
// Wait for all processes associated with the launch
// and the shutdown sequence to be completed.
// The wait time is restricted to stop the job in case
// of termination error.
boolean result = !DsfSession.isSessionActive(fSessionId);
if (!result) {
fLock.lock();
try {
result = fTerminated.await(1, TimeUnit.MINUTES);
}
catch(InterruptedException e) {
}
finally {
fLock.unlock();
}
}
// Marking the request as cancelled will prevent the removal of
// the launch from the Debug view in case of "Terminate and Remove".
// This is important for multi-process sessions when "Terminate and Remove"
// is applied to one of the running processes. In this case the selected
// process will be terminated but the associated launch will not be removed
// from the Debug view.
fRequest.setStatus(result ? Status.OK_STATUS : Status.CANCEL_STATUS);
fRequest.done();
DsfSession.removeSessionEndedListener(WaitForTerminationJob.this);
return Status.OK_STATUS;
}
@Override
public void sessionEnded(DsfSession session) {
if (fSessionId.equals(session.getId())) {
fLock.lock();
try {
fTerminated.signal();
}
finally {
fLock.unlock();
}
}
}
}
private final DsfSession fSession; private final DsfSession fSession;
private final DsfExecutor fExecutor; private final DsfExecutor fExecutor;
private final DsfServicesTracker fTracker; private final DsfServicesTracker fTracker;
@ -115,7 +48,6 @@ public class DsfTerminateCommand implements ITerminateHandler {
fTracker.dispose(); fTracker.dispose();
} }
// Run control may not be available after a connection is terminated and shut down.
@Override @Override
public void canExecute(final IEnabledStateRequest request) { public void canExecute(final IEnabledStateRequest request) {
if (request.getElements().length != 1 || if (request.getElements().length != 1 ||
@ -189,8 +121,7 @@ public class DsfTerminateCommand implements ITerminateHandler {
request.done(); request.done();
} }
else { else {
WaitForTerminationJob job = new WaitForTerminationJob(fSession.getId(), request); waitForTermination(request);
job.schedule();
} }
}; };
}); });
@ -249,8 +180,7 @@ public class DsfTerminateCommand implements ITerminateHandler {
request.done(); request.done();
} }
else { else {
WaitForTerminationJob job = new WaitForTerminationJob(fSession.getId(), request); waitForTermination(request);
job.schedule();
} }
}; };
}); });
@ -264,4 +194,64 @@ public class DsfTerminateCommand implements ITerminateHandler {
} }
return false; return false;
} }
/**
* Wait for the debug session to be fully shutdown before reporting
* that the terminate was completed. This is important for the
* 'Terminate and remove' operation.
* The wait time is limited with a timeout so as to eventually complete the
* request in the case of termination error, or when terminating
* a single process in a multi-process session.
* See bug 377447
*/
private void waitForTermination(final IDebugCommandRequest request) {
// It is possible that the session already had time to terminate
if (!DsfSession.isSessionActive(fSession.getId())) {
request.done();
return;
}
// Listener that will indicate when the shutdown is complete
final SessionEndedListener endedListener = new SessionEndedListener () {
@Override
public void sessionEnded(DsfSession session) {
if (fSession.equals(session)) {
DsfSession.removeSessionEndedListener(this);
request.done();
}
}
};
DsfSession.addSessionEndedListener(endedListener);
// Create the timeout
// For a multi-process session, if a single process is
// terminated, this timeout will always hit (unless the
// session is also terminated before the timeout).
// We haven't found a problem with delaying the completion
// of the request that way.
// Note that this timeout is not removed even if we don't
// need it anymore, once the session has terminated;
// instead, we let it timeout and ignore it if the session
// is already terminated.
fExecutor.schedule(new Runnable() {
@Override
public void run() {
// Check that the session is still active when the timeout hits.
// If it is not, then everything has been cleaned up already.
if (DsfSession.isSessionActive(fSession.getId())) {
DsfSession.removeSessionEndedListener(endedListener);
// Marking the request as cancelled will prevent the removal of
// the launch from the Debug view in case of "Terminate and Remove".
// This is important for multi-process sessions when "Terminate and Remove"
// is applied to one of the running processes. In this case the selected
// process will be terminated but the associated launch will not be removed
// from the Debug view.
request.setStatus(Status.CANCEL_STATUS);
request.done();
}
}},
1, TimeUnit.MINUTES);
}
} }

View file

@ -128,7 +128,7 @@
id="cdt.managedbuild.tool.xlc.c.compiler.abstract" id="cdt.managedbuild.tool.xlc.c.compiler.abstract"
isAbstract="true" isAbstract="true"
name="%tool.compiler.c.abstract" name="%tool.compiler.c.abstract"
natureFilter="cnature" natureFilter="both"
outputFlag="-o" outputFlag="-o"
superClass="org.eclipse.cdt.managedbuilder.xlc.ui.tool.abstractCompiler"> superClass="org.eclipse.cdt.managedbuilder.xlc.ui.tool.abstractCompiler">
<option <option