mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Obtain timestamp and file size _before_ reading the file contents to
protect the index from getting stale.
This commit is contained in:
parent
d9caf9f42b
commit
3c572e9afb
13 changed files with 272 additions and 88 deletions
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2009 IBM Corporation and others.
|
||||
* Copyright (c) 2004, 2012 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
|
||||
|
@ -8,15 +8,15 @@
|
|||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast;
|
||||
|
||||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
|
||||
|
||||
/**
|
||||
* This interface represent a preprocessor #include statement.
|
||||
* This interface represents a preprocessor #include statement.
|
||||
*
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
|
@ -76,12 +76,30 @@ public interface IASTPreprocessorIncludeStatement extends IASTPreprocessorStatem
|
|||
*/
|
||||
public ISignificantMacros[] getLoadedVersions();
|
||||
|
||||
/**
|
||||
* Returns the modification time of the included file, or -1 if the file was not read.
|
||||
* @since 5.4
|
||||
*/
|
||||
public long getIncludedFileTimestamp();
|
||||
|
||||
/**
|
||||
* Returns the size of the included file, or -1 if the file was not read.
|
||||
* @since 5.4
|
||||
*/
|
||||
public long getIncludedFileSize();
|
||||
|
||||
/**
|
||||
* Returns a hash-code for the contents of the file included, or <code>0</code>
|
||||
* if the content has not been parsed.
|
||||
* @since 5.4
|
||||
*/
|
||||
public long getContentsHash();
|
||||
public long getIncludedFileContentsHash();
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if I/O errors were encountered while reading the included file.
|
||||
* @since 5.4
|
||||
*/
|
||||
public boolean isErrorInIncludedFile();
|
||||
|
||||
/**
|
||||
* Returns true, if an attempt will be or has been made to create AST for the target
|
||||
|
|
|
@ -29,11 +29,37 @@ import org.eclipse.core.runtime.IPath;
|
|||
* @since 5.2
|
||||
*/
|
||||
public abstract class FileContent {
|
||||
/** @since 5.4 */
|
||||
public static final long NULL_TIMESTAMP = -1;
|
||||
/** @since 5.4 */
|
||||
public static final long NULL_FILE_SIZE = -1;
|
||||
|
||||
/**
|
||||
* Returns the location of this file content as it will appear in {@link IASTFileLocation#getFileName()}
|
||||
*/
|
||||
public abstract String getFileLocation();
|
||||
|
||||
/**
|
||||
* Returns the modification time of the file containing the content or NULL_TIMESTAMP if
|
||||
* the content does not originate from a file. A zero value may be returned if there was
|
||||
* an I/O error.
|
||||
* @since 5.4
|
||||
*/
|
||||
public abstract long getTimestamp();
|
||||
|
||||
/**
|
||||
* Returns the size of the file, or NULL_FILE_SIZE if the content does not originate from
|
||||
* a file. A zero value may be returned if there was an I/O error.
|
||||
* @since 5.4
|
||||
*/
|
||||
public abstract long getFileSize();
|
||||
|
||||
/**
|
||||
* Returns {@code true} if there were I/O errors while retrieving contents of this file.
|
||||
* @since 5.4
|
||||
*/
|
||||
public abstract boolean hasError();
|
||||
|
||||
/**
|
||||
* Returns a 64-bit hash value of the file contents.
|
||||
*/
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContent;
|
|||
import org.eclipse.cdt.internal.core.resources.PathCanonicalizationStrategy;
|
||||
import org.eclipse.cdt.utils.UNCPathConverter;
|
||||
import org.eclipse.core.filesystem.EFS;
|
||||
import org.eclipse.core.filesystem.IFileInfo;
|
||||
import org.eclipse.core.filesystem.IFileStore;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
|
@ -152,28 +153,30 @@ public class InternalParserUtil extends ParserFactory {
|
|||
String path= file.getLocationURI().getPath();
|
||||
path= normalizePath(path, file);
|
||||
|
||||
InputStream in;
|
||||
InputStream input;
|
||||
try {
|
||||
in= file.getContents(true);
|
||||
if (!(in instanceof FileInputStream)) {
|
||||
/*
|
||||
* In general, non-local file-systems will not use FileInputStream. Instead make a
|
||||
* cached copy of the file and open an input stream to that.
|
||||
*/
|
||||
IFileStore store = EFS.getStore(file.getLocationURI());
|
||||
IFileInfo fileInfo = store.fetchInfo();
|
||||
input= file.getContents(true);
|
||||
if (!(input instanceof FileInputStream)) {
|
||||
/*
|
||||
* In general, non-local file-systems will not use FileInputStream.
|
||||
* Instead make a cached copy of the file and open an input stream to that.
|
||||
*/
|
||||
File fileCache = store.toLocalFile(EFS.CACHE, null);
|
||||
try {
|
||||
in = new FileInputStream(fileCache);
|
||||
input = new FileInputStream(fileCache);
|
||||
} catch (FileNotFoundException e) {
|
||||
CCorePlugin.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
try {
|
||||
return createFileContent(path, file.getCharset(), in);
|
||||
return createFileContent(path, file.getCharset(), input,
|
||||
fileInfo.getLastModified(), fileInfo.getLength());
|
||||
} finally {
|
||||
try {
|
||||
in.close();
|
||||
input.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
@ -215,6 +218,8 @@ public class InternalParserUtil extends ParserFactory {
|
|||
}
|
||||
}
|
||||
if (includeFile != null && includeFile.isFile()) {
|
||||
long timestamp = includeFile.lastModified();
|
||||
long fileSize = includeFile.length();
|
||||
FileInputStream in;
|
||||
try {
|
||||
in = new FileInputStream(includeFile);
|
||||
|
@ -223,7 +228,7 @@ public class InternalParserUtil extends ParserFactory {
|
|||
return null;
|
||||
}
|
||||
try {
|
||||
return createFileContent(path, encoding, in);
|
||||
return createFileContent(path, encoding, in, timestamp, fileSize);
|
||||
} finally {
|
||||
try {
|
||||
in.close();
|
||||
|
@ -234,13 +239,14 @@ public class InternalParserUtil extends ParserFactory {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static InternalFileContent createFileContent(String path, String charset, InputStream in) {
|
||||
private static InternalFileContent createFileContent(String path, String charset, InputStream in,
|
||||
long fileTimestamp, long fileSize) {
|
||||
try {
|
||||
AbstractCharArray chars= FileCharArray.create(path, charset, in);
|
||||
if (chars == null)
|
||||
return null;
|
||||
|
||||
return new InternalFileContent(path, chars);
|
||||
return new InternalFileContent(path, chars, fileTimestamp, fileSize);
|
||||
} catch (IOException e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007, 2011 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2007, 2012 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
|
||||
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
|
@ -294,7 +295,10 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
|
|||
private boolean fCreatesAST;
|
||||
private ISignificantMacros fSignificantMacros;
|
||||
private ISignificantMacros[] fLoadedVersions = NO_VERSIONS;
|
||||
private long fContentsHash;
|
||||
private long fIncludedFileContentsHash;
|
||||
private long fIncludedFileTimestamp = -1;
|
||||
private long fIncludedFileSize;
|
||||
private boolean fErrorInIncludedFile;
|
||||
|
||||
public ASTInclusionStatement(IASTTranslationUnit parent,
|
||||
int startNumber, int nameStartNumber, int nameEndNumber, int endNumber,
|
||||
|
@ -388,17 +392,56 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
|
|||
}
|
||||
|
||||
@Override
|
||||
public long getContentsHash() {
|
||||
public long getIncludedFileTimestamp() {
|
||||
if (fNominationDelegate != null) {
|
||||
return 0;
|
||||
}
|
||||
return fContentsHash;
|
||||
return fIncludedFileTimestamp;
|
||||
}
|
||||
|
||||
public void setContentsHash(long hash) {
|
||||
public void setIncludedFileTimestamp(long timestamp) {
|
||||
assert fNominationDelegate == null;
|
||||
fIncludedFileTimestamp= timestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getIncludedFileSize() {
|
||||
if (fNominationDelegate != null) {
|
||||
return 0;
|
||||
}
|
||||
return fIncludedFileSize;
|
||||
}
|
||||
|
||||
public void setIncludedFileSize(long size) {
|
||||
assert fNominationDelegate == null;
|
||||
fIncludedFileSize= size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getIncludedFileContentsHash() {
|
||||
if (fNominationDelegate != null) {
|
||||
return 0;
|
||||
}
|
||||
return fIncludedFileContentsHash;
|
||||
}
|
||||
|
||||
public void setIncludedFileContentsHash(long hash) {
|
||||
assert fNominationDelegate == null;
|
||||
fCreatesAST= true;
|
||||
fContentsHash= hash;
|
||||
fIncludedFileContentsHash= hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isErrorInIncludedFile() {
|
||||
if (fNominationDelegate != null) {
|
||||
return false;
|
||||
}
|
||||
return fErrorInIncludedFile;
|
||||
}
|
||||
|
||||
public void setErrorInIncludedFile(boolean error) {
|
||||
assert fNominationDelegate == null;
|
||||
fErrorInIncludedFile= error;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -53,6 +53,11 @@ public abstract class AbstractCharArray {
|
|||
*/
|
||||
public abstract void arraycopy(int offset, char[] destination, int destinationPos, int length);
|
||||
|
||||
/**
|
||||
* Returns {@code true} if there were I/O errors while retrieving contents of this array.
|
||||
*/
|
||||
public abstract boolean hasError();
|
||||
|
||||
/**
|
||||
* This method is slow. Use only for debugging.
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2011 IBM Corporation and others.
|
||||
* Copyright (c) 2004, 2012 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
|
||||
|
@ -1487,7 +1487,10 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
detectIncludeGuard(path, source, fctx);
|
||||
fCurrentContext= fctx;
|
||||
stmt= ctx.getInclusionStatement();
|
||||
stmt.setContentsHash(source.getContentsHash());
|
||||
stmt.setIncludedFileTimestamp(fi.getTimestamp());
|
||||
stmt.setIncludedFileSize(fi.getFileSize());
|
||||
stmt.setIncludedFileContentsHash(source.getContentsHash());
|
||||
stmt.setErrorInIncludedFile(source.hasError());
|
||||
if (!fCurrentContext.isPragmaOnce()) {
|
||||
// Track the loaded version count, even in a non-pragma-once context.
|
||||
loadedVerisons= fFileContentProvider.getLoadedVersions(path);
|
||||
|
|
|
@ -55,6 +55,11 @@ public final class CharArray extends AbstractCharArray {
|
|||
return offset < fArray.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasError() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getContentsHash() {
|
||||
if (hash64 == 0 && fArray.length != 0) {
|
||||
|
|
|
@ -30,7 +30,8 @@ import org.eclipse.cdt.core.CCorePlugin;
|
|||
public class FileCharArray extends LazyCharArray {
|
||||
private static final String UTF8_CHARSET_NAME = "UTF-8"; //$NON-NLS-1$
|
||||
|
||||
public static AbstractCharArray create(String fileName, String charSet, InputStream in) throws IOException {
|
||||
public static AbstractCharArray create(String fileName, String charSet, InputStream in)
|
||||
throws IOException {
|
||||
// No support for non-local files.
|
||||
if (!(in instanceof FileInputStream)) {
|
||||
return null;
|
||||
|
@ -48,7 +49,8 @@ public class FileCharArray extends LazyCharArray {
|
|||
return new FileCharArray(fileName, charSet);
|
||||
}
|
||||
|
||||
private static AbstractCharArray decodeSmallFile(FileChannel channel, int lsize, String charSet) throws IOException {
|
||||
private static AbstractCharArray decodeSmallFile(FileChannel channel, int lsize, String charSet)
|
||||
throws IOException {
|
||||
ByteBuffer byteBuffer = ByteBuffer.allocate(lsize);
|
||||
channel.read(byteBuffer);
|
||||
byteBuffer.flip();
|
||||
|
@ -80,8 +82,9 @@ public class FileCharArray extends LazyCharArray {
|
|||
return buf;
|
||||
}
|
||||
|
||||
private String fFileName;
|
||||
private String fCharSet;
|
||||
private final String fFileName;
|
||||
private final String fCharSet;
|
||||
private boolean fHasError;
|
||||
private FileChannel fChannel;
|
||||
private long fNextFileOffset;
|
||||
private int fNextCharOffset;
|
||||
|
@ -97,8 +100,9 @@ public class FileCharArray extends LazyCharArray {
|
|||
FileInputStream fis;
|
||||
try {
|
||||
fis = new FileInputStream(fFileName);
|
||||
} catch (FileNotFoundException e1) {
|
||||
} catch (FileNotFoundException e) {
|
||||
// File has been deleted in the meantime
|
||||
fHasError = true;
|
||||
return null;
|
||||
}
|
||||
fChannel= fis.getChannel();
|
||||
|
@ -121,7 +125,8 @@ public class FileCharArray extends LazyCharArray {
|
|||
try {
|
||||
assert fChannel != null;
|
||||
final Charset charset = Charset.forName(fCharSet);
|
||||
final CharsetDecoder decoder = charset.newDecoder().onMalformedInput(CodingErrorAction.REPLACE)
|
||||
final CharsetDecoder decoder = charset.newDecoder()
|
||||
.onMalformedInput(CodingErrorAction.REPLACE)
|
||||
.onUnmappableCharacter(CodingErrorAction.REPLACE);
|
||||
|
||||
int needBytes = 3 + (int) (CHUNK_SIZE * (double) decoder.averageCharsPerByte()); // avoid rounding errors.
|
||||
|
@ -141,7 +146,7 @@ public class FileCharArray extends LazyCharArray {
|
|||
skipUTF8ByteOrderMark(in, fCharSet);
|
||||
}
|
||||
result = decoder.decode(in, dest, eof);
|
||||
fileOffset+= in.position();
|
||||
fileOffset += in.position();
|
||||
} while (result == CoderResult.UNDERFLOW && !eof);
|
||||
|
||||
dest.flip();
|
||||
|
@ -154,14 +159,14 @@ public class FileCharArray extends LazyCharArray {
|
|||
}
|
||||
final char[] chars = extractChars(dest);
|
||||
Chunk chunk = newChunk(fNextFileOffset, fileOffset, fNextCharOffset, chars);
|
||||
fNextFileOffset= fileOffset;
|
||||
fNextCharOffset+= chars.length;
|
||||
|
||||
fNextFileOffset = fileOffset;
|
||||
fNextCharOffset += chars.length;
|
||||
return chunk;
|
||||
} catch (Exception e) {
|
||||
// The file cannot be read
|
||||
CCorePlugin.log(e);
|
||||
fReachedEOF= true;
|
||||
fHasError = true;
|
||||
fReachedEOF = true;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -173,6 +178,7 @@ public class FileCharArray extends LazyCharArray {
|
|||
fis = new FileInputStream(fFileName);
|
||||
} catch (FileNotFoundException e1) {
|
||||
// File has been deleted in the meantime
|
||||
fHasError = true;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
|
@ -180,6 +186,7 @@ public class FileCharArray extends LazyCharArray {
|
|||
decode(channel, chunk.fSourceOffset, chunk.fSourceEndOffset, CharBuffer.wrap(dest));
|
||||
} catch (IOException e) {
|
||||
// File cannot be read
|
||||
fHasError = true;
|
||||
} finally {
|
||||
try {
|
||||
fis.close();
|
||||
|
@ -188,7 +195,8 @@ public class FileCharArray extends LazyCharArray {
|
|||
}
|
||||
}
|
||||
|
||||
private void decode(FileChannel channel, long fileOffset, long fileEndOffset, CharBuffer dest) throws IOException {
|
||||
private void decode(FileChannel channel, long fileOffset, long fileEndOffset, CharBuffer dest)
|
||||
throws IOException {
|
||||
final Charset charset = Charset.forName(fCharSet);
|
||||
final CharsetDecoder decoder = charset.newDecoder()
|
||||
.onMalformedInput(CodingErrorAction.REPLACE)
|
||||
|
@ -205,4 +213,9 @@ public class FileCharArray extends LazyCharArray {
|
|||
}
|
||||
decoder.decode(in, dest, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasError() {
|
||||
return fHasError;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,9 +55,11 @@ public class InternalFileContent extends FileContent {
|
|||
private final String fFileLocation;
|
||||
private final List<FileVersion> fNonPragmaOnceFiles;
|
||||
private boolean fHeuristic;
|
||||
private boolean fIsSource= false;
|
||||
private boolean fIsSource;
|
||||
private List<IIndexFile> fFiles;
|
||||
private IncludeSearchPathElement fFoundOnPath;
|
||||
private final long fTimestamp;
|
||||
private final long fFileSize;
|
||||
|
||||
/**
|
||||
* For skipping include files.
|
||||
|
@ -76,13 +78,16 @@ public class InternalFileContent extends FileContent {
|
|||
fUsingDirectives= null;
|
||||
fSource= null;
|
||||
fNonPragmaOnceFiles= null;
|
||||
fTimestamp= NULL_TIMESTAMP;
|
||||
fFileSize = NULL_FILE_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* For reading include files from disk.
|
||||
* @throws IllegalArgumentException in case the codeReader or its location is <code>null</code>.
|
||||
*/
|
||||
public InternalFileContent(String filePath, AbstractCharArray content) throws IllegalArgumentException {
|
||||
public InternalFileContent(String filePath, AbstractCharArray content, long timestamp,
|
||||
long fileSize) throws IllegalArgumentException {
|
||||
if (content == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
@ -95,6 +100,29 @@ public class InternalFileContent extends FileContent {
|
|||
if (fFileLocation == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
fTimestamp= timestamp;
|
||||
fFileSize = fileSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* For reading in-memory buffers.
|
||||
* @throws IllegalArgumentException in case the codeReader or its location is <code>null</code>.
|
||||
*/
|
||||
public InternalFileContent(String filePath, CharArray content) throws IllegalArgumentException {
|
||||
if (content == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
fKind= InclusionKind.USE_SOURCE;
|
||||
fFileLocation= filePath;
|
||||
fSource= content;
|
||||
fMacroDefinitions= null;
|
||||
fUsingDirectives= null;
|
||||
fNonPragmaOnceFiles= null;
|
||||
if (fFileLocation == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
fTimestamp= NULL_TIMESTAMP;
|
||||
fFileSize = NULL_FILE_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,8 +132,9 @@ public class InternalFileContent extends FileContent {
|
|||
* @param files
|
||||
* @throws IllegalArgumentException in case the fileLocation or the macroDefinitions are <code>null</code>.
|
||||
*/
|
||||
public InternalFileContent(String fileLocation, List<IIndexMacro> macroDefinitions, List<ICPPUsingDirective> usingDirectives,
|
||||
List<IIndexFile> files, List<FileVersion> nonPragmaOnceVersions) {
|
||||
public InternalFileContent(String fileLocation, List<IIndexMacro> macroDefinitions,
|
||||
List<ICPPUsingDirective> usingDirectives, List<IIndexFile> files,
|
||||
List<FileVersion> nonPragmaOnceVersions) {
|
||||
fKind= InclusionKind.FOUND_IN_INDEX;
|
||||
fFileLocation= fileLocation;
|
||||
fSource= null;
|
||||
|
@ -113,6 +142,8 @@ public class InternalFileContent extends FileContent {
|
|||
fMacroDefinitions= macroDefinitions;
|
||||
fFiles= files;
|
||||
fNonPragmaOnceFiles= nonPragmaOnceVersions;
|
||||
fTimestamp= NULL_TIMESTAMP;
|
||||
fFileSize = NULL_FILE_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -130,14 +161,26 @@ public class InternalFileContent extends FileContent {
|
|||
return fFileLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a 64-bit hash value of the file contents.
|
||||
*/
|
||||
@Override
|
||||
public long getTimestamp() {
|
||||
return fTimestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getFileSize() {
|
||||
return fFileSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getContentsHash() {
|
||||
return fSource != null ? fSource.getContentsHash() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasError() {
|
||||
return fSource != null && fSource.hasError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Valid with {@link InclusionKind#USE_SOURCE}.
|
||||
* @return the codeReader or <code>null</code> if kind is different to {@link InclusionKind#USE_SOURCE}.
|
||||
|
|
|
@ -725,7 +725,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
|
||||
@Override
|
||||
protected void reportFileWrittenToIndex(FileInAST file, IIndexFragmentFile ifile) throws CoreException {
|
||||
final FileContentKey fck = file.fFileContentKey;
|
||||
final FileContentKey fck = file.fileContentKey;
|
||||
final IIndexFileLocation location = fck.getLocation();
|
||||
boolean wasCounted= false;
|
||||
UpdateKind kind= UpdateKind.OTHER_HEADER;
|
||||
|
@ -748,7 +748,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
}
|
||||
}
|
||||
fIndexContentCache.remove(ifile);
|
||||
fIndexFilesCache.remove(file.fFileContentKey.getLocation());
|
||||
fIndexFilesCache.remove(file.fileContentKey.getLocation());
|
||||
|
||||
LocationTask task= fOneLinkageTasks.remove(location);
|
||||
if (task != null && task != locTask) {
|
||||
|
@ -978,8 +978,9 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
}
|
||||
|
||||
|
||||
private DependsOnOutdatedFileException parseFile(Object tu, AbstractLanguage lang, IIndexFileLocation ifl, IScannerInfo scanInfo,
|
||||
FileContext ctx, IProgressMonitor pm) throws CoreException, InterruptedException {
|
||||
private DependsOnOutdatedFileException parseFile(Object tu, AbstractLanguage lang,
|
||||
IIndexFileLocation ifl, IScannerInfo scanInfo, FileContext ctx, IProgressMonitor pm)
|
||||
throws CoreException, InterruptedException {
|
||||
IPath path= getLabel(ifl);
|
||||
Throwable th= null;
|
||||
try {
|
||||
|
@ -995,7 +996,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
IASTTranslationUnit ast= createAST(lang, codeReader, scanInfo, isSource, fASTOptions, ctx, pm);
|
||||
fStatistics.fParsingTime += System.currentTimeMillis() - start;
|
||||
if (ast != null) {
|
||||
writeToIndex(lang.getLinkageID(), ast, codeReader.getContentsHash(), ctx, pm);
|
||||
writeToIndex(lang.getLinkageID(), ast, codeReader, ctx, pm);
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
th= e;
|
||||
|
@ -1133,7 +1134,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
throw new IllegalArgumentException("Invalid file content provider"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
private void writeToIndex(final int linkageID, IASTTranslationUnit ast, long fileContentsHash,
|
||||
private void writeToIndex(final int linkageID, IASTTranslationUnit ast, FileContent codeReader,
|
||||
FileContext ctx, IProgressMonitor pm) throws CoreException, InterruptedException {
|
||||
HashSet<FileContentKey> enteredFiles= new HashSet<FileContentKey>();
|
||||
ArrayList<FileInAST> orderedFileKeys= new ArrayList<FileInAST>();
|
||||
|
@ -1149,11 +1150,11 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
|
||||
IIndexFragmentFile newFile= selectIndexFile(linkageID, topIfl, ast.getSignificantMacros());
|
||||
if (ctx != null) {
|
||||
orderedFileKeys.add(new FileInAST(null, topKey, fileContentsHash));
|
||||
orderedFileKeys.add(new FileInAST(topKey, codeReader));
|
||||
// File can be reused
|
||||
ctx.fNewFile= newFile;
|
||||
} else if (newFile == null) {
|
||||
orderedFileKeys.add(new FileInAST(null, topKey, fileContentsHash));
|
||||
orderedFileKeys.add(new FileInAST(topKey, codeReader));
|
||||
}
|
||||
|
||||
FileInAST[] fileKeys= orderedFileKeys.toArray(new FileInAST[orderedFileKeys.size()]);
|
||||
|
@ -1184,7 +1185,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
collectOrderedFileKeys(linkageID, element, enteredFiles, orderedFileKeys);
|
||||
}
|
||||
if (isFirstEntry && selectIndexFile(linkageID, ifl, include.getSignificantMacros()) == null) {
|
||||
orderedFileKeys.add(new FileInAST(include, fileKey, include.getContentsHash()));
|
||||
orderedFileKeys.add(new FileInAST(include, fileKey));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1193,7 +1194,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
LinkageTask map = findRequestMap(linkageID);
|
||||
if (map != null) {
|
||||
for (FileInAST fileKey : fileKeys) {
|
||||
LocationTask locTask = map.find(fileKey.fFileContentKey.getLocation());
|
||||
LocationTask locTask = map.find(fileKey.fileContentKey.getLocation());
|
||||
if (locTask != null) {
|
||||
if (locTask.fCountedUnknownVersion) {
|
||||
locTask.fCountedUnknownVersion= false;
|
||||
|
|
|
@ -37,12 +37,12 @@ public abstract class IndexerInputAdapter extends ASTFilePathResolver {
|
|||
/**
|
||||
* Returns the size of the file in bytes, or 0 if the file does not exist.
|
||||
*/
|
||||
public abstract long getFileSize(IIndexFileLocation ifl);
|
||||
public abstract long getFileSize(IIndexFileLocation location);
|
||||
|
||||
/**
|
||||
* Returns the encoding for the file.
|
||||
*/
|
||||
public abstract String getEncoding(IIndexFileLocation ifl);
|
||||
public abstract String getEncoding(IIndexFileLocation location);
|
||||
|
||||
/**
|
||||
* Create an index location for the given input file.
|
||||
|
@ -70,7 +70,7 @@ public abstract class IndexerInputAdapter extends ASTFilePathResolver {
|
|||
* @param ifl The Location of the file.
|
||||
* @return {@code true} if the file should be indexed unconditionally.
|
||||
*/
|
||||
public abstract boolean isIndexedUnconditionally(IIndexFileLocation ifl);
|
||||
public abstract boolean isIndexedUnconditionally(IIndexFileLocation location);
|
||||
|
||||
/**
|
||||
* Tests whether the file in the index is allowed to be part of an SDK. If not
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007, 2011 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2007, 2012 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
|
||||
|
@ -48,6 +48,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
|
|||
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.parser.FileContent;
|
||||
import org.eclipse.cdt.core.parser.IProblem;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
|
||||
|
@ -67,24 +68,40 @@ import org.eclipse.core.runtime.Status;
|
|||
import org.eclipse.osgi.util.NLS;
|
||||
|
||||
/**
|
||||
* Abstract class to write information from AST
|
||||
* Abstract class to write information from AST.
|
||||
* @since 4.0
|
||||
*/
|
||||
abstract public class PDOMWriter {
|
||||
public static class FileInAST {
|
||||
final IASTPreprocessorIncludeStatement fIncludeStatement;
|
||||
final FileContentKey fFileContentKey;
|
||||
final long fContentsHash;
|
||||
|
||||
public FileInAST(IASTPreprocessorIncludeStatement includeStmt, FileContentKey key, long contentsHash) {
|
||||
fIncludeStatement= includeStmt;
|
||||
fFileContentKey= key;
|
||||
fContentsHash= contentsHash;
|
||||
public static class FileInAST {
|
||||
final IASTPreprocessorIncludeStatement includeStatement;
|
||||
final FileContentKey fileContentKey;
|
||||
final long timestamp;
|
||||
final long fileSize;
|
||||
final long contentsHash;
|
||||
final boolean hasError;
|
||||
|
||||
public FileInAST(IASTPreprocessorIncludeStatement includeStmt, FileContentKey key) {
|
||||
includeStatement= includeStmt;
|
||||
fileContentKey= key;
|
||||
timestamp= includeStmt.getIncludedFileTimestamp();
|
||||
fileSize = includeStmt.getIncludedFileSize();
|
||||
contentsHash= includeStmt.getIncludedFileContentsHash();
|
||||
hasError= includeStmt.isErrorInIncludedFile();
|
||||
}
|
||||
|
||||
public FileInAST(FileContentKey key, FileContent codeReader) {
|
||||
includeStatement= null;
|
||||
fileContentKey= key;
|
||||
timestamp= codeReader.getTimestamp();
|
||||
fileSize= codeReader.getFileSize();
|
||||
contentsHash= codeReader.getContentsHash();
|
||||
hasError= codeReader.hasError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return fFileContentKey.toString();
|
||||
return fileContentKey.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -198,7 +215,7 @@ abstract public class PDOMWriter {
|
|||
|
||||
Data data= new Data(ast, selectedFiles, index);
|
||||
for (FileInAST file : selectedFiles) {
|
||||
data.fSymbolMap.put(file.fIncludeStatement, new Symbols());
|
||||
data.fSymbolMap.put(file.includeStatement, new Symbols());
|
||||
}
|
||||
|
||||
|
||||
|
@ -215,7 +232,7 @@ abstract public class PDOMWriter {
|
|||
if (taskUpdater != null) {
|
||||
Set<IIndexFileLocation> locations= new HashSet<IIndexFileLocation>();
|
||||
for (FileInAST file : selectedFiles) {
|
||||
locations.add(file.fFileContentKey.getLocation());
|
||||
locations.add(file.fileContentKey.getLocation());
|
||||
}
|
||||
taskUpdater.updateTasks(ast.getComments(), locations.toArray(new IIndexFileLocation[locations.size()]));
|
||||
}
|
||||
|
@ -223,7 +240,7 @@ abstract public class PDOMWriter {
|
|||
List<IStatus> stati = data.fStati;
|
||||
String path= null;
|
||||
if (selectedFiles.length > 0) {
|
||||
path= selectedFiles[selectedFiles.length - 1].fFileContentKey.getLocation().getURI().getPath();
|
||||
path= selectedFiles[selectedFiles.length - 1].fileContentKey.getLocation().getURI().getPath();
|
||||
} else {
|
||||
path= ast.getFilePath().toString();
|
||||
}
|
||||
|
@ -252,13 +269,13 @@ abstract public class PDOMWriter {
|
|||
final FileInAST fileInAST= data.fSelectedFiles[i];
|
||||
if (fileInAST != null) {
|
||||
if (fShowActivity) {
|
||||
trace("Indexer: adding " + fileInAST.fFileContentKey.getLocation().getURI()); //$NON-NLS-1$
|
||||
trace("Indexer: adding " + fileInAST.fileContentKey.getLocation().getURI()); //$NON-NLS-1$
|
||||
}
|
||||
Throwable th= null;
|
||||
YieldableIndexLock lock = new YieldableIndexLock(data.fIndex, flushIndex);
|
||||
lock.acquire();
|
||||
try {
|
||||
final boolean isReplacement= ctx != null && fileInAST.fIncludeStatement == null;
|
||||
final boolean isReplacement= ctx != null && fileInAST.includeStatement == null;
|
||||
IIndexFragmentFile ifile= null;
|
||||
if (!isReplacement || newFile == null) {
|
||||
ifile= storeFileInIndex(data, fileInAST, linkageID, lock);
|
||||
|
@ -294,7 +311,7 @@ abstract public class PDOMWriter {
|
|||
}
|
||||
if (th != null) {
|
||||
data.fStati.add(createStatus(NLS.bind(Messages.PDOMWriter_errorWhileParsing,
|
||||
fileInAST.fFileContentKey.getLocation().getURI().getPath()), th));
|
||||
fileInAST.fileContentKey.getLocation().getURI().getPath()), th));
|
||||
}
|
||||
fStatistics.fAddToIndexTime += lock.getCumulativeLockTime();
|
||||
}
|
||||
|
@ -307,7 +324,7 @@ abstract public class PDOMWriter {
|
|||
if (pm.isCanceled()) {
|
||||
return;
|
||||
}
|
||||
Symbols symbols= data.fSymbolMap.get(file.fIncludeStatement);
|
||||
Symbols symbols= data.fSymbolMap.get(file.includeStatement);
|
||||
|
||||
final ArrayList<IASTName[]> names= symbols.fNames;
|
||||
boolean reported= false;
|
||||
|
@ -351,7 +368,7 @@ abstract public class PDOMWriter {
|
|||
if (th != null) {
|
||||
if (!reported) {
|
||||
data.fStati.add(CCorePlugin.createStatus(NLS.bind(Messages.PDOMWriter_errorResolvingName,
|
||||
name.toString(), file.fFileContentKey.getLocation().getURI().getPath()), th));
|
||||
name.toString(), file.fileContentKey.getLocation().getURI().getPath()), th));
|
||||
}
|
||||
reported= true;
|
||||
j.remove();
|
||||
|
@ -516,8 +533,8 @@ abstract public class PDOMWriter {
|
|||
// contents of the old file from the temporary one, then delete the temporary file.
|
||||
// The write lock on the index can be yielded between adding names to the temporary file,
|
||||
// if another thread is waiting for a read lock.
|
||||
final FileContentKey fileKey = astFile.fFileContentKey;
|
||||
final IASTPreprocessorIncludeStatement owner= astFile.fIncludeStatement;
|
||||
final FileContentKey fileKey = astFile.fileContentKey;
|
||||
final IASTPreprocessorIncludeStatement owner= astFile.includeStatement;
|
||||
|
||||
IIndexFileLocation location = fileKey.getLocation();
|
||||
ISignificantMacros significantMacros = fileKey.getSignificantMacros();
|
||||
|
@ -559,9 +576,9 @@ abstract public class PDOMWriter {
|
|||
IncludeInformation[] includeInfoArray= includeInfos.toArray(new IncludeInformation[includeInfos.size()]);
|
||||
index.setFileContent(file, linkageID, includeInfoArray, macros, names, fResolver, lock);
|
||||
}
|
||||
file.setTimestamp(fResolver.getLastModified(location));
|
||||
file.setSizeAndEncodingHashcode(computeFileSizeAndEncodingHashcode(location));
|
||||
file.setContentsHash(astFile.fContentsHash);
|
||||
file.setTimestamp(astFile.hasError ? 0 : astFile.timestamp);
|
||||
file.setSizeAndEncodingHashcode(computeFileSizeAndEncodingHashcode(astFile.fileSize, location));
|
||||
file.setContentsHash(astFile.contentsHash);
|
||||
file = index.commitUncommittedFile();
|
||||
} finally {
|
||||
index.clearUncommittedFile();
|
||||
|
@ -570,7 +587,11 @@ abstract public class PDOMWriter {
|
|||
}
|
||||
|
||||
protected int computeFileSizeAndEncodingHashcode(IIndexFileLocation location) {
|
||||
return ((int) fResolver.getFileSize(location)) + 31 * fResolver.getEncoding(location).hashCode();
|
||||
return computeFileSizeAndEncodingHashcode((int) fResolver.getFileSize(location), location);
|
||||
}
|
||||
|
||||
private int computeFileSizeAndEncodingHashcode(long size, IIndexFileLocation location) {
|
||||
return (int) size + 31 * fResolver.getEncoding(location).hashCode();
|
||||
}
|
||||
|
||||
private boolean isContextFor(IIndexFragmentFile oldFile, IASTPreprocessorIncludeStatement stmt)
|
||||
|
|
Loading…
Add table
Reference in a new issue