Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergey Prigogin2012-05-10 00:05:51 +0000
committerSergey Prigogin2012-05-10 00:12:45 +0000
commitae606fe28bd730d640f6ec722da99628e813984d (patch)
tree2ceb0c5d500221d61fd20d897258e0a269878701 /core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal
parentfdbfec3f2bb2334d5818cc7bc3bed2cc75c151a8 (diff)
downloadorg.eclipse.cdt-ae606fe28bd730d640f6ec722da99628e813984d.tar.gz
org.eclipse.cdt-ae606fe28bd730d640f6ec722da99628e813984d.tar.xz
org.eclipse.cdt-ae606fe28bd730d640f6ec722da99628e813984d.zip
Bug 378317 - Index update mode for resolving unresolved includes and
reindexing files with I/O errors.
Diffstat (limited to 'core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal')
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java26
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java12
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java10
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java16
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java10
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java14
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java65
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/FileCharArray.java1
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/IncludeSearchPathElement.java2
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/InternalFileContent.java16
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java11
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java70
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java18
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java21
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java32
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMUpdateTask.java193
17 files changed, 429 insertions, 92 deletions
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java
index 1fbc93e4b55..c3dde20b6f0 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java
@@ -759,6 +759,32 @@ public class CIndex implements IIndex {
}
@Override
+ public IIndexFile[] getDefectiveFiles() throws CoreException {
+ HashMap<IIndexFileLocation, IIndexFile> result= new HashMap<IIndexFileLocation, IIndexFile>();
+ for (IIndexFragment fragment : fFragments) {
+ for (IIndexFragmentFile file : fragment.getDefectiveFiles()) {
+ if (file.hasContent()) {
+ result.put(file.getLocation(), file);
+ }
+ }
+ }
+ return result.values().toArray(new IIndexFile[result.size()]);
+ }
+
+ @Override
+ public IIndexFile[] getFilesWithUnresolvedIncludes() throws CoreException {
+ HashMap<IIndexFileLocation, IIndexFile> result= new HashMap<IIndexFileLocation, IIndexFile>();
+ for (IIndexFragment fragment : fFragments) {
+ for (IIndexFragmentFile file : fragment.getFilesWithUnresolvedIncludes()) {
+ if (file.hasContent()) {
+ result.put(file.getLocation(), file);
+ }
+ }
+ }
+ return result.values().toArray(new IIndexFile[result.size()]);
+ }
+
+ @Override
public IIndexScope[] getInlineNamespaces() throws CoreException {
if (SPECIALCASE_SINGLES && fFragments.length == 1) {
return fFragments[0].getInlineNamespaces();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java
index 503ede13120..9168511d58d 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2011 Wind River Systems, Inc. and others.
+ * Copyright (c) 2006, 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
@@ -190,6 +190,16 @@ final public class EmptyCIndex implements IIndex {
}
@Override
+ public IIndexFile[] getDefectiveFiles() {
+ return IIndexFile.EMPTY_FILE_ARRAY;
+ }
+
+ @Override
+ public IIndexFile[] getFilesWithUnresolvedIncludes() {
+ return IIndexFile.EMPTY_FILE_ARRAY;
+ }
+
+ @Override
public IIndexBinding[] findBindings(char[] name, boolean fileScopeOnly, IndexFilter filter, IProgressMonitor monitor) {
return IIndexBinding.EMPTY_INDEX_BINDING_ARRAY;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java
index 2b2ac26362f..7a2bc0ccf72 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java
@@ -326,6 +326,16 @@ public interface IIndexFragment {
IIndexFragmentFile[] getAllFiles() throws CoreException;
/**
+ * @return an array of files that were indexed with I/O errors.
+ */
+ IIndexFragmentFile[] getDefectiveFiles() throws CoreException;
+
+ /**
+ * @return an array of files containg unresolved includes.
+ */
+ IIndexFragmentFile[] getFilesWithUnresolvedIncludes() throws CoreException;
+
+ /**
* Caches an object with the key, the cache must be cleared at latest when the fragment no
* longer holds a locks.
* @param replace if <code>false</code> an existing entry will not be replaced.
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java
index f6ca6b05ca2..0577e408b1b 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2011 Wind River Systems, Inc. and others.
+ * Copyright (c) 2006, 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
@@ -24,11 +24,16 @@ public interface IIndexFragmentFile extends IIndexFile {
IIndexFragment getIndexFragment();
/**
- * Sets the timestamp of the file
+ * Sets the timestamp of the file.
*/
void setTimestamp(long timestamp) throws CoreException;
/**
+ * Sets the file read time.
+ */
+ void setSourceReadTime(long time) throws CoreException;
+
+ /**
* Sets the hash of the file content.
*/
void setContentsHash(long hash) throws CoreException;
@@ -58,6 +63,12 @@ public interface IIndexFragmentFile extends IIndexFile {
boolean hasContent() throws CoreException;
/**
+ * Checks if the file contains at least one unresolved include.
+ * @return {@code true} if the file contains an unresolved include
+ */
+ boolean hasUnresolvedInclude() throws CoreException;
+
+ /**
* Returns the id of the linkage this file belongs to.
*/
@Override
@@ -74,4 +85,5 @@ public interface IIndexFragmentFile extends IIndexFile {
* The file 'source' must belong to the same fragment as this file.
*/
void transferContext(IIndexFragmentFile source) throws CoreException;
+
}
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 37ac0d0b27b..a9de019b08e 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
@@ -155,6 +155,7 @@ public class InternalParserUtil extends ParserFactory {
InputStream input;
try {
+ long fileReadTime = System.currentTimeMillis();
IFileStore store = EFS.getStore(file.getLocationURI());
IFileInfo fileInfo = store.fetchInfo();
input= file.getContents(true);
@@ -173,7 +174,7 @@ public class InternalParserUtil extends ParserFactory {
}
try {
return createFileContent(path, file.getCharset(), input,
- fileInfo.getLastModified(), fileInfo.getLength());
+ fileInfo.getLastModified(), fileInfo.getLength(), fileReadTime);
} finally {
try {
input.close();
@@ -201,6 +202,7 @@ public class InternalParserUtil extends ParserFactory {
* canonical path.
*/
public static InternalFileContent createExternalFileContent(String externalLocation, String encoding) {
+ long fileReadTime = System.currentTimeMillis();
File includeFile = null;
String path = null;
if (!UNCPathConverter.isUNC(externalLocation)) {
@@ -228,7 +230,7 @@ public class InternalParserUtil extends ParserFactory {
return null;
}
try {
- return createFileContent(path, encoding, in, timestamp, fileSize);
+ return createFileContent(path, encoding, in, timestamp, fileSize, fileReadTime);
} finally {
try {
in.close();
@@ -240,13 +242,13 @@ public class InternalParserUtil extends ParserFactory {
}
private static InternalFileContent createFileContent(String path, String charset, InputStream in,
- long fileTimestamp, long fileSize) {
+ long fileTimestamp, long fileSize, long fileReadTime) {
try {
AbstractCharArray chars= FileCharArray.create(path, charset, in);
if (chars == null)
return null;
- return new InternalFileContent(path, chars, fileTimestamp, fileSize);
+ return new InternalFileContent(path, chars, fileTimestamp, fileSize, fileReadTime);
} 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 8cf8471286d..43bc89e7012 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
@@ -298,6 +298,7 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
private long fIncludedFileContentsHash;
private long fIncludedFileTimestamp = -1;
private long fIncludedFileSize;
+ private long fIncludedFileReadTime;
private boolean fErrorInIncludedFile;
public ASTInclusionStatement(IASTTranslationUnit parent,
@@ -405,6 +406,19 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
}
@Override
+ public long getIncludedFileReadTime() {
+ if (fNominationDelegate != null) {
+ return 0;
+ }
+ return fIncludedFileReadTime;
+ }
+
+ public void setIncludedFileReadTime(long time) {
+ assert fNominationDelegate == null;
+ fIncludedFileReadTime= time;
+ }
+
+ @Override
public long getIncludedFileSize() {
if (fNominationDelegate != null) {
return 0;
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 0829535d524..46da6f2a30b 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
@@ -302,7 +302,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
if (contextPath == null) {
contextPath= fRootContent.getFileLocation();
}
- configureIncludeSearchPath(new File(contextPath).getParentFile(), info);
+ fIncludeSearchPath = configureIncludeSearchPath(new File(contextPath).getParentFile(), info);
setupMacroDictionary(configuration, info, language);
ILocationCtx ctx= fLocationMap.pushTranslationUnit(fRootContent.getFileLocation(), fRootContent.getSource());
@@ -396,37 +396,39 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
return array == null ? CharArrayUtils.EMPTY_CHAR_ARRAY : array;
}
- private void configureIncludeSearchPath(File directory, IScannerInfo info) {
+ public static IncludeSearchPathElement[] configureIncludeSearchPath(File directory, IScannerInfo info) {
+ IncludeSearchPathElement[] includeSearchPath = null;
String[] searchPath= info.getIncludePaths();
int idx= 0;
if (info instanceof IExtendedScannerInfo) {
final IExtendedScannerInfo einfo= (IExtendedScannerInfo) info;
final String[] quoteIncludeSearchPath= einfo.getLocalIncludePath();
if (quoteIncludeSearchPath != null && quoteIncludeSearchPath.length > 0) {
- fIncludeSearchPath= new IncludeSearchPathElement[quoteIncludeSearchPath.length + searchPath.length];
- for (String qip : quoteIncludeSearchPath) {
- fIncludeSearchPath[idx++]= new IncludeSearchPathElement(makeAbsolute(directory, qip), true);
+ includeSearchPath= new IncludeSearchPathElement[quoteIncludeSearchPath.length + searchPath.length];
+ for (String path : quoteIncludeSearchPath) {
+ includeSearchPath[idx++]= new IncludeSearchPathElement(makeAbsolute(directory, path), true);
}
}
}
- if (fIncludeSearchPath == null) {
- fIncludeSearchPath= new IncludeSearchPathElement[searchPath.length];
+ if (includeSearchPath == null) {
+ includeSearchPath= new IncludeSearchPathElement[searchPath.length];
}
for (String path : searchPath) {
- fIncludeSearchPath[idx++]= new IncludeSearchPathElement(makeAbsolute(directory, path), false);
+ includeSearchPath[idx++]= new IncludeSearchPathElement(makeAbsolute(directory, path), false);
}
+ return includeSearchPath;
}
- private String makeAbsolute(File directory, String inlcudePath) {
- if (directory == null || new File(inlcudePath).isAbsolute()) {
- return inlcudePath;
+ private static String makeAbsolute(File directory, String includePath) {
+ if (directory == null || new File(includePath).isAbsolute()) {
+ return includePath;
}
- return ScannerUtility.createReconciledPath(directory.getAbsolutePath(), inlcudePath);
+ return ScannerUtility.createReconciledPath(directory.getAbsolutePath(), includePath);
}
private void setupMacroDictionary(IScannerExtensionConfiguration config, IScannerInfo info,
ParserLanguage lang) {
- // built in macros
+ // Built-in macros
fMacroDictionary.put(__CDT_PARSER__.getNameCharArray(), __CDT_PARSER__);
fMacroDictionary.put(__STDC__.getNameCharArray(), __STDC__);
fMacroDictionary.put(__FILE__.getNameCharArray(), __FILE__);
@@ -1066,20 +1068,10 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
private <T> T findInclusion(final String includeDirective, final boolean quoteInclude,
final boolean includeNext, final String currentFile, final IIncludeFileTester<T> tester) {
T reader = null;
- // Filename is an absolute path
- if (new File(includeDirective).isAbsolute()) {
- return tester.checkFile(includeDirective, false, null);
- }
- // Filename is a Linux absolute path on a windows machine
- if (File.separatorChar == '\\' && includeDirective.length() > 0) {
- final char firstChar = includeDirective.charAt(0);
- if (firstChar == '\\' || firstChar == '/') {
- if (currentFile != null && currentFile.length() > 1 && currentFile.charAt(1) == ':') {
- return tester.checkFile(currentFile.substring(0, 2) + includeDirective, false, null);
- }
- return tester.checkFile(includeDirective, false, null);
- }
- }
+ String absoluteInclusionPath = getAbsoluteInclusionPath(includeDirective, currentFile);
+ if (absoluteInclusionPath != null) {
+ return tester.checkFile(absoluteInclusionPath, false, null);
+ }
if (currentFile != null && quoteInclude && !includeNext) {
// Check to see if we find a match in the current directory
@@ -1134,6 +1126,24 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
return null;
}
+ public static String getAbsoluteInclusionPath(String includeDirective, String currentFile) {
+ // Filename is an absolute path
+ if (new File(includeDirective).isAbsolute()) {
+ return includeDirective;
+ }
+ // Filename is a Linux absolute path on a Windows machine
+ if (File.separatorChar == '\\' && includeDirective.length() > 0) {
+ final char firstChar = includeDirective.charAt(0);
+ if (firstChar == '\\' || firstChar == '/') {
+ if (currentFile != null && currentFile.length() > 1 && currentFile.charAt(1) == ':') {
+ return currentFile.substring(0, 2) + includeDirective;
+ }
+ return includeDirective;
+ }
+ }
+ return null;
+ }
+
private IncludeSearchPathElement findFileInIncludePath(String file, String includeDirective) {
for (IncludeSearchPathElement path : fIncludeSearchPath) {
String fileLocation = path.getLocation(includeDirective);
@@ -1490,6 +1500,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
stmt.setIncludedFileTimestamp(fi.getTimestamp());
stmt.setIncludedFileSize(fi.getFileSize());
stmt.setIncludedFileContentsHash(source.getContentsHash());
+ stmt.setIncludedFileReadTime(fi.getReadTime());
stmt.setErrorInIncludedFile(source.hasError());
if (!fCurrentContext.isPragmaOnce()) {
// Track the loaded version count, even in a non-pragma-once context.
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 66708a23bb3..94c45ff9255 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
@@ -186,6 +186,7 @@ public class FileCharArray extends LazyCharArray {
decode(channel, chunk.fSourceOffset, chunk.fSourceEndOffset, CharBuffer.wrap(dest));
} catch (IOException e) {
// File cannot be read
+ CCorePlugin.log(e);
fHasError = true;
} finally {
try {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/IncludeSearchPathElement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/IncludeSearchPathElement.java
index 7cd2ef5e4da..458dbc3f632 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/IncludeSearchPathElement.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/IncludeSearchPathElement.java
@@ -15,7 +15,7 @@ import java.io.File;
/**
* Represents an entry of the include search path
*/
-final class IncludeSearchPathElement {
+public final class IncludeSearchPathElement {
private static final boolean NON_SLASH_SEPARATOR = File.separatorChar != '/';
public static final String FRAMEWORK_VAR = "__framework__"; //$NON-NLS-1$
public static final String FILE_VAR = "__header__"; //$NON-NLS-1$
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 d8daeb12efb..5ce1b706be9 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
@@ -60,6 +60,7 @@ public class InternalFileContent extends FileContent {
private IncludeSearchPathElement fFoundOnPath;
private final long fTimestamp;
private final long fFileSize;
+ private final long fReadTime;
/**
* For skipping include files.
@@ -79,7 +80,8 @@ public class InternalFileContent extends FileContent {
fSource= null;
fNonPragmaOnceFiles= null;
fTimestamp= NULL_TIMESTAMP;
- fFileSize = NULL_FILE_SIZE;
+ fFileSize= NULL_FILE_SIZE;
+ fReadTime= 0;
}
/**
@@ -87,7 +89,7 @@ public class InternalFileContent extends FileContent {
* @throws IllegalArgumentException in case the codeReader or its location is <code>null</code>.
*/
public InternalFileContent(String filePath, AbstractCharArray content, long timestamp,
- long fileSize) throws IllegalArgumentException {
+ long fileSize, long fileReadTime) throws IllegalArgumentException {
if (content == null) {
throw new IllegalArgumentException();
}
@@ -101,7 +103,8 @@ public class InternalFileContent extends FileContent {
throw new IllegalArgumentException();
}
fTimestamp= timestamp;
- fFileSize = fileSize;
+ fFileSize= fileSize;
+ fReadTime= fileReadTime;
}
/**
@@ -123,6 +126,7 @@ public class InternalFileContent extends FileContent {
}
fTimestamp= NULL_TIMESTAMP;
fFileSize = NULL_FILE_SIZE;
+ fReadTime= 0;
}
/**
@@ -144,6 +148,7 @@ public class InternalFileContent extends FileContent {
fNonPragmaOnceFiles= nonPragmaOnceVersions;
fTimestamp= NULL_TIMESTAMP;
fFileSize = NULL_FILE_SIZE;
+ fReadTime= 0;
}
/**
@@ -167,6 +172,11 @@ public class InternalFileContent extends FileContent {
}
@Override
+ public long getReadTime() {
+ return fReadTime;
+ }
+
+ @Override
public long getFileSize() {
return fFileSize;
}
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 8a15c8298a1..b86005f0d7a 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
@@ -584,6 +584,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
final boolean forceAll= (fUpdateFlags & IIndexManager.UPDATE_ALL) != 0;
final boolean checkTimestamps= (fUpdateFlags & IIndexManager.UPDATE_CHECK_TIMESTAMPS) != 0;
final boolean checkFileContentsHash = (fUpdateFlags & IIndexManager.UPDATE_CHECK_CONTENTS_HASH) != 0;
+ final boolean forceUnresolvedIncludes = (fUpdateFlags & IIndexManager.UPDATE_UNRESOLVED_INCLUDES) != 0;
final boolean both = fIndexHeadersWithoutContext == UnusedHeaderStrategy.useBoth;
int count= 0;
int forceFirst= fForceNumberFiles;
@@ -616,7 +617,9 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
if (ifile != null && ifile.getLinkageID() == linkageID && ifile.hasContent()) {
foundInLinkage = true;
indexFiles[i]= null; // Take the file.
- boolean update= force || isModified(checkTimestamps, checkFileContentsHash, ifl, tu, ifile);
+ boolean update= force ||
+ (forceUnresolvedIncludes && ifile.hasUnresolvedInclude()) ||
+ isModified(checkTimestamps, checkFileContentsHash, ifl, tu, ifile);
if (update && requestUpdate(linkageID, ifl, ifile, tu, updateKind)) {
count++;
linkages.set(linkageID);
@@ -639,7 +642,9 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
iFilesToRemove.add(ifile);
count++;
} else {
- boolean update= force || isModified(checkTimestamps, checkFileContentsHash, ifl, tu, ifile);
+ boolean update= force ||
+ (forceUnresolvedIncludes && ifile.hasUnresolvedInclude()) ||
+ isModified(checkTimestamps, checkFileContentsHash, ifl, tu, ifile);
final int linkageID = ifile.getLinkageID();
if (update && requestUpdate(linkageID, ifl, ifile, tu, UpdateKind.OTHER_HEADER)) {
count++;
@@ -648,7 +653,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
}
}
}
- for (int lid = linkages.nextSetBit(0); lid >= 0; lid= linkages.nextSetBit(lid+1)) {
+ for (int lid = linkages.nextSetBit(0); lid >= 0; lid= linkages.nextSetBit(lid + 1)) {
addPerLinkage(lid, ifl, files);
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
index 3d027cb7c6b..b7f081a4cc9 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
@@ -72,6 +72,7 @@ import org.eclipse.cdt.internal.core.pdom.db.BTree;
import org.eclipse.cdt.internal.core.pdom.db.ChunkCache;
import org.eclipse.cdt.internal.core.pdom.db.DBProperties;
import org.eclipse.cdt.internal.core.pdom.db.Database;
+import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator;
import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
import org.eclipse.cdt.internal.core.pdom.dom.BindingCollector;
import org.eclipse.cdt.internal.core.pdom.dom.FindBinding;
@@ -215,10 +216,11 @@ public class PDOM extends PlatformObject implements IPDOM {
* 122.0 - Compacting strings
* 123.0 - Combined file size and encoding hash code.
* 124.0 - GCC attributes and NO_RETURN flag for functions.
+ * 125.0 - Indexes for unresolved includes and files indexed with I/O errors.
*/
- private static final int MIN_SUPPORTED_VERSION= version(124, 0);
- private static final int MAX_SUPPORTED_VERSION= version(124, Short.MAX_VALUE);
- private static final int DEFAULT_VERSION = version(124, 0);
+ private static final int MIN_SUPPORTED_VERSION= version(125, 0);
+ private static final int MAX_SUPPORTED_VERSION= version(125, Short.MAX_VALUE);
+ private static final int DEFAULT_VERSION = version(125, 0);
private static int version(int major, int minor) {
return (major << 16) + minor;
@@ -251,8 +253,10 @@ public class PDOM extends PlatformObject implements IPDOM {
public static final int LINKAGES = Database.DATA_AREA;
public static final int FILE_INDEX = Database.DATA_AREA + 4;
- public static final int PROPERTIES = Database.DATA_AREA + 8;
- public static final int END= Database.DATA_AREA + 12;
+ public static final int INDEX_OF_DEFECTIVE_FILES = Database.DATA_AREA + 8;
+ public static final int INDEX_OF_FILES_WITH_UNRESOLVED_INCLUDES = Database.DATA_AREA + 12;
+ public static final int PROPERTIES = Database.DATA_AREA + 16;
+ public static final int END= Database.DATA_AREA + 20;
static {
assert END <= Database.CHUNK_SIZE;
}
@@ -303,9 +307,19 @@ public class PDOM extends PlatformObject implements IPDOM {
public void handleChange(PDOM pdom, ChangeEvent event);
}
+ // Primitive comparator that compares database offsets of two records.
+ private static final IBTreeComparator offsetComparator = new IBTreeComparator() {
+ @Override
+ public int compare(long record1, long record2) throws CoreException {
+ return record1 < record2 ? -1 : record1 == record2 ? 0 : 1;
+ }
+ };
+
// Local caches
protected Database db;
private BTree fileIndex;
+ private BTree indexOfDefectiveFiles;
+ private BTree indexOfFiledWithUnresolvedIncludes;
private Map<Integer, PDOMLinkage> fLinkageIDCache = new HashMap<Integer, PDOMLinkage>();
private File fPath;
private IIndexLocationConverter locationConverter;
@@ -432,6 +446,26 @@ public class PDOM extends PlatformObject implements IPDOM {
return fileIndex;
}
+ /**
+ * Returns the index of files that were read with I/O errors.
+ */
+ public BTree getIndexOfDefectiveFiles() throws CoreException {
+ if (indexOfDefectiveFiles == null)
+ indexOfDefectiveFiles = new BTree(getDB(), INDEX_OF_DEFECTIVE_FILES, offsetComparator);
+ return indexOfDefectiveFiles;
+ }
+
+ /**
+ * Returns the index of files containg unresolved includes.
+ */
+ public BTree getIndexOfFilesWithUnresolvedIncludes() throws CoreException {
+ if (indexOfFiledWithUnresolvedIncludes == null) {
+ indexOfFiledWithUnresolvedIncludes =
+ new BTree(getDB(), INDEX_OF_FILES_WITH_UNRESOLVED_INCLUDES, offsetComparator);
+ }
+ return indexOfFiledWithUnresolvedIncludes;
+ }
+
@Deprecated
@Override
public PDOMFile getFile(int linkageID, IIndexFileLocation location) throws CoreException {
@@ -471,8 +505,22 @@ public class PDOM extends PlatformObject implements IPDOM {
@Override
public IIndexFragmentFile[] getAllFiles() throws CoreException {
- final List<PDOMFile> locations = new ArrayList<PDOMFile>();
- getFileIndex().accept(new IBTreeVisitor() {
+ return getFiles(getFileIndex());
+ }
+
+ @Override
+ public IIndexFragmentFile[] getDefectiveFiles() throws CoreException {
+ return getFiles(getIndexOfDefectiveFiles());
+ }
+
+ @Override
+ public IIndexFragmentFile[] getFilesWithUnresolvedIncludes() throws CoreException {
+ return getFiles(getIndexOfFilesWithUnresolvedIncludes());
+ }
+
+ private IIndexFragmentFile[] getFiles(BTree index) throws CoreException {
+ final List<PDOMFile> files = new ArrayList<PDOMFile>();
+ index.accept(new IBTreeVisitor() {
@Override
public int compare(long record) throws CoreException {
return 0;
@@ -481,13 +529,13 @@ public class PDOM extends PlatformObject implements IPDOM {
@Override
public boolean visit(long record) throws CoreException {
PDOMFile file = PDOMFile.recreateFile(PDOM.this, record);
- locations.add(file);
+ files.add(file);
return true;
}
});
- return locations.toArray(new IIndexFragmentFile[locations.size()]);
+ return files.toArray(new IIndexFragmentFile[files.size()]);
}
-
+
protected IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location,
ISignificantMacros sigMacros) throws CoreException {
PDOMLinkage linkage= createLinkage(linkageID);
@@ -1296,6 +1344,8 @@ public class PDOM extends PlatformObject implements IPDOM {
private void clearCaches() {
fileIndex= null;
+ indexOfDefectiveFiles= null;
+ indexOfFiledWithUnresolvedIncludes= null;
fLinkageIDCache.clear();
clearResultCache();
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java
index 20f4d820d0a..99d43bc24d3 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2010 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
@@ -41,7 +41,7 @@ import org.eclipse.core.runtime.IProgressMonitor;
/**
* The PDOMProxy is returned by the PDOMManager before the indexer kicks in. Also and more
* importantly it is returned when the indexer has been shut down (clients may not be aware
- * of this yet). Doing that prevents the creation of empty pdoms for deleted projects.
+ * of this yet). Doing that prevents the creation of empty PDOMs for deleted projects.
*/
public class PDOMProxy implements IPDOM {
private PDOM fDelegate;
@@ -319,6 +319,20 @@ public class PDOMProxy implements IPDOM {
}
@Override
+ public synchronized IIndexFragmentFile[] getDefectiveFiles() throws CoreException {
+ if (fDelegate != null)
+ return fDelegate.getDefectiveFiles();
+ return IIndexFragmentFile.EMPTY_ARRAY;
+ }
+
+ @Override
+ public synchronized IIndexFragmentFile[] getFilesWithUnresolvedIncludes() throws CoreException {
+ if (fDelegate != null)
+ return fDelegate.getFilesWithUnresolvedIncludes();
+ return IIndexFragmentFile.EMPTY_ARRAY;
+ }
+
+ @Override
public synchronized IIndexFragmentBinding[] findMacroContainers(Pattern pattern, IndexFilter filter,
IProgressMonitor monitor) throws CoreException {
if (fDelegate != null) {
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 c3b7c051b92..bcdc654fe9f 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
@@ -79,6 +79,7 @@ abstract public class PDOMWriter {
final long timestamp;
final long fileSize;
final long contentsHash;
+ final long sourceReadTime;
final boolean hasError;
public FileInAST(IASTPreprocessorIncludeStatement includeStmt, FileContentKey key) {
@@ -87,6 +88,7 @@ abstract public class PDOMWriter {
timestamp= includeStmt.getIncludedFileTimestamp();
fileSize = includeStmt.getIncludedFileSize();
contentsHash= includeStmt.getIncludedFileContentsHash();
+ sourceReadTime= includeStmt.getIncludedFileReadTime();
hasError= includeStmt.isErrorInIncludedFile();
}
@@ -96,6 +98,7 @@ abstract public class PDOMWriter {
timestamp= codeReader.getTimestamp();
fileSize= codeReader.getFileSize();
contentsHash= codeReader.getContentsHash();
+ sourceReadTime= codeReader.getReadTime();
hasError= codeReader.hasError();
}
@@ -577,6 +580,7 @@ abstract public class PDOMWriter {
index.setFileContent(file, linkageID, includeInfoArray, macros, names, fResolver, lock);
}
file.setTimestamp(astFile.hasError ? 0 : astFile.timestamp);
+ file.setSourceReadTime(astFile.sourceReadTime);
file.setSizeAndEncodingHashcode(computeFileSizeAndEncodingHashcode(astFile.fileSize, location));
file.setContentsHash(astFile.contentsHash);
file = index.commitUncommittedFile();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java
index aaeb280dfd8..89b1b26d487 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java
@@ -87,17 +87,36 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
public IIndexFragmentFile commitUncommittedFile() throws CoreException {
if (uncommittedFile == null)
return null;
+
+ int defectiveStateChange = uncommittedFile.getTimestamp() == 0 ? 1 : 0;
+ int unresolvedIncludeStateChange = uncommittedFile.hasUnresolvedInclude() ? 1 : 0;
+
PDOMFile file;
if (fileBeingUpdated == null) {
// New file, insert it into the index.
file = uncommittedFile;
- getFileIndex().insert(file.getRecord());
+ getFileIndex().insert(file.getRecord());
} else {
// Existing file.
+ if (fileBeingUpdated.getTimestamp() == 0)
+ defectiveStateChange -= 1;
+ if (fileBeingUpdated.hasUnresolvedInclude())
+ unresolvedIncludeStateChange -= 1;
fileBeingUpdated.replaceContentsFrom(uncommittedFile);
file = fileBeingUpdated;
fileBeingUpdated = null;
}
+ if (defectiveStateChange > 0) {
+ getIndexOfDefectiveFiles().insert(file.getRecord());
+ } else if (defectiveStateChange < 0) {
+ getIndexOfDefectiveFiles().delete(file.getRecord());
+ }
+ if (unresolvedIncludeStateChange > 0) {
+ getIndexOfFilesWithUnresolvedIncludes().insert(file.getRecord());
+ } else if (unresolvedIncludeStateChange < 0) {
+ getIndexOfFilesWithUnresolvedIncludes().delete(file.getRecord());
+ }
+
fEvent.fFilesWritten.add(uncommittedKey.getLocation());
uncommittedFile = null;
uncommittedKey = null;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java
index 816e1dbcbb1..e44b2170e72 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java
@@ -72,13 +72,14 @@ public class PDOMFile implements IIndexFragmentFile {
private static final int LOCATION_REPRESENTATION = FIRST_MACRO + Database.PTR_SIZE;
private static final int LINKAGE_ID= LOCATION_REPRESENTATION + Database.PTR_SIZE; // size 3
private static final int FLAGS= LINKAGE_ID + 3; // size 1
- private static final int TIME_STAMP = FLAGS + 1; // long
- private static final int CONTENT_HASH= TIME_STAMP + 8; // long
+ private static final int TIME_STAMP= FLAGS + 1; // long
+ private static final int SOURCE_READ_TIME= TIME_STAMP + 8; // long
+ private static final int CONTENT_HASH= SOURCE_READ_TIME + 8; // long
private static final int SIZE_AND_ENCODING_HASH= CONTENT_HASH + 8;
private static final int LAST_USING_DIRECTIVE= SIZE_AND_ENCODING_HASH + 4;
private static final int FIRST_MACRO_REFERENCE= LAST_USING_DIRECTIVE + Database.PTR_SIZE;
private static final int SIGNIFICANT_MACROS= FIRST_MACRO_REFERENCE + Database.PTR_SIZE;
- private static final int RECORD_SIZE= SIGNIFICANT_MACROS + Database.PTR_SIZE; // 8*PTR_SIZE + 3+1+8+8+4 = 56
+ private static final int RECORD_SIZE= SIGNIFICANT_MACROS + Database.PTR_SIZE; // 8*PTR_SIZE + 3+1+8+8+8+4 = 64
private static final int FLAG_PRAGMA_ONCE_SEMANTICS = 0x01;
@@ -205,6 +206,7 @@ public class PDOMFile implements IIndexFragmentFile {
}
setTimestamp(sourceFile.getTimestamp());
+ setSourceReadTime(sourceFile.getSourceReadTime());
setSizeAndEncodingHashcode(sourceFile.getSizeAndEncodingHashcode());
setContentsHash(sourceFile.getContentsHash());
@@ -310,6 +312,18 @@ public class PDOMFile implements IIndexFragmentFile {
}
@Override
+ public long getSourceReadTime() throws CoreException {
+ Database db = fLinkage.getDB();
+ return db.getLong(record + SOURCE_READ_TIME);
+ }
+
+ @Override
+ public void setSourceReadTime(long time) throws CoreException {
+ Database db= fLinkage.getDB();
+ db.putLong(record + SOURCE_READ_TIME, time);
+ }
+
+ @Override
public long getContentsHash() throws CoreException {
Database db = fLinkage.getDB();
return db.getLong(record + CONTENT_HASH);
@@ -571,6 +585,7 @@ public class PDOMFile implements IIndexFragmentFile {
m.delete();
}
setFirstMacroReference(null);
+ setSourceReadTime(0);
setTimestamp(-1);
}
@@ -645,6 +660,17 @@ public class PDOMFile implements IIndexFragmentFile {
}
@Override
+ public boolean hasUnresolvedInclude() throws CoreException {
+ PDOMInclude include = getFirstInclude();
+ while (include != null) {
+ if (!include.isResolved() && include.isActive())
+ return true;
+ include = include.getNextInIncludes();
+ }
+ return false;
+ }
+
+ @Override
public IIndexMacro[] getMacros() throws CoreException {
List<PDOMMacro> result= new ArrayList<PDOMMacro>();
PDOMMacro macro = getFirstMacro();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMUpdateTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMUpdateTask.java
index 349ea0fde3f..df8621199c4 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMUpdateTask.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMUpdateTask.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2010 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
@@ -11,6 +11,7 @@
******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.indexer;
+import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -22,13 +23,18 @@ import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexFileLocation;
+import org.eclipse.cdt.core.index.IIndexInclude;
import org.eclipse.cdt.core.index.IIndexManager;
import org.eclipse.cdt.core.index.IndexLocationFactory;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ITranslationUnit;
+import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.internal.core.model.ExternalTranslationUnit;
+import org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor;
+import org.eclipse.cdt.internal.core.parser.scanner.IncludeSearchPathElement;
+import org.eclipse.cdt.internal.core.parser.scanner.ScannerUtility;
import org.eclipse.cdt.internal.core.pdom.IndexerProgress;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
@@ -42,19 +48,18 @@ import org.eclipse.osgi.util.NLS;
* A task for updating an index, suitable for all indexers.
*/
public class PDOMUpdateTask implements IPDOMIndexerTask {
- protected static final String TRUE= String.valueOf(true);
- protected static final ITranslationUnit[] NO_TUS = {};
+ private static final ITranslationUnit[] NO_TUS = {};
private final IPDOMIndexer fIndexer;
- private final IndexerProgress fProgress;
private final int fUpdateOptions;
+ private final IndexerProgress fProgress;
private volatile IPDOMIndexerTask fDelegate;
private ArrayList<ICElement> fFilesAndFolders;
public PDOMUpdateTask(IPDOMIndexer indexer, int updateOptions) {
fIndexer= indexer;
- fProgress= createProgress();
fUpdateOptions= updateOptions;
+ fProgress= createProgress();
}
private IndexerProgress createProgress() {
@@ -92,40 +97,65 @@ public class PDOMUpdateTask implements IPDOMIndexerTask {
private void createDelegate(ICProject project, IProgressMonitor monitor)
throws CoreException, InterruptedException {
HashSet<ITranslationUnit> set= new HashSet<ITranslationUnit>();
- TranslationUnitCollector collector= new TranslationUnitCollector(set, set, monitor);
- boolean haveProject= false;
- if (fFilesAndFolders == null) {
- project.accept(collector);
- } else {
- for (ICElement elem : fFilesAndFolders) {
- if (elem.getElementType() == ICElement.C_PROJECT) {
- haveProject= true;
+ if ((fUpdateOptions & (IIndexManager.UPDATE_ALL | IIndexManager.UPDATE_CHECK_TIMESTAMPS)) != 0) {
+ TranslationUnitCollector collector= new TranslationUnitCollector(set, set, monitor);
+ boolean haveProject= false;
+ if (fFilesAndFolders == null) {
+ project.accept(collector);
+ } else {
+ for (ICElement elem : fFilesAndFolders) {
+ if (elem.getElementType() == ICElement.C_PROJECT) {
+ haveProject= true;
+ }
+ elem.accept(collector);
+ }
+ }
+ if (haveProject && (fUpdateOptions & IIndexManager.UPDATE_EXTERNAL_FILES_FOR_PROJECT) != 0) {
+ final String projectPrefix= project.getProject().getFullPath().toString() + IPath.SEPARATOR;
+ IIndex index= CCorePlugin.getIndexManager().getIndex(project);
+ index.acquireReadLock();
+ try {
+ IIndexFile[] files= index.getAllFiles();
+ for (IIndexFile indexFile : files) {
+ IIndexFileLocation floc= indexFile.getLocation();
+ final String fullPath = floc.getFullPath();
+ if (fullPath == null || !fullPath.startsWith(projectPrefix)) {
+ ITranslationUnit tu = getTranslationUnit(floc, project);
+ if (tu != null) {
+ set.add(tu);
+ }
+ }
+ }
+ } finally {
+ index.releaseReadLock();
}
- elem.accept(collector);
}
}
- if (haveProject && (fUpdateOptions & IIndexManager.UPDATE_EXTERNAL_FILES_FOR_PROJECT) != 0) {
- final String projectPrefix= project.getProject().getFullPath().toString() + IPath.SEPARATOR;
+
+ if ((fUpdateOptions & IIndexManager.UPDATE_UNRESOLVED_INCLUDES) != 0) {
IIndex index= CCorePlugin.getIndexManager().getIndex(project);
index.acquireReadLock();
try {
- IIndexFile[] files= index.getAllFiles();
- for (IIndexFile indexFile : files) {
- IIndexFileLocation floc= indexFile.getLocation();
- final String fullPath = floc.getFullPath();
- if (fullPath == null || !fullPath.startsWith(projectPrefix)) {
- IPath path= IndexLocationFactory.getAbsolutePath(floc);
- if (path != null) {
- ITranslationUnit tu= CoreModel.getDefault().createTranslationUnitFrom(project, path);
- if (tu != null) {
- if (fullPath != null) {
- if (tu instanceof ExternalTranslationUnit) {
- IResource file= ResourcesPlugin.getWorkspace().getRoot().findMember(fullPath);
- if (file instanceof IFile) {
- ((ExternalTranslationUnit) tu).setResource((IFile) file);
- }
- }
- }
+ // Files that were indexed with I/O errors.
+ IIndexFile[] files= index.getDefectiveFiles();
+ for (IIndexFile file : files) {
+ ITranslationUnit tu = getTranslationUnit(file.getLocation(), project);
+ if (tu != null) {
+ set.add(tu);
+ }
+ }
+
+ // Files with unresolved includes.
+ files= index.getFilesWithUnresolvedIncludes();
+ if (files.length > 0) {
+ ProjectIndexerInputAdapter inputAdapter = new ProjectIndexerInputAdapter(project, true);
+ ProjectIndexerIncludeResolutionHeuristics includeResolutionHeuristics =
+ new ProjectIndexerIncludeResolutionHeuristics(project.getProject(), inputAdapter);
+ for (IIndexFile file : files) {
+ ITranslationUnit tu = getTranslationUnit(file.getLocation(), project);
+ if (tu != null) {
+ IScannerInfo scannerInfo = tu.getScannerInfo(true);
+ if (canResolveUnresolvedInclude(file, scannerInfo, includeResolutionHeuristics)) {
set.add(tu);
}
}
@@ -135,15 +165,108 @@ public class PDOMUpdateTask implements IPDOMIndexerTask {
index.releaseReadLock();
}
}
+
ITranslationUnit[] tus= set.toArray(new ITranslationUnit[set.size()]);
IPDOMIndexerTask delegate= fIndexer.createTask(NO_TUS, tus, NO_TUS);
if (delegate instanceof PDOMIndexerTask) {
final PDOMIndexerTask task = (PDOMIndexerTask) delegate;
task.setUpdateFlags(fUpdateOptions);
}
- synchronized (this) {
- fDelegate= delegate;
+ setDelegate(delegate);
+ }
+
+ private ITranslationUnit getTranslationUnit(IIndexFileLocation location, ICProject project) {
+ IPath path= IndexLocationFactory.getAbsolutePath(location);
+ if (path == null)
+ return null;
+ ITranslationUnit tu= CoreModel.getDefault().createTranslationUnitFrom(project, path);
+ if (tu != null) {
+ final String fullPath = location.getFullPath();
+ if (fullPath != null) {
+ if (tu instanceof ExternalTranslationUnit) {
+ IResource file= ResourcesPlugin.getWorkspace().getRoot().findMember(fullPath);
+ if (file instanceof IFile) {
+ ((ExternalTranslationUnit) tu).setResource((IFile) file);
+ }
+ }
+ }
+ }
+ return tu;
+ }
+
+ private boolean canResolveUnresolvedInclude(IIndexFile file, IScannerInfo scannerInfo,
+ ProjectIndexerIncludeResolutionHeuristics includeResolutionHeuristics) {
+ try {
+ String filePath = IndexLocationFactory.getAbsolutePath(file.getLocation()).toOSString();
+ long fileReadTime = file.getSourceReadTime();
+ IncludeSearchPathElement[] includeSearchPath =
+ CPreprocessor.configureIncludeSearchPath(new File(filePath).getParentFile(), scannerInfo);
+ for (IIndexInclude include : file.getIncludes()) {
+ if (!include.isResolved() && include.isActive() &&
+ canResolveInclude(include, filePath, fileReadTime, includeSearchPath, includeResolutionHeuristics)) {
+ return true;
+ }
+ }
+ } catch (CoreException e) {
+ CCorePlugin.log(e);
}
+ return false;
+ }
+
+ private boolean canResolveInclude(IIndexInclude include, String currentFile, long timestamp,
+ IncludeSearchPathElement[] includeSearchPath,
+ ProjectIndexerIncludeResolutionHeuristics includeResolutionHeuristics) throws CoreException {
+ String includeName = include.getFullName();
+ String filePath = CPreprocessor.getAbsoluteInclusionPath(includeName, currentFile);
+ if (filePath != null && fileIsNotOlderThanTimestamp(filePath, timestamp)) {
+ return true;
+ }
+
+ if (currentFile != null && !include.isSystemInclude()) {
+ // Check to see if we find a match in the current directory
+ final File currentDir= new File(currentFile).getParentFile();
+ if (currentDir != null) {
+ filePath = ScannerUtility.createReconciledPath(currentDir.getAbsolutePath(), includeName);
+ if (!filePath.equals(currentFile) && fileIsNotOlderThanTimestamp(filePath, timestamp)) {
+ return true;
+ }
+ }
+ }
+
+ // Unlike CPreprocessor.findInclusion we are searching include path from the beginning.
+ // This simplification may produce false positives, but by checking file modification time
+ // we guarantee that any false positive won't be produced again when this task runs
+ // next time.
+ for (IncludeSearchPathElement path : includeSearchPath) {
+ if (!include.isSystemInclude() || !path.isForQuoteIncludesOnly()) {
+ filePath = path.getLocation(includeName);
+ if (filePath != null && fileIsNotOlderThanTimestamp(filePath, timestamp)) {
+ return true;
+ }
+ }
+ }
+ if (includeResolutionHeuristics != null) {
+ filePath= includeResolutionHeuristics.findInclusion(includeName, currentFile);
+ if (filePath != null && fileIsNotOlderThanTimestamp(filePath, timestamp)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns true if the file exists and is not older than the given timestamp.
+ */
+ private boolean fileIsNotOlderThanTimestamp(String filename, long timestamp) {
+ // We are subtracting 1 second from the timestamp to account for limited precision
+ // of File.lastModified() method and possible asynchrony between clocks on multi-CPU
+ // systems. This may produce false positives, but they are pretty harmless.
+ return new File(filename).lastModified() >= timestamp - 1000;
+ }
+
+ private synchronized void setDelegate(IPDOMIndexerTask delegate) {
+ fDelegate= delegate;
}
@Override

Back to the top