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:
parent
99e39db8a4
commit
fdc1f3a72f
4 changed files with 155 additions and 19 deletions
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue