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;
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,9 +86,11 @@ 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;
|
||||||
|
@ -72,6 +98,69 @@ public class CModelListener implements IElementChangedListener, IResourceChangeL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void resourceChanged(IResourceChangeEvent event) {
|
public void resourceChanged(IResourceChangeEvent event) {
|
||||||
if (event.getType() == IResourceChangeEvent.POST_BUILD) {
|
if (event.getType() == IResourceChangeEvent.POST_BUILD) {
|
||||||
fManager.handlePostBuildEvent();
|
fManager.handlePostBuildEvent();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue