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

related to 169847 and 167551, simplification of PDOMIndexerTasks

This commit is contained in:
Markus Schorn 2007-02-28 10:45:34 +00:00
parent 0a1dd38992
commit 835dcd2dbc
24 changed files with 1129 additions and 1049 deletions

View file

@ -15,9 +15,8 @@ package org.eclipse.cdt.core.dom;
import java.util.Properties;
import org.eclipse.cdt.core.model.ICElementDelta;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.cdt.core.model.ITranslationUnit;
/**
@ -28,11 +27,7 @@ public interface IPDOMIndexer {
public void setProject(ICProject project);
public ICProject getProject();
public void handleDelta(ICElementDelta delta) throws CoreException;
public void reindex() throws CoreException;
/**
* Return the unique ID of type of this indexer
* @return the unique ID of type of this indexer
@ -56,5 +51,12 @@ public interface IPDOMIndexer {
* Used to check whether we need to reindex a project.
* @since 4.0
*/
public boolean hasProperties(Properties props);
public boolean needsToRebuildForProperties(Properties props);
/**
* Clients are not allowed to call this method, it is called by the framework.
* Creates a task that handles the changes.
* @since 4.0
*/
public IPDOMIndexerTask createTask(ITranslationUnit[] added, ITranslationUnit[] changed, ITranslationUnit[] removed);
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2006 QNX Software Systems
* Copyright (c) 2005, 2007 QNX Software Systems
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -15,6 +15,7 @@
package org.eclipse.cdt.core.dom;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.internal.core.pdom.IndexerProgress;
import org.eclipse.core.runtime.IProgressMonitor;
@ -26,39 +27,19 @@ public interface IPDOMIndexerTask {
public static final String TRACE_ACTIVITY = CCorePlugin.PLUGIN_ID + "/debug/indexer/activity"; //$NON-NLS-1$
public static final String TRACE_STATISTICS = CCorePlugin.PLUGIN_ID + "/debug/indexer/statistics"; //$NON-NLS-1$
public static final String TRACE_PROBLEMS = CCorePlugin.PLUGIN_ID + "/debug/indexer/problems"; //$NON-NLS-1$
/**
* Run the sub job progress to the main job.
*
* @param mainJob
* Called by the framework to perform the task.
*/
public void run(IProgressMonitor monitor);
/**
* Returns the indexer the task belongs to.
*/
public IPDOMIndexer getIndexer();
/**
* Returns the remaining subtasks. The count may increase over the time.
* Used by the framework to report progress.
* @since 4.0
* Returns progress information for the task.
*/
public int estimateRemainingSources();
/**
* Used by the framework to report progress.
* @since 4.0
*/
public int getCompletedSourcesCount();
/**
* Used by the framework to report progress.
* @since 4.0
*/
public int getCompletedHeadersCount();
/**
* Returns information about the current subtask.
* Used by the framework to report progress.
* @since 4.0
*/
public String getMonitorMessageDetail();
public IndexerProgress getProgressInformation();
}

View file

@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2007 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom;
public class IndexerProgress {
public int fTotalSourcesEstimate;
public int fCompletedHeaders;
public int fCompletedSources;
public String fMonitorDetail;
public IndexerProgress() {
}
public IndexerProgress(IndexerProgress info) {
fTotalSourcesEstimate= info.fTotalSourcesEstimate;
fCompletedHeaders= info.fCompletedHeaders;
fCompletedSources= info.fCompletedSources;
fMonitorDetail= info.fMonitorDetail;
}
public int getRemainingSources() {
return fTotalSourcesEstimate-fCompletedSources;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2006 QNX Software Systems
* Copyright (c) 2005, 2007 QNX Software Systems
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -16,6 +16,7 @@ import org.eclipse.cdt.core.dom.IPDOMIndexer;
import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
@ -26,7 +27,7 @@ import org.eclipse.core.runtime.jobs.Job;
*/
public class PDOMIndexerJob extends Job {
private static final int TOTAL_MONITOR_WORK = 1000;
private static final int TOTAL_MONITOR_WORK = 100000;
private final PDOMManager pdomManager;
private IPDOMIndexerTask currentTask;
private boolean cancelledByManager= false;
@ -49,6 +50,15 @@ public class PDOMIndexerJob extends Job {
Job monitorJob= startMonitorJob(monitor);
try {
do {
IProgressMonitor npm= new NullProgressMonitor() {
public boolean isCanceled() {
return fMonitor.isCanceled();
}
public void setCanceled(boolean cancelled) {
fMonitor.setCanceled(cancelled);
}
};
synchronized(taskMutex) {
currentTask= null;
taskMutex.notify();
@ -64,7 +74,7 @@ public class PDOMIndexerJob extends Job {
}
if (currentTask != null) {
currentTask.run(monitor);
currentTask.run(npm);
}
}
while (currentTask != null);

View file

@ -41,6 +41,9 @@ import org.eclipse.cdt.internal.core.index.IndexerStateEvent;
import org.eclipse.cdt.internal.core.pdom.PDOM.IListener;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMProjectIndexLocationConverter;
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
import org.eclipse.cdt.internal.core.pdom.indexer.PDOMImportTask;
import org.eclipse.cdt.internal.core.pdom.indexer.PDOMRebuildTask;
import org.eclipse.cdt.internal.core.pdom.indexer.PDOMResourceDeltaTask;
import org.eclipse.cdt.internal.core.pdom.indexer.nulli.PDOMNullIndexer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResourceDelta;
@ -79,8 +82,8 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
}
private final class PCL implements IPreferenceChangeListener {
private IProject fProject;
public PCL(IProject prj) {
private ICProject fProject;
public PCL(ICProject prj) {
fProject= prj;
}
public void preferenceChange(PreferenceChangeEvent event) {
@ -225,21 +228,15 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
IndexerPreferences.set(prj, IndexerPreferences.KEY_INDEXER_ID, indexerId);
CCoreInternals.savePreferences(prj);
}
public IPDOMIndexer getIndexer(ICProject project) {
return getIndexer(project, true);
}
protected void onPreferenceChange(IProject project, PreferenceChangeEvent event) {
protected void onPreferenceChange(ICProject cproject, PreferenceChangeEvent event) {
IProject project= cproject.getProject();
if (project.exists() && project.isOpen()) {
ICProject cproject= CoreModel.getDefault().create(project);
if (cproject != null) {
try {
changeIndexer(cproject);
}
catch (Exception e) {
CCorePlugin.log(e);
}
try {
changeIndexer(cproject);
}
catch (Exception e) {
CCorePlugin.log(e);
}
}
}
@ -255,11 +252,14 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
synchronized (fIndexerMutex) {
oldIndexer= getIndexer(cproject, false);
if (oldIndexer != null) {
if (oldIndexer.getID().equals(newid) && oldIndexer.hasProperties(props)) {
return;
if (oldIndexer.getID().equals(newid)) {
if (!oldIndexer.needsToRebuildForProperties(props)) {
oldIndexer.setProperties(props);
return;
}
}
createIndexer(cproject, newid, props, true);
}
createIndexer(cproject, newid, props, true);
}
if (oldIndexer != null) {
@ -267,7 +267,7 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
}
}
public IPDOMIndexer getIndexer(ICProject project, boolean create) {
private IPDOMIndexer getIndexer(ICProject project, boolean create) {
assert !Thread.holdsLock(fProjectToPDOM);
synchronized (fIndexerMutex) {
IProject prj = project.getProject();
@ -333,12 +333,17 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
project.getProject().setSessionProperty(indexerProperty, indexer);
if (reindex) {
indexer.reindex();
if (forceReindex) {
enqueue(new PDOMRebuildTask(indexer));
}
else {
enqueue(new PDOMImportTask(indexer));
}
}
return indexer;
}
public void enqueue(IPDOMIndexerTask subjob) {
public void enqueue(IPDOMIndexerTask subjob) {
synchronized (fTaskQueueMutex) {
fTaskQueue.addLast(subjob);
if (fIndexerJob == null) {
@ -362,8 +367,11 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
}
else {
if (fCurrentTask != null) {
fCompletedSources+= fCurrentTask.getCompletedSourcesCount();
fCompletedHeaders+= fCurrentTask.getCompletedHeadersCount();
IndexerProgress info= fCurrentTask.getProgressInformation();
if (info != null) {
fCompletedSources+= info.fCompletedSources;
fCompletedHeaders+= info.fCompletedHeaders;
}
}
result= fCurrentTask= (IPDOMIndexerTask)fTaskQueue.removeFirst();
}
@ -403,7 +411,7 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
IProject prj= project.getProject();
PCL pcl= (PCL) fPrefListeners.get(prj);
if (pcl == null) {
pcl= new PCL(prj);
pcl= new PCL(project);
fPrefListeners.put(prj, pcl);
}
IndexerPreferences.addChangeListener(prj, pcl);
@ -419,11 +427,14 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
public void changeProject(ICProject project, ICElementDelta delta) throws CoreException {
IPDOMIndexer indexer = getIndexer(project, true);
if (indexer != null)
indexer.handleDelta(delta);
if (indexer != null) {
PDOMResourceDeltaTask resourceDeltaTask = new PDOMResourceDeltaTask(indexer, delta);
if (!resourceDeltaTask.isEmpty()) {
enqueue(resourceDeltaTask);
}
}
}
public void removeProject(ICProject project) {
IPDOMIndexer indexer= getIndexer(project, false);
if (indexer != null) {
@ -496,7 +507,7 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
synchronized(fIndexerMutex) {
indexer= getIndexer(project, true);
indexer.reindex();
enqueue(new PDOMRebuildTask(indexer));
}
}
@ -632,19 +643,33 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
int remainingSources= 0;
int completedSources= 0;
int completedHeaders= 0;
int unknown= 0;
String detail= null;
IndexerProgress info;
synchronized (fTaskQueueMutex) {
completedHeaders= fCompletedHeaders;
completedSources= fCompletedSources;
for (Iterator iter = fTaskQueue.iterator(); iter.hasNext();) {
IPDOMIndexerTask task = (IPDOMIndexerTask) iter.next();
remainingSources+= task.estimateRemainingSources();
info= task.getProgressInformation();
if (info == null) {
unknown++;
}
else {
remainingSources+= info.getRemainingSources();
}
}
if (fCurrentTask != null) {
remainingSources+= fCurrentTask.estimateRemainingSources();
completedHeaders+= fCurrentTask.getCompletedHeadersCount();
completedSources+= fCurrentTask.getCompletedSourcesCount();
detail= fCurrentTask.getMonitorMessageDetail();
info= fCurrentTask.getProgressInformation();
if (info == null) {
unknown++;
}
else {
remainingSources+= info.getRemainingSources();
completedHeaders+= info.fCompletedHeaders;
completedSources+= info.fCompletedSources;
detail= info.fMonitorDetail;
}
}
}
@ -657,6 +682,7 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
}
monitor.subTask(msg);
totalSources+= unknown*1000;
if (completedSources > 0 && totalSources >= completedSources) {
int newTick= completedSources*base/totalSources;
if (newTick > currentTicks) {

View file

@ -39,7 +39,7 @@ public abstract class AbstractPDOMIndexer implements IPDOMIndexer {
return fProperties.getProperty(key);
}
public boolean hasProperties(Properties props) {
public boolean needsToRebuildForProperties(Properties props) {
for (Iterator i= fProperties.entrySet().iterator(); i.hasNext();) {
Map.Entry entry = (Map.Entry) i.next();
String key = (String) entry.getKey();
@ -48,11 +48,11 @@ public abstract class AbstractPDOMIndexer implements IPDOMIndexer {
if (myval != null) { // relevant property
String v2= (String) props.get(key);
if (v2 != null && !myval.equals(v2)) {
return false;
return true;
}
}
}
return true;
return false;
}
public void setProperties(Properties props) {

View file

@ -0,0 +1,22 @@
/*******************************************************************************
* Copyright (c) 2007 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.indexer;
public class IndexerStatistics {
public int fResolutionTime;
public int fParsingTime;
public int fAddToIndexTime;
public int fErrorCount;
public int fReferenceCount= 0;
public int fDeclarationCount= 0;
public int fProblemBindingCount= 0;
}

View file

@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2007 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.indexer;
import org.eclipse.cdt.core.dom.IPDOMIndexer;
import org.eclipse.core.runtime.IProgressMonitor;
public class PDOMImportTask extends PDOMRebuildTask {
public PDOMImportTask(IPDOMIndexer indexer) {
super(indexer);
}
public void run(IProgressMonitor monitor) {
// mstodo try to import pdom first.
super.run(monitor);
}
}

View file

@ -17,19 +17,12 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
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.IPDOMIndexerTask;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexFileLocation;
@ -37,170 +30,75 @@ import org.eclipse.cdt.core.index.IIndexInclude;
import org.eclipse.cdt.core.index.IndexLocationFactory;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.CoreModelUtil;
import org.eclipse.cdt.core.model.ICContainer;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICElementDelta;
import org.eclipse.cdt.core.model.ICElementVisitor;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
import org.eclipse.cdt.internal.core.index.IWritableIndex;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMASTAdapter;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.cdt.internal.core.pdom.IndexerProgress;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
public abstract class PDOMIndexerTask implements IPDOMIndexerTask {
private static final class TranslationUnitCollector implements ICElementVisitor {
private final Collection fHeaders;
private final boolean fAllFiles;
private final Collection fSources;
private final IProgressMonitor fProgressMonitor;
private TranslationUnitCollector(Collection sources, Collection headers, boolean allFiles,
IProgressMonitor pm) {
fHeaders = headers;
fAllFiles = allFiles;
fSources = sources;
fProgressMonitor= pm;
}
public boolean visit(ICElement element) throws CoreException {
if (fProgressMonitor.isCanceled()) {
return false;
}
switch (element.getElementType()) {
case ICElement.C_UNIT:
ITranslationUnit tu = (ITranslationUnit)element;
if (tu.isSourceUnit()) {
if (fAllFiles || !CoreModel.isScannerInformationEmpty(tu.getResource())) {
fSources.add(tu);
}
}
else if (fHeaders != null && tu.isHeaderUnit()) {
fHeaders.add(tu);
}
return false;
case ICElement.C_CCONTAINER:
case ICElement.C_PROJECT:
return true;
}
return false;
}
}
public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexerTask {
private static final Object NO_CONTEXT = new Object();
protected static final int MAX_ERRORS = 500;
private static final String TRUE = String.valueOf(true);
protected volatile int fTotalSourcesEstimate= 0;
protected volatile int fCompletedSources= 0;
protected volatile int fCompletedHeaders= 0;
private static final int MAX_ERRORS = 500;
private static final String TRUE = "true"; //$NON-NLS-1$
private IPDOMIndexer fIndexer;
protected Map/*<IIndexFileLocation, Object>*/ fContextMap = new HashMap/*<IIndexFileLocation, Object>*/();
protected volatile String fMessage;
private boolean fShowActivity;
private boolean fShowStatistics;
private boolean fShowProblems;
private int fResolutionTime;
private int fParsingTime;
private int fAddToIndexTime;
private int fErrorCount;
private int fReferenceCount= 0;
private int fDeclarationCount= 0;
private int fProblemBindingCount= 0;
protected PDOMIndexerTask() {
fShowActivity= checkDebugOption(TRACE_ACTIVITY, "true"); //$NON-NLS-1$
fShowStatistics= checkDebugOption(TRACE_STATISTICS, "true"); //$NON-NLS-1$
fShowProblems= checkDebugOption(TRACE_PROBLEMS, "true"); //$NON-NLS-1$
protected PDOMIndexerTask(IPDOMIndexer indexer) {
fIndexer= indexer;
}
private boolean checkDebugOption(String option, String value) {
String trace= Platform.getDebugOption(option);
boolean internallyActivated= Boolean.getBoolean(option);
return internallyActivated || (trace != null && trace.equalsIgnoreCase(value));
final public IPDOMIndexer getIndexer() {
return fIndexer;
}
final public ICProject getProject() {
return fIndexer.getProject();
}
final public IndexerProgress getProgressInformation() {
return super.getProgressInformation();
}
/**
* Figurues out whether all files (sources without config, headers not included)
* should be parsed.
* @since 4.0
*/
final protected boolean getIndexAllFiles() {
return TRUE.equals(getIndexer().getProperty(IndexerPreferences.KEY_INDEX_ALL_FILES));
}
protected void processDelta(ICElementDelta delta, Collection added, Collection changed, Collection removed,
IProgressMonitor pm) throws CoreException {
boolean allFiles= getIndexAllFiles();
int flags = delta.getFlags();
/**
* Called to create the ast for a translation unit. May return <code>null</code>.
* @see #parseTUs(IWritableIndex, int, Collection, Collection, IProgressMonitor)
* @since 4.0
*/
abstract protected IASTTranslationUnit createAST(ITranslationUnit tu, IProgressMonitor pm) throws CoreException, InterruptedException;
if ((flags & ICElementDelta.F_CHILDREN) != 0) {
ICElementDelta[] children = delta.getAffectedChildren();
for (int i = 0; i < children.length; ++i) {
processDelta(children[i], added, changed, removed, pm);
}
}
ICElement element = delta.getElement();
switch (element.getElementType()) {
case ICElement.C_UNIT:
ITranslationUnit tu = (ITranslationUnit)element;
switch (delta.getKind()) {
case ICElementDelta.CHANGED:
if ((flags & ICElementDelta.F_CONTENT) != 0 &&
(allFiles || !CoreModel.isScannerInformationEmpty(tu.getResource()))) {
changed.add(tu);
}
break;
case ICElementDelta.ADDED:
if (!tu.isWorkingCopy() &&
(allFiles || !CoreModel.isScannerInformationEmpty(tu.getResource()))) {
added.add(tu);
}
break;
case ICElementDelta.REMOVED:
if (!tu.isWorkingCopy())
removed.add(tu);
break;
}
break;
case ICElement.C_CCONTAINER:
ICContainer folder= (ICContainer) element;
if (delta.getKind() == ICElementDelta.ADDED) {
collectSources(folder, added, added, allFiles, pm);
}
break;
}
}
private void collectSources(ICContainer container, Collection sources, Collection headers, boolean allFiles,
IProgressMonitor pm) throws CoreException {
container.accept(new TranslationUnitCollector(sources, headers, allFiles, pm));
}
protected void collectSources(ICProject project, Collection sources, Collection headers, boolean allFiles,
IProgressMonitor pm) throws CoreException {
fMessage= MessageFormat.format(Messages.PDOMIndexerTask_collectingFilesTask, new Object[]{project.getElementName()});
project.accept(new TranslationUnitCollector(sources, headers, allFiles, pm));
}
protected void removeTU(IWritableIndex index, ITranslationUnit tu, int readlocks) throws CoreException, InterruptedException {
index.acquireWriteLock(readlocks);
try {
IIndexFragmentFile file = (IIndexFragmentFile) index.getFile(getIndexFileLocation(tu));
if (file != null)
index.clearFile(file);
} finally {
index.releaseWriteLock(readlocks);
}
}
protected void parseTUs(Collection sources, Collection headers, IProgressMonitor monitor) throws CoreException, InterruptedException {
/**
* Convenience method for subclasses, parses the files calling out to the methods
* {@link #createAST(ITranslationUnit, IProgressMonitor)},
* {@link #needToUpdate(IIndexFileLocation)},
* {@link #addSymbols(IASTTranslationUnit, IWritableIndex, int, IProgressMonitor)}
* {@link #postAddToIndex(IIndexFileLocation, IIndexFile)} and
* {@link #findLocation(String)}
* @since 4.0
*/
protected void parseTUs(IWritableIndex index, int readlockCount, Collection sources, Collection headers, IProgressMonitor monitor) throws CoreException, InterruptedException {
// sources first
for (Iterator iter = sources.iterator(); iter.hasNext();) {
if (monitor.isCanceled())
return;
ITranslationUnit tu = (ITranslationUnit) iter.next();
if (needToUpdate(getIndexFileLocation(tu))) {
parseTU(tu, monitor);
parseTU(tu, index, readlockCount, monitor);
}
}
@ -213,9 +111,9 @@ public abstract class PDOMIndexerTask implements IPDOMIndexerTask {
if (!needToUpdate(location)) {
iter.remove();
} else {
ITranslationUnit context= findContext(getIndex(), location);
ITranslationUnit context= findContext(index, location);
if (context != null) {
parseTU(context, monitor);
parseTU(context, index, readlockCount, monitor);
}
}
}
@ -230,23 +128,26 @@ public abstract class PDOMIndexerTask implements IPDOMIndexerTask {
iter.remove();
}
else {
parseTU(tu, monitor);
parseTU(tu, index, readlockCount, monitor);
}
}
}
}
protected void parseTU(ITranslationUnit tu, IProgressMonitor pm) throws CoreException, InterruptedException {
private void parseTU(ITranslationUnit tu, IWritableIndex index, int readlockCount, IProgressMonitor pm) throws CoreException, InterruptedException {
IPath path= tu.getPath();
try {
if (fShowActivity) {
System.out.println("Indexer: parsing " + path.toOSString()); //$NON-NLS-1$
}
fMessage= MessageFormat.format(Messages.PDOMIndexerTask_parsingFileTask,
new Object[]{path.lastSegment(), path.removeLastSegments(1).toString()});
setMonitorDetail(MessageFormat.format(Messages.PDOMIndexerTask_parsingFileTask,
new Object[]{path.lastSegment(), path.removeLastSegments(1).toString()}));
long start= System.currentTimeMillis();
doParseTU(tu, pm);
fParsingTime += System.currentTimeMillis()-start;
IASTTranslationUnit ast= createAST(tu, pm);
fStatistics.fParsingTime += System.currentTimeMillis()-start;
if (tu != null) {
addSymbols(ast, index, readlockCount, pm);
}
}
catch (CoreException e) {
swallowError(path, e);
@ -263,32 +164,13 @@ public abstract class PDOMIndexerTask implements IPDOMIndexerTask {
IStatus status= CCorePlugin.createStatus(
MessageFormat.format(Messages.PDOMIndexerTask_errorWhileParsing, new Object[]{file}), e);
CCorePlugin.log(status);
if (++fErrorCount > MAX_ERRORS) {
if (++fStatistics.fErrorCount > MAX_ERRORS) {
throw new CoreException(CCorePlugin.createStatus(
MessageFormat.format(Messages.PDOMIndexerTask_tooManyIndexProblems, new Object[]{getIndexer().getProject().getElementName()})));
}
}
abstract protected void doParseTU(ITranslationUnit tu, IProgressMonitor pm) throws CoreException, InterruptedException;
protected void clearIndex(IWritableIndex index) throws InterruptedException, CoreException {
// reset error count
fErrorCount= 0;
// First clear the pdom
index.acquireWriteLock(0);
try {
index.clear();
}
finally {
index.releaseWriteLock(0);
}
}
protected boolean getIndexAllFiles() {
return TRUE.equals(getIndexer().getProperty(IndexerPreferences.KEY_INDEX_ALL_FILES));
}
protected ITranslationUnit findContext(IIndex index, IIndexFileLocation location) {
private ITranslationUnit findContext(IIndex index, IIndexFileLocation location) {
Object cachedContext= fContextMap.get(location);
if (cachedContext != null) {
return cachedContext == NO_CONTEXT ? null : (ITranslationUnit) cachedContext;
@ -329,234 +211,18 @@ public abstract class PDOMIndexerTask implements IPDOMIndexerTask {
return null;
}
public String getMonitorMessageDetail() {
return fMessage;
}
final public int estimateRemainingSources() {
return fTotalSourcesEstimate-fCompletedSources;
}
public int getCompletedHeadersCount() {
return fCompletedHeaders;
}
public int getCompletedSourcesCount() {
return fCompletedSources;
}
protected void addSymbols(IASTTranslationUnit ast, IProgressMonitor pm) throws InterruptedException, CoreException {
final Map symbolMap= new HashMap();
/**
* Conveninence method for subclasses, removes a translation unit from the index.
* @since 4.0
*/
protected void removeTU(IWritableIndex index, ITranslationUnit tu, int readlocks) throws CoreException, InterruptedException {
index.acquireWriteLock(readlocks);
try {
IIndexFileLocation[] orderedPaths= extractSymbols(ast, symbolMap);
for (int i=0; i<orderedPaths.length; i++) {
if (pm.isCanceled()) {
return;
}
IIndexFileLocation path= orderedPaths[i];
ArrayList[] arrayLists = ((ArrayList[]) symbolMap.get(path));
// resolve the names
long start= System.currentTimeMillis();
ArrayList names= arrayLists[2];
for (int j=0; j<names.size(); j++) {
final IASTName name = ((IASTName[]) names.get(j))[0];
final IBinding binding= name.resolveBinding();
if (fShowStatistics) {
if (binding instanceof IProblemBinding)
reportProblem((IProblemBinding) binding);
else if (name.isReference())
fReferenceCount++;
else
fDeclarationCount++;
}
}
fResolutionTime += System.currentTimeMillis()-start;
}
boolean isFirstRequest= true;
boolean isFirstAddition= true;
IWritableIndex index= getIndex();
index.acquireWriteLock(getReadlockCount());
long start= System.currentTimeMillis();
try {
for (int i=0; i<orderedPaths.length; i++) {
if (pm.isCanceled())
return;
IIndexFileLocation path = orderedPaths[i];
if (path != null) {
if (fShowActivity) {
System.out.println("Indexer: adding " + path.getURI()); //$NON-NLS-1$
}
IIndexFile file= addToIndex(index, path, symbolMap);
if (postAddToIndex(path, file)) {
if (isFirstRequest)
isFirstRequest= false;
else
fTotalSourcesEstimate--;
}
if (isFirstAddition)
isFirstAddition= false;
else
fCompletedHeaders++;
}
}
} finally {
index.releaseWriteLock(getReadlockCount());
}
fAddToIndexTime+= System.currentTimeMillis()-start;
}
finally {
fCompletedSources++;
}
}
private void reportProblem(IProblemBinding problem) {
fProblemBindingCount++;
if (fShowProblems) {
String msg= "Indexer problem at "+ problem.getFileName() + ": " + problem.getLineNumber(); //$NON-NLS-1$//$NON-NLS-2$
String pmsg= problem.getMessage();
if (pmsg != null && pmsg.length() > 0)
msg+= "; " + problem.getMessage(); //$NON-NLS-1$
System.out.println(msg);
}
}
private IIndexFileLocation[] extractSymbols(IASTTranslationUnit ast, final Map symbolMap) throws CoreException {
LinkedHashSet/*<IIndexFileLocation>*/ orderedIncludes= new LinkedHashSet/*<IIndexFileLocation>*/();
ArrayList/*<IIndexFileLocation>*/ stack= new ArrayList/*<IIndexFileLocation>*/();
final IIndexFileLocation astLocation = findLocation(ast.getFilePath());
IIndexFileLocation currentPath = astLocation;
IASTPreprocessorIncludeStatement[] includes = ast.getIncludeDirectives();
for (int i= 0; i < includes.length; i++) {
IASTPreprocessorIncludeStatement include = includes[i];
IASTFileLocation sourceLoc = include.getFileLocation();
IIndexFileLocation newPath= sourceLoc != null ? findLocation(sourceLoc.getFileName()) : astLocation; // command-line includes
while (!stack.isEmpty() && !currentPath.equals(newPath)) {
if (needToUpdate(currentPath)) {
prepareInMap(symbolMap, currentPath);
orderedIncludes.add(currentPath);
}
currentPath= (IIndexFileLocation) stack.remove(stack.size()-1);
}
if (needToUpdate(newPath)) {
prepareInMap(symbolMap, newPath);
addToMap(symbolMap, 0, newPath, include);
}
stack.add(currentPath);
currentPath= findLocation(include.getPath());
}
stack.add(currentPath);
while (!stack.isEmpty()) {
currentPath= (IIndexFileLocation) stack.remove(stack.size()-1);
if (needToUpdate(currentPath)) {
prepareInMap(symbolMap, currentPath);
orderedIncludes.add(currentPath);
}
}
// macros
IASTPreprocessorMacroDefinition[] macros = ast.getMacroDefinitions();
for (int i2 = 0; i2 < macros.length; ++i2) {
IASTPreprocessorMacroDefinition macro = macros[i2];
IASTFileLocation sourceLoc = macro.getFileLocation();
if (sourceLoc != null) { // skip built-ins and command line macros
IIndexFileLocation path2 = findLocation(sourceLoc.getFileName());
addToMap(symbolMap, 1, path2, macro);
}
}
// names
ast.accept(new IndexerASTVisitor() {
public void visit(IASTName name, IASTName caller) {
// assign a location to anonymous types.
name= PDOMASTAdapter.getAdapterIfAnonymous(name);
IASTFileLocation nameLoc = name.getFileLocation();
if (nameLoc != null) {
IIndexFileLocation location = findLocation(nameLoc.getFileName());
addToMap(symbolMap, 2, location, new IASTName[]{name, caller});
}
}
});
return (IIndexFileLocation[]) orderedIncludes.toArray(new IIndexFileLocation[orderedIncludes.size()]);
}
protected abstract IWritableIndex getIndex();
protected abstract int getReadlockCount();
protected abstract boolean needToUpdate(IIndexFileLocation location) throws CoreException;
protected abstract boolean postAddToIndex(IIndexFileLocation location, IIndexFile file) throws CoreException;
private void addToMap(Map map, int idx, IIndexFileLocation location, Object thing) {
List[] lists= (List[]) map.get(location);
if (lists != null)
lists[idx].add(thing);
}
private boolean prepareInMap(Map map, IIndexFileLocation location) {
if (map.get(location) == null) {
Object lists= new ArrayList[]{new ArrayList(), new ArrayList(), new ArrayList()};
map.put(location, lists);
}
return false;
}
private IIndexFragmentFile addToIndex(IWritableIndex index, IIndexFileLocation location, Map symbolMap) throws CoreException {
IIndexFragmentFile file= (IIndexFragmentFile) index.getFile(location);
if (file != null) {
index.clearFile(file);
} else {
file= index.addFile(location);
}
file.setTimestamp(EFS.getStore(location.getURI()).fetchInfo().getLastModified());
ArrayList[] lists= (ArrayList[]) symbolMap.get(location);
if (lists != null) {
ArrayList list= lists[0];
IASTPreprocessorIncludeStatement[] includes= (IASTPreprocessorIncludeStatement[]) list.toArray(new IASTPreprocessorIncludeStatement[list.size()]);
list= lists[1];
IASTPreprocessorMacroDefinition[] macros= (IASTPreprocessorMacroDefinition[]) list.toArray(new IASTPreprocessorMacroDefinition[list.size()]);
list= lists[2];
IASTName[][] names= (IASTName[][]) list.toArray(new IASTName[list.size()][]);
IIndexFileLocation[] includeLocations = new IIndexFileLocation[includes.length];
for(int i=0; i<includes.length; i++) {
includeLocations[i] = findLocation(includes[i].getPath());
}
index.setFileContent(file, includes, includeLocations, macros, names);
}
return file;
}
protected void traceEnd(long start) {
if (fShowStatistics) {
String name= getClass().getName();
name= name.substring(name.lastIndexOf('.')+1);
System.out.println(name + " " + getIndexer().getProject().getElementName() //$NON-NLS-1$
+ " (" + fCompletedSources + " sources, " //$NON-NLS-1$ //$NON-NLS-2$
+ fCompletedHeaders + " headers)"); //$NON-NLS-1$
System.out.println(name + " Timings: " //$NON-NLS-1$
+ (System.currentTimeMillis() - start) + " total, " //$NON-NLS-1$
+ (fParsingTime-fResolutionTime-fAddToIndexTime) + " parser, " //$NON-NLS-1$
+ fResolutionTime + " resolution, " //$NON-NLS-1$
+ fAddToIndexTime + " index update."); //$NON-NLS-1$
int sum= fDeclarationCount+fReferenceCount+fProblemBindingCount;
double problemPct= sum==0 ? 0.0 : (double) fProblemBindingCount / (double) sum;
NumberFormat nf= NumberFormat.getPercentInstance();
nf.setMaximumFractionDigits(2);
nf.setMinimumFractionDigits(2);
System.out.println(name + " Result: " //$NON-NLS-1$
+ fDeclarationCount + " declarations, " //$NON-NLS-1$
+ fReferenceCount + " references, " //$NON-NLS-1$
+ fErrorCount + " errors, " //$NON-NLS-1$
+ fProblemBindingCount + "(" + nf.format(problemPct) + ") problems."); //$NON-NLS-1$ //$NON-NLS-2$
IIndexFragmentFile file = (IIndexFragmentFile) index.getFile(getIndexFileLocation(tu));
if (file != null)
index.clearFile(file);
} finally {
index.releaseWriteLock(readlocks);
}
}
@ -566,6 +232,33 @@ public abstract class PDOMIndexerTask implements IPDOMIndexerTask {
else
return IndexLocationFactory.getExternalIFL(tu.getLocation());
}
protected void traceEnd(long start) {
if (checkDebugOption(IPDOMIndexerTask.TRACE_STATISTICS, TRUE)) {
IndexerProgress info= getProgressInformation();
String name= getClass().getName();
name= name.substring(name.lastIndexOf('.')+1);
System.out.println(name + " " + getProject().getElementName() //$NON-NLS-1$
+ " (" + info.fCompletedSources + " sources, " //$NON-NLS-1$ //$NON-NLS-2$
+ info.fCompletedHeaders + " headers)"); //$NON-NLS-1$
System.out.println(name + " Timings: " //$NON-NLS-1$
+ (System.currentTimeMillis() - start) + " total, " //$NON-NLS-1$
+ fStatistics.fParsingTime + " parser, " //$NON-NLS-1$
+ fStatistics.fResolutionTime + " resolution, " //$NON-NLS-1$
+ fStatistics.fAddToIndexTime + " index update."); //$NON-NLS-1$
int sum= fStatistics.fDeclarationCount+fStatistics.fReferenceCount+fStatistics.fProblemBindingCount;
double problemPct= sum==0 ? 0.0 : (double) fStatistics.fProblemBindingCount / (double) sum;
NumberFormat nf= NumberFormat.getPercentInstance();
nf.setMaximumFractionDigits(2);
nf.setMinimumFractionDigits(2);
System.out.println(name + " Result: " //$NON-NLS-1$
+ fStatistics.fDeclarationCount + " declarations, " //$NON-NLS-1$
+ fStatistics.fReferenceCount + " references, " //$NON-NLS-1$
+ fStatistics.fErrorCount + " errors, " //$NON-NLS-1$
+ fStatistics.fProblemBindingCount + "(" + nf.format(problemPct) + ") problems."); //$NON-NLS-1$ //$NON-NLS-2$
}
}
protected abstract IIndexFileLocation findLocation(String absolutePath);
}

View file

@ -0,0 +1,90 @@
/*******************************************************************************
* Copyright (c) 2007 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.indexer;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMIndexer;
import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.index.IWritableIndex;
import org.eclipse.cdt.internal.core.index.IWritableIndexManager;
import org.eclipse.cdt.internal.core.pdom.IndexerProgress;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
public class PDOMRebuildTask implements IPDOMIndexerTask {
private static final String TRUE= String.valueOf(true);
private static final ITranslationUnit[] NO_TUS = new ITranslationUnit[0];
private IPDOMIndexer fIndexer;
private IPDOMIndexerTask fDelegate;
public PDOMRebuildTask(IPDOMIndexer indexer) {
fIndexer= indexer;
}
public IPDOMIndexer getIndexer() {
return fIndexer;
}
public void run(IProgressMonitor monitor) {
ICProject project= fIndexer.getProject();
if (project.getProject().isOpen()) {
try {
clearIndex(project);
if (!IPDOMManager.ID_NO_INDEXER.equals(fIndexer.getID())) {
createDelegate(project, monitor);
}
} catch (CoreException e) {
CCorePlugin.log(e);
} catch (InterruptedException e) {
}
}
if (fDelegate != null) {
fDelegate.run(monitor);
}
}
private void clearIndex(ICProject project) throws CoreException, InterruptedException {
IWritableIndex index= ((IWritableIndexManager) CCorePlugin.getIndexManager()).getWritableIndex(project);
// First clear the pdom
index.acquireWriteLock(0);
try {
index.clear();
}
finally {
index.releaseWriteLock(0);
}
}
private void createDelegate(ICProject project, IProgressMonitor monitor) throws CoreException {
boolean allFiles= TRUE.equals(fIndexer.getProperty(IndexerPreferences.KEY_INDEX_ALL_FILES));
List list= new ArrayList();
TranslationUnitCollector collector= new TranslationUnitCollector(list, allFiles, monitor);
project.accept(collector);
ITranslationUnit[] tus= (ITranslationUnit[]) list.toArray(new ITranslationUnit[list.size()]);
fDelegate= fIndexer.createTask(tus, NO_TUS, NO_TUS);
}
public IndexerProgress getProgressInformation() {
return fDelegate != null ? fDelegate.getProgressInformation() : null;
}
}

View file

@ -0,0 +1,118 @@
/*******************************************************************************
* Copyright (c) 2007 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.indexer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.cdt.core.dom.IPDOMIndexer;
import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICContainer;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICElementDelta;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.pdom.IndexerProgress;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
public class PDOMResourceDeltaTask implements IPDOMIndexerTask {
private static final String TRUE = String.valueOf(true);
private IPDOMIndexer fIndexer;
private boolean fAllFiles;
private IPDOMIndexerTask fDelegate;
public PDOMResourceDeltaTask(IPDOMIndexer indexer, ICElementDelta delta) throws CoreException {
fIndexer= indexer;
fAllFiles= TRUE.equals(getIndexer().getProperty(IndexerPreferences.KEY_INDEX_ALL_FILES));
List a= new ArrayList();
List c= new ArrayList();
List r= new ArrayList();
processDelta(delta, a, c, r, new NullProgressMonitor());
if (!a.isEmpty() || !c.isEmpty() || !r.isEmpty()) {
ITranslationUnit[] aa= (ITranslationUnit[]) a.toArray(new ITranslationUnit[a.size()]);
ITranslationUnit[] ca= (ITranslationUnit[]) c.toArray(new ITranslationUnit[c.size()]);
ITranslationUnit[] ra= (ITranslationUnit[]) r.toArray(new ITranslationUnit[r.size()]);
fDelegate= indexer.createTask(aa, ca, ra);
}
}
private void processDelta(ICElementDelta delta, List added, List changed, List removed, IProgressMonitor pm) throws CoreException {
int flags = delta.getFlags();
if ((flags & ICElementDelta.F_CHILDREN) != 0) {
ICElementDelta[] children = delta.getAffectedChildren();
for (int i = 0; i < children.length; ++i) {
processDelta(children[i], added, changed, removed, pm);
}
}
ICElement element = delta.getElement();
switch (element.getElementType()) {
case ICElement.C_UNIT:
ITranslationUnit tu = (ITranslationUnit)element;
switch (delta.getKind()) {
case ICElementDelta.CHANGED:
if ((flags & ICElementDelta.F_CONTENT) != 0 &&
(fAllFiles || !CoreModel.isScannerInformationEmpty(tu.getResource()))) {
changed.add(tu);
}
break;
case ICElementDelta.ADDED:
if (!tu.isWorkingCopy() &&
(fAllFiles || !CoreModel.isScannerInformationEmpty(tu.getResource()))) {
added.add(tu);
}
break;
case ICElementDelta.REMOVED:
if (!tu.isWorkingCopy())
removed.add(tu);
break;
}
break;
case ICElement.C_CCONTAINER:
ICContainer folder= (ICContainer) element;
if (delta.getKind() == ICElementDelta.ADDED) {
collectSources(folder, added, pm);
}
break;
}
}
private void collectSources(ICContainer container, Collection sources, IProgressMonitor pm) throws CoreException {
container.accept(new TranslationUnitCollector(sources, fAllFiles, pm));
}
public void run(IProgressMonitor monitor) {
if (fDelegate != null) {
fDelegate.run(monitor);
}
}
public IPDOMIndexer getIndexer() {
return fIndexer;
}
public IndexerProgress getProgressInformation() {
return fDelegate == null ? null : fDelegate.getProgressInformation();
}
public boolean isEmpty() {
return fDelegate == null;
}
}

View file

@ -0,0 +1,314 @@
/*******************************************************************************
* Copyright (c) 2007 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.indexer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
import org.eclipse.cdt.internal.core.index.IWritableIndex;
import org.eclipse.cdt.internal.core.pdom.IndexerProgress;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMASTAdapter;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
/**
* Abstract class to write information from AST
* @since 4.0
*/
abstract public class PDOMWriter {
private static final String TRUE = "true"; //$NON-NLS-1$
protected boolean fShowActivity;
protected boolean fShowProblems;
protected IndexerStatistics fStatistics;
private IndexerProgress fInfo= new IndexerProgress();
public PDOMWriter() {
fShowActivity= checkDebugOption(IPDOMIndexerTask.TRACE_ACTIVITY, TRUE);
fShowProblems= checkDebugOption(IPDOMIndexerTask.TRACE_PROBLEMS, TRUE);
fStatistics= new IndexerStatistics();
}
/**
* Checks whether a given debug option is enabled. See {@link IPDOMIndexerTask}
* for valid values.
* @since 4.0
*/
protected boolean checkDebugOption(String option, String value) {
String trace= Platform.getDebugOption(option);
boolean internallyActivated= Boolean.getBoolean(option);
return internallyActivated || (trace != null && trace.equalsIgnoreCase(value));
}
/**
* Called to check whether a translation unit still needs to be updated.
* @see #addSymbols(IASTTranslationUnit, IWritableIndex, int, IProgressMonitor)
* @since 4.0
*/
protected abstract boolean needToUpdate(IIndexFileLocation location) throws CoreException;
/**
* Called after a file was added to the index.
* @return whether the file was actually requested by the indexer.
* @see #addSymbols(IASTTranslationUnit, IWritableIndex, int, IProgressMonitor)
* @since 4.0
*/
protected abstract boolean postAddToIndex(IIndexFileLocation location, IIndexFile file) throws CoreException;
/**
* Called to resolve an absolute path to an index file location.
* @since 4.0
*/
protected abstract IIndexFileLocation findLocation(String absolutePath);
/**
* Extracts symbols from the given ast and adds them to the index. It will
* make calls to
* {@link #needToUpdate(IIndexFileLocation)},
* {@link #postAddToIndex(IIndexFileLocation, IIndexFile)} and
* {@link #findLocation(String)} to obtain further information.
* @since 4.0
*/
public void addSymbols(IASTTranslationUnit ast, IWritableIndex index, int readlockCount, IProgressMonitor pm) throws InterruptedException, CoreException {
final Map symbolMap= new HashMap();
try {
IIndexFileLocation[] orderedPaths= extractSymbols(ast, symbolMap);
for (int i=0; i<orderedPaths.length; i++) {
if (pm.isCanceled()) {
return;
}
IIndexFileLocation path= orderedPaths[i];
ArrayList[] arrayLists = ((ArrayList[]) symbolMap.get(path));
// resolve the names
long start= System.currentTimeMillis();
ArrayList names= arrayLists[2];
for (int j=0; j<names.size(); j++) {
final IASTName name = ((IASTName[]) names.get(j))[0];
final IBinding binding= name.resolveBinding();
if (binding instanceof IProblemBinding)
reportProblem((IProblemBinding) binding);
else if (name.isReference())
fStatistics.fReferenceCount++;
else
fStatistics.fDeclarationCount++;
}
fStatistics.fResolutionTime += System.currentTimeMillis()-start;
}
boolean isFirstRequest= true;
boolean isFirstAddition= true;
index.acquireWriteLock(readlockCount);
long start= System.currentTimeMillis();
try {
for (int i=0; i<orderedPaths.length; i++) {
if (pm.isCanceled())
return;
IIndexFileLocation path = orderedPaths[i];
if (path != null) {
if (fShowActivity) {
System.out.println("Indexer: adding " + path.getURI()); //$NON-NLS-1$
}
IIndexFile file= addToIndex(index, path, symbolMap);
boolean wasRequested= postAddToIndex(path, file);
synchronized(fInfo) {
if (wasRequested) {
if (isFirstRequest)
isFirstRequest= false;
else
fInfo.fTotalSourcesEstimate--;
}
if (isFirstAddition)
isFirstAddition= false;
else
fInfo.fCompletedHeaders++;
}
}
}
} finally {
index.releaseWriteLock(readlockCount);
}
fStatistics.fAddToIndexTime+= System.currentTimeMillis()-start;
}
finally {
synchronized(fInfo) {
fInfo.fCompletedSources++;
}
}
}
private IIndexFileLocation[] extractSymbols(IASTTranslationUnit ast, final Map symbolMap) throws CoreException {
LinkedHashSet/*<IIndexFileLocation>*/ orderedIncludes= new LinkedHashSet/*<IIndexFileLocation>*/();
ArrayList/*<IIndexFileLocation>*/ stack= new ArrayList/*<IIndexFileLocation>*/();
final IIndexFileLocation astLocation = findLocation(ast.getFilePath());
IIndexFileLocation currentPath = astLocation;
IASTPreprocessorIncludeStatement[] includes = ast.getIncludeDirectives();
for (int i= 0; i < includes.length; i++) {
IASTPreprocessorIncludeStatement include = includes[i];
IASTFileLocation sourceLoc = include.getFileLocation();
IIndexFileLocation newPath= sourceLoc != null ? findLocation(sourceLoc.getFileName()) : astLocation; // command-line includes
while (!stack.isEmpty() && !currentPath.equals(newPath)) {
if (needToUpdate(currentPath)) {
prepareInMap(symbolMap, currentPath);
orderedIncludes.add(currentPath);
}
currentPath= (IIndexFileLocation) stack.remove(stack.size()-1);
}
if (needToUpdate(newPath)) {
prepareInMap(symbolMap, newPath);
addToMap(symbolMap, 0, newPath, include);
}
stack.add(currentPath);
currentPath= findLocation(include.getPath());
}
stack.add(currentPath);
while (!stack.isEmpty()) {
currentPath= (IIndexFileLocation) stack.remove(stack.size()-1);
if (needToUpdate(currentPath)) {
prepareInMap(symbolMap, currentPath);
orderedIncludes.add(currentPath);
}
}
// macros
IASTPreprocessorMacroDefinition[] macros = ast.getMacroDefinitions();
for (int i2 = 0; i2 < macros.length; ++i2) {
IASTPreprocessorMacroDefinition macro = macros[i2];
IASTFileLocation sourceLoc = macro.getFileLocation();
if (sourceLoc != null) { // skip built-ins and command line macros
IIndexFileLocation path2 = findLocation(sourceLoc.getFileName());
addToMap(symbolMap, 1, path2, macro);
}
}
// names
ast.accept(new IndexerASTVisitor() {
public void visit(IASTName name, IASTName caller) {
// assign a location to anonymous types.
name= PDOMASTAdapter.getAdapterIfAnonymous(name);
IASTFileLocation nameLoc = name.getFileLocation();
if (nameLoc != null) {
IIndexFileLocation location = findLocation(nameLoc.getFileName());
addToMap(symbolMap, 2, location, new IASTName[]{name, caller});
}
}
});
return (IIndexFileLocation[]) orderedIncludes.toArray(new IIndexFileLocation[orderedIncludes.size()]);
}
private void reportProblem(IProblemBinding problem) {
fStatistics.fProblemBindingCount++;
if (fShowProblems) {
String msg= "Indexer problem at "+ problem.getFileName() + ": " + problem.getLineNumber(); //$NON-NLS-1$//$NON-NLS-2$
String pmsg= problem.getMessage();
if (pmsg != null && pmsg.length() > 0)
msg+= "; " + problem.getMessage(); //$NON-NLS-1$
System.out.println(msg);
}
}
private void addToMap(Map map, int idx, IIndexFileLocation location, Object thing) {
List[] lists= (List[]) map.get(location);
if (lists != null)
lists[idx].add(thing);
}
private boolean prepareInMap(Map map, IIndexFileLocation location) {
if (map.get(location) == null) {
Object lists= new ArrayList[]{new ArrayList(), new ArrayList(), new ArrayList()};
map.put(location, lists);
}
return false;
}
private IIndexFragmentFile addToIndex(IWritableIndex index, IIndexFileLocation location, Map symbolMap) throws CoreException {
IIndexFragmentFile file= (IIndexFragmentFile) index.getFile(location);
if (file != null) {
index.clearFile(file);
} else {
file= index.addFile(location);
}
file.setTimestamp(EFS.getStore(location.getURI()).fetchInfo().getLastModified());
ArrayList[] lists= (ArrayList[]) symbolMap.get(location);
if (lists != null) {
ArrayList list= lists[0];
IASTPreprocessorIncludeStatement[] includes= (IASTPreprocessorIncludeStatement[]) list.toArray(new IASTPreprocessorIncludeStatement[list.size()]);
list= lists[1];
IASTPreprocessorMacroDefinition[] macros= (IASTPreprocessorMacroDefinition[]) list.toArray(new IASTPreprocessorMacroDefinition[list.size()]);
list= lists[2];
IASTName[][] names= (IASTName[][]) list.toArray(new IASTName[list.size()][]);
IIndexFileLocation[] includeLocations = new IIndexFileLocation[includes.length];
for(int i=0; i<includes.length; i++) {
includeLocations[i] = findLocation(includes[i].getPath());
}
index.setFileContent(file, includes, includeLocations, macros, names);
}
return file;
}
/**
* Makes a copy of the current progress information and returns it.
* @since 4.0
*/
protected IndexerProgress getProgressInformation() {
synchronized (fInfo) {
return new IndexerProgress(fInfo);
}
}
/**
* Updates current progress information with the provided delta.
* @since 4.0
*/
protected void updateInfo(int completedSources, int completedHeaders, int totalEstimate) {
synchronized(fInfo) {
fInfo.fCompletedHeaders+= completedHeaders;
fInfo.fCompletedSources+= completedSources;
fInfo.fTotalSourcesEstimate+= totalEstimate;
}
}
/**
* Updates the current monitor detail.
* @since 4.0
*/
protected void setMonitorDetail(String detail) {
synchronized(fInfo) {
fInfo.fMonitorDetail= detail;
}
}
}

View file

@ -0,0 +1,56 @@
/*******************************************************************************
* Copyright (c) 2007 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.indexer;
import java.util.Collection;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICElementVisitor;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
final class TranslationUnitCollector implements ICElementVisitor {
private final Collection fTUs;
private final boolean fAllFiles;
private final IProgressMonitor fProgressMonitor;
public TranslationUnitCollector(Collection tus, boolean allFiles, IProgressMonitor pm) {
fTUs = tus;
fAllFiles = allFiles;
fProgressMonitor= pm;
}
public boolean visit(ICElement element) throws CoreException {
if (fProgressMonitor.isCanceled()) {
return false;
}
switch (element.getElementType()) {
case ICElement.C_UNIT:
ITranslationUnit tu = (ITranslationUnit)element;
if (tu.isSourceUnit()) {
if (fAllFiles || !CoreModel.isScannerInformationEmpty(tu.getResource())) {
fTUs.add(tu);
}
}
else if (tu.isHeaderUnit()) {
fTUs.add(tu);
}
return false;
case ICElement.C_CCONTAINER:
case ICElement.C_PROJECT:
return true;
}
return false;
}
}

View file

@ -1,85 +0,0 @@
/*******************************************************************************
* Copyright (c) 2006 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.indexer.fast;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.ICElementDelta;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
class PDOMFastHandleDelta extends PDOMFastIndexerJob {
private List changed = new ArrayList();
private List removed = new ArrayList();
public PDOMFastHandleDelta(PDOMFastIndexer indexer, ICElementDelta delta) throws CoreException {
super(indexer);
processDelta(delta, changed, changed, removed, new NullProgressMonitor());
fTotalSourcesEstimate= changed.size() + removed.size();
}
public void run(IProgressMonitor monitor) {
long start = System.currentTimeMillis();
try {
setupIndexAndReaderFactory();
index.acquireReadLock();
try {
registerTUsInReaderFactory(changed);
Iterator i= removed.iterator();
while (i.hasNext()) {
if (monitor.isCanceled())
return;
ITranslationUnit tu = (ITranslationUnit)i.next();
removeTU(index, tu, 1);
if (tu.isSourceUnit()) {
fCompletedSources++;
}
else {
fTotalSourcesEstimate--;
fCompletedHeaders++;
}
}
// separate headers
List headers= new ArrayList();
List sources= changed;
for (Iterator iter = changed.iterator(); iter.hasNext();) {
ITranslationUnit tu = (ITranslationUnit) iter.next();
if (!tu.isSourceUnit()) {
headers.add(tu);
iter.remove();
}
}
parseTUs(sources, headers, monitor);
if (monitor.isCanceled()) {
return;
}
}
finally {
index.releaseReadLock();
}
} catch (CoreException e) {
CCorePlugin.log(e);
} catch (InterruptedException e) {
}
traceEnd(start);
}
}

View file

@ -13,37 +13,25 @@
package org.eclipse.cdt.internal.core.pdom.indexer.fast;
import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.model.ICElementDelta;
import org.eclipse.cdt.internal.core.CCoreInternals;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.pdom.indexer.AbstractPDOMIndexer;
import org.eclipse.core.runtime.CoreException;
/**
* @author Doug Schaefer
*
*/
public class PDOMFastIndexer extends AbstractPDOMIndexer {
// Must match extension id
public static final String ID = IPDOMManager.ID_FAST_INDEXER;
public PDOMFastIndexer() {
}
public void handleDelta(ICElementDelta delta) throws CoreException {
PDOMFastHandleDelta fhd= new PDOMFastHandleDelta(this, delta);
if (fhd.estimateRemainingSources() > 0) {
CCoreInternals.getPDOMManager().enqueue(fhd);
}
}
public void reindex() throws CoreException {
CCoreInternals.getPDOMManager().enqueue(new PDOMFastReindex(this));
}
public String getID() {
return ID;
}
public IPDOMIndexerTask createTask(ITranslationUnit[] added,
ITranslationUnit[] changed, ITranslationUnit[] removed) {
return new PDOMFastIndexerTask(this, added, changed, removed);
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006 QNX Software Systems and others.
* Copyright (c) 2006, 2007 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -8,18 +8,19 @@
* Contributors:
* QNX - Initial API and implementation
* Markus Schorn (Wind River Systems)
* IBM Corporation
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.indexer.fast;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
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.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexFileLocation;
@ -38,96 +39,134 @@ import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
/**
* @author Doug Schaefer
*
*/
abstract class PDOMFastIndexerJob extends PDOMIndexerTask {
class PDOMFastIndexerTask extends PDOMIndexerTask {
private List fChanged = new ArrayList();
private List fRemoved = new ArrayList();
private IWritableIndex index;
private IndexBasedCodeReaderFactory fCodeReaderFactory;
private Map fIflCache;
protected final PDOMFastIndexer indexer;
protected IWritableIndex index;
protected IndexBasedCodeReaderFactory codeReaderFactory;
private Map/*<String,IIndexFileLocation>*/ iflCache;
public PDOMFastIndexerTask(PDOMFastIndexer indexer, ITranslationUnit[] added,
ITranslationUnit[] changed, ITranslationUnit[] removed) {
super(indexer);
fChanged.addAll(Arrays.asList(added));
fChanged.addAll(Arrays.asList(changed));
fRemoved.addAll(Arrays.asList(removed));
updateInfo(0, 0, fChanged.size() + fRemoved.size());
}
public PDOMFastIndexerJob(PDOMFastIndexer indexer) throws CoreException {
this.indexer = indexer;
public void run(IProgressMonitor monitor) {
long start = System.currentTimeMillis();
try {
setupIndexAndReaderFactory();
index.acquireReadLock();
try {
registerTUsInReaderFactory(fChanged);
Iterator i= fRemoved.iterator();
while (i.hasNext()) {
if (monitor.isCanceled())
return;
ITranslationUnit tu = (ITranslationUnit)i.next();
removeTU(index, tu, 1);
if (tu.isSourceUnit()) {
updateInfo(1, 0, 0);
}
else {
updateInfo(0, 1, -1);
}
}
// separate headers
List headers= new ArrayList();
List sources= fChanged;
for (Iterator iter = fChanged.iterator(); iter.hasNext();) {
ITranslationUnit tu = (ITranslationUnit) iter.next();
if (!tu.isSourceUnit()) {
headers.add(tu);
iter.remove();
}
}
parseTUs(index, 1, sources, headers, monitor);
if (monitor.isCanceled()) {
return;
}
}
finally {
index.releaseReadLock();
}
} catch (CoreException e) {
CCorePlugin.log(e);
} catch (InterruptedException e) {
}
traceEnd(start);
}
protected void setupIndexAndReaderFactory() throws CoreException {
this.index= ((IWritableIndexManager) CCorePlugin.getIndexManager()).getWritableIndex(indexer.getProject());
this.iflCache = new HashMap/*<String,IIndexFileLocation>*/();
this.codeReaderFactory = new IndexBasedCodeReaderFactory(index, iflCache);
private void setupIndexAndReaderFactory() throws CoreException {
this.index= ((IWritableIndexManager) CCorePlugin.getIndexManager()).getWritableIndex(getProject());
this.fIflCache = new HashMap/*<String,IIndexFileLocation>*/();
this.fCodeReaderFactory = new IndexBasedCodeReaderFactory(index, fIflCache);
}
private void registerTUsInReaderFactory(Collection files) throws CoreException {
for (Iterator iter = files.iterator(); iter.hasNext();) {
ITranslationUnit tu = (ITranslationUnit) iter.next();
IIndexFileLocation location = getIndexFileLocation(tu);
FileInfo info= fCodeReaderFactory.createFileInfo(location);
info.setRequested(true);
}
}
protected IIndexFileLocation findLocation(String absolutePath) {
IIndexFileLocation result = (IIndexFileLocation) iflCache.get(absolutePath);
IIndexFileLocation result = (IIndexFileLocation) fIflCache.get(absolutePath);
if(result==null) {
result = IndexLocationFactory.getIFLExpensive(absolutePath);
iflCache.put(absolutePath, result);
fIflCache.put(absolutePath, result);
}
return result;
}
protected void registerTUsInReaderFactory(Collection files) throws CoreException {
for (Iterator iter = files.iterator(); iter.hasNext();) {
ITranslationUnit tu = (ITranslationUnit) iter.next();
IIndexFileLocation location = getIndexFileLocation(tu);
FileInfo info= codeReaderFactory.createFileInfo(location);
info.setRequested(true);
}
}
public IPDOMIndexer getIndexer() {
return indexer;
}
protected void doParseTU(ITranslationUnit tu, IProgressMonitor pm) throws CoreException, InterruptedException {
protected IASTTranslationUnit createAST(ITranslationUnit tu, IProgressMonitor pm) throws CoreException,
InterruptedException {
IPath path = tu.getLocation();
if (path == null) {
return;
return null;
}
ILanguage language = tu.getLanguage();
if (language == null)
return;
return null;
// skip if no scanner info
IScannerInfo scanner= tu.getScannerInfo(getIndexAllFiles());
if (scanner == null) {
return;
return null;
}
CodeReader codeReader = tu.getCodeReader();
if (codeReader == null) {
return;
return null;
}
// get the AST in a "Fast" way
IASTTranslationUnit ast= language.getASTTranslationUnit(codeReader, scanner, codeReaderFactory, index, ParserUtil.getParserLogService());
IASTTranslationUnit ast= language.getASTTranslationUnit(codeReader, scanner, fCodeReaderFactory, index, ParserUtil.getParserLogService());
if (pm.isCanceled()) {
return;
return null;
}
// Clear the macros
codeReaderFactory.clearMacroAttachements();
fCodeReaderFactory.clearMacroAttachements();
// Add the new symbols
addSymbols(ast, pm);
}
protected IWritableIndex getIndex() {
return index;
}
protected int getReadlockCount() {
return 1;
return ast;
}
protected boolean needToUpdate(IIndexFileLocation location) throws CoreException {
// file is requested or is not yet indexed.
FileInfo info= codeReaderFactory.createFileInfo(location);
FileInfo info= fCodeReaderFactory.createFileInfo(location);
return info.isRequested() || info.fFile == null;
}
protected boolean postAddToIndex(IIndexFileLocation path, IIndexFile file) throws CoreException {
FileInfo info= codeReaderFactory.createFileInfo(path);
protected boolean postAddToIndex(IIndexFileLocation path, IIndexFile file)
throws CoreException {
FileInfo info= fCodeReaderFactory.createFileInfo(path);
info.fFile= file;
if (info.isRequested()) {
info.setRequested(false);

View file

@ -1,68 +0,0 @@
/*******************************************************************************
* Copyright (c) 2006 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.indexer.fast;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
/**
* @author Doug Schaefer
*
*/
class PDOMFastReindex extends PDOMFastIndexerJob {
public PDOMFastReindex(PDOMFastIndexer indexer) throws CoreException {
super(indexer);
}
public void run(final IProgressMonitor monitor) {
long start = System.currentTimeMillis();
try {
boolean allFiles= getIndexAllFiles();
List sources= new ArrayList();
List headers= new ArrayList();
collectSources(indexer.getProject(), sources,
allFiles ? headers : null, allFiles, monitor);
if (monitor.isCanceled()) {
return;
}
fTotalSourcesEstimate= sources.size() + headers.size();
setupIndexAndReaderFactory();
clearIndex(index);
if (fTotalSourcesEstimate==0 || monitor.isCanceled()) {
return;
}
index.acquireReadLock();
try {
registerTUsInReaderFactory(sources);
registerTUsInReaderFactory(headers);
parseTUs(sources, headers, monitor);
}
finally {
index.releaseReadLock();
}
} catch (CoreException e) {
CCorePlugin.log(e);
} catch (InterruptedException e) {
}
traceEnd(start);
}
}

View file

@ -1,88 +0,0 @@
/*******************************************************************************
* Copyright (c) 2006 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.indexer.full;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.ICElementDelta;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
/**
* @author Doug Schaefer
*
*/
class PDOMFullHandleDelta extends PDOMFullIndexerJob {
private List changed = new ArrayList();
private List removed = new ArrayList();
public PDOMFullHandleDelta(PDOMFullIndexer indexer, ICElementDelta delta) throws CoreException {
super(indexer);
processDelta(delta, changed, changed, removed, new NullProgressMonitor());
fTotalSourcesEstimate= changed.size() + removed.size();
}
public void run(IProgressMonitor monitor) {
long start = System.currentTimeMillis();
try {
setupIndexAndReaderFactory();
// separate headers
List headers= new ArrayList();
List sources= changed;
for (Iterator iter = changed.iterator(); iter.hasNext();) {
ITranslationUnit tu = (ITranslationUnit) iter.next();
if (!tu.isSourceUnit()) {
headers.add(tu);
iter.remove();
}
}
registerTUsInReaderFactory(sources);
registerTUsInReaderFactory(headers);
Iterator i= removed.iterator();
while (i.hasNext()) {
if (monitor.isCanceled())
return;
ITranslationUnit tu = (ITranslationUnit)i.next();
removeTU(index, tu, 0);
if (tu.isSourceUnit()) {
fCompletedSources++;
}
else {
fTotalSourcesEstimate--;
fCompletedHeaders++;
}
}
index.acquireReadLock();
try {
parseTUs(sources, headers, monitor);
}
finally {
index.releaseReadLock();
}
} catch (CoreException e) {
CCorePlugin.log(e);
} catch (InterruptedException e) {
}
traceEnd(start);
}
}

View file

@ -12,11 +12,10 @@
package org.eclipse.cdt.internal.core.pdom.indexer.full;
import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.model.ICElementDelta;
import org.eclipse.cdt.internal.core.CCoreInternals;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.pdom.indexer.AbstractPDOMIndexer;
import org.eclipse.core.runtime.CoreException;
/**
* The Full indexer does full parsing in order to gather index information.
@ -28,18 +27,12 @@ import org.eclipse.core.runtime.CoreException;
public class PDOMFullIndexer extends AbstractPDOMIndexer {
public static final String ID = IPDOMManager.ID_FULL_INDEXER;
public void handleDelta(ICElementDelta delta) throws CoreException {
PDOMFullHandleDelta task = new PDOMFullHandleDelta(this, delta);
if (task.estimateRemainingSources() > 0) {
CCoreInternals.getPDOMManager().enqueue(task);
}
}
public void reindex() throws CoreException {
CCoreInternals.getPDOMManager().enqueue(new PDOMFullReindex(this));
}
public String getID() {
return ID;
}
public IPDOMIndexerTask createTask(ITranslationUnit[] added,
ITranslationUnit[] changed, ITranslationUnit[] removed) {
return new PDOMFullIndexerTask(this, added, changed, removed);
}
}

View file

@ -1,114 +0,0 @@
/*******************************************************************************
* Copyright (c) 2006 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.indexer.full;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMIndexer;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.index.IndexLocationFactory;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.index.IWritableIndex;
import org.eclipse.cdt.internal.core.index.IWritableIndexManager;
import org.eclipse.cdt.internal.core.pdom.indexer.PDOMIndexerTask;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
/**
* @author Doug Schaefer
*
*/
abstract class PDOMFullIndexerJob extends PDOMIndexerTask {
final static Object REQUIRED= new Object();
final static Object MISSING = new Object();
final static Object SKIP= new Object();
protected final PDOMFullIndexer indexer;
protected IWritableIndex index= null;
private Map/*<IIndexFileLocation, Object>*/ filePathsToParse= new HashMap/*<IIndexFileLocation, Object>*/();
private Map/*<String, IIndexFileLocation>*/ iflCache = new HashMap/*<String, IIndexFileLocation>*/();
public PDOMFullIndexerJob(PDOMFullIndexer indexer) throws CoreException {
this.indexer = indexer;
}
public IPDOMIndexer getIndexer() {
return indexer;
}
protected void setupIndexAndReaderFactory() throws CoreException {
this.index = ((IWritableIndexManager) CCorePlugin.getIndexManager()).getWritableIndex(indexer.getProject());
}
protected void registerTUsInReaderFactory(Collection/*<ITranslationUnit>*/ sources) throws CoreException {
filePathsToParse= new HashMap/*<IIndexFileLocation, Object>*/();
for (Iterator iter = sources.iterator(); iter.hasNext();) {
ITranslationUnit tu = (ITranslationUnit) iter.next();
filePathsToParse.put(getIndexFileLocation(tu), REQUIRED);
}
}
protected IIndexFileLocation findLocation(String absolutePath) {
IIndexFileLocation result = (IIndexFileLocation) iflCache.get(absolutePath);
if(result==null) {
result = IndexLocationFactory.getIFLExpensive(absolutePath);
iflCache.put(absolutePath, result);
}
return result;
}
protected void doParseTU(ITranslationUnit tu, IProgressMonitor pm) throws CoreException, InterruptedException {
IPath path = tu.getLocation();
if (path == null) {
return;
}
int options= 0;
if (!getIndexAllFiles()) {
options |= ITranslationUnit.AST_SKIP_IF_NO_BUILD_INFO;
}
IASTTranslationUnit ast= tu.getAST(null, options);
if (ast != null)
addSymbols(ast, pm);
}
protected IWritableIndex getIndex() {
return index;
}
protected int getReadlockCount() {
return 1;
}
protected boolean needToUpdate(IIndexFileLocation location) throws CoreException {
Object required= filePathsToParse.get(location);
if (required == null) {
required= MISSING;
filePathsToParse.put(location, required);
}
return required != SKIP;
}
protected boolean postAddToIndex(IIndexFileLocation location, IIndexFile file) throws CoreException {
Object required= filePathsToParse.get(location);
filePathsToParse.put(location, SKIP);
return required == REQUIRED;
}
}

View file

@ -0,0 +1,157 @@
/*******************************************************************************
* Copyright (c) 2006, 2007 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.indexer.full;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.index.IndexLocationFactory;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.index.IWritableIndex;
import org.eclipse.cdt.internal.core.index.IWritableIndexManager;
import org.eclipse.cdt.internal.core.pdom.indexer.PDOMIndexerTask;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
/**
* @author Doug Schaefer
*
*/
class PDOMFullIndexerTask extends PDOMIndexerTask {
private final static Object REQUIRED= new Object();
private final static Object MISSING = new Object();
private final static Object SKIP= new Object();
private List fChanged = new ArrayList();
private List fRemoved = new ArrayList();
private IWritableIndex fIndex = null;
private Map filePathsToParse = new HashMap/*<IIndexFileLocation, Object>*/();
private Map fIflCache = new HashMap/*<String, IIndexFileLocation>*/();
public PDOMFullIndexerTask(PDOMFullIndexer indexer, ITranslationUnit[] added,
ITranslationUnit[] changed, ITranslationUnit[] removed) {
super(indexer);
fChanged.addAll(Arrays.asList(added));
fChanged.addAll(Arrays.asList(changed));
fRemoved.addAll(Arrays.asList(removed));
updateInfo(0, 0, fChanged.size() + fRemoved.size());
}
public void run(IProgressMonitor monitor) {
long start = System.currentTimeMillis();
try {
setupIndex();
// separate headers
List headers= new ArrayList();
List sources= fChanged;
for (Iterator iter = fChanged.iterator(); iter.hasNext();) {
ITranslationUnit tu = (ITranslationUnit) iter.next();
if (!tu.isSourceUnit()) {
headers.add(tu);
iter.remove();
}
}
registerTUsInReaderFactory(sources);
registerTUsInReaderFactory(headers);
Iterator i= fRemoved.iterator();
while (i.hasNext()) {
if (monitor.isCanceled())
return;
ITranslationUnit tu = (ITranslationUnit)i.next();
removeTU(fIndex, tu, 0);
if (tu.isSourceUnit()) {
updateInfo(1, 0, 0);
}
else {
updateInfo(0, 1, -1);
}
}
fIndex.acquireReadLock();
try {
parseTUs(fIndex, 1, sources, headers, monitor);
}
finally {
fIndex.releaseReadLock();
}
} catch (CoreException e) {
CCorePlugin.log(e);
} catch (InterruptedException e) {
}
traceEnd(start);
}
private void setupIndex() throws CoreException {
fIndex = ((IWritableIndexManager) CCorePlugin.getIndexManager()).getWritableIndex(getProject());
}
private void registerTUsInReaderFactory(Collection/*<ITranslationUnit>*/ sources)
throws CoreException {
filePathsToParse= new HashMap/*<IIndexFileLocation, Object>*/();
for (Iterator iter = sources.iterator(); iter.hasNext();) {
ITranslationUnit tu = (ITranslationUnit) iter.next();
filePathsToParse.put(getIndexFileLocation(tu), REQUIRED);
}
}
protected IIndexFileLocation findLocation(String absolutePath) {
IIndexFileLocation result = (IIndexFileLocation) fIflCache.get(absolutePath);
if(result==null) {
result = IndexLocationFactory.getIFLExpensive(absolutePath);
fIflCache.put(absolutePath, result);
}
return result;
}
protected IASTTranslationUnit createAST(ITranslationUnit tu, IProgressMonitor pm) throws CoreException,
InterruptedException {
IPath path = tu.getLocation();
if (path == null) {
return null;
}
int options= 0;
if (!getIndexAllFiles()) {
options |= ITranslationUnit.AST_SKIP_IF_NO_BUILD_INFO;
}
return tu.getAST(null, options);
}
protected boolean needToUpdate(IIndexFileLocation location) throws CoreException {
Object required= filePathsToParse.get(location);
if (required == null) {
required= MISSING;
filePathsToParse.put(location, required);
}
return required != SKIP;
}
protected boolean postAddToIndex(IIndexFileLocation location, IIndexFile file)
throws CoreException {
Object required= filePathsToParse.get(location);
filePathsToParse.put(location, SKIP);
return required == REQUIRED;
}
}

View file

@ -1,66 +0,0 @@
/*******************************************************************************
* Copyright (c) 2006 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.indexer.full;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Status;
/**
* @author Doug Schaefer
*
*/
class PDOMFullReindex extends PDOMFullIndexerJob {
public PDOMFullReindex(PDOMFullIndexer indexer) throws CoreException {
super(indexer);
}
public void run(final IProgressMonitor monitor) {
long start = System.currentTimeMillis();
try {
boolean allFiles= getIndexAllFiles();
List/*<ITranslationUnit>*/ sources= new ArrayList/*<ITranslationUnit>*/();
List/*<ITranslationUnit>*/ headers= new ArrayList/*<ITranslationUnit>*/();
collectSources(indexer.getProject(), sources,
allFiles ? headers : null, allFiles, monitor);
fTotalSourcesEstimate= sources.size() + headers.size();
setupIndexAndReaderFactory();
clearIndex(index);
if (fTotalSourcesEstimate == 0 || monitor.isCanceled()) {
return;
}
registerTUsInReaderFactory(sources);
index.acquireReadLock();
try {
parseTUs(sources, headers, monitor);
}
finally {
index.releaseReadLock();
}
} catch (CoreException e) {
if (e.getStatus() != Status.CANCEL_STATUS)
CCorePlugin.log(e);
} catch (InterruptedException e) {
}
traceEnd(start);
}
}

View file

@ -12,17 +12,10 @@
package org.eclipse.cdt.internal.core.pdom.indexer.nulli;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMIndexer;
import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.model.ICElementDelta;
import org.eclipse.cdt.internal.core.CCoreInternals;
import org.eclipse.cdt.internal.core.index.IWritableIndex;
import org.eclipse.cdt.internal.core.index.IWritableIndexManager;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.pdom.indexer.AbstractPDOMIndexer;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
/**
* @author Doug Schaefer
@ -37,54 +30,12 @@ public class PDOMNullIndexer extends AbstractPDOMIndexer {
fProperties.clear(); // don't accept any properties
}
public void handleDelta(ICElementDelta delta) {
}
private class PDOMNullReindex implements IPDOMIndexerTask {
public IPDOMIndexer getIndexer() {
return PDOMNullIndexer.this;
}
public void run(IProgressMonitor monitor) {
try {
IWritableIndex index= ((IWritableIndexManager) CCorePlugin.getIndexManager()).getWritableIndex(project);
index.acquireWriteLock(0);
try {
index.clear();
}
finally {
index.releaseWriteLock(0);
}
}
catch (InterruptedException e) {
}
catch (CoreException e) {
CCorePlugin.log(e);
}
}
public String getMonitorMessageDetail() {
return null;
}
public int estimateRemainingSources() {
return 0;
}
public int getCompletedHeadersCount() {
return 0;
}
public int getCompletedSourcesCount() {
return 0;
}
}
public void reindex() throws CoreException {
CCoreInternals.getPDOMManager().enqueue(new PDOMNullReindex());
}
public String getID() {
return ID;
}
public IPDOMIndexerTask createTask(ITranslationUnit[] added,
ITranslationUnit[] changed, ITranslationUnit[] removed) {
return null;
}
}

View file

@ -41,7 +41,6 @@ import org.eclipse.cdt.internal.core.CConfigBasedDescriptorManager;
import org.eclipse.cdt.internal.core.CContentTypes;
import org.eclipse.cdt.internal.core.CDTLogWriter;
import org.eclipse.cdt.internal.core.CdtVarPathEntryVariableManager;
import org.eclipse.cdt.internal.core.PathEntryVariableManager;
import org.eclipse.cdt.internal.core.PositionTrackerManager;
import org.eclipse.cdt.internal.core.cdtvariables.CdtVariableManager;
import org.eclipse.cdt.internal.core.envvar.EnvironmentVariableManager;