1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

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.
This commit is contained in:
Alain Magloire 2004-06-19 02:43:04 +00:00
parent c5c4b73fed
commit a443caeb08
26 changed files with 333 additions and 316 deletions

View file

@ -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();

View file

@ -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) {
}
}

View file

@ -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;
}

View file

@ -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);

View file

@ -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();

View file

@ -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.

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -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()) {

View file

@ -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;
}

View file

@ -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 {
}
}

View file

@ -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 {
}
}

View file

@ -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();

View file

@ -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 <code>IOpenable</code> that is known to be closed (no check for
* <code>isOpen()</code>).
*/
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,

View file

@ -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 {

View file

@ -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

View file

@ -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.
*/

View file

@ -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();

View file

@ -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()
*/

View file

@ -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);
}

View file

@ -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 {
}
}

View file

@ -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 <code>IOpenable</code> that is known to be closed (no check for
* <code>isOpen()</code>).
/* (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);
}
}

View file

@ -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();
}

View file

@ -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);
}
}

View file

@ -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();
}
}

View file

@ -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;
}