Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergey Prigogin2012-05-03 03:35:52 +0000
committerSergey Prigogin2012-05-03 03:35:52 +0000
commit3c572e9afb1bd24841e716802d19ec061ab5fea6 (patch)
tree6f70ecc2eaa4369966bb28ad29354f824026b22e /core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core
parentd9caf9f42b918f83927cf64e98f5e9e9177a8f75 (diff)
downloadorg.eclipse.cdt-3c572e9afb1bd24841e716802d19ec061ab5fea6.tar.gz
org.eclipse.cdt-3c572e9afb1bd24841e716802d19ec061ab5fea6.tar.xz
org.eclipse.cdt-3c572e9afb1bd24841e716802d19ec061ab5fea6.zip
Obtain timestamp and file size _before_ reading the file contents to
protect the index from getting stale.
Diffstat (limited to 'core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core')
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java30
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java55
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/AbstractCharArray.java5
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java7
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CharArray.java5
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/FileCharArray.java39
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/InternalFileContent.java63
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java21
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerInputAdapter.java6
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java73
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java2
11 files changed, 223 insertions, 83 deletions
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java
index c47c98eeaec..37ac0d0b27b 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java
@@ -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)) {
+ 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.
+ * 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());
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);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java
index 605bdf42a9c..8cf8471286d 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java
@@ -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
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/AbstractCharArray.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/AbstractCharArray.java
index 72d90942cc9..dfe7e27a2da 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/AbstractCharArray.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/AbstractCharArray.java
@@ -54,6 +54,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.
*/
@Override
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java
index fc66bb4a861..0829535d524 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java
@@ -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);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CharArray.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CharArray.java
index ba1748cf60a..00fad00fc6e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CharArray.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CharArray.java
@@ -56,6 +56,11 @@ public final class CharArray extends AbstractCharArray {
}
@Override
+ public boolean hasError() {
+ return false;
+ }
+
+ @Override
public long getContentsHash() {
if (hash64 == 0 && fArray.length != 0) {
StreamHasher hasher = new StreamHasher();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/FileCharArray.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/FileCharArray.java
index eba6c0652af..66708a23bb3 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/FileCharArray.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/FileCharArray.java
@@ -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,8 +125,9 @@ public class FileCharArray extends LazyCharArray {
try {
assert fChannel != null;
final Charset charset = Charset.forName(fCharSet);
- final CharsetDecoder decoder = charset.newDecoder().onMalformedInput(CodingErrorAction.REPLACE)
- .onUnmappableCharacter(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.
final ByteBuffer in = ByteBuffer.allocate(needBytes);
@@ -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;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/InternalFileContent.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/InternalFileContent.java
index 56534886481..d8daeb12efb 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/InternalFileContent.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/InternalFileContent.java
@@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Markus Schorn - initial API and implementation
- * Sergey Prigogin (Google)
+ * Markus Schorn - initial API and implementation
+ * Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
@@ -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}.
@@ -200,7 +243,7 @@ public class InternalFileContent extends FileContent {
public void setFoundOnPath(IncludeSearchPathElement isp) {
fFoundOnPath= isp;
}
-
+
/**
* This method is slow. Use only for debugging.
*/
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java
index 9c30c079929..a67dc06a458 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java
@@ -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;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerInputAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerInputAdapter.java
index d49d6c13d81..69349d5fac2 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerInputAdapter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerInputAdapter.java
@@ -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
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java
index ed854f09862..c3b7c051b92 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java
@@ -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;
+ 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)
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java
index bfb8c6cba4c..e24dce8546a 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java
@@ -320,7 +320,7 @@ public class ProjectIndexerInputAdapter extends IndexerInputAdapter {
ITranslationUnit tu= (ITranslationUnit) tuo;
if (tu.getLocation() == null)
return null;
-
+
final FileContent reader= FileContent.create(tu);
if (reader != null) {
IIndexFileLocation ifl= IndexLocationFactory.getIFL(tu);

Back to the top