1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Extracts common stuff from full and fast indexer to a base class.

This commit is contained in:
Markus Schorn 2006-11-20 12:38:56 +00:00
parent 0eca098d3c
commit e62a54fcea
6 changed files with 204 additions and 283 deletions

View file

@ -14,7 +14,6 @@ package org.eclipse.cdt.internal.core.index;
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.LinkedHashSet;
@ -26,6 +25,7 @@ import org.eclipse.cdt.core.dom.ICodeReaderFactory;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexInclude;
import org.eclipse.cdt.core.index.IIndexMacro;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.ICodeReaderCache;
@ -33,6 +33,7 @@ import org.eclipse.cdt.core.parser.IMacro;
import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.ParserUtil;
import org.eclipse.cdt.internal.core.parser.scanner2.ObjectStyleMacro;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMacro;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
@ -46,7 +47,6 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory {
private final IIndex index;
private Map fileInfoCache = new HashMap(); // filename, fileInfo
private List usedMacros = new ArrayList();
private Collection fPathCollector;
private static final char[] EMPTY_CHARS = new char[0];
@ -55,6 +55,7 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory {
private FileInfo() {}
public IIndexFile fFile= null;
public IMacro[] fMacros= null;
// public FileInfo[] fFileInfos= null;
private boolean fRequested= false;
public boolean isRequested() {
@ -75,9 +76,6 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory {
}
public CodeReader createCodeReaderForTranslationUnit(String path) {
if (fPathCollector != null) {
fPathCollector.add(path);
}
return ParserUtil.createReader(path, null);
}
@ -108,7 +106,13 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory {
FileInfo fi = (FileInfo) iter.next();
if (fi.fMacros == null) {
assert fi.fFile != null;
fi.fMacros= fi.fFile.getMacros();
IIndexMacro[] macros= fi.fFile.getMacros();
IMacro[] converted= new IMacro[macros.length];
for (int i = 0; i < macros.length; i++) {
IIndexMacro macro = macros[i];
converted[i]= ((PDOMMacro)macro).getMacro();
}
fi.fMacros= converted;
}
for (int i = 0; i < fi.fMacros.length; ++i) {
scanner.addDefinition(fi.fMacros[i]);
@ -126,9 +130,6 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory {
// still try to parse the file.
}
if (fPathCollector != null) {
fPathCollector.add(canonicalPath);
}
return ParserUtil.createReader(canonicalPath, null);
}
@ -187,8 +188,4 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory {
public FileInfo createFileInfo(ITranslationUnit tu) throws CoreException {
return createInfo(tu.getLocation().toOSString(), null);
}
public void setPathCollector(Collection paths) {
fPathCollector= paths;
}
}

View file

@ -14,13 +14,11 @@ package org.eclipse.cdt.internal.core.pdom.indexer;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
@ -137,6 +135,53 @@ public abstract class PDOMIndexerTask implements IPDOMIndexerTask {
}
}
protected void parseTUs(Collection sources, Collection headers, IProgressMonitor monitor) throws CoreException, InterruptedException {
// sources first
Iterator iter;
for (iter = sources.iterator(); iter.hasNext();) {
if (monitor.isCanceled())
return;
ITranslationUnit tu = (ITranslationUnit) iter.next();
String path = tu.getLocation().toOSString();
if (needToUpdate(path)) {
parseTU(tu, monitor);
}
}
// headers with context
for (iter = headers.iterator(); iter.hasNext();) {
if (monitor.isCanceled())
return;
ITranslationUnit tu = (ITranslationUnit) iter.next();
String path = tu.getLocation().toOSString();
if (!needToUpdate(path)) {
iter.remove();
}
else {
ITranslationUnit context= findContext(getIndex(), path);
if (context != null) {
parseTU(context, monitor);
}
}
}
// headers without context
if (getIndexAllFiles()) {
for (iter = headers.iterator(); iter.hasNext();) {
if (monitor.isCanceled())
return;
ITranslationUnit tu = (ITranslationUnit) iter.next();
String path = tu.getLocation().toOSString();
if (!needToUpdate(path)) {
iter.remove();
}
else {
parseTU(tu, monitor);
}
}
}
}
protected void parseTU(ITranslationUnit tu, IProgressMonitor pm) throws CoreException, InterruptedException {
IPath path= tu.getPath();
try {
@ -246,40 +291,101 @@ public abstract class PDOMIndexerTask implements IPDOMIndexerTask {
return fCompletedSources;
}
/**
* Extracts a map of names from the ast and returns an array defining the order in
* which the symbols should be added to the index.
* @since 4.0
*/
protected String[] extractSymbols(IASTTranslationUnit ast, Set legalPaths, final LinkedHashMap symbolMap) {
// includes
protected void addSymbols(IASTTranslationUnit ast, IProgressMonitor pm) throws InterruptedException, CoreException {
final Map symbolMap= new HashMap();
String[] orderedPaths= extractSymbols(ast, symbolMap);
for (int i=0; i<orderedPaths.length; i++) {
if (pm.isCanceled()) {
return;
}
String path= orderedPaths[i];
ArrayList[] arrayLists = ((ArrayList[]) symbolMap.get(path));
// resolve the names
ArrayList names= arrayLists[2];
for (int j=0; j<names.size(); j++) {
((IASTName[]) names.get(j))[0].resolveBinding();
}
}
boolean isFirstRequest= true;
boolean isFirstAddition= true;
IWritableIndex index= getIndex();
index.acquireWriteLock(getReadlockCount());
try {
for (int i=0; i<orderedPaths.length; i++) {
if (pm.isCanceled())
return;
String path = orderedPaths[i];
if (path != null) {
if (fTrace) {
System.out.println("Indexer: adding " + path); //$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());
}
fCompletedSources++;
}
private String[] extractSymbols(IASTTranslationUnit ast, final Map symbolMap) throws CoreException {
LinkedHashSet orderedIncludes= new LinkedHashSet();
ArrayList stack= new ArrayList();
final String astFilePath = ast.getFilePath();
String currentPath= astFilePath;
IASTPreprocessorIncludeStatement[] includes = ast.getIncludeDirectives();
for (int i = includes.length-1; i >= 0; --i) {
for (int i= 0; i < includes.length; i++) {
IASTPreprocessorIncludeStatement include = includes[i];
IASTFileLocation sourceLoc = include.getFileLocation();
String path= sourceLoc != null ? sourceLoc.getFileName() : astFilePath; // command-line includes
if (legalPaths.contains(path)) {
prepareInMap(symbolMap, path);
addToMap(symbolMap, 0, path, include);
String newPath= sourceLoc != null ? sourceLoc.getFileName() : astFilePath; // command-line includes
while (!stack.isEmpty() && !currentPath.equals(newPath)) {
if (needToUpdate(currentPath)) {
prepareInMap(symbolMap, currentPath);
orderedIncludes.add(currentPath);
}
path= include.getPath();
if (legalPaths.contains(path)) {
prepareInMap(symbolMap, path);
currentPath= (String) stack.remove(stack.size()-1);
}
if (needToUpdate(newPath)) {
prepareInMap(symbolMap, newPath);
addToMap(symbolMap, 0, newPath, include);
}
stack.add(currentPath);
currentPath= include.getPath();
}
stack.add(currentPath);
while (!stack.isEmpty()) {
currentPath= (String) stack.remove(stack.size()-1);
if (needToUpdate(currentPath)) {
prepareInMap(symbolMap, currentPath);
orderedIncludes.add(currentPath);
}
if (legalPaths.contains(astFilePath)) {
prepareInMap(symbolMap, ast.getFilePath());
}
// macros
IASTPreprocessorMacroDefinition[] macros = ast.getMacroDefinitions();
for (int i = 0; i < macros.length; ++i) {
IASTPreprocessorMacroDefinition macro = macros[i];
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
String path = sourceLoc.getFileName();
addToMap(symbolMap, 1, path, macro);
String path2 = sourceLoc.getFileName();
addToMap(symbolMap, 1, path2, macro);
}
}
@ -292,17 +398,16 @@ public abstract class PDOMIndexerTask implements IPDOMIndexerTask {
}
}
});
Collection temp= symbolMap.keySet();
int size= temp.size();
String[] result= new String[temp.size()];
for (Iterator iter = temp.iterator(); iter.hasNext();) {
result[--size]= (String) iter.next();
}
return result;
return (String[]) orderedIncludes.toArray(new String[orderedIncludes.size()]);
}
private void addToMap(HashMap map, int idx, String path, Object thing) {
protected abstract IWritableIndex getIndex();
protected abstract int getReadlockCount();
protected abstract boolean needToUpdate(String path) throws CoreException;
protected abstract boolean postAddToIndex(String path, IIndexFile file) throws CoreException;
private void addToMap(Map map, int idx, String path, Object thing) {
List[] lists= (List[]) map.get(path);
if (lists != null)
lists[idx].add(thing);
@ -316,20 +421,7 @@ public abstract class PDOMIndexerTask implements IPDOMIndexerTask {
return false;
}
protected void prepareIndexInsertion(String path, Map symbolMap) {
ArrayList[] arrayLists = ((ArrayList[]) symbolMap.get(path));
// reverse the includes
Collections.reverse(arrayLists[0]);
// resolve the names
ArrayList names= arrayLists[2];
for (int j=0; j<names.size(); j++) {
((IASTName[]) names.get(j))[0].resolveBinding();
}
}
protected IIndexFragmentFile addToIndex(IWritableIndex index, String location, Map symbolMap) throws CoreException {
private IIndexFragmentFile addToIndex(IWritableIndex index, String location, Map symbolMap) throws CoreException {
// Remove the old symbols in the tu
Path path= new Path(location);
IIndexFragmentFile file= (IIndexFragmentFile) index.getFile(path);

View file

@ -13,15 +13,13 @@
package org.eclipse.cdt.internal.core.pdom.indexer.fast;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
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.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.CodeReader;
@ -85,9 +83,6 @@ abstract class PDOMFastIndexerJob extends PDOMIndexerTask implements IPDOMIndexe
return;
}
HashSet paths= new HashSet();
paths.add(path.toOSString());
codeReaderFactory.setPathCollector(paths);
index.acquireReadLock();
try {
// get the AST in a "Fast" way
@ -99,118 +94,34 @@ abstract class PDOMFastIndexerJob extends PDOMIndexerTask implements IPDOMIndexe
codeReaderFactory.clearMacroAttachements();
// Add the new symbols
addSymbols(paths, ast, pm);
addSymbols(ast, pm);
}
finally {
index.releaseReadLock();
codeReaderFactory.setPathCollector(null);
}
}
protected void addSymbols(HashSet paths, IASTTranslationUnit ast, IProgressMonitor pm) throws InterruptedException, CoreException {
// Add in the includes
final LinkedHashMap symbolMap= new LinkedHashMap();
String[] orderedPaths= extractSymbols(ast, paths, symbolMap);
for (int i=0; i<orderedPaths.length; i++) {
if (pm.isCanceled()) {
return;
protected IWritableIndex getIndex() {
return index;
}
String path= orderedPaths[i];
FileInfo info= codeReaderFactory.createFileInfo(path);
protected int getReadlockCount() {
return 1;
}
protected boolean needToUpdate(String path) throws CoreException {
// file is requested or is not yet indexed.
if (info.isRequested() || info.fFile == null) {
prepareIndexInsertion(path, symbolMap);
}
else {
if (fTrace) {
System.out.println("Indexer: skipping " + path); //$NON-NLS-1$
}
orderedPaths[i]= null;
}
}
boolean isFirstRequest= true;
boolean isFirstAddition= true;
index.acquireWriteLock(1);
try {
for (int i=0; i<orderedPaths.length; i++) {
if (pm.isCanceled())
return;
String path = orderedPaths[i];
if (path != null) {
FileInfo info= codeReaderFactory.createFileInfo(path);
return info.isRequested() || info.fFile == null;
}
protected boolean postAddToIndex(String path, IIndexFile file) throws CoreException {
FileInfo info= codeReaderFactory.createFileInfo(path);
info.fFile= file;
if (info.isRequested()) {
info.setRequested(false);
if (isFirstRequest)
isFirstRequest= false;
else
fTotalSourcesEstimate--;
}
if (fTrace) {
System.out.println("Indexer: adding " + path); //$NON-NLS-1$
}
info.fFile= addToIndex(index, path, symbolMap);
if (isFirstAddition)
isFirstAddition= false;
else
fCompletedHeaders++;
}
}
} finally {
index.releaseWriteLock(1);
}
fCompletedSources++;
}
protected void parseTUs(List sources, List headers, IProgressMonitor monitor) throws CoreException, InterruptedException {
// sources first
Iterator iter;
for (iter= sources.iterator(); iter.hasNext();) {
if (monitor.isCanceled())
return;
ITranslationUnit tu = (ITranslationUnit) iter.next();
parseTU(tu, monitor);
}
// headers with context
for (iter= headers.iterator(); iter.hasNext();) {
if (monitor.isCanceled())
return;
ITranslationUnit tu = (ITranslationUnit) iter.next();
FileInfo info= codeReaderFactory.createFileInfo(tu);
// check if header was handled while parsing a source
if (!info.isRequested()) {
iter.remove();
}
else if (info.fFile != null) {
ITranslationUnit context= findContext(index, info.fFile.getLocation());
if (context != null) {
parseTU(context, monitor);
}
}
}
// headers without context
if (getIndexAllFiles()) {
for (iter= headers.iterator(); iter.hasNext();) {
if (monitor.isCanceled())
return;
ITranslationUnit tu = (ITranslationUnit) iter.next();
FileInfo info= codeReaderFactory.createFileInfo(tu);
// check if header was handled while parsing a source
if (!info.isRequested()) {
iter.remove();
}
else {
parseTU(tu, monitor);
}
}
return true;
}
return false;
}
}

View file

@ -54,7 +54,8 @@ class PDOMFullHandleDelta extends PDOMFullIndexerJob {
}
}
registerTUsInReaderFactory(sources, headers, true);
registerTUsInReaderFactory(sources);
registerTUsInReaderFactory(headers);
Iterator i= removed.iterator();
while (i.hasNext()) {

View file

@ -15,13 +15,13 @@ package org.eclipse.cdt.internal.core.pdom.indexer.full;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
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.IASTTranslationUnit;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.index.IWritableIndex;
import org.eclipse.cdt.internal.core.index.IWritableIndexManager;
@ -35,10 +35,13 @@ import org.eclipse.core.runtime.IProgressMonitor;
*
*/
abstract class PDOMFullIndexerJob extends PDOMIndexerTask implements IPDOMIndexerTask {
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 filePathsToParse= null;
private Map filePathsToParse= new HashMap();
public PDOMFullIndexerJob(PDOMFullIndexer indexer) throws CoreException {
this.indexer = indexer;
@ -52,65 +55,12 @@ abstract class PDOMFullIndexerJob extends PDOMIndexerTask implements IPDOMIndexe
this.index = ((IWritableIndexManager) CCorePlugin.getIndexManager()).getWritableIndex(indexer.getProject());
}
protected void registerTUsInReaderFactory(Collection sources, Collection headers,
boolean requireHeaders) throws CoreException {
protected void registerTUsInReaderFactory(Collection sources) throws CoreException {
filePathsToParse= new HashMap();
for (Iterator iter = sources.iterator(); iter.hasNext();) {
ITranslationUnit tu = (ITranslationUnit) iter.next();
filePathsToParse.put(tu.getLocation().toOSString(), Boolean.TRUE);
}
Boolean required= Boolean.valueOf(requireHeaders);
for (Iterator iter = headers.iterator(); iter.hasNext();) {
ITranslationUnit tu = (ITranslationUnit) iter.next();
filePathsToParse.put(tu.getLocation().toOSString(), required);
}
}
protected void parseTUs(Collection sources, Collection headers, IProgressMonitor monitor) throws CoreException, InterruptedException {
// sources first
Iterator iter;
for (iter = sources.iterator(); iter.hasNext();) {
if (monitor.isCanceled())
return;
ITranslationUnit tu = (ITranslationUnit) iter.next();
String path = tu.getLocation().toOSString();
if (filePathsToParse.get(path) != null) {
parseTU(tu, monitor);
}
}
// headers with context
for (iter = headers.iterator(); iter.hasNext();) {
if (monitor.isCanceled())
return;
ITranslationUnit tu = (ITranslationUnit) iter.next();
String path = tu.getLocation().toOSString();
if (filePathsToParse.get(path)==null) {
iter.remove();
}
else {
ITranslationUnit context= findContext(index, path);
if (context != null) {
parseTU(context, monitor);
}
}
}
// headers without context
if (getIndexAllFiles()) {
for (iter = headers.iterator(); iter.hasNext();) {
if (monitor.isCanceled())
return;
ITranslationUnit tu = (ITranslationUnit) iter.next();
String path = tu.getLocation().toOSString();
if (filePathsToParse.get(path)==null) {
iter.remove();
}
else {
parseTU(tu, monitor);
}
}
filePathsToParse.put(tu.getLocation().toOSString(), REQUIRED);
}
}
@ -128,51 +78,27 @@ abstract class PDOMFullIndexerJob extends PDOMIndexerTask implements IPDOMIndexe
addSymbols(ast, pm);
}
protected void addSymbols(IASTTranslationUnit ast, IProgressMonitor pm) throws InterruptedException, CoreException {
// Add in the includes
final LinkedHashMap symbolMap= new LinkedHashMap();
String[] orderedPaths= extractSymbols(ast, filePathsToParse.keySet(), symbolMap);
for (int i=0; i<orderedPaths.length; i++) {
if (pm.isCanceled()) {
return;
}
String path= orderedPaths[i];
prepareIndexInsertion(path, symbolMap);
protected IWritableIndex getIndex() {
return index;
}
boolean isFirstRequest= true;
boolean isFirstAddition= true;
index.acquireWriteLock(0);
try {
for (int i=0; i<orderedPaths.length; i++) {
if (pm.isCanceled())
return;
String path = orderedPaths[i];
Boolean required= (Boolean) filePathsToParse.remove(path);
if (required != null) {
if (required.booleanValue()) {
if (isFirstRequest)
isFirstRequest= false;
else
fTotalSourcesEstimate--;
protected int getReadlockCount() {
return 0;
}
if (fTrace)
System.out.println("Indexer: adding " + path); //$NON-NLS-1$
protected boolean needToUpdate(String path) throws CoreException {
Object required= filePathsToParse.get(path);
if (required == null) {
required= MISSING;
filePathsToParse.put(path, required);
}
return required != SKIP;
}
addToIndex(index, path, symbolMap);
if (isFirstAddition)
isFirstAddition= false;
else
fCompletedHeaders++;
}
}
} finally {
index.releaseWriteLock(0);
}
fCompletedSources++;
protected boolean postAddToIndex(String path, IIndexFile file) throws CoreException {
Object required= filePathsToParse.get(path);
filePathsToParse.put(path, SKIP);
return required == REQUIRED;
}
}

View file

@ -34,15 +34,12 @@ class PDOMFullReindex extends PDOMFullIndexerJob {
public void run(final IProgressMonitor monitor) {
try {
long start = System.currentTimeMillis();
boolean allfiles= getIndexAllFiles();
List headers= new ArrayList();
boolean allFiles= getIndexAllFiles();
List sources= new ArrayList();
List headers= new ArrayList();
collectSources(indexer.getProject(), sources, headers, allfiles);
fTotalSourcesEstimate= sources.size();
if (allfiles)
fTotalSourcesEstimate+= headers.size();
collectSources(indexer.getProject(), sources, allFiles ? headers : null, allFiles);
fTotalSourcesEstimate= sources.size() + headers.size();
setupIndexAndReaderFactory();
clearIndex(index);
@ -51,10 +48,7 @@ class PDOMFullReindex extends PDOMFullIndexerJob {
return;
}
registerTUsInReaderFactory(sources, headers, allfiles);
if (!allfiles)
headers.clear();
registerTUsInReaderFactory(sources);
parseTUs(sources, headers, monitor);
String showTimings = Platform.getDebugOption(CCorePlugin.PLUGIN_ID