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;
}
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));
}
@ -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;
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.dom.IPDOMIndexer;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.model.ElementChangedEvent;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICElementDelta;
import org.eclipse.cdt.core.model.ICProject;
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.IResourceChangeListener;
import org.eclipse.core.runtime.CoreException;
@ -26,8 +36,14 @@ import org.eclipse.core.runtime.CoreException;
* @since 4.0
*/
public class CModelListener implements IElementChangedListener, IResourceChangeListener {
private static final int UPDATE_LR_CHANGED_FILES_COUNT = 5;
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) {
fManager= manager;
@ -38,22 +54,30 @@ public class CModelListener implements IElementChangedListener, IResourceChangeL
if (event.getType() != ElementChangedEvent.POST_CHANGE)
return;
// Walk the delta sending the subtrees to the appropriate indexers
try {
processDelta(event.getDelta());
} catch (CoreException e) {
CCorePlugin.log(e);
// Walk the delta collecting tu's per project
HashMap changeMap= new HashMap();
processDelta(event.getDelta(), changeMap);
// 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();
switch (type) {
case ICElement.C_MODEL:
// Loop through the children
ICElementDelta[] children = delta.getAffectedChildren();
for (int i = 0; i < children.length; ++i)
processDelta(children[i]);
for (int i = 0; i < children.length; ++i) {
processDelta(children[i], changeMap);
}
break;
case ICElement.C_PROJECT:
// Find the appropriate indexer and pass the delta on
@ -62,12 +86,77 @@ public class CModelListener implements IElementChangedListener, IResourceChangeL
case ICElementDelta.ADDED:
fManager.addProject(project);
break;
case ICElementDelta.CHANGED:
fManager.changeProject(project, delta);
processProjectDelta(project, delta, changeMap);
break;
case ICElementDelta.REMOVED:
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.db.ChunkCache;
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.PDOMRebuildTask;
import org.eclipse.cdt.internal.core.pdom.indexer.PDOMUpdateTask;
@ -471,7 +470,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
createPolicy(project).setIndexer(indexer);
}
private IPDOMIndexer getIndexer(ICProject project) {
IPDOMIndexer getIndexer(ICProject project) {
assert !Thread.holdsLock(fProjectToPDOM);
synchronized (fUpdatePolicies) {
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);
IPDOMIndexer indexer = getIndexer(project);
if (indexer != null && indexer.getID().equals(IPDOMManager.ID_NO_INDEXER)) {
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) {
synchronized (fUpdatePolicies) {
IndexUpdatePolicy policy= createPolicy(project);

View file

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