blob: 4124789fca2edca419a05e5fa9bac8f162cfbda7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2009 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
* IBM Corporation
*******************************************************************************/
package org.eclipse.cdt.internal.core.indexer;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.internal.core.index.IWritableIndex;
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
import org.eclipse.cdt.internal.core.pdom.IndexerProgress;
import org.eclipse.cdt.internal.core.pdom.PDOMWriter;
import org.eclipse.cdt.internal.core.pdom.WritablePDOM;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
/**
* The base class for standalone index population tools.
*
* <p>
* <strong>EXPERIMENTAL</strong>. This class or interface has been added as
* part of a work in progress. There is no guarantee that this API will work or
* that it will remain the same. Please do not use this API without consulting
* with the CDT team.
*
* This class is not thread safe.
* </p>
*
* @since 4.0
*/
public abstract class StandaloneIndexer {
/**
* Parser should not skip any references.
*/
public static final int SKIP_NO_REFERENCES = PDOMWriter.SKIP_NO_REFERENCES;
/**
* Parser to skip all references.
*/
public static final int SKIP_ALL_REFERENCES = PDOMWriter.SKIP_ALL_REFERENCES;
/**
* Parser to skip type references.
*/
public static final int SKIP_TYPE_REFERENCES = PDOMWriter.SKIP_TYPE_REFERENCES;
/**
* Constant for indicating to update all translation units.
*/
public final static int UPDATE_ALL= 0x1;
/**
* Constant for indicating to update translation units if their timestamp
* has changed.
*/
public final static int UPDATE_CHECK_TIMESTAMPS= 0x2;
/**
* Empty list.
*/
protected static final List<String> NO_TUS = Collections.emptyList();
/**
* The IWritableIndex that stores all bindings and names.
*/
protected IWritableIndex fIndex;
/**
* A flag that indicates if all files (sources without config, headers not included)
* should be parsed.
*/
protected boolean fIndexAllFiles;
/**
* Collection of valid file extensions for C/C++ source.
*/
protected Set<String> fValidSourceUnitNames;
/**
* The IScannerInfo that provides include paths and defined symbols.
* Either a single scanner info or a IStandaloneScannerInfoProvider must
* be provided, but not both. If a single IScannerInfo object is provided
* it will always be used. Otherwise the provider will be used.
*/
@Deprecated
protected IScannerInfo fScanner;
/**
* Creates IScannerInfo objects from file paths, allows there
* to be separate scanner infos for specific files and folders.
*/
protected IStandaloneScannerInfoProvider fScannerInfoProvider;
/**
* The ILanguageMapper that determines the ILanguage for a file.
*/
protected ILanguageMapper fMapper;
/**
* The logger during parsing.
*/
protected IParserLogService fLog;
/**
* A flag that indicates if all activities during indexing should be shown.
*/
protected boolean fShowActivity;
/**
* A flag that indicates if any problems encountered during indexing.
* should be shown.
*/
protected boolean fShowProblems;
/**
* A flag that indicates if statistics should be gathered during indexing.
*/
protected boolean fTraceStatistics;
/**
* The type of references the parser should skip.
*/
protected int fSkipReferences = SKIP_NO_REFERENCES;
/**
* The exclusion filter that skips over files that should not be indexed.
*/
protected FilenameFilter fExclusionFilter;
/**
* Files to parse up front.
*/
protected String[] fFilesToParseUpFront = new String[0];
protected int fUpdateOptions = UPDATE_ALL;
private IndexerProgress fProgress = null;
private volatile StandaloneIndexerTask fDelegate;
private static FilenameFilter DEFAULT_FILTER = new FilenameFilter() {
public boolean accept(File dir, String name) {
return true;
}
};
protected FileEncodingRegistry fFileEncodingRegistry;
/**
* @deprecated Its better to provide a scanner info provider instead.
*/
@Deprecated
public StandaloneIndexer(IWritableIndex index, boolean indexAllFiles,
ILanguageMapper mapper, IParserLogService log, IScannerInfo scanner, FileEncodingRegistry fileEncodingRegistry) {
fIndex = index;
fIndexAllFiles = indexAllFiles;
fMapper = mapper;
fLog = log;
fScanner = scanner;
fScannerInfoProvider = null;
fFileEncodingRegistry = fileEncodingRegistry;
setupASTFilePathResolver();
}
public StandaloneIndexer(IWritableIndex index, boolean indexAllFiles,
ILanguageMapper mapper, IParserLogService log, IStandaloneScannerInfoProvider scannerProvider, FileEncodingRegistry fileEncodingRegistry) {
fIndex = index;
fIndexAllFiles = indexAllFiles;
fMapper = mapper;
fLog = log;
fScanner = null;
fScannerInfoProvider = scannerProvider;
fFileEncodingRegistry = fileEncodingRegistry;
setupASTFilePathResolver();
}
private void setupASTFilePathResolver() {
IWritableIndexFragment fragment = getIndex().getWritableFragment();
if(fragment instanceof WritablePDOM) {
WritablePDOM pdom = (WritablePDOM)fragment;
pdom.setASTFilePathResolver(new StandaloneIndexerInputAdapter(this));
}
}
public void setScannerInfoProvider(IStandaloneScannerInfoProvider provider) {
fScannerInfoProvider = provider;
fScanner = null;
}
/**
* Returns the index.
* @return the IWritable index the indexer is writing to
*/
public IWritableIndex getIndex() {
return fIndex;
}
/**
* Returns true if all files (sources without config, headers not included)
* should be parsed. Otherwise, this method returns false.
*/
public boolean getIndexAllFiles() {
return fIndexAllFiles;
}
/**
* If true then all files will be indexed.
*/
public void setIndexAllFiles(boolean indexAllFiles) {
fIndexAllFiles = indexAllFiles;
}
/**
* Returns the collection of valid file extensions for C/C++ source.
*/
public Set<String> getValidSourceUnitNames() {
return fValidSourceUnitNames;
}
/**
* Sets the collection of valid file extensions for C/C++ source.
*/
public void setValidSourceUnitNames(Set<String> validSourceUnitNames) {
fValidSourceUnitNames = validSourceUnitNames;
}
/**
* Returns the IScannerInfo that provides include paths and defined symbols.
* @deprecated Should probably be using a IStandaloneScannerInfoProvider instead and
* calling getScannerInfo(String).
*/
@Deprecated
public IScannerInfo getScannerInfo() {
return fScanner;
}
/**
* Returns the IScannerInfo for the given path.
* If the current instance was created with an IScannerInfo instead of
* an IScannerInfoProvider then the path will be ignored and
* that IScannerInfo will always be returned.
*/
public IScannerInfo getScannerInfo(String path) {
if(fScanner != null)
return fScanner;
return fScannerInfoProvider.getScannerInformation(path);
}
/**
* Returns the IStandaloneScannerInfoProvider or null if one was not provided.
*/
public IStandaloneScannerInfoProvider getScannerInfoProvider() {
return fScannerInfoProvider;
}
/**
* Returns the ILanguageMapper that determines the ILanguage for a file.
*/
public ILanguageMapper getLanguageMapper() {
return fMapper;
}
public void setLanguageMapper(ILanguageMapper mapper) {
fMapper = mapper;
}
/**
* Returns the logger.
*/
public IParserLogService getParserLog() {
return fLog;
}
/**
* Sets the logger.
*/
public void setParserLog(IParserLogService log) {
fLog = log;
}
/**
* Returns true if indexing activities should be shown.
* Otherwise, this method returns false.
*/
public boolean getShowActivity() {
return fShowActivity;
}
/**
* Tells indexer if indexing activities should be shown.
*/
public void setShowActivity(boolean showActivity) {
fShowActivity = showActivity;
}
/**
* Returns true if problems during indexing should be shown.
* Otherwise, this method returns false.
*/
public boolean getShowProblems() {
return fShowProblems;
}
/**
* Tells indexer if problems during indexing should be shown.
*/
public void setShowProblems(boolean showProblems) {
fShowProblems = showProblems;
}
/**
* Returns true if statistics should be gathered during indexing.
* Otherwise, this method returns false..
*/
public boolean getTraceStatistics() {
return fTraceStatistics;
}
/**
* Tells indexer if statistics should be gathered during indexing.
*/
public void setTraceStatistics(boolean traceStatistics) {
fTraceStatistics = traceStatistics;
}
private IndexerProgress createProgress() {
IndexerProgress progress= new IndexerProgress();
progress.fTimeEstimate= 1000;
return progress;
}
private void clearIndex() throws CoreException, InterruptedException {
IWritableIndex index= getIndex();
// First clear the pdom
index.acquireWriteLock(0);
try {
index.clear();
}
finally {
index.releaseWriteLock(0);
}
}
/**
* Returns the progress information.
*/
public synchronized IndexerProgress getProgressInformation() {
return fDelegate != null ? fDelegate.getProgressInformation() : fProgress;
}
/**
* Returns the update options specified.
*/
public int getUpdateOptions() {
return fUpdateOptions;
}
/**
* Specifies the update options, whether all translation units should be updated or only the ones
* with timestamp changes.
* @param options
*/
public void setUpdateOptions (int options) {
fUpdateOptions = options;
}
/**
* Clears the index and rebuild
* @param tus - directories/files to be added to index
* @param monitor
* @throws IOException
*/
public void rebuild(List<String> tus, IProgressMonitor monitor) throws IOException {
fProgress = createProgress();
try {
clearIndex();
fDelegate= createTask(getFilesAdded(tus), NO_TUS, NO_TUS);
fDelegate.setUpdateFlags(fUpdateOptions);
fDelegate.setParseUpFront();
if (fDelegate != null) {
fDelegate.run(monitor);
}
} catch (CoreException e) {
e.printStackTrace();
} catch (InterruptedException e) {
}
}
/**
* Updates the index with changes.
* @param added - directories/files to be added to the index
* @param changed - files that have been changed
* @param removed - files to be removed from the index
* @param monitor
* @throws IOException
*/
public void handleDelta(List<String> added, List<String> changed, List<String> removed, IProgressMonitor monitor) throws IOException {
fProgress= new IndexerProgress();
fDelegate= createTask(getFilesAdded(added), changed, removed);
if (fDelegate != null) {
try {
fDelegate.setUpdateFlags(fUpdateOptions);
fDelegate.run(monitor);
} catch (InterruptedException e) {
}
}
}
/**
* Returns files that are being added to the index, skipping over files that
* should not be excluded.
* @param tus
* @return
*/
private List<String> getFilesAdded(List<String> tus) {
List<String> added = new ArrayList<String>();
FilenameFilter filter = getExclusionFilter();
if (filter == null) {
filter = DEFAULT_FILTER;
}
Iterator<String> iter = tus.iterator();
while (iter.hasNext()) {
String path = iter.next();
File file = new File(path);
if (file.isDirectory()) {
String[] files = file.list(filter);
for (String file2 : files) {
added.add(file2);
}
}
else {
if (filter.accept(file.getParentFile(), file.getName())) {
added.add(path);
}
}
}
return added;
}
/**
* Creates a delegate standalone indexing task
*/
protected abstract StandaloneIndexerTask createTask(List<String> added, List<String> changed, List<String> removed);
/**
* Return the type of references the parser should skip.
*/
public int getSkipReferences() {
return fSkipReferences;
}
/**
* Sets the type of references the parser should skip.
* @param skipReferences
*/
public void setSkipReferences(int skipReferences) {
fSkipReferences = skipReferences;
}
/**
* Returns an array of files that should be parsed up front.
*/
public String[] getFilesToParseUpFront() {
return fFilesToParseUpFront;
}
/**
* Sets an array of files that should be parsed up front.
* @param filesToParseUpFront
*/
public void setFilesToParseUpFront(String[] filesToParseUpFront) {
fFilesToParseUpFront = filesToParseUpFront;
}
/**
* Returns the exclusion filter for this indexer.
*/
public FilenameFilter getExclusionFilter() {
return fExclusionFilter;
}
/**
* Sets the exclusion filter that tells the indexer to skip over
* files that should not be indexed.
* @param exclusionFilter
*/
public void setExclusionFilter(FilenameFilter exclusionFilter) {
fExclusionFilter = exclusionFilter;
}
public FileEncodingRegistry getFileEncodingRegistry() {
return fFileEncodingRegistry;
}
public void setFileEncodingRegistry(FileEncodingRegistry fileEncodingRegistry) {
fFileEncodingRegistry = fileEncodingRegistry;
}
}