diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/CModelElementsTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/CModelElementsTests.java index ec3d8a0cb30..e32c4a9bed7 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/CModelElementsTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/CModelElementsTests.java @@ -70,7 +70,7 @@ public class CModelElementsTests extends TestCase { protected void setUp() throws Exception { monitor = new NullProgressMonitor(); - fCProject= CProjectHelper.createCCProject("TestProject1", "bin", IPDOMManager.ID_NO_INDEXER); + fCProject= CProjectHelper.createCCProject("TestProject1", "bin", IPDOMManager.ID_FAST_INDEXER); headerFile = fCProject.getProject().getFile("CModelElementsTest.h"); includedFile = fCProject.getProject().getFile("included.h"); if (!headerFile.exists()) { diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/IntegratedCModelTest.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/IntegratedCModelTest.java index fb54d2acd1c..aeb10c3861a 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/IntegratedCModelTest.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/IntegratedCModelTest.java @@ -71,7 +71,7 @@ public abstract class IntegratedCModelTest extends TestCase { public void setUp() throws Exception { monitor = new NullProgressMonitor(); - fCProject= CProjectHelper.createCCProject("TestProject1", "bin", IPDOMManager.ID_NO_INDEXER); + fCProject= CProjectHelper.createCCProject("TestProject1", "bin", IPDOMManager.ID_FAST_INDEXER); sourceFile = fCProject.getProject().getFile( getSourcefileResource() ); if (!sourceFile.exists()) { try{ @@ -84,6 +84,7 @@ public abstract class IntegratedCModelTest extends TestCase { e.printStackTrace(); } } + CCorePlugin.getIndexManager().joinIndexer(2000, new NullProgressMonitor()); } protected void tearDown() { @@ -99,7 +100,7 @@ public abstract class IntegratedCModelTest extends TestCase { tu.close(); tu.open(new NullProgressMonitor()); CCorePlugin.getDefault().setStructuralParseMode(false); - CCorePlugin.getDefault().setUseNewModelBuilder(false); + CCorePlugin.getDefault().setUseNewModelBuilder(true); return tu; } /** diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/StructuralCModelElementsTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/StructuralCModelElementsTests.java index 6b6533c651b..f911d0a4a6e 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/StructuralCModelElementsTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/StructuralCModelElementsTests.java @@ -71,7 +71,7 @@ public class StructuralCModelElementsTests extends TestCase { protected void setUp() throws Exception { monitor = new NullProgressMonitor(); - fCProject= CProjectHelper.createCCProject("TestProject1", "bin", IPDOMManager.ID_NO_INDEXER); //$NON-NLS-1$ //$NON-NLS-2$ + fCProject= CProjectHelper.createCCProject("TestProject1", "bin", IPDOMManager.ID_FAST_INDEXER); //$NON-NLS-1$ //$NON-NLS-2$ headerFile = fCProject.getProject().getFile("CModelElementsTest.h"); //$NON-NLS-1$ includedFile = fCProject.getProject().getFile("included.h"); //$NON-NLS-1$ if (!headerFile.exists()) { diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/TranslationUnitBaseTest.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/TranslationUnitBaseTest.java index 737ea849866..f5b0fb26bbf 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/TranslationUnitBaseTest.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/TranslationUnitBaseTest.java @@ -14,6 +14,7 @@ import java.io.FileInputStream; import junit.framework.TestCase; +import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.IPDOMManager; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.testplugin.CProjectHelper; @@ -96,7 +97,7 @@ public class TranslationUnitBaseTest extends TestCase * tests */ - testProject=CProjectHelper.createCProject("filetest", "none", IPDOMManager.ID_NO_INDEXER); + testProject=CProjectHelper.createCProject("filetest", "none", IPDOMManager.ID_FAST_INDEXER); if (testProject==null) fail("Unable to create project"); @@ -140,8 +141,8 @@ public class TranslationUnitBaseTest extends TestCase } archpath=new Path(workspace.getRoot().getLocation()+"/filetest/libtestlib_g.a"); - - } + CCorePlugin.getIndexManager().joinIndexer(1000, new NullProgressMonitor()); + } /** * Tears down the test fixture. * diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/TranslationUnitTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/TranslationUnitTests.java index b110ca4992d..66c6e745972 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/TranslationUnitTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/TranslationUnitTests.java @@ -39,7 +39,7 @@ public class TranslationUnitTests extends TranslationUnitBaseTest { * number of places in the tests */ String[] expectedStringList = { "stdio.h", "unistd.h", "func2p", - "globalvar", "myenum", "mystruct", "mystruct_t", "myunion", + "globalvar", "myenum", "mystruct_t", "myunion", "mytype", "func1", "func2", "main", "func3" }; int[] expectedLines = { 12, 14, 17, 20, 23, 28, 32, 35, 42, 47, 53, 58, 65, diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IWorkingCopy.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IWorkingCopy.java index 1de12b00a2f..a141d7e3c4d 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IWorkingCopy.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IWorkingCopy.java @@ -12,6 +12,7 @@ package org.eclipse.cdt.core.model; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IProgressMonitor; @@ -122,11 +123,43 @@ public interface IWorkingCopy extends ITranslationUnit{ * over the cached contents and the new contents, and finally firing * this delta. *

- * The boolean argument allows to force problem detection even if the - * working copy is already consistent. + * @param forceProblemDetection The boolean argument allows to force problem + * detection even if the working copy is already consistent. + * @param monitor a progress monitor + * @throw CModelException if the contents of the original element + * cannot be accessed */ void reconcile(boolean forceProblemDetection, IProgressMonitor monitor) throws CModelException; + /** + * Reconciles the contents of this working copy. + * It performs the reconciliation by locally caching the contents of + * the working copy, updating the contents, then creating a delta + * over the cached contents and the new contents, and finally firing + * this delta. + *

+ * The boolean argument allows to force problem detection even if the + * working copy is already consistent. + * + *

+ * EXPERIMENTAL. This method has been added as + * part of a work in progress. There is no guarantee that this API will work or + * that it will remain the same. Please do not use this API without consulting + * with the CDT team. + *

+ * + * @param computeAST flag to indicate if an AST should be returned + * @param forceProblemDetection The boolean argument allows to force problem + * detection even if the working copy is already consistent. + * @param monitor a progress monitor + * @return the AST or null + * @throw CModelException if the contents of the original element + * cannot be accessed + * + * @since 4.0 + */ + IASTTranslationUnit reconcile(boolean computeAST, boolean forceProblemDetection, IProgressMonitor monitor) throws CModelException; + /** * Restores the contents of this working copy to the current contents of * this working copy's original element. Has no effect if this element diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ASTHolderTUInfo.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ASTHolderTUInfo.java new file mode 100644 index 00000000000..e57addba0b9 --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ASTHolderTUInfo.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2006 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.dom.ast.IASTTranslationUnit; + +public class ASTHolderTUInfo extends TranslationUnitInfo { + + public IASTTranslationUnit fAST; + + /** + * @param translationUnit + */ + public ASTHolderTUInfo(TranslationUnit translationUnit) { + super(translationUnit); + } + +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder.java index fb239ff4615..368974bacb6 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder.java @@ -384,9 +384,15 @@ public class CModelBuilder { private void generateModelElements (Parent parent, IASTTypedefDeclaration declaration) throws CModelException, ASTNotImplementedException { - createTypeDef(parent, declaration); + Parent typeDef= createTypeDef(parent, declaration); + if (typeDef instanceof IParent) { + // create nested + parent= typeDef; + } IASTAbstractDeclaration abstractDeclaration = declaration.getAbstractDeclarator(); - createAbstractElement(parent, abstractDeclaration, false, true); + if (abstractDeclaration != null && !(abstractDeclaration.getTypeSpecifier() instanceof IASTElaboratedTypeSpecifier)) { + createAbstractElement(parent, abstractDeclaration, false, true); + } } private CElement createClassSpecifierElement(Parent parent, IASTClassSpecifier classSpecifier, boolean isTemplate)throws ASTNotImplementedException, CModelException{ diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder2.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder2.java index 975776ba8e6..5995a256d58 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder2.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder2.java @@ -12,10 +12,12 @@ package org.eclipse.cdt.internal.core.model; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.List; import java.util.Stack; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.IPDOMManager; import org.eclipse.cdt.core.dom.ast.ASTSignatureUtil; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTASMDeclaration; @@ -66,6 +68,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.index.IIndex; +import org.eclipse.cdt.core.index.IIndexManager; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.IContributedModelBuilder; @@ -79,6 +82,9 @@ import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclaration; import org.eclipse.cdt.internal.core.dom.parser.IASTDeclarationAmbiguity; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; /** * Build TranslationUnit structure from an IASTTranslationUnit. @@ -204,23 +210,31 @@ public class CModelBuilder2 implements IContributedModelBuilder { private String fTranslationUnitFileName; private ASTAccessVisibility fCurrentVisibility; private Stack fVisibilityStack; + private IProgressMonitor fProgressMonitor; /** * Create a model builder for the given translation unit. * * @param tu the translation unit (must be a {@link TranslationUnit} + * @param monitor the progress monitor */ - public CModelBuilder2(ITranslationUnit tu) { + public CModelBuilder2(ITranslationUnit tu, IProgressMonitor monitor) { fTranslationUnit= (TranslationUnit)tu; + fProgressMonitor= monitor; } /* * @see org.eclipse.cdt.core.model.IContributedModelBuilder#parse(boolean) */ public void parse(boolean quickParseMode) throws Exception { - // always parse fast - quickParseMode= true; - IIndex index= CCorePlugin.getIndexManager().getIndex(fTranslationUnit.getCProject()); + if (isIndexerDisabled()) { + // fallback to old model builder + new CModelBuilder(fTranslationUnit, new HashMap()).parse(true); + return; + } + final IIndexManager indexManager= CCorePlugin.getIndexManager(); + IIndex index= indexManager.getIndex(fTranslationUnit.getCProject()); + try { if (index != null) { try { @@ -229,20 +243,29 @@ public class CModelBuilder2 implements IContributedModelBuilder { index= null; } } + checkCanceled(); long startTime= System.currentTimeMillis(); - final IASTTranslationUnit ast= fTranslationUnit.getAST(index, quickParseMode ? ITranslationUnit.AST_SKIP_ALL_HEADERS : 0); - if (ast == null) { - return; - } + final IASTTranslationUnit ast= fTranslationUnit.getAST(index, ITranslationUnit.AST_SKIP_ALL_HEADERS); Util.debugLog("CModelBuilder2: parsing " //$NON-NLS-1$ + fTranslationUnit.getElementName() + " mode="+ (quickParseMode ? "fast " : "full ") //$NON-NLS-1$ //$NON-NLS-2$ + " time="+ ( System.currentTimeMillis() - startTime ) + "ms", //$NON-NLS-1$ //$NON-NLS-2$ IDebugLogConstants.MODEL, false); + final CElementInfo elementInfo= fTranslationUnit.getElementInfo(); + if (elementInfo instanceof ASTHolderTUInfo) { + ((ASTHolderTUInfo)elementInfo).fAST= ast; + } + + if (ast == null) { + checkCanceled(); + // fallback to old model builder + new CModelBuilder(fTranslationUnit, new HashMap()).parse(true); + return; + } startTime= System.currentTimeMillis(); buildModel(ast); - fTranslationUnit.getElementInfo().setIsStructureKnown(true); + elementInfo.setIsStructureKnown(true); Util.debugLog("CModelBuilder2: building " //$NON-NLS-1$ +"children="+ fTranslationUnit.getElementInfo().internalGetChildren().size() //$NON-NLS-1$ +" time="+ (System.currentTimeMillis() - startTime) + "ms", //$NON-NLS-1$ //$NON-NLS-2$ @@ -254,6 +277,27 @@ public class CModelBuilder2 implements IContributedModelBuilder { } } + private boolean isCanceled() { + return fProgressMonitor != null && fProgressMonitor.isCanceled(); + } + + private void checkCanceled() { + if (fProgressMonitor != null && fProgressMonitor.isCanceled()) { + Util.debugLog("CModelBuilder2: cancelled ", IDebugLogConstants.MODEL, false); //$NON-NLS-1$ + throw new OperationCanceledException(); + } + } + + private boolean isIndexerDisabled() { + final IPDOMManager pdomManager= CCorePlugin.getPDOMManager(); + try { + return IPDOMManager.ID_NO_INDEXER.equals(pdomManager.getIndexerId(fTranslationUnit.getCProject())); + } catch (CoreException exc) { + CCorePlugin.log(exc.getStatus()); + } + return true; + } + /** * Build the model from the given AST. * @param ast @@ -312,6 +356,10 @@ public class CModelBuilder2 implements IContributedModelBuilder { } }}); + if (isCanceled()) { + return; + } + // report problems IProblemRequestor problemRequestor= fTranslationUnit.getProblemRequestor(); if (problemRequestor == null && PRINT_PROBLEMS) { diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Openable.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Openable.java index 1dc734fac47..143efa0edb7 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Openable.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Openable.java @@ -12,8 +12,6 @@ package org.eclipse.cdt.internal.core.model; import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; import java.util.Map; import org.eclipse.cdt.core.model.BufferChangedEvent; @@ -204,38 +202,8 @@ public abstract class Openable extends Parent implements IOpenable, IBufferChang } public void makeConsistent(IProgressMonitor monitor, boolean forced) throws CModelException { - if (isConsistent()) { - return; - } - - // create a new info and make it the current info - // (this will remove the info and its children just before storing the new infos) - CModelManager manager = CModelManager.getDefault(); - boolean hadTemporaryCache = manager.hasTemporaryCache(); - try { - HashMap newElements = manager.getTemporaryCache(); - CElementInfo info = createElementInfo(); - openWhenClosed(info, monitor); - if (newElements.get(this) == null) { - // close any buffer that was opened for the new elements - Iterator iterator = newElements.keySet().iterator(); - while (iterator.hasNext()) { - ICElement element = (ICElement)iterator.next(); - if (element instanceof Openable) { - ((Openable)element).closeBuffer(); - } - } - throw newNotPresentException(); - } - if (!hadTemporaryCache) { - manager.putInfos(this, newElements); - } - } finally { - if (!hadTemporaryCache) { - manager.resetTemporaryCache(); - } - } - + // only translation units can be inconsistent + // other openables cannot be inconsistent so default is to do nothing } /** diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ReconcileWorkingCopyOperation.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ReconcileWorkingCopyOperation.java index 70aff050535..c2696b61e25 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ReconcileWorkingCopyOperation.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ReconcileWorkingCopyOperation.java @@ -10,10 +10,12 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.model; -import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICModelStatus; import org.eclipse.cdt.core.model.ICModelStatusConstants; +import org.eclipse.core.runtime.OperationCanceledException; /** * Reconcile a working copy and signal the changes through a delta. @@ -21,18 +23,26 @@ import org.eclipse.cdt.core.model.ICModelStatusConstants; public class ReconcileWorkingCopyOperation extends CModelOperation { boolean forceProblemDetection; + boolean fComputeAST; + IASTTranslationUnit fAST; public ReconcileWorkingCopyOperation(ICElement workingCopy, boolean forceProblemDetection) { + this(workingCopy, false, forceProblemDetection); + } + public ReconcileWorkingCopyOperation(ICElement workingCopy, boolean computeAST, boolean forceProblemDetection) { super(new ICElement[] {workingCopy}); + fComputeAST= computeAST; this.forceProblemDetection = forceProblemDetection; } + /** * @exception CModelException if setting the source * of the original compilation unit fails */ protected void executeOperation() throws CModelException { if (fMonitor != null){ - if (fMonitor.isCanceled()) return; + if (fMonitor.isCanceled()) + throw new OperationCanceledException(); fMonitor.beginTask("element.reconciling", 10); //$NON-NLS-1$ } @@ -46,7 +56,11 @@ public class ReconcileWorkingCopyOperation extends CModelOperation { deltaBuilder = new CElementDeltaBuilder(workingCopy); // update the element infos with the content of the working copy - workingCopy.makeConsistent(fMonitor); + if (fComputeAST) { + fAST= workingCopy.makeConsistent(fComputeAST, fMonitor); + } else { + workingCopy.makeConsistent(fMonitor); + } deltaBuilder.buildDeltas(); // register the deltas diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java index eef532a379a..6b9c26fc72e 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java @@ -15,6 +15,7 @@ package org.eclipse.cdt.internal.core.model; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import org.eclipse.cdt.core.CCorePlugin; @@ -51,6 +52,7 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.content.IContentType; import org.eclipse.core.runtime.content.IContentTypeManager; @@ -418,7 +420,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit { CModelManager.getDefault().removeChildrenInfo(this); // generate structure - this.parse(newElements); + this.parse(newElements, pm); // ///////////////////////////////////////////////////////////// @@ -530,6 +532,58 @@ public class TranslationUnit extends Openable implements ITranslationUnit { return CModelManager.getDefault().getElementsOutOfSynchWithBuffers().get(this) == null; } + /* + * @see org.eclipse.cdt.internal.core.model.Openable#makeConsistent(org.eclipse.core.runtime.IProgressMonitor, boolean) + */ + public void makeConsistent(IProgressMonitor monitor, boolean forced) throws CModelException { + makeConsistent(false, monitor); + } + + protected IASTTranslationUnit makeConsistent(boolean computeAST, IProgressMonitor monitor) throws CModelException { + if (isConsistent()) { + return null; + } + + // create a new info and make it the current info + // (this will remove the info and its children just before storing the new infos) + CModelManager manager = CModelManager.getDefault(); + boolean hadTemporaryCache = manager.hasTemporaryCache(); + final CElementInfo info; + if (computeAST) { + info= new ASTHolderTUInfo(this); + } else { + info= createElementInfo(); + } + try { + HashMap newElements = manager.getTemporaryCache(); + openWhenClosed(info, monitor); + if (newElements.get(this) == null) { + // close any buffer that was opened for the new elements + Iterator iterator = newElements.keySet().iterator(); + while (iterator.hasNext()) { + ICElement element = (ICElement)iterator.next(); + if (element instanceof Openable) { + ((Openable)element).closeBuffer(); + } + } + throw newNotPresentException(); + } + if (!hadTemporaryCache) { + manager.putInfos(this, newElements); + } + } finally { + if (!hadTemporaryCache) { + manager.resetTemporaryCache(); + } + } + if (info instanceof ASTHolderTUInfo) { + final IASTTranslationUnit ast= ((ASTHolderTUInfo)info).fAST; + ((ASTHolderTUInfo)info).fAST= null; + return ast; + } + return null; + } + /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.model.Openable#isSourceElement() */ @@ -582,34 +636,39 @@ public class TranslationUnit extends Openable implements ITranslationUnit { /** * Parse the buffer contents of this element. */ - private void parse(Map newElements) { + private void parse(Map newElements, IProgressMonitor monitor) { boolean quickParseMode = ! (CCorePlugin.getDefault().useStructuralParseMode()); IContributedModelBuilder mb = LanguageManager.getInstance().getContributedModelBuilderFor(this); if (mb == null) { - parseUsingCModelBuilder(newElements, quickParseMode); + parseUsingCModelBuilder(newElements, quickParseMode, monitor); } else { - parseUsingContributedModelBuilder(mb, quickParseMode); + parseUsingContributedModelBuilder(mb, quickParseMode, monitor); } } /** * Parse the buffer contents of this element. + * @param monitor */ - private void parseUsingCModelBuilder(Map newElements, boolean quickParseMode) { + private void parseUsingCModelBuilder(Map newElements, boolean quickParseMode, IProgressMonitor monitor) { try { boolean useNewModelBuilder= CCorePlugin.getDefault().useNewModelBuilder(); if (useNewModelBuilder) { - new CModelBuilder2(this).parse(quickParseMode); + new CModelBuilder2(this, monitor).parse(quickParseMode); } else { new CModelBuilder(this, newElements).parse(quickParseMode); } + } catch (OperationCanceledException oce) { + if (isWorkingCopy()) { + throw oce; + } } catch (Exception e) { // use the debug log for this exception. Util.debugLog( "Exception in CModelBuilder", IDebugLogConstants.MODEL); //$NON-NLS-1$ } } - private void parseUsingContributedModelBuilder(IContributedModelBuilder mb, boolean quickParseMode) { + private void parseUsingContributedModelBuilder(IContributedModelBuilder mb, boolean quickParseMode, IProgressMonitor monitor) { try { mb.parse(quickParseMode); } catch (Exception e) { diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/WorkingCopy.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/WorkingCopy.java index 2c628927b52..e1e797fc961 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/WorkingCopy.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/WorkingCopy.java @@ -16,6 +16,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.ArrayList; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.IBuffer; import org.eclipse.cdt.core.model.ICElement; @@ -119,13 +120,6 @@ public class WorkingCopy extends TranslationUnit implements IWorkingCopy { } } - /** - * Returns a new element info for this element. - */ - protected CElementInfo createElementInfo() { - return new WorkingCopyInfo(this); - } - /** * @see org.eclipse.cdt.core.model.IWorkingCopy#destroy() */ @@ -351,11 +345,7 @@ public class WorkingCopy extends TranslationUnit implements IWorkingCopy { * @see org.eclipse.cdt.core.model.IWorkingCopy#reconcile(boolean, org.eclipse.core.runtime.IProgressMonitor) */ public void reconcile(boolean forceProblemDetection, IProgressMonitor monitor) throws CModelException { - - if (this.useCount == 0) throw newNotPresentException(); //was destroyed - - ReconcileWorkingCopyOperation op = new ReconcileWorkingCopyOperation(this, forceProblemDetection); - op.runOperation(monitor); + reconcile(false, forceProblemDetection, monitor); } /** @@ -397,4 +387,17 @@ public class WorkingCopy extends TranslationUnit implements IWorkingCopy { ((TranslationUnitInfo) getElementInfo()).fTimestamp = timeStamp; } + /* + * @see org.eclipse.cdt.core.model.IWorkingCopy#reconcile(boolean, boolean, org.eclipse.core.runtime.IProgressMonitor) + */ + public IASTTranslationUnit reconcile(boolean computeAST, boolean forceProblemDetection, IProgressMonitor monitor) + throws CModelException { + + if (this.useCount == 0) throw newNotPresentException(); //was destroyed + + ReconcileWorkingCopyOperation op = new ReconcileWorkingCopyOperation(this, computeAST, forceProblemDetection); + op.runOperation(monitor); + return op.fAST; + } + } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/WorkingCopyInfo.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/WorkingCopyInfo.java index 6868949c768..5e7be65f579 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/WorkingCopyInfo.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/WorkingCopyInfo.java @@ -12,6 +12,7 @@ package org.eclipse.cdt.internal.core.model; /** * The Element Info of a Working Copy. + * @deprecated Use {@link TranslationUnitInfo} directly */ public class WorkingCopyInfo extends TranslationUnitInfo { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CReconciler.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CReconciler.java new file mode 100644 index 00000000000..80a9c79fd8e --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CReconciler.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2006 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.ui.text; + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.reconciler.MonoReconciler; + +/** + * A single strategy C reconciler. + * + * @since 4.0 + */ +public class CReconciler extends MonoReconciler { + + /** + * Create a reconciler for the given strategy. + * + * @param strategy the C reconciling strategy + */ + public CReconciler(CReconcilingStrategy strategy) { + super(strategy, false); + } + + /* + * @see org.eclipse.jface.text.reconciler.AbstractReconciler#aboutToBeReconciled() + */ + protected void aboutToBeReconciled() { + CReconcilingStrategy strategy= (CReconcilingStrategy)getReconcilingStrategy(IDocument.DEFAULT_CONTENT_TYPE); + strategy.aboutToBeReconciled(); + } + +} 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 2a12757fbfe..1b35886b2be 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 @@ -12,14 +12,10 @@ *******************************************************************************/ package org.eclipse.cdt.internal.ui.text; -import org.eclipse.cdt.core.model.CModelException; -import org.eclipse.cdt.core.model.ITranslationUnit; -import org.eclipse.cdt.core.model.IWorkingCopy; -import org.eclipse.cdt.internal.core.model.CModelManager; -import org.eclipse.cdt.internal.ui.editor.IReconcilingParticipant; -import org.eclipse.cdt.ui.CUIPlugin; -import org.eclipse.cdt.ui.IWorkingCopyManager; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Status; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.reconciler.DirtyRegion; @@ -27,6 +23,18 @@ import org.eclipse.jface.text.reconciler.IReconcilingStrategy; import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension; import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.index.IIndex; +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.core.model.IWorkingCopy; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.IWorkingCopyManager; + +import org.eclipse.cdt.internal.core.model.CModelManager; + +import org.eclipse.cdt.internal.ui.editor.IReconcilingParticipant; + public class CReconcilingStrategy implements IReconcilingStrategy, IReconcilingStrategyExtension { @@ -59,7 +67,7 @@ public class CReconcilingStrategy implements IReconcilingStrategy, IReconcilingS * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.IRegion) */ public void reconcile(IRegion region) { - reconcile(); + reconcile(false); } @@ -101,29 +109,55 @@ public class CReconcilingStrategy implements IReconcilingStrategy, IReconcilingS } } } - if (needReconcile) reconcile(); + if (needReconcile) reconcile(false); txt = doc.get(); // save doc copy for further use } - private void reconcile() { + private void reconcile(final boolean initialReconcile) { + IASTTranslationUnit ast= null; try { ITranslationUnit tu = fManager.getWorkingCopy(fEditor.getEditorInput()); if (tu != null && tu.isWorkingCopy()) { IWorkingCopy workingCopy = (IWorkingCopy)tu; + final boolean computeAST= initialReconcile || CUIPlugin.getDefault().getASTProvider().isActive(tu); // reconcile synchronized (workingCopy) { - workingCopy.reconcile(true, fProgressMonitor); + ast= workingCopy.reconcile(computeAST, true, fProgressMonitor); } } - - // update participants - if (fEditor instanceof IReconcilingParticipant /*&& !fProgressMonitor.isCanceled()*/) { + } catch(OperationCanceledException oce) { + // document was modified while parsing + } catch(CModelException e) { + IStatus status= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, IStatus.OK, "Error in CDT UI during reconcile", e); //$NON-NLS-1$ + CUIPlugin.getDefault().log(status); + } finally { + if (fEditor instanceof ICReconcilingListener) { + IIndex index= null; + if (ast != null) { + index= ast.getIndex(); + if (index != null) { + try { + index.acquireReadLock(); + } catch (InterruptedException exc) { + ast= null; + } + } + } + try { + ((ICReconcilingListener)fEditor).reconciled(ast, null, fProgressMonitor); + } finally { + if (index != null) { + index.releaseReadLock(); + } + } + } + if (fProgressMonitor != null && fProgressMonitor.isCanceled()) { + return; + } + if (ast == null && fEditor instanceof IReconcilingParticipant) { IReconcilingParticipant p= (IReconcilingParticipant) fEditor; p.reconciled(true); } - - } catch(CModelException e) { - } } @@ -131,10 +165,13 @@ public class CReconcilingStrategy implements IReconcilingStrategy, IReconcilingS * @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#initialReconcile() */ public void initialReconcile() { - if (fEditor instanceof IReconcilingParticipant) { - IReconcilingParticipant p= (IReconcilingParticipant) fEditor; - p.reconciled(true); - } + reconcile(true); fInitialProcessDone= true; + } + + void aboutToBeReconciled() { + if (fEditor instanceof ICReconcilingListener) { + ((ICReconcilingListener)fEditor).aboutToBeReconciled(); + } } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java index 2151f1e94e8..0cfea38bb1d 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java @@ -16,8 +16,10 @@ package org.eclipse.cdt.internal.ui.text; import java.util.Vector; import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.content.IContentType; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.AbstractInformationControlManager; @@ -46,7 +48,6 @@ import org.eclipse.jface.text.rules.RuleBasedScanner; import org.eclipse.jface.text.source.IAnnotationHover; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.text.source.SourceViewerConfiguration; -import org.eclipse.core.runtime.Assert; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Shell; @@ -81,6 +82,7 @@ import org.eclipse.cdt.internal.ui.text.c.hover.CEditorTextHoverDescriptor; import org.eclipse.cdt.internal.ui.text.c.hover.CEditorTextHoverProxy; import org.eclipse.cdt.internal.ui.text.contentassist.CCompletionProcessor2; import org.eclipse.cdt.internal.ui.text.contentassist.ContentAssistPreference; +import org.eclipse.cdt.internal.ui.util.ExternalEditorInput; /** @@ -353,15 +355,16 @@ public class CSourceViewerConfiguration extends TextSourceViewerConfiguration { return assistant; } - - /** - * @see SourceViewerConfiguration#getReconciler(ISourceViewer) + /* + * @see org.eclipse.ui.editors.text.TextSourceViewerConfiguration#getReconciler(org.eclipse.jface.text.source.ISourceViewer) */ public IReconciler getReconciler(ISourceViewer sourceViewer) { - if (fTextEditor != null && fTextEditor.isEditable()) { + if (fTextEditor != null && (fTextEditor.isEditable() || fTextEditor.getEditorInput() instanceof ExternalEditorInput)) { //Delay changed and non-incremental reconciler used due to //PR 130089 - MonoReconciler reconciler= new MonoReconciler(new CReconcilingStrategy(fTextEditor), false); + MonoReconciler reconciler= new CReconciler(new CReconcilingStrategy(fTextEditor)); + reconciler.setIsIncrementalReconciler(false); + reconciler.setProgressMonitor(new NullProgressMonitor()); reconciler.setDelay(500); return reconciler; } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/CElementLabels.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/CElementLabels.java index 2bcf075d9e9..3a607452119 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/CElementLabels.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/CElementLabels.java @@ -353,9 +353,12 @@ public class CElementLabels { } } - if( getFlag( flags, M_APP_RETURNTYPE ) && method.exists() && !method.isConstructor()) { - buf.append( DECL_STRING ); - buf.append( method.getReturnType() ); + if( getFlag( flags, M_APP_RETURNTYPE ) && method.exists() && !method.isConstructor() && !method.isDestructor()) { + final String typeName= method.getReturnType(); + if (typeName != null && typeName.length() > 0) { + buf.append( DECL_STRING ); + buf.append(typeName); + } } // post qualification