diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerInputAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerInputAdapter.java index bd018868a36..e38fe25da9a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerInputAdapter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerInputAdapter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2011 Wind River Systems, Inc. and others. + * Copyright (c) 2007, 2014 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 @@ -85,6 +85,11 @@ public class StandaloneIndexerInputAdapter extends IndexerInputAdapter { return false; } + @Override + public int getIndexingPriority(IIndexFileLocation ifl) { + return 0; + } + @Override public boolean isSource(String filename) { return isValidSourceUnitName(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 8f452b75221..744cfc83e62 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 @@ -16,9 +16,11 @@ package org.eclipse.cdt.internal.core.pdom; import java.lang.reflect.InvocationTargetException; import java.net.URI; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.BitSet; import java.util.Collections; +import java.util.Deque; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -326,7 +328,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter { * A queue of urgent indexing tasks that contribute additional files to this task. * The files from the urgent tasks are indexed before all not yet processed files. */ - private final LinkedList fUrgentTasks; + private final Deque fUrgentTasks; boolean fTaskCompleted; private IndexerProgress fInfo= new IndexerProgress(); private IProgressMonitor fProgressMonitor; @@ -338,7 +340,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter { fFilesToUpdate= filesToUpdate; Collections.addAll(fFilesToRemove, filesToRemove); incrementRequestedFilesCount(fFilesToUpdate.length + fFilesToRemove.size()); - fUrgentTasks = new LinkedList<>(); + fUrgentTasks = new ArrayDeque<>(); } public final void setIndexHeadersWithoutContext(UnusedHeaderStrategy mode) { @@ -626,7 +628,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter { } } - private void extractFiles(HashMap> files, List iFilesToRemove, + private void extractFiles(HashMap> files, List filesToRemove, IProgressMonitor monitor) throws CoreException { final boolean forceAll= (fUpdateFlags & IIndexManager.UPDATE_ALL) != 0; final boolean checkTimestamps= (fUpdateFlags & IIndexManager.UPDATE_CHECK_TIMESTAMPS) != 0; @@ -686,7 +688,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter { if (ifile != null) { IIndexInclude ctx= ifile.getParsedInContext(); if (ctx == null && !indexedUnconditionally && ifile.hasContent()) { - iFilesToRemove.add(ifile); + filesToRemove.add(ifile); count++; } else { boolean update= force || @@ -713,7 +715,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter { private void addPerLinkage(int linkageID, IIndexFileLocation ifl, HashMap> files) { List list= files.get(linkageID); if (list == null) { - list= new LinkedList<>(); + list= new ArrayList<>(); files.put(linkageID, list); } list.add(ifl); @@ -859,84 +861,108 @@ public abstract class AbstractIndexerTask extends PDOMWriter { if (map == null || files == null || files.isEmpty()) return; - // First parse the required sources - for (Iterator it= files.iterator(); it.hasNext();) { - IIndexFileLocation ifl= it.next(); - LocationTask locTask = map.find(ifl); - if (locTask == null || locTask.isCompleted()) { - it.remove(); - } else if (locTask.fKind == UpdateKind.REQUIRED_SOURCE) { - if (monitor.isCanceled() || hasUrgentTasks()) - return; - final Object tu = locTask.fTu; - final IScannerInfo scannerInfo = getScannerInfo(linkageID, tu); - parseFile(tu, getLanguage(tu, linkageID), ifl, scannerInfo, null, monitor); + int maxPriority = Integer.MIN_VALUE; + int minPriority = Integer.MAX_VALUE; + Map> filesByPriority = new HashMap<>(); + for (IIndexFileLocation file : files) { + int priority = fResolver.getIndexingPriority(file); + List list = filesByPriority.get(priority); + if (list == null) { + list = new LinkedList<>(); + filesByPriority.put(priority, list); } + list.add(file); + + if (maxPriority < priority) + maxPriority = priority; + if (minPriority > priority) + minPriority = priority; } - // Files with context - for (Iterator it= files.iterator(); it.hasNext();) { - IIndexFileLocation ifl= it.next(); - LocationTask locTask = map.find(ifl); - if (locTask == null || locTask.isCompleted()) { - it.remove(); - } else { - for (FileVersionTask versionTask : locTask.fVersionTasks) { - if (versionTask.fOutdated) { - if (monitor.isCanceled() || hasUrgentTasks()) - return; - parseVersionInContext(linkageID, map, ifl, versionTask, locTask.fTu, - new LinkedHashSet(), monitor); - } - } - } - } + for (int priority = maxPriority; priority >= minPriority; priority--) { + List filesAtPriority = filesByPriority.get(priority); + if (filesAtPriority == null) + continue; - // Files without context - for (Iterator it= files.iterator(); it.hasNext();) { - IIndexFileLocation ifl= it.next(); - LocationTask locTask = map.find(ifl); - if (locTask == null || locTask.isCompleted()) { - it.remove(); - } else { - if (locTask.needsVersion()) { + // First parse the required sources. + for (Iterator it= filesAtPriority.iterator(); it.hasNext();) { + IIndexFileLocation ifl= it.next(); + LocationTask locTask = map.find(ifl); + if (locTask == null || locTask.isCompleted()) { + it.remove(); + } else if (locTask.fKind == UpdateKind.REQUIRED_SOURCE) { if (monitor.isCanceled() || hasUrgentTasks()) return; final Object tu = locTask.fTu; - final IScannerInfo scannerInfo= getScannerInfo(linkageID, tu); + final IScannerInfo scannerInfo = getScannerInfo(linkageID, tu); parseFile(tu, getLanguage(tu, linkageID), ifl, scannerInfo, null, monitor); - if (locTask.isCompleted()) - it.remove(); - } } - } - - // Delete remaining files. - fIndex.acquireWriteLock(fProgressMonitor); - try { - for (IIndexFileLocation ifl : files) { + + // Files with context. + for (Iterator it= filesAtPriority.iterator(); it.hasNext();) { + IIndexFileLocation ifl= it.next(); LocationTask locTask = map.find(ifl); - if (locTask != null && !locTask.isCompleted()) { - if (!locTask.needsVersion()) { - if (monitor.isCanceled() || hasUrgentTasks()) - return; - Iterator it= locTask.fVersionTasks.iterator(); - while (it.hasNext()) { - FileVersionTask v = it.next(); - if (v.fOutdated) { - fIndex.clearFile(v.fIndexFile); - reportFile(true, locTask.fKind); - locTask.removeVersionTask(it); - fIndexContentCache.remove(v.fIndexFile); - fIndexFilesCache.remove(ifl); - } + if (locTask == null || locTask.isCompleted()) { + it.remove(); + } else { + for (FileVersionTask versionTask : locTask.fVersionTasks) { + if (versionTask.fOutdated) { + if (monitor.isCanceled() || hasUrgentTasks()) + return; + parseVersionInContext(linkageID, map, ifl, versionTask, locTask.fTu, + new LinkedHashSet(), monitor); } } } } - } finally { - fIndex.releaseWriteLock(); + + // Files without context. + for (Iterator it= filesAtPriority.iterator(); it.hasNext();) { + IIndexFileLocation ifl= it.next(); + LocationTask locTask = map.find(ifl); + if (locTask == null || locTask.isCompleted()) { + it.remove(); + } else { + if (locTask.needsVersion()) { + if (monitor.isCanceled() || hasUrgentTasks()) + return; + final Object tu = locTask.fTu; + final IScannerInfo scannerInfo= getScannerInfo(linkageID, tu); + parseFile(tu, getLanguage(tu, linkageID), ifl, scannerInfo, null, monitor); + if (locTask.isCompleted()) + it.remove(); + + } + } + } + + // Delete remaining files. + fIndex.acquireWriteLock(fProgressMonitor); + try { + for (IIndexFileLocation ifl : filesAtPriority) { + LocationTask locTask = map.find(ifl); + if (locTask != null && !locTask.isCompleted()) { + if (!locTask.needsVersion()) { + if (monitor.isCanceled() || hasUrgentTasks()) + return; + Iterator it= locTask.fVersionTasks.iterator(); + while (it.hasNext()) { + FileVersionTask v = it.next(); + if (v.fOutdated) { + fIndex.clearFile(v.fIndexFile); + reportFile(true, locTask.fKind); + locTask.removeVersionTask(it); + fIndexContentCache.remove(v.fIndexFile); + fIndexFilesCache.remove(ifl); + } + } + } + } + } + } finally { + fIndex.releaseWriteLock(); + } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerInputAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerInputAdapter.java index 4f27d33d3aa..c9385644dd9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerInputAdapter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerInputAdapter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2009 Wind River Systems, Inc. and others. + * Copyright (c) 2007, 2014 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 @@ -66,12 +66,23 @@ public abstract class IndexerInputAdapter extends ASTFilePathResolver { public abstract boolean isIndexedOnlyIfIncluded(Object tu); /** - * Checks whether the given file should be indexed unconditionally. - * @param location the location of the file. - * @return {@code true} if the file should be indexed unconditionally. + * Checks whether the given file should be indexed unconditionally. + * + * @param location the location of the file + * @return {@code true} if the file should be indexed unconditionally */ public abstract boolean isIndexedUnconditionally(IIndexFileLocation location); + /** + * Returns the priority of indexing a file. The priority is a nonnegative number. A larger + * number means a higher priority causing the file to be indexed ahead of files with lower + * priorities. + * + * @param location the location of the file + * @return {@code true} the indexing priority + */ + public abstract int getIndexingPriority(IIndexFileLocation location); + /** * Tests whether the file in the index is allowed to be part of an SDK. If not * it will be indexed. 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 271cf56c77a..25c6c6c9ef5 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 @@ -1651,4 +1651,8 @@ public class PDOMManager implements IWritableIndexManager, IListener { public boolean isFileIndexedUnconditionally(IIndexFileLocation ifl) { return fFilesIndexedUnconditionlly.contains(ifl); } + + public int getIndexingPriority(IIndexFileLocation ifl) { + return fFilesIndexedUnconditionlly.getCount(ifl); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java index 695044c7902..0d166d4965b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2011 Wind River Systems, Inc. and others. + * Copyright (c) 2007, 2014 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 @@ -275,6 +275,11 @@ public class ProjectIndexerInputAdapter extends IndexerInputAdapter { return CCoreInternals.getPDOMManager().isFileIndexedUnconditionally(ifl); } + @Override + public int getIndexingPriority(IIndexFileLocation ifl) { + return CCoreInternals.getPDOMManager().getIndexingPriority(ifl); + } + @Override public boolean isSourceUnit(Object tuo) { ITranslationUnit tu= (ITranslationUnit) tuo; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ASTProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ASTProvider.java index caa5742d74e..22b963a3851 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ASTProvider.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ASTProvider.java @@ -105,7 +105,6 @@ public final class ASTProvider { * Internal activation listener. */ private class ActivationListener implements IPartListener2, IWindowListener { - /* * @see org.eclipse.ui.IPartListener2#partActivated(org.eclipse.ui.IWorkbenchPartReference) */ @@ -238,10 +237,11 @@ public final class ASTProvider { } } - private ASTCache fCache= new ASTCache(); + private final ASTCache fCache= new ASTCache(); private ActivationListener fActivationListener; private IWorkbenchPart fActiveEditor; private long fTimeStamp; + private final IndexUpdateRequestor fIndexUpdateRequestor = new IndexUpdateRequestor(); /** * Returns the C plug-in's AST provider. @@ -288,6 +288,9 @@ public final class ASTProvider { fTimeStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; fCache.setActiveElement(tu); } + + // Increase indexing priority of the translation unit of the active editor. + fIndexUpdateRequestor.updateIndexInclusion(tu); } /** diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java index f8ade41240f..1d0357e2683 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java @@ -30,7 +30,6 @@ import java.util.Stack; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; -import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ProjectScope; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; @@ -40,8 +39,6 @@ import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.content.IContentType; import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener; -import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; import org.eclipse.help.IContext; import org.eclipse.help.IContextProvider; import org.eclipse.jface.action.GroupMarker; @@ -176,7 +173,6 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage; import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants; -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.ICProject; @@ -198,8 +194,6 @@ import org.eclipse.cdt.ui.text.ICPartitions; import org.eclipse.cdt.ui.text.folding.ICFoldingStructureProvider; import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable; -import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences; -import org.eclipse.cdt.internal.corext.util.CModelUtil; import org.eclipse.cdt.internal.corext.util.CodeFormatterUtil; import org.eclipse.cdt.internal.ui.CPluginImages; @@ -1138,71 +1132,6 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi } } - private class IndexerPreferenceListener implements IPreferenceChangeListener { - private IProject fProject; - - @Override - public void preferenceChange(PreferenceChangeEvent event) { - if (IndexerPreferences.KEY_INDEX_ON_OPEN.equals(event.getKey())) { - ICElement element= getInputCElement(); - ITranslationUnit tu = element != null ? (ITranslationUnit) element : null; - updateIndexInclusion(tu); - } - } - - void registerFor(IProject project) { - if (fProject == project || fProject != null && fProject.equals(project)) { - return; - } - unregister(); - fProject = project; - if (fProject != null) { - IndexerPreferences.addChangeListener(fProject, this); - } - } - - void unregister() { - if (fProject != null) { - IndexerPreferences.removeChangeListener(fProject, this); - fProject = null; - } - } - } - - private static class IndexUpdateRequestorJob extends Job { - private final ITranslationUnit tuToAdd; - private final ITranslationUnit tuToReset; - - /** - * @param tu The translation unit to add or to remove from the index. - * @param add {@code true} to add, {@code false} to reset index inclusion. - */ - IndexUpdateRequestorJob(ITranslationUnit tuToAdd, ITranslationUnit tuToReset) { - super(CEditorMessages.CEditor_index_expander_job_name); - this.tuToAdd = tuToAdd; - this.tuToReset = tuToReset; - setSystem(true); - setPriority(Job.DECORATE); - } - - @Override - protected IStatus run(IProgressMonitor monitor) { - try { - IIndexManager indexManager = CCorePlugin.getIndexManager(); - if (tuToReset != null) { - indexManager.update(new ICElement[] { CModelUtil.toOriginal(tuToReset) }, - IIndexManager.RESET_INDEX_INCLUSION | IIndexManager.UPDATE_CHECK_TIMESTAMPS); - } - if (tuToAdd != null) { - indexManager.update(new ICElement[] { CModelUtil.toOriginal(tuToAdd) }, - IIndexManager.FORCE_INDEX_INCLUSION | IIndexManager.UPDATE_CHECK_TIMESTAMPS); - } - } catch (CoreException e) { - } - return Status.OK_STATUS; - } - } - /** * The editor selection changed listener. * @@ -1301,21 +1230,16 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi * True if editor is opening a large file. * @since 5.0 */ - private boolean fEnableScalablilityMode = false; + private boolean fEnableScalablilityMode; - /** - * Flag indicating whether the reconciler is currently running. - */ + /** Flag indicating whether the reconciler is currently running. */ private volatile boolean fIsReconciling; private CTemplatesPage fTemplatesPage; private SelectionHistory fSelectionHistory; - /** The translation unit that was added by the editor to index, or null. */ - private ITranslationUnit fTuAddedToIndex; - - private final IndexerPreferenceListener fIndexerPreferenceListener; + private final IndexUpdateRequestor fIndexUpdateRequestor = new IndexUpdateRequestor(); private final ListenerList fPostSaveListeners; @@ -1354,7 +1278,6 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi setOutlinerContextMenuId("#CEditorOutlinerContext"); //$NON-NLS-1$ fCEditorErrorTickUpdater = new CEditorErrorTickUpdater(this); - fIndexerPreferenceListener = new IndexerPreferenceListener(); fPostSaveListeners = new ListenerList(); } @@ -1402,8 +1325,6 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi if (cSourceViewer != null && isFoldingEnabled() && (store == null || !store.getBoolean(PreferenceConstants.EDITOR_SHOW_SEGMENTS))) cSourceViewer.prepareDelayedProjection(); - fIndexerPreferenceListener.unregister(); - super.doSetInput(input); setOutlinePageInput(fOutlinePage, input); @@ -1415,35 +1336,16 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi fCEditorErrorTickUpdater.updateEditorImage(getInputCElement()); } ICElement element= getInputCElement(); - if (element != null) { - IProject project = element.getCProject().getProject(); - fIndexerPreferenceListener.registerFor(project); - } - if (element instanceof ITranslationUnit) { ITranslationUnit tu = (ITranslationUnit) element; - updateIndexInclusion(tu); + fIndexUpdateRequestor.updateIndexInclusion(tu); fBracketMatcher.configure(tu.getLanguage()); } else { - updateIndexInclusion(null); + fIndexUpdateRequestor.updateIndexInclusion(null); fBracketMatcher.configure(null); } } - private void updateIndexInclusion(ITranslationUnit tu) { - if (tu != null) { - IProject project = tu.getCProject().getProject(); - if (!String.valueOf(true).equals(IndexerPreferences.get(project, IndexerPreferences.KEY_INDEX_ON_OPEN, null))) { - tu = null; - } - } - if ((tu != null || fTuAddedToIndex != null) && tu != fTuAddedToIndex) { - IndexUpdateRequestorJob job = new IndexUpdateRequestorJob(tu, fTuAddedToIndex); - fTuAddedToIndex = tu; - job.schedule(); - } - } - private void updateScalabilityMode(IEditorInput input) { int lines = getDocumentProvider().getDocument(input).getNumberOfLines(); boolean wasEnabled = fEnableScalablilityMode; @@ -2101,8 +2003,7 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi */ @Override public void dispose() { - fIndexerPreferenceListener.unregister(); - updateIndexInclusion(null); + fIndexUpdateRequestor.updateIndexInclusion(null); ISourceViewer sourceViewer = getSourceViewer(); if (sourceViewer instanceof ITextViewerExtension) diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorMessages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorMessages.java index df53af91e0a..1fb850fee6c 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorMessages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorMessages.java @@ -107,8 +107,8 @@ public final class CEditorMessages extends NLS { public static String SemanticHighlighting_problem; public static String SemanticHighlighting_externalSDK; public static String CEditor_markOccurrences_job_name; - public static String CEditor_index_expander_job_name; public static String CEditorActionContributor_ExpandSelectionMenu_label; + public static String IndexUpdateRequestor_job_name; public static String StepIntoSelection_unable_to_resolve_name; static { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorMessages.properties index 43e1782ba7c..062332c0c9a 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorMessages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorMessages.properties @@ -105,6 +105,6 @@ SemanticHighlighting_problem= Problems SemanticHighlighting_externalSDK= External SDK calls CEditor_markOccurrences_job_name= Occurrences Marker -CEditor_index_expander_job_name= Index Expander CEditorActionContributor_ExpandSelectionMenu_label=E&xpand Selection To +IndexUpdateRequestor_job_name= Updating index StepIntoSelection_unable_to_resolve_name=Unable to resolve the selection to a semantic object \ No newline at end of file diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/IndexUpdateRequestor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/IndexUpdateRequestor.java new file mode 100644 index 00000000000..02b9b97c7ce --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/IndexUpdateRequestor.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) 2014 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.editor; + +import java.util.Objects; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener; +import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.index.IIndexManager; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ITranslationUnit; + +import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences; +import org.eclipse.cdt.internal.corext.util.CModelUtil; + +/** + * A controller for on-demand indexing of files opened in C/C++ editors. + */ +public class IndexUpdateRequestor implements IPreferenceChangeListener { + private static class IndexUpdateRequestorJob extends Job { + private final ITranslationUnit tuToAdd; + private final ITranslationUnit tuToReset; + + /** + * @param tu The translation unit to add or to remove from the index. + * @param add {@code true} to add, {@code false} to reset index inclusion. + */ + IndexUpdateRequestorJob(ITranslationUnit tuToAdd, ITranslationUnit tuToReset) { + super(CEditorMessages.IndexUpdateRequestor_job_name); + this.tuToAdd = tuToAdd; + this.tuToReset = tuToReset; + setSystem(true); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + IIndexManager indexManager = CCorePlugin.getIndexManager(); + if (tuToReset != null) { + indexManager.update(new ICElement[] { CModelUtil.toOriginal(tuToReset) }, + IIndexManager.RESET_INDEX_INCLUSION | IIndexManager.UPDATE_CHECK_TIMESTAMPS); + } + if (tuToAdd != null) { + indexManager.update(new ICElement[] { CModelUtil.toOriginal(tuToAdd) }, + IIndexManager.FORCE_INDEX_INCLUSION | IIndexManager.UPDATE_CHECK_TIMESTAMPS); + } + } catch (CoreException e) { + } + return Status.OK_STATUS; + } + } + + private ITranslationUnit fTu; + private ITranslationUnit fTuAddedToIndex; + + public void updateIndexInclusion(ITranslationUnit tu) { + IProject oldProject; + IProject newProject; + synchronized (this) { + oldProject = fTu == null ? null : fTu.getCProject().getProject(); + newProject = tu == null ? null : tu.getCProject().getProject(); + fTu = tu; + } + + if (Objects.equals(newProject, oldProject)) { + if (oldProject != null) { + IndexerPreferences.removeChangeListener(oldProject, this); + } + if (newProject != null) { + IndexerPreferences.addChangeListener(newProject, this); + } + } + + if (tu != null) { + IProject project = tu.getCProject().getProject(); + if (!String.valueOf(true).equals(IndexerPreferences.get(project, IndexerPreferences.KEY_INDEX_ON_OPEN, null))) { + tu = null; + } + } + requestIndexUpdate(tu); + } + + private synchronized void requestIndexUpdate(ITranslationUnit tu) { + if (!Objects.equals(tu, fTuAddedToIndex)) { + IndexUpdateRequestorJob job = new IndexUpdateRequestorJob(tu, fTuAddedToIndex); + fTuAddedToIndex = tu; + job.schedule(); + } + } + + @Override + public void preferenceChange(PreferenceChangeEvent event) { + if (IndexerPreferences.KEY_INDEX_ON_OPEN.equals(event.getKey())) { + requestIndexUpdate(null); + } + } +}