diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuildCommandParserTest.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuildCommandParserTest.java index 022f671cd5c..b719fbf4312 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuildCommandParserTest.java +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuildCommandParserTest.java @@ -446,6 +446,8 @@ public class GCCBuildCommandParserTest extends BaseTestCase { IFile file6=ResourceHelper.createFile(project, "file6.cpp"); IFile file7=ResourceHelper.createFile(project, "file7.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); 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 file7.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(); // check populated entries @@ -498,6 +502,14 @@ public class GCCBuildCommandParserTest extends BaseTestCase { List entries = parser.getSettingEntries(cfgDescription, file8, languageId); assertEquals(new CIncludePathEntry(path0, 0), entries.get(0)); } + { + List entries = parser.getSettingEntries(cfgDescription, file9, languageId); + assertEquals(new CIncludePathEntry(path0, 0), entries.get(0)); + } + { + List entries = parser.getSettingEntries(cfgDescription, file10, languageId); + assertEquals(new CIncludePathEntry(path0, 0), entries.get(0)); + } } /** diff --git a/build/org.eclipse.cdt.managedbuilder.core/plugin.xml b/build/org.eclipse.cdt.managedbuilder.core/plugin.xml index 21a4cb321a2..9d615cbc091 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/plugin.xml +++ b/build/org.eclipse.cdt.managedbuilder.core/plugin.xml @@ -308,13 +308,13 @@ diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/DiscoveryTab.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/DiscoveryTab.java index 18d6660c721..4cfadb749f5 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/DiscoveryTab.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/DiscoveryTab.java @@ -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."); } } 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); } diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/RefreshPolicyTab.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/RefreshPolicyTab.java index 2bb36643def..cf8f9a0afb0 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/RefreshPolicyTab.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/RefreshPolicyTab.java @@ -66,7 +66,7 @@ import org.eclipse.ui.model.WorkbenchLabelProvider; * @since 8.0 */ @SuppressWarnings("restriction") -public class RefreshPolicyTab extends AbstractCBuildPropertyTab { +public class RefreshPolicyTab extends AbstractCBuildPropertyTab { private final Image IMG_FOLDER = CDTSharedImages.getImage(CDTSharedImages.IMG_OBJS_FOLDER); private final Image IMG_FILE = ManagedBuilderUIImages.get(ManagedBuilderUIImages.IMG_FILE_OBJ); @@ -93,6 +93,7 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab { HashMap> resourceMap = fConfigurationToResourcesToExclusionsMap.get(configName); if (resourceMap == null) { resourceMap = new HashMap>(); + resourceMap.put(fProject, new ArrayList()); fConfigurationToResourcesToExclusionsMap.put(configName, resourceMap); } @@ -107,8 +108,8 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab { HashMap>> target = new HashMap>>(); - if (source.size() == 0) - return null; + if (source.isEmpty()) + return target; Iterator config_iterator = source.keySet().iterator(); // for each Configuration ... @@ -135,13 +136,15 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab { // ADD each resource. target.put(configName, target_resourceMap); + } + return target; } private void loadInfo() { HashMap>> configMap = fManager.getConfigurationToResourcesMap(fProject); - if ( (configMap != null) && !(configMap.isEmpty())) + if (configMap != null) fConfigurationToResourcesToExclusionsMap = copyHashMap(configMap); } @@ -151,6 +154,7 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab { if(exclusions == null) { exclusions = new LinkedList(); resourceMap.put(resource, exclusions); + } return resourceMap.get(resource); } @@ -159,10 +163,10 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab { * Wrapper for IResource/RefreshExclusion */ 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; - //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; //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) { exclusions = new LinkedList(); getResourcesToExclusionsMap(getConfigName()).put(parent.resourceToRefresh, exclusions); + } exclusions.add(exclusion); } @@ -349,6 +354,8 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab { } } + + /* (non-Javadoc) * @see org.eclipse.cdt.ui.newui.AbstractCPropertyTab#createControls(org.eclipse.swt.widgets.Composite) */ @@ -370,7 +377,7 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab { Group g1 = setupGroup(usercomp, Messages.RefreshPolicyTab_resourcesGroupLabel, 2, GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL); fSrc = new ArrayList<_Entry>(); - generateTreeContent(); + generateTreeContent(); fTree = new TreeViewer(g1); fTree.getTree().setLayoutData(new GridData(GridData.FILL_BOTH)); @@ -505,6 +512,7 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab { @Override protected void performDefaults() { // TODO Auto-generated method stub + } @Override @@ -514,6 +522,7 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab { setAllVisible(false, null); return; } else { + setAllVisible(true, null); clearTreeContent(); generateTreeContent(); fTree.refresh(); @@ -521,6 +530,7 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab { } } + @Override protected void updateButtons() { TreeItem[] sel = fTree.getTree().getSelection(); @@ -538,7 +548,7 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab { @Override public Object[] getChildren(Object element) { ArrayList filteredChildren = new ArrayList(Arrays.asList(super.getChildren(element))); - Iterator iterator = getResourcesToExclusionsMap(getConfigName()).keySet().iterator(); //fResourcesToRefresh.iterator(); + Iterator iterator = getResourcesToExclusionsMap(getConfigName()).keySet().iterator(); while (iterator.hasNext()) { filteredChildren.remove(iterator.next()); @@ -676,12 +686,15 @@ public class RefreshPolicyTab extends AbstractCBuildPropertyTab { */ @Override protected void performOK() { + + Iterator config_iterator = fConfigurationToResourcesToExclusionsMap.keySet().iterator(); while (config_iterator.hasNext()) { String configName = config_iterator.next(); - fManager.setResourcesToExclusionsMap(fProject, configName, getResourcesToExclusionsMap(configName)); + fManager.setResourcesToExclusionsMap(fProject, configName, getResourcesToExclusionsMap(configName)); + } try { fManager.persistSettings(getResDesc().getConfiguration().getProjectDescription()); diff --git a/codan/org.eclipse.cdt.codan.ui.cxx/src/org/eclipse/cdt/codan/internal/ui/cxx/Messages.properties b/codan/org.eclipse.cdt.codan.ui.cxx/src/org/eclipse/cdt/codan/internal/ui/cxx/Messages.properties index bb6a767564d..5ada0924843 100644 --- a/codan/org.eclipse.cdt.codan.ui.cxx/src/org/eclipse/cdt/codan/internal/ui/cxx/Messages.properties +++ b/codan/org.eclipse.cdt.codan.ui.cxx/src/org/eclipse/cdt/codan/internal/ui/cxx/Messages.properties @@ -8,5 +8,5 @@ # Contributors: # Sergey Prigogin (Google) - initial API and implementation ############################################################################### -Activatior_InternalError=Error -Startup_AnalyzingFile=Analizing ''{0}'' +Activatior_Error=Error +Startup_AnalyzingFile=Analyzing ''{0}'' diff --git a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/resources/tests/RefreshScopeTests.java b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/resources/tests/RefreshScopeTests.java index 81c4628ec69..c6d45b6ffff 100644 --- a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/resources/tests/RefreshScopeTests.java +++ b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/resources/tests/RefreshScopeTests.java @@ -27,10 +27,12 @@ import org.eclipse.cdt.core.resources.ExclusionInstance; import org.eclipse.cdt.core.resources.ExclusionType; import org.eclipse.cdt.core.resources.RefreshExclusion; 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.testplugin.CProjectHelper; import org.eclipse.cdt.core.testplugin.CTestPlugin; 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.IProject; import org.eclipse.core.resources.IResource; @@ -406,8 +408,13 @@ public class RefreshScopeTests extends TestCase { 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 // will be included/excluded as follows /* @@ -428,7 +435,8 @@ public class RefreshScopeTests extends TestCase { ExclusionInstance instance2 = new ExclusionInstance(); instance2.setResource(fFolder2); exclusion1.addExclusionInstance(instance2); - manager.addExclusion(fProject, config1, config1_resource, exclusion1); + manager.addExclusion(fProject, conf_name, config1_resource, exclusion1); + ResourceExclusion exclusion2 = new ResourceExclusion(); ExclusionInstance instance3 = new ExclusionInstance(); @@ -444,14 +452,15 @@ public class RefreshScopeTests extends TestCase { // now check and see if the right folders are included/excluded - assertEquals(true, manager.shouldResourceBeRefreshed(config1, config1_resource)); - assertEquals(false, manager.shouldResourceBeRefreshed(config1, fFolder1)); - assertEquals(false, manager.shouldResourceBeRefreshed(config1, fFolder2)); - assertEquals(true, manager.shouldResourceBeRefreshed(config1, fFolder3)); - assertEquals(false, manager.shouldResourceBeRefreshed(config1, fFolder4)); - assertEquals(true, manager.shouldResourceBeRefreshed(config1, fFolder5)); - assertEquals(false, manager.shouldResourceBeRefreshed(config1, fFolder6)); - + assertEquals(true, manager.shouldResourceBeRefreshed(conf_name, config1_resource)); + assertEquals(false, manager.shouldResourceBeRefreshed(conf_name, fFolder1)); + assertEquals(false, manager.shouldResourceBeRefreshed(conf_name, fFolder2)); + assertEquals(true, manager.shouldResourceBeRefreshed(conf_name, fFolder3)); + assertEquals(false, manager.shouldResourceBeRefreshed(conf_name, fFolder4)); + assertEquals(true, manager.shouldResourceBeRefreshed(conf_name, fFolder5)); + 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 // resource deltas happening), and refresh the project according to the policy. We should only see the files // in the same folders above when consulting the resource system diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java index 0c638a1740a..d9809920daa 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java @@ -178,11 +178,22 @@ public class EmptyIndexFragment implements IIndexFragment { public IIndexFragmentFileSet createFileSet() { return null; } + @Override public IIndexFragmentFile[] getAllFiles() { return IIndexFragmentFile.EMPTY_ARRAY; } + @Override + public IIndexFragmentFile[] getDefectiveFiles() { + return IIndexFragmentFile.EMPTY_ARRAY; + } + + @Override + public IIndexFragmentFile[] getFilesWithUnresolvedIncludes() { + return IIndexFragmentFile.EMPTY_ARRAY; + } + @Override public Object getCachedResult(Object key) { return null; diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java index 86963579eaf..a0f00014261 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java @@ -18,6 +18,7 @@ import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.util.HashSet; +import java.util.Properties; import java.util.Set; 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.IIndexBinding; 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.IIndexInclude; 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.internal.core.dom.parser.ASTNode; 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.IFile; import org.eclipse.core.resources.IFolder; @@ -105,7 +108,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; 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; protected IIndex fIndex; @@ -2470,4 +2473,58 @@ public class IndexBugsTests extends BaseTestCase { 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()); + } + } } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java index 60809769641..278a16667f1 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java @@ -133,7 +133,7 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang /** * Set of elements which are out of sync with their buffers. */ - protected Map elementsOutOfSynchWithBuffers = new HashMap(11); + protected Map elementsOutOfSynchWithBuffers = new HashMap(11); /* * Temporary cache of newly opened elements @@ -378,11 +378,11 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang if (bin.getType() == IBinaryFile.ARCHIVE) { ArchiveContainer vlib = (ArchiveContainer)cproject.getArchiveContainer(); - celement = new Archive(cfolder, file, (IBinaryArchive)bin); + celement = new Archive(cfolder, file, (IBinaryArchive) bin); vlib.addChild(celement); } else { BinaryContainer vbin = (BinaryContainer)cproject.getBinaryContainer(); - celement = new Binary(cfolder, file, (IBinaryObject)bin); + celement = new Binary(cfolder, file, (IBinaryObject) bin); vbin.addChild(celement); } } @@ -421,7 +421,7 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang } 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. if (contentTypeId != null && path.toFile().exists()) { // TODO: use URI @@ -470,41 +470,42 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang IFileStore fileStore = null; try { fileStore = EFS.getStore(locationURI); - } catch (CoreException e1) { - CCorePlugin.log(e1); + } catch (CoreException e) { + CCorePlugin.log(e); return null; } final String contentTypeId = CoreModel.getRegistedContentTypeId(project, fileStore.getName()); - if (!Util.isNonZeroLengthFile(locationURI)) { - return null; - } + if (!Util.isNonZeroLengthFile(locationURI)) { + return null; + } - try { - IIncludeReference[] includeReferences = cproject.getIncludeReferences(); - for (IIncludeReference includeReference : includeReferences) { - // crecoskie - // TODO FIXME: include entries don't handle URIs yet - IPath path = URIUtil.toPath(locationURI); - if (path != null && includeReference.isOnIncludeEntry(path)) { - String headerContentTypeId= contentTypeId; - if (headerContentTypeId == null) { - headerContentTypeId= CoreModel.hasCCNature(project) ? CCorePlugin.CONTENT_TYPE_CXXHEADER : CCorePlugin.CONTENT_TYPE_CHEADER; - } - - return new ExternalTranslationUnit(includeReference, locationURI, headerContentTypeId); + try { + IIncludeReference[] includeReferences = cproject.getIncludeReferences(); + for (IIncludeReference includeReference : includeReferences) { + // crecoskie + // TODO FIXME: include entries don't handle URIs yet + IPath path = URIUtil.toPath(locationURI); + if (path != null && includeReference.isOnIncludeEntry(path)) { + String headerContentTypeId= contentTypeId; + if (headerContentTypeId == null) { + headerContentTypeId= CoreModel.hasCCNature(project) ? + CCorePlugin.CONTENT_TYPE_CXXHEADER : CCorePlugin.CONTENT_TYPE_CHEADER; } + + return new ExternalTranslationUnit(includeReference, locationURI, headerContentTypeId); } - } catch (CModelException e) { } + } catch (CModelException e) { + } - // if the file exists and it has a known C/C++ file extension then just create - // an external translation unit for it. - IFileInfo info = fileStore.fetchInfo(); + // if the file exists and it has a known C/C++ file extension then just create + // an external translation unit for it. + IFileInfo info = fileStore.fetchInfo(); - if (contentTypeId != null && info != null && info.exists()) { - return new ExternalTranslationUnit(cproject, locationURI, contentTypeId); - } + if (contentTypeId != null && info != null && info.exists()) { + return new ExternalTranslationUnit(cproject, locationURI, contentTypeId); + } return null; } @@ -663,11 +664,11 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang } 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)) { // PR:xxx the EFS does not seem to work for newly created file // 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$ File f = new File(fileUri); if (f.length() == 0) { @@ -770,14 +771,14 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang runner = binaryRunners.get(project); } 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); synchronized (binaryRunners) { if (binaryRunners.get(project) == null) { binaryRunners.put(project, runner); runner.start(); } else { - // another thread was faster + // Another thread was faster runner = binaryRunners.get(project); } } @@ -920,12 +921,12 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang } } if ((flags & ICDescriptionDelta.EXT_REF) != 0) { - // update binary parsers + // Update binary parsers IProject project = newDes.getProject(); try { ICConfigExtensionReference[] newExts = CCorePlugin.getDefault().getDefaultBinaryParserExtensions(project); BinaryParserConfig[] currentConfigs = binaryParsersMap.get(project); - // anything added/removed + // Anything added/removed if (currentConfigs != null) { if (newExts.length != currentConfigs.length) { resetBinaryParser(project); @@ -959,9 +960,6 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang return null; } - /* (non-Javadoc) - * @see org.eclipse.core.runtime.content.IContentTypeManager.IContentTypeListener#contentTypeChanged() - */ @Override public void contentTypeChanged(ContentTypeChangeEvent event) { ContentTypeProcessor.processContentTypeChanges(new ContentTypeChangeEvent[]{ event }); @@ -1048,7 +1046,7 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang System.out.println(deltaToNotify == null ? "" : deltaToNotify.toString()); //$NON-NLS-1$ } 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.flush(); notifyListeners(deltaToNotify, ElementChangedEvent.POST_CHANGE, listeners, listenerMask, listenerCount); } @@ -1061,7 +1059,7 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang System.out.println(deltaToNotify == null ? "" : deltaToNotify.toString()); //$NON-NLS-1$ } 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(); 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, int[] listenerMask, int listenerCount) { - // post change deltas + // Post change deltas if (Util.VERBOSE_DELTA) { System.out.println("FIRING POST_SHIFT event [" + Thread.currentThread() + "]:"); //$NON-NLS-1$//$NON-NLS-2$ System.out.println(deltaToNotify == null ? "" : 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$ 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() { @Override public void handleException(Throwable exception) { diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ExternalTranslationUnit.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ExternalTranslationUnit.java index 60cad88f9f6..30cd5dc8129 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ExternalTranslationUnit.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ExternalTranslationUnit.java @@ -10,7 +10,6 @@ * Anton Leherbauer (Wind River Systems) * Warren Paul (Nokia) - Bug 218266 *******************************************************************************/ - package org.eclipse.cdt.internal.core.model; import java.net.URI; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPreprocessorIncludeStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPreprocessorIncludeStatement.java index 01c773d3041..0f7ce9af3f1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPreprocessorIncludeStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPreprocessorIncludeStatement.java @@ -95,6 +95,13 @@ public interface IASTPreprocessorIncludeStatement extends IASTPreprocessorStatem */ 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 true if I/O errors were encountered while reading the included file. * @since 5.4 @@ -113,5 +120,5 @@ public interface IASTPreprocessorIncludeStatement extends IASTPreprocessorStatem * if the include creates AST or is unresolved or skipped. * @since 5.4 */ - public IIndexFile getImportedIndexFile(); + public IIndexFile getImportedIndexFile(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java index 87a8b947dd6..173f410687b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java @@ -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 * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -436,6 +436,20 @@ public interface IIndex { */ 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. * @throws CoreException diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexFile.java index 257e1647451..eb63038b785 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexFile.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexFile.java @@ -62,6 +62,14 @@ public interface IIndexFile extends IFileNomination { */ 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. * @return 64-bit hash of the file content. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexManager.java index 34b00db01de..20b8fc3536b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexManager.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexManager.java @@ -113,32 +113,31 @@ public interface IIndexManager extends IPDOMManager { 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) */ 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; /** - * Constant for indicating to update translation units if their timestamp - * has changed. + * Constant for requesting an update of translation units if theit timestamps have changed. */ public final static int UPDATE_CHECK_TIMESTAMPS= 0x2; /** - * Constant for indicating to update translation units if their configuration - * has changed. The flag currently has no effect. + * Constant for requesting an update of translation units if their configurations + * have changed. The flag currently has no effect. */ public final static int UPDATE_CHECK_CONFIGURATION= 0x4; /** - * Constant for requesting to update the external files for a project, also. This flag works only - * if it is used to update one or more projects. It shall be used together with {@link #UPDATE_ALL} - * or {@link #UPDATE_CHECK_TIMESTAMPS}. + * Constant for requesting to update the external files for a project, also. This flag works + * only if it is used to update one or more projects. It shall be used together with + * {@link #UPDATE_ALL} or {@link #UPDATE_CHECK_TIMESTAMPS}. * @since 5.1 */ 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; + /** + * 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. * @param project the project to get the index for diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/FileContent.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/FileContent.java index f9a93b043a8..fd7085fbd78 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/FileContent.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/FileContent.java @@ -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 * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -40,13 +40,20 @@ public abstract class FileContent { 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 * an I/O error. * @since 5.4 */ 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 * a file. A zero value may be returned if there was an I/O error. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java index 1fbc93e4b55..c3dde20b6f0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java @@ -758,6 +758,32 @@ public class CIndex implements IIndex { return result.values().toArray(new IIndexFile[result.size()]); } + @Override + public IIndexFile[] getDefectiveFiles() throws CoreException { + HashMap result= new HashMap(); + 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 result= new HashMap(); + 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 public IIndexScope[] getInlineNamespaces() throws CoreException { if (SPECIALCASE_SINGLES && fFragments.length == 1) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java index 503ede13120..9168511d58d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java @@ -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 * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -189,6 +189,16 @@ final public class EmptyCIndex implements IIndex { return IIndexFile.EMPTY_FILE_ARRAY; } + @Override + public IIndexFile[] getDefectiveFiles() { + return IIndexFile.EMPTY_FILE_ARRAY; + } + + @Override + public IIndexFile[] getFilesWithUnresolvedIncludes() { + return IIndexFile.EMPTY_FILE_ARRAY; + } + @Override public IIndexBinding[] findBindings(char[] name, boolean fileScopeOnly, IndexFilter filter, IProgressMonitor monitor) { return IIndexBinding.EMPTY_INDEX_BINDING_ARRAY; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java index 2b2ac26362f..7a2bc0ccf72 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java @@ -325,6 +325,16 @@ public interface IIndexFragment { */ 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 * longer holds a locks. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java index f6ca6b05ca2..0577e408b1b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java @@ -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 * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -24,10 +24,15 @@ public interface IIndexFragmentFile extends IIndexFile { IIndexFragment getIndexFragment(); /** - * Sets the timestamp of the file + * Sets the timestamp of the file. */ void setTimestamp(long timestamp) throws CoreException; + /** + * Sets the file read time. + */ + void setSourceReadTime(long time) throws CoreException; + /** * Sets the hash of the file content. */ @@ -57,6 +62,12 @@ public interface IIndexFragmentFile extends IIndexFile { */ 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. */ @@ -74,4 +85,5 @@ public interface IIndexFragmentFile extends IIndexFile { * The file 'source' must belong to the same fragment as this file. */ void transferContext(IIndexFragmentFile source) throws CoreException; + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFileLocation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFileLocation.java index b7a2207d829..2efc770cab4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFileLocation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFileLocation.java @@ -6,7 +6,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Andrew Ferguson (Symbian) - initial API and implementation + * Andrew Ferguson (Symbian) - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.core.index; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java index 37ac0d0b27b..a9de019b08e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java @@ -155,6 +155,7 @@ public class InternalParserUtil extends ParserFactory { InputStream input; try { + long fileReadTime = System.currentTimeMillis(); IFileStore store = EFS.getStore(file.getLocationURI()); IFileInfo fileInfo = store.fetchInfo(); input= file.getContents(true); @@ -173,7 +174,7 @@ public class InternalParserUtil extends ParserFactory { } try { return createFileContent(path, file.getCharset(), input, - fileInfo.getLastModified(), fileInfo.getLength()); + fileInfo.getLastModified(), fileInfo.getLength(), fileReadTime); } finally { try { input.close(); @@ -201,6 +202,7 @@ public class InternalParserUtil extends ParserFactory { * canonical path. */ public static InternalFileContent createExternalFileContent(String externalLocation, String encoding) { + long fileReadTime = System.currentTimeMillis(); File includeFile = null; String path = null; if (!UNCPathConverter.isUNC(externalLocation)) { @@ -228,7 +230,7 @@ public class InternalParserUtil extends ParserFactory { return null; } try { - return createFileContent(path, encoding, in, timestamp, fileSize); + return createFileContent(path, encoding, in, timestamp, fileSize, fileReadTime); } finally { try { in.close(); @@ -240,13 +242,13 @@ public class InternalParserUtil extends ParserFactory { } private static InternalFileContent createFileContent(String path, String charset, InputStream in, - long fileTimestamp, long fileSize) { + long fileTimestamp, long fileSize, long fileReadTime) { try { AbstractCharArray chars= FileCharArray.create(path, charset, in); if (chars == null) return null; - return new InternalFileContent(path, chars, fileTimestamp, fileSize); + return new InternalFileContent(path, chars, fileTimestamp, fileSize, fileReadTime); } catch (IOException e) { CCorePlugin.log(e); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java index 8cf8471286d..43bc89e7012 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java @@ -298,6 +298,7 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces private long fIncludedFileContentsHash; private long fIncludedFileTimestamp = -1; private long fIncludedFileSize; + private long fIncludedFileReadTime; private boolean fErrorInIncludedFile; public ASTInclusionStatement(IASTTranslationUnit parent, @@ -404,6 +405,19 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces fIncludedFileTimestamp= timestamp; } + @Override + public long getIncludedFileReadTime() { + if (fNominationDelegate != null) { + return 0; + } + return fIncludedFileReadTime; + } + + public void setIncludedFileReadTime(long time) { + assert fNominationDelegate == null; + fIncludedFileReadTime= time; + } + @Override public long getIncludedFileSize() { if (fNominationDelegate != null) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java index 0829535d524..46da6f2a30b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java @@ -302,7 +302,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable { if (contextPath == null) { contextPath= fRootContent.getFileLocation(); } - configureIncludeSearchPath(new File(contextPath).getParentFile(), info); + fIncludeSearchPath = configureIncludeSearchPath(new File(contextPath).getParentFile(), info); setupMacroDictionary(configuration, info, language); 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; } - private void configureIncludeSearchPath(File directory, IScannerInfo info) { + public static IncludeSearchPathElement[] configureIncludeSearchPath(File directory, IScannerInfo info) { + IncludeSearchPathElement[] includeSearchPath = null; String[] searchPath= info.getIncludePaths(); int idx= 0; if (info instanceof IExtendedScannerInfo) { final IExtendedScannerInfo einfo= (IExtendedScannerInfo) info; final String[] quoteIncludeSearchPath= einfo.getLocalIncludePath(); if (quoteIncludeSearchPath != null && quoteIncludeSearchPath.length > 0) { - fIncludeSearchPath= new IncludeSearchPathElement[quoteIncludeSearchPath.length + searchPath.length]; - for (String qip : quoteIncludeSearchPath) { - fIncludeSearchPath[idx++]= new IncludeSearchPathElement(makeAbsolute(directory, qip), true); + includeSearchPath= new IncludeSearchPathElement[quoteIncludeSearchPath.length + searchPath.length]; + for (String path : quoteIncludeSearchPath) { + includeSearchPath[idx++]= new IncludeSearchPathElement(makeAbsolute(directory, path), true); } } } - if (fIncludeSearchPath == null) { - fIncludeSearchPath= new IncludeSearchPathElement[searchPath.length]; + if (includeSearchPath == null) { + includeSearchPath= new IncludeSearchPathElement[searchPath.length]; } 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) { - if (directory == null || new File(inlcudePath).isAbsolute()) { - return inlcudePath; + private static String makeAbsolute(File directory, String includePath) { + if (directory == null || new File(includePath).isAbsolute()) { + return includePath; } - return ScannerUtility.createReconciledPath(directory.getAbsolutePath(), inlcudePath); + return ScannerUtility.createReconciledPath(directory.getAbsolutePath(), includePath); } private void setupMacroDictionary(IScannerExtensionConfiguration config, IScannerInfo info, ParserLanguage lang) { - // built in macros + // Built-in macros fMacroDictionary.put(__CDT_PARSER__.getNameCharArray(), __CDT_PARSER__); fMacroDictionary.put(__STDC__.getNameCharArray(), __STDC__); fMacroDictionary.put(__FILE__.getNameCharArray(), __FILE__); @@ -1066,20 +1068,10 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable { private T findInclusion(final String includeDirective, final boolean quoteInclude, final boolean includeNext, final String currentFile, final IIncludeFileTester tester) { T reader = null; - // Filename is an absolute path - if (new File(includeDirective).isAbsolute()) { - return tester.checkFile(includeDirective, 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); - } - } + String absoluteInclusionPath = getAbsoluteInclusionPath(includeDirective, currentFile); + if (absoluteInclusionPath != null) { + return tester.checkFile(absoluteInclusionPath, false, null); + } if (currentFile != null && quoteInclude && !includeNext) { // Check to see if we find a match in the current directory @@ -1134,6 +1126,24 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable { 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) { for (IncludeSearchPathElement path : fIncludeSearchPath) { String fileLocation = path.getLocation(includeDirective); @@ -1490,6 +1500,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable { stmt.setIncludedFileTimestamp(fi.getTimestamp()); stmt.setIncludedFileSize(fi.getFileSize()); stmt.setIncludedFileContentsHash(source.getContentsHash()); + stmt.setIncludedFileReadTime(fi.getReadTime()); stmt.setErrorInIncludedFile(source.hasError()); if (!fCurrentContext.isPragmaOnce()) { // Track the loaded version count, even in a non-pragma-once context. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/FileCharArray.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/FileCharArray.java index 66708a23bb3..94c45ff9255 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/FileCharArray.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/FileCharArray.java @@ -186,6 +186,7 @@ public class FileCharArray extends LazyCharArray { decode(channel, chunk.fSourceOffset, chunk.fSourceEndOffset, CharBuffer.wrap(dest)); } catch (IOException e) { // File cannot be read + CCorePlugin.log(e); fHasError = true; } finally { try { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/IncludeSearchPathElement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/IncludeSearchPathElement.java index 7cd2ef5e4da..458dbc3f632 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/IncludeSearchPathElement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/IncludeSearchPathElement.java @@ -15,7 +15,7 @@ import java.io.File; /** * Represents an entry of the include search path */ -final class IncludeSearchPathElement { +public final class IncludeSearchPathElement { private static final boolean NON_SLASH_SEPARATOR = File.separatorChar != '/'; public static final String FRAMEWORK_VAR = "__framework__"; //$NON-NLS-1$ public static final String FILE_VAR = "__header__"; //$NON-NLS-1$ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/InternalFileContent.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/InternalFileContent.java index d8daeb12efb..5ce1b706be9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/InternalFileContent.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/InternalFileContent.java @@ -60,6 +60,7 @@ public class InternalFileContent extends FileContent { private IncludeSearchPathElement fFoundOnPath; private final long fTimestamp; private final long fFileSize; + private final long fReadTime; /** * For skipping include files. @@ -79,7 +80,8 @@ public class InternalFileContent extends FileContent { fSource= null; fNonPragmaOnceFiles= null; 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 null. */ public InternalFileContent(String filePath, AbstractCharArray content, long timestamp, - long fileSize) throws IllegalArgumentException { + long fileSize, long fileReadTime) throws IllegalArgumentException { if (content == null) { throw new IllegalArgumentException(); } @@ -101,7 +103,8 @@ public class InternalFileContent extends FileContent { throw new IllegalArgumentException(); } fTimestamp= timestamp; - fFileSize = fileSize; + fFileSize= fileSize; + fReadTime= fileReadTime; } /** @@ -123,6 +126,7 @@ public class InternalFileContent extends FileContent { } fTimestamp= NULL_TIMESTAMP; fFileSize = NULL_FILE_SIZE; + fReadTime= 0; } /** @@ -144,6 +148,7 @@ public class InternalFileContent extends FileContent { fNonPragmaOnceFiles= nonPragmaOnceVersions; fTimestamp= NULL_TIMESTAMP; fFileSize = NULL_FILE_SIZE; + fReadTime= 0; } /** @@ -166,6 +171,11 @@ public class InternalFileContent extends FileContent { return fTimestamp; } + @Override + public long getReadTime() { + return fReadTime; + } + @Override public long getFileSize() { return fFileSize; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ScannerUtility.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ScannerUtility.java index 28e6eb48ac5..6afddc421c7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ScannerUtility.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ScannerUtility.java @@ -6,7 +6,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM Rational Software - Initial API and implementation + * IBM Rational Software - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.core.parser.scanner; @@ -14,10 +14,8 @@ import java.io.File; /** * @author jcamelon - * */ public class ScannerUtility { - static final char DOT = '.'; static final char SLASH = '/'; static final char BSLASH = '\\'; @@ -68,8 +66,7 @@ public class ScannerUtility { } } - - for (int i=0; i0) + // No separator before, not a 1st string symbol. + if (noSepBefore && j > 0) { aus[j++] = c; - else { // separator before "." ! + } else { // Separator before "." if (i < len1) { - c = ein[i+1]; // check for next symbol - // check for "/./" case + c = ein[i + 1]; // Check for next symbol + // Check for "/./" case if (c == SLASH || c == BSLASH) { - // write nothing to output - // skip the next symbol + // Write nothing to output, skip the next symbol i++; noSepBefore = false; - } - // symbol other than "." - write it also - else if (c != DOT) { + } else { // Process as usual i++; noSepBefore = true; aus[j++] = DOT; aus[j++] = c; } - // Processed as usual - else { - i++; - noSepBefore = true; - aus[j++] = DOT; - aus[j++] = DOT; - } - } else - {} // do nothing when "." is last symbol + } } break; default: @@ -125,10 +111,10 @@ public class ScannerUtility { /** * @param path - include path * @param fileName - include file name - * @return - reconsiled path + * @return - reconciled path */ public static String createReconciledPath(String path, String fileName) { boolean pathEmpty = (path == null || path.length() == 0); - return (pathEmpty ? fileName : reconcilePath(path + File.separatorChar + fileName)); + return pathEmpty ? fileName : reconcilePath(path + File.separatorChar + fileName); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java index a67dc06a458..b86005f0d7a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java @@ -307,6 +307,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter { private final LinkedList fUrgentTasks; boolean fTaskCompleted; private IndexerProgress fInfo= new IndexerProgress(); + public AbstractIndexerTask(Object[] filesToUpdate, Object[] filesToRemove, IndexerInputAdapter resolver, boolean fastIndexer) { super(resolver); @@ -384,6 +385,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter { protected abstract IWritableIndex createIndex(); protected abstract IIncludeFileResolutionHeuristics createIncludeHeuristics(); protected abstract IncludeFileContentProvider createReaderFactory(); + protected ITodoTaskUpdater createTodoTaskUpdater() { return null; } @@ -582,6 +584,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter { final boolean forceAll= (fUpdateFlags & IIndexManager.UPDATE_ALL) != 0; final boolean checkTimestamps= (fUpdateFlags & IIndexManager.UPDATE_CHECK_TIMESTAMPS) != 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; int count= 0; int forceFirst= fForceNumberFiles; @@ -614,7 +617,9 @@ public abstract class AbstractIndexerTask extends PDOMWriter { if (ifile != null && ifile.getLinkageID() == linkageID && ifile.hasContent()) { foundInLinkage = true; 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)) { count++; linkages.set(linkageID); @@ -637,7 +642,9 @@ public abstract class AbstractIndexerTask extends PDOMWriter { iFilesToRemove.add(ifile); count++; } 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(); if (update && requestUpdate(linkageID, ifl, ifile, tu, UpdateKind.OTHER_HEADER)) { 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); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexUpdatePolicy.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexUpdatePolicy.java index 9e9d8b81717..e8068b75d23 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexUpdatePolicy.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexUpdatePolicy.java @@ -6,7 +6,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Markus Schorn - initial API and implementation + * Markus Schorn - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom; @@ -142,8 +142,7 @@ public class IndexUpdatePolicy { task= new PDOMUpdateTask(fIndexer, IIndexManager.UPDATE_CHECK_TIMESTAMPS | IIndexManager.UPDATE_CHECK_CONTENTS_HASH); clearTUs(); - } - else if (fKind == POST_CHANGE) { + } else if (fKind == POST_CHANGE) { task= createTask(); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index 3d027cb7c6b..b7f081a4cc9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -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.DBProperties; 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.dom.BindingCollector; import org.eclipse.cdt.internal.core.pdom.dom.FindBinding; @@ -215,10 +216,11 @@ public class PDOM extends PlatformObject implements IPDOM { * 122.0 - Compacting strings * 123.0 - Combined file size and encoding hash code. * 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 MAX_SUPPORTED_VERSION= version(124, Short.MAX_VALUE); - private static final int DEFAULT_VERSION = version(124, 0); + private static final int MIN_SUPPORTED_VERSION= version(125, 0); + private static final int MAX_SUPPORTED_VERSION= version(125, Short.MAX_VALUE); + private static final int DEFAULT_VERSION = version(125, 0); private static int version(int major, int 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 FILE_INDEX = Database.DATA_AREA + 4; - public static final int PROPERTIES = Database.DATA_AREA + 8; - public static final int END= Database.DATA_AREA + 12; + public static final int INDEX_OF_DEFECTIVE_FILES = Database.DATA_AREA + 8; + 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 { assert END <= Database.CHUNK_SIZE; } @@ -303,9 +307,19 @@ public class PDOM extends PlatformObject implements IPDOM { 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 protected Database db; private BTree fileIndex; + private BTree indexOfDefectiveFiles; + private BTree indexOfFiledWithUnresolvedIncludes; private Map fLinkageIDCache = new HashMap(); private File fPath; private IIndexLocationConverter locationConverter; @@ -432,6 +446,26 @@ public class PDOM extends PlatformObject implements IPDOM { 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 @Override public PDOMFile getFile(int linkageID, IIndexFileLocation location) throws CoreException { @@ -471,8 +505,22 @@ public class PDOM extends PlatformObject implements IPDOM { @Override public IIndexFragmentFile[] getAllFiles() throws CoreException { - final List locations = new ArrayList(); - getFileIndex().accept(new IBTreeVisitor() { + return getFiles(getFileIndex()); + } + + @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 files = new ArrayList(); + index.accept(new IBTreeVisitor() { @Override public int compare(long record) throws CoreException { return 0; @@ -481,13 +529,13 @@ public class PDOM extends PlatformObject implements IPDOM { @Override public boolean visit(long record) throws CoreException { PDOMFile file = PDOMFile.recreateFile(PDOM.this, record); - locations.add(file); + files.add(file); return true; } }); - return locations.toArray(new IIndexFragmentFile[locations.size()]); + return files.toArray(new IIndexFragmentFile[files.size()]); } - + protected IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location, ISignificantMacros sigMacros) throws CoreException { PDOMLinkage linkage= createLinkage(linkageID); @@ -1296,6 +1344,8 @@ public class PDOM extends PlatformObject implements IPDOM { private void clearCaches() { fileIndex= null; + indexOfDefectiveFiles= null; + indexOfFiledWithUnresolvedIncludes= null; fLinkageIDCache.clear(); clearResultCache(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java index 2848f3fc7c8..f4f0219f14c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java @@ -20,11 +20,11 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; import java.util.Map; 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 }; - private final LinkedList fProjectQueue= new LinkedList(); + private final ArrayDeque fProjectQueue= new ArrayDeque(); private final PDOMSetupJob fSetupJob; /** * Protects fIndexerJob, fCurrentTask and fTaskQueue. */ - private final LinkedList fTaskQueue = new LinkedList(); + private final ArrayDeque fTaskQueue = new ArrayDeque(); private final PDOMIndexerJob fIndexerJob; private IPDOMIndexerTask fCurrentTask; private int fSourceCount, fHeaderCount, fTickCount; - private final LinkedList fChangeEvents= new LinkedList(); + private final ArrayDeque fChangeEvents= new ArrayDeque(); private final Job fNotificationJob; private final AtomicMultiSet fFilesIndexedUnconditionlly= new AtomicMultiSet(); @@ -1513,10 +1513,10 @@ public class PDOMManager implements IWritableIndexManager, IListener { IIndex index= getIndex(cproject); index.acquireReadLock(); try { - for(ITranslationUnit tu : sources) { + for (ITranslationUnit tu : sources) { IResource resource= tu.getResource(); if (resource instanceof IFile && isSubjectToIndexing(tu.getLanguage())) { - IIndexFileLocation location= IndexLocationFactory.getWorkspaceIFL((IFile)resource); + IIndexFileLocation location= IndexLocationFactory.getWorkspaceIFL((IFile) resource); if (!areSynchronized(new HashSet(), index, resource, location)) { 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 // be read from the index. IIndexInclude[] includes= index.findIncludes(file[0]); - for(IIndexInclude inc : includes) { + for (IIndexInclude inc : includes) { IIndexFileLocation newLocation= inc.getIncludesLocation(); if (newLocation != null) { String path= newLocation.getFullPath(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java index 20f4d820d0a..99d43bc24d3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java @@ -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 * are made available under the terms of the Eclipse Public License v1.0 * 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 * 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 { private PDOM fDelegate; @@ -318,6 +318,20 @@ public class PDOMProxy implements IPDOM { 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 public synchronized IIndexFragmentBinding[] findMacroContainers(Pattern pattern, IndexFilter filter, IProgressMonitor monitor) throws CoreException { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java index c3b7c051b92..bcdc654fe9f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java @@ -79,6 +79,7 @@ abstract public class PDOMWriter { final long timestamp; final long fileSize; final long contentsHash; + final long sourceReadTime; final boolean hasError; public FileInAST(IASTPreprocessorIncludeStatement includeStmt, FileContentKey key) { @@ -87,6 +88,7 @@ abstract public class PDOMWriter { timestamp= includeStmt.getIncludedFileTimestamp(); fileSize = includeStmt.getIncludedFileSize(); contentsHash= includeStmt.getIncludedFileContentsHash(); + sourceReadTime= includeStmt.getIncludedFileReadTime(); hasError= includeStmt.isErrorInIncludedFile(); } @@ -96,6 +98,7 @@ abstract public class PDOMWriter { timestamp= codeReader.getTimestamp(); fileSize= codeReader.getFileSize(); contentsHash= codeReader.getContentsHash(); + sourceReadTime= codeReader.getReadTime(); hasError= codeReader.hasError(); } @@ -577,6 +580,7 @@ abstract public class PDOMWriter { index.setFileContent(file, linkageID, includeInfoArray, macros, names, fResolver, lock); } file.setTimestamp(astFile.hasError ? 0 : astFile.timestamp); + file.setSourceReadTime(astFile.sourceReadTime); file.setSizeAndEncodingHashcode(computeFileSizeAndEncodingHashcode(astFile.fileSize, location)); file.setContentsHash(astFile.contentsHash); file = index.commitUncommittedFile(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java index aaeb280dfd8..89b1b26d487 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java @@ -87,17 +87,36 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment { public IIndexFragmentFile commitUncommittedFile() throws CoreException { if (uncommittedFile == null) return null; + + int defectiveStateChange = uncommittedFile.getTimestamp() == 0 ? 1 : 0; + int unresolvedIncludeStateChange = uncommittedFile.hasUnresolvedInclude() ? 1 : 0; + PDOMFile file; if (fileBeingUpdated == null) { // New file, insert it into the index. file = uncommittedFile; - getFileIndex().insert(file.getRecord()); + getFileIndex().insert(file.getRecord()); } else { // Existing file. + if (fileBeingUpdated.getTimestamp() == 0) + defectiveStateChange -= 1; + if (fileBeingUpdated.hasUnresolvedInclude()) + unresolvedIncludeStateChange -= 1; fileBeingUpdated.replaceContentsFrom(uncommittedFile); file = fileBeingUpdated; 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()); uncommittedFile = null; uncommittedKey = null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java index 816e1dbcbb1..e44b2170e72 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java @@ -72,13 +72,14 @@ public class PDOMFile implements IIndexFragmentFile { 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 FLAGS= LINKAGE_ID + 3; // size 1 - private static final int TIME_STAMP = FLAGS + 1; // long - private static final int CONTENT_HASH= TIME_STAMP + 8; // long + private static final int TIME_STAMP= FLAGS + 1; // 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 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 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; @@ -205,6 +206,7 @@ public class PDOMFile implements IIndexFragmentFile { } setTimestamp(sourceFile.getTimestamp()); + setSourceReadTime(sourceFile.getSourceReadTime()); setSizeAndEncodingHashcode(sourceFile.getSizeAndEncodingHashcode()); setContentsHash(sourceFile.getContentsHash()); @@ -309,6 +311,18 @@ public class PDOMFile implements IIndexFragmentFile { 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 public long getContentsHash() throws CoreException { Database db = fLinkage.getDB(); @@ -571,6 +585,7 @@ public class PDOMFile implements IIndexFragmentFile { m.delete(); } setFirstMacroReference(null); + setSourceReadTime(0); setTimestamp(-1); } @@ -644,6 +659,17 @@ public class PDOMFile implements IIndexFragmentFile { 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 public IIndexMacro[] getMacros() throws CoreException { List result= new ArrayList(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerPreferences.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerPreferences.java index 7af2137518f..684d0b07696 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerPreferences.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerPreferences.java @@ -188,9 +188,7 @@ public class IndexerPreferences { } public static int getDefaultUpdatePolicy() { - Preferences[] prefs = new Preferences[] { - getDefaultPreferences() - }; + Preferences[] prefs = new Preferences[] { getDefaultPreferences() }; return getUpdatePolicy(prefs); } @@ -203,7 +201,7 @@ public class IndexerPreferences { } private static void setProperties(Preferences prefs, Properties props) { - for (Map.Entry entry : props.entrySet()) { + for (Map.Entry entry : props.entrySet()) { String key = (String) entry.getKey(); String val = (String) entry.getValue(); prefs.put(key, val); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFastIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFastIndexerTask.java index 5f7eaf90272..6058d285666 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFastIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFastIndexerTask.java @@ -6,10 +6,9 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * QNX - Initial API and implementation - * Markus Schorn (Wind River Systems) + * QNX - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ - package org.eclipse.cdt.internal.core.pdom.indexer; 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. */ class PDOMFastIndexerTask extends PDOMIndexerTask { + public PDOMFastIndexerTask(PDOMFastIndexer indexer, ITranslationUnit[] added, ITranslationUnit[] changed, ITranslationUnit[] removed) { super(added, changed, removed, indexer, true); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMUpdateTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMUpdateTask.java index 3cf21f99917..df8621199c4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMUpdateTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMUpdateTask.java @@ -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 * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -11,6 +11,7 @@ ******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.indexer; +import java.io.File; import java.util.ArrayList; import java.util.HashSet; 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.IIndexFile; 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.IndexLocationFactory; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICProject; 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.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.core.resources.IFile; 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. */ public class PDOMUpdateTask implements IPDOMIndexerTask { - protected static final String TRUE= String.valueOf(true); - protected static final ITranslationUnit[] NO_TUS = new ITranslationUnit[0]; + private static final ITranslationUnit[] NO_TUS = {}; private final IPDOMIndexer fIndexer; - private final IndexerProgress fProgress; private final int fUpdateOptions; + private final IndexerProgress fProgress; private volatile IPDOMIndexerTask fDelegate; private ArrayList fFilesAndFolders; public PDOMUpdateTask(IPDOMIndexer indexer, int updateOptions) { fIndexer= indexer; - fProgress= createProgress(); fUpdateOptions= updateOptions; + fProgress= createProgress(); } private IndexerProgress createProgress() { @@ -89,42 +94,68 @@ 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 set= new HashSet(); - TranslationUnitCollector collector= new TranslationUnitCollector(set, set, monitor); - boolean haveProject= false; - if (fFilesAndFolders == null) { - project.accept(collector); - } else { - for (ICElement elem : fFilesAndFolders) { - if (elem.getElementType() == ICElement.C_PROJECT) { - haveProject= true; + if ((fUpdateOptions & (IIndexManager.UPDATE_ALL | IIndexManager.UPDATE_CHECK_TIMESTAMPS)) != 0) { + TranslationUnitCollector collector= new TranslationUnitCollector(set, set, monitor); + boolean haveProject= false; + if (fFilesAndFolders == null) { + project.accept(collector); + } else { + for (ICElement elem : fFilesAndFolders) { + if (elem.getElementType() == ICElement.C_PROJECT) { + haveProject= true; + } + elem.accept(collector); + } + } + if (haveProject && (fUpdateOptions & IIndexManager.UPDATE_EXTERNAL_FILES_FOR_PROJECT) != 0) { + final String projectPrefix= project.getProject().getFullPath().toString() + IPath.SEPARATOR; + IIndex index= CCorePlugin.getIndexManager().getIndex(project); + index.acquireReadLock(); + try { + IIndexFile[] files= index.getAllFiles(); + for (IIndexFile indexFile : files) { + IIndexFileLocation floc= indexFile.getLocation(); + final String fullPath = floc.getFullPath(); + if (fullPath == null || !fullPath.startsWith(projectPrefix)) { + ITranslationUnit tu = getTranslationUnit(floc, project); + if (tu != null) { + set.add(tu); + } + } + } + } finally { + index.releaseReadLock(); } - elem.accept(collector); } } - if (haveProject && (fUpdateOptions & IIndexManager.UPDATE_EXTERNAL_FILES_FOR_PROJECT) != 0) { - final String projectPrefix= project.getProject().getFullPath().toString() + IPath.SEPARATOR; + + if ((fUpdateOptions & IIndexManager.UPDATE_UNRESOLVED_INCLUDES) != 0) { IIndex index= CCorePlugin.getIndexManager().getIndex(project); index.acquireReadLock(); try { - IIndexFile[] files= index.getAllFiles(); - for (IIndexFile indexFile : files) { - IIndexFileLocation floc= indexFile.getLocation(); - final String fullPath = floc.getFullPath(); - if (fullPath == null || !fullPath.startsWith(projectPrefix)) { - IPath path= IndexLocationFactory.getAbsolutePath(floc); - if (path != null) { - ITranslationUnit tu= CoreModel.getDefault().createTranslationUnitFrom(project, path); - if (tu != null) { - if (fullPath != null) { - if (tu instanceof ExternalTranslationUnit) { - IResource file= ResourcesPlugin.getWorkspace().getRoot().findMember(fullPath); - if (file instanceof IFile) { - ((ExternalTranslationUnit) tu).setResource((IFile) file); - } - } - } + // 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); } } @@ -134,15 +165,108 @@ public class PDOMUpdateTask implements IPDOMIndexerTask { index.releaseReadLock(); } } + ITranslationUnit[] tus= set.toArray(new ITranslationUnit[set.size()]); IPDOMIndexerTask delegate= fIndexer.createTask(NO_TUS, tus, NO_TUS); if (delegate instanceof PDOMIndexerTask) { final PDOMIndexerTask task = (PDOMIndexerTask) delegate; task.setUpdateFlags(fUpdateOptions); } - synchronized (this) { - fDelegate= delegate; + setDelegate(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 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerIncludeResolutionHeuristics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerIncludeResolutionHeuristics.java index a16957cfc7e..7f86c02366a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerIncludeResolutionHeuristics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerIncludeResolutionHeuristics.java @@ -6,7 +6,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Markus Schorn - initial API and implementation + * Markus Schorn - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.indexer; @@ -30,7 +30,7 @@ import org.eclipse.core.runtime.Path; * Heuristics for picking up includes from the project */ 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[] fProjects; @@ -52,8 +52,7 @@ public class ProjectIndexerIncludeResolutionHeuristics implements IIncludeFileRe if (fProject == null) return null; - - + if (fProjects == null) { if (fProject.isOpen()) { String val= IndexerPreferences.get(fProject, IndexerPreferences.KEY_INCLUDE_HEURISTICS, TRUE); @@ -77,8 +76,7 @@ public class ProjectIndexerIncludeResolutionHeuristics implements IIncludeFileRe return bestLocation.toString(); } - - + private IResource selectBest(IFile[] files, char[] currentFullPath) { IFile best= files[0]; int bestScore= computeScore(best.getFullPath().toString().toCharArray(), currentFullPath); @@ -96,14 +94,14 @@ public class ProjectIndexerIncludeResolutionHeuristics implements IIncludeFileRe private int computeScore(char[] path1, char[] path2) { final int limit= Math.min(path1.length, path2.length); - int match=0; + int match= 0; for (int i = 0; i < limit; i++) { if (path1[i] != path2[i]) break; if (path1[i] == '/') match= i; } - // prefer shortest path with longest matches with + // Prefer shortest path with longest matches with. return (match << 16) - path1.length; } @@ -115,7 +113,7 @@ public class ProjectIndexerIncludeResolutionHeuristics implements IIncludeFileRe List projectsToSearch= new ArrayList(); projectsToSearch.add(prj); - for (int i=0; i>> configMap = getConfigurationToResourcesMap(project); - - Iterator it = configMap.keySet().iterator(); - while (it.hasNext()) { - String configName = it.next(); - List resourcesToRefresh = getResourcesToRefresh(project,configName); - for (IResource resource : resourcesToRefresh) { - List exclusions = getExclusions(project,configName,resource); - refreshResources(configName, resource, exclusions, monitor); - } - } + + CProjectDescriptionManager descriptionManager = CProjectDescriptionManager + .getInstance(); + ICProjectDescription projectDescription = descriptionManager.getProjectDescription(project, false); + ICConfigurationDescription active_conf = projectDescription.getActiveConfiguration(); + String name = active_conf.getName(); + List resourcesToRefresh = getResourcesToRefresh(project,name); + for (IResource resource : resourcesToRefresh) { + List exclusions = getExclusions(project,name,resource); + refreshResources(name, resource, exclusions, monitor); + } } }; @@ -723,8 +725,7 @@ public class RefreshScopeManager { /** * @since 5.4 */ - public synchronized void setResourcesToExclusionsMap(IProject project, String configName, HashMap> source_resourceMap) { // List resources) { - + public synchronized void setResourcesToExclusionsMap(IProject project, String configName, HashMap> source_resourceMap) { HashMap> target_resourceMap = getResourcesToExclusionsMap(project,configName); target_resourceMap.clear(); diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CCorePreferenceInitializer.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CCorePreferenceInitializer.java index b9c3c2b1cd9..3eb7839aa2d 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CCorePreferenceInitializer.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CCorePreferenceInitializer.java @@ -14,6 +14,9 @@ *******************************************************************************/ 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.CCorePreferenceConstants; 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.IEclipsePreferences; -import java.util.HashSet; -import java.util.Map; - public class CCorePreferenceInitializer extends AbstractPreferenceInitializer { /* (non-Javadoc) @@ -51,7 +51,7 @@ public class CCorePreferenceInitializer extends AbstractPreferenceInitializer { // Store default values to default preferences IEclipsePreferences defaultPreferences = DefaultScope.INSTANCE.getNode(CCorePlugin.PLUGIN_ID); - for (Map.Entry entry : defaultOptionsMap.entrySet()) { + for (Map.Entry entry : defaultOptionsMap.entrySet()) { String optionName = entry.getKey(); defaultPreferences.put(optionName, entry.getValue()); optionNames.add(optionName); diff --git a/core/org.eclipse.cdt.ui/plugin.properties b/core/org.eclipse.cdt.ui/plugin.properties index 8551271a582..5de290067a3 100644 --- a/core/org.eclipse.cdt.ui/plugin.properties +++ b/core/org.eclipse.cdt.ui/plugin.properties @@ -460,8 +460,9 @@ CDTIndexer.fastindexer=C/C++ Indexer IndexView.name=C/C++ Index RebuildIndex.name=&Rebuild -SyncIndex.name=&Update with Modified 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 CreateParserLog.name=Create Parser &Log File diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index 19de4efb06d..ec3347b3891 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -28,7 +28,7 @@ - + @@ -1372,15 +1372,20 @@ + class="org.eclipse.cdt.internal.ui.actions.UpdateUnresolvedIncludesAction" + id="org.eclipse.cdt.ui.updateUnresolvedIncludesAction" + label="%UpdateUnresolvedIncludes.name" + menubarPath="org.eclipse.cdt.ui.indexmenu/update"/> + class="org.eclipse.cdt.internal.ui.actions.UpdateIndexWithModifiedFilesAction" + id="org.eclipse.cdt.ui.syncIndexWithDiskAction" + label="%SyncIndex.name" + menubarPath="org.eclipse.cdt.ui.indexmenu/update"/> + + i= cElements.iterator(); ArrayList tuSelection= new ArrayList(); - while (i.hasNext()) { + for (Iterator i= cElements.iterator(); i.hasNext();) { Object o= i.next(); if (o instanceof ICProject || o instanceof ICContainer || o instanceof ITranslationUnit) { tuSelection.add((ICElement) o); @@ -57,8 +54,7 @@ public abstract class AbstractUpdateIndexAction implements IObjectActionDelegate try { CCorePlugin.getIndexManager().update(tuArray, getUpdateOptions()); - } - catch (CoreException e) { + } catch (CoreException e) { CUIPlugin.log(e); } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/RebuildIndexAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/RebuildIndexAction.java index 232c32e1ecc..07814660f0d 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/RebuildIndexAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/RebuildIndexAction.java @@ -6,9 +6,8 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Markus Schorn - initial API and implementation + * Markus Schorn - initial API and implementation *******************************************************************************/ - package org.eclipse.cdt.internal.ui.actions; import java.util.Iterator; @@ -24,7 +23,6 @@ import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.model.ICProject; public class RebuildIndexAction implements IObjectActionDelegate { - private ISelection fSelection; @Override diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/UpdateIndexWithModifiedFilesAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/UpdateIndexWithModifiedFilesAction.java index 569f0717606..cfc4b915aae 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/UpdateIndexWithModifiedFilesAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/UpdateIndexWithModifiedFilesAction.java @@ -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 * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * Markus Schorn - initial API and implementation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.ui.actions; @@ -18,6 +19,7 @@ public class UpdateIndexWithModifiedFilesAction extends AbstractUpdateIndexActio return IIndexManager.UPDATE_CHECK_TIMESTAMPS | IIndexManager.UPDATE_CHECK_CONFIGURATION | IIndexManager.UPDATE_EXTERNAL_FILES_FOR_PROJECT | - IIndexManager.UPDATE_CHECK_CONTENTS_HASH; + IIndexManager.UPDATE_CHECK_CONTENTS_HASH | + IIndexManager.UPDATE_UNRESOLVED_INCLUDES; } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/UpdateUnresolvedIncludesAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/UpdateUnresolvedIncludesAction.java new file mode 100644 index 00000000000..94b1982453e --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/UpdateUnresolvedIncludesAction.java @@ -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; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsEntriesTab.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsEntriesTab.java index dff8d314d3f..9a0e10b9276 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsEntriesTab.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsEntriesTab.java @@ -112,6 +112,9 @@ public class LanguageSettingsEntriesTab extends AbstractCPropertyTab { @Override protected String[] getOverlayKeys(ILanguageSettingsProvider provider) { String[] overlayKeys = super.getOverlayKeys(provider); + if (provider.getName() == null) { + return overlayKeys; + } if (currentLanguageId != null) { IResource rc = getResource(); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProviderTab.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProviderTab.java index 6ec74419583..1e235892470 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProviderTab.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProviderTab.java @@ -115,14 +115,11 @@ public class LanguageSettingsProviderTab extends AbstractCPropertyTab { private class ProvidersTableLabelProvider extends LanguageSettingsProvidersLabelProvider { @Override protected String[] getOverlayKeys(ILanguageSettingsProvider provider) { + String[] overlayKeys = super.getOverlayKeys(provider); if (provider.getName() == null) { - String[] overlayKeys = new String[5]; - overlayKeys[IDecoration.TOP_RIGHT] = CDTSharedImages.IMG_OVR_ERROR; return overlayKeys; } - String[] overlayKeys = super.getOverlayKeys(provider); - if (page.isForProject()) { if (isEditedForProject(provider)) { overlayKeys[IDecoration.TOP_RIGHT] = CDTSharedImages.IMG_OVR_EDITED; @@ -1095,9 +1092,11 @@ public class LanguageSettingsProviderTab extends AbstractCPropertyTab { } else if (page.isForPrefs()) { presentedProviders = new ArrayList(); - for (ILanguageSettingsProvider provider : LanguageSettingsManager.getWorkspaceProviders()) { - if (!LanguageSettingsManager.isEqualExtensionProvider(provider, true)) { - ILanguageSettingsProvider extProvider = LanguageSettingsManager.getExtensionProviderCopy(provider.getId(), true); + for (String id : LanguageSettingsManager.getExtensionProviderIds()) { + ILanguageSettingsProvider provider = LanguageSettingsManager.getWorkspaceProvider(id); + ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(provider); + if (!LanguageSettingsManager.isEqualExtensionProvider(rawProvider, true)) { + ILanguageSettingsProvider extProvider = LanguageSettingsManager.getExtensionProviderCopy(id, true); if (extProvider != null) { provider = extProvider; } @@ -1112,7 +1111,9 @@ public class LanguageSettingsProviderTab extends AbstractCPropertyTab { updateData(rcDescription); // update other tabs - masterPropertyPage.informAll(UPDATE, rcDescription); + if (masterPropertyPage != null) { + masterPropertyPage.informAll(UPDATE, rcDescription); + } } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProvidersLabelProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProvidersLabelProvider.java index e93bae0f8d3..b7c8598a6b8 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProvidersLabelProvider.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProvidersLabelProvider.java @@ -12,6 +12,7 @@ package org.eclipse.cdt.internal.ui.language.settings.providers; import java.net.URL; +import org.eclipse.jface.viewers.IDecoration; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.osgi.util.NLS; 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. */ 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 diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.java index d0ad9a79ce5..f250ed7ce84 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.java @@ -28,6 +28,7 @@ public class Messages extends NLS { public static String AbstractLangsListTab_Unexport; public static String AbstractLangsListTab_Conjunction; public static String AbstractLangsListTab_Disjunction; + public static String AbstractLangsListTab_MbsProviderNotEnabled; public static String AbstractLangsListTab_Modify; public static String AbstractLangsListTab_MultiConfigStringListModeLinkHint; public static String AbstractLangsListTab_Replace; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.properties index 06cc6138bdb..ad4c41fa34c 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.properties @@ -107,6 +107,7 @@ AbstractLangsListTab_ExportIndicator=\ [exp] AbstractLangsListTab_Unexport=Unexport AbstractLangsListTab_Conjunction=Conjunction 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_MultiConfigStringListModeLinkHint=Multiple configurations string list mode. Click on link to change or for more info. AbstractLangsListTab_Replace=Replace diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/CSearchUnresolvedIncludesQuery.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/CSearchUnresolvedIncludesQuery.java index 09a73b401b3..f44bd9954a5 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/CSearchUnresolvedIncludesQuery.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/CSearchUnresolvedIncludesQuery.java @@ -7,6 +7,7 @@ * * Contributors: * Markus Schorn - initial API and implementation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.ui.search; @@ -37,7 +38,7 @@ public class CSearchUnresolvedIncludesQuery extends CSearchQuery { @Override protected IStatus runWithIndex(final IIndex index, IProgressMonitor monitor) { try { - for (IIndexFile file : index.getAllFiles()) { + for (IIndexFile file : index.getFilesWithUnresolvedIncludes()) { for (IIndexInclude include : file.getIncludes()) { if (include.isActive() && !include.isResolved()) { result.addMatch(new CSearchMatch(new ProblemSearchElement( diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java index c3e8ccc8064..4980170cc42 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java @@ -6,8 +6,8 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Markus Schorn - initial API and implementation - * Sergey Prigogin (Google) + * Markus Schorn - initial API and implementation + * Sergey Prigogin (Google) ******************************************************************************/ package org.eclipse.cdt.internal.ui.search.actions; @@ -98,7 +98,6 @@ import org.eclipse.cdt.internal.ui.viewsupport.CElementLabels; import org.eclipse.cdt.internal.ui.viewsupport.IndexUI; class OpenDeclarationsJob extends Job implements ASTRunnable { - private enum NameKind { REFERENCE, DECLARATION, USING_DECL, DEFINITION } private final SelectionParseAction fAction; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/AbstractLangsListTab.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/AbstractLangsListTab.java index 637b944fa27..f564ec4eefe 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/AbstractLangsListTab.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/AbstractLangsListTab.java @@ -19,6 +19,9 @@ import java.util.Comparator; import java.util.LinkedList; 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.viewers.IFontProvider; 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.TreeItem; +import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport; import org.eclipse.cdt.core.model.ILanguageDescriptor; import org.eclipse.cdt.core.model.LanguageManager; 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.MultiLanguageSetting; 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.Messages; 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. * Multiline selection is not supported. */ - private void updateStatusLine() { - fStatusLine.setErrorStatus(LanguageSettingsImages.getStatus(getSelectedEntry(), getResDesc().getConfiguration())); + protected void updateStatusLine() { + 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); } /** diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/SymbolTab.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/SymbolTab.java index 6d93c850be2..e1c02838ed7 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/SymbolTab.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/SymbolTab.java @@ -95,6 +95,7 @@ public class SymbolTab extends AbstractLangsListTab { table.setSelection(0); } updateStringListModeControl(); + updateStatusLine(); updateButtons(); } diff --git a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/GDBCDIDebugger2.java b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/GDBCDIDebugger2.java index c58b5f482e3..cfad08fbd3b 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/GDBCDIDebugger2.java +++ b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/GDBCDIDebugger2.java @@ -11,7 +11,6 @@ package org.eclipse.cdt.debug.mi.core; import java.io.File; -import com.ibm.icu.text.MessageFormat; import java.util.ArrayList; import java.util.Collections; 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.cdi.CDIException; 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.SharedLibraryManager; 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.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.output.MIInfo; import org.eclipse.core.resources.IProject; @@ -36,6 +37,8 @@ import org.eclipse.core.runtime.Path; import org.eclipse.core.variables.VariablesPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; + +import com.ibm.icu.text.MessageFormat; /** * Implementing the cdebugger extension point for basic launch configurations. @@ -107,6 +110,7 @@ public class GDBCDIDebugger2 extends AbstractGDBCDIDebugger { @Override protected void doStartSession( ILaunch launch, Session session, IProgressMonitor monitor ) throws CoreException { ILaunchConfiguration config = launch.getLaunchConfiguration(); + setAsyncMode( config, session ); initializeLibraries( config, session ); if ( monitor.isCanceled() ) { 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 ); 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". + } + } + } } diff --git a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/GDBServerCDIDebugger2.java b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/GDBServerCDIDebugger2.java index e61fd0031f8..37365ef3fed 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/GDBServerCDIDebugger2.java +++ b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/GDBServerCDIDebugger2.java @@ -11,7 +11,9 @@ package org.eclipse.cdt.debug.mi.core; 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.mi.core.cdi.CdiResources; 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.command.CommandFactory; @@ -35,6 +37,7 @@ public class GDBServerCDIDebugger2 extends GDBCDIDebugger2 { @Override protected void doStartSession( ILaunch launch, Session session, IProgressMonitor monitor ) throws CoreException { ILaunchConfiguration config = launch.getLaunchConfiguration(); + setAsyncMode( config, session ); initializeLibraries( config, session ); if ( monitor.isCanceled() ) { throw new OperationCanceledException(); @@ -134,4 +137,25 @@ public class GDBServerCDIDebugger2 extends GDBCDIDebugger2 { protected boolean usePty( ILaunchConfiguration config ) throws CoreException { 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". + } + } + } } diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.xml b/debug/org.eclipse.cdt.debug.ui/plugin.xml index 16b824cf325..dba67c653a7 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.xml +++ b/debug/org.eclipse.cdt.debug.ui/plugin.xml @@ -2250,7 +2250,7 @@ + locationURI="menu:org.eclipse.ui.run?after=stepGroup"> + +