1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Heuristics to update files after changes to a header (bug 171834).

This commit is contained in:
Markus Schorn 2007-11-26 17:27:57 +00:00
parent 99e39db8a4
commit fdc1f3a72f
4 changed files with 155 additions and 19 deletions

View file

@ -96,7 +96,7 @@ public class IndexUpdateTests extends IndexTestBase {
fContentUsed= -1; fContentUsed= -1;
} }
IProject project= cpp ? fCppProject.getProject() : fCProject.getProject(); IProject project= cpp ? fCppProject.getProject() : fCProject.getProject();
fFile= TestSourceReader.createFile(project, "header.h", fContents[++fContentUsed].toString()); fHeader= TestSourceReader.createFile(project, "header.h", fContents[++fContentUsed].toString());
assertTrue(CCorePlugin.getIndexManager().joinIndexer(INDEXER_WAIT_TIME, NPM)); assertTrue(CCorePlugin.getIndexManager().joinIndexer(INDEXER_WAIT_TIME, NPM));
} }
@ -711,4 +711,49 @@ public class IndexUpdateTests extends IndexTestBase {
} }
} }
// int globalVar;
// #include "header.h"
// void test() {
// globalVar= 1;
// }
public void testChangingSourceBeforeHeader_Bug171834() throws Exception {
setupHeader(2, true);
setupFile(0, true);
IBinding binding;
ICompositeType ct;
fIndex.acquireReadLock();
try {
binding = findBinding("globalVar");
assertTrue(binding instanceof IVariable);
assertEquals(2, fIndex.findNames(binding, IIndex.FIND_ALL_OCCURENCES).length);
} finally {
fIndex.releaseReadLock();
}
fFile= TestSourceReader.createFile(fFile.getParent(), fFile.getName(), fContents[1].toString().replaceAll("globalVar", "newVar"));
TestSourceReader.waitUntilFileIsIndexed(fIndex, fFile, INDEXER_WAIT_TIME);
fIndex.acquireReadLock();
try {
binding = findBinding("globalVar");
assertTrue(binding instanceof IVariable);
assertEquals(1, fIndex.findNames(binding, IIndex.FIND_ALL_OCCURENCES).length);
} finally {
fIndex.releaseReadLock();
}
fHeader= TestSourceReader.createFile(fHeader.getParent(), fHeader.getName(), fContents[0].toString().replaceAll("globalVar", "newVar"));
TestSourceReader.waitUntilFileIsIndexed(fIndex, fHeader, INDEXER_WAIT_TIME);
assertTrue(CCorePlugin.getIndexManager().joinIndexer(INDEXER_WAIT_TIME, NPM));
fIndex.acquireReadLock();
try {
binding = findBinding("newVar");
assertTrue(binding instanceof IVariable);
assertEquals(2, fIndex.findNames(binding, IIndex.FIND_ALL_OCCURENCES).length);
} finally {
fIndex.releaseReadLock();
}
}
} }

View file

@ -11,12 +11,22 @@
package org.eclipse.cdt.internal.core.pdom; package org.eclipse.cdt.internal.core.pdom;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMIndexer;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.model.ElementChangedEvent; import org.eclipse.cdt.core.model.ElementChangedEvent;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICElementDelta; import org.eclipse.cdt.core.model.ICElementDelta;
import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IElementChangedListener; import org.eclipse.cdt.core.model.IElementChangedListener;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.pdom.indexer.DeltaAnalyzer;
import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
@ -26,8 +36,14 @@ import org.eclipse.core.runtime.CoreException;
* @since 4.0 * @since 4.0
*/ */
public class CModelListener implements IElementChangedListener, IResourceChangeListener { public class CModelListener implements IElementChangedListener, IResourceChangeListener {
private static final int UPDATE_LR_CHANGED_FILES_COUNT = 5;
private PDOMManager fManager; private PDOMManager fManager;
private LinkedHashMap fLRUs= new LinkedHashMap(UPDATE_LR_CHANGED_FILES_COUNT, 0.75f, true) {
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > UPDATE_LR_CHANGED_FILES_COUNT;
}
};
public CModelListener(PDOMManager manager) { public CModelListener(PDOMManager manager) {
fManager= manager; fManager= manager;
@ -38,22 +54,30 @@ public class CModelListener implements IElementChangedListener, IResourceChangeL
if (event.getType() != ElementChangedEvent.POST_CHANGE) if (event.getType() != ElementChangedEvent.POST_CHANGE)
return; return;
// Walk the delta sending the subtrees to the appropriate indexers // Walk the delta collecting tu's per project
try { HashMap changeMap= new HashMap();
processDelta(event.getDelta()); processDelta(event.getDelta(), changeMap);
} catch (CoreException e) {
CCorePlugin.log(e); // bug 171834 update last recently changed sources
addLastRecentlyUsed(changeMap);
for (Iterator it = changeMap.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
ICProject cproject = (ICProject) entry.getKey();
DeltaAnalyzer analyzer= (DeltaAnalyzer) entry.getValue();
fManager.changeProject(cproject, analyzer.getAddedTUs(), analyzer.getChangedTUs(), analyzer.getRemovedTUs());
} }
} }
private void processDelta(ICElementDelta delta) throws CoreException { private void processDelta(ICElementDelta delta, HashMap changeMap) {
int type = delta.getElement().getElementType(); int type = delta.getElement().getElementType();
switch (type) { switch (type) {
case ICElement.C_MODEL: case ICElement.C_MODEL:
// Loop through the children // Loop through the children
ICElementDelta[] children = delta.getAffectedChildren(); ICElementDelta[] children = delta.getAffectedChildren();
for (int i = 0; i < children.length; ++i) for (int i = 0; i < children.length; ++i) {
processDelta(children[i]); processDelta(children[i], changeMap);
}
break; break;
case ICElement.C_PROJECT: case ICElement.C_PROJECT:
// Find the appropriate indexer and pass the delta on // Find the appropriate indexer and pass the delta on
@ -62,12 +86,77 @@ public class CModelListener implements IElementChangedListener, IResourceChangeL
case ICElementDelta.ADDED: case ICElementDelta.ADDED:
fManager.addProject(project); fManager.addProject(project);
break; break;
case ICElementDelta.CHANGED: case ICElementDelta.CHANGED:
fManager.changeProject(project, delta); processProjectDelta(project, delta, changeMap);
break; break;
case ICElementDelta.REMOVED: case ICElementDelta.REMOVED:
fManager.removeProject(project, delta); fManager.removeProject(project, delta);
break; break;
}
}
}
private void processProjectDelta(ICProject project, ICElementDelta delta, HashMap changeMap) {
IPDOMIndexer indexer = fManager.getIndexer(project);
if (indexer != null && indexer.getID().equals(IPDOMManager.ID_NO_INDEXER)) {
return;
}
DeltaAnalyzer deltaAnalyzer = new DeltaAnalyzer();
try {
deltaAnalyzer.analyzeDelta(delta);
} catch (CoreException e) {
CCorePlugin.log(e);
}
changeMap.put(project, deltaAnalyzer);
}
private void addLastRecentlyUsed(HashMap changeMap) {
boolean addLRUs= false;
int count= 0;
ITranslationUnit[] newLRUs= new ITranslationUnit[UPDATE_LR_CHANGED_FILES_COUNT];
for (Iterator iterator = changeMap.values().iterator(); iterator.hasNext();) {
DeltaAnalyzer analyzer = (DeltaAnalyzer) iterator.next();
List l= analyzer.getAddedList();
for (Iterator it = l.iterator(); it.hasNext();) {
ITranslationUnit tu= (ITranslationUnit) it.next();
newLRUs[count++ % UPDATE_LR_CHANGED_FILES_COUNT]= tu;
if (!addLRUs && tu.isHeaderUnit()) {
addLRUs= true;
}
}
l= analyzer.getChangedList();
for (Iterator it = l.iterator(); it.hasNext();) {
ITranslationUnit tu= (ITranslationUnit) it.next();
newLRUs[count++ % UPDATE_LR_CHANGED_FILES_COUNT]= tu;
if (!addLRUs && tu.isHeaderUnit()) {
addLRUs= true;
}
}
}
if (count > 0) {
if (addLRUs) {
for (Iterator it = fLRUs.keySet().iterator(); it.hasNext();) {
final ITranslationUnit tu = (ITranslationUnit) it.next();
if (tu.getResource().exists()) {
final ICProject cproject= tu.getCProject();
DeltaAnalyzer analyzer= (DeltaAnalyzer) changeMap.get(cproject);
if (analyzer == null) {
analyzer= new DeltaAnalyzer();
changeMap.put(cproject, analyzer);
}
analyzer.getChangedList().add(tu);
}
}
}
count= Math.min(count, newLRUs.length);
for (int i = 0; i < count; i++) {
final ITranslationUnit tu = newLRUs[i];
fLRUs.put(tu, tu);
} }
} }
} }

View file

@ -63,7 +63,6 @@ import org.eclipse.cdt.internal.core.index.provider.IndexProviderManager;
import org.eclipse.cdt.internal.core.pdom.PDOM.IListener; import org.eclipse.cdt.internal.core.pdom.PDOM.IListener;
import org.eclipse.cdt.internal.core.pdom.db.ChunkCache; import org.eclipse.cdt.internal.core.pdom.db.ChunkCache;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMProjectIndexLocationConverter; import org.eclipse.cdt.internal.core.pdom.dom.PDOMProjectIndexLocationConverter;
import org.eclipse.cdt.internal.core.pdom.indexer.DeltaAnalyzer;
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences; import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
import org.eclipse.cdt.internal.core.pdom.indexer.PDOMRebuildTask; import org.eclipse.cdt.internal.core.pdom.indexer.PDOMRebuildTask;
import org.eclipse.cdt.internal.core.pdom.indexer.PDOMUpdateTask; import org.eclipse.cdt.internal.core.pdom.indexer.PDOMUpdateTask;
@ -471,7 +470,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
createPolicy(project).setIndexer(indexer); createPolicy(project).setIndexer(indexer);
} }
private IPDOMIndexer getIndexer(ICProject project) { IPDOMIndexer getIndexer(ICProject project) {
assert !Thread.holdsLock(fProjectToPDOM); assert !Thread.holdsLock(fProjectToPDOM);
synchronized (fUpdatePolicies) { synchronized (fUpdatePolicies) {
IndexUpdatePolicy policy= getPolicy(project); IndexUpdatePolicy policy= getPolicy(project);
@ -724,18 +723,13 @@ public class PDOMManager implements IWritableIndexManager, IListener {
} }
} }
void changeProject(ICProject project, ICElementDelta delta) throws CoreException { void changeProject(ICProject project, ITranslationUnit[] added, ITranslationUnit[] changed, ITranslationUnit[] removed) {
assert !Thread.holdsLock(fProjectToPDOM); assert !Thread.holdsLock(fProjectToPDOM);
IPDOMIndexer indexer = getIndexer(project); IPDOMIndexer indexer = getIndexer(project);
if (indexer != null && indexer.getID().equals(IPDOMManager.ID_NO_INDEXER)) { if (indexer != null && indexer.getID().equals(IPDOMManager.ID_NO_INDEXER)) {
return; return;
} }
DeltaAnalyzer deltaAnalyzer = new DeltaAnalyzer();
deltaAnalyzer.analyzeDelta(delta);
ITranslationUnit[] added= deltaAnalyzer.getAddedTUs();
ITranslationUnit[] changed= deltaAnalyzer.getChangedTUs();
ITranslationUnit[] removed= deltaAnalyzer.getRemovedTUs();
if (added.length > 0 || changed.length > 0 || removed.length > 0) { if (added.length > 0 || changed.length > 0 || removed.length > 0) {
synchronized (fUpdatePolicies) { synchronized (fUpdatePolicies) {
IndexUpdatePolicy policy= createPolicy(project); IndexUpdatePolicy policy= createPolicy(project);

View file

@ -88,4 +88,12 @@ public class DeltaAnalyzer {
public ITranslationUnit[] getRemovedTUs() { public ITranslationUnit[] getRemovedTUs() {
return (ITranslationUnit[]) fRemoved.toArray(new ITranslationUnit[fRemoved.size()]); return (ITranslationUnit[]) fRemoved.toArray(new ITranslationUnit[fRemoved.size()]);
} }
public List getAddedList() {
return fAdded;
}
public List getChangedList() {
return fChanged;
}
} }