diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/CPPFunctionTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/CPPFunctionTests.java
index 0b544e2122b..a0cfce22d09 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/CPPFunctionTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/CPPFunctionTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2007 IBM Corporation.
+ * Copyright (c) 2006, 2008 IBM Corporation.
* 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
@@ -9,7 +9,6 @@
* IBM Corporation - initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
-
package org.eclipse.cdt.internal.pdom.tests;
import junit.framework.Test;
@@ -48,12 +47,14 @@ public class CPPFunctionTests extends PDOMTestBase {
return suite(CPPFunctionTests.class);
}
+ @Override
protected void setUp() throws Exception {
project = createProject("functionTests");
pdom = (PDOM) CCoreInternals.getPDOMManager().getPDOM(project);
pdom.acquireReadLock();
}
+ @Override
protected void tearDown() throws Exception {
pdom.releaseReadLock();
if (project != null) {
@@ -172,17 +173,17 @@ public class CPPFunctionTests extends PDOMTestBase {
for (int i = 0; i < 2; i++) {
ICPPFunction function = (ICPPFunction) bindings[i];
assertEquals(1, pdom.findNames(function, IIndex.FIND_DECLARATIONS_DEFINITIONS).length);
- assertEquals(1, pdom.getDefinitions(function).length);
+ assertEquals(1, pdom.findNames(function, IIndex.FIND_DEFINITIONS).length);
IParameter[] parameters = function.getParameters();
switch (parameters.length) {
case 0:
assertFalse(seen[0]);
- assertEquals(1, pdom.getReferences(function).length);
+ assertEquals(1, pdom.findNames(function, IIndex.FIND_REFERENCES).length);
seen[0] = true;
break;
case 1:
assertFalse(seen[1]);
- assertEquals(2, pdom.getReferences(function).length);
+ assertEquals(2, pdom.findNames(function, IIndex.FIND_REFERENCES).length);
assertEquals("p1", parameters[0].getName());
assertEquals(IBasicType.t_int, ((ICPPBasicType) parameters[0].getType()).getType());
seen[1] = true;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexChangeEvent.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexChangeEvent.java
index 2819ffe2ee9..5a4e5806150 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexChangeEvent.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexChangeEvent.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006 Wind River Systems, Inc. and others.
+ * Copyright (c) 2006, 2008 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
@@ -8,13 +8,14 @@
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
-
package org.eclipse.cdt.core.index;
+import java.util.Set;
+
import org.eclipse.cdt.core.model.ICProject;
/**
- * IndexChangeEvents descrive changes to the index.
+ * IndexChangeEvents describe changes to the index.
*
* EXPERIMENTAL . This class or interface has been added as
* part of a work in progress. There is no guarantee that this API will work or
@@ -30,4 +31,27 @@ public interface IIndexChangeEvent {
* Returns the project for which the index has changed.
*/
public ICProject getAffectedProject();
+
+ /**
+ * Returns true
when the index for the project was loaded for the first time or
+ * reloaded with a different database.
+ */
+ public boolean isReloaded();
+
+ /**
+ * Returns true
when the index for the project was cleared.
+ */
+ public boolean isCleared();
+
+ /**
+ * Returns the set of files that has been cleared in the index. When {@link #isCleared()}
+ * returns true
, the set will be empty.
+ */
+ public Set getFilesCleared();
+
+ /**
+ * Returns the set of files that has been added or updated. When {@link #isCleared()} returns
+ * true
, the files of the set have been written after the index was cleared.
+ */
+ public Set getFilesWritten();
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexerStateEvent.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexerStateEvent.java
index 9543dab11e8..23f8da3ef96 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexerStateEvent.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexerStateEvent.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006 Wind River Systems, Inc. and others.
+ * Copyright (c) 2006, 2008 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
@@ -8,12 +8,10 @@
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
-
package org.eclipse.cdt.core.index;
-
/**
- * IndexChangeEvents descrive changes to the state of the indexer.
+ * IndexChangeEvents describe changes to the state of the indexer.
*
* EXPERIMENTAL . This class or interface has been added as
* part of a work in progress. There is no guarantee that this API will work or
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexChangeEvent.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexChangeEvent.java
index e508e463e5b..31db4631674 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexChangeEvent.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexChangeEvent.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006 Wind River Systems, Inc. and others.
+ * Copyright (c) 2006, 2008 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
@@ -8,29 +8,52 @@
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
-
package org.eclipse.cdt.internal.core.index;
+import java.util.Set;
+
import org.eclipse.cdt.core.index.IIndexChangeEvent;
+import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.internal.core.pdom.PDOM.ChangeEvent;
public class IndexChangeEvent implements IIndexChangeEvent {
private ICProject fAffectedProject;
+ private ChangeEvent fChangeEvent;
- public IndexChangeEvent(ICProject projectChanged) {
+ public IndexChangeEvent(ICProject projectChanged, ChangeEvent e) {
fAffectedProject= projectChanged;
+ fChangeEvent= e;
}
public IndexChangeEvent() {
fAffectedProject= null;
+ fChangeEvent= new ChangeEvent();
}
public ICProject getAffectedProject() {
return fAffectedProject;
}
- public void setAffectedProject(ICProject project) {
+ public void setAffectedProject(ICProject project, ChangeEvent e) {
fAffectedProject= project;
+ fChangeEvent= e;
+ }
+
+ public Set getFilesCleared() {
+ return fChangeEvent.fClearedFiles;
+ }
+
+ public Set getFilesWritten() {
+ return fChangeEvent.fFilesWritten;
+ }
+
+ public boolean isCleared() {
+ return fChangeEvent.fCleared;
+ }
+
+ public boolean isReloaded() {
+ return fChangeEvent.fReloaded;
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/JobChangeListener.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/JobChangeListener.java
new file mode 100644
index 00000000000..73718480512
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/JobChangeListener.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.pdom;
+
+import org.eclipse.cdt.internal.core.index.IndexerStateEvent;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.IJobChangeListener;
+import org.eclipse.core.runtime.jobs.Job;
+
+/**
+ * Notifies clients of the indexer state.
+ */
+class JobChangeListener implements IJobChangeListener {
+ private final PDOMManager fPDomManager;
+
+ JobChangeListener(PDOMManager pdomManager) {
+ fPDomManager= pdomManager;
+ }
+
+ public void aboutToRun(IJobChangeEvent event) {
+ }
+
+ public void awake(IJobChangeEvent event) {
+ }
+
+ public void done(IJobChangeEvent event) {
+ if (event.getJob().belongsTo(fPDomManager)) {
+ if (Job.getJobManager().find(fPDomManager).length == 0) {
+ fPDomManager.fireStateChange(IndexerStateEvent.STATE_IDLE);
+ }
+ }
+ }
+
+ public void running(IJobChangeEvent event) {
+ }
+
+ public void scheduled(IJobChangeEvent event) {
+ if (event.getJob().belongsTo(fPDomManager)) {
+ fPDomManager.fireStateChange(IndexerStateEvent.STATE_BUSY);
+ }
+ }
+ public void sleeping(IJobChangeEvent event) {
+ }
+
+}
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 79b9a39c3ed..e35b0797f71 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
@@ -20,15 +20,16 @@ import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
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.Set;
import java.util.regex.Pattern;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ILinkage;
-import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.IPDOMNode;
import org.eclipse.cdt.core.dom.IPDOMVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
@@ -45,7 +46,6 @@ import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.index.IIndexLinkage;
import org.eclipse.cdt.core.index.IIndexLocationConverter;
import org.eclipse.cdt.core.index.IIndexMacro;
-import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.internal.core.index.IIndexCBindingConstants;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
@@ -168,6 +168,30 @@ public class PDOM extends PlatformObject implements IPDOM {
assert END <= Database.CHUNK_SIZE;
}
+ public static class ChangeEvent {
+ public Set fClearedFiles= new HashSet();
+ public Set fFilesWritten= new HashSet();
+ public boolean fCleared= false;
+ public boolean fReloaded= false;
+
+ private void setCleared() {
+ fReloaded= false;
+ fCleared= true;
+ fClearedFiles.clear();
+ fFilesWritten.clear();
+ }
+
+ public void clear() {
+ fReloaded= fCleared= false;
+ fClearedFiles.clear();
+ fFilesWritten.clear();
+ }
+ }
+ public static interface IListener {
+ public void handleChange(PDOM pdom, ChangeEvent event);
+ }
+
+
// Local caches
protected Database db;
private BTree fileIndex;
@@ -177,8 +201,9 @@ public class PDOM extends PlatformObject implements IPDOM {
private IIndexLocationConverter locationConverter;
private Map fPDOMLinkageFactoryCache;
private HashMap fResultCache= new HashMap();
+ private List listeners;
+ protected ChangeEvent fEvent= new ChangeEvent();
-
public PDOM(File dbPath, IIndexLocationConverter locationConverter, Map linkageFactoryMappings) throws CoreException {
this(dbPath, locationConverter, ChunkCache.getSharedInstance(), linkageFactoryMappings);
}
@@ -231,12 +256,6 @@ public class PDOM extends PlatformObject implements IPDOM {
}
}
- public static interface IListener {
- public void handleChange(PDOM pdom);
- }
-
- private List listeners;
-
public void addListener(IListener listener) {
if (listeners == null)
listeners = new LinkedList();
@@ -249,12 +268,12 @@ public class PDOM extends PlatformObject implements IPDOM {
listeners.remove(listener);
}
- private void fireChange() {
+ private void fireChange(ChangeEvent event) {
if (listeners == null)
return;
Iterator i = listeners.iterator();
while (i.hasNext())
- i.next().handleChange(this);
+ i.next().handleChange(this, event);
}
public Database getDB() {
@@ -311,6 +330,7 @@ public class PDOM extends PlatformObject implements IPDOM {
// Clear out the database, everything is set to zero.
db.clear(CURRENT_VERSION);
clearCaches();
+ fEvent.setCleared();
}
void reloadFromFile(File file) throws CoreException {
@@ -325,42 +345,13 @@ public class PDOM extends PlatformObject implements IPDOM {
loadDatabase(file, db.getChunkCache());
db.setExclusiveLock();
oldFile.delete();
+ fEvent.fReloaded= true;
}
public boolean isEmpty() throws CoreException {
return getFirstLinkageRecord() == 0;
}
- /**
- * @deprecated use findDefinitions() instead
- */
- public IName[] getDefinitions(IBinding binding) throws CoreException {
- if (binding instanceof PDOMBinding) {
- List names = new ArrayList();
- for (PDOMName name = ((PDOMBinding)binding).getFirstDefinition();
- name != null;
- name = name.getNextInBinding())
- names.add(name);
- return names.toArray(new IIndexName[names.size()]);
- }
- return IIndexFragmentName.EMPTY_NAME_ARRAY;
- }
-
- /**
- * @deprecated use findReferences() instead
- */
- public IName[] getReferences(IBinding binding) throws CoreException {
- if (binding instanceof PDOMBinding) {
- List names = new ArrayList();
- for (PDOMName name = ((PDOMBinding)binding).getFirstReference();
- name != null;
- name = name.getNextInBinding())
- names.add(name);
- return names.toArray(new IIndexName[names.size()]);
- }
- return IIndexFragmentName.EMPTY_NAME_ARRAY;
- }
-
public IIndexFragmentBinding findBinding(IASTName name) throws CoreException {
PDOMLinkage linkage= adaptLinkage(name.getLinkage());
if (linkage != null) {
@@ -669,13 +660,15 @@ public class PDOM extends PlatformObject implements IPDOM {
}
assert lockCount == -1;
lastWriteAccess= System.currentTimeMillis();
+ final ChangeEvent event= fEvent;
+ fEvent= new ChangeEvent();
synchronized (mutex) {
if (lockCount < 0)
lockCount= establishReadLocks;
mutex.notifyAll();
db.setLocked(lockCount != 0);
}
- fireChange();
+ fireChange(event);
}
@@ -932,6 +925,7 @@ public class PDOM extends PlatformObject implements IPDOM {
IndexFilter filter= null;
if (binding instanceof IFunction) {
filter= new IndexFilter() {
+ @Override
public boolean acceptBinding(IBinding binding) {
try {
if (binding instanceof ICPPFunction) {
@@ -945,6 +939,7 @@ public class PDOM extends PlatformObject implements IPDOM {
} else if (binding instanceof IVariable) {
if (!(binding instanceof IField) && !(binding instanceof IParameter)) {
filter= new IndexFilter() {
+ @Override
public boolean acceptBinding(IBinding binding) {
try {
if (binding instanceof ICPPVariable) {
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 077149d3221..94c85b8e71b 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
@@ -143,12 +143,11 @@ public class PDOMManager implements IWritableIndexManager, IListener {
private static final ISchedulingRule INIT_INDEXER_SCHEDULING_RULE = new PerInstanceSchedulingRule();
/**
- * Protects indexerJob, currentTask and taskQueue.
+ * Protects fIndexerJob, fCurrentTask and fTaskQueue.
*/
- private Object fTaskQueueMutex = new Object();
+ private final LinkedList fTaskQueue = new LinkedList();
private PDOMIndexerJob fIndexerJob;
private IPDOMIndexerTask fCurrentTask;
- private LinkedList fTaskQueue = new LinkedList();
private int fSourceCount, fHeaderCount, fTickCount;
/**
@@ -165,6 +164,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
private CModelListener fCModelListener= new CModelListener(this);
private ILanguageMappingChangeListener fLanguageChangeListener = new LanguageMappingChangeListener(this);
private final ICProjectDescriptionListener fProjectDescriptionListener;
+ private final JobChangeListener fJobChangeListener;
private IndexFactory fIndexFactory= new IndexFactory(this);
private IndexProviderManager fIndexProviderManager = new IndexProviderManager();
@@ -178,9 +178,11 @@ public class PDOMManager implements IWritableIndexManager, IListener {
private HashMap fPrefListeners= new HashMap();
private ArrayList fSetupParticipants= new ArrayList();
private HashSet fPostponedProjects= new HashSet();
+ private int fLastNotifiedState= IndexerStateEvent.STATE_IDLE;
public PDOMManager() {
fProjectDescriptionListener= new CProjectDescriptionListener(this);
+ fJobChangeListener= new JobChangeListener(this);
}
public Job startup() {
@@ -207,7 +209,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
// order to avoid a race condition where its not noticed
// that new projects are being created
initializeDatabaseCache();
-
+ Job.getJobManager().addJobChangeListener(fJobChangeListener);
fIndexProviderManager.startup();
final CoreModel model = CoreModel.getDefault();
@@ -234,15 +236,16 @@ public class PDOMManager implements IWritableIndexManager, IListener {
ResourcesPlugin.getWorkspace().removeResourceChangeListener(fCModelListener);
LanguageManager.getInstance().unregisterLanguageChangeListener(fLanguageChangeListener);
PDOMIndexerJob jobToCancel= null;
- synchronized (fTaskQueueMutex) {
+ synchronized (fTaskQueue) {
fTaskQueue.clear();
jobToCancel= fIndexerJob;
}
if (jobToCancel != null) {
- assert !Thread.holdsLock(fTaskQueueMutex);
+ assert !Thread.holdsLock(fTaskQueue);
jobToCancel.cancelJobs(null, false);
}
+ Job.getJobManager().removeJobChangeListener(fJobChangeListener);
}
private void initializeDatabaseCache() {
@@ -589,7 +592,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
if (indexer != null) {
getReferencingProjects(indexer.getProject().getProject(), referencing);
}
- synchronized (fTaskQueueMutex) {
+ synchronized (fTaskQueue) {
int i=0;
for (Iterator it = fTaskQueue.iterator(); it.hasNext();) {
final IPDOMIndexerTask task= it.next();
@@ -608,7 +611,6 @@ public class PDOMManager implements IWritableIndexManager, IListener {
fIndexerJob = new PDOMIndexerJob(this);
fIndexerJob.setRule(INDEXER_SCHEDULING_RULE);
fIndexerJob.schedule();
- notifyState(IndexerStateEvent.STATE_BUSY);
}
}
}
@@ -626,11 +628,10 @@ public class PDOMManager implements IWritableIndexManager, IListener {
IPDOMIndexerTask getNextTask() {
IPDOMIndexerTask result= null;
- synchronized (fTaskQueueMutex) {
+ synchronized (fTaskQueue) {
if (fTaskQueue.isEmpty()) {
fCurrentTask= null;
fIndexerJob= null;
- notifyState(IndexerStateEvent.STATE_IDLE);
}
else {
if (fCurrentTask != null) {
@@ -647,14 +648,13 @@ public class PDOMManager implements IWritableIndexManager, IListener {
}
void cancelledJob(boolean byManager) {
- synchronized (fTaskQueueMutex) {
+ synchronized (fTaskQueue) {
fCurrentTask= null;
if (!byManager) {
fTaskQueue.clear();
}
if (fTaskQueue.isEmpty()) {
fIndexerJob= null;
- notifyState(IndexerStateEvent.STATE_IDLE);
}
else {
fIndexerJob = new PDOMIndexerJob(this);
@@ -857,7 +857,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
private void cancelIndexerJobs(IPDOMIndexer indexer) {
PDOMIndexerJob jobToCancel= null;
- synchronized (fTaskQueueMutex) {
+ synchronized (fTaskQueue) {
for (Iterator iter = fTaskQueue.iterator(); iter.hasNext();) {
IPDOMIndexerTask task= iter.next();
if (task.getIndexer() == indexer) {
@@ -868,7 +868,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
}
if (jobToCancel != null) {
- assert !Thread.holdsLock(fTaskQueueMutex);
+ assert !Thread.holdsLock(fTaskQueue);
jobToCancel.cancelJobs(indexer, true);
}
}
@@ -922,43 +922,43 @@ public class PDOMManager implements IWritableIndexManager, IListener {
fStateListeners.remove(listener);
}
- private void notifyState(final int state) {
- if (state == IndexerStateEvent.STATE_IDLE) {
- synchronized(fTaskQueueMutex) {
- fTaskQueueMutex.notifyAll();
+ void fireStateChange(final int state) {
+ synchronized(fStateListeners) {
+ if (fLastNotifiedState == state) {
+ return;
}
- }
-
- if (fStateListeners.isEmpty()) {
- return;
- }
- Job notify= new Job(Messages.PDOMManager_notifyJob_label) {
- @Override
- protected IStatus run(IProgressMonitor monitor) {
- fIndexerStateEvent.setState(state);
- Object[] listeners= fStateListeners.getListeners();
- monitor.beginTask(Messages.PDOMManager_notifyTask_message, listeners.length);
- for (int i = 0; i < listeners.length; i++) {
- final IIndexerStateListener listener = (IIndexerStateListener) listeners[i];
- SafeRunner.run(new ISafeRunnable(){
- public void handleException(Throwable exception) {
- CCorePlugin.log(exception);
- }
- public void run() throws Exception {
- listener.indexChanged(fIndexerStateEvent);
- }
- });
- monitor.worked(1);
+ fLastNotifiedState= state;
+ if (fStateListeners.isEmpty()) {
+ return;
+ }
+ Job notify= new Job(Messages.PDOMManager_notifyJob_label) {
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ fIndexerStateEvent.setState(state);
+ Object[] listeners= fStateListeners.getListeners();
+ monitor.beginTask(Messages.PDOMManager_notifyTask_message, listeners.length);
+ for (int i = 0; i < listeners.length; i++) {
+ final IIndexerStateListener listener = (IIndexerStateListener) listeners[i];
+ SafeRunner.run(new ISafeRunnable(){
+ public void handleException(Throwable exception) {
+ CCorePlugin.log(exception);
+ }
+ public void run() throws Exception {
+ listener.indexChanged(fIndexerStateEvent);
+ }
+ });
+ monitor.worked(1);
+ }
+ return Status.OK_STATUS;
}
- return Status.OK_STATUS;
- }
- };
- notify.setRule(NOTIFICATION_SCHEDULING_RULE);
- notify.setSystem(true);
- notify.schedule();
+ };
+ notify.setRule(NOTIFICATION_SCHEDULING_RULE);
+ notify.setSystem(true);
+ notify.schedule();
+ }
}
- public void handleChange(PDOM pdom) {
+ public void handleChange(PDOM pdom, final PDOM.ChangeEvent e) {
if (fChangeListeners.isEmpty()) {
return;
}
@@ -973,7 +973,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
Job notify= new Job(Messages.PDOMManager_notifyJob_label) {
@Override
protected IStatus run(IProgressMonitor monitor) {
- fIndexChangeEvent.setAffectedProject(finalProject);
+ fIndexChangeEvent.setAffectedProject(finalProject, e);
Object[] listeners= fChangeListeners.getListeners();
monitor.beginTask(Messages.PDOMManager_notifyTask_message, listeners.length);
for (int i = 0; i < listeners.length; i++) {
@@ -1032,11 +1032,11 @@ public class PDOMManager implements IWritableIndexManager, IListener {
}
int getMonitorMessage(IProgressMonitor monitor, int currentTicks, int base) {
- assert !Thread.holdsLock(fTaskQueueMutex);
+ assert !Thread.holdsLock(fTaskQueue);
int sourceCount, sourceEstimate, headerCount, tickCount, tickEstimate;
String detail= null;
- synchronized (fTaskQueueMutex) {
+ synchronized (fTaskQueue) {
// add historic data
sourceCount= sourceEstimate= fSourceCount;
headerCount= fHeaderCount;
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 9dd5700c700..3c33b386b54 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
@@ -26,6 +26,7 @@ import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
import org.eclipse.cdt.internal.core.index.IIndexFragmentFileSet;
import org.eclipse.cdt.internal.core.index.IIndexFragmentInclude;
import org.eclipse.cdt.internal.core.index.IIndexFragmentName;
+import org.eclipse.cdt.internal.core.pdom.PDOM.ChangeEvent;
import org.eclipse.cdt.internal.core.pdom.PDOM.IListener;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.core.runtime.CoreException;
@@ -214,9 +215,11 @@ public class PDOMProxy implements IPDOM {
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
+ ChangeEvent event= new ChangeEvent();
+ event.fReloaded= true;
for (Iterator iterator = fListeners.iterator(); iterator.hasNext();) {
IListener listener = iterator.next();
- listener.handleChange(fDelegate);
+ listener.handleChange(fDelegate, event);
}
}
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 ccdc925d16f..ebac516694c 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
@@ -9,7 +9,6 @@
* Markus Schorn - initial API and implementation
* Andrew Ferguson (Symbian)
*******************************************************************************/
-
package org.eclipse.cdt.internal.core.pdom;
import java.io.File;
@@ -75,11 +74,17 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
finally {
fPathResolver= origResolver;
}
+
+ final IIndexFileLocation location = pdomFile.getLocation();
+ fEvent.fClearedFiles.remove(location);
+ fEvent.fFilesWritten.add(location);
}
public void clearFile(IIndexFragmentFile file, Collection contextsRemoved) throws CoreException {
assert file.getIndexFragment() == this;
- ((PDOMFile) file).clear(contextsRemoved);
+ ((PDOMFile) file).clear(contextsRemoved);
+
+ fEvent.fClearedFiles.add(file.getLocation());
}
@Override
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 7e3f765d90c..0bd4595e8ce 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
@@ -52,6 +52,7 @@ import org.eclipse.core.runtime.CoreException;
public class PDOMFile implements IIndexFragmentFile {
private final PDOM pdom;
private final int record;
+ private IIndexFileLocation location;
private static final int FIRST_NAME = 0;
private static final int FIRST_INCLUDE = 4;
@@ -90,6 +91,7 @@ public class PDOMFile implements IIndexFragmentFile {
public PDOMFile(PDOM pdom, IIndexFileLocation location, int linkageID) throws CoreException {
this.pdom = pdom;
+ this.location= location;
Database db = pdom.getDB();
record = db.malloc(RECORD_SIZE);
String locationString = pdom.getLocationConverter().toInternalFormat(location);
@@ -109,6 +111,7 @@ public class PDOMFile implements IIndexFragmentFile {
return record;
}
+ @Override
public boolean equals(Object obj) {
if (obj == this)
return true;
@@ -119,6 +122,7 @@ public class PDOMFile implements IIndexFragmentFile {
return false;
}
+ @Override
public final int hashCode() {
return System.identityHashCode(pdom) + 41*record;
}
@@ -135,6 +139,7 @@ public class PDOMFile implements IIndexFragmentFile {
int oldRecord = db.getInt(record + LOCATION_REPRESENTATION);
db.free(oldRecord);
db.putInt(record + LOCATION_REPRESENTATION, db.newString(internalLocation).getRecord());
+ location= null;
}
public int getLinkageID() throws CoreException {
@@ -491,12 +496,14 @@ public class PDOMFile implements IIndexFragmentFile {
}
public IIndexFileLocation getLocation() throws CoreException {
- Database db = pdom.getDB();
- String raw = db.getString(db.getInt(record + LOCATION_REPRESENTATION)).getString();
- IIndexFileLocation result = pdom.getLocationConverter().fromInternalFormat(raw);
- if(result==null)
- throw new CoreException(CCorePlugin.createStatus(Messages.getString("PDOMFile.toExternalProblem")+raw)); //$NON-NLS-1$
- return result;
+ if (location == null) {
+ Database db = pdom.getDB();
+ String raw = db.getString(db.getInt(record + LOCATION_REPRESENTATION)).getString();
+ location= pdom.getLocationConverter().fromInternalFormat(raw);
+ if(location==null)
+ throw new CoreException(CCorePlugin.createStatus(Messages.getString("PDOMFile.toExternalProblem")+raw)); //$NON-NLS-1$
+ }
+ return location;
}
public boolean hasContent() throws CoreException {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/TriggerNotificationTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/TriggerNotificationTask.java
index d7b7d9eb101..b97cd66487d 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/TriggerNotificationTask.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/TriggerNotificationTask.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 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
@@ -15,8 +15,13 @@ import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
import org.eclipse.cdt.internal.core.pdom.IndexerProgress;
import org.eclipse.cdt.internal.core.pdom.PDOMManager;
import org.eclipse.cdt.internal.core.pdom.WritablePDOM;
+import org.eclipse.cdt.internal.core.pdom.PDOM.ChangeEvent;
import org.eclipse.core.runtime.IProgressMonitor;
+/**
+ * Used to trigger a change notification when a pdom is loaded.
+ * In this situation the pdom itself does not generate a notification.
+ */
public class TriggerNotificationTask implements IPDOMIndexerTask {
private WritablePDOM fPDOM;
@@ -36,6 +41,8 @@ public class TriggerNotificationTask implements IPDOMIndexerTask {
}
public void run(IProgressMonitor monitor) {
- fManager.handleChange(fPDOM);
+ ChangeEvent event= new ChangeEvent();
+ event.fReloaded= true;
+ fManager.handleChange(fPDOM, event);
}
}
diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CallHierarchyAcrossProjectsTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CallHierarchyAcrossProjectsTest.java
index 72c623ede28..716079a134e 100644
--- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CallHierarchyAcrossProjectsTest.java
+++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CallHierarchyAcrossProjectsTest.java
@@ -280,9 +280,10 @@ public class CallHierarchyAcrossProjectsTest extends CallHierarchyBaseTest {
openCallHierarchy(editor, false);
TreeViewer tv = getCHTreeViewer();
- TreeItem item= checkTreeNode(tv.getTree(), 0, "main()");
- TreeItem nextItem= checkTreeNode(item, 0, "MyClass::method1()");
- checkTreeNode(item, 1, null); item= nextItem;
+ final Tree tree = tv.getTree();
+ checkTreeNode(tree, 0, "main()");
+ TreeItem item= checkTreeNode(tree, 0, 0, "MyClass::method1()");
+ checkTreeNode(tree, 0, 1, null);
tv.setExpandedState(item.getData(), true);
TreeItem item0= checkTreeNode(item, 0, "MyClass::method1()");
@@ -291,7 +292,7 @@ public class CallHierarchyAcrossProjectsTest extends CallHierarchyBaseTest {
try {
tv.setExpandedState(item0.getData(), true);
- nextItem= checkTreeNode(item0, 0, "MyClass::method2()");
+ checkTreeNode(item0, 0, "MyClass::method2()");
}
catch (Throwable e) {
TreeItem tmp= item0; item0= item1; item1= tmp;
@@ -299,7 +300,7 @@ public class CallHierarchyAcrossProjectsTest extends CallHierarchyBaseTest {
// method 1
tv.setExpandedState(item0.getData(), true);
- nextItem= checkTreeNode(item0, 0, "MyClass::method2()");
+ TreeItem nextItem= checkTreeNode(item0, 0, "MyClass::method2()");
checkTreeNode(item0, 1, null); item0= nextItem;
tv.setExpandedState(item0.getData(), true);
checkTreeNode(item0, 0, null);
@@ -311,5 +312,4 @@ public class CallHierarchyAcrossProjectsTest extends CallHierarchyBaseTest {
tv.setExpandedState(item1.getData(), true);
checkTreeNode(item1, 0, null);
}
-
}
diff --git a/core/org.eclipse.cdt.ui/icons/ovr16/indexedFile.gif b/core/org.eclipse.cdt.ui/icons/ovr16/indexedFile.gif
new file mode 100644
index 00000000000..9b4c11c4572
Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/ovr16/indexedFile.gif differ
diff --git a/core/org.eclipse.cdt.ui/plugin.properties b/core/org.eclipse.cdt.ui/plugin.properties
index 5d088da9112..92038b04d7d 100644
--- a/core/org.eclipse.cdt.ui/plugin.properties
+++ b/core/org.eclipse.cdt.ui/plugin.properties
@@ -454,3 +454,5 @@ OccurrenceAnnotation.label= C/C++ Occurrences
DocCommentOwner.name = DocCommentOwner
Doxygen.name = Doxygen
+
+indexedFilesDecorator.label = C/C++ Indexed Files
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml
index d9e82604f89..f4db8b8f54d 100644
--- a/core/org.eclipse.cdt.ui/plugin.xml
+++ b/core/org.eclipse.cdt.ui/plugin.xml
@@ -2548,4 +2548,20 @@
singleline="org.eclipse.cdt.ui.text.doctools.doxygen.DoxygenSingleConfiguration">
+
+
+
+
+
+
+
+
+
+
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/IndexView.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/IndexView.java
index e2d38f7bb79..e44c215e80c 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/IndexView.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/IndexView.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 QNX Software Systems and others.
+ * Copyright (c) 2005, 2008 QNX Software Systems 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
@@ -80,7 +80,7 @@ public class IndexView extends ViewPart implements PDOM.IListener, IElementChang
Filter filter = new Filter();
public boolean isLinking = false;
private volatile boolean fUpdateRequested= false;
- private Map fTimestampPerProject= new HashMap();
+ private Map fTimestampPerProject= new HashMap();
private IndexContentProvider contentProvider;
@@ -112,6 +112,7 @@ public class IndexView extends ViewPart implements PDOM.IListener, IElementChang
private static class Filter extends ViewerFilter {
public boolean showExternalDefs = false;
+ @Override
public boolean select(Viewer viewer, Object parentElement, Object element) {
if (element instanceof IndexNode) {
IndexNode node= (IndexNode)element;
@@ -151,9 +152,9 @@ public class IndexView extends ViewPart implements PDOM.IListener, IElementChang
}
private static class Children implements IPDOMVisitor {
- private ArrayList fNodes;
+ private ArrayList fNodes;
public Children() {
- fNodes= new ArrayList();
+ fNodes= new ArrayList();
}
public boolean visit(IPDOMNode node) throws CoreException {
fNodes.add(node);
@@ -162,7 +163,7 @@ public class IndexView extends ViewPart implements PDOM.IListener, IElementChang
public void leave(IPDOMNode node) throws CoreException {
}
public IPDOMNode[] getNodes() {
- return (IPDOMNode[]) fNodes.toArray(new IPDOMNode[fNodes.size()]);
+ return fNodes.toArray(new IPDOMNode[fNodes.size()]);
}
}
@@ -171,6 +172,7 @@ public class IndexView extends ViewPart implements PDOM.IListener, IElementChang
super(disp);
}
+ @Override
public Object getParent(Object element) {
if (element instanceof IndexNode) {
return ((IndexNode) element).fParent;
@@ -181,6 +183,7 @@ public class IndexView extends ViewPart implements PDOM.IListener, IElementChang
return null;
}
+ @Override
protected Object[] syncronouslyComputeChildren(Object parentElement) {
if (parentElement instanceof ICModel) {
ICModel element = (ICModel) parentElement;
@@ -205,6 +208,7 @@ public class IndexView extends ViewPart implements PDOM.IListener, IElementChang
}
+ @Override
protected Object[] asyncronouslyComputeChildren(Object parentElement, IProgressMonitor monitor) {
try {
if (parentElement instanceof ICProject) {
@@ -218,7 +222,7 @@ public class IndexView extends ViewPart implements PDOM.IListener, IElementChang
IndexNode node= (IndexNode) parentElement;
ICProject cproject= node.getProject();
if (cproject != null && cproject.getProject().isOpen()) {
- Long ts= (Long) fTimestampPerProject.get(cproject.getElementName());
+ Long ts= fTimestampPerProject.get(cproject.getElementName());
IPDOM pdom= CCoreInternals.getPDOMManager().getPDOM(cproject);
pdom.acquireReadLock();
try {
@@ -283,6 +287,7 @@ public class IndexView extends ViewPart implements PDOM.IListener, IElementChang
}
}
+ @Override
public void createPartControl(Composite parent) {
viewer = new ExtendedTreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
contentProvider= new IndexContentProvider(getSite().getShell().getDisplay());
@@ -333,6 +338,7 @@ public class IndexView extends ViewPart implements PDOM.IListener, IElementChang
});
}
+ @Override
public void dispose() {
super.dispose();
ICModel model = CoreModel.getDefault().getCModel();
@@ -404,11 +410,12 @@ public class IndexView extends ViewPart implements PDOM.IListener, IElementChang
manager.add(discardExternalDefsAction);
}
+ @Override
public void setFocus() {
viewer.getControl().setFocus();
}
- public void handleChange(PDOM pdom) {
+ public void handleChange(PDOM pdom, PDOM.ChangeEvent e) {
requestUpdate();
}
@@ -450,19 +457,19 @@ public class IndexView extends ViewPart implements PDOM.IListener, IElementChang
try {
IPDOM pdom = CCoreInternals.getPDOMManager().getPDOM((ICProject)delta.getElement());
pdom.addListener(this);
- handleChange(null);
+ handleChange(null, null);
} catch (CoreException e) {
}
break;
case ICElementDelta.REMOVED:
- handleChange(null);
+ handleChange(null, null);
break;
}
}
}
public long getLastWriteAccess(ICProject cproject) {
- Long result= (Long) fTimestampPerProject.get(cproject.getElementName());
+ Long result= fTimestampPerProject.get(cproject.getElementName());
return result == null ? -1 : result.longValue();
}
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexedFilesCache.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexedFilesCache.java
new file mode 100644
index 00000000000..c44c97d3498
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexedFilesCache.java
@@ -0,0 +1,276 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.ui.viewsupport;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+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.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.LabelProviderChangedEvent;
+import org.eclipse.swt.SWTException;
+import org.eclipse.ui.IDecoratorManager;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PlatformUI;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.index.IIndex;
+import org.eclipse.cdt.core.index.IIndexChangeEvent;
+import org.eclipse.cdt.core.index.IIndexChangeListener;
+import org.eclipse.cdt.core.index.IIndexFile;
+import org.eclipse.cdt.core.index.IIndexFileLocation;
+import org.eclipse.cdt.core.index.IIndexManager;
+import org.eclipse.cdt.core.index.IIndexerStateEvent;
+import org.eclipse.cdt.core.index.IIndexerStateListener;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ICProject;
+
+class IndexedFilesCache implements IIndexChangeListener, IIndexerStateListener, ILabelProviderListener {
+ private static final String DECORATOR_ID = "org.eclipse.cdt.ui.indexedFiles"; //$NON-NLS-1$
+ private static final IndexedFilesCache INSTANCE = new IndexedFilesCache();
+ private static final ISchedulingRule RULE = new ISchedulingRule() {
+ public boolean contains(ISchedulingRule rule) {
+ return rule == this;
+ }
+ public boolean isConflicting(ISchedulingRule rule) {
+ return rule == this;
+ }
+ };
+
+ public static IndexedFilesCache getInstance() {
+ return INSTANCE;
+ }
+
+ private final HashMap> fIndexedFiles= new HashMap>();
+ private boolean fIsDirty= false;
+ private boolean fActive= false;
+
+ private void scheduleInitialize() {
+ Job j= new Job(Messages.IndexedFilesCache_jobName) {
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ try {
+ ICProject[] prj= CoreModel.getDefault().getCModel().getCProjects();
+ for (ICProject project : prj) {
+ initialize(project);
+ }
+ } catch (CoreException e) {
+ return e.getStatus();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return Status.CANCEL_STATUS;
+ }
+ checkTriggerDecorator(1);
+ return Status.OK_STATUS;
+ }
+ @Override
+ public boolean belongsTo(Object family) {
+ return family == IndexedFilesCache.this;
+ }
+
+ };
+ j.setSystem(true);
+ j.setRule(RULE);
+ j.schedule();
+ }
+
+ private void scheduleInitialize(final ICProject project) {
+ Job j= new Job(Messages.IndexedFilesCache_jobName) {
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ try {
+ initialize(project);
+ } catch (CoreException e) {
+ return e.getStatus();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return Status.CANCEL_STATUS;
+ }
+ checkTriggerDecorator(1);
+ return Status.OK_STATUS;
+ }
+ @Override
+ public boolean belongsTo(Object family) {
+ return family == IndexedFilesCache.this;
+ }
+ };
+ j.setSystem(true);
+ j.setRule(RULE);
+ j.schedule();
+ }
+
+ final protected void initialize(ICProject prj) throws CoreException, InterruptedException {
+ IIndex index= CCorePlugin.getIndexManager().getIndex(prj, 0);
+ List list= new ArrayList();
+ index.acquireReadLock();
+ try {
+ IIndexFile[] files= index.getAllFiles();
+ for (IIndexFile ifile : files) {
+ if (ifile.getTimestamp() >= 0) {
+ list.add(ifile.getLocation());
+ }
+ }
+ if (!list.isEmpty()) {
+ final String prjName= prj.getElementName();
+ synchronized(fIndexedFiles) {
+ Set cache= fIndexedFiles.get(prjName);
+ if (cache == null) {
+ cache= new HashSet();
+ fIndexedFiles.put(prjName, cache);
+ }
+ else {
+ if (!cache.isEmpty()) {
+ cache.clear();
+ fIsDirty= true;
+ }
+ }
+ for (IIndexFileLocation ifl: list) {
+ final int h= computeHash(ifl);
+ if (cache.add(h)) {
+ fIsDirty= true;
+ }
+ }
+ }
+ }
+ }
+ finally {
+ index.releaseReadLock();
+ }
+ }
+
+ public void indexChanged(IIndexChangeEvent e) {
+ // the index manager has reported a change to an index
+ ICProject cproject= e.getAffectedProject();
+ if (cproject == null) {
+ return;
+ }
+ synchronized (fIndexedFiles) {
+ if (!fActive) {
+ return;
+ }
+ if (e.isReloaded()) {
+ scheduleInitialize(cproject);
+ }
+ else {
+ final String prjName = cproject.getElementName();
+ if (e.isCleared()) {
+ if (fIndexedFiles.remove(prjName) != null) {
+ fIsDirty= true;
+ }
+ }
+ final Set filesCleared = e.getFilesCleared();
+ final Set filesWritten = e.getFilesWritten();
+ if (!(filesCleared.isEmpty() && filesWritten.isEmpty())) {
+ Set cache= fIndexedFiles.get(prjName);
+ if (cache == null) {
+ cache= new HashSet();
+ fIndexedFiles.put(prjName, cache);
+ }
+ for (IIndexFileLocation ifl: filesCleared) {
+ final int h= computeHash(ifl);
+ if (cache.remove(h)) {
+ fIsDirty= true;
+ }
+ }
+ for (IIndexFileLocation ifl: filesWritten) {
+ final int h= computeHash(ifl);
+ if (cache.add(h)) {
+ fIsDirty= true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void indexChanged(IIndexerStateEvent event) {
+ if (event.indexerIsIdle()) {
+ checkTriggerDecorator(0);
+ }
+ }
+
+ private void activate() {
+ synchronized (fIndexedFiles) {
+ fActive= true;
+ PlatformUI.getWorkbench().getDecoratorManager().addListener(this);
+ final IIndexManager indexManager = CCorePlugin.getIndexManager();
+ indexManager.addIndexChangeListener(IndexedFilesCache.this);
+ indexManager.addIndexerStateListener(IndexedFilesCache.this);
+ scheduleInitialize();
+ }
+ }
+
+ private void deactivate() {
+ synchronized (fIndexedFiles) {
+ fActive= false;
+ fIndexedFiles.clear();
+ final IIndexManager indexManager = CCorePlugin.getIndexManager();
+ indexManager.removeIndexChangeListener(IndexedFilesCache.this);
+ indexManager.removeIndexerStateListener(IndexedFilesCache.this);
+ PlatformUI.getWorkbench().getDecoratorManager().removeListener(this);
+ }
+ }
+
+
+ final protected void checkTriggerDecorator(int jobCount) {
+ if (fIsDirty && CCorePlugin.getIndexManager().isIndexerIdle() &&
+ Job.getJobManager().find(this).length == jobCount) {
+ fIsDirty= false;
+ final IWorkbench workbench= PlatformUI.getWorkbench();
+ try {
+ workbench.getDisplay().asyncExec(new Runnable(){
+ public void run() {
+ workbench.getDecoratorManager().update(DECORATOR_ID);
+ }
+ });
+ }
+ catch (SWTException e) {
+ // in case the display is no longer valid
+ }
+ }
+ }
+
+ public boolean isIndexed(IProject project, IIndexFileLocation ifl) {
+ // request from a label provider
+ synchronized(fIndexedFiles) {
+ if (!fActive) {
+ activate();
+ }
+ Set cache= fIndexedFiles.get(project.getName());
+ return cache != null && cache.contains(computeHash(ifl));
+ }
+ }
+
+ private int computeHash(IIndexFileLocation ifl) {
+ final String fp= ifl.getFullPath();
+ final int h1= fp == null ? 0 : fp.hashCode() * 43;
+ return h1 + ifl.getURI().hashCode();
+ }
+
+ public void labelProviderChanged(LabelProviderChangedEvent event) {
+ final Object src= event.getSource();
+ if (src instanceof IDecoratorManager) {
+ IDecoratorManager mng= (IDecoratorManager) src;
+ if (!mng.getEnabled(DECORATOR_ID)) {
+ deactivate();
+ }
+ }
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexedFilesLabelProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexedFilesLabelProvider.java
new file mode 100644
index 00000000000..831844257cd
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexedFilesLabelProvider.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.ui.viewsupport;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.IDecoration;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ILightweightLabelDecorator;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+import org.eclipse.cdt.core.index.IIndexFileLocation;
+import org.eclipse.cdt.core.index.IndexLocationFactory;
+import org.eclipse.cdt.core.model.ITranslationUnit;
+import org.eclipse.cdt.ui.CUIPlugin;
+
+/**
+ * A label provider that marks all translation units that are currently part of the index.
+ */
+public class IndexedFilesLabelProvider implements ILightweightLabelDecorator {
+ private static final ImageDescriptor INDEXED=
+ AbstractUIPlugin.imageDescriptorFromPlugin(CUIPlugin.PLUGIN_ID, "$nl$/icons/ovr16/indexedFile.gif"); //$NON-NLS-1$
+
+ public IndexedFilesLabelProvider() {
+ }
+
+ public void addListener(ILabelProviderListener listener) {
+ }
+
+ public void dispose() {
+ }
+
+ public boolean isLabelProperty(Object element, String property) {
+ return false;
+ }
+
+ public void removeListener(ILabelProviderListener listener) {
+ }
+
+ /**
+ * Adds the linked resource overlay if the given element is a linked
+ * resource.
+ *
+ * @param element element to decorate
+ * @param decoration The decoration we are adding to
+ * @see org.eclipse.jface.viewers.ILightweightLabelDecorator#decorate(Object, IDecoration)
+ */
+ public void decorate(Object element, IDecoration decoration) {
+ IIndexFileLocation ifl= null;
+ IProject project= null;
+ if (element instanceof IFile) {
+ final IFile file = (IFile) element;
+ ifl= IndexLocationFactory.getWorkspaceIFL(file);
+ project= file.getProject();
+ }
+ else if (element instanceof ITranslationUnit) {
+ final ITranslationUnit tu = (ITranslationUnit) element;
+ ifl= IndexLocationFactory.getIFL(tu);
+ project= tu.getCProject().getProject();
+ }
+ if (isIndexed(project, ifl)) {
+ decoration.addOverlay(INDEXED, IDecoration.TOP_LEFT);
+ }
+ }
+
+ private boolean isIndexed(IProject project, IIndexFileLocation ifl) {
+ if (project == null || ifl == null) {
+ return false;
+ }
+
+ return IndexedFilesCache.getInstance().isIndexed(project, ifl);
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/Messages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/Messages.java
index 7230e5dfd6c..3dfdba03aa8 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/Messages.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/Messages.java
@@ -14,6 +14,7 @@ import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.ui.viewsupport.messages"; //$NON-NLS-1$
+ public static String IndexedFilesCache_jobName;
public static String IndexUI_infoNotInIndex;
public static String IndexUI_infoNotInSource;
public static String IndexUI_infoSelectIndexAllFiles;
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/messages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/messages.properties
index f672ee384a2..52402c7d06f 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/messages.properties
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/messages.properties
@@ -8,6 +8,7 @@
# Contributors:
# Markus Schorn - initial API and implementation
################################################################################
+IndexedFilesCache_jobName=Initialize C/C++ Index Label Provider
IndexUI_infoNotInSource=The element ''{0}'' does not belong to a source file.
IndexUI_infoNotInIndex=The file ''{0}'' is currently not part of the index.
IndexUI_infoSelectIndexAllFiles=For headers that are never included, or sources that are not part of the build, consider selecting the preference 'Index all files'.