diff --git a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/AbstractIndexAstChecker.java b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/AbstractIndexAstChecker.java index 6f306b23af3..64b5fcc8ddd 100644 --- a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/AbstractIndexAstChecker.java +++ b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/AbstractIndexAstChecker.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2011 Alena Laskavaia + * Copyright (c) 2009, 2012 Alena Laskavaia * 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 @@ -70,10 +70,14 @@ public abstract class AbstractIndexAstChecker extends AbstractCheckerWithProblem } try { - IASTTranslationUnit ast = modelCache.getAST(); - if (ast != null) { - synchronized (ast) { - processAst(ast); + // Run the checker only if the index is fully initialized. Otherwise it may produce + // false positives. + if (modelCache.getIndex().isFullyInitialized()) { + IASTTranslationUnit ast = modelCache.getAST(); + if (ast != null) { + synchronized (ast) { + processAst(ast); + } } } } catch (CoreException e) { @@ -83,16 +87,19 @@ public abstract class AbstractIndexAstChecker extends AbstractCheckerWithProblem } } - /* - * (non-Javadoc) - * + /* (non-Javadoc) * @see IRunnableInEditorChecker#processModel(Object, ICheckerInvocationContext) */ @Override public synchronized void processModel(Object model, ICheckerInvocationContext context) { if (model instanceof IASTTranslationUnit) { - setContext(context); IASTTranslationUnit ast = (IASTTranslationUnit) model; + // Run the checker only if the index was fully initialized when the file was parsed. + // Otherwise the checker may produce false positives. + if (ast.isBasedOnIncompleteIndex()) + return; + + setContext(context); synchronized (context) { modelCache = context.get(CxxModelsCache.class); if (modelCache == null) { diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java index f2bc149c12e..0c638a1740a 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java @@ -201,4 +201,9 @@ public class EmptyIndexFragment implements IIndexFragment { public IIndexScope[] getInlineNamespaces() { return IIndexScope.EMPTY_INDEX_SCOPE_ARRAY; } + + @Override + public boolean isFullyInitialized() { + return true; + } } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java index 3f74ba7243b..8016d285b12 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 QNX Software Systems and others. + * Copyright (c) 2000, 2012 QNX Software Systems 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 @@ -817,6 +817,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit { } public IASTTranslationUnit getAST(IIndex index, int style, IProgressMonitor monitor) throws CoreException { + boolean incompleteIndex = index != null && !index.isFullyInitialized(); IIndexFile[] contextToHeader = getContextToHeader(index, style); ITranslationUnit configureWith = getConfigureWith(contextToHeader); if (configureWith == this) @@ -860,6 +861,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit { ASTTranslationUnit ast = (ASTTranslationUnit) ((AbstractLanguage) language).getASTTranslationUnit( fileContent, scanInfo, crf, index, options, log); ast.setOriginatingTranslationUnit(this); + ast.setBasedOnIncompleteIndex(incompleteIndex); return ast; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java index b7bc864054e..36db4a9af0e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.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 @@ -8,6 +8,7 @@ * Contributors: * Doug Schaefer (IBM) - Initial API and implementation * Markus Schorn (Wind River Systems) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.core.dom.ast; @@ -347,6 +348,13 @@ public interface IASTTranslationUnit extends IASTDeclarationListOwner, IFileNomi */ public ITranslationUnit getOriginatingTranslationUnit(); + /** + * Returns {@code true} if the index was not fully initialized when the code of the translation + * unit was parsed. + * @since 5.4 + */ + boolean isBasedOnIncompleteIndex(); + /** * @since 5.4 * @noreference This method is not intended to be referenced by clients. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java index 2f868eb12e3..283652b41fe 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java @@ -445,4 +445,11 @@ public interface IIndex { * @since 5.3 */ public IScope[] getInlineNamespaces() throws CoreException; + + /** + * Returns {@code true} if the index is fully initialized. An index may not be fully initialized + * during Eclipse startup, or soon after adding a new project to the workspace. + * @since 5.4 + */ + public boolean isFullyInitialized(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java index 8bced17fc9f..fe788c55505 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java @@ -80,6 +80,7 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat private SizeofCalculator fSizeofCalculator; /** The semaphore controlling exclusive access to the AST. */ private final Semaphore fSemaphore= new Semaphore(1); + private boolean fBasedOnIncompleteIndex; @Override public final IASTTranslationUnit getTranslationUnit() { @@ -341,6 +342,15 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat fForContentAssist= forContentAssist; } + @Override + public boolean isBasedOnIncompleteIndex() { + return fBasedOnIncompleteIndex; + } + + public void setBasedOnIncompleteIndex(boolean basedOnIncompleteIndex) { + fBasedOnIncompleteIndex = basedOnIncompleteIndex; + } + @Override public void skippedFile(int offset, InternalFileContent fileContent) { if (fIndexFileSet != null) { 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 7374440818d..1fbc93e4b55 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 @@ -781,6 +781,15 @@ public class CIndex implements IIndex { return result; } + @Override + public boolean isFullyInitialized() { + for (IIndexFragment fragment : fFragments) { + if (!fragment.isFullyInitialized()) + return false; + } + return true; + } + /** * A key used to uniquely identify an IIndexFragmentName object. Uniqueness is guaranteed only * for names corresponding to the same binding. 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 383217ae74c..503ede13120 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 @@ -12,7 +12,6 @@ * Sergey Prigogin (Google) * Jens Elmenthaler - http://bugs.eclipse.org/173458 (camel case completion) *******************************************************************************/ - package org.eclipse.cdt.internal.core.index; import java.util.regex.Pattern; @@ -204,4 +203,9 @@ final public class EmptyCIndex implements IIndex { public IScope[] getInlineNamespaces() { return new IScope[0]; } + + @Override + public boolean isFullyInitialized() { + return true; + } } \ No newline at end of file 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 bc7558d648a..2b2ac26362f 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 @@ -349,4 +349,10 @@ public interface IIndexFragment { * @throws CoreException */ IIndexScope[] getInlineNamespaces() throws CoreException; + + /** + * Returns {@code true} if the index fragment is fully initialized. An fragment may not be fully + * initialized during Eclipse startup, or soon after adding a new project to the workspace. + */ + boolean isFullyInitialized(); } 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 c0e9f1fede2..b15b330d85b 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 @@ -1650,4 +1650,9 @@ public class PDOM extends PlatformObject implements IPDOM { } return linkage.getInlineNamespaces(); } + + @Override + public boolean isFullyInitialized() { + return true; + } } 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 1607aae69d8..20f4d820d0a 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 @@ -350,4 +350,10 @@ public class PDOMProxy implements IPDOM { return IIndexScope.EMPTY_INDEX_SCOPE_ARRAY; } + + + @Override + public synchronized boolean isFullyInitialized() { + return fDelegate != null; + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CDocumentProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CDocumentProvider.java index 55c519499b8..02fc42d18e8 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CDocumentProvider.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CDocumentProvider.java @@ -69,6 +69,7 @@ import org.eclipse.ui.texteditor.MarkerUtilities; import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel; import org.eclipse.ui.texteditor.spelling.SpellingAnnotation; +import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ICModelMarker; import org.eclipse.cdt.core.model.ICProject; @@ -429,11 +430,22 @@ public class CDocumentProvider extends TextFileDocumentProvider { public void acceptProblem(IProblem problem) { if (isActive()) { ProblemRequestorState state= fProblemRequestorState.get(); - if (state != null) + if (state != null && isReliable(problem)) { state.fReportedProblems.add(problem); + } } } + /** + * A problem is not considered reliable if it belongs to an unreliable AST. + */ + private static boolean isReliable(IProblem problem) { + if (problem instanceof IASTNode) { + return !((IASTNode) problem).getTranslationUnit().isBasedOnIncompleteIndex(); + } + return true; + } + @Override public void endReporting() { ProblemRequestorState state= fProblemRequestorState.get(); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java index 9f199957714..1fd6bbada24 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java @@ -1316,6 +1316,10 @@ public class SemanticHighlightings { @Override public boolean consumes(SemanticToken token) { IASTNode node= token.getNode(); + if (node.getTranslationUnit().isBasedOnIncompleteIndex()) { + // Do not highlight problems is the AST is unreliable. + return false; + } if (node instanceof IASTProblem) { return true; }