1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-01 14:15:23 +02:00

Bug 377045 - Bogus transient errors in C/C++ editor soon after Eclipse

startup.
This commit is contained in:
Sergey Prigogin 2012-04-17 19:53:05 -07:00
parent 885f6f1b7e
commit e7ef578e94
13 changed files with 98 additions and 13 deletions

View file

@ -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) {

View file

@ -201,4 +201,9 @@ public class EmptyIndexFragment implements IIndexFragment {
public IIndexScope[] getInlineNamespaces() {
return IIndexScope.EMPTY_INDEX_SCOPE_ARRAY;
}
@Override
public boolean isFullyInitialized() {
return true;
}
}

View file

@ -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;
}

View file

@ -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.

View file

@ -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();
}

View file

@ -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) {

View file

@ -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.

View file

@ -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;
}
}

View file

@ -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();
}

View file

@ -1650,4 +1650,9 @@ public class PDOM extends PlatformObject implements IPDOM {
}
return linkage.getInlineNamespaces();
}
@Override
public boolean isFullyInitialized() {
return true;
}
}

View file

@ -350,4 +350,10 @@ public class PDOMProxy implements IPDOM {
return IIndexScope.EMPTY_INDEX_SCOPE_ARRAY;
}
@Override
public synchronized boolean isFullyInitialized() {
return fDelegate != null;
}
}

View file

@ -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();

View file

@ -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;
}