From a443caeb08f5ebfeb103b91f9ece5f9775887585 Mon Sep 17 00:00:00 2001 From: Alain Magloire Date: Sat, 19 Jun 2004 02:43:04 +0000 Subject: [PATCH] 2004-06-18 Alain Magloire This was heavy and lots of files were change. The problem: to create the CElementInfo we use to synchronize of the CModelManager singleton instance, this was handy and allowed us to serialize the creation of the proxy info and save in the LRU cache. Then came Eclipse-3.0 with job spawning everywhere, lots of deadlock since the CModelManager was lock and the singleton is the center to get all the info. We use the same scheme as the JDT by using a ThreadLocal class cache to collect the information. We fixed a couple of bug allong the way and probably introduce some. The tests were doing something stupid, by creating directly the TranslationUnit: new TranslationUnit(project, file); This does not work since only the sourceRoot can be the parent of a TranslationUnit, the tests are now fix bug we should restrict access of the class in the core model after 2.0. --- .../core/model/tests/CModelElementsTests.java | 7 +- .../core/model/tests/ElementDeltaTests.java | 4 +- .../model/tests/IntegratedCModelTest.java | 10 +- .../tests/StructuralCModelElementsTests.java | 7 +- .../core/model/tests/WorkingCopyTests.java | 4 +- core/org.eclipse.cdt.core/ChangeLog | 15 ++ .../cdt/internal/core/model/Archive.java | 9 +- .../internal/core/model/ArchiveContainer.java | 5 +- .../cdt/internal/core/model/Binary.java | 6 +- .../internal/core/model/BinaryContainer.java | 5 +- .../internal/core/model/BinaryElement.java | 7 + .../cdt/internal/core/model/BinaryModule.java | 9 + .../cdt/internal/core/model/CContainer.java | 4 +- .../cdt/internal/core/model/CElement.java | 104 +++++----- .../cdt/internal/core/model/CModel.java | 6 +- .../internal/core/model/CModelBuilder.java | 6 +- .../internal/core/model/CModelManager.java | 53 ++++- .../cdt/internal/core/model/CProject.java | 8 +- .../cdt/internal/core/model/Include.java | 3 - .../internal/core/model/IncludeReference.java | 5 +- .../internal/core/model/LibraryReference.java | 10 + .../cdt/internal/core/model/Openable.java | 196 +++++++----------- .../model/ReconcileWorkingCopyOperation.java | 15 +- .../core/model/SourceManipulation.java | 19 ++ .../internal/core/model/TranslationUnit.java | 121 ++++------- .../CompletionProposalsBaseTest.java | 11 +- 26 files changed, 333 insertions(+), 316 deletions(-) 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 633d4e6b032..89ff73a9e9e 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 @@ -19,6 +19,7 @@ import junit.framework.TestCase; import junit.framework.TestSuite; import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.IEnumeration; @@ -33,6 +34,7 @@ import org.eclipse.cdt.core.model.IMethodDeclaration; import org.eclipse.cdt.core.model.INamespace; import org.eclipse.cdt.core.model.IParent; import org.eclipse.cdt.core.model.IStructure; +import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITypeDef; import org.eclipse.cdt.core.model.IVariable; import org.eclipse.cdt.core.model.IVariableDeclaration; @@ -41,7 +43,6 @@ import org.eclipse.cdt.internal.core.model.CElement; import org.eclipse.cdt.internal.core.model.FunctionTemplate; import org.eclipse.cdt.internal.core.model.MethodTemplate; import org.eclipse.cdt.internal.core.model.StructureTemplate; -import org.eclipse.cdt.internal.core.model.TranslationUnit; import org.eclipse.cdt.testplugin.CProjectHelper; import org.eclipse.cdt.testplugin.CTestPlugin; import org.eclipse.core.resources.IFile; @@ -92,8 +93,8 @@ public class CModelElementsTests extends TestCase { } public void testCModelElements() throws CModelException{ - TranslationUnit tu = new TranslationUnit(fCProject, headerFile); - TranslationUnit included = new TranslationUnit(fCProject, includedFile); + ITranslationUnit tu = (ITranslationUnit)CoreModel.getDefault().create(headerFile); + //ITranslationUnit included = (ITranslationUnit)CoreModel.getDefault().create(includedFile); // parse the translation unit to get the elements tree tu.parse(); diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/ElementDeltaTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/ElementDeltaTests.java index a5b7d085663..9a890b1f94e 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/ElementDeltaTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/ElementDeltaTests.java @@ -241,8 +241,8 @@ public class ElementDeltaTests extends TestCase implements IElementChangedListen addedElements.clear(); removedElements.clear(); changedElements.clear(); - - processDelta(event.getDelta()); + ICElementDelta delta = event.getDelta(); + processDelta(delta); } catch(CModelException e) { } } 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 b9e1e037599..719c9633e7a 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 @@ -6,14 +6,13 @@ package org.eclipse.cdt.core.model.tests; import java.io.FileInputStream; import java.io.FileNotFoundException; -import java.util.Map; import junit.framework.TestCase; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ITranslationUnit; -import org.eclipse.cdt.internal.core.model.TranslationUnit; import org.eclipse.cdt.testplugin.CProjectHelper; import org.eclipse.cdt.testplugin.CTestPlugin; import org.eclipse.core.resources.IFile; @@ -79,12 +78,15 @@ public abstract class IntegratedCModelTest extends TestCase { } protected ITranslationUnit getTU() { - TranslationUnit tu = new TranslationUnit(fCProject, sourceFile); + ITranslationUnit tu = (ITranslationUnit)CoreModel.getDefault().create(sourceFile); if(isStructuralParse()) { CCorePlugin.getDefault().setStructuralParseMode(true); + } else { + CCorePlugin.getDefault().setStructuralParseMode(false); } // parse the translation unit to get the elements tree - Map newElement = tu.parse(); + // Force the parsing now to do this in the right ParseMode. + tu.parse(); CCorePlugin.getDefault().setStructuralParseMode(false); 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 ea0c3bcb3c9..95b51461631 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 @@ -20,6 +20,7 @@ import junit.framework.TestSuite; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.IEnumeration; @@ -34,6 +35,7 @@ import org.eclipse.cdt.core.model.IMethodDeclaration; import org.eclipse.cdt.core.model.INamespace; import org.eclipse.cdt.core.model.IParent; import org.eclipse.cdt.core.model.IStructure; +import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITypeDef; import org.eclipse.cdt.core.model.IVariable; import org.eclipse.cdt.core.model.IVariableDeclaration; @@ -42,7 +44,6 @@ import org.eclipse.cdt.internal.core.model.CElement; import org.eclipse.cdt.internal.core.model.FunctionTemplate; import org.eclipse.cdt.internal.core.model.MethodTemplate; import org.eclipse.cdt.internal.core.model.StructureTemplate; -import org.eclipse.cdt.internal.core.model.TranslationUnit; import org.eclipse.cdt.testplugin.CProjectHelper; import org.eclipse.cdt.testplugin.CTestPlugin; import org.eclipse.core.resources.IFile; @@ -93,8 +94,8 @@ public class StructuralCModelElementsTests extends TestCase { } public void testCModelElements() throws CModelException{ - TranslationUnit tu = new TranslationUnit(fCProject, headerFile); - TranslationUnit included = new TranslationUnit(fCProject, includedFile); + ITranslationUnit tu = (ITranslationUnit)CoreModel.getDefault().create(headerFile); + //ITranslationUnit included = (ITranslationUnit)CoreModel.getDefault().create(includedFile); // turn on the structural parse mode CCorePlugin.getDefault().setStructuralParseMode(true); diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/WorkingCopyTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/WorkingCopyTests.java index fa7e073b49e..7765c3d1f03 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/WorkingCopyTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/WorkingCopyTests.java @@ -18,11 +18,11 @@ import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.IBuffer; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.IWorkingCopy; -import org.eclipse.cdt.internal.core.model.TranslationUnit; import org.eclipse.cdt.testplugin.CProjectHelper; import org.eclipse.cdt.testplugin.CTestPlugin; import org.eclipse.cdt.testplugin.TestPluginLauncher; @@ -80,7 +80,7 @@ public class WorkingCopyTests extends TestCase { public void testWorkingCopy() throws Exception { - ITranslationUnit tu = new TranslationUnit(fCProject, headerFile); + ITranslationUnit tu = (ITranslationUnit)CoreModel.getDefault().create(headerFile); // CreateWorkingCopy assertNotNull (tu); IWorkingCopy wc = tu.getWorkingCopy(); diff --git a/core/org.eclipse.cdt.core/ChangeLog b/core/org.eclipse.cdt.core/ChangeLog index e3770feb872..ae0d652fd7f 100644 --- a/core/org.eclipse.cdt.core/ChangeLog +++ b/core/org.eclipse.cdt.core/ChangeLog @@ -1,3 +1,18 @@ +2004-06-18 Alain Magloire + + This was heavy and lots of files were change. The problem: to create the CElementInfo we use + to synchronize of the CModelManager singleton instance, this was handy and allowed us to serialize + the creation of the proxy info and save in the LRU cache. Then came Eclipse-3.0 with job spawning + everywhere, lots of deadlock since the CModelManager was lock and the singleton is the center + to get all the info. We use the same scheme as the JDT by using a ThreadLocal class cache + to collect the information. We fixed a couple of bug allong the way and probably introduce some. + + The tests were doing something stupid, by creating directly the TranslationUnit: + new TranslationUnit(project, file); + This does not work since only the sourceRoot can be the parent + of a TranslationUnit, the tests are now fix bug we should restrict access of the class in the core model + after 2.0. + 2004-06-18 Andrew Niefer - DeltaProcessor.updateIndexRemoveResource() : discard if removing a project, discard index jobs for that project. diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Archive.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Archive.java index 558e6574d4a..c2861639499 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Archive.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Archive.java @@ -53,16 +53,12 @@ public class Archive extends Openable implements IArchive { protected ArchiveInfo getArchiveInfo() throws CModelException { return (ArchiveInfo)getElementInfo(); } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.model.Openable#generateInfos(org.eclipse.cdt.internal.core.model.OpenableInfo, org.eclipse.core.runtime.IProgressMonitor, java.util.Map, org.eclipse.core.resources.IResource) - */ - protected boolean generateInfos(OpenableInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) + + protected boolean buildStructure(OpenableInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws CModelException { - CModelManager.getDefault().putInfo(this, info); return computeChildren(info, underlyingResource); } - public boolean computeChildren(OpenableInfo info, IResource res) { IBinaryArchive ar = getBinaryArchive(); if (ar != null) { @@ -100,4 +96,5 @@ public class Archive extends Openable implements IArchive { } super.closing(info); } + } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ArchiveContainer.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ArchiveContainer.java index ad98fa73c2a..6a334d5e7f4 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ArchiveContainer.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ArchiveContainer.java @@ -33,13 +33,12 @@ public class ArchiveContainer extends Openable implements IArchiveContainer { } /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.model.Openable#generateInfos(org.eclipse.cdt.internal.core.model.OpenableInfo, org.eclipse.core.runtime.IProgressMonitor, java.util.Map, org.eclipse.core.resources.IResource) + * @see org.eclipse.cdt.internal.core.model.Openable#buildStructure(org.eclipse.cdt.internal.core.model.OpenableInfo, org.eclipse.core.runtime.IProgressMonitor, java.util.Map, org.eclipse.core.resources.IResource) */ - protected boolean generateInfos(OpenableInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) + protected boolean buildStructure(OpenableInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws CModelException { // this will bootstrap/start the runner for the project. CModelManager.getDefault().getBinaryRunner(getCProject()); - CModelManager.getDefault().putInfo(this, info); return true; } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java index ae839c623a0..35188337cb0 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java @@ -210,15 +210,13 @@ public class Binary extends Openable implements IBinary { } /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.model.Openable#generateInfos(org.eclipse.cdt.internal.core.model.OpenableInfo, org.eclipse.core.runtime.IProgressMonitor, java.util.Map, org.eclipse.core.resources.IResource) + * @see org.eclipse.cdt.internal.core.model.Openable#buildStructure(org.eclipse.cdt.internal.core.model.OpenableInfo, org.eclipse.core.runtime.IProgressMonitor, java.util.Map, org.eclipse.core.resources.IResource) */ - protected boolean generateInfos(OpenableInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) + protected boolean buildStructure(OpenableInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws CModelException { - CModelManager.getDefault().putInfo(this, info); return computeChildren(info, underlyingResource); } - boolean computeChildren(OpenableInfo info, IResource res) throws CModelException { boolean ok = false; if (isObject() || isExecutable() || isSharedLib()) { diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryContainer.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryContainer.java index 0112de9bdca..26afef108b1 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryContainer.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryContainer.java @@ -43,13 +43,12 @@ public class BinaryContainer extends Openable implements IBinaryContainer { } /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.model.Openable#generateInfos(org.eclipse.cdt.internal.core.model.OpenableInfo, org.eclipse.core.runtime.IProgressMonitor, java.util.Map, org.eclipse.core.resources.IResource) + * @see org.eclipse.cdt.internal.core.model.Openable#buildStructure(org.eclipse.cdt.internal.core.model.OpenableInfo, org.eclipse.core.runtime.IProgressMonitor, java.util.Map, org.eclipse.core.resources.IResource) */ - protected boolean generateInfos(OpenableInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) + protected boolean buildStructure(OpenableInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws CModelException { // this will bootstrap/start the runner for the project. CModelManager.getDefault().getBinaryRunner(getCProject()); - CModelManager.getDefault().putInfo(this, info); return true; } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryElement.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryElement.java index 7d3adad6607..4101adc58d1 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryElement.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryElement.java @@ -5,6 +5,7 @@ package org.eclipse.cdt.internal.core.model; import java.io.IOException; +import java.util.Map; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.IBinary; @@ -166,4 +167,10 @@ public class BinaryElement extends CElement implements IBinaryElement, ISourceMa return null; } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.model.CElement#generateInfos(java.lang.Object, java.util.Map, org.eclipse.core.runtime.IProgressMonitor) + */ + protected void generateInfos(Object info, Map newElements, IProgressMonitor monitor) throws CModelException { + } + } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryModule.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryModule.java index 5a90dd97c97..459ae797ff6 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryModule.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryModule.java @@ -5,6 +5,8 @@ package org.eclipse.cdt.internal.core.model; +import java.util.Map; + import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.IBinary; import org.eclipse.cdt.core.model.IBinaryElement; @@ -12,6 +14,7 @@ import org.eclipse.cdt.core.model.IBinaryModule; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; /** */ @@ -76,4 +79,10 @@ public class BinaryModule extends Parent implements IBinaryModule { return path; } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.model.CElement#generateInfos(java.lang.Object, java.util.Map, org.eclipse.core.runtime.IProgressMonitor) + */ + protected void generateInfos(Object info, Map newElements, IProgressMonitor monitor) throws CModelException { + } + } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CContainer.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CContainer.java index b3285811160..87a24202710 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CContainer.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CContainer.java @@ -159,14 +159,12 @@ public class CContainer extends Openable implements ICContainer { /** * @see Openable */ - protected boolean generateInfos(OpenableInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) + protected boolean buildStructure(OpenableInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws CModelException { boolean validInfo = false; try { IResource res = getResource(); if (res != null && res.isAccessible()) { - // put the info now, because computing the roots requires it - CModelManager.getDefault().putInfo(this, info); validInfo = computeChildren(info, res); } else { throw newNotPresentException(); diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElement.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElement.java index 556f9ecbb86..1bc0e262d71 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElement.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElement.java @@ -4,6 +4,10 @@ package org.eclipse.cdt.internal.core.model; * All Rights Reserved. */ +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElementVisitor; @@ -231,18 +235,20 @@ public abstract class CElement extends PlatformObject implements ICElement { } return false; } - - public CElementInfo getElementInfo () throws CModelException { + + public CElementInfo getElementInfo() throws CModelException { + return getElementInfo(null); + } + + public CElementInfo getElementInfo (IProgressMonitor monitor) throws CModelException { CModelManager manager = CModelManager.getDefault(); - Object info = manager.getInfo(this); - if (info == null) { - openHierarchy(); - info= manager.getInfo(this); - if (info == null) { - throw newNotPresentException(); - } + CElementInfo info = (CElementInfo)manager.getInfo(this); + if (info != null) { + return info; } - return (CElementInfo)info; + info = createElementInfo(); + openWhenClosed(info, monitor); + return info; } public String toString() { @@ -331,29 +337,54 @@ public abstract class CElement extends PlatformObject implements ICElement { return null; } + /** + * Builds this element's structure and properties in the given + * info object, based on this element's current contents (i.e. buffer + * contents if this element has an open buffer, or resource contents + * if this element does not have an open buffer). Children + * are placed in the given newElements table (note, this element + * has already been placed in the newElements table). Returns true + * if successful, or false if an error is encountered while determining + * the structure of this element. + */ + protected abstract void generateInfos(Object info, Map newElements, IProgressMonitor monitor) throws CModelException; /** - * Opens this element and all parents that are not already open. - * - * @exception CModelException this element is not present or accessible + * Open a IOpenable that is known to be closed (no check for + * isOpen()). */ - protected void openHierarchy() throws CModelException { - if (this instanceof IOpenable) { - ((Openable) this).openWhenClosed(null); - } else { - Openable openableParent = (Openable)getOpenableParent(); - if (openableParent != null) { - CElementInfo openableParentInfo = (CElementInfo) CModelManager.getDefault().getInfo(openableParent); - if (openableParentInfo == null) { - openableParent.openWhenClosed(null); - } - //else { - CModelManager.getDefault().putInfo( this, createElementInfo()); - //} + protected void openWhenClosed(CElementInfo info, IProgressMonitor pm) throws CModelException { + CModelManager manager = CModelManager.getDefault(); + boolean hadTemporaryCache = manager.hasTemporaryCache(); + try { + HashMap newElements = manager.getTemporaryCache(); + generateInfos(info, newElements, pm); + if (info == null) { + info = (CElementInfo)newElements.get(this); + } + if (info == null) { // a source ref element could not be opened + // close any buffer that was opened for the openable parent + 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(); } } } + /** * @see ICElement */ @@ -386,27 +417,6 @@ public abstract class CElement extends PlatformObject implements ICElement { protected CModelException newNotPresentException() { return new CModelException(new CModelStatus(ICModelStatusConstants.ELEMENT_DOES_NOT_EXIST, this)); } - /** - * Removes all cached info from the C Model, including all children, - * but does not close this element. - */ - protected void removeInfo() { - Object info = CModelManager.getDefault().peekAtInfo(this); - if (info != null) { - if (this instanceof IParent) { - ICElement[] children = ((CElementInfo)info).getChildren(); - for (int i = 0, size = children.length; i < size; ++i) { - CElement child = (CElement) children[i]; - child.removeInfo(); - } - // we have to remove children here - // to clear the children list before - // removing the entry from the cache. - ((CElementInfo)info).removeChildren(); - } - CModelManager.getDefault().removeInfo(this); - } - } /** * Returns the hash code for this Java element. By default, diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModel.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModel.java index 2b920e7f9c6..d02eb108015 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModel.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModel.java @@ -174,15 +174,13 @@ public class CModel extends Openable implements ICModel { } /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.model.Openable#generateInfos(org.eclipse.cdt.internal.core.model.OpenableInfo, org.eclipse.core.runtime.IProgressMonitor, java.util.Map, org.eclipse.core.resources.IResource) + * @see org.eclipse.cdt.internal.core.model.Openable#buildStructure(org.eclipse.cdt.internal.core.model.OpenableInfo, org.eclipse.core.runtime.IProgressMonitor, java.util.Map, org.eclipse.core.resources.IResource) */ - protected boolean generateInfos(OpenableInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws CModelException { + protected boolean buildStructure(OpenableInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws CModelException { boolean validInfo = false; try { IResource res = getResource(); if (res != null && (res instanceof IWorkspaceRoot || res.getProject().isOpen())) { - // put the info now, because computing the roots requires it - CModelManager.getDefault().putInfo(this, info); validInfo = computeChildren(info, res); } } finally { 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 323c9416690..813796c0946 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 @@ -10,9 +10,7 @@ ******************************************************************************/ package org.eclipse.cdt.internal.core.model; -import java.util.HashMap; import java.util.Iterator; -import java.util.List; import java.util.Map; import org.eclipse.cdt.core.CCorePlugin; @@ -95,9 +93,9 @@ public class CModelBuilder { } } - public CModelBuilder(org.eclipse.cdt.internal.core.model.TranslationUnit tu) { + public CModelBuilder(org.eclipse.cdt.internal.core.model.TranslationUnit tu, Map newElements) { this.translationUnit = tu ; - this.newElements = new HashMap(); + this.newElements = newElements; } private IASTCompilationUnit parse(boolean quickParseMode, boolean throwExceptionOnError) throws ParserException diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java index 41b2d4af180..f88774bc018 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java @@ -1017,13 +1017,56 @@ public class CModelManager implements IResourceChangeListener, ICDescriptorListe return this.cache.peekAtInfo(element); } - /** - * Puts the info for a C Model Element + /* + * Puts the infos in the given map (keys are ICElements and values are CElementInfos) + * in the C model cache in an atomic way. + * First checks that the info for the opened element (or one of its ancestors) has not been + * added to the cache. If it is the case, another thread has opened the element (or one of + * its ancestors). So returns without updating the cache. */ - protected synchronized void putInfo(ICElement element, Object info) { - this.cache.putInfo(element, info); - } + protected synchronized void putInfos(ICElement openedElement, Map newElements) { + // remove children + Object existingInfo = this.cache.peekAtInfo(openedElement); + if (openedElement instanceof IParent && existingInfo instanceof CElementInfo) { + ICElement[] children = ((CElementInfo)existingInfo).getChildren(); + for (int i = 0, size = children.length; i < size; ++i) { + CElement child = (CElement) children[i]; + try { + child.close(); + } catch (CModelException e) { + // ignore + } + } + } + Iterator iterator = newElements.keySet().iterator(); + while (iterator.hasNext()) { + ICElement element = (ICElement)iterator.next(); + Object info = newElements.get(element); + this.cache.putInfo(element, info); + } + } + + /** + * Removes all cached info from the C Model, including all children, + * but does not close this element. + */ + protected synchronized void removeChildrenInfo(ICElement openedElement) { + // remove children + Object existingInfo = this.cache.peekAtInfo(openedElement); + if (openedElement instanceof IParent && existingInfo instanceof CElementInfo) { + ICElement[] children = ((CElementInfo)existingInfo).getChildren(); + for (int i = 0, size = children.length; i < size; ++i) { + CElement child = (CElement) children[i]; + try { + child.close(); + } catch (CModelException e) { + // ignore + } + } + } + } + /** * Removes the info of this model element. */ diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CProject.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CProject.java index 7a47c7ae283..e9f7c391975 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CProject.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CProject.java @@ -464,7 +464,7 @@ public class CProject extends Openable implements ICProject { } public IOutputEntry[] getOutputEntries() throws CModelException { - CProjectInfo pinfo = (CProjectInfo)CModelManager.getDefault().peekAtInfo(this); + CProjectInfo pinfo = (CProjectInfo) CModelManager.getDefault().peekAtInfo(this); IOutputEntry[] outs = null; if (pinfo != null) { if (pinfo.outputEntries != null) { @@ -528,17 +528,15 @@ public class CProject extends Openable implements ICProject { } /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.model.Openable#generateInfos(org.eclipse.cdt.internal.core.model.OpenableInfo, org.eclipse.core.runtime.IProgressMonitor, java.util.Map, org.eclipse.core.resources.IResource) + * @see org.eclipse.cdt.internal.core.model.Openable#buildStructure(org.eclipse.cdt.internal.core.model.OpenableInfo, org.eclipse.core.runtime.IProgressMonitor, java.util.Map, org.eclipse.core.resources.IResource) */ - protected boolean generateInfos(OpenableInfo info, IProgressMonitor pm, + protected boolean buildStructure(OpenableInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws CModelException { boolean validInfo = false; try { IResource res = getResource(); if (res != null && res.isAccessible()) { - // put the info now, because computing the roots requires it - CModelManager.getDefault().putInfo(this, info); validInfo = computeSourceRoots(info, res); } else { throw newNotPresentException(); diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Include.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Include.java index 91ef79fe688..dffe3cdfaa9 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Include.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Include.java @@ -26,9 +26,6 @@ public class Include extends SourceManipulation implements IInclude { return standard; } - protected CElementInfo createElementInfo () { - return new SourceManipulationInfo(this); - } /* (non-Javadoc) * @see org.eclipse.cdt.core.model.IInclude#getFullFileName() */ diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/IncludeReference.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/IncludeReference.java index 44eba2b4836..14be6c62b78 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/IncludeReference.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/IncludeReference.java @@ -72,10 +72,9 @@ public class IncludeReference extends Openable implements IIncludeReference { } /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.model.Openable#generateInfos(org.eclipse.cdt.internal.core.model.OpenableInfo, org.eclipse.core.runtime.IProgressMonitor, java.util.Map, org.eclipse.core.resources.IResource) + * @see org.eclipse.cdt.internal.core.model.Openable#buildStructure(org.eclipse.cdt.internal.core.model.OpenableInfo, org.eclipse.core.runtime.IProgressMonitor, java.util.Map, org.eclipse.core.resources.IResource) */ - protected boolean generateInfos(OpenableInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws CModelException { - CModelManager.getDefault().putInfo(this, info); + protected boolean buildStructure(OpenableInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws CModelException { return computeChildren(info, underlyingResource); } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/LibraryReference.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/LibraryReference.java index 0d345cb9389..c5fd5d312dd 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/LibraryReference.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/LibraryReference.java @@ -6,11 +6,15 @@ */ package org.eclipse.cdt.internal.core.model; +import java.util.Map; + +import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ILibraryEntry; import org.eclipse.cdt.core.model.ILibraryReference; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; /** * @author alain @@ -52,4 +56,10 @@ public class LibraryReference extends Parent implements ILibraryReference { return entry; } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.model.CElement#generateInfos(java.lang.Object, java.util.Map, org.eclipse.core.runtime.IProgressMonitor) + */ + protected void generateInfos(Object info, Map newElements, IProgressMonitor monitor) throws CModelException { + } + } 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 48d5f9fda26..fd49f8682a7 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 @@ -61,34 +61,23 @@ public abstract class Openable extends Parent implements IOpenable, IBufferChang CModelManager.getDefault().getElementsOutOfSynchWithBuffers().put(this, this); } } - /** - * Updates the info objects for this element and all of its children by - * removing the current infos, generating new infos, and then placing - * the new infos into the C Model cache tables. - */ - protected void buildStructure(OpenableInfo info, HashMap newElements, IProgressMonitor monitor) throws CModelException { - if (monitor != null && monitor.isCanceled()) return; - - // remove existing (old) infos - removeInfo(); - info.setIsStructureKnown(generateInfos(info, monitor, newElements, getResource())); - CModelManager.getDefault().getElementsOutOfSynchWithBuffers().remove(this); - for (Iterator iter = newElements.keySet().iterator(); iter.hasNext();) { - ICElement key = (ICElement) iter.next(); - Object value = newElements.get(key); - CModelManager.getDefault().putInfo(key, value); - } - - // add the info for this at the end, to ensure that a getInfo cannot reply null in case the LRU cache needs - // to be flushed. Might lead to performance issues. - CModelManager.getDefault().putInfo(this, info); - } + /** + * Builds this element's structure and properties in the given + * info object, based on this element's current contents (reuse buffer + * contents if this element has an open buffer, or resource contents + * if this element does not have an open buffer). Children + * are placed in the given newElements table (note, this element + * has already been placed in the newElements table). Returns true + * if successful, or false if an error is encountered while determining + * the structure of this element. + */ + protected abstract boolean buildStructure(OpenableInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws CModelException; /** * Close the buffer associated with this element, if any. */ - protected void closeBuffer(OpenableInfo info) { + protected void closeBuffer() { if (!hasBuffer()) return; // nothing to do IBuffer buffer = null; buffer = getBufferManager().getBuffer(this); @@ -102,26 +91,9 @@ public abstract class Openable extends Parent implements IOpenable, IBufferChang * This element is being closed. Do any necessary cleanup. */ protected void closing(Object info) throws CModelException { - if (info instanceof OpenableInfo) { - closeBuffer((OpenableInfo)info); - } else { - closeBuffer(null); - } + closeBuffer(); } - - /** - * Builds this element's structure and properties in the given - * info object, based on this element's current contents (i.e. buffer - * contents if this element has an open buffer, or resource contents - * if this element does not have an open buffer). Children - * are placed in the given newElements table (note, this element - * has already been placed in the newElements table). Returns true - * if successful, or false if an error is encountered while determining - * the structure of this element. - */ - protected abstract boolean generateInfos(OpenableInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws CModelException; - /** * @see org.eclipse.cdt.core.model.IOpenable#getBuffer() */ @@ -225,28 +197,46 @@ public abstract class Openable extends Parent implements IOpenable, IBufferChang makeConsistent(pm, false); } - public void makeConsistent(IProgressMonitor pm, boolean forced) throws CModelException { - if (!isConsistent() || forced) { - CModelManager manager = CModelManager.getDefault(); - boolean hadTemporaryCache = manager.hasTemporaryCache(); - try { - HashMap newElements = manager.getTemporaryCache(); - buildStructure((OpenableInfo)getElementInfo(), newElements, pm); - } finally { - if (!hadTemporaryCache) { - manager.resetTemporaryCache(); - } + 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(); } } + } /** * @see org.eclipse.cdt.core.model.IOpenable#open(IProgressMonitor) */ public void open(IProgressMonitor pm) throws CModelException { - if (!isOpen()) { - this.openWhenClosed(pm); - } + getElementInfo(pm); } /** @@ -260,56 +250,49 @@ public abstract class Openable extends Parent implements IOpenable, IBufferChang } /** - * Open the parent element if necessary - * + * Open the parent element if necessary. */ - protected void openParent(IProgressMonitor pm) throws CModelException { + protected void openParent(Object childInfo, Map newElements, IProgressMonitor pm) throws CModelException { Openable openableParent = (Openable)getOpenableParent(); - if (openableParent != null) { - if (!openableParent.isOpen()){ - openableParent.openWhenClosed(pm); - } + if (openableParent != null && !openableParent.isOpen()){ + openableParent.generateInfos(openableParent.createElementInfo(), newElements, pm); } } - /** - * Open a IOpenable that is known to be closed (no check for - * isOpen()). + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.model.CElement#generateInfos(java.lang.Object, java.util.Map, org.eclipse.core.runtime.IProgressMonitor) */ - protected void openWhenClosed(IProgressMonitor pm) throws CModelException { - CModelManager manager = CModelManager.getDefault(); - boolean hadTemporaryCache = manager.hasTemporaryCache(); - try { - HashMap newElements = manager.getTemporaryCache(); - // 1) Parent must be open - open the parent if necessary - openParent(pm); + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.model.CElement#generateInfos(java.lang.Object, java.util.Map, org.eclipse.core.runtime.IProgressMonitor) + */ + protected void generateInfos(Object info, Map newElements, IProgressMonitor monitor) throws CModelException { - // 2) create the new element info and open a buffer if needed - OpenableInfo info = (OpenableInfo) createElementInfo(); - IResource resource = getResource(); - if (resource != null && isSourceElement()) { - this.openBuffer(pm); - } - - // 3) build the structure of the openable - buildStructure(info, newElements, pm); - - //if (!hadTemporaryCache) { - // manager.putInfos(this, newElements); - //} - - // if any problems occuring openning the element, ensure that it's info - // does not remain in the cache (some elements, pre-cache their info - // as they are being opened). - } catch (CModelException e) { - CModelManager.getDefault().removeInfo(this); - throw e; - } finally { - if (!hadTemporaryCache) { - manager.resetTemporaryCache(); - } + if (CModelManager.VERBOSE){ + System.out.println("OPENING Element ("+ Thread.currentThread()+"): " + this); //$NON-NLS-1$//$NON-NLS-2$ } + + // open the parent if necessary + openParent(info, newElements, monitor); + if (monitor != null && monitor.isCanceled()) return; + + // puts the info before building the structure so that questions to the handle behave as if the element existed + // (case of compilation units becoming working copies) + newElements.put(this, info); + + // build the structure of the openable (this will open the buffer if needed) + try { + OpenableInfo openableInfo = (OpenableInfo)info; + boolean isStructureKnown = buildStructure(openableInfo, monitor, newElements, getResource()); + openableInfo.setIsStructureKnown(isStructureKnown); + } catch (CModelException e) { + newElements.remove(this); + throw e; + } + + // remove out of sync buffer for this element + CModelManager.getDefault().getElementsOutOfSynchWithBuffers().remove(this); + } /** @@ -326,25 +309,4 @@ public abstract class Openable extends Parent implements IOpenable, IBufferChang } } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.model.CElement#createElementInfo() - */ - protected CElementInfo createElementInfo() { - // TODO Auto-generated method stub - return null; - } - - /* (non-Javadoc) - * @see java.lang.Object#equals(java.lang.Object) - */ - public boolean equals(Object o) { - if (o instanceof Openable) { - IResource otherRes = ((Openable)o).getResource(); - IResource res = this.getResource(); - if (otherRes != null && res != null) { - return otherRes.equals(res); - } - } - return super.equals(o); - } } 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 b6b608bdfe5..3f12010dd29 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 @@ -48,7 +48,14 @@ public class ReconcileWorkingCopyOperation extends CModelOperation { // update the element infos with the content of the working copy workingCopy.makeConsistent(fMonitor); deltaBuilder.buildDeltas(); - + + // register the deltas + if (deltaBuilder != null){ + if ((deltaBuilder.delta != null) && (deltaBuilder.delta.getAffectedChildren().length > 0)) { + addReconcileDelta(workingCopy, deltaBuilder.delta); + } + } + } if (fMonitor != null) fMonitor.worked(2); @@ -58,12 +65,6 @@ public class ReconcileWorkingCopyOperation extends CModelOperation { if (fMonitor != null && fMonitor.isCanceled()) return; } - // register the deltas - if (deltaBuilder != null){ - if ((deltaBuilder.delta != null) && (deltaBuilder.delta.getAffectedChildren().length > 0)) { - addReconcileDelta(workingCopy, deltaBuilder.delta); - } - } } finally { if (fMonitor != null) fMonitor.done(); } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/SourceManipulation.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/SourceManipulation.java index 19080530a4c..bd96ed0d40e 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/SourceManipulation.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/SourceManipulation.java @@ -5,6 +5,8 @@ package org.eclipse.cdt.internal.core.model; * All Rights Reserved. */ +import java.util.Map; + import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.IOpenable; @@ -161,4 +163,21 @@ public class SourceManipulation extends Parent implements ISourceManipulation, I return (this.equals(other) && (this.getSourceManipulationInfo().hasSameContentsAs(other.getSourceManipulationInfo()))); } + + /* + * @see JavaElement#generateInfos + */ + protected void generateInfos(Object info, Map newElements, IProgressMonitor pm) throws CModelException { + Openable openableParent = (Openable)getOpenableParent(); + if (openableParent == null) { + return; + } + + CElementInfo openableParentInfo = (CElementInfo) CModelManager.getDefault().getInfo(openableParent); + if (openableParentInfo == null) { + openableParent.generateInfos(openableParent.createElementInfo(), newElements, pm); + } + newElements.put(this, info); + } + } 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 090dbce3480..8cf8c13e480 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 @@ -7,7 +7,6 @@ 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; @@ -237,41 +236,6 @@ public class TranslationUnit extends Openable implements ITranslationUnit { protected CElementInfo createElementInfo () { return new TranslationUnitInfo(this); } - - /** - * @param info - * @param monitor - * @throws CModelException - */ - protected void buildStructure(OpenableInfo info, IProgressMonitor monitor) throws CModelException { - if (monitor != null && monitor.isCanceled()) return; - - // remove existing (old) infos - removeInfo(); - - HashMap newElements = new HashMap(11); - info.setIsStructureKnown(generateInfos(info, monitor, newElements, getResource())); - CModelManager.getDefault().getElementsOutOfSynchWithBuffers().remove(this); - for (Iterator iter = newElements.keySet().iterator(); iter.hasNext();) { - ICElement key = (ICElement) iter.next(); - Object value = newElements.get(key); - CModelManager.getDefault().putInfo(key, value); - } - // problem detection - if (monitor != null && monitor.isCanceled()) return; - - //IProblemRequestor problemRequestor = this.getProblemRequestor(); - //if (problemRequestor != null && problemRequestor.isActive()){ - // problemRequestor.beginReporting(); - // CompilationUnitProblemFinder.process(this, problemRequestor, monitor); - // problemRequestor.endReporting(); - //} - - // add the info for this at the end, to ensure that a getInfo cannot reply null in case the LRU cache needs - // to be flushed. Might lead to performance issues. - CModelManager.getDefault().putInfo(this, info); - - } /** * Returns true if this handle represents the same Java element @@ -309,7 +273,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit { * @param newElements * @param element */ - private void getNewElements(Map newElements, CElement element){ + private void getNewElements(Map mapping, CElement element){ Object info = null; try { info = element.getElementInfo(); @@ -321,30 +285,27 @@ public class TranslationUnit extends Openable implements ITranslationUnit { int size = children.length; for (int i = 0; i < size; ++i) { CElement child = (CElement) children[i]; - getNewElements(newElements, child); + getNewElements(mapping, child); } } } - newElements.put(element, info); + mapping.put(element, info); } /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.model.Openable#generateInfos(org.eclipse.cdt.internal.core.model.OpenableInfo, org.eclipse.core.runtime.IProgressMonitor, java.util.Map, org.eclipse.core.resources.IResource) + * @see org.eclipse.cdt.internal.core.model.Openable#buildStructure(org.eclipse.cdt.internal.core.model.OpenableInfo, org.eclipse.core.runtime.IProgressMonitor, java.util.Map, org.eclipse.core.resources.IResource) */ - protected boolean generateInfos(OpenableInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws CModelException { - // put the info now, because getting the contents requires it - CModelManager.getDefault().putInfo(this, info); + protected boolean buildStructure(OpenableInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws CModelException { TranslationUnitInfo unitInfo = (TranslationUnitInfo) info; - + + // We reuse the general info cache in the CModelBuilder, We should not do this + // and instead create the info explicitely(see JDT). + // So to get by we need to remove in the LRU all the info of this handle + CModelManager.getDefault().removeChildrenInfo(this); + // generate structure - Map mapping = this.parse(); + this.parse(newElements); - // this is temporary until the New Model Builder is implemented - if(mapping == null) { - getNewElements(newElements, this); - } else { - newElements.putAll(mapping); - } /////////////////////////////////////////////////////////////// if (isWorkingCopy()) { @@ -436,6 +397,20 @@ public class TranslationUnit extends Openable implements ITranslationUnit { return true; } + /* + * @see Openable#openParent + */ + protected void openParent(Object childInfo, Map newElements, IProgressMonitor pm) throws CModelException { + try { + super.openParent(childInfo, newElements, pm); + } catch(CModelException e){ + // allow parent to not exist for working copies defined outside + if (!isWorkingCopy()){ + throw e; + } + } + } + /* (non-Javadoc) * @see org.eclipse.cdt.core.model.IOpenable#isConsistent() */ @@ -457,21 +432,6 @@ public class TranslationUnit extends Openable implements ITranslationUnit { return false; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.model.IOpenable#makeConsistent(org.eclipse.core.runtime.IProgressMonitor) - */ - public void makeConsistent(IProgressMonitor pm) throws CModelException { - makeConsistent(pm, false); - } - - public void makeConsistent(IProgressMonitor pm, boolean forced) throws CModelException { - if (!isConsistent() || forced) { - // create a new info and make it the current info - OpenableInfo info = (OpenableInfo) createElementInfo(); - buildStructure(info, pm); - } - } - /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.model.Openable#openBuffer(org.eclipse.core.runtime.IProgressMonitor) */ @@ -500,33 +460,29 @@ public class TranslationUnit extends Openable implements ITranslationUnit { return buffer; } + public Map parse() { + Map map = new HashMap(); + try { + getNewElements(map, this); + } catch (Exception e) { + } + return map; + } + /** * Parse the buffer contents of this element. */ - public Map parse(){ + private void parse(Map newElements){ try { - removeChildren(this); - CModelBuilder modelBuilder = new CModelBuilder(this); + CModelBuilder modelBuilder = new CModelBuilder(this, newElements); boolean quickParseMode = ! (CCorePlugin.getDefault().useStructuralParseMode()); - return modelBuilder.parse(quickParseMode); + modelBuilder.parse(quickParseMode); } catch (Exception e) { // use the debug log for this exception. Util.debugLog( "Exception in CModelBuilder", IDebugLogConstants.MODEL); //$NON-NLS-1$ - return null; } } - public void removeChildren(ICElement element) throws CModelException{ - if (element instanceof Parent){ - Parent parent = (Parent) element; - ICElement[] children = parent.getChildren(); - for(int i =0; i< children.length; ++i){ - removeChildren(children[i]); - } - parent.removeChildren(); - } - } - public IProblemRequestor getProblemRequestor() { return problemRequestor; } @@ -587,6 +543,5 @@ public class TranslationUnit extends Openable implements ITranslationUnit { return res.exists(); return super.exists(); } - } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist/CompletionProposalsBaseTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist/CompletionProposalsBaseTest.java index bb21e856c3e..3bb9ceb1194 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist/CompletionProposalsBaseTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist/CompletionProposalsBaseTest.java @@ -23,12 +23,13 @@ import junit.framework.TestCase; import org.eclipse.cdt.core.CCProjectNature; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.core.parser.ast.IASTCompletionNode; import org.eclipse.cdt.core.parser.ast.IASTNode; import org.eclipse.cdt.core.parser.ast.IASTScope; -import org.eclipse.cdt.internal.core.model.TranslationUnit; import org.eclipse.cdt.internal.core.search.indexing.IndexManager; import org.eclipse.cdt.internal.ui.text.contentassist.CCompletionProcessor; import org.eclipse.cdt.testplugin.CProjectHelper; @@ -51,7 +52,7 @@ public abstract class CompletionProposalsBaseTest extends TestCase{ private IFile fCFile; private IFile fHeaderFile; private NullProgressMonitor monitor; - private TranslationUnit tu = null; + private ITranslationUnit tu = null; private String buffer = EMPTY_STRING; private Document document = null; @@ -120,8 +121,8 @@ public abstract class CompletionProposalsBaseTest extends TestCase{ public void testCompletionProposals(){ try{ // setup the translation unit, the buffer and the document - TranslationUnit header = new TranslationUnit(fCProject, fHeaderFile); - tu = new TranslationUnit(fCProject, fCFile); + //ITranslationUnit header = (ITranslationUnit)CoreModel.getDefault().create(fHeaderFile); + ITranslationUnit tu = (ITranslationUnit)CoreModel.getDefault().create(fCFile); buffer = tu.getBuffer().getContents(); document = new Document(buffer); @@ -200,7 +201,7 @@ public abstract class CompletionProposalsBaseTest extends TestCase{ /** * @return Returns the tu. */ - public TranslationUnit getTranslationUnit() { + public ITranslationUnit getTranslationUnit() { return tu; }