1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-09-09 19:43:27 +02:00

Fix for 226682: Need to stop parsing when reconciler is stopped

This commit is contained in:
Anton Leherbauer 2008-04-17 08:18:00 +00:00
parent 902a30fae3
commit 52fa978c3c
8 changed files with 201 additions and 51 deletions

View file

@ -76,6 +76,7 @@ import org.eclipse.cdt.core.model.IProblemRequestor;
import org.eclipse.cdt.core.model.IStructure; import org.eclipse.cdt.core.model.IStructure;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.Keywords; import org.eclipse.cdt.core.parser.Keywords;
import org.eclipse.cdt.core.parser.ParseError;
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility; import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclaration; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.IASTDeclarationAmbiguity; import org.eclipse.cdt.internal.core.dom.parser.IASTDeclarationAmbiguity;
@ -90,6 +91,8 @@ import org.eclipse.core.runtime.OperationCanceledException;
*/ */
public class CModelBuilder2 implements IContributedModelBuilder { public class CModelBuilder2 implements IContributedModelBuilder {
private final static boolean DEBUG= Util.isActive(DebugLogConstants.MODEL);
private final TranslationUnit fTranslationUnit; private final TranslationUnit fTranslationUnit;
private final IProgressMonitor fProgressMonitor; private final IProgressMonitor fProgressMonitor;
@ -133,13 +136,19 @@ public class CModelBuilder2 implements IContributedModelBuilder {
else { else {
parseFlags |= ITranslationUnit.AST_CONFIGURE_USING_SOURCE_CONTEXT; parseFlags |= ITranslationUnit.AST_CONFIGURE_USING_SOURCE_CONTEXT;
} }
final IASTTranslationUnit ast= fTranslationUnit.getAST(index, parseFlags);
Util.debugLog("CModelBuilder2: parsing " //$NON-NLS-1$
+ fTranslationUnit.getElementName()
+ " mode="+ (quickParseMode ? "skip all " : "skip indexed ") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ " time="+ ( System.currentTimeMillis() - startTime ) + "ms", //$NON-NLS-1$ //$NON-NLS-2$
DebugLogConstants.MODEL, false);
final IASTTranslationUnit ast;
try {
ast= fTranslationUnit.getAST(index, parseFlags, fProgressMonitor);
if (DEBUG) Util.debugLog("CModelBuilder2: parsing " //$NON-NLS-1$
+ fTranslationUnit.getElementName()
+ " mode="+ (quickParseMode ? "skip all " : "skip indexed ") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ " time="+ ( System.currentTimeMillis() - startTime ) + "ms", //$NON-NLS-1$ //$NON-NLS-2$
DebugLogConstants.MODEL, false);
} catch (ParseError e) {
checkCanceled();
throw e;
}
if (ast == null) { if (ast == null) {
return; return;
} }
@ -148,7 +157,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
startTime= System.currentTimeMillis(); startTime= System.currentTimeMillis();
buildModel(ast); buildModel(ast);
elementInfo.setIsStructureKnown(true); elementInfo.setIsStructureKnown(true);
Util.debugLog("CModelBuilder2: building " //$NON-NLS-1$ if (DEBUG) Util.debugLog("CModelBuilder2: building " //$NON-NLS-1$
+"children="+ fTranslationUnit.getElementInfo().internalGetChildren().size() //$NON-NLS-1$ +"children="+ fTranslationUnit.getElementInfo().internalGetChildren().size() //$NON-NLS-1$
+" time="+ (System.currentTimeMillis() - startTime) + "ms", //$NON-NLS-1$ //$NON-NLS-2$ +" time="+ (System.currentTimeMillis() - startTime) + "ms", //$NON-NLS-1$ //$NON-NLS-2$
DebugLogConstants.MODEL, false); DebugLogConstants.MODEL, false);
@ -171,7 +180,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
private void checkCanceled() { private void checkCanceled() {
if (fProgressMonitor != null && fProgressMonitor.isCanceled()) { if (fProgressMonitor != null && fProgressMonitor.isCanceled()) {
Util.debugLog("CModelBuilder2: cancelled ", DebugLogConstants.MODEL, false); //$NON-NLS-1$ if (DEBUG) Util.debugLog("CModelBuilder2: cancelled ", DebugLogConstants.MODEL, false); //$NON-NLS-1$
throw new OperationCanceledException(); throw new OperationCanceledException();
} }
} }
@ -213,6 +222,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
} }
// sort by offset // sort by offset
@SuppressWarnings("unchecked")
final List<SourceManipulation> children= fTranslationUnit.getElementInfo().internalGetChildren(); final List<SourceManipulation> children= fTranslationUnit.getElementInfo().internalGetChildren();
Collections.sort(children, new Comparator<SourceManipulation>() { Collections.sort(children, new Comparator<SourceManipulation>() {
public int compare(SourceManipulation o1, SourceManipulation o2) { public int compare(SourceManipulation o1, SourceManipulation o2) {
@ -436,21 +446,18 @@ public class CModelBuilder2 implements IContributedModelBuilder {
if (declSpecifier instanceof IASTCompositeTypeSpecifier) { if (declSpecifier instanceof IASTCompositeTypeSpecifier) {
if (declarator != null) { if (declarator != null) {
return createTypedefOrFunctionOrVariable(parent, declSpecifier, declarator, isTemplate); return createTypedefOrFunctionOrVariable(parent, declSpecifier, declarator, isTemplate);
} else {
return createCompositeType(parent, (IASTCompositeTypeSpecifier)declSpecifier, isTemplate);
} }
return createCompositeType(parent, (IASTCompositeTypeSpecifier)declSpecifier, isTemplate);
} else if (declSpecifier instanceof IASTElaboratedTypeSpecifier) { } else if (declSpecifier instanceof IASTElaboratedTypeSpecifier) {
if (declarator != null) { if (declarator != null) {
return createTypedefOrFunctionOrVariable(parent, declSpecifier, declarator, isTemplate); return createTypedefOrFunctionOrVariable(parent, declSpecifier, declarator, isTemplate);
} else {
return createElaboratedTypeDeclaration(parent, (IASTElaboratedTypeSpecifier)declSpecifier, isTemplate);
} }
return createElaboratedTypeDeclaration(parent, (IASTElaboratedTypeSpecifier)declSpecifier, isTemplate);
} else if (declSpecifier instanceof IASTEnumerationSpecifier) { } else if (declSpecifier instanceof IASTEnumerationSpecifier) {
if (declarator != null) { if (declarator != null) {
return createTypedefOrFunctionOrVariable(parent, declSpecifier, declarator, isTemplate); return createTypedefOrFunctionOrVariable(parent, declSpecifier, declarator, isTemplate);
} else {
return createEnumeration(parent, (IASTEnumerationSpecifier)declSpecifier);
} }
return createEnumeration(parent, (IASTEnumerationSpecifier)declSpecifier);
} else if (declSpecifier instanceof IASTNamedTypeSpecifier) { } else if (declSpecifier instanceof IASTNamedTypeSpecifier) {
if (declarator != null) { if (declarator != null) {
return createTypedefOrFunctionOrVariable(parent, declSpecifier, declarator, isTemplate); return createTypedefOrFunctionOrVariable(parent, declSpecifier, declarator, isTemplate);

View file

@ -0,0 +1,44 @@
/*******************************************************************************
* Copyright (c) 2008 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Anton Leherbauer (Wind River Systems) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.model;
import org.eclipse.cdt.internal.core.util.ICancelable;
import org.eclipse.cdt.internal.core.util.ICanceler;
import org.eclipse.core.runtime.NullProgressMonitor;
/**
* A progress monitor accepting a <code>ICancelable</code> object to receive the cancel request.
*
* @since 5.0
*/
public class ProgressMonitorAndCanceler extends NullProgressMonitor implements ICanceler {
private ICancelable fCancelable;
public void setCancelable(ICancelable cancelable) {
fCancelable= cancelable;
checkCanceled();
}
@Override
public void setCanceled(boolean canceled) {
super.setCanceled(canceled);
checkCanceled();
}
private void checkCanceled() {
if (fCancelable != null && isCanceled()) {
fCancelable.cancel();
fCancelable= null;
}
}
}

View file

@ -58,6 +58,7 @@ import org.eclipse.cdt.core.model.IUsing;
import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.core.model.LanguageManager; import org.eclipse.cdt.core.model.LanguageManager;
import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.IScannerInfoProvider; import org.eclipse.cdt.core.parser.IScannerInfoProvider;
import org.eclipse.cdt.core.parser.ParserUtil; import org.eclipse.cdt.core.parser.ParserUtil;
@ -67,7 +68,9 @@ import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.internal.core.dom.NullCodeReaderFactory; import org.eclipse.cdt.internal.core.dom.NullCodeReaderFactory;
import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory; import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory;
import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory; import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory;
import org.eclipse.cdt.internal.core.parser.ParserLogService;
import org.eclipse.cdt.internal.core.pdom.indexer.ProjectIndexerInputAdapter; import org.eclipse.cdt.internal.core.pdom.indexer.ProjectIndexerInputAdapter;
import org.eclipse.cdt.internal.core.util.ICanceler;
import org.eclipse.cdt.internal.core.util.MementoTokenizer; import org.eclipse.cdt.internal.core.util.MementoTokenizer;
import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo; import org.eclipse.core.filesystem.IFileInfo;
@ -785,10 +788,14 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
} }
public IASTTranslationUnit getAST() throws CoreException { public IASTTranslationUnit getAST() throws CoreException {
return getAST(null, 0); return getAST(null, 0, null);
} }
public IASTTranslationUnit getAST(IIndex index, int style) throws CoreException { public IASTTranslationUnit getAST(IIndex index, int style) throws CoreException {
return getAST(index, style, null);
}
public IASTTranslationUnit getAST(IIndex index, int style, IProgressMonitor monitor) throws CoreException {
ITranslationUnit configureWith = getSourceContextTU(index, style); ITranslationUnit configureWith = getSourceContextTU(index, style);
IScannerInfo scanInfo= configureWith.getScannerInfo( (style & AST_SKIP_IF_NO_BUILD_INFO) == 0); IScannerInfo scanInfo= configureWith.getScannerInfo( (style & AST_SKIP_IF_NO_BUILD_INFO) == 0);
@ -814,7 +821,13 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
if (isSourceUnit()) { if (isSourceUnit()) {
options |= ILanguage.OPTION_IS_SOURCE_UNIT; options |= ILanguage.OPTION_IS_SOURCE_UNIT;
} }
return ((AbstractLanguage)language).getASTTranslationUnit(reader, scanInfo, crf, index, options, ParserUtil.getParserLogService()); final IParserLogService log;
if (monitor instanceof ICanceler) {
log= new ParserLogService(DebugLogConstants.PARSER, (ICanceler)monitor);
} else {
log= ParserUtil.getParserLogService();
}
return ((AbstractLanguage)language).getASTTranslationUnit(reader, scanInfo, crf, index, options, log);
} }
} }
return null; return null;
@ -942,7 +955,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
/** /**
* Return the language of the context this file was parsed in. Works only after using * Return the language of the context this file was parsed in. Works only after using
* {@link #getAST(IIndex, int)} with the flag {@link ITranslationUnit#AST_CONFIGURE_USING_SOURCE_CONTEXT}. * {@link #getAST(IIndex, int, IProgressMonitor)} with the flag {@link ITranslationUnit#AST_CONFIGURE_USING_SOURCE_CONTEXT}.
*/ */
public ILanguage getLanguageOfContext() throws CoreException { public ILanguage getLanguageOfContext() throws CoreException {
final ILanguage result= fLanguageOfContext; final ILanguage result= fLanguageOfContext;

View file

@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2008 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Anton Leherbauer (Wind River Systems) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.util;
/**
* Interface for cancelable objects.
*
* @since 5.0
*/
public interface ICancelable {
/**
* Marks the receiver cancelled.
*/
void cancel();
}

View file

@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2008 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Anton Leherbauer (Wind River Systems) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.util;
/**
* An interface for objects accepting an instance of {@link ICancelable}.
*
* @since 5.0
*/
public interface ICanceler {
/**
* Set the cancelable object.
*
* @param cancelable the cancelable object
*/
void setCancelable(ICancelable cancelable);
}

View file

@ -40,6 +40,8 @@ import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.util.CharArrayIntMap; import org.eclipse.cdt.core.parser.util.CharArrayIntMap;
import org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor; import org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor;
import org.eclipse.cdt.internal.core.parser.token.KeywordSets; import org.eclipse.cdt.internal.core.parser.token.KeywordSets;
import org.eclipse.cdt.internal.core.util.ICancelable;
import org.eclipse.cdt.internal.core.util.ICanceler;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
/** /**
@ -115,16 +117,33 @@ public abstract class AbstractCLikeLanguage extends AbstractLanguage implements
public IASTTranslationUnit getASTTranslationUnit(CodeReader reader, IScannerInfo scanInfo, public IASTTranslationUnit getASTTranslationUnit(CodeReader reader, IScannerInfo scanInfo,
ICodeReaderFactory codeReaderFactory, IIndex index, int options, IParserLogService log) throws CoreException { ICodeReaderFactory codeReaderFactory, IIndex index, int options, IParserLogService log) throws CoreException {
IScanner scanner= createScanner(reader, scanInfo, codeReaderFactory, log); final IScanner scanner= createScanner(reader, scanInfo, codeReaderFactory, log);
scanner.setScanComments((options & OPTION_ADD_COMMENTS) != 0); scanner.setScanComments((options & OPTION_ADD_COMMENTS) != 0);
scanner.setComputeImageLocations((options & OPTION_NO_IMAGE_LOCATIONS) == 0); scanner.setComputeImageLocations((options & OPTION_NO_IMAGE_LOCATIONS) == 0);
ISourceCodeParser parser= createParser(scanner, log, index, false, options); final ISourceCodeParser parser= createParser(scanner, log, index, false, options);
// Parse // make parser cancelable by reconciler - http://bugs.eclipse.org/226682
IASTTranslationUnit ast= parser.parse(); ICanceler canceler= null;
ast.setIsHeaderUnit((options & OPTION_IS_SOURCE_UNIT) == 0); if (log instanceof ICanceler) {
return ast; canceler= (ICanceler) log;
canceler.setCancelable(new ICancelable() {
public void cancel() {
scanner.cancel();
parser.cancel();
}});
}
try {
// Parse
IASTTranslationUnit ast= parser.parse();
ast.setIsHeaderUnit((options & OPTION_IS_SOURCE_UNIT) == 0);
return ast;
} finally {
if (canceler != null) {
canceler.setCancelable(null);
}
}
} }

View file

@ -17,19 +17,25 @@ import org.eclipse.cdt.core.ICLogConstants;
import org.eclipse.cdt.core.parser.AbstractParserLogService; import org.eclipse.cdt.core.parser.AbstractParserLogService;
import org.eclipse.cdt.internal.core.model.DebugLogConstants; import org.eclipse.cdt.internal.core.model.DebugLogConstants;
import org.eclipse.cdt.internal.core.model.Util; import org.eclipse.cdt.internal.core.model.Util;
import org.eclipse.cdt.internal.core.util.ICancelable;
import org.eclipse.cdt.internal.core.util.ICanceler;
/** /**
* @author jcamelon * @author jcamelon
* *
*/ */
public class ParserLogService extends AbstractParserLogService { public class ParserLogService extends AbstractParserLogService implements ICanceler {
private final DebugLogConstants topic; private final DebugLogConstants topic;
private final boolean fIsTracing; private final boolean fIsTracing;
private final boolean fIsTracingExceptions; private final boolean fIsTracingExceptions;
private final ICanceler fCanceler;
public ParserLogService(DebugLogConstants constant) { public ParserLogService(DebugLogConstants constant) {
this(constant, null);
}
public ParserLogService(DebugLogConstants constant, ICanceler canceler) {
topic = constant; topic = constant;
if (CCorePlugin.getDefault() == null) { if (CCorePlugin.getDefault() == null) {
fIsTracing= fIsTracingExceptions= false; fIsTracing= fIsTracingExceptions= false;
@ -38,6 +44,7 @@ public class ParserLogService extends AbstractParserLogService {
fIsTracingExceptions= Util.PARSER_EXCEPTIONS; fIsTracingExceptions= Util.PARSER_EXCEPTIONS;
fIsTracing= Util.isActive(topic); fIsTracing= Util.isActive(topic);
} }
fCanceler= canceler;
} }
@ -61,4 +68,13 @@ public class ParserLogService extends AbstractParserLogService {
public boolean isTracingExceptions() { public boolean isTracingExceptions() {
return fIsTracingExceptions; return fIsTracingExceptions;
} }
/*
* @see org.eclipse.cdt.internal.core.util.ICanceler#setCancelable(org.eclipse.cdt.internal.core.util.ICancelable)
*/
public void setCancelable(ICancelable cancelable) {
if (fCanceler != null) {
fCanceler.setCancelable(cancelable);
}
}
} }

View file

@ -23,7 +23,6 @@ import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.content.IContentType; import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.IPreferenceStore;
@ -86,6 +85,7 @@ import org.eclipse.cdt.ui.text.doctools.DefaultMultilineCommentAutoEditStrategy;
import org.eclipse.cdt.ui.text.doctools.IDocCommentOwner; import org.eclipse.cdt.ui.text.doctools.IDocCommentOwner;
import org.eclipse.cdt.ui.text.doctools.IDocCommentViewerConfiguration; import org.eclipse.cdt.ui.text.doctools.IDocCommentViewerConfiguration;
import org.eclipse.cdt.internal.core.model.ProgressMonitorAndCanceler;
import org.eclipse.cdt.internal.corext.util.CodeFormatterUtil; import org.eclipse.cdt.internal.corext.util.CodeFormatterUtil;
import org.eclipse.cdt.internal.ui.editor.CDocumentProvider; import org.eclipse.cdt.internal.ui.editor.CDocumentProvider;
@ -434,7 +434,7 @@ public class CSourceViewerConfiguration extends TextSourceViewerConfiguration {
new CCompositeReconcilingStrategy(sourceViewer, fTextEditor, getConfiguredDocumentPartitioning(sourceViewer)); new CCompositeReconcilingStrategy(sourceViewer, fTextEditor, getConfiguredDocumentPartitioning(sourceViewer));
MonoReconciler reconciler= new CReconciler(fTextEditor, strategy); MonoReconciler reconciler= new CReconciler(fTextEditor, strategy);
reconciler.setIsIncrementalReconciler(false); reconciler.setIsIncrementalReconciler(false);
reconciler.setProgressMonitor(new NullProgressMonitor()); reconciler.setProgressMonitor(new ProgressMonitorAndCanceler());
reconciler.setDelay(500); reconciler.setDelay(500);
return reconciler; return reconciler;
} }