summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormclay2008-12-10 17:26:29 (EST)
committer sefftinge2008-12-10 17:26:29 (EST)
commit20de41ac1e8f0a7a991fbebd1868f664eb606a1e (patch)
tree38ed35f464973882071e5fec26e93b5b646d42a3
parent2bed6d8b200271e61344b22c0b176b7e24b8d143 (diff)
downloadorg.eclipse.xtext-20de41ac1e8f0a7a991fbebd1868f664eb606a1e.zip
org.eclipse.xtext-20de41ac1e8f0a7a991fbebd1868f664eb606a1e.tar.gz
org.eclipse.xtext-20de41ac1e8f0a7a991fbebd1868f664eb606a1e.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/plugin.xml39
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/OpenDeclarationAction.java134
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextHyperlinkDetector.java124
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/handler/OpenDeclarationHandler.java29
4 files changed, 224 insertions, 102 deletions
diff --git a/plugins/org.eclipse.xtext.ui.core/plugin.xml b/plugins/org.eclipse.xtext.ui.core/plugin.xml
index 829b444..d194ace 100644
--- a/plugins/org.eclipse.xtext.ui.core/plugin.xml
+++ b/plugins/org.eclipse.xtext.ui.core/plugin.xml
@@ -12,6 +12,14 @@
label="Syntax">
</keyword>
</extension>
+ <extension
+ point="org.eclipse.ui.commands">
+ <command
+ id="org.eclipse.xtext.ui.core.editor.handler.openDeclaration"
+ name="Open Declaration"
+ description="Opens the declaration for the currently selected CrossReference">
+ </command>
+ </extension>
<extension
point="org.eclipse.ui.handlers">
<handler
@@ -23,6 +31,15 @@
</reference>
</activeWhen>
</handler>
+ <handler
+ class="org.eclipse.xtext.ui.core.editor.handler.OpenDeclarationHandler"
+ commandId="org.eclipse.xtext.ui.core.editor.handler.openDeclaration">
+ <activeWhen>
+ <reference
+ definitionId="isActiveEditorAnInstanceOfXtextEditor">
+ </reference>
+ </activeWhen>
+ </handler>
</extension>
<extension
point="org.eclipse.core.expressions.definitions">
@@ -38,10 +55,9 @@
</extension>
<extension
point="org.eclipse.ui.menus">
- <menuContribution
+ <menuContribution
locationURI="popup:#TextEditorContext?after=additions">
- <command
- commandId="org.eclipse.ui.edit.text.contentAssist.proposals"
+ <command commandId="org.eclipse.ui.edit.text.contentAssist.proposals"
style="push">
<visibleWhen
checkEnabled="false">
@@ -51,8 +67,23 @@
</visibleWhen>
</command>
</menuContribution>
+ <menuContribution locationURI="popup:#TextEditorContext?after=group.open">
+ <command commandId="org.eclipse.xtext.ui.core.editor.handler.openDeclaration">
+ <visibleWhen checkEnabled="false">
+ <reference definitionId="isActiveEditorAnInstanceOfXtextEditor"/>
+ </visibleWhen>
+ </command>
+ </menuContribution>
+ </extension>
+ <extension
+ point="org.eclipse.ui.bindings">
+ <key
+ contextId="org.eclipse.ui.textEditorScope"
+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+ sequence="F3"
+ commandId="org.eclipse.xtext.ui.core.editor.handler.openDeclaration">
+ </key>
</extension>
-
<!--extension
point="org.eclipse.ui.workbench.texteditor.hyperlinkDetectors">
<hyperlinkDetector
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/OpenDeclarationAction.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/OpenDeclarationAction.java
new file mode 100644
index 0000000..a105d28
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/OpenDeclarationAction.java
@@ -0,0 +1,134 @@
+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.action.Action;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.widgets.Control;
+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.service.ServiceRegistry;
+import org.eclipse.xtext.ui.core.editor.model.IXtextDocument;
+import org.eclipse.xtext.ui.core.editor.model.UnitOfWork;
+
+/**
+ * This action opens a <code>XtextEditor</code> on a selected <code>CrossReference</code> element.
+ *
+ * @author Michael Clay - Initial contribution and API
+ *
+ * @see org.eclipse.jface.action.Action
+ */
+public class OpenDeclarationAction extends Action {
+
+ // logger available to subclasses
+ protected final Logger logger = Logger.getLogger(getClass());
+
+ private XtextEditor xtextEditor;
+
+ private LeafNode currentNode;
+
+ public OpenDeclarationAction(XtextEditor xtextEditor) {
+ this.xtextEditor = xtextEditor;
+ }
+
+ public OpenDeclarationAction(LeafNode currentNode) {
+ this.currentNode = currentNode;
+ this.xtextEditor = (XtextEditor) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
+ .getActiveEditor();
+ }
+
+ @Override
+ public void run() {
+
+ if (currentNode == null) {
+
+ StyledText styledText = (StyledText) this.xtextEditor.getAdapter(Control.class);
+
+ int caretOffset = styledText.getCaretOffset();
+
+ IXtextDocument document = this.xtextEditor.getDocument();
+
+ CompositeNode rootNode = getRootNode(document);
+
+ this.currentNode = (LeafNode) ParseTreeUtil.getCurrentOrFollowingNodeByOffset(rootNode, caretOffset);
+ }
+
+ if (currentNode != null && currentNode.getGrammarElement() instanceof CrossReference) {
+
+ ILinkingService linkingService = ServiceRegistry.getService(this.xtextEditor.getScope(),
+ ILinkingService.class);
+
+ EObject semanticModel = NodeUtil.getNearestSemanticObject(currentNode);
+
+ EReference eReference = GrammarUtil.getReference((CrossReference) currentNode.getGrammarElement(),
+ semanticModel.eClass());
+
+ List<EObject> linkedObjects = linkingService.getLinkedObjects(semanticModel, eReference, currentNode);
+
+ if (!linkedObjects.isEmpty()) {
+
+ EObject referenceEObject = linkedObjects.iterator().next();
+
+ 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/XtextHyperlinkDetector.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextHyperlinkDetector.java
index 6b199ed..4fd8837 100644
--- 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
@@ -8,34 +8,17 @@
*******************************************************************************/
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.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;
@@ -57,99 +40,44 @@ public class XtextHyperlinkDetector implements IHyperlinkDetector {
/*
* (non-Javadoc)
- *
- * @see
- * org.eclipse.jface.text.hyperlink.IHyperlinkDetector#detectHyperlinks(
- * org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion,
- * boolean)
+ * @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) {
// TODO: should all of this be part of the read transaction?
- CompositeNode rootNode = getRootNode(textViewer.getDocument());
- LeafNode currentNode = (LeafNode) ParseTreeUtil.getCurrentOrFollowingNodeByOffset(rootNode, region.getOffset());
-
- if (currentNode.getGrammarElement() instanceof CrossReference) {
-
- EObject semanticModel = NodeUtil.getNearestSemanticObject(currentNode);
- EReference eReference = GrammarUtil.getReference((CrossReference) currentNode.getGrammarElement(),
- semanticModel.eClass());
- EObject linkMe = null;
- if (eReference.isMany()) {
- List<?> values = (List<?>) semanticModel.eGet(eReference);
- if (!values.isEmpty() && values.get(0) instanceof EObject)
- linkMe = (EObject) values.get(0);
- } else {
- Object value = semanticModel.eGet(eReference);
- if (value instanceof EObject)
- linkMe = (EObject) value;
- }
-// List<EObject> linkedObjects = this.linkingService.getLinkedObjects(semanticModel, eReference, currentNode);
-
- if (linkMe != null) {
- return createXtextHyperlink(currentNode, linkMe);
- }
-
- }
-
- 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;
+ CompositeNode rootNode = ((IXtextDocument) textViewer.getDocument()).readOnly(new UnitOfWork<CompositeNode>() {
+ public CompositeNode exec(XtextResource resource) throws Exception {
+ IParseResult parseResult = resource.getParseResult();
+ Assert.isNotNull(parseResult);
+ return parseResult.getRootNode();
}
+ });
+
+ final LeafNode currentNode =
+ (LeafNode) ParseTreeUtil.getCurrentOrFollowingNodeByOffset(rootNode, region.getOffset());
- 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 (currentNode.getGrammarElement() instanceof CrossReference) {
+ return new IHyperlink[] { new IHyperlink() {
- if (openEditor instanceof ITextEditor) {
+ public IRegion getHyperlinkRegion() {
+ return new Region(currentNode.getTotalOffset(), currentNode.getTotalLength());
+ }
- 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);
- }
+ public String getHyperlinkText() {
+ return currentNode.getText();
}
- }
- } };
- }
- private CompositeNode getRootNode(IDocument document) {
+ public String getTypeLabel() {
+ return null;
+ }
- 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();
- }
- });
+ public void open() {
+ new OpenDeclarationAction(currentNode).run();
+ }
+ } };
+ }
- return rootNode;
+ return null;
}
}
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/handler/OpenDeclarationHandler.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/handler/OpenDeclarationHandler.java
new file mode 100644
index 0000000..63ecfc2
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/handler/OpenDeclarationHandler.java
@@ -0,0 +1,29 @@
+package org.eclipse.xtext.ui.core.editor.handler;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.xtext.ui.core.editor.OpenDeclarationAction;
+import org.eclipse.xtext.ui.core.editor.XtextEditor;
+
+/**
+ * Represents a declarative handler contributed with the 'org.eclipse.ui.handlers'
+ * extension-point which simply delegates to {@link OpenDeclarationAction}.
+ * <p/>
+ * Note: this handler should only be enabled if the current active editor is an instance of <code>XtextEditor</code>.
+ *
+ * @author Michael Clay - Initial contribution and API
+ *
+ * @see org.eclipse.core.commands.AbstractHandler
+ */
+public class OpenDeclarationHandler extends AbstractHandler {
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+ */
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ new OpenDeclarationAction((XtextEditor) HandlerUtil.getActiveEditor(event)).run();
+ return this;
+ }
+}