mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-24 09:25:31 +02:00
for bug 169847 - standalone indexer
This commit is contained in:
parent
99726101d7
commit
3abcf010f8
8 changed files with 1610 additions and 0 deletions
|
@ -0,0 +1,38 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 IBM Corporation 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:
|
||||
* IBM - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.core.indexer;
|
||||
|
||||
import org.eclipse.cdt.core.model.ILanguage;
|
||||
|
||||
/**
|
||||
* This mapper can be used for determining the ILanguage for a particular file.
|
||||
*
|
||||
* A mapper is needed for standalone indexing when the ILanguage for a file is unknown.
|
||||
*
|
||||
* <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.
|
||||
* </p>
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public interface ILanguageMapper {
|
||||
|
||||
/**
|
||||
* Returns the language of a file.
|
||||
* @param file - path of the file
|
||||
* @return the ILanguage of the file
|
||||
*/
|
||||
ILanguage getLanguage(String file);
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*******************************************************************************
|
||||
* 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)
|
||||
* IBM Corporation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.core.indexer;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.index.IIndexLocationConverter;
|
||||
import org.eclipse.cdt.core.parser.IParserLogService;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexFragment;
|
||||
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
|
||||
import org.eclipse.cdt.internal.core.index.WritableCIndex;
|
||||
import org.eclipse.cdt.internal.core.pdom.WritablePDOM;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
* A standalone tool for populating an index. This indexer optimizes for
|
||||
* speed at the expense of accuracy.
|
||||
*
|
||||
* <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.
|
||||
* </p>
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class StandaloneFastIndexer extends StandaloneIndexer{
|
||||
|
||||
/**
|
||||
* Construct a fast standalone indexer.
|
||||
* @param writableIndexFile - the file where the PDOM index is stored
|
||||
* @param converter - a converter used to convert between String locations and IIndexLocations
|
||||
* @param linkageFactoryMappings - all of the available IPDOMLinkageFactories the index can use during indexing
|
||||
* @param scanner - provides include paths and defined symbols
|
||||
* @param mapper - a mapper used to determine ICLanguage for a particular file
|
||||
* @param log - logger
|
||||
* @throws CoreException
|
||||
*/
|
||||
public StandaloneFastIndexer(File writableIndexFile, IIndexLocationConverter converter, Map linkageFactoryMappings,
|
||||
IScannerInfo scanner, ILanguageMapper mapper, IParserLogService log) throws CoreException {
|
||||
WritablePDOM pdom = new WritablePDOM(writableIndexFile, converter, linkageFactoryMappings);
|
||||
fIndex = new WritableCIndex(
|
||||
new IWritableIndexFragment[] { pdom },
|
||||
new IIndexFragment[0]);
|
||||
fIndexAllFiles = false;
|
||||
fScanner = scanner;
|
||||
fMapper = mapper;
|
||||
fLog = log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a delegate standalone indexing task
|
||||
*/
|
||||
protected StandaloneIndexerTask createTask(List added, List changed, List removed) {
|
||||
return new StandaloneFastIndexerTask(this, added, changed, removed);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,209 @@
|
|||
/*******************************************************************************
|
||||
* 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)
|
||||
* IBM Corporation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.core.indexer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
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.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||
import org.eclipse.cdt.core.model.AbstractLanguage;
|
||||
import org.eclipse.cdt.core.parser.CodeReader;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||
import org.eclipse.cdt.internal.core.index.IWritableIndex;
|
||||
import org.eclipse.cdt.internal.core.index.IndexFileLocation;
|
||||
import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory.CallbackHandler;
|
||||
import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory.IndexFileInfo;
|
||||
import org.eclipse.core.filesystem.URIUtil;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
/**
|
||||
* A task for index updates.
|
||||
*
|
||||
* <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.
|
||||
* </p>
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class StandaloneFastIndexerTask extends StandaloneIndexerTask implements CallbackHandler {
|
||||
private List fChanged = new ArrayList();
|
||||
private List fRemoved = new ArrayList();
|
||||
private IWritableIndex fIndex;
|
||||
private StandaloneIndexBasedCodeReaderFactory fCodeReaderFactory;
|
||||
private Map fIflCache;
|
||||
private int fCurrentConfigHash= 0;
|
||||
|
||||
public StandaloneFastIndexerTask(StandaloneFastIndexer indexer, List added,
|
||||
List changed, List removed) {
|
||||
super(indexer);
|
||||
fChanged.addAll(added);
|
||||
fChanged.addAll(changed);
|
||||
fRemoved.addAll(removed);
|
||||
updateInfo(0, 0, fChanged.size() + fRemoved.size());
|
||||
}
|
||||
|
||||
public void run(IProgressMonitor monitor) throws IOException{
|
||||
long start = System.currentTimeMillis();
|
||||
try {
|
||||
setupIndexAndReaderFactory();
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
registerTUsInReaderFactory(fChanged);
|
||||
|
||||
Iterator i= fRemoved.iterator();
|
||||
while (i.hasNext()) {
|
||||
if (monitor.isCanceled())
|
||||
return;
|
||||
String tu = (String) i.next();
|
||||
removeTU(fIndex, getIndexFileLocation(tu), 1);
|
||||
if (isValidSourceUnitName(tu)) {
|
||||
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();) {
|
||||
String tu = (String) iter.next();
|
||||
if (!isValidSourceUnitName(tu)) {
|
||||
headers.add(tu);
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
|
||||
parseTUs(fIndex, 1, sources, headers, monitor);
|
||||
if (monitor.isCanceled()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
fIndex.releaseReadLock();
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
traceEnd(start);
|
||||
}
|
||||
|
||||
private void setupIndexAndReaderFactory() throws CoreException {
|
||||
fIndex= fIndexer.getIndex();
|
||||
fIndex.resetCacheCounters();
|
||||
fIflCache = new HashMap/*<String,IIndexFileLocation>*/();
|
||||
fCodeReaderFactory = new StandaloneIndexBasedCodeReaderFactory(fIndex, fIflCache);
|
||||
fCodeReaderFactory.setCallbackHandler(this);
|
||||
}
|
||||
|
||||
private void registerTUsInReaderFactory(Collection files) throws IOException, CoreException {
|
||||
int removed= 0;
|
||||
for (Iterator iter = files.iterator(); iter.hasNext();) {
|
||||
String sourcePath = (String) iter.next();
|
||||
String path = new File(sourcePath).getCanonicalPath();
|
||||
IIndexFileLocation location = getIndexFileLocation(path);
|
||||
IndexFileInfo info= fCodeReaderFactory.createFileInfo(location);
|
||||
if (updateAll()) {
|
||||
info.fRequested= IndexFileInfo.REQUESTED;
|
||||
}
|
||||
else if (updateChangedTimestamps() && isOutdated(location, info.fFile)) {
|
||||
info.fRequested= IndexFileInfo.REQUESTED;
|
||||
}
|
||||
else {
|
||||
iter.remove();
|
||||
removed++;
|
||||
}
|
||||
}
|
||||
updateInfo(0, 0, -removed);
|
||||
|
||||
}
|
||||
|
||||
protected IIndexFileLocation findLocation(String absolutePath) {
|
||||
IIndexFileLocation result = (IIndexFileLocation) fIflCache.get(absolutePath);
|
||||
if(result==null) {
|
||||
//Standalone indexing stores the absolute paths of files being indexed
|
||||
result = new IndexFileLocation(URIUtil.toURI(absolutePath),absolutePath);
|
||||
fIflCache.put(absolutePath, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected IASTTranslationUnit createAST(AbstractLanguage lang, CodeReader codeReader, IScannerInfo scanInfo, int options, IProgressMonitor pm) throws CoreException {
|
||||
|
||||
// get the AST in a "Fast" way
|
||||
IASTTranslationUnit ast= lang.getASTTranslationUnit(codeReader, scanInfo, fCodeReaderFactory, fIndex, options, fIndexer.getParserLog());
|
||||
if (pm.isCanceled()) {
|
||||
return null;
|
||||
}
|
||||
// Clear the macros
|
||||
fCodeReaderFactory.clearMacroAttachements();
|
||||
return ast;
|
||||
}
|
||||
|
||||
protected boolean needToUpdate(IIndexFileLocation location, int confighash) throws CoreException {
|
||||
if (super.needToUpdate(location, confighash)) {
|
||||
// file is requested or is not yet indexed.
|
||||
IndexFileInfo info= fCodeReaderFactory.createFileInfo(location);
|
||||
return needToUpdate(info, confighash);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean needToUpdate(IndexFileInfo info) throws CoreException {
|
||||
return needToUpdate(info, fCurrentConfigHash);
|
||||
}
|
||||
|
||||
private boolean needToUpdate(IndexFileInfo info, int confighash) throws CoreException {
|
||||
if (info.fFile == null) {
|
||||
return true;
|
||||
}
|
||||
if (confighash != 0 && info.fRequested == IndexFileInfo.REQUESTED_IF_CONFIG_CHANGED) {
|
||||
int oldhash= info.fFile.getScannerConfigurationHashcode();
|
||||
if (oldhash == 0 || oldhash==confighash) {
|
||||
info.fRequested= IndexFileInfo.NOT_REQUESTED;
|
||||
updateInfo(0, 0, -1);
|
||||
}
|
||||
else {
|
||||
info.fRequested= IndexFileInfo.REQUESTED;
|
||||
}
|
||||
}
|
||||
return info.fRequested != IndexFileInfo.NOT_REQUESTED;
|
||||
}
|
||||
|
||||
|
||||
protected boolean postAddToIndex(IIndexFileLocation path, IIndexFile file)
|
||||
throws CoreException {
|
||||
IndexFileInfo info= fCodeReaderFactory.createFileInfo(path);
|
||||
info.fFile= file;
|
||||
if (info.fRequested != IndexFileInfo.NOT_REQUESTED) {
|
||||
info.fRequested= IndexFileInfo.NOT_REQUESTED;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/*******************************************************************************
|
||||
* 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)
|
||||
* IBM Corporation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.core.indexer;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
|
||||
import org.eclipse.cdt.core.index.IIndexLocationConverter;
|
||||
import org.eclipse.cdt.core.parser.IParserLogService;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexFragment;
|
||||
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
|
||||
import org.eclipse.cdt.internal.core.index.WritableCIndex;
|
||||
import org.eclipse.cdt.internal.core.pdom.WritablePDOM;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
* A standalone tool for populating an index. This indexer optimizes for
|
||||
* accuracy so it may be slower than the StandaloneFastIndexer.
|
||||
*
|
||||
* <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.
|
||||
* </p>
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class StandaloneFullIndexer extends StandaloneIndexer{
|
||||
|
||||
private ICodeReaderFactory fCodeReaderFactory;
|
||||
|
||||
/**
|
||||
* Create a full indexer.
|
||||
* @param writableIndexFile - the file where the PDOM index is stored
|
||||
* @param converter - a converter used to convert between String locations and IIndexLocations
|
||||
* @param linkageFactoryMappings - all of the available IPDOMLinkageFactories the index can use during indexing
|
||||
* @param scanner - provides include paths and defined symbols
|
||||
* @param mapper - a mapper used to determine ICLanguage for a particular file
|
||||
* @param log - logger
|
||||
* @param codeReaderFactory - factory that provides CodeReaders for files included
|
||||
* by the source code being parsed.
|
||||
* @throws CoreException
|
||||
*/
|
||||
public StandaloneFullIndexer(File writableIndexFile, IIndexLocationConverter converter, Map linkageFactoryMappings,
|
||||
IScannerInfo scanner, ILanguageMapper mapper, IParserLogService log, ICodeReaderFactory codeReaderFactory) throws CoreException {
|
||||
WritablePDOM pdom = new WritablePDOM(writableIndexFile, converter, linkageFactoryMappings);
|
||||
fIndex = new WritableCIndex(
|
||||
new IWritableIndexFragment[] { pdom },
|
||||
new IIndexFragment[0]);
|
||||
fIndexAllFiles = false;
|
||||
fScanner = scanner;
|
||||
fMapper = mapper;
|
||||
fCodeReaderFactory = codeReaderFactory;
|
||||
fLog = log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the factory that provides CodeReaders for files included
|
||||
* by the source code being parsed.
|
||||
* @return
|
||||
*/
|
||||
public ICodeReaderFactory getCodeReaderFactory() {
|
||||
return fCodeReaderFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a delegate standalone indexing task
|
||||
*/
|
||||
protected StandaloneIndexerTask createTask(List added, List changed, List removed) {
|
||||
return new StandaloneFullIndexerTask(this, added, changed, removed);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,179 @@
|
|||
/*******************************************************************************
|
||||
* 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)
|
||||
* IBM Corporation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.core.indexer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
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.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||
import org.eclipse.cdt.core.model.AbstractLanguage;
|
||||
import org.eclipse.cdt.core.parser.CodeReader;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||
import org.eclipse.cdt.internal.core.index.IWritableIndex;
|
||||
import org.eclipse.cdt.internal.core.index.IndexFileLocation;
|
||||
import org.eclipse.core.filesystem.URIUtil;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
/**
|
||||
* A task for index updates.
|
||||
*
|
||||
* <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.
|
||||
* </p>
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class StandaloneFullIndexerTask extends StandaloneIndexerTask {
|
||||
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 StandaloneFullIndexerTask(StandaloneFullIndexer indexer, List added,
|
||||
List changed, List removed) {
|
||||
super(indexer);
|
||||
fChanged.addAll(added);
|
||||
fChanged.addAll(changed);
|
||||
fRemoved.addAll(removed);
|
||||
updateInfo(0, 0, fChanged.size() + fRemoved.size());
|
||||
}
|
||||
|
||||
public void run(IProgressMonitor monitor) throws IOException {
|
||||
long start = System.currentTimeMillis();
|
||||
try {
|
||||
setupIndex();
|
||||
registerTUsInReaderFactory(fChanged);
|
||||
|
||||
// separate headers
|
||||
List headers= new ArrayList();
|
||||
List sources= fChanged;
|
||||
for (Iterator iter = fChanged.iterator(); iter.hasNext();) {
|
||||
String tu = (String) iter.next();
|
||||
if (!isValidSourceUnitName(tu)) {
|
||||
headers.add(tu);
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
|
||||
Iterator i= fRemoved.iterator();
|
||||
while (i.hasNext()) {
|
||||
if (monitor.isCanceled())
|
||||
return;
|
||||
String tu = (String) i.next();
|
||||
removeTU(fIndex, getIndexFileLocation(tu), 0);
|
||||
if (isValidSourceUnitName(tu)) {
|
||||
updateInfo(1, 0, 0);
|
||||
}
|
||||
else {
|
||||
updateInfo(0, 1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
parseTUs(fIndex, 1, sources, headers, monitor);
|
||||
}
|
||||
finally {
|
||||
fIndex.releaseReadLock();
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
traceEnd(start);
|
||||
}
|
||||
|
||||
private void setupIndex() throws CoreException {
|
||||
fIndex = fIndexer.getIndex();
|
||||
fIndex.resetCacheCounters();
|
||||
}
|
||||
|
||||
private void registerTUsInReaderFactory(Collection/*<ITranslationUnit>*/ sources)
|
||||
throws IOException, CoreException {
|
||||
int removed= 0;
|
||||
filePathsToParse= new HashMap/*<IIndexFileLocation, Object>*/();
|
||||
for (Iterator iter = sources.iterator(); iter.hasNext();) {
|
||||
String sourcePath = (String) iter.next();
|
||||
String path = new File(sourcePath).getCanonicalPath();
|
||||
IIndexFileLocation location = getIndexFileLocation(path);
|
||||
if (updateAll()) {
|
||||
filePathsToParse.put(location, REQUIRED);
|
||||
}
|
||||
else if (updateChangedTimestamps() && isOutdated(location, fIndex.getFile(location))) {
|
||||
filePathsToParse.put(location, REQUIRED);
|
||||
}
|
||||
else {
|
||||
iter.remove();
|
||||
removed++;
|
||||
continue;
|
||||
}
|
||||
updateInfo(0, 0, -removed);
|
||||
}
|
||||
}
|
||||
|
||||
protected IIndexFileLocation findLocation(String absolutePath) {
|
||||
IIndexFileLocation result = (IIndexFileLocation) fIflCache.get(absolutePath);
|
||||
if(result==null) {
|
||||
//Standalone indexing stores the absolute paths of files being indexed
|
||||
result = new IndexFileLocation(URIUtil.toURI(absolutePath),absolutePath);
|
||||
fIflCache.put(absolutePath, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected IASTTranslationUnit createAST(AbstractLanguage lang, CodeReader codeReader, IScannerInfo scanInfo, int options, IProgressMonitor pm) throws CoreException {
|
||||
// get the AST in a "Fast" way
|
||||
IASTTranslationUnit ast= lang.getASTTranslationUnit(codeReader, scanInfo, ((StandaloneFullIndexer)fIndexer).getCodeReaderFactory(), null, options, fIndexer.getParserLog());
|
||||
if (pm.isCanceled()) {
|
||||
return null;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
protected boolean needToUpdate(IIndexFileLocation location, int confighash) throws CoreException {
|
||||
if (super.needToUpdate(location, confighash)) {
|
||||
Object required= filePathsToParse.get(location);
|
||||
if (required == null) {
|
||||
required= MISSING;
|
||||
filePathsToParse.put(location, required);
|
||||
}
|
||||
return required != SKIP;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean postAddToIndex(IIndexFileLocation location, IIndexFile file)
|
||||
throws CoreException {
|
||||
Object required= filePathsToParse.get(location);
|
||||
filePathsToParse.put(location, SKIP);
|
||||
return required == REQUIRED;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 IBM Corporation 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:
|
||||
* IBM - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.core.indexer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
|
||||
import org.eclipse.cdt.core.dom.IMacroCollector;
|
||||
import org.eclipse.cdt.core.index.IIndex;
|
||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||
import org.eclipse.cdt.core.parser.CodeReader;
|
||||
import org.eclipse.cdt.core.parser.ICodeReaderCache;
|
||||
import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory;
|
||||
import org.eclipse.cdt.internal.core.index.IndexFileLocation;
|
||||
import org.eclipse.core.filesystem.URIUtil;
|
||||
|
||||
/**
|
||||
* A factory for CodeReaders construction.
|
||||
*
|
||||
* <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.
|
||||
* </p>
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class StandaloneIndexBasedCodeReaderFactory extends IndexBasedCodeReaderFactory {
|
||||
|
||||
public static class DefaultFallBackFactory implements ICodeReaderFactory {
|
||||
|
||||
public CodeReader createCodeReaderForInclusion(IMacroCollector callback, String path) {
|
||||
try {
|
||||
if (!new File(path).exists())
|
||||
return null;
|
||||
return new CodeReader(path);
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public CodeReader createCodeReaderForTranslationUnit(String path) {
|
||||
try {
|
||||
if (!new File(path).exists())
|
||||
return null;
|
||||
return new CodeReader(path);
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public ICodeReaderCache getCodeReaderCache() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getUniqueIdentifier() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public StandaloneIndexBasedCodeReaderFactory(IIndex index) {
|
||||
super(index);
|
||||
}
|
||||
|
||||
public StandaloneIndexBasedCodeReaderFactory(IIndex index, ICodeReaderFactory fallbackFactory) {
|
||||
super(index, new HashMap/*<String,IIndexFileLocation>*/(), fallbackFactory);
|
||||
}
|
||||
|
||||
public StandaloneIndexBasedCodeReaderFactory(IIndex index, Map iflCache) {
|
||||
super(index, iflCache, new DefaultFallBackFactory());
|
||||
}
|
||||
|
||||
public IIndexFileLocation findLocation(String absolutePath) {
|
||||
IIndexFileLocation result = (IIndexFileLocation) getIFLCache().get(absolutePath);
|
||||
if(result==null) {
|
||||
//Standalone indexing stores the absolute paths of files being indexed
|
||||
result = new IndexFileLocation(URIUtil.toURI(absolutePath),absolutePath);
|
||||
getIFLCache().put(absolutePath, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,428 @@
|
|||
/*******************************************************************************
|
||||
* 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
|
||||
* 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.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.pdom.IndexerProgress;
|
||||
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= 0;
|
||||
|
||||
/**
|
||||
* Parser to skip all references.
|
||||
*/
|
||||
public static final int SKIP_ALL_REFERENCES= 1;
|
||||
|
||||
/**
|
||||
* Parser to skp type references.
|
||||
*/
|
||||
public static final int SKIP_TYPE_REFERENCES= 2;
|
||||
|
||||
/**
|
||||
* 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 NO_TUS = new ArrayList();
|
||||
/**
|
||||
* The IWritableIndex that stores all bindings and names.
|
||||
*/
|
||||
protected IWritableIndex fIndex;
|
||||
|
||||
/**
|
||||
* A flag that indiciates 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 fValidSourceUnitNames;
|
||||
|
||||
/**
|
||||
* The IScannerInfo that provides include paths and defined symbols.
|
||||
*/
|
||||
protected IScannerInfo fScanner;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the collection of valid file extensions for C/C++ source.
|
||||
* @return
|
||||
*/
|
||||
public Set getValidSourceUnitNames() {
|
||||
return fValidSourceUnitNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the collection of valid file extensions for C/C++ source.
|
||||
*/
|
||||
public void setValidSourceUnitNames(Set validSourceUnitNames) {
|
||||
fValidSourceUnitNames = validSourceUnitNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the IScannerInfo that provides include paths and defined symbols.
|
||||
* @return
|
||||
*/
|
||||
public IScannerInfo getScannerInfo() {
|
||||
return fScanner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ILanguageMapper that determines the ILanguage for a file.
|
||||
* @return
|
||||
*/
|
||||
public ILanguageMapper getLanguageMapper() {
|
||||
return fMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the logger.
|
||||
* @return
|
||||
*/
|
||||
public IParserLogService getParserLog() {
|
||||
return fLog;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if indexing activities should be shown.
|
||||
* Otherwise, this method returns false.
|
||||
* @return
|
||||
*/
|
||||
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.
|
||||
* @return
|
||||
*/
|
||||
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..
|
||||
* @return
|
||||
*/
|
||||
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.
|
||||
* @return
|
||||
*/
|
||||
public synchronized IndexerProgress getProgressInformation() {
|
||||
return fDelegate != null ? fDelegate.getProgressInformation() : fProgress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the update options specified.
|
||||
* @return
|
||||
*/
|
||||
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 tus, IProgressMonitor monitor) throws IOException {
|
||||
fProgress = createProgress();
|
||||
|
||||
try {
|
||||
clearIndex();
|
||||
fDelegate= createTask(getFilesAdded(tus), NO_TUS, NO_TUS);
|
||||
fDelegate.setUpdateFlags(fUpdateOptions);
|
||||
|
||||
} catch (CoreException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
|
||||
if (fDelegate != null) {
|
||||
fDelegate.run(monitor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 added, List changed, List removed, IProgressMonitor monitor) throws IOException {
|
||||
fProgress= new IndexerProgress();
|
||||
|
||||
fDelegate= createTask(getFilesAdded(added), changed, removed);
|
||||
if (fDelegate instanceof StandaloneIndexerTask) {
|
||||
fDelegate.setUpdateFlags(fUpdateOptions);
|
||||
}
|
||||
|
||||
if (fDelegate != null) {
|
||||
fDelegate.run(monitor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns files that are being added to the index, skipping over files that
|
||||
* should not be excluded.
|
||||
* @param tus
|
||||
* @return
|
||||
*/
|
||||
private List getFilesAdded(List tus) {
|
||||
List added = new ArrayList();
|
||||
|
||||
FilenameFilter filter = getExclusionFilter();
|
||||
if (filter == null) {
|
||||
filter = DEFAULT_FILTER;
|
||||
}
|
||||
|
||||
Iterator iter = tus.iterator();
|
||||
while (iter.hasNext()) {
|
||||
String path = (String) iter.next();
|
||||
File file = new File(path);
|
||||
if (file.isDirectory()) {
|
||||
String[] files = file.list(filter);
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
added.add((String)files[i]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (filter.accept(file.getParentFile(), file.getName())) {
|
||||
added.add(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
return added;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a delegate standalone indexing task
|
||||
*/
|
||||
protected abstract StandaloneIndexerTask createTask(List added, List changed, List removed);
|
||||
|
||||
/**
|
||||
* Return the type of references the parser should skip.
|
||||
* @return
|
||||
*/
|
||||
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.
|
||||
* @return
|
||||
*/
|
||||
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.
|
||||
* @return
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,499 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 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
|
||||
* IBM Corporation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.core.indexer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
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.IIndex;
|
||||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||
import org.eclipse.cdt.core.index.IIndexInclude;
|
||||
import org.eclipse.cdt.core.model.AbstractLanguage;
|
||||
import org.eclipse.cdt.core.model.ILanguage;
|
||||
import org.eclipse.cdt.core.parser.CodeReader;
|
||||
import org.eclipse.cdt.core.parser.IExtendedScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
|
||||
import org.eclipse.cdt.internal.core.index.IWritableIndex;
|
||||
import org.eclipse.cdt.internal.core.index.IndexFileLocation;
|
||||
import org.eclipse.cdt.internal.core.pdom.IndexerProgress;
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOMWriter;
|
||||
import org.eclipse.core.filesystem.URIUtil;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
|
||||
/**
|
||||
* A task for index updates.
|
||||
*
|
||||
* <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.
|
||||
* </p>
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public abstract class StandaloneIndexerTask extends PDOMWriter{
|
||||
private static final Object NO_CONTEXT = new Object();
|
||||
|
||||
protected StandaloneIndexer fIndexer;
|
||||
protected Map/*<IIndexFileLocation, Object>*/ fContextMap = new HashMap/*<IIndexFileLocation, Object>*/();
|
||||
private List fFilesUpFront= new ArrayList();
|
||||
private String fDummyFileName;
|
||||
private URI fDummyFileURI;
|
||||
private int fUpdateFlags= StandaloneIndexer.UPDATE_ALL;
|
||||
|
||||
protected StandaloneIndexerTask(StandaloneIndexer indexer) {
|
||||
fIndexer= indexer;
|
||||
setShowActivity(fIndexer.getShowActivity());
|
||||
setShowProblems(fIndexer.getShowProblems());
|
||||
setSkipReferences(fIndexer.getSkipReferences());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the indexer.
|
||||
* @return
|
||||
*/
|
||||
final public StandaloneIndexer getIndexer() {
|
||||
return fIndexer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return indexer's progress information.
|
||||
*/
|
||||
final public IndexerProgress getProgressInformation() {
|
||||
return super.getProgressInformation();
|
||||
}
|
||||
|
||||
public void setUpdateFlags(int flags) {
|
||||
fUpdateFlags= flags;
|
||||
}
|
||||
|
||||
final public boolean updateAll() {
|
||||
return (fUpdateFlags & StandaloneIndexer.UPDATE_ALL) != 0;
|
||||
}
|
||||
|
||||
final public boolean updateChangedTimestamps() {
|
||||
return (fUpdateFlags & StandaloneIndexer.UPDATE_CHECK_TIMESTAMPS) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells the parser which files to parse first
|
||||
*/
|
||||
final public void setParseUpFront() {
|
||||
String[] files = fIndexer.getFilesToParseUpFront();
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
fFilesUpFront.add((String) files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Figurues out whether all files (sources without config, headers not included)
|
||||
* should be parsed.
|
||||
* @since 4.0
|
||||
*/
|
||||
final protected boolean getIndexAllFiles() {
|
||||
return getIndexer().getIndexAllFiles();
|
||||
}
|
||||
|
||||
private IASTTranslationUnit createAST(IIndexFileLocation location, IScannerInfo scannerInfo, int options, IProgressMonitor pm) throws IOException, CoreException {
|
||||
String path = location.getFullPath();
|
||||
if (path == null) {
|
||||
return null;
|
||||
}
|
||||
ILanguage language = fIndexer.getLanguageMapper().getLanguage(path);
|
||||
if (language == null)
|
||||
return null;
|
||||
|
||||
CodeReader codeReader = new CodeReader(path);
|
||||
if (codeReader == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return createAST((AbstractLanguage)language, codeReader, scannerInfo, options, pm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to create the ast for a translation unit or a pre-parsed file.
|
||||
* May return <code>null</code>.
|
||||
* @see #parseTUs(IWritableIndex, int, Collection, Collection, IProgressMonitor)
|
||||
* @since 4.0
|
||||
*/
|
||||
abstract protected IASTTranslationUnit createAST(AbstractLanguage lang, CodeReader codeReader, IScannerInfo scanInfo, int options, IProgressMonitor pm) throws CoreException;
|
||||
|
||||
/**
|
||||
* Convenience method for subclasses, parses the files calling out to the methods
|
||||
* {@link #createAST(IIndexFileLocation, 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 IOException, CoreException, InterruptedException {
|
||||
int options= 0;
|
||||
if (fIndexer.getSkipReferences() == StandaloneIndexer.SKIP_ALL_REFERENCES) {
|
||||
options |= AbstractLanguage.OPTION_SKIP_FUNCTION_BODIES;
|
||||
}
|
||||
for (Iterator iter = fFilesUpFront.iterator(); iter.hasNext();) {
|
||||
String upfront= (String) iter.next();
|
||||
parseUpFront(upfront, options, index, readlockCount, monitor);
|
||||
}
|
||||
|
||||
// sources first
|
||||
for (Iterator iter = sources.iterator(); iter.hasNext();) {
|
||||
if (monitor.isCanceled())
|
||||
return;
|
||||
String sourcePath = (String) iter.next();
|
||||
String path = new File(sourcePath).getCanonicalPath();
|
||||
final IIndexFileLocation ifl = getIndexFileLocation(path);
|
||||
|
||||
if (needToUpdate(ifl, 0)) {
|
||||
parseTU(ifl, options, index, readlockCount, monitor);
|
||||
}
|
||||
}
|
||||
|
||||
// headers with context
|
||||
for (Iterator iter = headers.iterator(); iter.hasNext();) {
|
||||
if (monitor.isCanceled())
|
||||
return;
|
||||
String sourcePath = (String) iter.next();
|
||||
String path = new File(sourcePath).getCanonicalPath();
|
||||
final IIndexFileLocation location = getIndexFileLocation(path);
|
||||
|
||||
if (!needToUpdate(location, 0)) {
|
||||
iter.remove();
|
||||
}
|
||||
else {
|
||||
IIndexFileLocation context= findContext(index, location);
|
||||
if (context != null) {
|
||||
parseTU(context, options, index, readlockCount, monitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// headers without context
|
||||
if (getIndexAllFiles()) {
|
||||
for (Iterator iter = headers.iterator(); iter.hasNext();) {
|
||||
if (monitor.isCanceled())
|
||||
return;
|
||||
|
||||
String sourcePath = (String) iter.next();
|
||||
String path = new File(sourcePath).getCanonicalPath();
|
||||
final IIndexFileLocation ifl = getIndexFileLocation(path);
|
||||
|
||||
if (!needToUpdate(ifl, 0)) {
|
||||
iter.remove();
|
||||
}
|
||||
else {
|
||||
parseTU(ifl, options, index, readlockCount, monitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final protected boolean isOutdated(IIndexFileLocation ifl, IIndexFile indexFile) throws CoreException {
|
||||
if (indexFile == null) {
|
||||
return true;
|
||||
}
|
||||
File res = new File(ifl.getFullPath());
|
||||
if (res != null) {
|
||||
if (indexFile != null) {
|
||||
if (res.lastModified() == indexFile.getTimestamp()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private void parseTU(IIndexFileLocation location, int options, IWritableIndex index, int readlockCount, IProgressMonitor pm) throws IOException, CoreException, InterruptedException {
|
||||
String path = location.getFullPath();
|
||||
|
||||
try {
|
||||
// skip if no scanner info
|
||||
IScannerInfo scanner= fIndexer.getScannerInfo();
|
||||
if (scanner == null) {
|
||||
updateInfo(0, 0, -1);
|
||||
}
|
||||
else {
|
||||
final int configHash = computeHashCode(scanner);
|
||||
if (needToUpdate(location, configHash)) {
|
||||
if (fShowActivity) {
|
||||
System.out.println("Indexer: parsing " + path); //$NON-NLS-1$
|
||||
}
|
||||
long start= System.currentTimeMillis();
|
||||
IASTTranslationUnit ast= createAST(location, scanner, options, pm);
|
||||
fStatistics.fParsingTime += System.currentTimeMillis()-start;
|
||||
if (ast != null) {
|
||||
addSymbols(ast, index, readlockCount, configHash, pm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (CoreException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (Error e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void parseUpFront(String file, int options, IWritableIndex index, int readlockCount, IProgressMonitor pm) throws CoreException, InterruptedException {
|
||||
file= file.trim();
|
||||
if (file.length() == 0) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (fShowActivity) {
|
||||
System.out.println("Indexer: parsing " + file + " up front"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
|
||||
long start= System.currentTimeMillis();
|
||||
|
||||
IASTTranslationUnit ast= null;
|
||||
ILanguage l = fIndexer.getLanguageMapper().getLanguage(file);
|
||||
if (l instanceof AbstractLanguage) {
|
||||
AbstractLanguage lang= (AbstractLanguage) l;
|
||||
IScannerInfo scanInfo = fIndexer.getScannerInfo();
|
||||
String code= "#include \"" + file + "\"\n"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
if (fDummyFileName == null) {
|
||||
fDummyFileName= file + "___"; //$NON-NLS-1$
|
||||
fDummyFileURI= findLocation(fDummyFileName).getURI();
|
||||
}
|
||||
CodeReader codeReader= new CodeReader(fDummyFileName, code.toCharArray());
|
||||
ast= createAST(lang, codeReader, scanInfo, options, pm);
|
||||
}
|
||||
fStatistics.fParsingTime += System.currentTimeMillis()-start;
|
||||
if (ast != null) {
|
||||
addSymbols(ast, index, readlockCount, 0, pm);
|
||||
updateInfo(-1, +1, 0);
|
||||
}
|
||||
}
|
||||
catch (CoreException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (Error e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overriders must call super.needToUpdate(). If <code>false</code> is returned
|
||||
* this must be passed on to their caller:
|
||||
* <pre>
|
||||
* if (super.needToUpdate()) {
|
||||
* // your code
|
||||
* }
|
||||
* return false;
|
||||
*/
|
||||
protected boolean needToUpdate(IIndexFileLocation fileLoc, int configHash) throws CoreException {
|
||||
return fDummyFileURI==null || !fDummyFileURI.equals(fileLoc.getURI());
|
||||
}
|
||||
|
||||
private IIndexFileLocation findContext(IIndex index, IIndexFileLocation location) {
|
||||
Object cachedContext= fContextMap.get(location);
|
||||
if (cachedContext != null) {
|
||||
return cachedContext == NO_CONTEXT ? null : (IIndexFileLocation) cachedContext;
|
||||
}
|
||||
IIndexFileLocation context= null;
|
||||
fContextMap.put(location, NO_CONTEXT); // prevent recursion
|
||||
IIndexFile pdomFile;
|
||||
try {
|
||||
pdomFile = index.getFile(location);
|
||||
if (pdomFile != null) {
|
||||
IIndexInclude[] includedBy = index.findIncludedBy(pdomFile, IIndex.DEPTH_ZERO);
|
||||
ArrayList/*<IIndexFileLocation>*/ paths= new ArrayList/*<IIndexFileLocation>*/(includedBy.length);
|
||||
for (int i = 0; i < includedBy.length; i++) {
|
||||
IIndexInclude include = includedBy[i];
|
||||
IIndexFileLocation incLocation = include.getIncludedByLocation();
|
||||
if (isValidSourceUnitName(incLocation.getFullPath())) {
|
||||
context = incLocation;
|
||||
if (context != null) {
|
||||
fContextMap.put(location, context);
|
||||
return context;
|
||||
}
|
||||
}
|
||||
paths.add(incLocation);
|
||||
}
|
||||
for (Iterator/*<IIndexFileLocation>*/ iter = paths.iterator(); iter.hasNext();) {
|
||||
IIndexFileLocation nextLevel = (IIndexFileLocation) iter.next();
|
||||
context = findContext(index, nextLevel);
|
||||
if (context != null) {
|
||||
fContextMap.put(location, context);
|
||||
return context;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conveninence method for subclasses, removes a translation unit from the index.
|
||||
* @since 4.0
|
||||
*/
|
||||
protected void removeTU(IWritableIndex index, IIndexFileLocation ifl, int readlocks) throws CoreException, InterruptedException {
|
||||
index.acquireWriteLock(readlocks);
|
||||
try {
|
||||
IIndexFragmentFile file = (IIndexFragmentFile) index.getFile(ifl);
|
||||
if (file != null)
|
||||
index.clearFile(file, null);
|
||||
} finally {
|
||||
index.releaseWriteLock(readlocks);
|
||||
}
|
||||
}
|
||||
|
||||
protected void traceEnd(long start) {
|
||||
if (fIndexer.getTraceStatistics()) {
|
||||
IndexerProgress info= getProgressInformation();
|
||||
String name= getClass().getName();
|
||||
name= name.substring(name.lastIndexOf('.')+1);
|
||||
|
||||
System.out.println(name + " " //$NON-NLS-1$
|
||||
+ " (" + info.fCompletedSources + " sources, " //$NON-NLS-1$ //$NON-NLS-2$
|
||||
+ info.fCompletedHeaders + " headers)"); //$NON-NLS-1$
|
||||
|
||||
boolean allFiles= getIndexAllFiles();
|
||||
boolean skipRefs= fIndexer.getSkipReferences() == StandaloneIndexer.SKIP_ALL_REFERENCES;
|
||||
boolean skipTypeRefs= skipRefs || fIndexer.getSkipReferences() == StandaloneIndexer.SKIP_TYPE_REFERENCES;
|
||||
System.out.println(name + " Options: " //$NON-NLS-1$
|
||||
+ "parseAllFiles=" + allFiles //$NON-NLS-1$
|
||||
+ ",skipReferences=" + skipRefs //$NON-NLS-1$
|
||||
+ ", skipTypeReferences=" + skipTypeRefs //$NON-NLS-1$
|
||||
+ "."); //$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$
|
||||
|
||||
IWritableIndex index = fIndexer.getIndex();
|
||||
if (index != null) {
|
||||
long misses= index.getCacheMisses();
|
||||
long hits= index.getCacheHits();
|
||||
long tries= misses+hits;
|
||||
double missPct= tries==0 ? 0.0 : (double) misses / (double) tries;
|
||||
System.out.println(name + " Cache: " //$NON-NLS-1$
|
||||
+ hits + " hits, " //$NON-NLS-1$
|
||||
+ misses + "(" + nf.format(missPct)+ ") misses."); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void run(IProgressMonitor monitor) throws IOException;
|
||||
|
||||
protected IIndexFileLocation getIndexFileLocation(String path) {
|
||||
String absolutePath = new File(path).getAbsolutePath();
|
||||
//Standalone indexing stores the absolute paths of files being indexed
|
||||
return new IndexFileLocation(URIUtil.toURI(absolutePath),absolutePath);
|
||||
}
|
||||
|
||||
protected boolean isValidSourceUnitName(String filename) {
|
||||
IPath path = new Path(filename);
|
||||
if (fIndexer.getValidSourceUnitNames() == null || fIndexer.getValidSourceUnitNames().size() == 0)
|
||||
return true;
|
||||
return fIndexer.getValidSourceUnitNames().contains(path.getFileExtension());
|
||||
}
|
||||
|
||||
protected long getLastModified(IIndexFileLocation location) {
|
||||
return new File(location.getFullPath()).lastModified();
|
||||
}
|
||||
|
||||
protected static int computeHashCode(IScannerInfo scannerInfo) {
|
||||
int result= 0;
|
||||
Map macros= scannerInfo.getDefinedSymbols();
|
||||
if (macros != null) {
|
||||
for (Iterator i = macros.entrySet().iterator(); i.hasNext();) {
|
||||
Map.Entry entry = (Map.Entry) i.next();
|
||||
String key = (String) entry.getKey();
|
||||
String value = (String) entry.getValue();
|
||||
result= addToHashcode(result, key);
|
||||
if (value != null && value.length() > 0) {
|
||||
result= addToHashcode(result, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
String[] a= scannerInfo.getIncludePaths();
|
||||
if (a != null) {
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
result= addToHashcode(result, a[i]);
|
||||
|
||||
}
|
||||
}
|
||||
if (scannerInfo instanceof IExtendedScannerInfo) {
|
||||
IExtendedScannerInfo esi= (IExtendedScannerInfo) scannerInfo;
|
||||
a= esi.getIncludeFiles();
|
||||
if (a != null) {
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
result= addToHashcode(result, a[i]);
|
||||
|
||||
}
|
||||
}
|
||||
a= esi.getLocalIncludePath();
|
||||
if (a != null) {
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
result= addToHashcode(result, a[i]);
|
||||
|
||||
}
|
||||
}
|
||||
a= esi.getMacroFiles();
|
||||
if (a != null) {
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
result= addToHashcode(result, a[i]);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int addToHashcode(int result, String key) {
|
||||
return result*31 + key.hashCode();
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue