diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/ASTCacheTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/ASTCacheTests.java
new file mode 100644
index 00000000000..8fce841b803
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/ASTCacheTests.java
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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:
+ * Anton Leherbauer (Wind River Systems) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.core.model.tests;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.dom.IPDOMManager;
+import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.index.IIndex;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.model.ITranslationUnit;
+import org.eclipse.cdt.core.testplugin.CProjectHelper;
+import org.eclipse.cdt.core.testplugin.CTestPlugin;
+import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
+import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
+import org.eclipse.cdt.internal.core.model.ASTCache;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+
+/**
+ * Tests for the {@link ASTCache}.
+ */
+public class ASTCacheTests extends BaseTestCase {
+ private static int fgReconcilerCount;
+
+ public class MockReconciler extends Thread {
+ private ITranslationUnit fTU;
+ private ASTCache fCache;
+ public volatile boolean fStopped;
+ private IASTTranslationUnit fAST;
+
+ public MockReconciler(ITranslationUnit tu, ASTCache cache) {
+ super("MockReconciler-"+fgReconcilerCount++);
+ fTU= tu;
+ fCache= cache;
+ }
+ public void run() {
+ while (!fStopped) {
+ try {
+ Thread.sleep(500);
+ fCache.aboutToBeReconciled(fTU);
+ IASTTranslationUnit ast;
+ synchronized (this) {
+ notifyAll();
+ }
+ fAST= fCache.createAST(fTU, fIndex, null);
+ fCache.reconciled(fAST, fTU);
+ } catch (InterruptedException exc) {
+ fStopped= true;
+ break;
+ }
+ }
+ }
+ }
+
+ private ICProject fProject;
+ private ITranslationUnit fTU1;
+ private ITranslationUnit fTU2;
+ private IIndex fIndex;
+
+ public ASTCacheTests(String name) {
+ super(name);
+ }
+
+ // {source1.cpp}
+ // void foo1() {}
+ // void bar1() {}
+
+ // {source2.cpp}
+ // void foo2() {}
+ // void bar2() {}
+
+ public static Test suite() {
+ TestSuite suite= new TestSuite(ASTCacheTests.class);
+ return suite;
+ }
+
+ public void setUp() throws Exception {
+ super.setUp();
+ fProject= createProject("ASTCacheTest");
+ assertNotNull(fProject);
+ IFile file1= createFile(fProject.getProject(), "source1.cpp", readTaggedComment("source1.cpp"));
+ assertNotNull(file1);
+ fTU1= CProjectHelper.findTranslationUnit(fProject, file1.getName());
+ assertNotNull(fTU1);
+ IFile file2= createFile(fProject.getProject(), "source2.cpp", readTaggedComment("source2.cpp"));
+ assertNotNull(file2);
+ fTU2= CProjectHelper.findTranslationUnit(fProject, file2.getName());
+ assertNotNull(fTU2);
+ CCorePlugin.getIndexManager().joinIndexer(5000, new NullProgressMonitor());
+ fIndex= CCorePlugin.getIndexManager().getIndex(fProject);
+ fIndex.acquireReadLock();
+ }
+
+ public void tearDown() throws Exception {
+ if (fIndex != null) {
+ fIndex.releaseReadLock();
+ }
+ if (fProject != null) {
+ CProjectHelper.delete(fProject);
+ }
+ super.tearDown();
+ }
+
+ protected ICProject createProject(final String name) throws CoreException {
+ return CProjectHelper.createCProject(name, null, IPDOMManager.ID_FAST_INDEXER);
+ }
+
+ protected String readTaggedComment(String tag) throws Exception {
+ return TestSourceReader.readTaggedComment(CTestPlugin.getDefault().getBundle(), "model", getClass(), tag);
+ }
+
+ protected IFile createFile(IContainer container, String fileName, String contents) throws Exception {
+ return TestSourceReader.createFile(container, new Path(fileName), contents);
+ }
+
+ public void testASTCache() throws Exception {
+ checkActiveElement();
+ checkSingleThreadAccess();
+ checkAccessWithBackgroundReconciler();
+ }
+
+ private void checkActiveElement() throws Exception {
+ ASTCache cache= new ASTCache();
+ assertFalse(cache.isActiveElement(fTU1));
+ assertFalse(cache.isActiveElement(fTU2));
+ cache.setActiveElement(fTU1);
+ assertTrue(cache.isActiveElement(fTU1));
+ assertFalse(cache.isActiveElement(fTU2));
+ cache.setActiveElement(fTU2);
+ assertFalse(cache.isActiveElement(fTU1));
+ assertTrue(cache.isActiveElement(fTU2));
+ }
+
+ private void checkSingleThreadAccess() throws Exception {
+ ASTCache cache= new ASTCache();
+ cache.setActiveElement(fTU1);
+ IASTTranslationUnit ast;
+ ast= cache.getAST(fTU1, fIndex, false, null);
+ assertNull(ast);
+ IProgressMonitor npm= new NullProgressMonitor();
+ npm.setCanceled(true);
+ ast= cache.getAST(fTU1, fIndex, true, npm);
+ assertNull(ast);
+ npm.setCanceled(false);
+ ast= cache.getAST(fTU1, fIndex, true, npm);
+ assertNotNull(ast);
+ }
+
+ private void checkAccessWithBackgroundReconciler() throws Exception {
+ ASTCache cache= new ASTCache();
+ cache.setActiveElement(fTU1);
+ MockReconciler reconciler1= new MockReconciler(fTU1, cache);
+ MockReconciler reconciler2= null;
+ try {
+ assertFalse(cache.isReconciling(fTU1));
+ reconciler1.start();
+ synchronized (reconciler1) {
+ reconciler1.wait();
+ }
+ IASTTranslationUnit ast;
+ ast= cache.getAST(fTU1, fIndex, true, null);
+ assertNotNull(ast);
+ assertSame(ast, reconciler1.fAST);
+
+ // change active element
+ cache.setActiveElement(fTU2);
+ reconciler2= new MockReconciler(fTU2, cache);
+ reconciler2.start();
+ synchronized (reconciler2) {
+ reconciler2.wait();
+ }
+ ast= cache.getAST(fTU2, fIndex, true, null);
+ assertNotNull(ast);
+ assertSame(ast, reconciler2.fAST);
+ } finally {
+ reconciler1.fStopped= true;
+ reconciler1.join(1000);
+ if (reconciler2 != null) {
+ reconciler2.fStopped= true;
+ reconciler2.join(1000);
+ }
+ }
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AllCoreTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AllCoreTests.java
index 423b189510c..223d165b9c7 100644
--- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AllCoreTests.java
+++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AllCoreTests.java
@@ -47,7 +47,7 @@ public class AllCoreTests {
suite.addTest(FailedDeclaratorsTest.suite());
suite.addTest(CPathEntryTest.suite());
suite.addTest(CConfigurationDescriptionReferenceTests.suite());
-
+ suite.addTest(ASTCacheTests.suite());
return suite;
}
diff --git a/core/org.eclipse.cdt.core/.options b/core/org.eclipse.cdt.core/.options
index 61c44b47d45..4b2af371095 100644
--- a/core/org.eclipse.cdt.core/.options
+++ b/core/org.eclipse.cdt.core/.options
@@ -35,3 +35,6 @@ org.eclipse.cdt.core/debug/indexer/problems=false
# Code formatter debugging
org.eclipse.cdt.core/debug/formatter=false
+
+# ASTCache debugging
+org.eclipse.cdt.core/debug/ASTCache=false
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ASTCache.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ASTCache.java
new file mode 100644
index 00000000000..9dce129d997
--- /dev/null
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ASTCache.java
@@ -0,0 +1,427 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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: Anton Leherbauer (Wind River Systems) - initial API and
+ * implementation
+ ******************************************************************************/
+package org.eclipse.cdt.internal.core.model;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
+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.ITranslationUnit;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.core.runtime.Status;
+
+/**
+ * Provides a shared AST of a single translation unit at a time.
+ *
+ * @since 4.0
+ */
+public class ASTCache {
+ /**
+ * Tells whether this class is in debug mode.
+ */
+ private static final boolean DEBUG= "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.cdt.core/debug/ASTCache")); //$NON-NLS-1$//$NON-NLS-2$
+ private static final String DEBUG_PREFIX= "[ASTCache] "; //$NON-NLS-1$
+
+ /** Full parse mode (no PDOM) */
+ public static int PARSE_MODE_FULL= 0;
+ /** Fast parse mode (use PDOM) */
+ public static int PARSE_MODE_FAST= ITranslationUnit.AST_SKIP_INDEXED_HEADERS;
+
+ /**
+ * Do something with an AST.
+ *
+ * @see #runOnAST(IASTTranslationUnit)
+ */
+ public static interface ASTRunnable {
+ /**
+ * Do something with the given AST.
+ *
+ * @param ast the translation unit AST, may be null
+ * @return a status object
+ */
+ IStatus runOnAST(IASTTranslationUnit ast);
+ }
+
+ private final int fParseMode;
+ private final Object fCacheMutex= new Object();
+
+ /** The active translation unit for which to cache the AST */
+ private ITranslationUnit fActiveTU;
+ /** The cached AST if any */
+ private IASTTranslationUnit fAST;
+ /**
+ * The timestamp of the last index write access at the time
+ * the AST got cached. A cached AST becomes invalid on any index
+ * write access afterwards.
+ */
+ private long fLastWriteOnIndex;
+ /** Inidicates whether the AST is currenty being computed */
+ private volatile boolean fIsReconciling;
+
+ /**
+ * Create a new AST cache.
+ */
+ public ASTCache() {
+ fParseMode= PARSE_MODE_FAST;
+ }
+
+ /**
+ * Returns a shared translation unit AST for the given
+ * translation unit.
+ *
+ * Clients are not allowed to modify the AST and must + * hold a read lock prior to calling this method and continue + * to hold the lock as long as the AST is being used. + *
+ * + * @param tUnit the translation unit + * @param index the index used to create the AST, needs to be read-locked + * @param wait iftrue
, wait for AST to be computed (might compute a new AST)
+ * @param progressMonitor the progress monitor or null
+ * @return the AST or null
if the AST is not available
+ */
+ public IASTTranslationUnit getAST(ITranslationUnit tUnit, IIndex index, boolean wait, IProgressMonitor progressMonitor) {
+ if (tUnit == null)
+ return null;
+
+ while (true) {
+ if (progressMonitor != null && progressMonitor.isCanceled())
+ return null;
+
+ final boolean isActiveElement;
+ synchronized (fCacheMutex) {
+ isActiveElement= tUnit.equals(fActiveTU);
+ if (isActiveElement) {
+ if (fAST != null) {
+ // AST is cached
+ if (fLastWriteOnIndex < index.getLastWriteAccess()) {
+ // AST has been invalidated by index write access
+ disposeAST();
+ } else {
+ // cached AST is valid
+ if (DEBUG)
+ System.out.println(DEBUG_PREFIX + getThreadName() + "returning cached AST:" + toString(fAST) + " for: " + tUnit.getElementName()); //$NON-NLS-1$ //$NON-NLS-2$
+ return fAST;
+ }
+ }
+ // no cached AST
+ if (!wait) {
+ // no AST, no wait - we are done
+ if (DEBUG)
+ System.out.println(DEBUG_PREFIX + getThreadName() + "returning null (WAIT_NO) for: " + tUnit.getElementName()); //$NON-NLS-1$
+ return null;
+ }
+ }
+ // no cached AST, but wait
+ if (isActiveElement && isReconciling(tUnit)) {
+ try {
+ final ICElement activeElement= fActiveTU;
+ // Wait for AST
+ if (DEBUG)
+ System.out.println(DEBUG_PREFIX + getThreadName() + "waiting for AST for: " + tUnit.getElementName()); //$NON-NLS-1$
+ fCacheMutex.wait();
+ // Check whether active element is still valid (
+ synchronized (this) {
+ if (activeElement == fActiveTU && fAST != null) {
+ if (DEBUG)
+ System.out.println(DEBUG_PREFIX + getThreadName() + "...got AST for: " + tUnit.getElementName()); //$NON-NLS-1$
+ return fAST;
+ }
+ }
+ // try again
+ continue;
+ } catch (InterruptedException e) {
+ return null; // thread has been interrupted don't compute AST
+ }
+ } else if (!wait) {
+ return null;
+ }
+ }
+
+ if (isActiveElement)
+ aboutToBeReconciled(tUnit);
+
+ if (DEBUG)
+ System.err.println(DEBUG_PREFIX + getThreadName() + "creating AST for " + tUnit.getElementName()); //$NON-NLS-1$
+
+ IASTTranslationUnit ast= null;
+ try {
+ ast= createAST(tUnit, index, progressMonitor);
+ if (progressMonitor != null && progressMonitor.isCanceled())
+ ast= null;
+ else if (DEBUG && ast != null)
+ System.err.println(DEBUG_PREFIX + getThreadName() + "created AST for: " + tUnit.getElementName()); //$NON-NLS-1$
+ } finally {
+ if (isActiveElement) {
+ if (fAST != null) {
+ if (DEBUG)
+ System.out.println(DEBUG_PREFIX + getThreadName() + "Ignore created AST for " + tUnit.getElementName() + "- AST from reconciler is newer"); //$NON-NLS-1$ //$NON-NLS-2$
+ // other reconciler was faster, still need to trigger notify
+ reconciled(fAST, tUnit);
+ } else
+ reconciled(ast, tUnit);
+ }
+ }
+ return ast;
+ }
+ }
+
+ /**
+ * Executes {@link ASTRunnable#runOnAST(IASTTranslationUnit)} with the AST
+ * provided by this cache for the given translation unit. Handles acquiring
+ * and releasing the index read-lock for the client.
+ *
+ * @param tUnit
+ * the translation unit
+ * @param wait
+ * true
if the AST should be computed or waited
+ * upon in case it is not yet available
+ * @param monitor a progress monitor, may be null
+ * @param astRunnable the runnable taking the AST
+ * @return the status returned by the ASTRunnable
+ */
+ public IStatus runOnAST(ITranslationUnit tUnit, boolean wait, IProgressMonitor monitor,
+ ASTRunnable astRunnable) {
+ IIndex index;
+ try {
+ index = CCorePlugin.getIndexManager().getIndex(tUnit.getCProject());
+ index.acquireReadLock();
+ } catch (CoreException e) {
+ return e.getStatus();
+ } catch (InterruptedException e) {
+ return Status.CANCEL_STATUS;
+ }
+
+ try {
+ IASTTranslationUnit ast= getAST(tUnit, index, wait, monitor);
+ return astRunnable.runOnAST(ast);
+ }
+ finally {
+ index.releaseReadLock();
+ }
+ }
+
+ /**
+ * Caches the given AST for the given translation unit.
+ *
+ * @param ast the AST
+ * @param tUnit the translation unit
+ */
+ private void cache(IASTTranslationUnit ast, ITranslationUnit tUnit) {
+ synchronized (fCacheMutex) {
+ if (fActiveTU != null && !fActiveTU.equals(tUnit)) {
+ if (DEBUG && tUnit != null) // don't report call from disposeAST()
+ System.out.println(DEBUG_PREFIX + getThreadName() + "don't cache AST for inactive: " + toString(tUnit)); //$NON-NLS-1$
+ return;
+ }
+
+ if (DEBUG && (tUnit != null || ast != null)) // don't report call from disposeAST()
+ System.out.println(DEBUG_PREFIX + getThreadName() + "caching AST: " + toString(ast) + " for: " + toString(tUnit)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ if (fAST != null)
+ disposeAST();
+
+ fAST= ast;
+ fLastWriteOnIndex= fAST == null ? 0 : fAST.getIndex().getLastWriteAccess();
+
+ // Signal AST change
+ fCacheMutex.notifyAll();
+ }
+ }
+
+ /**
+ * Disposes the cached AST.
+ */
+ public void disposeAST() {
+ synchronized (fCacheMutex) {
+ if (fAST == null)
+ return;
+
+ if (DEBUG)
+ System.out.println(DEBUG_PREFIX + getThreadName() + "disposing AST: " + toString(fAST) + " for: " + toString(fActiveTU)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ fAST= null;
+ cache(null, null);
+ }
+ }
+
+ /**
+ * Creates a new translation unit AST.
+ *
+ * @param tUnit the C element for which to create the AST
+ * @param index for AST generation, needs to be read-locked.
+ * @param progressMonitor the progress monitor
+ * @return AST
+ */
+ public IASTTranslationUnit createAST(final ITranslationUnit tUnit, final IIndex index, final IProgressMonitor progressMonitor) {
+ if (progressMonitor != null && progressMonitor.isCanceled())
+ return null;
+
+ final IASTTranslationUnit root[]= new IASTTranslationUnit[1];
+
+ SafeRunner.run(new ISafeRunnable() {
+ public void run() throws CoreException {
+ try {
+ if (progressMonitor != null && progressMonitor.isCanceled()) {
+ root[0]= null;
+ } else {
+ root[0]= tUnit.getAST(index, fParseMode);
+ }
+ } catch (OperationCanceledException ex) {
+ root[0]= null;
+ }
+ }
+ public void handleException(Throwable ex) {
+ IStatus status= new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, IStatus.OK, "Error in CDT Core during AST creation", ex); //$NON-NLS-1$
+ CCorePlugin.getDefault().getLog().log(status);
+ }
+ });
+
+ return root[0];
+ }
+
+ /**
+ * Set the given translation unit as active element to cache an AST for.
+ *
+ * @param tUnit
+ */
+ public void setActiveElement(ITranslationUnit tUnit) {
+ if (tUnit == fActiveTU) {
+ return;
+ }
+ fIsReconciling= false;
+ synchronized (fCacheMutex) {
+ fActiveTU= tUnit;
+ cache(null, tUnit);
+ }
+ if (DEBUG)
+ System.out.println(DEBUG_PREFIX + getThreadName() + "active element is: " + toString(tUnit)); //$NON-NLS-1$
+ }
+
+ /**
+ * Check whether the given translation unit is the active element of this cache.
+ *
+ * @param tUnit
+ * @return true
, if this cache manages the given translation unit
+ */
+ public boolean isActiveElement(ITranslationUnit tUnit) {
+ synchronized (fCacheMutex) {
+ return fActiveTU != null && fActiveTU.equals(tUnit);
+ }
+ }
+
+ /**
+ * Informs that reconciling (computation of the AST) for the given element
+ * is about to be started.
+ *
+ * @param tUnit the C element
+ * @see org.eclipse.cdt.internal.ui.text.ICReconcilingListener#aboutToBeReconciled()
+ */
+ public void aboutToBeReconciled(ITranslationUnit tUnit) {
+ if (tUnit == null)
+ return;
+ if (fActiveTU == null || !fActiveTU.equals(tUnit)) {
+ return;
+ }
+
+ if (DEBUG)
+ System.out.println(DEBUG_PREFIX + getThreadName() + "about to reconcile: " + toString(tUnit)); //$NON-NLS-1$
+
+ fIsReconciling= true;
+ cache(null, tUnit);
+ }
+
+ /**
+ * Informs that reconciling of the AST of the given translation unit has finished.
+ *
+ * @param ast
+ * @param tUnit
+ */
+ public void reconciled(IASTTranslationUnit ast, ITranslationUnit tUnit) {
+ synchronized (fCacheMutex) {
+ if (DEBUG)
+ System.out.println(DEBUG_PREFIX + getThreadName() + "reconciled: " + toString(tUnit) + ", AST: " + toString(ast)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ fIsReconciling= false;
+ if (tUnit == null || !tUnit.equals(fActiveTU)) {
+ if (DEBUG)
+ System.out.println(DEBUG_PREFIX + getThreadName() + " ignoring AST of out-dated element"); //$NON-NLS-1$
+
+ // Signal - threads might wait for wrong element
+ fCacheMutex.notifyAll();
+ return;
+ }
+ cache(ast, tUnit);
+ }
+ }
+
+ /**
+ * Tells whether the given C element is the one
+ * reported as currently being reconciled.
+ *
+ * @param tUnit the C element
+ * @return true
if reported as currently being reconciled
+ */
+ public boolean isReconciling(ITranslationUnit tUnit) {
+ synchronized (fCacheMutex) {
+ if (fActiveTU == null || tUnit == null) {
+ return false;
+ }
+ return fIsReconciling && (fActiveTU.equals(tUnit));
+ }
+ }
+
+ private static String getThreadName() {
+ String name= Thread.currentThread().getName();
+ if (name != null)
+ return name + ": "; //$NON-NLS-1$
+ else
+ return Thread.currentThread().toString() + ": "; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns a string for the given C element used for debugging.
+ *
+ * @param cElement the translation unit AST
+ * @return a string used for debugging
+ */
+ private static String toString(ICElement cElement) {
+ if (cElement == null)
+ return "null"; //$NON-NLS-1$
+ else
+ return cElement.getElementName();
+
+ }
+
+ /**
+ * Returns a string for the given AST used for debugging.
+ *
+ * @param ast the translation unit AST
+ * @return a string used for debugging
+ */
+ private static String toString(IASTTranslationUnit ast) {
+ if (ast == null)
+ return "null"; //$NON-NLS-1$
+
+ IASTNode[] nodes= ast.getDeclarations();
+ if (nodes != null && nodes.length > 0)
+ return nodes[0].getRawSignature();
+ else
+ return "AST without any declaration"; //$NON-NLS-1$
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/SemanticHighlightingTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/SemanticHighlightingTest.java
index 352bf12e60f..4243c7b9256 100644
--- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/SemanticHighlightingTest.java
+++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/SemanticHighlightingTest.java
@@ -131,7 +131,7 @@ public class SemanticHighlightingTest extends AbstractSemanticHighlightingTest {
createPosition(118, 4, 15),
};
Position[] actual= getSemanticHighlightingPositions();
- System.out.println(toString(actual));
+ if (PRINT_POSITIONS) System.out.println(toString(actual));
assertEqualPositions(expected, actual);
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ASTProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ASTProvider.java
index b6abe57ff4d..110538f0fc5 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ASTProvider.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ASTProvider.java
@@ -14,14 +14,8 @@
package org.eclipse.cdt.internal.ui.editor;
import org.eclipse.core.runtime.Assert;
-import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.OperationCanceledException;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.SafeRunner;
-import org.eclipse.core.runtime.Status;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IWindowListener;
import org.eclipse.ui.IWorkbenchPart;
@@ -29,21 +23,19 @@ import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
-import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.IPositionConverter;
-import org.eclipse.cdt.core.dom.ast.IASTNode;
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.ISourceReference;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.cdt.internal.core.model.ASTCache;
+
/**
* Provides a shared AST for clients. The shared AST is
* the AST of the active CEditor's input element.
- * Cloned from JDT.
*
* @since 4.0
*/
@@ -105,11 +97,6 @@ public final class ASTProvider {
/** Fast parse mode (use PDOM) */
public static int PARSE_MODE_FAST= ITranslationUnit.AST_SKIP_INDEXED_HEADERS;
- /**
- * Tells whether this class is in debug mode.
- */
- private static final boolean DEBUG= "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.cdt.ui/debug/ASTProvider")); //$NON-NLS-1$//$NON-NLS-2$
-
/**
* Internal activation listener.
*/
@@ -136,9 +123,6 @@ public final class ASTProvider {
*/
public void partClosed(IWorkbenchPartReference ref) {
if (isActiveEditor(ref)) {
- if (DEBUG)
- System.out.println(getThreadName() + " - " + DEBUG_PREFIX + "closed active editor: " + ref.getTitle()); //$NON-NLS-1$ //$NON-NLS-2$
-
activeEditorChanged(null);
}
}
@@ -199,9 +183,6 @@ public final class ASTProvider {
*/
public void windowClosed(IWorkbenchWindow window) {
if (fActiveEditor != null && fActiveEditor.getSite() != null && window == fActiveEditor.getSite().getWorkbenchWindow()) {
- if (DEBUG)
- System.out.println(getThreadName() + " - " + DEBUG_PREFIX + "closed active editor: " + fActiveEditor.getTitle()); //$NON-NLS-1$ //$NON-NLS-2$
-
activeEditorChanged(null);
}
window.getPartService().removePartListener(this);
@@ -232,23 +213,10 @@ public final class ASTProvider {
}
}
- private static final String DEBUG_PREFIX= "ASTProvider > "; //$NON-NLS-1$
-
-
- private ICElement fReconcilingCElement;
- private ICElement fActiveCElement;
- private IPositionConverter fActivePositionConverter;
- private IASTTranslationUnit fAST;
+ private ASTCache fCache= new ASTCache();
private ActivationListener fActivationListener;
- private Object fReconcileLock= new Object();
- private Object fWaitLock= new Object();
- private boolean fIsReconciling;
private IWorkbenchPart fActiveEditor;
- protected int fParseMode= PARSE_MODE_FAST;
-
- private long fLastWriteOnIndex= -1;
-
/**
* Returns the C plug-in's AST provider.
*
@@ -282,41 +250,14 @@ public final class ASTProvider {
}
private void activeEditorChanged(IWorkbenchPart editor) {
-
ICElement cElement= null;
if (editor instanceof CEditor) {
cElement= ((CEditor)editor).getInputCElement();
}
-
synchronized (this) {
fActiveEditor= editor;
- fActiveCElement= cElement;
- cache(null, null, cElement);
+ fCache.setActiveElement((ITranslationUnit)cElement);
}
-
- if (DEBUG)
- System.out.println(getThreadName() + " - " + DEBUG_PREFIX + "active editor is: " + toString(cElement)); //$NON-NLS-1$ //$NON-NLS-2$
-
- synchronized (fReconcileLock) {
- if (fIsReconciling && (fReconcilingCElement == null || !fReconcilingCElement.equals(cElement))) {
- fIsReconciling= false;
- fReconcilingCElement= null;
- } else if (cElement == null) {
- fIsReconciling= false;
- fReconcilingCElement= null;
- }
- }
- }
-
- /**
- * Returns whether the given translation unit AST is
- * cached by this AST provided.
- *
- * @param ast the translation unit AST
- * @return true
if the given AST is the cached one
- */
- public boolean isCached(IASTTranslationUnit ast) {
- return ast != null && fAST == ast;
}
/**
@@ -327,7 +268,7 @@ public final class ASTProvider {
* @return true
if the given translation unit is the active one
*/
public boolean isActive(ITranslationUnit tu) {
- return tu != null && tu.equals(fActiveCElement);
+ return fCache.isActiveElement(tu);
}
/**
@@ -337,95 +278,10 @@ public final class ASTProvider {
* @see org.eclipse.cdt.internal.ui.text.ICReconcilingListener#aboutToBeReconciled()
*/
void aboutToBeReconciled(ICElement cElement) {
-
if (cElement == null)
return;
-
- if (DEBUG)
- System.out.println(getThreadName() + " - " + DEBUG_PREFIX + "about to reconcile: " + toString(cElement)); //$NON-NLS-1$ //$NON-NLS-2$
-
- synchronized (fReconcileLock) {
- fIsReconciling= true;
- fReconcilingCElement= cElement;
- }
- cache(null, null, cElement);
- }
-
- /**
- * Disposes the cached AST.
- */
- private synchronized void disposeAST() {
-
- if (fAST == null)
- return;
-
- if (DEBUG)
- System.out.println(getThreadName() + " - " + DEBUG_PREFIX + "disposing AST: " + toString(fAST) + " for: " + toString(fActiveCElement)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-
- fAST= null;
-
- cache(null, null, null);
- }
-
- /**
- * Returns a string for the given C element used for debugging.
- *
- * @param cElement the translation unit AST
- * @return a string used for debugging
- */
- private String toString(ICElement cElement) {
- if (cElement == null)
- return "null"; //$NON-NLS-1$
- else
- return cElement.getElementName();
-
- }
-
- /**
- * Returns a string for the given AST used for debugging.
- *
- * @param ast the translation unit AST
- * @return a string used for debugging
- */
- private String toString(IASTTranslationUnit ast) {
- if (ast == null)
- return "null"; //$NON-NLS-1$
-
- IASTNode[] nodes= ast.getDeclarations();
- if (nodes != null && nodes.length > 0)
- return nodes[0].getRawSignature();
- else
- return "AST without any declaration"; //$NON-NLS-1$
- }
-
- /**
- * Caches the given translation unit AST for the given C element.
- *
- * @param ast
- * @param cElement
- */
- private synchronized void cache(IASTTranslationUnit ast, IPositionConverter converter, ICElement cElement) {
-
- if (fActiveCElement != null && !fActiveCElement.equals(cElement)) {
- if (DEBUG && cElement != null) // don't report call from disposeAST()
- System.out.println(getThreadName() + " - " + DEBUG_PREFIX + "don't cache AST for inactive: " + toString(cElement)); //$NON-NLS-1$ //$NON-NLS-2$
- return;
- }
-
- if (DEBUG && (cElement != null || ast != null)) // don't report call from disposeAST()
- System.out.println(getThreadName() + " - " + DEBUG_PREFIX + "caching AST: " + toString(ast) + " for: " + toString(cElement)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-
- if (fAST != null)
- disposeAST();
-
- fAST= ast;
- fLastWriteOnIndex= fAST == null ? 0 : fAST.getIndex().getLastWriteAccess();
- fActivePositionConverter= converter;
-
- // Signal AST change
- synchronized (fWaitLock) {
- fWaitLock.notifyAll();
- }
+ Assert.isTrue(cElement instanceof ITranslationUnit);
+ fCache.aboutToBeReconciled((ITranslationUnit)cElement);
}
/**
@@ -445,248 +301,48 @@ public final class ASTProvider {
public IASTTranslationUnit getAST(ICElement cElement, IIndex index, WAIT_FLAG waitFlag, IProgressMonitor progressMonitor) {
if (cElement == null)
return null;
-
Assert.isTrue(cElement instanceof ITranslationUnit);
-
- if (progressMonitor != null && progressMonitor.isCanceled())
- return null;
-
- boolean isActiveElement;
- synchronized (this) {
- isActiveElement= cElement.equals(fActiveCElement);
- if (isActiveElement) {
- if (fAST != null) {
- if (fLastWriteOnIndex < index.getLastWriteAccess()) {
- disposeAST();
- }
- else {
- if (DEBUG)
- System.out.println(getThreadName() + " - " + DEBUG_PREFIX + "returning cached AST:" + toString(fAST) + " for: " + cElement.getElementName()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-
- return fAST;
- }
- }
- if (waitFlag == WAIT_NO) {
- if (DEBUG)
- System.out.println(getThreadName() + " - " + DEBUG_PREFIX + "returning null (WAIT_NO) for: " + cElement.getElementName()); //$NON-NLS-1$ //$NON-NLS-2$
-
- return null;
- }
- }
- }
- if (isActiveElement && isReconciling(cElement)) {
- try {
- final ICElement activeElement= fReconcilingCElement;
-
- // Wait for AST
- synchronized (fWaitLock) {
- if (DEBUG)
- System.out.println(getThreadName() + " - " + DEBUG_PREFIX + "waiting for AST for: " + cElement.getElementName()); //$NON-NLS-1$ //$NON-NLS-2$
-
- // don't wait forever, notify might have happened already
- fWaitLock.wait(1000);
- }
-
- // Check whether active element is still valid
- synchronized (this) {
- if (activeElement == fActiveCElement && fAST != null) {
- if (DEBUG)
- System.out.println(getThreadName() + " - " + DEBUG_PREFIX + "...got AST for: " + cElement.getElementName()); //$NON-NLS-1$ //$NON-NLS-2$
-
- return fAST;
- }
- }
- return getAST(cElement, index, waitFlag, progressMonitor);
- } catch (InterruptedException e) {
- return null; // thread has been interrupted don't compute AST
- }
- } else if (waitFlag == WAIT_NO || (waitFlag == WAIT_ACTIVE_ONLY && !(isActiveElement && fAST == null)))
- return null;
-
- if (isActiveElement)
- aboutToBeReconciled(cElement);
-
- if (DEBUG)
- System.err.println(getThreadName() + " - " + DEBUG_PREFIX + "creating AST for " + cElement.getElementName()); //$NON-NLS-1$ //$NON-NLS-2$
-
- IASTTranslationUnit ast= null;
- try {
- ast= createAST(cElement, index, progressMonitor);
- if (progressMonitor != null && progressMonitor.isCanceled())
- ast= null;
- else if (DEBUG && ast != null)
- System.err.println(getThreadName() + " - " + DEBUG_PREFIX + "created AST for: " + cElement.getElementName()); //$NON-NLS-1$ //$NON-NLS-2$
- } finally {
- if (isActiveElement) {
- if (fAST != null) {
- if (DEBUG)
- System.out.println(getThreadName() + " - " + DEBUG_PREFIX + "Ignore created AST for " + cElement.getElementName() + "- AST from reconciler is newer"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- reconciled(fAST, fActivePositionConverter, cElement, null);
- } else
- reconciled(ast, null, cElement, null);
- }
- }
- return ast;
+ return fCache.getAST((ITranslationUnit)cElement, index, waitFlag != WAIT_NO, progressMonitor);
}
- /**
- * Tells whether the given C element is the one
- * reported as currently being reconciled.
- *
- * @param cElement the C element
- * @return true
if reported as currently being reconciled
- */
- private boolean isReconciling(ICElement cElement) {
- synchronized (fReconcileLock) {
- return cElement != null && cElement.equals(fReconcilingCElement) && fIsReconciling;
- }
- }
-
- /**
- * Creates a new translation unit AST.
- *
- * @param cElement the C element for which to create the AST
- * @param index for AST generation, needs to be read-locked.
- * @param progressMonitor the progress monitor
- * @return AST
- */
- IASTTranslationUnit createAST(ICElement cElement, final IIndex index, final IProgressMonitor progressMonitor) {
- if (!hasSource(cElement))
- return null;
-
- if (progressMonitor != null && progressMonitor.isCanceled())
- return null;
-
- if (!(cElement instanceof ITranslationUnit))
- return null;
-
- final ITranslationUnit tu= (ITranslationUnit)cElement;
- final IASTTranslationUnit root[]= new IASTTranslationUnit[1];
-
- SafeRunner.run(new ISafeRunnable() {
- public void run() throws CoreException {
- try {
- if (progressMonitor != null && progressMonitor.isCanceled()) {
- root[0]= null;
- } else {
- root[0]= tu.getAST(index, fParseMode);
- }
- } catch (OperationCanceledException ex) {
- root[0]= null;
- }
- }
- public void handleException(Throwable ex) {
- IStatus status= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, IStatus.OK, "Error in CDT Core during AST creation", ex); //$NON-NLS-1$
- CUIPlugin.getDefault().getLog().log(status);
- }
- });
-
- return root[0];
- }
-
- /**
- * Checks whether the given C element has accessible source.
- *
- * @param cElement the C element to test
- * @return true
if the element has source
- */
- private boolean hasSource(ICElement cElement) {
- if (cElement == null || !cElement.exists())
- return false;
-
- try {
- return cElement instanceof ISourceReference /* && ((ISourceReference)cElement).getSource() != null */;
- } catch (Exception ex) {
- IStatus status= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, IStatus.OK, "Error in CDT Core during AST creation", ex); //$NON-NLS-1$
- CUIPlugin.getDefault().getLog().log(status);
- }
- return false;
- }
-
/**
* Disposes this AST provider.
*/
public void dispose() {
-
if (fActivationListener != null) {
// Dispose activation listener
PlatformUI.getWorkbench().removeWindowListener(fActivationListener);
fActivationListener= null;
}
- disposeAST();
-
- synchronized (fWaitLock) {
- fWaitLock.notifyAll();
- }
+ fCache.disposeAST();
}
/*
* @see org.eclipse.cdt.internal.ui.text.ICReconcilingListener#reconciled()
*/
void reconciled(IASTTranslationUnit ast, IPositionConverter converter, ICElement cElement, IProgressMonitor progressMonitor) {
-
- if (DEBUG)
- System.out.println(getThreadName() + " - " + DEBUG_PREFIX + "reconciled: " + toString(cElement) + ", AST: " + toString(ast)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-
- synchronized (fReconcileLock) {
-
- fIsReconciling= progressMonitor != null && progressMonitor.isCanceled();
- if (cElement == null || !cElement.equals(fReconcilingCElement)) {
-
- if (DEBUG)
- System.out.println(getThreadName() + " - " + DEBUG_PREFIX + " ignoring AST of out-dated editor"); //$NON-NLS-1$ //$NON-NLS-2$
-
- // Signal - threads might wait for wrong element
- synchronized (fWaitLock) {
- fWaitLock.notifyAll();
- }
-
- return;
- }
-
- cache(ast, converter, cElement);
- }
- }
-
- private static String getThreadName() {
- String name= Thread.currentThread().getName();
- if (name != null)
- return name;
- else
- return Thread.currentThread().toString();
- }
-
- /**
- * @param element
- * @return the position converter for the AST of the active element or null
- */
- public IPositionConverter getActivePositionConverter(ICElement element) {
- if (fActiveCElement == element) {
- return fActivePositionConverter;
- }
- return null;
+ if (cElement == null)
+ return;
+ Assert.isTrue(cElement instanceof ITranslationUnit);
+ fCache.reconciled(ast, (ITranslationUnit)cElement);
}
public IStatus runOnAST(ICElement cElement, WAIT_FLAG waitFlag, IProgressMonitor monitor,
- ASTRunnable astRunnable) {
- IIndex index;
- try {
- index = CCorePlugin.getIndexManager().getIndex(cElement.getCProject());
- index.acquireReadLock();
- } catch (CoreException e) {
- return e.getStatus();
- } catch (InterruptedException e) {
- return Status.CANCEL_STATUS;
- }
-
- try {
- IASTTranslationUnit ast= getAST(cElement, index, waitFlag, monitor);
- return astRunnable.runOnAST(ast);
- }
- finally {
- index.releaseReadLock();
- }
+ ASTCache.ASTRunnable astRunnable) {
+ Assert.isTrue(cElement instanceof ITranslationUnit);
+ return fCache.runOnAST((ITranslationUnit)cElement, waitFlag != WAIT_NO, monitor, astRunnable);
+ }
+
+ /**
+ * @param cElement
+ * @param index
+ * @param monitor
+ * @return an AST or null
, 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);
}
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/InactiveCodeHighlighting.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/InactiveCodeHighlighting.java
index 71034e3e518..520750da3a7 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/InactiveCodeHighlighting.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/InactiveCodeHighlighting.java
@@ -40,8 +40,9 @@ import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.cdt.internal.core.model.ASTCache;
+
import org.eclipse.cdt.internal.ui.LineBackgroundPainter;
-import org.eclipse.cdt.internal.ui.editor.ASTProvider.ASTRunnable;
import org.eclipse.cdt.internal.ui.text.ICReconcilingListener;
/**
@@ -101,7 +102,7 @@ public class InactiveCodeHighlighting implements ICReconcilingListener {
IStatus result = Status.OK_STATUS;
if (fTranslationUnit != null) {
final ASTProvider astProvider= CUIPlugin.getDefault().getASTProvider();
- result= astProvider.runOnAST(fTranslationUnit, ASTProvider.WAIT_YES, monitor, new ASTRunnable() {
+ result= astProvider.runOnAST(fTranslationUnit, ASTProvider.WAIT_YES, monitor, new ASTCache.ASTRunnable() {
public IStatus runOnAST(IASTTranslationUnit ast) {
reconciled(ast, null, monitor);
return Status.OK_STATUS;
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java
index 6c29a551764..33b1967d1dc 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java
@@ -43,6 +43,7 @@ import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.IInclude;
import org.eclipse.cdt.core.parser.ExtendedScannerInfo;
import org.eclipse.cdt.core.parser.IExtendedScannerInfo;
import org.eclipse.cdt.core.parser.IScannerInfo;
@@ -96,17 +97,22 @@ public class OpenIncludeAction extends Action {
if (info == null) {
info = provider.getScannerInformation(proj);
}
- if (info != null) {
- // search in system includes
- String[] includePaths = info.getIncludePaths();
- findFile(includePaths, includeName, filesFound);
+
+ boolean isSystemInclude = include instanceof IInclude
+ && ((IInclude) include).isStandard();
+
+ // search in user includes
+ if (!isSystemInclude && info != null) {
+ IExtendedScannerInfo scanInfo = new ExtendedScannerInfo(info);
+ String[] localIncludePaths = scanInfo.getLocalIncludePath();
+ findFile(localIncludePaths, includeName, filesFound);
}
+
if (filesFound.size() == 0) {
- // search in local includes
if (info != null) {
- IExtendedScannerInfo scanInfo = new ExtendedScannerInfo(info);
- String[] localIncludePaths = scanInfo.getLocalIncludePath();
- findFile(localIncludePaths, includeName, filesFound);
+ // search in system includes
+ String[] includePaths = info.getIncludePaths();
+ findFile(includePaths, includeName, filesFound);
}
if (filesFound.size() == 0) {
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightingReconciler.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightingReconciler.java
index b70432670c3..b0a49f0a6ea 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightingReconciler.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightingReconciler.java
@@ -45,7 +45,8 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.ui.CUIPlugin;
-import org.eclipse.cdt.internal.ui.editor.ASTProvider.ASTRunnable;
+import org.eclipse.cdt.internal.core.model.ASTCache;
+
import org.eclipse.cdt.internal.ui.editor.SemanticHighlightingManager.HighlightedPosition;
import org.eclipse.cdt.internal.ui.editor.SemanticHighlightingManager.HighlightingStyle;
import org.eclipse.cdt.internal.ui.text.ICReconcilingListener;
@@ -513,7 +514,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
final Job me= this;
ASTProvider astProvider= CUIPlugin.getDefault().getASTProvider();
- IStatus status= astProvider.runOnAST(element, ASTProvider.WAIT_YES, monitor, new ASTRunnable() {
+ IStatus status= astProvider.runOnAST(element, ASTProvider.WAIT_YES, monitor, new ASTCache.ASTRunnable() {
public IStatus runOnAST(IASTTranslationUnit ast) {
reconciled(ast, null, monitor);
synchronized (fJobLock) {
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CReconcilingStrategy.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CReconcilingStrategy.java
index 1b35886b2be..a870e69860e 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CReconcilingStrategy.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CReconcilingStrategy.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * Copyright (c) 2005, 2007 IBM Corporation 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
@@ -140,6 +140,7 @@ public class CReconcilingStrategy implements IReconcilingStrategy, IReconcilingS
index.acquireReadLock();
} catch (InterruptedException exc) {
ast= null;
+ index= null;
}
}
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/DefaultCFoldingStructureProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/DefaultCFoldingStructureProvider.java
index 26ad851637d..76cf0388b7d 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/DefaultCFoldingStructureProvider.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/DefaultCFoldingStructureProvider.java
@@ -72,9 +72,10 @@ import org.eclipse.cdt.ui.PreferenceConstants;
import org.eclipse.cdt.ui.text.ICPartitions;
import org.eclipse.cdt.ui.text.folding.ICFoldingStructureProvider;
+import org.eclipse.cdt.internal.core.model.ASTCache;
+
import org.eclipse.cdt.internal.ui.editor.ASTProvider;
import org.eclipse.cdt.internal.ui.editor.CEditor;
-import org.eclipse.cdt.internal.ui.editor.ASTProvider.ASTRunnable;
import org.eclipse.cdt.internal.ui.text.DocumentCharacterIterator;
import org.eclipse.cdt.internal.ui.text.ICReconcilingListener;
@@ -1093,11 +1094,11 @@ public class DefaultCFoldingStructureProvider implements ICFoldingStructureProvi
IASTTranslationUnit ast= ctx.getAST();
if (ast == null) {
final ASTProvider astProvider= CUIPlugin.getDefault().getASTProvider();
- IStatus status= astProvider.runOnAST(getInputElement(), ASTProvider.WAIT_ACTIVE_ONLY, null, new ASTRunnable() {
+ IStatus status= astProvider.runOnAST(getInputElement(), ASTProvider.WAIT_ACTIVE_ONLY, null, new ASTCache.ASTRunnable() {
public IStatus runOnAST(IASTTranslationUnit ast) {
if (ast != null) {
ctx.fAST= ast;
- ctx.fASTPositionConverter= astProvider.getActivePositionConverter(getInputElement());
+ ctx.fASTPositionConverter= null;
fInitialASTReconcile= false;
computeFoldingStructure(ast, ctx);
}