aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormclay2008-12-08 15:31:47 (EST)
committersefftinge2008-12-08 15:31:47 (EST)
commit7140ccb354c7a073c2ac52ae38942379f961f472 (patch)
tree707a224e7ec086f9b36ce3ee2d857de4aa65f531
parent980d213e4ee9ccbcddc7ce521662f1d89b7b4a7a (diff)
downloadorg.eclipse.xtext-7140ccb354c7a073c2ac52ae38942379f961f472.zip
org.eclipse.xtext-7140ccb354c7a073c2ac52ae38942379f961f472.tar.gz
org.eclipse.xtext-7140ccb354c7a073c2ac52ae38942379f961f472.tar.bz2
ASSIGNED - bug 256402: [UI] Goto declaration
https://bugs.eclipse.org/bugs/show_bug.cgi?id=256402
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextHyperlinkDetector.java151
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewerConfiguration.java40
2 files changed, 190 insertions, 1 deletions
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextHyperlinkDetector.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextHyperlinkDetector.java
new file mode 100644
index 0000000..ec3ff47
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextHyperlinkDetector.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (c) 2008 itemis AG (http://www.itemis.eu) 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
+ *
+ *******************************************************************************/
+package org.eclipse.xtext.ui.core.editor;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.xtext.CrossReference;
+import org.eclipse.xtext.GrammarUtil;
+import org.eclipse.xtext.crossref.ILinkingService;
+import org.eclipse.xtext.parser.IParseResult;
+import org.eclipse.xtext.parsetree.CompositeNode;
+import org.eclipse.xtext.parsetree.LeafNode;
+import org.eclipse.xtext.parsetree.NodeAdapter;
+import org.eclipse.xtext.parsetree.NodeUtil;
+import org.eclipse.xtext.parsetree.ParseTreeUtil;
+import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.ui.core.editor.model.IXtextDocument;
+import org.eclipse.xtext.ui.core.editor.model.UnitOfWork;
+
+/**
+ * Represents an implementation of interface {@link IHyperlinkDetector} to find
+ * and convert {@link CrossReference elements}, at a given location, to
+ * <code>IHyperlink</code>.
+ *
+ * @author Michael Clay - Initial contribution and API
+ * @see org.eclipse.jface.text.hyperlink.IHyperlinkDetector
+ * @see org.eclipse.jface.text.hyperlink.IHyperlink
+ */
+public class XtextHyperlinkDetector implements IHyperlinkDetector {
+
+ // logger available to subclasses
+ protected final Logger logger = Logger.getLogger(getClass());
+
+ private ILinkingService linkingService;
+
+ public XtextHyperlinkDetector(ILinkingService linkingService) {
+ this.linkingService = linkingService;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.text.hyperlink.IHyperlinkDetector#detectHyperlinks(
+ * org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion,
+ * boolean)
+ */
+ public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) {
+
+ CompositeNode rootNode = getRootNode(textViewer.getDocument());
+ LeafNode currentNode = (LeafNode) ParseTreeUtil.getCurrentNodeByOffset(rootNode, region.getOffset());
+
+ if (currentNode.getGrammarElement() instanceof CrossReference) {
+
+ EObject semanticModel = NodeUtil.getNearestSemanticObject(currentNode);
+ EReference eReference = GrammarUtil.getReference((CrossReference) currentNode.getGrammarElement(),
+ semanticModel.eClass());
+ List<EObject> linkedObjects = this.linkingService.getLinkedObjects(semanticModel, eReference, currentNode);
+
+ if (!linkedObjects.isEmpty()) {
+ return createXtextHyperlink(currentNode, linkedObjects.iterator().next());
+ }
+
+ }
+
+ return null;
+ }
+
+ private IHyperlink[] createXtextHyperlink(final LeafNode currentNode, final EObject referenceEObject) {
+
+ return new IHyperlink[] { new IHyperlink() {
+
+ public IRegion getHyperlinkRegion() {
+ return new Region(currentNode.getTotalOffset(), currentNode.getTotalLength());
+ }
+
+ public String getHyperlinkText() {
+ return currentNode.getText();
+ }
+
+ public String getTypeLabel() {
+ return null;
+ }
+
+ public void open() {
+
+ IFile targetFile = ResourcesPlugin.getWorkspace().getRoot().getFile(
+ new Path(referenceEObject.eResource().getURI().toPlatformString(true)));
+
+ if (targetFile != null) {
+
+ IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+
+ try {
+ IEditorPart openEditor = IDE.openEditor(page, targetFile);
+
+ if (openEditor instanceof ITextEditor) {
+
+ NodeAdapter nodeAdapter = NodeUtil.getNodeAdapter(referenceEObject);
+ ((ITextEditor) openEditor).selectAndReveal(nodeAdapter.getParserNode().getOffset(),
+ nodeAdapter.getParserNode().getLength());
+ }
+ }
+ catch (PartInitException partInitException) {
+ logger.error("Error while opening editor part from workbench with file '" + targetFile + "'",
+ partInitException);
+ }
+ }
+ }
+ } };
+ }
+
+ private CompositeNode getRootNode(IDocument document) {
+
+ CompositeNode rootNode = ((IXtextDocument) document).readOnly(new UnitOfWork<CompositeNode>() {
+ public CompositeNode exec(XtextResource resource) throws Exception {
+ IParseResult parseResult = resource.getParseResult();
+ Assert.isNotNull(parseResult);
+ return parseResult.getRootNode();
+ }
+ });
+
+ return rootNode;
+ }
+
+}
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewerConfiguration.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewerConfiguration.java
index abeb18a..d63ba88 100644
--- a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewerConfiguration.java
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewerConfiguration.java
@@ -1,9 +1,16 @@
package org.eclipse.xtext.ui.core.editor;
+import java.util.LinkedList;
+import java.util.List;
+
import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContentAssistant;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
import org.eclipse.jface.text.presentation.PresentationReconciler;
import org.eclipse.jface.text.reconciler.IReconciler;
@@ -11,6 +18,7 @@ import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
import org.eclipse.jface.text.rules.ITokenScanner;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
+import org.eclipse.xtext.crossref.ILinkingService;
import org.eclipse.xtext.service.Inject;
import org.eclipse.xtext.ui.core.editor.reconciler.XtextDocumentReconcileStrategy;
import org.eclipse.xtext.ui.core.editor.reconciler.XtextReconciler;
@@ -19,10 +27,12 @@ public class XtextSourceViewerConfiguration extends TextSourceViewerConfiguratio
@Inject(optional = true)
private IContentAssistant contentAssistant;
-
@Inject(optional = true)
private IContentAssistProcessor contentAssistProcessor;
+
+ @Inject(optional = true)
+ private ILinkingService linkingService;
@Inject(optional = true)
private ITokenScanner tokenScanner;
@@ -45,6 +55,8 @@ public class XtextSourceViewerConfiguration extends TextSourceViewerConfiguratio
xtextReconciler.setDelay(500);
return xtextReconciler;
}
+
+
@Override
public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
@@ -59,5 +71,31 @@ public class XtextSourceViewerConfiguration extends TextSourceViewerConfiguratio
return super.getPresentationReconciler(sourceViewer);
}
}
+
+ @Override
+ public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) {
+ List<IHyperlinkDetector> detectors = new LinkedList<IHyperlinkDetector>();
+ IHyperlinkDetector[] inheritedDetectors = super.getHyperlinkDetectors(sourceViewer);
+ if (inheritedDetectors != null) {
+ for (final IHyperlinkDetector detector : inheritedDetectors) {
+ detectors.add(new IHyperlinkDetector() {
+ public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region,
+ boolean canShowMultipleHyperlinks) {
+ try {
+ return detector.detectHyperlinks(textViewer, region, canShowMultipleHyperlinks);
+ }
+ catch (Throwable e) {
+ // fail safe hyperlink detector - prevent others
+ // from failing
+ }
+ return null;
+ }
+
+ });
+ }
+ }
+ detectors.add(new XtextHyperlinkDetector(this.linkingService));
+ return detectors.toArray(new IHyperlinkDetector[detectors.size()]);
+ }
}