From d835e0652e72f28308cba6f5cc302f8acf0f1775 Mon Sep 17 00:00:00 2001 From: angelozerr Date: Mon, 10 Aug 2015 18:05:02 +0200 Subject: [PATCH] Double click on Tern Explorer open the declared variable, function. See https://github.com/angelozerr/tern.java/issues/289 --- .../server/protocol/IJSONObjectHelper.java | 1 + .../src/tern/server/protocol/JsonHelper.java | 2 +- .../server/protocol/MinimalJSONHelper.java | 4 +++ .../tern/server/protocol/outline/JSNode.java | 17 ++++++++-- .../server/protocol/outline/JSNodeRoot.java | 2 +- .../outline/TernOutlineResultProcessor.java | 6 +++- .../tern/server/rhino/RhinoTernServer.java | 5 +++ .../tern/node_modules/tern-outline/outline.js | 31 ++++++++++++++----- .../ui/views/TernContentOutlinePage.java | 27 ++++++++++++++++ .../ui/views/TernExplorerLabelProvider.java | 2 +- 10 files changed, 84 insertions(+), 13 deletions(-) diff --git a/core/tern.core/src/tern/server/protocol/IJSONObjectHelper.java b/core/tern.core/src/tern/server/protocol/IJSONObjectHelper.java index cb1221ef4..b3441bb11 100644 --- a/core/tern.core/src/tern/server/protocol/IJSONObjectHelper.java +++ b/core/tern.core/src/tern/server/protocol/IJSONObjectHelper.java @@ -24,4 +24,5 @@ public interface IJSONObjectHelper { boolean getBoolean(Object jsonObj, String name, boolean defaultValue); + Long getLong(Object jsonObject, String name); } diff --git a/core/tern.core/src/tern/server/protocol/JsonHelper.java b/core/tern.core/src/tern/server/protocol/JsonHelper.java index 12514b1b5..ed2e002fe 100644 --- a/core/tern.core/src/tern/server/protocol/JsonHelper.java +++ b/core/tern.core/src/tern/server/protocol/JsonHelper.java @@ -58,7 +58,7 @@ public static Long getLong(JsonObject json, String name) { JsonValue value = json.get(name); return value == null ? null : value.asLong(); } - + public static Object getValue(JsonValue value) { if (value == null) { return null; diff --git a/core/tern.core/src/tern/server/protocol/MinimalJSONHelper.java b/core/tern.core/src/tern/server/protocol/MinimalJSONHelper.java index 6f37aae24..54f7aa344 100644 --- a/core/tern.core/src/tern/server/protocol/MinimalJSONHelper.java +++ b/core/tern.core/src/tern/server/protocol/MinimalJSONHelper.java @@ -63,4 +63,8 @@ public boolean getBoolean(Object jsonObject, String name, boolean defaultValue) return JsonHelper.getBoolean((JsonObject) jsonObject, name, defaultValue); } + @Override + public Long getLong(Object jsonObject, String name) { + return JsonHelper.getLong((JsonObject) jsonObject, name); + } } \ No newline at end of file diff --git a/core/tern.core/src/tern/server/protocol/outline/JSNode.java b/core/tern.core/src/tern/server/protocol/outline/JSNode.java index 5d8ca6954..be1aff184 100644 --- a/core/tern.core/src/tern/server/protocol/outline/JSNode.java +++ b/core/tern.core/src/tern/server/protocol/outline/JSNode.java @@ -7,16 +7,22 @@ public class JSNode { private final String name; private final String type; - private JSNode parent; + private final Long start; + private final Long end; + private final JSNode parent; private final List children; - public JSNode(String name, String type, JSNode parent) { + public JSNode(String name, String type, Long start, Long end, JSNode parent) { this.name = name; this.type = type; + this.start = start; + this.end = end; this.children = new ArrayList(); if (parent != null) { this.parent = parent; parent.addChild(this); + } else { + this.parent = null; } } @@ -44,4 +50,11 @@ public void addChild(JSNode node) { children.add(node); } + public Long getStart() { + return start; + } + + public Long getEnd() { + return end; + } } diff --git a/core/tern.core/src/tern/server/protocol/outline/JSNodeRoot.java b/core/tern.core/src/tern/server/protocol/outline/JSNodeRoot.java index 4b0a209be..3b9c7b489 100644 --- a/core/tern.core/src/tern/server/protocol/outline/JSNodeRoot.java +++ b/core/tern.core/src/tern/server/protocol/outline/JSNodeRoot.java @@ -3,7 +3,7 @@ public class JSNodeRoot extends JSNode { public JSNodeRoot() { - super("#Root", null, null); + super("#Root", null, null, null, null); } } diff --git a/core/tern.core/src/tern/server/protocol/outline/TernOutlineResultProcessor.java b/core/tern.core/src/tern/server/protocol/outline/TernOutlineResultProcessor.java index b6ae30fc3..67f975bf9 100644 --- a/core/tern.core/src/tern/server/protocol/outline/TernOutlineResultProcessor.java +++ b/core/tern.core/src/tern/server/protocol/outline/TernOutlineResultProcessor.java @@ -35,12 +35,16 @@ public void process(TernDoc doc, IJSONObjectHelper jsonObjectHelper, Object json protected void addChildren(Iterable jsonNodes, JSNode parent, IJSONObjectHelper helper) { String name = null; String type = null; + Long start = null; + Long end = null; JSNode node = null; Iterable jsonChildren; for (Object jsonNode : jsonNodes) { name = helper.getText(jsonNode, "name"); type = helper.getText(jsonNode, "type"); - node = new JSNode(name, type, parent); + start = helper.getLong(jsonNode, "start"); + end = helper.getLong(jsonNode, "end"); + node = new JSNode(name, type, start, end, parent); jsonChildren = helper.getList(jsonNode, CHILDREN_FIELD_NAME); // $NON-NLS-1$ if (jsonChildren != null) { addChildren(jsonChildren, node, helper); diff --git a/core/tern.server.rhino/src/tern/server/rhino/RhinoTernServer.java b/core/tern.server.rhino/src/tern/server/rhino/RhinoTernServer.java index 9bece54d7..223cd4f9e 100644 --- a/core/tern.server.rhino/src/tern/server/rhino/RhinoTernServer.java +++ b/core/tern.server.rhino/src/tern/server/rhino/RhinoTernServer.java @@ -259,6 +259,11 @@ public String getText(Object jsonObj, String property) { } return text.toString(); } + + @Override + public Long getLong(Object jsonObject, String name) { + return null; + } @Override public boolean isString(Object value) { diff --git a/core/ternjs/node_modules/tern/node_modules/tern-outline/outline.js b/core/ternjs/node_modules/tern/node_modules/tern-outline/outline.js index 766e01a39..26e78df85 100644 --- a/core/ternjs/node_modules/tern/node_modules/tern-outline/outline.js +++ b/core/ternjs/node_modules/tern/node_modules/tern-outline/outline.js @@ -33,6 +33,8 @@ } else if(node.id) { // This is a Function return node.id.name ? node.id.name : "function"; + } else if(node.value) { + return node.value; } else { return node.name; } @@ -64,15 +66,22 @@ for (var i = 0, len = node.declarations.length; i < len; i++) { var decl = node.declarations[i]; var parent = st.parent, scope = st.scope, type = infer.expressionType({node: decl.id, state: scope}); - addChild(decl.id, type, parent); + if (isObjectLiteral(type) || isFunctionType(type)) { + var obj = parent[parent.length -1]; + if (obj) { + obj.name = getNodeName(decl.id); + obj.start = Number(node.start); + obj.end = Number(node.end); + } + } else { + addChild(decl.id, type, parent); + } } }, - MemberExpression: function (node, scope) { - //console.log(node) - /*collect(node.id, 'FunctionDeclaration'); - for (var i = 0, len = node.params.length; i < len; i++) { - collect(node.params[i], 'ArgumentDeclaration'); - }*/ + Property: function (node, st) { + var parent = st.parent, scope = st.scope; + var type = node.value && node.value.name != "✖" ? infer.expressionType({node: node.value, state: scope}) : null; + addChild(node.key, type, parent); } } } @@ -96,6 +105,14 @@ for (var i = 0; i < node.params.length; ++i) c(node.params[i], scope); c(node.body, scope, "ScopeBody"); + }, + ObjectExpression: function (node, st, c) { + var parent = st.parent, scope = st.scope, type = infer.expressionType({node: node.id ? node.id : node, state: scope}); + var obj = addChild(node, type, parent); + parent = obj.children = []; + var scope = {parent: parent, scope: st.scope}; + for (var i = 0; i < node.properties.length; ++i) + c(node.properties[i], scope); } }); diff --git a/eclipse/tern.eclipse.ide.ui/src/tern/eclipse/ide/internal/ui/views/TernContentOutlinePage.java b/eclipse/tern.eclipse.ide.ui/src/tern/eclipse/ide/internal/ui/views/TernContentOutlinePage.java index a2aad9982..794f3afdf 100644 --- a/eclipse/tern.eclipse.ide.ui/src/tern/eclipse/ide/internal/ui/views/TernContentOutlinePage.java +++ b/eclipse/tern.eclipse.ide.ui/src/tern/eclipse/ide/internal/ui/views/TernContentOutlinePage.java @@ -1,10 +1,14 @@ package tern.eclipse.ide.internal.ui.views; +import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; @@ -15,7 +19,9 @@ import tern.eclipse.ide.core.TernCorePlugin; import tern.eclipse.ide.core.resources.TernDocumentFile; import tern.eclipse.ide.internal.ui.TernUIMessages; +import tern.eclipse.ide.ui.utils.EditorUtils; import tern.server.TernPlugin; +import tern.server.protocol.outline.JSNode; import tern.server.protocol.outline.TernOutlineQuery; public class TernContentOutlinePage extends ContentOutlinePage { @@ -37,6 +43,27 @@ public void createControl(Composite parent) { super.createControl(parent); getTreeViewer().setContentProvider(new TernExplorerContentProvider(this)); getTreeViewer().setLabelProvider(new DelegatingStyledCellLabelProvider(new TernExplorerLabelProvider())); + getTreeViewer().addDoubleClickListener(new IDoubleClickListener() { + + @Override + public void doubleClick(DoubleClickEvent event) { + IStructuredSelection selection = (IStructuredSelection) event.getSelection(); + if (!selection.isEmpty()) { + if (selection.getFirstElement() instanceof JSNode) { + JSNode node = (JSNode) selection.getFirstElement(); + IFile file = outline.getTernFile().getFile(); + Long start = node.getStart(); + Long end = node.getEnd(); + EditorUtils.openInEditor( + file, + start != null ? start.intValue() : -1, + start != null && end != null ? end.intValue() + - start.intValue() : -1, true); + + } + } + } + }); getTreeViewer().setAutoExpandLevel(TreeViewer.ALL_LEVELS); refreshOutline(); } diff --git a/eclipse/tern.eclipse.ide.ui/src/tern/eclipse/ide/internal/ui/views/TernExplorerLabelProvider.java b/eclipse/tern.eclipse.ide.ui/src/tern/eclipse/ide/internal/ui/views/TernExplorerLabelProvider.java index c7e8ec691..960f5778a 100644 --- a/eclipse/tern.eclipse.ide.ui/src/tern/eclipse/ide/internal/ui/views/TernExplorerLabelProvider.java +++ b/eclipse/tern.eclipse.ide.ui/src/tern/eclipse/ide/internal/ui/views/TernExplorerLabelProvider.java @@ -34,7 +34,7 @@ public Image getImage(Object element) { public StyledString getStyledText(Object element) { if (element instanceof JSNode) { JSNode node = ((JSNode) element); - StyledString buff = new StyledString(node.getName()); + StyledString buff = new StyledString(StringUtils.isEmpty(node.getName()) ? "" : node.getName()); String type = node.getType(); if (!StringUtils.isEmpty(type)) { buff.append(" : ", StyledString.DECORATIONS_STYLER);