package org.jactr.eclipse.ui.reconciler; /* * default logging */ import java.net.MalformedURLException; import java.net.URI; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.jobs.IJobChangeEvent; import org.eclipse.core.runtime.jobs.IJobChangeListener; import org.eclipse.jface.preference.IPreferenceStore; 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.ui.IEditorInput; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IURIEditorInput; import org.jactr.eclipse.core.comp.ICompilationUnit; import org.jactr.eclipse.core.comp.IProjectCompilationUnit; import org.jactr.eclipse.core.comp.internal.IMutableCompilationUnit; import org.jactr.eclipse.core.compiler.CompileRunnable; import org.jactr.eclipse.core.compiler.IDECompiler; import org.jactr.eclipse.core.compiler.MarkRunnable; import org.jactr.eclipse.core.parser.IDEParserFactory; import org.jactr.eclipse.core.parser.ParseRunnable; import org.jactr.eclipse.ui.UIPlugin; import org.jactr.eclipse.ui.editor.ACTRModelEditor; import org.jactr.eclipse.ui.editor.assist.CodeAssistMarkerParticipant; import org.jactr.eclipse.ui.editor.markers.FoldingMarkerParticipant; import org.jactr.eclipse.ui.editor.markers.IPositionMarkerParticipant; import org.jactr.eclipse.ui.editor.markers.PositionMarker; import org.jactr.eclipse.ui.preferences.UIPreferences; import org.jactr.io.antlr3.parser.AbstractModelParser; import org.jactr.io.parser.IModelParser; public class ACTRReconciler implements IReconcilingStrategyExtension, IReconcilingStrategy { /** * Logger definition */ static private final transient Log LOGGER = LogFactory .getLog(ACTRReconciler.class); private final ACTRModelEditor _editor; private ICompilationUnit _compilationUnit; private ParseJob _parseJob; private CompilationUnitJob _compileJob; private CompilationUnitJob _markJob; private IJobChangeListener _jobListener; private long _maxChangeSize = 10; private long _changeSize = 0; public ACTRReconciler(ACTRModelEditor editor) { _editor = editor; _jobListener = new IJobChangeListener() { public void aboutToRun(IJobChangeEvent event) { } public void awake(IJobChangeEvent event) { } public void done(IJobChangeEvent event) { boolean clean = event.getResult().getSeverity() == IStatus.OK; boolean canceled = event.getResult().getSeverity() == IStatus.CANCEL; if (event.getJob() == _parseJob && clean) compile(); else if (!canceled) mark(); } public void running(IJobChangeEvent event) { } public void scheduled(IJobChangeEvent event) { } public void sleeping(IJobChangeEvent event) { } }; } private void clear() { _compilationUnit = null; _parseJob = null; _compileJob = null; _markJob = null; } public void setProgressMonitor(IProgressMonitor monitor) { } public void setDocument(IDocument document) { URI uri = getURI(); if (uri == null) { clear(); return; } AbstractModelParser modelParser = null; IResource resource = getResource(); String name = uri.getPath(); if (resource != null) { modelParser = (AbstractModelParser) IDEParserFactory.getParser(resource); name = resource.getName(); } else modelParser = (AbstractModelParser) IDEParserFactory.getParser(uri); ANTLRDocumentStream documentStream = new ANTLRDocumentStream(document, name); /* * set the base url so that relative imports will work */ try { modelParser.setBaseURL(uri.toURL()); } catch (MalformedURLException e) { LOGGER.error("NewReconciler.setDocument threw MalformedURLException : ", e); } modelParser.setInput(documentStream); installPositionMarkers(modelParser, document); _compilationUnit = _editor.getCompilationUnit(); if (_compilationUnit instanceof IProjectCompilationUnit) _markJob = new CompilationUnitJob("Marking", new MarkRunnable( (IProjectCompilationUnit) _compilationUnit)); _parseJob = new ParseJob(new ParseRunnable( (IMutableCompilationUnit) _compilationUnit, modelParser), documentStream); _parseJob.addJobChangeListener(_jobListener); _compileJob = new CompilationUnitJob("Compiling", new CompileRunnable( (IMutableCompilationUnit) _compilationUnit, new IDECompiler())); _compileJob.addJobChangeListener(_jobListener); } private void installPositionMarkers(IModelParser parser, IDocument document) { PositionMarker marker = new PositionMarker(); marker.setBase(_editor.getBase()); marker.setDocument(document); IPreferenceStore prefs = UIPlugin.getDefault().getPreferenceStore(); if (prefs.getBoolean(UIPreferences.ENABLE_ASSIST_PREF)) { IPositionMarkerParticipant participant = new CodeAssistMarkerParticipant(); marker.addParticipant(participant); } if (prefs.getBoolean(UIPreferences.ENABLE_FOLDING_PREF)) { IPositionMarkerParticipant participant = new FoldingMarkerParticipant( _editor); marker.addParticipant(participant); } parser.addTreeTracker(marker); } private void parse(boolean force) { if (!force) { if (_parseJob.isScheduled() || _parseJob.isRunning()) { if (LOGGER.isDebugEnabled()) LOGGER.debug("Parse scheduled or active, skipping"); return; } } else { if (LOGGER.isDebugEnabled()) LOGGER.debug("Canceling.."); if (_compileJob != null) _compileJob.cancel(); if (_parseJob != null) _parseJob.cancel(); } if (LOGGER.isDebugEnabled()) LOGGER.debug("Scheduling parse"); _parseJob.schedule(200); } private void compile() { if (_compileJob.isScheduled() || _compileJob.isRunning()) { if (LOGGER.isDebugEnabled()) LOGGER.debug("Compile scheduled or active, skipping"); return; } if (LOGGER.isDebugEnabled()) LOGGER.debug("Scheduling compile"); _compileJob.schedule(); } private void mark() { if (_markJob != null) { if (LOGGER.isDebugEnabled()) LOGGER.debug("Scheduling mark"); _markJob.schedule(); } } public void initialReconcile() { parse(true); } public void reconcile(IRegion partition) { _changeSize += partition.getLength(); boolean force = _changeSize >= _maxChangeSize; parse(force); if (force) _changeSize = 0; } public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) { _changeSize += dirtyRegion.getLength(); boolean force = _changeSize >= _maxChangeSize; parse(force); if (force) _changeSize = 0; } private IResource getResource() { IEditorInput input = _editor.getEditorInput(); if (input instanceof IFileEditorInput) return ((IFileEditorInput) input).getFile(); return null; } private URI getURI() { IEditorInput input = _editor.getEditorInput(); if (input instanceof IURIEditorInput) return ((IURIEditorInput) input).getURI(); return null; } }