blob: c8b811b0b4c94724055d88717cb05661d7f896f6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2017 IBM Corporation and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
*******************************************************************************/
package org.eclipse.dltk.internal.ui.text;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.ui.DLTKUIPlugin;
import org.eclipse.dltk.ui.IWorkingCopyManager;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.reconciler.DirtyRegion;
import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
public class ScriptReconcilingStrategy implements IReconcilingStrategy,
IReconcilingStrategyExtension {
private ITextEditor fEditor;
private IWorkingCopyManager fManager;
private IDocumentProvider fDocumentProvider;
private IProgressMonitor fProgressMonitor;
private IScriptReconcilingListener fScriptReconcilingListener;
private boolean fIsScriptReconcilingListener;
private boolean fNotify = true;
public ScriptReconcilingStrategy(ITextEditor editor) {
fEditor = editor;
fManager = DLTKUIPlugin.getDefault().getWorkingCopyManager();
fDocumentProvider = DLTKUIPlugin.getDefault()
.getSourceModuleDocumentProvider();
fIsScriptReconcilingListener = fEditor instanceof IScriptReconcilingListener;
if (fIsScriptReconcilingListener) {
fScriptReconcilingListener = (IScriptReconcilingListener) fEditor;
}
}
// private static class ReconcilerFeedback extends Job {
//
// public ReconcilerFeedback() {
// super(TextMessages.ScriptReconcilingStrategy_ReconcilingJobName);
// setPriority(Job.SHORT);
// schedule(1000);
// }
//
// @Override
// protected IStatus run(IProgressMonitor monitor) {
// for (;;) {
// if (monitor.isCanceled()) {
// break;
// }
// synchronized (lock) {
// if (canceled) {
// break;
// }
// try {
// lock.wait(1000);
// } catch (InterruptedException e) {
// break;
// }
// }
// }
// return Status.OK_STATUS;
// }
//
// private final Object lock = new Object();
// private boolean canceled = false;
//
// public void stop() {
// synchronized (lock) {
// canceled = true;
// lock.notify();
// }
// cancel();
// }
//
// }
private IProblemRequestorExtension getProblemRequestorExtension() {
IAnnotationModel model = fDocumentProvider.getAnnotationModel(fEditor
.getEditorInput());
if (model instanceof IProblemRequestorExtension)
return (IProblemRequestorExtension) model;
return null;
}
protected void reconcile(final boolean initialReconcile) {
if (fEditor == null) {
return;
}
final ISourceModule unit = fManager.getWorkingCopy(fEditor
.getEditorInput());
if (unit == null) {
return;
}
try {
SafeRunner.run(new ISafeRunnable() {
@Override
public void run() throws ModelException {
// final ReconcilerFeedback feedback = new
// ReconcilerFeedback();
// try {
reconcile(unit, initialReconcile);
// } finally {
// feedback.stop();
// }
}
@Override
public void handleException(Throwable ex) {
DLTKUIPlugin.logErrorMessage(
"Error in DLTK Core during reconcile", ex);//$NON-NLS-1$
}
});
} finally {
// Always notify listeners, see
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=55969 for the final
// solution
try {
if (fIsScriptReconcilingListener) {
IProgressMonitor pm = fProgressMonitor;
if (pm == null)
pm = new NullProgressMonitor();
fScriptReconcilingListener.reconciled(unit, !fNotify, pm);
}
} finally {
fNotify = true;
}
}
}
private void reconcile(ISourceModule unit, boolean initialReconcile)
throws ModelException {
/* fix for missing cancel flag communication */
IProblemRequestorExtension extension = getProblemRequestorExtension();
if (extension != null) {
extension.setProgressMonitor(fProgressMonitor);
extension.setIsActive(true);
}
try {
// reconcile
unit.reconcile(true, null, fProgressMonitor);
} catch (OperationCanceledException ex) {
Assert.isTrue(fProgressMonitor == null
|| fProgressMonitor.isCanceled());
} finally {
/* fix for missing cancel flag communication */
if (extension != null) {
extension.setProgressMonitor(null);
extension.setIsActive(false);
}
}
}
public void aboutToBeReconciled() {
if (fIsScriptReconcilingListener) {
fScriptReconcilingListener.aboutToBeReconciled();
}
}
@Override
public void setDocument(IDocument document) {
}
@Override
public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
reconcile(false);
}
@Override
public void reconcile(IRegion partition) {
reconcile(false);
}
@Override
public void setProgressMonitor(IProgressMonitor monitor) {
fProgressMonitor = monitor;
}
@Override
public void initialReconcile() {
reconcile(true);
}
public void notifyListeners(boolean notify) {
fNotify = notify;
}
}