diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/ITypeReference.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/ITypeReference.java index 5b38e15ef8f..67db865b49d 100644 --- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/ITypeReference.java +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/ITypeReference.java @@ -86,4 +86,6 @@ public interface ITypeReference { * given path. */ public IPath getRelativePath(IPath relativeToPath); + + boolean isLineNumber(); } diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/TypeInfo.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/TypeInfo.java index b575a4e94a7..a703be2af53 100644 --- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/TypeInfo.java +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/TypeInfo.java @@ -60,7 +60,9 @@ public class TypeInfo implements ITypeInfo public ITypeReference getResolvedReference() { for (int i = 0; i < fSourceRefsCount; ++i) { ITypeReference location = fSourceRefs[i]; - if (location.getLength() != 0) { + if (location.isLineNumber() ) + return location; + if( location.getLength() != 0) { return location; } } diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/TypeReference.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/TypeReference.java index 4128e243bca..059d330e5e8 100644 --- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/TypeReference.java +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/TypeReference.java @@ -28,6 +28,7 @@ public class TypeReference implements ITypeReference { private IWorkingCopy fWorkingCopy; private int fOffset; private int fLength; + public boolean offsetIsLineNumber = false; public TypeReference(IPath path, IProject project, int offset, int length) { fPath = path; @@ -170,7 +171,13 @@ public class TypeReference implements ITypeReference { ITranslationUnit unit = getTranslationUnit(); if (unit != null) { try { - return unit.getElementsAtOffset(fOffset); + if( offsetIsLineNumber ) + { + ICElement [] result = new ICElement[1]; + result[0] = unit.getElementAtLine(fOffset); + return result; + } + return unit.getElementsAtOffset(fOffset); } catch (CModelException e) { } } @@ -230,4 +237,8 @@ public class TypeReference implements ITypeReference { ITypeReference ref = (ITypeReference)obj; return toString().equals(ref.toString()); } + + public boolean isLineNumber() { + return offsetIsLineNumber; + } } diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/IndexerDependenciesJob2.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/IndexerDependenciesJob2.java new file mode 100644 index 00000000000..6a87fe541b7 --- /dev/null +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/IndexerDependenciesJob2.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.browser.cache; + +import java.io.IOException; + +import org.eclipse.cdt.core.browser.ITypeSearchScope; +import org.eclipse.cdt.core.browser.PathUtil; +import org.eclipse.cdt.internal.core.index.IEntryResult; +import org.eclipse.cdt.internal.core.index.IIndex; +import org.eclipse.cdt.internal.core.index.cindexstorage.Index; +import org.eclipse.cdt.internal.core.index.cindexstorage.IndexedFileEntry; +import org.eclipse.cdt.internal.core.index.cindexstorage.io.BlocksIndexInput; +import org.eclipse.cdt.internal.core.index.cindexstorage.io.IndexInput; +import org.eclipse.cdt.internal.core.search.indexing.IndexManager; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; + +public class IndexerDependenciesJob2 extends IndexerJob2 { + + private ITypeCache fTypeCache; + private ITypeSearchScope fScope; + + public IndexerDependenciesJob2(IndexManager indexManager, ITypeCache typeCache, ITypeSearchScope scope) { + super(indexManager, typeCache.getProject()); + fTypeCache = typeCache; + fScope = scope; + } + + protected boolean processIndex(IProgressMonitor progressMonitor) throws InterruptedException { + IndexInput input = new BlocksIndexInput(fProjectIndex.getIndexFile()); + try { + input.open(); + flushDependencies(input, progressMonitor); + return true; + } catch (IOException e) { + return false; + } finally { + try { + input.close(); + } catch (IOException e) { + return false; + } + } + } + + private void flushDependencies(IndexInput input, IProgressMonitor progressMonitor) + throws InterruptedException, IOException { + if (progressMonitor.isCanceled()) + throw new InterruptedException(); + + IEntryResult[] includeEntries = input.queryEntriesPrefixedBy(Index.encodeEntry(IIndex.INCLUDE, IIndex.ANY, IIndex.REFERENCE)); + if (includeEntries != null) { + //TODO subprogress monitor + for (int i = 0; i < includeEntries.length; ++i) { + if (progressMonitor.isCanceled()) + throw new InterruptedException(); + + IEntryResult entry = includeEntries[i]; + IPath includePath = getIncludePath(entry); + + if (fScope != null && fScope.encloses(includePath)) { + int[] references = entry.getFileReferences(); + if (references != null) { + for (int j = 0; j < references.length; ++j) { + if (progressMonitor.isCanceled()) + throw new InterruptedException(); + + IndexedFileEntry file = input.getIndexedFile(references[j]); + if (file != null && file.getPath() != null) { + IPath path = PathUtil.getWorkspaceRelativePath(file.getPath()); + fTypeCache.flush(path); + } + } + } + } + } + } + } + + private IPath getIncludePath(IEntryResult entry) { + return PathUtil.getWorkspaceRelativePath(entry.getName()); + } +} diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/IndexerJob2.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/IndexerJob2.java new file mode 100644 index 00000000000..c8bb2278b37 --- /dev/null +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/IndexerJob2.java @@ -0,0 +1,166 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corp. - Rational Software - initial implementation + * QNX Software Systems - adapted for type cache + *******************************************************************************/ +package org.eclipse.cdt.internal.core.browser.cache; + +import java.io.IOException; + +import org.eclipse.cdt.core.index.ICDTIndexer; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.internal.core.index.IIndex; +import org.eclipse.cdt.internal.core.search.indexing.IndexManager; +import org.eclipse.cdt.internal.core.search.indexing.ReadWriteMonitor; +import org.eclipse.cdt.internal.core.search.processing.IIndexJob; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; + +public abstract class IndexerJob2 implements IIndexJob { + + protected IProject fProject; + protected IIndex fProjectIndex = null; + protected ICDTIndexer fSourceIndexer = null; + + public static final String FAMILY= "BasicTypeIndexerJob"; //$NON-NLS-1$ + + public IndexerJob2(IndexManager indexManager, IProject project) { + fProject = project; + fSourceIndexer = indexManager.getIndexerForProject(project); + fProjectIndex = getIndexForProject(); + } + + public boolean belongsTo(String family) { + return family == FAMILY; + } + + public void cancel() { + } + + public boolean isReadyToRun() { + return true; + } + + public String toString() { + return FAMILY; + } + + protected abstract boolean processIndex(IProgressMonitor progressMonitor) throws InterruptedException; + + public boolean execute(IProgressMonitor progressMonitor) { + boolean success = false; + try { + if (fProjectIndex == null) + return false; + + if (progressMonitor == null) { + progressMonitor = new NullProgressMonitor(); + } + if (progressMonitor.isCanceled()) + throw new OperationCanceledException(); + + progressMonitor.beginTask("", 1); //$NON-NLS-1$ + + success = prepareIndex(progressMonitor); + + if (progressMonitor.isCanceled()) { + throw new OperationCanceledException(); + } + progressMonitor.worked(1); + + return success; + } catch (InterruptedException e) { + throw new OperationCanceledException(); + } finally { + progressMonitor.done(); + } + } + + private boolean prepareIndex(IProgressMonitor progressMonitor) throws InterruptedException { + if (progressMonitor.isCanceled()) + throw new InterruptedException(); + + if (fProjectIndex == null) + return COMPLETE; + + if (fSourceIndexer == null) + return FAILED; + + ReadWriteMonitor monitor = fSourceIndexer.getMonitorFor(fProjectIndex); + + if (monitor == null) + return COMPLETE; // index got deleted since acquired + + try { + monitor.enterRead(); // ask permission to read + /* if index has changed, commit these before querying */ + if (fProjectIndex.hasChanged()) { + try { + monitor.exitRead(); // free read lock + monitor.enterWrite(); // ask permission to write + fSourceIndexer.saveIndex(fProjectIndex); + } catch (IOException e) { + return FAILED; + } finally { + monitor.exitWriteEnterRead(); // finished writing and reacquire read permission + } + } + + if (progressMonitor.isCanceled()) + throw new InterruptedException(); + + return processIndex(progressMonitor); + } finally { + monitor.exitRead(); // finished reading + } + } + + private IIndex getIndexForProject() { + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + IPath path = fProject.getFullPath(); + IPath location; + if ((!root.getProject(path.lastSegment()).exists()) // if project does not exist + && path.segmentCount() > 1 + && ((location = root.getFile(path).getLocation()) == null + || !new java.io.File(location.toOSString()).exists()) // and internal jar file does not exist + && !new java.io.File(path.toOSString()).exists()) { // and external jar file does not exist + return null; + } + + // may trigger some index recreation work + if (fSourceIndexer != null) + return fSourceIndexer.getIndex(path, true /*reuse index file*/, false /*do not create if none*/); + + return null; + } + + protected int index2ICElement( int kind ) + { + switch(kind) { + case IIndex.TYPE_CLASS: + return ICElement.C_CLASS; + case IIndex.TYPE_STRUCT: + return ICElement.C_STRUCT; + case IIndex.TYPE_ENUM: + return ICElement.C_ENUMERATION; + case IIndex.TYPE_UNION: + return ICElement.C_UNION; + case IIndex.TYPE_TYPEDEF: + return ICElement.C_TYPEDEF; + default: + return 0; + } + } +} + diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/IndexerTypesJob2.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/IndexerTypesJob2.java new file mode 100644 index 00000000000..7176f616177 --- /dev/null +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/IndexerTypesJob2.java @@ -0,0 +1,218 @@ +/******************************************************************************* + * Copyright (c) 2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.browser.cache; + +import java.io.IOException; + +import org.eclipse.cdt.core.browser.ITypeInfo; +import org.eclipse.cdt.core.browser.ITypeSearchScope; +import org.eclipse.cdt.core.browser.PathUtil; +import org.eclipse.cdt.core.browser.QualifiedTypeName; +import org.eclipse.cdt.core.browser.TypeInfo; +import org.eclipse.cdt.core.browser.TypeReference; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.internal.core.index.IEntryResult; +import org.eclipse.cdt.internal.core.index.IIndex; +import org.eclipse.cdt.internal.core.index.IQueryResult; +import org.eclipse.cdt.internal.core.index.cindexstorage.io.BlocksIndexInput; +import org.eclipse.cdt.internal.core.index.cindexstorage.io.IndexInput; +import org.eclipse.cdt.internal.core.search.indexing.IndexManager; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; + +public class IndexerTypesJob2 extends IndexerJob2 { + + private ITypeCache fTypeCache; + + public IndexerTypesJob2(IndexManager indexManager, ITypeCache typeCache, ITypeSearchScope scope) { + super(indexManager, typeCache.getProject()); + fTypeCache = typeCache; + } + + protected boolean processIndex(IProgressMonitor progressMonitor) throws InterruptedException { + try { + updateNamespaces(progressMonitor); + updateTypes(progressMonitor); + return true; + } catch (IOException e) { + return false; + } + } + + private void updateNamespaces(IProgressMonitor monitor) + throws InterruptedException, IOException { + if (monitor.isCanceled()) + throw new InterruptedException(); + + IEntryResult[] namespaceEntries = fProjectIndex.getEntries( IIndex.NAMESPACE, IIndex.ANY, IIndex.DECLARATION ); + IQueryResult[] namespacePaths = fProjectIndex.getPrefix(IIndex.NAMESPACE, IIndex.ANY, IIndex.DECLARATION ); +// input.queryEntriesPrefixedBy(Index.encodeEntry(IIndex.NAMESPACE, IIndex.ANY, IIndex.DECLARATION)); + if (namespaceEntries != null) { + //TODO subprogress monitor + for (int i = 0; i < namespaceEntries.length; ++i) { + if (monitor.isCanceled()) + throw new InterruptedException(); + + IEntryResult entry = namespaceEntries[i]; + String name = entry.getName(); + if (name.length() != 0) { + String[] enclosingNames = entry.getEnclosingNames(); + addType(entry, namespacePaths[i].getPath(), ICElement.C_NAMESPACE, name, enclosingNames, monitor); + } + } + } + } + + private void updateTypes(IProgressMonitor monitor) + throws InterruptedException, IOException { + if (monitor.isCanceled()) + throw new InterruptedException(); + + for( int counter = 0; counter < 2; ++counter ) + { + IEntryResult[] typeEntries = fProjectIndex.getEntries( IIndex.TYPE, IIndex.ANY, ( counter == 0 ) ? IIndex.DECLARATION : IIndex.DEFINITION ); + + if (typeEntries != null) { + //TODO subprogress monitor + for (int i = 0; i < typeEntries.length; ++i) { + if (monitor.isCanceled()) + throw new InterruptedException(); + + IEntryResult entry = typeEntries[i]; + + String name = entry.extractSimpleName(); + switch (entry.getKind() ) { + case IIndex.TYPE_CLASS : + case IIndex.TYPE_STRUCT : + case IIndex.TYPE_TYPEDEF : + case IIndex.TYPE_ENUM : + case IIndex.TYPE_UNION : + if (counter != 0 && name.length() != 0) { // skip anonymous structs + addType(entry, getPathForEntry( entry ), index2ICElement( entry.getKind() ), name, entry.getEnclosingNames(), monitor); + } + break; + case IIndex.TYPE_DERIVED : + if (name.length() != 0) { // skip anonymous structs + addSuperTypeReference(entry, name, entry.getEnclosingNames(), monitor); + } + break; + default: + break; + } + } + } + } + } + + private String getPathForEntry(IEntryResult entry) { + return getPathForEntry(entry, 0); + } + + private void addType(IEntryResult entry, String pth, int type, String name, String[] enclosingNames, IProgressMonitor monitor) + throws InterruptedException, IOException { + QualifiedTypeName qualifiedName = new QualifiedTypeName(name, enclosingNames); + ITypeInfo info = fTypeCache.getType(type, qualifiedName); + if (info == null || info.isUndefinedType()) { + int[] references = entry.getFileReferences(); + if (references != null && references.length > 0) { + // add new type to cache + if (info != null) { + info.setCElementType(type); + } else { + info = new TypeInfo(type, qualifiedName); + fTypeCache.insert(info); + } + +// for (int i = 0; i < references.length; ++i) { +// if (monitor.isCanceled()) +// throw new InterruptedException(); +// +// IndexedFile file = input.getIndexedFile(references[i]); +// if (file != null && file.getPath() != null) { +// IPath path = PathUtil.getWorkspaceRelativePath(file.getPath()); +// info.addReference(new TypeReference(path, project)); +// } +// } + final IPath workspaceRelativePath = PathUtil.getWorkspaceRelativePath(pth); + int offset = entry.getOffsets()[0][0]; + int offsetType = Integer.valueOf(String.valueOf(offset).substring(0,1)).intValue(); + int value = Integer.valueOf(String.valueOf(offset).substring(1)).intValue(); + + TypeReference typeReference = null; + if (offsetType==IIndex.LINE){ + typeReference = new TypeReference(workspaceRelativePath, fProject, value, 0 ); + typeReference.offsetIsLineNumber = true; + }else if (offsetType==IIndex.OFFSET){ + typeReference = new TypeReference(workspaceRelativePath, fProject, value, entry.getOffsetLengths()[0][0] ); + } + if( typeReference != null ) + info.addReference(typeReference); + } + } + } + + private void addSuperTypeReference(IEntryResult entry, String name, String[] enclosingNames, IProgressMonitor monitor) throws InterruptedException, IOException { + QualifiedTypeName qualifiedName = new QualifiedTypeName(name, enclosingNames); + ITypeInfo info = fTypeCache.getType(ICElement.C_CLASS, qualifiedName); + if (info == null) + info = fTypeCache.getType(ICElement.C_STRUCT, qualifiedName); + if (info == null) { + // add dummy type to cache + info = new TypeInfo(0, qualifiedName); + fTypeCache.insert(info); + } + int[] references = entry.getFileReferences(); + if (references != null && references.length > 0) { + for (int i = 0; i < references.length; ++i) { + if (monitor.isCanceled()) + throw new InterruptedException(); + + IPath path = PathUtil.getWorkspaceRelativePath(getPathForEntry( entry, i )); + info.addDerivedReference(new TypeReference(path, fProject)); +// +// // get absolute path +// IPath path = new Path(file.getPath()); +// IPath projectPath = project.getFullPath(); +// if (projectPath.isPrefixOf(path)) { +// path = project.getLocation().append(path.removeFirstSegments(projectPath.segmentCount())); +// } +// info.addDerivedReference(new TypeReference(path, project)); + + } + } + } + + private String getPathForEntry(IEntryResult entry, int i) { + int [] references = entry.getFileReferences(); + IndexInput input = new BlocksIndexInput( fProjectIndex.getIndexFile() ); + try { + input.open(); + } catch (IOException e) { + return ""; //$NON-NLS-1$ + } + try + { + return input.getIndexedFile( references[i] ).getPath(); + } + catch( IOException io ) + { + } + finally + { + try { + input.close(); + } catch (IOException e) { + } + } + return ""; //$NON-NLS-1$ + } + +} diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheManager.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheManager.java index bb1664c63bc..430ff4a2922 100644 --- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheManager.java +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheManager.java @@ -29,6 +29,8 @@ import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElementDelta; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.internal.core.model.CModelManager; +import org.eclipse.cdt.internal.core.search.indexing.IndexManager; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.ISafeRunnable; @@ -39,7 +41,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.IJobManager; import org.eclipse.core.runtime.jobs.Job; -public class TypeCacheManager implements ITypeCacheChangedListener { +public class TypeCacheManager implements ITypeCacheChangedListener, IndexManager.IIndexerSelectionListener { private static final TypeCacheManager fgInstance = new TypeCacheManager(); private Map fCacheMap; private IWorkingCopyProvider fWorkingCopyProvider; @@ -53,11 +55,17 @@ public class TypeCacheManager implements ITypeCacheChangedListener { private TypeCacheManager() { fCacheMap = new HashMap(); + CModelManager.getDefault().getIndexManager().subscribeForIndexerChangeNotifications( this ); } public static TypeCacheManager getInstance() { return fgInstance; } + + protected void finalize() throws Throwable { + CModelManager.getDefault().getIndexManager().unSubscribeForIndexerChangeNotifications( this ); + super.finalize(); + } public void setWorkingCopyProvider(IWorkingCopyProvider workingCopyProvider) { fWorkingCopyProvider = workingCopyProvider; @@ -455,4 +463,8 @@ public class TypeCacheManager implements ITypeCacheChangedListener { public void setProcessTypeCacheEvents(boolean processTypeCacheEvents) { this.processTypeCacheEvents = processTypeCacheEvents; } + + public void indexerSelectionChanged(IProject project) { + addCacheDelta(project, null ); + } } diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacherJob.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacherJob.java index b864e697440..395d95c1738 100644 --- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacherJob.java +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacherJob.java @@ -144,7 +144,7 @@ public class TypeCacherJob extends BasicJob { monitor.beginTask("", 100); //$NON-NLS-1$ if (project.exists() && project.isOpen()) { - success = doIndexerJob(new IndexerTypesJob(fIndexManager, fTypeCache, scope), monitor); + success = doIndexerJob(new IndexerTypesJob2(fIndexManager, fTypeCache, scope), monitor); } if (!success || monitor.isCanceled()) { @@ -174,6 +174,27 @@ public class TypeCacherJob extends BasicJob { ICSearchConstants.FORCE_IMMEDIATE_SEARCH, monitor, null); } + private boolean doIndexerJob(IndexerJob2 job, IProgressMonitor monitor) { + if (!fEnableIndexing) { + return false; + } + + // check if indexer is busy + fIndexerIsBusy = false; + try { + fIndexManager.performConcurrentJob(new DummyIndexerJob(fIndexManager, fTypeCache.getProject()), + ICSearchConstants.CANCEL_IF_NOT_READY_TO_SEARCH, new NullProgressMonitor(), null); + } catch (OperationCanceledException e) { + fIndexerIsBusy = true; + } + + // do an immediate (but possibly incomplete) search + // if fIndexerIsBusy the cache will stay dirty and we'll hit the indexer again next time + return fIndexManager.performConcurrentJob(job, + ICSearchConstants.FORCE_IMMEDIATE_SEARCH, monitor, null); + } + + private static final int PATH_ENTRY_FLAGS = ICElementDelta.F_ADDED_PATHENTRY_SOURCE | ICElementDelta.F_REMOVED_PATHENTRY_SOURCE | ICElementDelta.F_CHANGED_PATHENTRY_INCLUDE @@ -248,7 +269,7 @@ public class TypeCacherJob extends BasicJob { protected boolean processIndex(IIndex index, IProject project, IProgressMonitor progressMonitor) throws InterruptedException { return false; } - }; + } } diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/core/index/ICDTIndexer.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/core/index/ICDTIndexer.java index c8f09d2b214..afe13820173 100644 --- a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/core/index/ICDTIndexer.java +++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/core/index/ICDTIndexer.java @@ -10,8 +10,11 @@ **********************************************************************/ package org.eclipse.cdt.core.index; +import java.io.IOException; + import org.eclipse.cdt.internal.core.index.IIndex; import org.eclipse.cdt.internal.core.index.impl.IndexDelta; +import org.eclipse.cdt.internal.core.search.indexing.ReadWriteMonitor; import org.eclipse.cdt.internal.core.search.processing.IIndexJob; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -156,5 +159,20 @@ public interface ICDTIndexer { */ public void indexerRemoved(IProject project); + /** + * Don't ask. + * + * @param index + * @return + */ + public ReadWriteMonitor getMonitorFor(IIndex index); + + /** + * Don't tell. + * + * @param index + */ + public void saveIndex(IIndex index) throws IOException; + } diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/nullindexer/NullIndexer.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/nullindexer/NullIndexer.java index 9b9ae260d64..29251e4b70d 100644 --- a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/nullindexer/NullIndexer.java +++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/nullindexer/NullIndexer.java @@ -9,6 +9,7 @@ import org.eclipse.cdt.core.index.IIndexStorage; import org.eclipse.cdt.internal.core.index.IIndex; import org.eclipse.cdt.internal.core.index.IIndexerOutput; import org.eclipse.cdt.internal.core.index.impl.IndexDelta; +import org.eclipse.cdt.internal.core.search.indexing.ReadWriteMonitor; import org.eclipse.cdt.internal.core.search.processing.IIndexJob; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; @@ -18,7 +19,7 @@ import org.eclipse.core.runtime.IPath; public class NullIndexer extends AbstractCExtension implements ICDTIndexer { - public int getIndexerFeatures() { + public int getIndexerFeatures() { // TODO Auto-generated method stub return 0; } @@ -103,4 +104,12 @@ public class NullIndexer extends AbstractCExtension implements ICDTIndexer { } + public ReadWriteMonitor getMonitorFor(IIndex index) { + return null; + } + + public void saveIndex(IIndex index) throws IOException { + // TODO Auto-generated method stub + } + } diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/IndexManager.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/IndexManager.java index e1024430d83..d2cfc96ab16 100644 --- a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/IndexManager.java +++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/IndexManager.java @@ -20,6 +20,7 @@ import org.eclipse.cdt.core.ICExtensionReference; import org.eclipse.cdt.core.index.ICDTIndexer; import org.eclipse.cdt.core.index.IIndexStorage; import org.eclipse.cdt.core.model.ICModelMarker; +import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.index.IndexRequest; import org.eclipse.cdt.internal.core.index.cindexstorage.CIndexStorage; import org.eclipse.cdt.internal.core.index.domsourceindexer.DOMSourceIndexer; @@ -47,6 +48,31 @@ import org.eclipse.core.runtime.jobs.Job; */ public class IndexManager extends JobManager{ + public static interface IIndexerSelectionListener + { + public void indexerSelectionChanged(IProject project); + } + + private IIndexerSelectionListener [] listeners = new IIndexerSelectionListener[1]; + + public synchronized void subscribeForIndexerChangeNotifications( IIndexerSelectionListener listener ) + { + listeners = (IIndexerSelectionListener[]) ArrayUtil.append( IIndexerSelectionListener.class, listeners, listener ); + } + + public synchronized void unSubscribeForIndexerChangeNotifications( IIndexerSelectionListener listener ) + { + if( listeners == null ) return; + if( listener == null ) return; + for( int i = 0; i < listeners.length; ++i ) + { + if( listeners[i] == listener ) + listeners[i] = null; + } + } + + + public final static String INDEX_MODEL_ID = CCorePlugin.PLUGIN_ID + ".cdtindexers"; //$NON-NLS-1$ public final static String INDEXERID = "indexerID"; //$NON-NLS-1$ public final static QualifiedName indexerIDKey = new QualifiedName(INDEX_MODEL_ID, INDEXERID); @@ -397,6 +423,11 @@ public class IndexManager extends JobManager{ }; job.schedule(); + + if( listeners != null ) + for( int i = 0; i < listeners.length; ++i ) + if( listeners[i] != null ) + listeners[i].indexerSelectionChanged(project); } } diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingPart.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingPart.java index e2be686e0cc..f0a27cef564 100644 --- a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingPart.java +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingPart.java @@ -58,6 +58,8 @@ import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.util.Assert; import org.eclipse.jface.util.IPropertyChangeListener; @@ -1094,9 +1096,24 @@ public abstract class CBrowsingPart extends ViewPart implements IMenuListener, I // highlight the type in the editor if (editorPart != null && editorPart instanceof ITextEditor) { - ITextEditor editor = (ITextEditor) editorPart; - editor.selectAndReveal(location.getOffset(), location.getLength()); - return true; + ITextEditor editor = (ITextEditor) editorPart; + if( location.isLineNumber() ) + { + IDocument document= editor.getDocumentProvider().getDocument(editor.getEditorInput()); + try + { + int startOffset = document.getLineOffset(location.getOffset()-1); + int length=document.getLineLength(location.getOffset()-1); + editor.selectAndReveal(startOffset, length); + return true; + } + catch( BadLocationException ble ) + { + return false; + } + } + editor.selectAndReveal(location.getOffset(), location.getLength()); + return true; } } catch (CModelException ex) { ex.printStackTrace(); diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeAction.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeAction.java index c077c93fff5..f6a9b3b2e22 100644 --- a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeAction.java +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeAction.java @@ -29,6 +29,8 @@ import org.eclipse.jface.action.IAction; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; import org.eclipse.jface.viewers.ISelection; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorPart; @@ -164,7 +166,22 @@ public class OpenTypeAction implements IWorkbenchWindowActionDelegate { // highlight the type in the editor if (editorPart != null && editorPart instanceof ITextEditor) { ITextEditor editor = (ITextEditor) editorPart; - editor.selectAndReveal(location.getOffset(), location.getLength()); + if( location.isLineNumber() ) + { + IDocument document= editor.getDocumentProvider().getDocument(editor.getEditorInput()); + try + { + int startOffset = document.getLineOffset(location.getOffset()-1); + int length=document.getLineLength(location.getOffset()-1); + editor.selectAndReveal(startOffset, length); + return true; + } + catch( BadLocationException ble ) + { + return false; + } + } + editor.selectAndReveal(location.getOffset(), location.getLength()); return true; } } catch (CModelException ex) {