| author | szarnekow | 2009-03-09 10:57:33 (EDT) |
|---|---|---|
| committer | sefftinge | 2009-03-09 10:57:33 (EDT) |
| commit | a64b60316c5a233005d6f90153b1630d8b705500 (patch) (side-by-side diff) | |
| tree | eb39bce5acd878aac6130e96055c3395c0cc2b73 | |
| parent | 178112adb586a0db1d379a8053d3f5c9ccea3295 (diff) | |
| download | org.eclipse.xtext-a64b60316c5a233005d6f90153b1630d8b705500.zip org.eclipse.xtext-a64b60316c5a233005d6f90153b1630d8b705500.tar.gz org.eclipse.xtext-a64b60316c5a233005d6f90153b1630d8b705500.tar.bz2 | |
Feature: More validation for the Xtext grammar itself
Feature: XtextEditor can be opened with IStorageEditorInput, too.
Fix: XtextDocument is not parsed twice, when opened
6 files changed, 82 insertions, 86 deletions
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextEditor.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextEditor.java index 5b1db54..136f9c4 100644 --- a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextEditor.java +++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextEditor.java @@ -20,7 +20,6 @@ import org.eclipse.jface.text.source.projection.ProjectionViewer; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorSite; -import org.eclipse.ui.IURIEditorInput; import org.eclipse.ui.PartInitException; import org.eclipse.ui.editors.text.TextEditor; import org.eclipse.ui.texteditor.ITextEditorActionConstants; @@ -81,9 +80,6 @@ public class XtextEditor extends TextEditor { if (log.isDebugEnabled()) log.debug("init:" + input); - if (!(input instanceof IURIEditorInput)) - throw new IllegalArgumentException("Can only handle IURIEditorInputs"); - // do document provider setup setDocumentProvider(documentProvider.get()); diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextResourceChecker.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextResourceChecker.java index 72021da..793e0d6 100644 --- a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextResourceChecker.java +++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextResourceChecker.java @@ -130,14 +130,20 @@ public class XtextResourceChecker { Diagnostic diagnostic = Diagnostician.INSTANCE.validate(ele, context); if (!diagnostic.getChildren().isEmpty()) { for (Diagnostic childDiagnostic : diagnostic.getChildren()) { - markers.add(markerFromEValidatorDiagnostic(childDiagnostic)); + Map<String, Object> marker = markerFromEValidatorDiagnostic(childDiagnostic); + if (marker != null) { + markers.add(marker); + if (markers.size() > MAX_ERRORS) + return markers; + } + } + } else { + Map<String, Object> marker = markerFromEValidatorDiagnostic(diagnostic); + if (marker != null) { + markers.add(marker); if (markers.size() > MAX_ERRORS) return markers; } - } else { - markers.add(markerFromEValidatorDiagnostic(diagnostic)); - if (markers.size() > MAX_ERRORS) - return markers; } } catch (RuntimeException e) { log.error(e.getMessage(), e); @@ -173,16 +179,17 @@ public class XtextResourceChecker { } private static Map<String, Object> markerFromEValidatorDiagnostic(Diagnostic diagnostic) { + if (diagnostic.getSeverity() == Diagnostic.OK) + return null; Map<String, Object> map = new HashMap<String, Object>(); int sever = IMarker.SEVERITY_ERROR; switch (diagnostic.getSeverity()) { - case Diagnostic.WARNING: - sever = IMarker.SEVERITY_WARNING; - break; - case Diagnostic.OK: - case Diagnostic.INFO: - sever = IMarker.SEVERITY_INFO; - break; + case Diagnostic.WARNING: + sever = IMarker.SEVERITY_WARNING; + break; + case Diagnostic.INFO: + sever = IMarker.SEVERITY_INFO; + break; } map.put(IMarker.SEVERITY, sever); Iterator<?> data = diagnostic.getData().iterator(); @@ -191,10 +198,10 @@ public class XtextResourceChecker { if (causer instanceof EObject) { EObject ele = (EObject) causer; NodeAdapter nodeAdapter = NodeUtil.getNodeAdapter(ele); - if (nodeAdapter != null && data.hasNext()) { + if (nodeAdapter != null) { AbstractNode parserNode = nodeAdapter.getParserNode(); // feature is the second element see Diagnostician.getData - Object feature = data.next(); + Object feature = data.hasNext() ? data.next() : null; EStructuralFeature structuralFeature = resolveStructuralFeature(ele, feature); if (structuralFeature != null) { List<AbstractNode> nodes = NodeUtil.findNodesForFeature(ele, structuralFeature); diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/model/XtextDocument.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/model/XtextDocument.java index 74af418..caeab92 100644 --- a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/model/XtextDocument.java +++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/model/XtextDocument.java @@ -8,7 +8,6 @@ *******************************************************************************/ package org.eclipse.xtext.ui.core.editor.model; -import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.Lock; @@ -19,6 +18,7 @@ import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.Path; @@ -30,13 +30,13 @@ import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jface.text.Document; import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IStorageEditorInput; import org.eclipse.ui.ide.ResourceUtil; import org.eclipse.xtext.resource.XtextResource; import org.eclipse.xtext.resource.XtextResourceSet; import org.eclipse.xtext.ui.core.editor.model.IXtextDocumentContentObserver.Processor; import org.eclipse.xtext.ui.core.editor.utils.ValidationJob; import org.eclipse.xtext.ui.core.util.JdtClasspathUriResolver; -import org.eclipse.xtext.util.StringInputStream; import org.eclipse.xtext.validator.CheckMode; import com.google.inject.Inject; @@ -45,42 +45,50 @@ import com.google.inject.Provider; public class XtextDocument extends Document implements IXtextDocument { private XtextResourceSet resourceSet = null; + private XtextResource resource = null; - private IEditorInput editorInput; + private IFile file; + private final ListenerList modelListeners = new ListenerList(ListenerList.IDENTITY); + + private final ListenerList xtextDocumentObservers = new ListenerList(ListenerList.IDENTITY); + @Inject private Provider<XtextResourceSet> resourceSetProvider; public void setInput(IEditorInput editorInput) { file = ResourceUtil.getFile(editorInput); - Assert.isTrue(file != null && this.editorInput == null || this.editorInput.equals(editorInput)); - if (this.editorInput != null) - return; - this.editorInput = editorInput; - resourceSet = resourceSetProvider.get(); - IJavaProject javaProject = getIJavaProject(file); - if (javaProject != null) { - resourceSet.setClasspathUriResolver(new JdtClasspathUriResolver()); - resourceSet.setClasspathURIContext(javaProject); + resourceSet = resourceSetProvider.get(); + if (file != null) { + // TODO find a way to identify a project for an IStorageEditorInput + IJavaProject javaProject = getIJavaProject(file); + if (javaProject != null) { + resourceSet.setClasspathUriResolver(new JdtClasspathUriResolver()); + resourceSet.setClasspathURIContext(javaProject); + } } - IPath path = file.getFullPath(); - Resource aResource = resourceSet.createResource(URI.createPlatformResourceURI(path.toString(), true)); - if (!(aResource instanceof XtextResource)) - throw new IllegalStateException("The resource factory registered for " + path - + " is not an XtextResourceFactory. Make sure the right resource factory has been registered."); - resource = (XtextResource) aResource; - if (!resource.isLoaded()) { + IPath path = null; + if (file != null) { + path = file.getFullPath(); + } else { + IStorageEditorInput storageInput = (IStorageEditorInput) editorInput; try { - String string = get(); - resource.load(new StringInputStream(string), null); + // TODO get the FQN of the resource + path = storageInput.getStorage().getFullPath(); } - catch (IOException e) { + catch (CoreException e) { throw new WrappedException(e); } } + Resource aResource = resourceSet.createResource(URI.createPlatformResourceURI(path.toString(), true)); + if (!(aResource instanceof XtextResource)) + throw new IllegalStateException("The resource factory registered for " + path + + " is not an XtextResourceFactory. Make sure the right resource factory has been registered."); + resource = (XtextResource) aResource; + resource.setValidationDisabled(file == null); } public boolean isReferenced(IResource anIResource) { @@ -98,8 +106,8 @@ public class XtextDocument extends Document implements IXtextDocument { return uriToRes.containsKey(anIResource.getFullPath().lastSegment()); } - private IJavaProject getIJavaProject(IFile file) { - IJavaProject create = JavaCore.create(file.getProject()); + private IJavaProject getIJavaProject(IResource resource) { + IJavaProject create = JavaCore.create(resource.getProject()); if (create.exists()) return create; return null; @@ -116,14 +124,11 @@ public class XtextDocument extends Document implements IXtextDocument { T exec = work.exec(resource); ensureThatStateIsNotReturned(exec, work); return exec; - } - catch (RuntimeException e) { + } catch (RuntimeException e) { throw e; - } - catch (Exception e) { + } catch (Exception e) { throw new WrappedException(e); - } - finally { + } finally { readLock.unlock(); } } @@ -136,14 +141,11 @@ public class XtextDocument extends Document implements IXtextDocument { notifyModelListeners(resource); // TODO track modifications and serialize back to the text buffer return exec; - } - catch (RuntimeException e) { + } catch (RuntimeException e) { throw e; - } - catch (Exception e) { + } catch (Exception e) { throw new WrappedException(e); - } - finally { + } finally { writeLock.unlock(); checkAndUpdateMarkers(); } @@ -161,8 +163,6 @@ public class XtextDocument extends Document implements IXtextDocument { // } } - ListenerList modelListeners = new ListenerList(ListenerList.IDENTITY); - public void addModelListener(IXtextModelListener listener) { Assert.isNotNull(listener); modelListeners.add(listener); @@ -180,8 +180,6 @@ public class XtextDocument extends Document implements IXtextDocument { } } - private final ListenerList xtextDocumentObservers = new ListenerList(ListenerList.IDENTITY); - public void addXtextDocumentContentObserver(IXtextDocumentContentObserver observer) { addDocumentListener(observer); xtextDocumentObservers.add(observer); @@ -208,8 +206,7 @@ public class XtextDocument extends Document implements IXtextDocument { writeLock.lock(); try { return modify(transaction); - } - finally { + } finally { readLock.lock(); writeLock.unlock(); } diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/model/XtextDocumentProvider.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/model/XtextDocumentProvider.java index 638315d..c36d49e 100644 --- a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/model/XtextDocumentProvider.java +++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/model/XtextDocumentProvider.java @@ -27,7 +27,7 @@ import org.eclipse.core.runtime.jobs.Job; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.jface.text.IDocument; -import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.IEditorInput; import org.eclipse.ui.editors.text.FileDocumentProvider; import org.eclipse.xtext.resource.XtextResource; @@ -161,13 +161,8 @@ public class XtextDocumentProvider extends FileDocumentProvider { } @Override - public IDocument getDocument(Object element) { - final XtextDocument document = (XtextDocument) super.getDocument(element); - if (!(element instanceof IFileEditorInput)) - throw new IllegalArgumentException("Can only handle instances of " + IFileEditorInput.class.getSimpleName() - + " as input."); - document.setInput((IFileEditorInput) element); - return document; + protected void setupDocument(Object element, IDocument document) { + ((XtextDocument) document).setInput((IEditorInput) element); } @Override diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/reconciler/XtextReconciler.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/reconciler/XtextReconciler.java index 8adf988..d8a09d2 100644 --- a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/reconciler/XtextReconciler.java +++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/reconciler/XtextReconciler.java @@ -32,9 +32,9 @@ import org.eclipse.xtext.ui.core.editor.model.XtextDocumentUtil; * performed for each DR in the queue. We overcome this situation by writing our * own reconciler that only creates ReplaceRegions which can always be merged, * such that we have to call the partial parser only once. - * + * * Additionally, we simplify the reconciler by using the Job API. - * + * * @author Jan Köhnlein - Initial contribution and API */ public class XtextReconciler extends Job implements IReconciler { @@ -44,9 +44,9 @@ public class XtextReconciler extends Job implements IReconciler { private boolean isInstalled; private ITextViewer textViewer; private TextInputListener textInputListener; - private DocumentListener documentListener; + private final DocumentListener documentListener; private ReplaceRegion pendingReplaceRegion; - private Object pendingReplaceRegionLock; + private final Object pendingReplaceRegionLock; private int delay; private IReconcilingStrategy strategy; @@ -59,7 +59,7 @@ public class XtextReconciler extends Job implements IReconciler { public void documentChanged(DocumentEvent event) { handleDocumentChanged(event); } - + public void performNecessaryUpdates(Processor processor) { final IXtextDocument document = XtextDocumentUtil.get(textViewer); if (document != null) { @@ -176,8 +176,7 @@ public class XtextReconciler extends Job implements IReconciler { if (log.isDebugEnabled()) { log.debug("Preparing reconciliation."); } - - IStatus result = null; + final IXtextDocument document = XtextDocumentUtil.get(textViewer); if (document != null) { final ReplaceRegion replaceRegionToBeProcessed = getAndResetReplaceRegion(); @@ -186,8 +185,8 @@ public class XtextReconciler extends Job implements IReconciler { } } if (log.isDebugEnabled()) - log.debug("Reconciliation finished. Time required: " + (System.currentTimeMillis() - start)); - return (result != null) ? result : Status.OK_STATUS; + log.debug("Reconciliation finished. Time required: " + (System.currentTimeMillis() - start)); + return Status.OK_STATUS; } private ReplaceRegion getAndResetReplaceRegion() { diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/utils/ValidationJob.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/utils/ValidationJob.java index 542b7e5..142b82e 100644 --- a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/utils/ValidationJob.java +++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/utils/ValidationJob.java @@ -26,9 +26,9 @@ import org.eclipse.xtext.ui.core.editor.model.UnitOfWork; import org.eclipse.xtext.validator.CheckMode; /** - * + * * @author Dennis Hübner - Initial contribution and API - * + * */ public final class ValidationJob extends Job { private static final Logger log = Logger.getLogger(ValidationJob.class); @@ -39,27 +39,25 @@ public final class ValidationJob extends Job { /** * Constructs a ValidationJob with a specified {@link CheckMode} - * + * * @param xtextEditor * @param checkMode */ public ValidationJob(XtextEditor xtextEditor, CheckMode checkMode) { - this(xtextEditor.getDocument(), (IFile) (IFile.class.isInstance(xtextEditor.getResource()) ? xtextEditor - .getResource() : null), checkMode); + this(xtextEditor.getDocument(), (IFile) (IFile.class.isInstance(xtextEditor.getResource()) ? + xtextEditor.getResource() : null), checkMode); } /** * Constructs a ValidationJob with a specified {@link CheckMode} - * + * * @param xtextDocument * @param iFile * @param checkMode */ public ValidationJob(IXtextDocument xtextDocument, IFile iFile, CheckMode checkMode) { super("Xtext validation"); - if (iFile == null) { - throw new IllegalStateException("IFile should not be null"); - } + this.xtextDocument = xtextDocument; this.iFile = iFile; this.checkMode = checkMode; @@ -68,6 +66,10 @@ public final class ValidationJob extends Job { @Override protected IStatus run(IProgressMonitor monitor) { log.debug("Starting Xtext Validation with CheckMode: " + checkMode); + if (iFile == null) { // file may be null, if it was opend from an IStorageEditorInput + log.debug("Aborting Xtext Validation with CheckMode: " + checkMode + " because file does not exist."); + return Status.OK_STATUS; + } final List<Map<String, Object>> issues = xtextDocument.readOnly(new UnitOfWork<List<Map<String, Object>>>() { public List<Map<String, Object>> exec(XtextResource resource) throws Exception { return XtextResourceChecker.check(resource, Collections.singletonMap(CheckMode.KEY, checkMode)); |

