1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 10:16:03 +02:00

Fix for 188282, potential use of unlocked index.

This commit is contained in:
Markus Schorn 2007-05-23 10:38:34 +00:00
parent dc82b160c3
commit d1db017310
7 changed files with 247 additions and 206 deletions

View file

@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Anton Leherbauer (Wind River Systems) - initial API and implementation * Anton Leherbauer (Wind River Systems) - initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.model.tests; package org.eclipse.cdt.core.model.tests;
@ -24,12 +25,15 @@ import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.core.testplugin.util.BaseTestCase; import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
import org.eclipse.cdt.core.testplugin.util.TestSourceReader; import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
import org.eclipse.cdt.internal.core.model.ASTCache; import org.eclipse.cdt.internal.core.model.ASTCache;
import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
/** /**
* Tests for the {@link ASTCache}. * Tests for the {@link ASTCache}.
@ -149,24 +153,44 @@ public class ASTCacheTests extends BaseTestCase {
} }
private void checkSingleThreadAccess() throws Exception { private void checkSingleThreadAccess() throws Exception {
ASTCache cache= new ASTCache(); final ASTCache cache= new ASTCache();
final int[] counter= {0};
cache.setActiveElement(fTU1); cache.setActiveElement(fTU1);
IASTTranslationUnit ast; IStatus status= cache.runOnAST(fTU1, false, null, new ASTRunnable() {
ast= cache.getAST(fTU1, fIndex, false, null); public IStatus runOnAST(IASTTranslationUnit ast) throws CoreException {
assertNull(ast); assertNull(ast);
counter[0]++;
return Status.OK_STATUS;
}
});
assertEquals(1, counter[0]);
IProgressMonitor npm= new NullProgressMonitor(); IProgressMonitor npm= new NullProgressMonitor();
npm.setCanceled(true); npm.setCanceled(true);
ast= cache.getAST(fTU1, fIndex, true, npm); status= cache.runOnAST(fTU1, true, npm, new ASTRunnable() {
public IStatus runOnAST(IASTTranslationUnit ast) throws CoreException {
assertNull(ast); assertNull(ast);
counter[0]++;
return Status.OK_STATUS;
}
});
assertEquals(2, counter[0]);
npm.setCanceled(false); npm.setCanceled(false);
ast= cache.getAST(fTU1, fIndex, true, npm); status= cache.runOnAST(fTU1, true, npm, new ASTRunnable() {
public IStatus runOnAST(IASTTranslationUnit ast) throws CoreException {
assertNotNull(ast); assertNotNull(ast);
counter[0]++;
return Status.OK_STATUS;
}
});
assertEquals(3, counter[0]);
} }
private void checkAccessWithSequentialReconciler() throws Exception { private void checkAccessWithSequentialReconciler() throws Exception {
ASTCache cache= new ASTCache(); final ASTCache cache= new ASTCache();
MockReconciler reconciler1= new MockReconciler(fTU1, cache); final MockReconciler reconciler1= new MockReconciler(fTU1, cache);
MockReconciler reconciler2= new MockReconciler(fTU2, cache); final MockReconciler reconciler2= new MockReconciler(fTU2, cache);
try { try {
cache.setActiveElement(fTU1); cache.setActiveElement(fTU1);
assertFalse(cache.isReconciling(fTU1)); assertFalse(cache.isReconciling(fTU1));
@ -178,12 +202,15 @@ public class ASTCacheTests extends BaseTestCase {
assertTrue(cache.isReconciling(fTU1)); assertTrue(cache.isReconciling(fTU1));
} }
reconciler1.fStopped= true; reconciler1.fStopped= true;
IASTTranslationUnit ast; IStatus status= cache.runOnAST(fTU1, true, null, new ASTRunnable() {
ast= cache.getAST(fTU1, fIndex, true, null); public IStatus runOnAST(IASTTranslationUnit ast) throws CoreException {
assertNotNull(ast); assertNotNull(ast);
assertTrue(cache.isActiveElement(fTU1)); assertTrue(cache.isActiveElement(fTU1));
assertFalse(cache.isReconciling(fTU1)); assertFalse(cache.isReconciling(fTU1));
assertSame(ast, reconciler1.fAST); assertSame(ast, reconciler1.fAST);
return Status.OK_STATUS;
}
});
// change active element // change active element
cache.setActiveElement(fTU2); cache.setActiveElement(fTU2);
@ -196,11 +223,16 @@ public class ASTCacheTests extends BaseTestCase {
assertTrue(cache.isReconciling(fTU2)); assertTrue(cache.isReconciling(fTU2));
} }
reconciler2.fStopped= true; reconciler2.fStopped= true;
ast= cache.getAST(fTU2, fIndex, true, null);
status= cache.runOnAST(fTU2, true, null, new ASTRunnable() {
public IStatus runOnAST(IASTTranslationUnit ast) throws CoreException {
assertNotNull(ast); assertNotNull(ast);
assertTrue(cache.isActiveElement(fTU2)); assertTrue(cache.isActiveElement(fTU2));
assertFalse(cache.isReconciling(fTU2)); assertFalse(cache.isReconciling(fTU2));
assertSame(ast, reconciler2.fAST); assertSame(ast, reconciler2.fAST);
return Status.OK_STATUS;
}
});
} finally { } finally {
reconciler1.fStopped= true; reconciler1.fStopped= true;
reconciler1.join(1000); reconciler1.join(1000);
@ -221,27 +253,42 @@ public class ASTCacheTests extends BaseTestCase {
while (iterations < 10) { while (iterations < 10) {
++iterations; ++iterations;
if (DEBUG) System.out.println("iteration="+iterations); if (DEBUG) System.out.println("iteration="+iterations);
IASTTranslationUnit ast;
cache.setActiveElement(fTU1); cache.setActiveElement(fTU1);
Thread.sleep(50); Thread.sleep(50);
ast = waitForAST(cache, fTU1); waitForAST(cache, fTU1, new ASTRunnable() {
public IStatus runOnAST(IASTTranslationUnit ast) {
assertNotNull(ast); assertNotNull(ast);
assertEquals("void foo1() {}", ast.getDeclarations()[0].getRawSignature()); assertEquals("void foo1() {}", ast.getDeclarations()[0].getRawSignature());
return Status.OK_STATUS;
}
});
ast = waitForAST(cache, fTU2); waitForAST(cache, fTU2, new ASTRunnable() {
public IStatus runOnAST(IASTTranslationUnit ast) {
assertNotNull(ast); assertNotNull(ast);
assertEquals("void foo2() {}", ast.getDeclarations()[0].getRawSignature()); assertEquals("void foo2() {}", ast.getDeclarations()[0].getRawSignature());
return Status.OK_STATUS;
}
});
// change active element // change active element
cache.setActiveElement(fTU2); cache.setActiveElement(fTU2);
Thread.sleep(50); Thread.sleep(50);
ast = waitForAST(cache, fTU2); waitForAST(cache, fTU2, new ASTRunnable() {
public IStatus runOnAST(IASTTranslationUnit ast) {
assertNotNull(ast); assertNotNull(ast);
assertEquals("void foo2() {}", ast.getDeclarations()[0].getRawSignature()); assertEquals("void foo2() {}", ast.getDeclarations()[0].getRawSignature());
return Status.OK_STATUS;
}
});
ast = waitForAST(cache, fTU1); waitForAST(cache, fTU1, new ASTRunnable() {
public IStatus runOnAST(IASTTranslationUnit ast) {
assertNotNull(ast); assertNotNull(ast);
assertEquals("void foo1() {}", ast.getDeclarations()[0].getRawSignature()); assertEquals("void foo1() {}", ast.getDeclarations()[0].getRawSignature());
return Status.OK_STATUS;
}
});
} }
} finally { } finally {
reconciler1.fStopped= true; reconciler1.fStopped= true;
@ -251,13 +298,14 @@ public class ASTCacheTests extends BaseTestCase {
} }
} }
private IASTTranslationUnit waitForAST(ASTCache cache, ITranslationUnit tUnit) { private void waitForAST(ASTCache cache, ITranslationUnit tUnit, ASTRunnable runnable) {
if (DEBUG) System.out.println("waiting for "+tUnit.getElementName()); if (DEBUG) System.out.println("waiting for "+tUnit.getElementName());
long start= System.currentTimeMillis(); long start= System.currentTimeMillis();
IASTTranslationUnit ast; try {
ast= cache.getAST(tUnit, fIndex, true, null); cache.runOnAST(tUnit, true, null, runnable);
if (DEBUG) System.out.println("wait time= " + (System.currentTimeMillis() - start)); }
return ast; finally {
if (DEBUG) System.out.println("wait time= " + (System.currentTimeMillis() - start));
}
} }
} }

View file

@ -4,14 +4,16 @@
* terms of the Eclipse Public License v1.0 which accompanies this distribution, * terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html * and is available at http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: Anton Leherbauer (Wind River Systems) - initial API and * Contributors:
* implementation * Anton Leherbauer (Wind River Systems) - initial API and implementation
* Markus Schorn (Wind River Systems)
******************************************************************************/ ******************************************************************************/
package org.eclipse.cdt.internal.core.model; package org.eclipse.cdt.internal.core.model;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexManager;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
@ -51,7 +53,7 @@ public class ASTCache {
* @param ast the translation unit AST, may be <code>null</code> * @param ast the translation unit AST, may be <code>null</code>
* @return a status object * @return a status object
*/ */
IStatus runOnAST(IASTTranslationUnit ast); IStatus runOnAST(IASTTranslationUnit ast) throws CoreException;
} }
private final int fParseMode; private final int fParseMode;
@ -92,7 +94,7 @@ public class ASTCache {
* @param progressMonitor the progress monitor or <code>null</code> * @param progressMonitor the progress monitor or <code>null</code>
* @return the AST or <code>null</code> if the AST is not available * @return the AST or <code>null</code> if the AST is not available
*/ */
public IASTTranslationUnit getAST(ITranslationUnit tUnit, IIndex index, boolean wait, IProgressMonitor progressMonitor) { private IASTTranslationUnit getAST(ITranslationUnit tUnit, IIndex index, boolean wait, IProgressMonitor progressMonitor) {
if (tUnit == null) if (tUnit == null)
return null; return null;
@ -193,7 +195,7 @@ public class ASTCache {
ASTRunnable astRunnable) { ASTRunnable astRunnable) {
IIndex index; IIndex index;
try { try {
index = CCorePlugin.getIndexManager().getIndex(tUnit.getCProject()); index = CCorePlugin.getIndexManager().getIndex(tUnit.getCProject(), IIndexManager.ADD_DEPENDENCIES);
index.acquireReadLock(); index.acquireReadLock();
} catch (CoreException e) { } catch (CoreException e) {
return e.getStatus(); return e.getStatus();
@ -205,6 +207,9 @@ public class ASTCache {
IASTTranslationUnit ast= getAST(tUnit, index, wait, monitor); IASTTranslationUnit ast= getAST(tUnit, index, wait, monitor);
return astRunnable.runOnAST(ast); return astRunnable.runOnAST(ast);
} }
catch (CoreException e) {
return e.getStatus();
}
finally { finally {
index.releaseReadLock(); index.releaseReadLock();
} }

View file

@ -154,7 +154,7 @@ public class CallHierarchyUI {
index.acquireReadLock(); index.acquireReadLock();
try { try {
IASTName name= IndexUI.getSelectedName(index, editorInput, sel); IASTName name= IndexUI.getSelectedName(editorInput, sel);
if (name != null) { if (name != null) {
IBinding binding= name.resolveBinding(); IBinding binding= name.resolveBinding();
if (CallHierarchyUI.isRelevantForCallHierarchy(binding)) { if (CallHierarchyUI.isRelevantForCallHierarchy(binding)) {

View file

@ -25,7 +25,6 @@ import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI; import org.eclipse.ui.PlatformUI;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.CUIPlugin;
@ -280,30 +279,6 @@ public final class ASTProvider {
fCache.aboutToBeReconciled((ITranslationUnit)cElement); fCache.aboutToBeReconciled((ITranslationUnit)cElement);
} }
/**
* Returns a shared translation unit AST for the given
* C element.
* <p>
* Clients are not allowed to modify the AST and must
* synchronize all access to its nodes.
* </p>
*
* @param cElement the C element
* @param index the index used to create the AST, needs to be read-locked.
* @param waitFlag {@link #WAIT_YES}, {@link #WAIT_NO} or {@link #WAIT_ACTIVE_ONLY}
* @param progressMonitor the progress monitor or <code>null</code>
* @return the AST or <code>null</code> if the AST is not available
*/
public IASTTranslationUnit getAST(ICElement cElement, IIndex index, WAIT_FLAG waitFlag, IProgressMonitor progressMonitor) {
if (cElement == null)
return null;
Assert.isTrue(cElement instanceof ITranslationUnit);
if (waitFlag == WAIT_ACTIVE_ONLY && !isActive((ITranslationUnit)cElement)) {
return null;
}
return fCache.getAST((ITranslationUnit)cElement, index, waitFlag != WAIT_NO, progressMonitor);
}
/** /**
* Disposes this AST provider. * Disposes this AST provider.
*/ */
@ -334,16 +309,5 @@ public final class ASTProvider {
} }
return fCache.runOnAST((ITranslationUnit)cElement, waitFlag != WAIT_NO, monitor, astRunnable); return fCache.runOnAST((ITranslationUnit)cElement, waitFlag != WAIT_NO, monitor, astRunnable);
} }
/**
* @param cElement
* @param index
* @param monitor
* @return an AST or <code>null</code>, if no AST could be computed
*/
public IASTTranslationUnit createAST(ICElement cElement, IIndex index, IProgressMonitor monitor) {
Assert.isTrue(cElement instanceof ITranslationUnit);
return fCache.createAST((ITranslationUnit)cElement, index, monitor);
}
} }

View file

@ -8,11 +8,14 @@
* Contributors: * Contributors:
* QNX Software Systems - Initial API and implementation * QNX Software Systems - Initial API and implementation
* IBM Corporation * IBM Corporation
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.ui.editor; package org.eclipse.cdt.internal.ui.editor;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IAction;
import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.ITextSelection;
@ -33,6 +36,8 @@ import org.eclipse.cdt.core.index.IIndexManager;
import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
import org.eclipse.cdt.internal.ui.search.actions.OpenDeclarationsAction; import org.eclipse.cdt.internal.ui.search.actions.OpenDeclarationsAction;
public class CElementHyperlinkDetector implements IHyperlinkDetector { public class CElementHyperlinkDetector implements IHyperlinkDetector {
@ -51,16 +56,16 @@ public class CElementHyperlinkDetector implements IHyperlinkDetector {
CEditor editor = (CEditor) fTextEditor; CEditor editor = (CEditor) fTextEditor;
int offset = region.getOffset(); int offset = region.getOffset();
IAction openAction= editor.getAction("OpenDeclarations"); //$NON-NLS-1$ final IAction openAction= editor.getAction("OpenDeclarations"); //$NON-NLS-1$
if (openAction == null) if (openAction == null)
return null; return null;
// reuse the logic from Open Decl that recognizes a word in the editor // reuse the logic from Open Decl that recognizes a word in the editor
ITextSelection selection = OpenDeclarationsAction.selectWord(offset, editor); final ITextSelection selection = OpenDeclarationsAction.selectWord(offset, editor);
if(selection == null) if(selection == null)
return null; return null;
IWorkingCopy workingCopy = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(editor.getEditorInput()); final IWorkingCopy workingCopy = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(editor.getEditorInput());
if (workingCopy == null) { if (workingCopy == null) {
return null; return null;
} }
@ -79,9 +84,11 @@ public class CElementHyperlinkDetector implements IHyperlinkDetector {
return null; return null;
} }
final IHyperlink[] result= {null};
try {
ASTProvider.getASTProvider().runOnAST(workingCopy, ASTProvider.WAIT_YES, null, new ASTRunnable() {
public IStatus runOnAST(IASTTranslationUnit ast) {
try { try {
IASTTranslationUnit ast =
ASTProvider.getASTProvider().getAST(workingCopy, index, ASTProvider.WAIT_YES, null);
IASTName[] selectedNames = IASTName[] selectedNames =
workingCopy.getLanguage().getSelectedNames(ast, selection.getOffset(), selection.getLength()); workingCopy.getLanguage().getSelectedNames(ast, selection.getOffset(), selection.getLength());
@ -94,14 +101,19 @@ public class CElementHyperlinkDetector implements IHyperlinkDetector {
} }
if(linkRegion != null) if(linkRegion != null)
return new IHyperlink[] { new CElementHyperlink(linkRegion, openAction) }; result[0]= new CElementHyperlink(linkRegion, openAction);
}
} catch(CoreException e) { catch (CoreException e) {
return e.getStatus();
}
return Status.OK_STATUS;
}
});
} finally { } finally {
index.releaseReadLock(); index.releaseReadLock();
} }
return null; return result[0] == null ? null : result;
} }

View file

@ -49,6 +49,8 @@ import org.eclipse.cdt.core.model.util.CElementBaseLabels;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
import org.eclipse.cdt.internal.ui.actions.OpenActionUtil; import org.eclipse.cdt.internal.ui.actions.OpenActionUtil;
import org.eclipse.cdt.internal.ui.editor.ASTProvider; import org.eclipse.cdt.internal.ui.editor.ASTProvider;
import org.eclipse.cdt.internal.ui.editor.CEditor; import org.eclipse.cdt.internal.ui.editor.CEditor;
@ -70,7 +72,10 @@ public class OpenDeclarationsAction extends SelectionParseAction {
setDescription(CEditorMessages.getString("OpenDeclarations.description")); //$NON-NLS-1$ setDescription(CEditorMessages.getString("OpenDeclarations.description")); //$NON-NLS-1$
} }
private class Runner extends Job { private class Runner extends Job implements ASTRunnable {
private IWorkingCopy fWorkingCopy;
private IIndex fIndex;
Runner() { Runner() {
super(CEditorMessages.getString("OpenDeclarations.dialog.title")); //$NON-NLS-1$ super(CEditorMessages.getString("OpenDeclarations.dialog.title")); //$NON-NLS-1$
} }
@ -79,28 +84,34 @@ public class OpenDeclarationsAction extends SelectionParseAction {
try { try {
clearStatusLine(); clearStatusLine();
int selectionStart = selNode.getOffset(); fWorkingCopy = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(fEditor.getEditorInput());
int selectionLength = selNode.getLength(); if (fWorkingCopy == null)
IWorkingCopy workingCopy = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(fEditor.getEditorInput());
if (workingCopy == null)
return Status.CANCEL_STATUS; return Status.CANCEL_STATUS;
IIndex index = CCorePlugin.getIndexManager().getIndex(workingCopy.getCProject(), fIndex= CCorePlugin.getIndexManager().getIndex(fWorkingCopy.getCProject(),
IIndexManager.ADD_DEPENDENCIES | IIndexManager.ADD_DEPENDENT); IIndexManager.ADD_DEPENDENCIES | IIndexManager.ADD_DEPENDENT);
try { try {
index.acquireReadLock(); fIndex.acquireReadLock();
} catch (InterruptedException e) { } catch (InterruptedException e) {
return Status.CANCEL_STATUS; return Status.CANCEL_STATUS;
} }
try { try {
IASTTranslationUnit ast= return ASTProvider.getASTProvider().runOnAST(fWorkingCopy, ASTProvider.WAIT_YES, monitor, this);
ASTProvider.getASTProvider().getAST( } finally {
workingCopy, index, ASTProvider.WAIT_YES, monitor); fIndex.releaseReadLock();
IASTName[] selectedNames = workingCopy.getLanguage().getSelectedNames(ast, selectionStart, selectionLength); }
} catch (CoreException e) {
return e.getStatus();
}
}
public IStatus runOnAST(IASTTranslationUnit ast) throws CoreException {
int selectionStart = selNode.getOffset();
int selectionLength = selNode.getLength();
IASTName[] selectedNames = fWorkingCopy.getLanguage().getSelectedNames(ast, selectionStart, selectionLength);
if (selectedNames.length > 0 && selectedNames[0] != null) { // just right, only one name selected if (selectedNames.length > 0 && selectedNames[0] != null) { // just right, only one name selected
boolean found = false; boolean found = false;
@ -108,7 +119,7 @@ public class OpenDeclarationsAction extends SelectionParseAction {
boolean isDefinition= searchName.isDefinition(); boolean isDefinition= searchName.isDefinition();
IBinding binding = searchName.resolveBinding(); IBinding binding = searchName.resolveBinding();
if (binding != null && !(binding instanceof IProblemBinding)) { if (binding != null && !(binding instanceof IProblemBinding)) {
IName[] declNames = findNames(index, ast, isDefinition, binding); IName[] declNames = findNames(fIndex, ast, isDefinition, binding);
if (declNames.length == 0) { if (declNames.length == 0) {
// bug 86829, handle implicit methods. // bug 86829, handle implicit methods.
if (binding instanceof ICPPMethod) { if (binding instanceof ICPPMethod) {
@ -117,7 +128,7 @@ public class OpenDeclarationsAction extends SelectionParseAction {
try { try {
IBinding clsBinding= method.getClassOwner(); IBinding clsBinding= method.getClassOwner();
if (clsBinding != null && !(clsBinding instanceof IProblemBinding)) { if (clsBinding != null && !(clsBinding instanceof IProblemBinding)) {
declNames= findNames(index, ast, false, clsBinding); declNames= findNames(fIndex, ast, false, clsBinding);
} }
} catch (DOMException e) { } catch (DOMException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
@ -125,7 +136,7 @@ public class OpenDeclarationsAction extends SelectionParseAction {
} }
} }
} }
if (navigateViaCElements(workingCopy.getCProject(), index, declNames)) { if (navigateViaCElements(fWorkingCopy.getCProject(), fIndex, declNames)) {
found= true; found= true;
} }
else { else {
@ -179,14 +190,7 @@ public class OpenDeclarationsAction extends SelectionParseAction {
} }
} }
} }
} finally {
index.releaseReadLock();
}
return Status.OK_STATUS; return Status.OK_STATUS;
} catch (CoreException e) {
return e.getStatus();
}
} }
private boolean navigateOneLocation(IName[] declNames) { private boolean navigateOneLocation(IName[] declNames) {

View file

@ -17,8 +17,10 @@ import java.util.ArrayList;
import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.Region; import org.eclipse.jface.text.Region;
@ -54,6 +56,7 @@ import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
import org.eclipse.cdt.internal.core.model.ext.CElementHandleFactory; import org.eclipse.cdt.internal.core.model.ext.CElementHandleFactory;
import org.eclipse.cdt.internal.core.model.ext.ICElementHandle; import org.eclipse.cdt.internal.core.model.ext.ICElementHandle;
@ -238,18 +241,23 @@ public class IndexUI {
return null; return null;
} }
public static IASTName getSelectedName(IIndex index, IEditorInput editorInput, ITextSelection selection) throws CoreException { public static IASTName getSelectedName(IEditorInput editorInput, ITextSelection selection) throws CoreException {
int selectionStart = selection.getOffset(); final int selectionStart = selection.getOffset();
int selectionLength = selection.getLength(); final int selectionLength = selection.getLength();
IWorkingCopy workingCopy = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(editorInput); IWorkingCopy workingCopy = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(editorInput);
if (workingCopy == null) if (workingCopy == null)
return null; return null;
IASTTranslationUnit ast= ASTProvider.getASTProvider().getAST( final IASTName[] result= {null};
workingCopy, index, ASTProvider.WAIT_YES, new NullProgressMonitor()); ASTProvider.getASTProvider().runOnAST(workingCopy, ASTProvider.WAIT_YES, null, new ASTRunnable() {
public IStatus runOnAST(IASTTranslationUnit ast) {
FindNameForSelectionVisitor finder= new FindNameForSelectionVisitor(ast.getFilePath(), selectionStart, selectionLength); FindNameForSelectionVisitor finder= new FindNameForSelectionVisitor(ast.getFilePath(), selectionStart, selectionLength);
ast.accept(finder); ast.accept(finder);
return finder.getSelectedName(); result[0]= finder.getSelectedName();
return Status.OK_STATUS;
}
});
return result[0];
} }
} }