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 72ecf2c61bf..2e98b26f711 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 @@ -13,6 +13,7 @@ package org.eclipse.cdt.core.index; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.IPDOMManager; +import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; @@ -59,6 +60,18 @@ public interface IIndexManager extends IPDOMManager { * @see IIndexManager#joinIndexer(int, IProgressMonitor) */ public final static int FOREVER= -1; + + /** + * Constant for indicating to update all translation units. + */ + public final static int UPDATE_ALL= 0x1; + + /** + * Constant for indicating to update translation units only if their timestamp + * has changed. + */ + public final static int UPDATE_CHECK_TIMESTAMPS= 0x2; + /** * Returns the index for the given project. * @param project the project to get the index for @@ -156,6 +169,19 @@ public interface IIndexManager extends IPDOMManager { */ public void reindex(ICProject project) throws CoreException; + /** + * Updates the index for the given selection of translation units considering + * the options supplied. The selection is defined by an array of translation + * units, containers and projects. For containers and projects all recursively + * nested translation units are considered. + * Valid options are {@link #UPDATE_ALL} and {@link #UPDATE_CHECK_TIMESTAMPS} + * @param tuSelection the translation units to update. + * @param options one of {@link #UPDATE_ALL} or {@link #UPDATE_CHECK_TIMESTAMPS}. + * @throws CoreException + * @since 4.0 + */ + public void update(ICElement[] tuSelection, int options) throws CoreException; + /** * Export index for usage within a team. * @param project a project for which the pdom is to be exported. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/LanguageMappingChangeListener.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/LanguageMappingChangeListener.java index 24035da5736..65b5b3be0e8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/LanguageMappingChangeListener.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/LanguageMappingChangeListener.java @@ -7,20 +7,19 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.index.IIndexManager; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.ICElement; -import org.eclipse.cdt.core.model.ICElementDelta; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ILanguageMappingChangeEvent; import org.eclipse.cdt.core.model.ILanguageMappingChangeListener; -import org.eclipse.cdt.internal.core.model.CElementDelta; import org.eclipse.cdt.internal.core.model.CModelManager; import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; /** @@ -32,9 +31,9 @@ import org.eclipse.core.runtime.CoreException; public class LanguageMappingChangeListener implements ILanguageMappingChangeListener { - private PDOMManager fManager; + private IIndexManager fManager; - public LanguageMappingChangeListener(PDOMManager manager) { + public LanguageMappingChangeListener(IIndexManager manager) { fManager = manager; } @@ -43,35 +42,18 @@ public class LanguageMappingChangeListener implements * @see org.eclipse.cdt.core.model.ILanguageMappingChangeListener#handleLanguageMappingChangeEvent(org.eclipse.cdt.core.model.ILanguageMappingsChangeEvent) */ public void handleLanguageMappingChangeEvent(ILanguageMappingChangeEvent event) { - IProject project = event.getProject(); - CModelManager manager = CModelManager.getDefault(); - if(project != null) { - ICProject cProject = manager.getCModel().findCProject(project); - - if(cProject != null) - try { - fManager.reindex(cProject); - } catch (CoreException e) { - CCorePlugin.log(e); - } - } - if (event.getType() == ILanguageMappingChangeEvent.TYPE_WORKSPACE) { // For now reindex all projects. // TODO: This should be smarter about figuring out which projects // are potentially unaffected due to project settings try { ICProject[] cProjects = manager.getCModel().getCProjects(); - for(int k = 0; k < cProjects.length; k++) { - try { - fManager.reindex(cProjects[k]); - } catch (CoreException e) { - CCorePlugin.log(e); - } - } + fManager.update(cProjects, IIndexManager.UPDATE_ALL); } catch (CModelException e) { CCorePlugin.log(e); + } catch (CoreException e) { + CCorePlugin.log(e); } } else if (event.getType() == ILanguageMappingChangeEvent.TYPE_PROJECT) { // For now, reindex the entire project since we don't know which @@ -89,10 +71,8 @@ public class LanguageMappingChangeListener implements IFile file = event.getFile(); ICProject cProject = manager.getCModel().getCProject(file); ICElement element = manager.create(file, cProject); - CElementDelta delta = new CElementDelta(element); - delta.changed(element, ICElementDelta.F_CONTENT); try { - fManager.changeProject(cProject, delta); + fManager.update(new ICElement[] {element}, IIndexManager.UPDATE_ALL); } catch (CoreException e) { CCorePlugin.log(e); } 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 5c0999a9071..21967b19c79 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,9 +20,11 @@ import java.io.InputStream; import java.io.OutputStream; import java.nio.channels.FileChannel; import java.text.MessageFormat; +import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; +import java.util.List; import java.util.Map; import java.util.Properties; @@ -37,10 +39,13 @@ import org.eclipse.cdt.core.index.IIndexChangeListener; import org.eclipse.cdt.core.index.IIndexLocationConverter; import org.eclipse.cdt.core.index.IIndexerStateListener; import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICContainer; +import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElementDelta; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.IElementChangedListener; import org.eclipse.cdt.core.model.ILanguageMappingChangeListener; +import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.LanguageManager; import org.eclipse.cdt.internal.core.CCoreInternals; import org.eclipse.cdt.internal.core.index.IIndexFragment; @@ -1049,4 +1054,89 @@ public class PDOMManager implements IWritableIndexManager, IListener { public boolean isProjectIndexed(ICProject proj) { return !IPDOMManager.ID_NO_INDEXER.equals(getIndexerId(proj)); } + + public void update(ICElement[] tuSelection, int options) throws CoreException { + Map projectsToElements= splitSelection(tuSelection); + for (Iterator i = projectsToElements.entrySet().iterator(); i + .hasNext();) { + Map.Entry entry = (Map.Entry) i.next(); + ICProject project = (ICProject) entry.getKey(); + List filesAndFolders = (List) entry.getValue(); + + update(project, filesAndFolders, options); + } + } + + /** + * computes a map from projects to a collection containing the minimal + * set of folders and files specifying the selection. + */ + private Map splitSelection(ICElement[] tuSelection) { + HashMap result= new HashMap(); + allElements: for (int i = 0; i < tuSelection.length; i++) { + ICElement element = tuSelection[i]; + if (element instanceof ICProject || element instanceof ICContainer || element instanceof ITranslationUnit) { + ICProject project= element.getCProject(); + ArrayList set= (ArrayList) result.get(project); + if (set == null) { + set= new ArrayList(); + result.put(project, set); + } + for (int j= 0; j*/ fContextMap = new HashMap/**/(); - private boolean fCheckTimestamps= false; private List fFilesUpFront= new ArrayList(); private String fDummyFileName; private URI fDummyFileURI; @@ -94,10 +93,8 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer return super.getProgressInformation(); } - final public void setCheckTimestamps(boolean val) { - fCheckTimestamps= val; - } - + abstract public void setCheckTimestamps(boolean val); + final public void setParseUpFront() { fFilesUpFront.addAll(Arrays.asList(fIndexer.getFilesToParseUpFront())); } @@ -182,10 +179,7 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer return; ITranslationUnit tu = (ITranslationUnit) iter.next(); final IIndexFileLocation ifl = IndexLocationFactory.getIFL(tu); - if (fCheckTimestamps && !isOutdated(tu, ifl, index)) { - updateInfo(0,0,-1); - } - else if (needToUpdate(ifl)) { + if (needToUpdate(ifl)) { parseTU(tu, options, index, readlockCount, monitor); } } @@ -196,11 +190,7 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer return; ITranslationUnit tu = (ITranslationUnit) iter.next(); IIndexFileLocation location = IndexLocationFactory.getIFL(tu); - if (fCheckTimestamps && !isOutdated(tu, location, index)) { - updateInfo(0,0,-1); - iter.remove(); - } - else if (!needToUpdate(location)) { + if (!needToUpdate(location)) { iter.remove(); } else { @@ -218,11 +208,7 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer return; ITranslationUnit tu = (ITranslationUnit) iter.next(); final IIndexFileLocation ifl = IndexLocationFactory.getIFL(tu); - if (fCheckTimestamps && !isOutdated(tu, ifl, index)) { - updateInfo(0,0,-1); - iter.remove(); - } - else if (!needToUpdate(ifl)) { + if (!needToUpdate(ifl)) { iter.remove(); } else { @@ -232,11 +218,16 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer } } - private boolean isOutdated(ITranslationUnit tu, IIndexFileLocation ifl, IIndex index) throws CoreException { + /** + * Convinience method to check whether a translation unit in the index is outdated + * with respect to its timestamp. + * @throws CoreException + * @since 4.0 + */ + final protected boolean isOutdated(ITranslationUnit tu, IIndexFile indexFile) throws CoreException { boolean outofdate= true; IResource res= tu.getResource(); if (res != null) { - IIndexFile indexFile= index.getFile(ifl); if (indexFile != null) { if (res.getLocalTimeStamp() == indexFile.getTimestamp()) { outofdate= false; 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 cc6454061b9..bff111b58ac 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 @@ -12,12 +12,15 @@ package org.eclipse.cdt.internal.core.pdom.indexer; import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; import java.util.List; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.IPDOMIndexer; import org.eclipse.cdt.core.dom.IPDOMIndexerTask; import org.eclipse.cdt.core.dom.IPDOMManager; +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.internal.core.pdom.IndexerProgress; @@ -32,6 +35,8 @@ public class PDOMUpdateTask implements IPDOMIndexerTask { private final IPDOMIndexer fIndexer; private final IndexerProgress fProgress; private volatile IPDOMIndexerTask fDelegate; + private boolean fCheckTimestamps= true; + private ArrayList fFilesAndFolders= null; public PDOMUpdateTask(IPDOMIndexer indexer) { fIndexer= indexer; @@ -70,13 +75,21 @@ public class PDOMUpdateTask implements IPDOMIndexerTask { private synchronized void createDelegate(ICProject project, IProgressMonitor monitor) throws CoreException { boolean allFiles= TRUE.equals(fIndexer.getProperty(IndexerPreferences.KEY_INDEX_ALL_FILES)); - List list= new ArrayList(); - TranslationUnitCollector collector= new TranslationUnitCollector(list, list, allFiles, monitor); - project.accept(collector); - ITranslationUnit[] tus= (ITranslationUnit[]) list.toArray(new ITranslationUnit[list.size()]); + HashSet set= new HashSet(); + TranslationUnitCollector collector= new TranslationUnitCollector(set, set, allFiles, monitor); + if (fFilesAndFolders == null) { + project.accept(collector); + } + else { + for (Iterator iterator = fFilesAndFolders.iterator(); iterator.hasNext();) { + ICElement elem = (ICElement) iterator.next(); + elem.accept(collector); + } + } + ITranslationUnit[] tus= (ITranslationUnit[]) set.toArray(new ITranslationUnit[set.size()]); fDelegate= fIndexer.createTask(tus, NO_TUS, NO_TUS); if (fDelegate instanceof PDOMIndexerTask) { - ((PDOMIndexerTask) fDelegate).setCheckTimestamps(true); + ((PDOMIndexerTask) fDelegate).setCheckTimestamps(fCheckTimestamps); } } @@ -84,4 +97,13 @@ public class PDOMUpdateTask implements IPDOMIndexerTask { public synchronized IndexerProgress getProgressInformation() { return fDelegate != null ? fDelegate.getProgressInformation() : fProgress; } + + public void setCheckTimestamps(boolean timestamps) { + fCheckTimestamps= timestamps; + } + + public void setTranslationUnitSelection(List filesAndFolders) { + fFilesAndFolders= new ArrayList(filesAndFolders.size()); + fFilesAndFolders.addAll(filesAndFolders); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerTask.java index 64887dd5014..5d6c0291f92 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerTask.java @@ -14,7 +14,6 @@ package org.eclipse.cdt.internal.core.pdom.indexer.fast; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -44,6 +43,7 @@ class PDOMFastIndexerTask extends PDOMIndexerTask { private IWritableIndex fIndex; private IndexBasedCodeReaderFactory fCodeReaderFactory; private Map fIflCache; + private boolean fCheckTimestamps= false; public PDOMFastIndexerTask(PDOMFastIndexer indexer, ITranslationUnit[] added, ITranslationUnit[] changed, ITranslationUnit[] removed) { @@ -60,7 +60,7 @@ class PDOMFastIndexerTask extends PDOMIndexerTask { setupIndexAndReaderFactory(); fIndex.acquireReadLock(); try { - registerTUsInReaderFactory(fChanged); + registerTUsInReaderFactory(); Iterator i= fRemoved.iterator(); while (i.hasNext()) { @@ -109,13 +109,21 @@ class PDOMFastIndexerTask extends PDOMIndexerTask { this.fCodeReaderFactory = new IndexBasedCodeReaderFactory(fIndex, fIflCache); } - private void registerTUsInReaderFactory(Collection files) throws CoreException { - for (Iterator iter = files.iterator(); iter.hasNext();) { + private void registerTUsInReaderFactory() throws CoreException { + int removed= 0; + for (Iterator iter = fChanged.iterator(); iter.hasNext();) { ITranslationUnit tu = (ITranslationUnit) iter.next(); - IIndexFileLocation location = IndexLocationFactory.getIFL(tu); - FileInfo info= fCodeReaderFactory.createFileInfo(location); - info.setRequested(true); + IIndexFileLocation ifl = IndexLocationFactory.getIFL(tu); + FileInfo info= fCodeReaderFactory.createFileInfo(ifl); + if (fCheckTimestamps && !isOutdated(tu, info.fFile)) { + iter.remove(); + removed++; + } + else { + info.setRequested(true); + } } + updateInfo(0, 0, -removed); } protected IIndexFileLocation findLocation(String absolutePath) { @@ -158,4 +166,8 @@ class PDOMFastIndexerTask extends PDOMIndexerTask { } return false; } + + public void setCheckTimestamps(boolean val) { + fCheckTimestamps= val; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerTask.java index 7f8b47d7e23..83352083ae7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerTask.java @@ -51,6 +51,7 @@ class PDOMFullIndexerTask extends PDOMIndexerTask { private IWritableIndex fIndex = null; private Map filePathsToParse = new HashMap/**/(); private Map fIflCache = new HashMap/**/(); + private boolean fCheckTimestamps= false; public PDOMFullIndexerTask(PDOMFullIndexer indexer, ITranslationUnit[] added, ITranslationUnit[] changed, ITranslationUnit[] removed) { @@ -69,14 +70,24 @@ class PDOMFullIndexerTask extends PDOMIndexerTask { // separate headers List headers= new ArrayList(); List sources= fChanged; + int removed= 0; for (Iterator iter = fChanged.iterator(); iter.hasNext();) { ITranslationUnit tu = (ITranslationUnit) iter.next(); + if (fCheckTimestamps) { + IIndexFileLocation ifl = IndexLocationFactory.getIFL(tu); + IIndexFile file= fIndex.getFile(ifl); + if (!isOutdated(tu, file)) { + iter.remove(); + removed++; + continue; + } + } if (!tu.isSourceUnit()) { headers.add(tu); iter.remove(); } } - + updateInfo(0, 0, -removed); registerTUsInReaderFactory(sources); registerTUsInReaderFactory(headers); @@ -161,4 +172,8 @@ class PDOMFullIndexerTask extends PDOMIndexerTask { filePathsToParse.put(location, SKIP); return required == REQUIRED; } + + public void setCheckTimestamps(boolean val) { + fCheckTimestamps= val; + } } diff --git a/core/org.eclipse.cdt.ui/plugin.properties b/core/org.eclipse.cdt.ui/plugin.properties index 91a6c24a7aa..a8470783774 100644 --- a/core/org.eclipse.cdt.ui/plugin.properties +++ b/core/org.eclipse.cdt.ui/plugin.properties @@ -357,7 +357,7 @@ CDTIndexer.fastindexer=Fast C/C++ Indexer (recommended) IndexView.name=C/C++ Index RebuildIndex.name=Rebuild -SyncIndex.name=Update Modified Files +SyncIndex.name=Update with Modified Files indexerPage.name = Indexer Page proposalFilter.name = Code Completion Proposal Filter diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index 3e337d9ee9d..0bed47ed4a6 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -716,11 +716,16 @@ + objectClass="org.eclipse.cdt.core.model.ICElement"> + @@ -732,6 +737,19 @@ name="gm1"> + + + + + + + + + +