Skip to content

Commit

Permalink
Implement tern server with nashorn. See
Browse files Browse the repository at this point in the history
  • Loading branch information
angelozerr committed Nov 6, 2015
1 parent efbf725 commit c4cc0ff
Show file tree
Hide file tree
Showing 66 changed files with 34,447 additions and 0 deletions.
7 changes: 7 additions & 0 deletions core/tern.server.nashorn/.classpath
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src/"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
2 changes: 2 additions & 0 deletions core/tern.server.nashorn/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/bin
/target
34 changes: 34 additions & 0 deletions core/tern.server.nashorn/.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>tern.server.nashorn</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
17 changes: 17 additions & 0 deletions core/tern.server.nashorn/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Bundle-SymbolicName: tern.server.nashorn;singleton:=true
Bundle-Version: 1.1.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Require-Bundle: tern.core
Bundle-ClassPath: .
Import-Package: com.eclipsesource.json;version="[0.9.4,0.9.5)",
com.eclipsesource.v8,
com.eclipsesource.v8.utils,
org.osgi.framework
Bundle-ActivationPolicy: lazy
Bundle-Activator: tern.server.nashorn.Activator
Export-Package: tern.server.nashorn
47 changes: 47 additions & 0 deletions core/tern.server.nashorn/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
tern.server.nashorn
=========

[tern.server.nashorn](https://github.com/angelozerr/tern.java/tree/master/core/tern.server.nashorn) is a tern server implementation based on nashorn.

## Sample with SWT

[tern.eclipse.swt.samples](https://github.com/angelozerr/tern.java/tree/master/eclipse/tern.eclipse.swt.samples) provides a sample with a simple SWT Text & the Nashorn tern server implementation. To use it :

* import the following projects in your workspace :

* the Nashorn bundle according your OS. If you have Windows 64 bits you can use https://github.com/angelozerr/tern.java/tree/master/thirdparties/nashorn/nashorn_win32_x86_64
* minimal-json. You can find it at https://github.com/angelozerr/tern.java/tree/master/thirdparties/minimal-json
* tern.core
* tern.eclipse
* tern.eclipse.swt.samples
* tern.server.nashorn
* ternjs

* Run the main https://github.com/angelozerr/tern.java/blob/master/eclipse/tern.eclipse.swt.samples/src/tern/eclipse/swt/samples/nashorn/NashornTernEditor.java

You can play with Ctrl+Space to open tern completion :

![SWT Tern Editor](https://github.com/angelozerr/tern.java/wiki/images/SWTTernEditor.png)


# Nashorn Integration

* no need to implement require AMD function, because ternjs is able to execute without node.js inside Web Browser. The Nashorn tern server implementation works like if ternjs was executed in a Web Browser.

* don't use V80bject because we need every time release it. I have just use String (which follows JSON format) for tern request/response.

* implement basic console.log. I think Nashorn should provide that.

# Limitation

* not tested, but is it working if there are several Nashorn tern server (several v8 instances)? Because in Eclipse IDE, there are a tern server per Eclipse project.
* some tern plugin requires **require** node function to support their features like :

* the **node** tern plugin which uses require to retrieve list of node module by completion inside require.
* tern-closure which works only in node.js context
* I will implement soon angular completion for templateUrl which will use require('fs') to retrieve list of HTML files.

# TODO

* clean code!
* integrate the thern server Nashorn inside Eclipse IDE
5 changes: 5 additions & 0 deletions core/tern.server.nashorn/build.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
plugin.properties
12 changes: 12 additions & 0 deletions core/tern.server.nashorn/plugin.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
###############################################################################
# Copyright (c) 2013 Angelo Zerr 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
#
# Contributors:
# Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation
###############################################################################
pluginName=Tern - Server - Nashorn
providerName=Angelo ZERR
10 changes: 10 additions & 0 deletions core/tern.server.nashorn/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>tern.server.nashorn</artifactId>
<packaging>eclipse-plugin</packaging>
<parent>
<groupId>fr.opensagres.js</groupId>
<artifactId>core</artifactId>
<version>1.1.0-SNAPSHOT</version>
</parent>
</project>
47 changes: 47 additions & 0 deletions core/tern.server.nashorn/src/tern/server/nashorn/Activator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Copyright (c) 2013-2014 Angelo ZERR.
* 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
*
* Contributors:
* Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
*/
package tern.server.nashorn;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class Activator implements BundleActivator {

public static final String PLUGIN_ID = "tern.server.nashorn";

private static BundleContext context;

static BundleContext getContext() {
return context;
}

/*
* (non-Javadoc)
*
* @see
* org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext
* )
*/
public void start(BundleContext bundleContext) throws Exception {
Activator.context = bundleContext;
}

/*
* (non-Javadoc)
*
* @see
* org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext bundleContext) throws Exception {
Activator.context = null;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/**
* Copyright (c) 2013-2015 Angelo ZERR.
* 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
*
* Contributors:
* Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
*/
package tern.server.nashorn;

import java.util.List;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import com.eclipsesource.json.Json;
import com.eclipsesource.json.JsonObject;

import tern.ITernProject;
import tern.TernException;
import tern.server.AbstractScriptEngineTernServer;
import tern.server.IResponseHandler;
import tern.server.protocol.IJSONObjectHelper;
import tern.server.protocol.MinimalJSONHelper;
import tern.server.protocol.TernDoc;
import tern.server.protocol.html.ScriptTagRegion;
import tern.utils.IOUtils;

/**
* Tern server implemented with Nashorn.
*
*/
public class NashornTernServer extends AbstractScriptEngineTernServer {

private ScriptEngine engine;

public NashornTernServer(ITernProject project) {
super(project);
}

@Override
public void addFile(String name, String text, ScriptTagRegion[] tags) {
TernDoc doc = new TernDoc();
doc.addFile(name, text, tags, null);
try {
request(doc);
} catch (TernException e) {
e.printStackTrace();
}
}

@Override
public void request(TernDoc doc, IResponseHandler handler) {
try {
JsonObject data = request(doc);
handler.onSuccess(data, null);
} catch (Exception e) {
handler.onError(e.getMessage(), e);
}
}

private synchronized JsonObject request(TernDoc doc) throws TernException {
ScriptEngine engine = getEngine();
try {
String script = new StringBuilder("server.request(").append(doc.toString()).append(");").toString();
String json = (String) engine.eval(script);
return Json.parse(json).asObject();
} catch (Throwable e) {
throw new TernException(e);
}
}

@Override
public IJSONObjectHelper getJSONObjectHelper() {
return MinimalJSONHelper.INSTANCE;
}

@Override
protected void doDispose() {
if (engine != null) {
try {

} finally {
engine = null;
}
}
fireEndServer();
}

public void log(String message, Integer level) {
if (level == 1) {
System.err.println(message);
} else {
System.out.println(message);
}
}

private synchronized ScriptEngine getEngine() throws TernException {
if (engine == null) {
engine = loadEngine();
}
return engine;
}

private ScriptEngine loadEngine() throws TernException {
ScriptEngine engine = null;
TernResources resources = loadTern();
try {
final ScriptEngineManager factory = new ScriptEngineManager();
engine = factory.getEngineByName("nashorn");

// Load tern scripts (acorn + ternjs) + plugins scripts
List<TernResource> scripts = resources.getScripts();
for (TernResource script : scripts) {
eval(script.getFilename(), script.getContent(), engine);
}
// Get defs
String defs = resources.getDefsAsString();

// invocable.(this, "log", "_javaConsole", new Class<?>[] {
// String.class, Integer.class });
eval("tern-nashorn.js", IOUtils.toString(NashornTernServer.class.getResourceAsStream("tern-nashorn.js")),
engine);

StringBuilder script = new StringBuilder("var server = new J2V8TernServer(");
script.append("[");
script.append(defs.toString());
script.append("],");
script.append(getProject().getPlugins() != null ? getProject().getPlugins().toString() : "");
script.append(");");
eval("init.js", script.toString(), engine);
return engine;
} catch (Exception e) {
throw new TernException(e);
}
}

private static void eval(String filename, String content, ScriptEngine engine) throws ScriptException {
engine.put(ScriptEngine.FILENAME, filename);
engine.eval(content);
}

}
Loading

0 comments on commit c4cc0ff

Please sign in to comment.