1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-13 11:15:38 +02:00

Index based code reader factory needs to respect the fallback factory, bug 275600.

This commit is contained in:
Markus Schorn 2009-05-13 16:05:51 +00:00
parent d791eec58b
commit ee628f9a74
20 changed files with 295 additions and 172 deletions

View file

@ -27,7 +27,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode; import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
@ -66,6 +65,7 @@ import org.eclipse.cdt.core.parser.ParserUtil;
import org.eclipse.cdt.core.parser.ScannerInfo; import org.eclipse.cdt.core.parser.ScannerInfo;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.internal.core.dom.AbstractCodeReaderFactory;
import org.eclipse.cdt.internal.core.dom.NullCodeReaderFactory; import org.eclipse.cdt.internal.core.dom.NullCodeReaderFactory;
import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory; import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory;
import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory; import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory;
@ -826,7 +826,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
ILanguage language= configureWith.getLanguage(); ILanguage language= configureWith.getLanguage();
fLanguageOfContext= language; fLanguageOfContext= language;
if (language != null) { if (language != null) {
ICodeReaderFactory crf= getCodeReaderFactory(style, index, language.getLinkageID()); AbstractCodeReaderFactory crf= getCodeReaderFactory(style, index, language.getLinkageID());
int options= 0; int options= 0;
if ((style & AST_SKIP_FUNCTION_BODIES) != 0) { if ((style & AST_SKIP_FUNCTION_BODIES) != 0) {
options |= ILanguage.OPTION_SKIP_FUNCTION_BODIES; options |= ILanguage.OPTION_SKIP_FUNCTION_BODIES;
@ -852,11 +852,11 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
return null; return null;
} }
private ICodeReaderFactory getCodeReaderFactory(int style, IIndex index, int linkageID) { private AbstractCodeReaderFactory getCodeReaderFactory(int style, IIndex index, int linkageID) {
final ICProject cprj= getCProject(); final ICProject cprj= getCProject();
final ProjectIndexerInputAdapter pathResolver = new ProjectIndexerInputAdapter(cprj); final ProjectIndexerInputAdapter pathResolver = new ProjectIndexerInputAdapter(cprj);
final ProjectIndexerIncludeResolutionHeuristics heuristics = new ProjectIndexerIncludeResolutionHeuristics(cprj.getProject(), pathResolver); final ProjectIndexerIncludeResolutionHeuristics heuristics = new ProjectIndexerIncludeResolutionHeuristics(cprj.getProject(), pathResolver);
ICodeReaderFactory codeReaderFactory; AbstractCodeReaderFactory codeReaderFactory;
if ((style & AST_SKIP_NONINDEXED_HEADERS) != 0) { if ((style & AST_SKIP_NONINDEXED_HEADERS) != 0) {
codeReaderFactory= NullCodeReaderFactory.getInstance(); codeReaderFactory= NullCodeReaderFactory.getInstance();
} else { } else {
@ -935,7 +935,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
ILanguage language= configureWith.getLanguage(); ILanguage language= configureWith.getLanguage();
fLanguageOfContext= language; fLanguageOfContext= language;
if (language != null) { if (language != null) {
ICodeReaderFactory crf= getCodeReaderFactory(style, index, language.getLinkageID()); AbstractCodeReaderFactory crf= getCodeReaderFactory(style, index, language.getLinkageID());
return language.getCompletionNode(reader, scanInfo, crf, index, ParserUtil.getParserLogService(), offset); return language.getCompletionNode(reader, scanInfo, crf, index, ParserUtil.getParserLogService(), offset);
} }
return null; return null;
@ -952,9 +952,9 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
IResource res= getResource(); IResource res= getResource();
try { try {
if (res instanceof IFile) if (res instanceof IFile)
return InternalParserUtil.createWorkspaceFileReader(location.toOSString(), (IFile) res); return InternalParserUtil.createWorkspaceFileReader(location.toOSString(), (IFile) res, null);
else else
return InternalParserUtil.createExternalFileReader(location.toOSString()); return InternalParserUtil.createExternalFileReader(location.toOSString(), null);
} catch (CoreException e) { } catch (CoreException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
} catch (IOException e) { } catch (IOException e) {

View file

@ -10,6 +10,11 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.parser; package org.eclipse.cdt.core.parser;
import java.io.IOException;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.core.runtime.CoreException;
/** /**
* This is the interface to a cache for CodeReaders. * This is the interface to a cache for CodeReaders.
* *
@ -31,6 +36,20 @@ public interface ICodeReaderCache {
*/ */
public CodeReader get(String key); public CodeReader get(String key);
/**
* Retrieves the CodeReader corresponding to the key specified that represents the
* path for that CodeReader. If no CodeReader is found in the cache then a new CodeReader
* is created for the ifl and then returned.
*
* @param key the path corresponding to the CodeReader, generally:
* fileToParse.getLocation().toOSString()
* @return the CodeReader corresponding to the path specified by the key
* @throws IOException
* @throws CoreException
* @since 5.1
*/
public CodeReader get(String key, IIndexFileLocation ifl) throws CoreException, IOException;
/** /**
* Used to remove the CodeReader corresponding to the path specified by key from the cache. * Used to remove the CodeReader corresponding to the path specified by key from the cache.
* *

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others. * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -12,17 +12,18 @@ package org.eclipse.cdt.internal.core.dom.parser;
import java.io.IOException; import java.io.IOException;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.ICodeReaderCache; import org.eclipse.cdt.core.parser.ICodeReaderCache;
import org.eclipse.cdt.internal.core.parser.InternalParserUtil;
import org.eclipse.core.runtime.CoreException;
/** /**
* This is an empty implementation of the ICodeReaderCache interface. It is used to implement a * This is an empty implementation of the ICodeReaderCache interface. It is used to implement a
* cache for the interface that isn't actually a cache, but rather always creates new CodeReaders * cache for the interface that isn't actually a cache, but rather always creates new CodeReaders
* everytime a CodeReader is retrieved. * every time a CodeReader is retrieved.
* *
* This cache is not optimized to be run from within Eclipse (i.e. it ignores IResources). * This cache is not optimized to be run from within Eclipse (i.e. it ignores IResources).
*
* @author dsteffle
*/ */
public class EmptyCodeReaderCache implements ICodeReaderCache { public class EmptyCodeReaderCache implements ICodeReaderCache {
@ -37,6 +38,10 @@ public class EmptyCodeReaderCache implements ICodeReaderCache {
return null; return null;
} }
public CodeReader get(String key, IIndexFileLocation ifl) throws CoreException, IOException {
return InternalParserUtil.createCodeReader(ifl, null);
}
/** /**
* Returns null. * Returns null.
*/ */
@ -55,5 +60,4 @@ public class EmptyCodeReaderCache implements ICodeReaderCache {
// nothing to do // nothing to do
} }
} }

View file

@ -22,7 +22,6 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexFile; import org.eclipse.cdt.core.index.IIndexFile;
@ -55,19 +54,19 @@ public final class IndexBasedCodeReaderFactory extends AbstractCodeReaderFactory
private int fLinkage; private int fLinkage;
private Set<IIndexFileLocation> fIncludedFiles= new HashSet<IIndexFileLocation>(); private Set<IIndexFileLocation> fIncludedFiles= new HashSet<IIndexFileLocation>();
/** The fall-back code reader factory used in case a header file is not indexed */ /** The fall-back code reader factory used in case a header file is not indexed */
private final ICodeReaderFactory fFallBackFactory; private final AbstractCodeReaderFactory fFallBackFactory;
private final ASTFilePathResolver fPathResolver; private final ASTFilePathResolver fPathResolver;
private final AbstractIndexerTask fRelatedIndexerTask; private final AbstractIndexerTask fRelatedIndexerTask;
private boolean fSupportFillGapFromContextToHeader= false; private boolean fSupportFillGapFromContextToHeader= false;
public IndexBasedCodeReaderFactory(IIndex index, IIncludeFileResolutionHeuristics heuristics, public IndexBasedCodeReaderFactory(IIndex index, IIncludeFileResolutionHeuristics heuristics,
ASTFilePathResolver pathResolver, int linkage, ICodeReaderFactory fallbackFactory) { ASTFilePathResolver pathResolver, int linkage, AbstractCodeReaderFactory fallbackFactory) {
this(index, heuristics, pathResolver, linkage, fallbackFactory, null); this(index, heuristics, pathResolver, linkage, fallbackFactory, null);
} }
public IndexBasedCodeReaderFactory(IIndex index, IIncludeFileResolutionHeuristics heuristics, public IndexBasedCodeReaderFactory(IIndex index, IIncludeFileResolutionHeuristics heuristics,
ASTFilePathResolver pathResolver, int linkage, ASTFilePathResolver pathResolver, int linkage,
ICodeReaderFactory fallbackFactory, AbstractIndexerTask relatedIndexerTask) { AbstractCodeReaderFactory fallbackFactory, AbstractIndexerTask relatedIndexerTask) {
super(heuristics); super(heuristics);
fIndex= index; fIndex= index;
fFallBackFactory= fallbackFactory; fFallBackFactory= fallbackFactory;
@ -103,6 +102,15 @@ public final class IndexBasedCodeReaderFactory extends AbstractCodeReaderFactory
return ParserUtil.createReader(path, null); return ParserUtil.createReader(path, null);
} }
@Override
public CodeReader createCodeReaderForInclusion(IIndexFileLocation ifl, String astPath) throws CoreException, IOException {
if (fFallBackFactory != null) {
return fFallBackFactory.createCodeReaderForInclusion(ifl, astPath);
}
return InternalParserUtil.createCodeReader(ifl, null);
}
@Deprecated
public CodeReader createCodeReaderForInclusion(String path) { public CodeReader createCodeReaderForInclusion(String path) {
if (fFallBackFactory != null) { if (fFallBackFactory != null) {
return fFallBackFactory.createCodeReaderForInclusion(path); return fFallBackFactory.createCodeReaderForInclusion(path);
@ -157,7 +165,7 @@ public final class IndexBasedCodeReaderFactory extends AbstractCodeReaderFactory
} }
try { try {
CodeReader codeReader= InternalParserUtil.createCodeReader(ifl); CodeReader codeReader= createCodeReaderForInclusion(ifl, path);
if (codeReader != null) { if (codeReader != null) {
IncludeFileContent ifc= new IncludeFileContent(codeReader); IncludeFileContent ifc= new IncludeFileContent(codeReader);
ifc.setIsSource(fPathResolver.isSource(path)); ifc.setIsSource(fPathResolver.isSource(path));

View file

@ -15,7 +15,7 @@ package org.eclipse.cdt.internal.core.indexer;
import java.util.List; import java.util.List;
import org.eclipse.cdt.core.dom.ICodeReaderFactory; import org.eclipse.cdt.internal.core.dom.AbstractCodeReaderFactory;
import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics; import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics;
/** /**
@ -36,7 +36,7 @@ public class StandaloneFastIndexerTask extends StandaloneIndexerTask {
} }
@Override @Override
protected ICodeReaderFactory createReaderFactory() { protected AbstractCodeReaderFactory createReaderFactory() {
return new StandaloneIndexerFallbackReaderFactory(); return new StandaloneIndexerFallbackReaderFactory();
} }

View file

@ -17,10 +17,10 @@ import java.io.File;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
import org.eclipse.cdt.core.index.IIndexLocationConverter; import org.eclipse.cdt.core.index.IIndexLocationConverter;
import org.eclipse.cdt.core.parser.IParserLogService; import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.internal.core.dom.AbstractCodeReaderFactory;
import org.eclipse.cdt.internal.core.index.IIndexFragment; import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.WritableCIndex; import org.eclipse.cdt.internal.core.index.WritableCIndex;
import org.eclipse.cdt.internal.core.pdom.WritablePDOM; import org.eclipse.cdt.internal.core.pdom.WritablePDOM;
@ -42,7 +42,7 @@ import org.eclipse.core.runtime.CoreException;
*/ */
public class StandaloneFullIndexer extends StandaloneIndexer{ public class StandaloneFullIndexer extends StandaloneIndexer{
private ICodeReaderFactory fCodeReaderFactory; private AbstractCodeReaderFactory fCodeReaderFactory;
/** /**
* Create a full indexer. * Create a full indexer.
@ -59,7 +59,7 @@ public class StandaloneFullIndexer extends StandaloneIndexer{
*/ */
@Deprecated @Deprecated
public StandaloneFullIndexer(File writableIndexFile, IIndexLocationConverter converter, Map<String, IPDOMLinkageFactory> linkageFactoryMappings, public StandaloneFullIndexer(File writableIndexFile, IIndexLocationConverter converter, Map<String, IPDOMLinkageFactory> linkageFactoryMappings,
IScannerInfo scanner, ILanguageMapper mapper, IParserLogService log, ICodeReaderFactory codeReaderFactory) throws CoreException { IScannerInfo scanner, ILanguageMapper mapper, IParserLogService log, AbstractCodeReaderFactory codeReaderFactory) throws CoreException {
super(new WritableCIndex(new WritablePDOM(writableIndexFile, converter, linkageFactoryMappings),new IIndexFragment[0]), super(new WritableCIndex(new WritablePDOM(writableIndexFile, converter, linkageFactoryMappings),new IIndexFragment[0]),
false, mapper, log, scanner); false, mapper, log, scanner);
fCodeReaderFactory = codeReaderFactory; fCodeReaderFactory = codeReaderFactory;
@ -78,7 +78,7 @@ public class StandaloneFullIndexer extends StandaloneIndexer{
* @throws CoreException * @throws CoreException
*/ */
public StandaloneFullIndexer(File writableIndexFile, IIndexLocationConverter converter, Map<String, IPDOMLinkageFactory> linkageFactoryMappings, public StandaloneFullIndexer(File writableIndexFile, IIndexLocationConverter converter, Map<String, IPDOMLinkageFactory> linkageFactoryMappings,
IStandaloneScannerInfoProvider scannerProvider, ILanguageMapper mapper, IParserLogService log, ICodeReaderFactory codeReaderFactory) throws CoreException { IStandaloneScannerInfoProvider scannerProvider, ILanguageMapper mapper, IParserLogService log, AbstractCodeReaderFactory codeReaderFactory) throws CoreException {
super(new WritableCIndex(new WritablePDOM(writableIndexFile, converter, linkageFactoryMappings),new IIndexFragment[0]), super(new WritableCIndex(new WritablePDOM(writableIndexFile, converter, linkageFactoryMappings),new IIndexFragment[0]),
false, mapper, log, scannerProvider); false, mapper, log, scannerProvider);
fCodeReaderFactory = codeReaderFactory; fCodeReaderFactory = codeReaderFactory;
@ -89,7 +89,7 @@ public class StandaloneFullIndexer extends StandaloneIndexer{
* Returns the factory that provides CodeReaders for files included * Returns the factory that provides CodeReaders for files included
* by the source code being parsed. * by the source code being parsed.
*/ */
public ICodeReaderFactory getCodeReaderFactory() { public AbstractCodeReaderFactory getCodeReaderFactory() {
return fCodeReaderFactory; return fCodeReaderFactory;
} }

View file

@ -15,7 +15,7 @@ package org.eclipse.cdt.internal.core.indexer;
import java.util.List; import java.util.List;
import org.eclipse.cdt.core.dom.ICodeReaderFactory; import org.eclipse.cdt.internal.core.dom.AbstractCodeReaderFactory;
import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics; import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics;
/** /**
@ -37,7 +37,7 @@ public class StandaloneFullIndexerTask extends StandaloneIndexerTask {
} }
@Override @Override
protected ICodeReaderFactory createReaderFactory() { protected AbstractCodeReaderFactory createReaderFactory() {
return ((StandaloneFullIndexer)fIndexer).getCodeReaderFactory(); return ((StandaloneFullIndexer)fIndexer).getCodeReaderFactory();
} }

View file

@ -14,9 +14,11 @@ package org.eclipse.cdt.internal.core.indexer;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import org.eclipse.cdt.core.dom.ICodeReaderFactory; import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.ICodeReaderCache; import org.eclipse.cdt.core.parser.ICodeReaderCache;
import org.eclipse.cdt.internal.core.dom.AbstractCodeReaderFactory;
import org.eclipse.core.runtime.CoreException;
/** /**
* A factory for CodeReaders construction. * A factory for CodeReaders construction.
@ -30,7 +32,11 @@ import org.eclipse.cdt.core.parser.ICodeReaderCache;
* *
* @since 4.0 * @since 4.0
*/ */
public class StandaloneIndexerFallbackReaderFactory implements ICodeReaderFactory { public class StandaloneIndexerFallbackReaderFactory extends AbstractCodeReaderFactory {
public StandaloneIndexerFallbackReaderFactory() {
super(null);
}
public CodeReader createCodeReaderForInclusion(String path) { public CodeReader createCodeReaderForInclusion(String path) {
try { try {
@ -59,4 +65,9 @@ public class StandaloneIndexerFallbackReaderFactory implements ICodeReaderFactor
public int getUniqueIdentifier() { public int getUniqueIdentifier() {
return 0; return 0;
} }
@Override
public CodeReader createCodeReaderForInclusion(IIndexFileLocation ifl, String astPath) throws CoreException, IOException {
return createCodeReaderForInclusion(astPath);
}
} }

View file

@ -0,0 +1,42 @@
/*******************************************************************************
* Copyright (c) 2005, 2009 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 Corporation - initial API and implementation
* Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser;
import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.internal.core.util.ILRUCacheable;
/**
* This is a wrapper for entries to put into the OverflowingLRUCache (required to determine the
* size of entries relative to the CodeReader's file size).
*
* Although the size of the CodeReaderCache is specified in terms of MB, the actual granularity of
* the cache is KB.
*/
class CodeReaderCacheEntry implements ILRUCacheable {
private static final double CHAR_TO_KB_FACTOR = 1024;
CodeReader reader = null;
int size = 0; // used to specify the size of the CodeReader in terms of KB
public CodeReaderCacheEntry(CodeReader value) {
this.reader = value;
size = (int)Math.ceil(reader.buffer.length / CHAR_TO_KB_FACTOR); // get the size of the file in terms of KB
}
public int getCacheFootprint() {
return size;
}
public CodeReader getCodeReader() {
return reader;
}
}

View file

@ -0,0 +1,90 @@
/*******************************************************************************
* Copyright (c) 2005, 2009 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 Corporation - initial API and implementation
* Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser;
import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.internal.core.util.OverflowingLRUCache;
/**
* This class is a wrapper/implementor class for OverflowingLRUCache.
*
* It uses CodeReaderCacheEntry (which implements ILRUCacheable) to specify that the size of
* the cache should be relative to the size of the entries and not the number of entries.
*/
public class CodeReaderLRUCache extends OverflowingLRUCache<String, CodeReaderCacheEntry> {
/**
* Creates a new CodeReaderLRUCache with a specified initial maximum size.
* @param size the maximum size of the cache in terms of MB
*/
public CodeReaderLRUCache(int size) {
super(); // need to initialize the LRUCache with super() so that the size of the hashtable isn't relative to the size in MB
this.setSpaceLimit(size);
}
// must be overloaded, required to remove entries from the cache
@Override
protected boolean close(LRUCacheEntry<String,CodeReaderCacheEntry> entry) {
Object obj = remove(entry._fKey);
if (obj != null)
return true;
return false;
}
@Override
protected OverflowingLRUCache<String,CodeReaderCacheEntry> newInstance(int size, int overflow) {
return null;
}
/**
* Removes an entry from the cache and returns the entry that was removed if found.
* Otherwise null is returned.
*/
@Override
public CodeReader remove(String key) {
Object removed = removeKey(key);
if (removed instanceof CodeReaderCacheEntry)
return ((CodeReaderCacheEntry)removed).getCodeReader();
return null;
}
/**
* Puts a CodeReader into the cache by wrapping it with a CodeReaderCacheEntry first.
* This way the proper size of the element in the cache can be determined
* via the CodeReaderCacheEntry.
*/
public CodeReader put(String key, CodeReader value) {
CodeReaderCacheEntry entry = new CodeReaderCacheEntry(value);
CodeReaderCacheEntry ret = put(key, entry);
if (ret != null)
return ret.getCodeReader();
return null;
}
/**
* Retrieves a CodeReader from the cache corresponding to the path specified by the key.
*/
public CodeReader get(String key) {
CodeReaderCacheEntry obj = peek(key);
if (obj != null)
return obj.getCodeReader();
return null;
}
}

View file

@ -44,15 +44,22 @@ public class InternalParserUtil extends ParserFactory {
/** /**
* Creates a code reader for an external location, normalizing path to * Creates a code reader for an external location, normalizing path to
* canonical path. * canonical path. The cache is consulted after the path has been normalized.
*/ */
public static CodeReader createExternalFileReader(String externalLocation) throws IOException { public static CodeReader createExternalFileReader(String externalLocation, CodeReaderLRUCache cache) throws IOException {
File includeFile = new File(externalLocation); File includeFile = new File(externalLocation);
if (includeFile.isFile()) { if (includeFile.isFile()) {
//use the canonical path so that in case of non-case-sensitive OSs //use the canonical path so that in case of non-case-sensitive OSs
//the CodeReader always has the same name as the file on disk with //the CodeReader always has the same name as the file on disk with
//no differences in case. //no differences in case.
return new CodeReader(includeFile.getCanonicalPath()); final String path = includeFile.getCanonicalPath();
if (cache != null) {
CodeReader result= cache.get(path);
if (result != null)
return result;
}
return new CodeReader(path);
} }
return null; return null;
} }
@ -61,8 +68,14 @@ public class InternalParserUtil extends ParserFactory {
* Creates a code reader for an external location, normalizing path to * Creates a code reader for an external location, normalizing path to
* canonical path. * canonical path.
*/ */
public static CodeReader createWorkspaceFileReader(String path, IFile file) throws CoreException, IOException{ public static CodeReader createWorkspaceFileReader(String path, IFile file, CodeReaderLRUCache cache) throws CoreException, IOException{
path = normalizePath(path, file); path = normalizePath(path, file);
if (cache != null) {
CodeReader result= cache.get(path);
if (result != null)
return result;
}
InputStream in; InputStream in;
try { try {
in= file.getContents(true); in= file.getContents(true);
@ -86,13 +99,13 @@ public class InternalParserUtil extends ParserFactory {
} }
} }
public static CodeReader createCodeReader(IIndexFileLocation ifl) throws CoreException, IOException { public static CodeReader createCodeReader(IIndexFileLocation ifl, CodeReaderLRUCache cache) throws CoreException, IOException {
String fullPath= ifl.getFullPath(); String fullPath= ifl.getFullPath();
if (fullPath != null) { if (fullPath != null) {
IResource res= ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(fullPath)); IResource res= ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(fullPath));
if (res instanceof IFile) if (res instanceof IFile)
return createWorkspaceFileReader(ifl.getURI().getPath(), (IFile) res); return createWorkspaceFileReader(ifl.getURI().getPath(), (IFile) res, cache);
} }
return createExternalFileReader(ifl.getURI().getPath()); return createExternalFileReader(ifl.getURI().getPath(), cache);
} }
} }

View file

@ -22,7 +22,6 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree;
@ -42,6 +41,7 @@ import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.ParserUtil; import org.eclipse.cdt.core.parser.ParserUtil;
import org.eclipse.cdt.core.parser.ScannerInfo; import org.eclipse.cdt.core.parser.ScannerInfo;
import org.eclipse.cdt.internal.core.dom.AbstractCodeReaderFactory;
import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics; import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics;
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile; import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
import org.eclipse.cdt.internal.core.index.IWritableIndex; import org.eclipse.cdt.internal.core.index.IWritableIndex;
@ -174,7 +174,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
protected IWritableIndex fIndex; protected IWritableIndex fIndex;
private ITodoTaskUpdater fTodoTaskUpdater; private ITodoTaskUpdater fTodoTaskUpdater;
private final boolean fIsFastIndexer; private final boolean fIsFastIndexer;
private ICodeReaderFactory fCodeReaderFactory; private AbstractCodeReaderFactory fCodeReaderFactory;
public AbstractIndexerTask(Object[] filesToUpdate, Object[] filesToRemove, IndexerInputAdapter resolver, boolean fastIndexer) { public AbstractIndexerTask(Object[] filesToUpdate, Object[] filesToRemove, IndexerInputAdapter resolver, boolean fastIndexer) {
super(resolver); super(resolver);
@ -208,7 +208,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
protected abstract IWritableIndex createIndex(); protected abstract IWritableIndex createIndex();
protected abstract IIncludeFileResolutionHeuristics createIncludeHeuristics(); protected abstract IIncludeFileResolutionHeuristics createIncludeHeuristics();
protected abstract ICodeReaderFactory createReaderFactory(); protected abstract AbstractCodeReaderFactory createReaderFactory();
protected abstract AbstractLanguage[] getLanguages(String fileName); protected abstract AbstractLanguage[] getLanguages(String fileName);
protected ITodoTaskUpdater createTodoTaskUpdater() { protected ITodoTaskUpdater createTodoTaskUpdater() {

View file

@ -12,8 +12,8 @@
package org.eclipse.cdt.internal.core.pdom.indexer; package org.eclipse.cdt.internal.core.pdom.indexer;
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.dom.AbstractCodeReaderFactory;
import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics; import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics;
/** /**
@ -26,7 +26,7 @@ class PDOMFastIndexerTask extends PDOMIndexerTask {
} }
@Override @Override
protected ICodeReaderFactory createReaderFactory() { protected AbstractCodeReaderFactory createReaderFactory() {
return null; return null;
} }

View file

@ -12,8 +12,8 @@
package org.eclipse.cdt.internal.core.pdom.indexer; package org.eclipse.cdt.internal.core.pdom.indexer;
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.dom.AbstractCodeReaderFactory;
import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics; import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics;
import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory; import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory;
@ -28,7 +28,7 @@ class PDOMFullIndexerTask extends PDOMIndexerTask {
} }
@Override @Override
protected ICodeReaderFactory createReaderFactory() { protected AbstractCodeReaderFactory createReaderFactory() {
return SavedCodeReaderFactory.createInstance(createIncludeHeuristics()); return SavedCodeReaderFactory.createInstance(createIncludeHeuristics());
} }

View file

@ -16,9 +16,9 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.internal.core.parser.CodeReaderLRUCache;
import org.eclipse.cdt.internal.core.parser.InternalParserUtil; import org.eclipse.cdt.internal.core.parser.InternalParserUtil;
import org.eclipse.cdt.internal.core.util.ILRUCacheable;
import org.eclipse.cdt.internal.core.util.OverflowingLRUCache;
import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeEvent;
@ -159,18 +159,9 @@ public class CodeReaderCache implements ICodeReaderCache {
IResource file = ParserUtil.getResourceForFilename(key); IResource file = ParserUtil.getResourceForFilename(key);
if (file instanceof IFile) { if (file instanceof IFile) {
key= InternalParserUtil.normalizePath(key, (IFile) file); key= InternalParserUtil.normalizePath(key, (IFile) file);
result= cache.get(key); result= InternalParserUtil.createWorkspaceFileReader(key, (IFile) file, cache);
if (result != null)
return result;
result= InternalParserUtil.createWorkspaceFileReader(key, (IFile) file);
} }
key= jfile.getCanonicalPath(); result= InternalParserUtil.createExternalFileReader(key, cache);
result= cache.get(key);
if (result != null)
return result;
result= InternalParserUtil.createExternalFileReader(key);
if (cache.getSpaceLimit() > 0) if (cache.getSpaceLimit() > 0)
put(result); put(result);
@ -182,6 +173,26 @@ public class CodeReaderCache implements ICodeReaderCache {
return null; return null;
} }
/**
* @throws IOException
* @throws CoreException
* @since 5.1
*/
public CodeReader get(String key, IIndexFileLocation ifl) throws CoreException, IOException {
CodeReader result = null;
if (cache.getSpaceLimit() > 0)
result= cache.get(key);
if (result != null)
return result;
result= InternalParserUtil.createCodeReader(ifl, cache);
if (cache.getSpaceLimit() > 0)
put(result);
return result;
}
/** /**
* Put a CodeReader into the Cache. * Put a CodeReader into the Cache.
* @param key * @param key
@ -206,114 +217,6 @@ public class CodeReaderCache implements ICodeReaderCache {
} }
/**
* This is a wrapper for entries to put into the OverflowingLRUCache (required to determine the
* size of entries relative to the CodeReader's file size).
*
* Although the size of the CodeReaderCache is specified in terms of MB, the actual granularity of
* the cache is KB.
*
* @author dsteffle
*
*/
private class CodeReaderCacheEntry implements ILRUCacheable {
private static final double CHAR_TO_KB_FACTOR = 1024;
CodeReader reader = null;
int size = 0; // used to specify the size of the CodeReader in terms of KB
public CodeReaderCacheEntry(CodeReader value) {
this.reader = value;
size = (int)Math.ceil(reader.buffer.length / CHAR_TO_KB_FACTOR); // get the size of the file in terms of KB
}
public int getCacheFootprint() {
return size;
}
public CodeReader getCodeReader() {
return reader;
}
}
/**
* This class is a wrapper/implementor class for OverflowingLRUCache.
*
* It uses CodeReaderCacheEntry (which implements ILRUCacheable) to specify that the size of
* the cache should be relative to the size of the entries and not the number of entries.
*
* @author dsteffle
*
*/
private class CodeReaderLRUCache extends OverflowingLRUCache<String, CodeReaderCacheEntry> {
/**
* Creates a new CodeReaderLRUCache with a specified initial maximum size.
* @param size the maximum size of the cache in terms of MB
*/
public CodeReaderLRUCache(int size) {
super(); // need to initialize the LRUCache with super() so that the size of the hashtable isn't relative to the size in MB
this.setSpaceLimit(size);
}
// must be overloaded, required to remove entries from the cache
@Override
protected boolean close(LRUCacheEntry<String,CodeReaderCacheEntry> entry) {
Object obj = remove(entry._fKey);
if (obj != null)
return true;
return false;
}
@Override
protected OverflowingLRUCache<String,CodeReaderCacheEntry> newInstance(int size, int overflow) {
return null;
}
/**
* Removes an entry from the cache and returns the entry that was removed if found.
* Otherwise null is returned.
*/
@Override
public CodeReader remove(String key) {
Object removed = removeKey(key);
if (removed instanceof CodeReaderCacheEntry)
return ((CodeReaderCacheEntry)removed).getCodeReader();
return null;
}
/**
* Puts a CodeReader into the cache by wrapping it with a CodeReaderCacheEntry first.
* This way the proper size of the element in the cache can be determined
* via the CodeReaderCacheEntry.
*/
public CodeReader put(String key, CodeReader value) {
CodeReaderCacheEntry entry = new CodeReaderCacheEntry(value);
CodeReaderCacheEntry ret = put(key, entry);
if (ret != null)
return ret.getCodeReader();
return null;
}
/**
* Retrieves a CodeReader from the cache corresponding to the path specified by the key.
*/
public CodeReader get(String key) {
CodeReaderCacheEntry obj = peek(key);
if (obj != null)
return obj.getCodeReader();
return null;
}
}
/** /**
* Removes the CodeReader from the cache corresponding to the path specified by the key and * Removes the CodeReader from the cache corresponding to the path specified by the key and
* returns the CodeReader that was removed. If no CodeReader is removed then null is returned. * returns the CodeReader that was removed. If no CodeReader is removed then null is returned.

View file

@ -74,9 +74,9 @@ public class ParserUtil
if (buffer != null) if (buffer != null)
return new CodeReader(InternalParserUtil.normalizePath(path, (IFile) file), buffer); return new CodeReader(InternalParserUtil.normalizePath(path, (IFile) file), buffer);
} }
return InternalParserUtil.createWorkspaceFileReader(path, (IFile) file); return InternalParserUtil.createWorkspaceFileReader(path, (IFile) file, null);
} }
return InternalParserUtil.createExternalFileReader(path); return InternalParserUtil.createExternalFileReader(path, null);
} catch (CoreException ce) { } catch (CoreException ce) {
} catch (IOException e) { } catch (IOException e) {
} catch (IllegalStateException e) { } catch (IllegalStateException e) {

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others. * Copyright (c) 2008, 2009 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -10,7 +10,12 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom; package org.eclipse.cdt.internal.core.dom;
import java.io.IOException;
import org.eclipse.cdt.core.dom.ICodeReaderFactory; import org.eclipse.cdt.core.dom.ICodeReaderFactory;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IAdaptable;
/** /**
@ -31,4 +36,6 @@ public abstract class AbstractCodeReaderFactory implements ICodeReaderFactory, I
} }
return null; return null;
} }
public abstract CodeReader createCodeReaderForInclusion(IIndexFileLocation ifl, String astPath) throws CoreException, IOException;
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007, 2008 Wind River Systems, Inc. and others. * Copyright (c) 2007, 2009 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -10,7 +10,7 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom; package org.eclipse.cdt.internal.core.dom;
import org.eclipse.cdt.core.dom.ICodeReaderFactory; import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.ICodeReaderCache; import org.eclipse.cdt.core.parser.ICodeReaderCache;
@ -22,9 +22,9 @@ import org.eclipse.cdt.core.parser.ICodeReaderCache;
public class NullCodeReaderFactory extends AbstractCodeReaderFactory { public class NullCodeReaderFactory extends AbstractCodeReaderFactory {
private static final char[] EMPTY_CHARS = new char[0]; private static final char[] EMPTY_CHARS = new char[0];
private static final ICodeReaderFactory INSTANCE= new NullCodeReaderFactory(); private static final NullCodeReaderFactory INSTANCE= new NullCodeReaderFactory();
public static ICodeReaderFactory getInstance() { public static NullCodeReaderFactory getInstance() {
return INSTANCE; return INSTANCE;
} }
@ -39,6 +39,12 @@ public class NullCodeReaderFactory extends AbstractCodeReaderFactory {
return new CodeReader(path, EMPTY_CHARS); return new CodeReader(path, EMPTY_CHARS);
} }
@Override
public CodeReader createCodeReaderForInclusion(IIndexFileLocation ifl, String astPath) {
return new CodeReader(astPath, EMPTY_CHARS);
}
/* /*
* @see org.eclipse.cdt.core.dom.ICodeReaderFactory#createCodeReaderForTranslationUnit(java.lang.String) * @see org.eclipse.cdt.core.dom.ICodeReaderFactory#createCodeReaderForTranslationUnit(java.lang.String)
*/ */

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -10,10 +10,12 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom; package org.eclipse.cdt.internal.core.dom;
import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import org.eclipse.cdt.core.dom.CDOM; import org.eclipse.cdt.core.dom.CDOM;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.core.model.IWorkingCopyProvider; import org.eclipse.cdt.core.model.IWorkingCopyProvider;
@ -21,6 +23,7 @@ import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.ICodeReaderCache; import org.eclipse.cdt.core.parser.ICodeReaderCache;
import org.eclipse.cdt.core.parser.ParserUtil; import org.eclipse.cdt.core.parser.ParserUtil;
import org.eclipse.cdt.internal.core.parser.EmptyIterator; import org.eclipse.cdt.internal.core.parser.EmptyIterator;
import org.eclipse.core.runtime.CoreException;
/** /**
* @author jcamelon * @author jcamelon
@ -71,6 +74,13 @@ public class PartialWorkingCopyCodeReaderFactory extends AbstractCodeReaderFacto
return cache.get( path ); return cache.get( path );
} }
@Override
public CodeReader createCodeReaderForInclusion(IIndexFileLocation ifl, String astPath)
throws CoreException, IOException {
return cache.get(astPath, ifl);
}
protected Iterator<IWorkingCopy> createWorkingCopyIterator() { protected Iterator<IWorkingCopy> createWorkingCopyIterator() {
if( provider == null ) return EmptyIterator.empty(); if( provider == null ) return EmptyIterator.empty();
return Arrays.asList( provider.getWorkingCopies() ).iterator(); return Arrays.asList( provider.getWorkingCopies() ).iterator();

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -10,12 +10,16 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom; package org.eclipse.cdt.internal.core.dom;
import java.io.IOException;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.CDOM; import org.eclipse.cdt.core.dom.CDOM;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.CodeReaderCache; import org.eclipse.cdt.core.parser.CodeReaderCache;
import org.eclipse.cdt.core.parser.ICodeReaderCache; import org.eclipse.cdt.core.parser.ICodeReaderCache;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Preferences; import org.eclipse.core.runtime.Preferences;
/** /**
@ -90,6 +94,12 @@ public class SavedCodeReaderFactory extends AbstractCodeReaderFactory {
return cache.get(path); return cache.get(path);
} }
@Override
public CodeReader createCodeReaderForInclusion(IIndexFileLocation ifl, String astPath)
throws CoreException, IOException {
return cache.get(astPath, ifl);
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ICodeReaderFactory#createCodeReaderForInclusion(java.lang.String) * @see org.eclipse.cdt.core.dom.ICodeReaderFactory#createCodeReaderForInclusion(java.lang.String)
*/ */