mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
LabelProvider to decorate indexed files, bug 159731.
This commit is contained in:
parent
41becf515a
commit
8c248ed68b
20 changed files with 636 additions and 135 deletions
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
* <p>
|
||||
* <strong>EXPERIMENTAL</strong>. 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 <code>true</code> when the index for the project was loaded for the first time or
|
||||
* reloaded with a different database.
|
||||
*/
|
||||
public boolean isReloaded();
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> 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 <code>true</code>, the set will be empty.
|
||||
*/
|
||||
public Set<IIndexFileLocation> getFilesCleared();
|
||||
|
||||
/**
|
||||
* Returns the set of files that has been added or updated. When {@link #isCleared()} returns
|
||||
* <code>true</code>, the files of the set have been written after the index was cleared.
|
||||
*/
|
||||
public Set<IIndexFileLocation> getFilesWritten();
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
* <p>
|
||||
* <strong>EXPERIMENTAL</strong>. This class or interface has been added as
|
||||
* part of a work in progress. There is no guarantee that this API will work or
|
||||
|
|
|
@ -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<IIndexFileLocation> getFilesCleared() {
|
||||
return fChangeEvent.fClearedFiles;
|
||||
}
|
||||
|
||||
public Set<IIndexFileLocation> getFilesWritten() {
|
||||
return fChangeEvent.fFilesWritten;
|
||||
}
|
||||
|
||||
public boolean isCleared() {
|
||||
return fChangeEvent.fCleared;
|
||||
}
|
||||
|
||||
public boolean isReloaded() {
|
||||
return fChangeEvent.fReloaded;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
|
||||
}
|
|
@ -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<IIndexFileLocation> fClearedFiles= new HashSet<IIndexFileLocation>();
|
||||
public Set<IIndexFileLocation> fFilesWritten= new HashSet<IIndexFileLocation>();
|
||||
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,7 +201,8 @@ public class PDOM extends PlatformObject implements IPDOM {
|
|||
private IIndexLocationConverter locationConverter;
|
||||
private Map<String, IPDOMLinkageFactory> fPDOMLinkageFactoryCache;
|
||||
private HashMap<Object, Object> fResultCache= new HashMap<Object, Object>();
|
||||
|
||||
private List<IListener> listeners;
|
||||
protected ChangeEvent fEvent= new ChangeEvent();
|
||||
|
||||
public PDOM(File dbPath, IIndexLocationConverter locationConverter, Map<String, IPDOMLinkageFactory> 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<IListener> listeners;
|
||||
|
||||
public void addListener(IListener listener) {
|
||||
if (listeners == null)
|
||||
listeners = new LinkedList<IListener>();
|
||||
|
@ -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<IListener> 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<PDOMName> names = new ArrayList<PDOMName>();
|
||||
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<PDOMName> names = new ArrayList<PDOMName>();
|
||||
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) {
|
||||
|
|
|
@ -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<IPDOMIndexerTask> fTaskQueue = new LinkedList<IPDOMIndexerTask>();
|
||||
private PDOMIndexerJob fIndexerJob;
|
||||
private IPDOMIndexerTask fCurrentTask;
|
||||
private LinkedList<IPDOMIndexerTask> fTaskQueue = new LinkedList<IPDOMIndexerTask>();
|
||||
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<IProject, PCL> fPrefListeners= new HashMap<IProject, PCL>();
|
||||
private ArrayList<IndexerSetupParticipant> fSetupParticipants= new ArrayList<IndexerSetupParticipant>();
|
||||
private HashSet<ICProject> fPostponedProjects= new HashSet<ICProject>();
|
||||
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<IPDOMIndexerTask> 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<IPDOMIndexerTask> 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;
|
||||
|
|
|
@ -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<IListener> iterator = fListeners.iterator(); iterator.hasNext();) {
|
||||
IListener listener = iterator.next();
|
||||
listener.handleChange(fDelegate);
|
||||
listener.handleChange(fDelegate, event);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<IIndexFileLocation> contextsRemoved) throws CoreException {
|
||||
assert file.getIndexFragment() == this;
|
||||
((PDOMFile) file).clear(contextsRemoved);
|
||||
|
||||
fEvent.fClearedFiles.add(file.getLocation());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
BIN
core/org.eclipse.cdt.ui/icons/ovr16/indexedFile.gif
Normal file
BIN
core/org.eclipse.cdt.ui/icons/ovr16/indexedFile.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 828 B |
|
@ -454,3 +454,5 @@ OccurrenceAnnotation.label= C/C++ Occurrences
|
|||
|
||||
DocCommentOwner.name = DocCommentOwner
|
||||
Doxygen.name = Doxygen
|
||||
|
||||
indexedFilesDecorator.label = C/C++ Indexed Files
|
|
@ -2548,4 +2548,20 @@
|
|||
singleline="org.eclipse.cdt.ui.text.doctools.doxygen.DoxygenSingleConfiguration">
|
||||
</owner>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.decorators">
|
||||
<decorator
|
||||
class="org.eclipse.cdt.internal.ui.viewsupport.IndexedFilesLabelProvider"
|
||||
id="org.eclipse.cdt.ui.indexedFiles"
|
||||
label="%indexedFilesDecorator.label"
|
||||
lightweight="true"
|
||||
state="false">
|
||||
<enablement>
|
||||
<or>
|
||||
<objectClass name="org.eclipse.cdt.core.model.ITranslationUnit"/>
|
||||
<objectClass name="org.eclipse.core.resources.IFile"/>
|
||||
</or>
|
||||
</enablement>
|
||||
</decorator>
|
||||
</extension>
|
||||
</plugin>
|
||||
|
|
|
@ -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<String, Long> fTimestampPerProject= new HashMap<String, Long>();
|
||||
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<IPDOMNode> fNodes;
|
||||
public Children() {
|
||||
fNodes= new ArrayList();
|
||||
fNodes= new ArrayList<IPDOMNode>();
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<String, Set<Integer>> fIndexedFiles= new HashMap<String, Set<Integer>>();
|
||||
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<IIndexFileLocation> list= new ArrayList<IIndexFileLocation>();
|
||||
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<Integer> cache= fIndexedFiles.get(prjName);
|
||||
if (cache == null) {
|
||||
cache= new HashSet<Integer>();
|
||||
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<IIndexFileLocation> filesCleared = e.getFilesCleared();
|
||||
final Set<IIndexFileLocation> filesWritten = e.getFilesWritten();
|
||||
if (!(filesCleared.isEmpty() && filesWritten.isEmpty())) {
|
||||
Set<Integer> cache= fIndexedFiles.get(prjName);
|
||||
if (cache == null) {
|
||||
cache= new HashSet<Integer>();
|
||||
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<Integer> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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'.
|
||||
|
|
Loading…
Add table
Reference in a new issue