From 680d7f89d04a6f771055bcdba13867df270be7d6 Mon Sep 17 00:00:00 2001 From: Douglas Campos Date: Mon, 2 Apr 2012 04:12:18 -0300 Subject: [PATCH] adding support for exposing builtins --- .../main/java/org/dynjs/runtime/DynJS.java | 24 +++++++++---- .../java/org/dynjs/runtime/DynJSConfig.java | 13 +++++++ .../org/dynjs/runtime/loader/Builtin.java | 20 +++++++++++ .../java/org/dynjs/runtime/DynJSTest.java | 36 ++++++++++++++++++- 4 files changed, 85 insertions(+), 8 deletions(-) create mode 100644 dynjs/src/main/java/org/dynjs/runtime/loader/Builtin.java diff --git a/dynjs/src/main/java/org/dynjs/runtime/DynJS.java b/dynjs/src/main/java/org/dynjs/runtime/DynJS.java index 50cbff1e0..3a66554ec 100644 --- a/dynjs/src/main/java/org/dynjs/runtime/DynJS.java +++ b/dynjs/src/main/java/org/dynjs/runtime/DynJS.java @@ -24,24 +24,25 @@ import org.antlr.runtime.tree.CommonTree; import org.antlr.runtime.tree.CommonTreeNodeStream; import org.dynjs.api.Function; +import org.dynjs.api.Scope; import org.dynjs.compiler.DynJSCompiler; import org.dynjs.exception.SyntaxError; -import org.dynjs.parser.ES3Lexer; -import org.dynjs.parser.ES3Parser; -import org.dynjs.parser.ES3Walker; -import org.dynjs.parser.Executor; -import org.dynjs.parser.Statement; +import org.dynjs.parser.*; +import org.dynjs.runtime.loader.Builtin; import java.io.IOException; import java.io.InputStream; import java.util.List; +import java.util.Set; public class DynJS { private final DynJSCompiler compiler; + private final DynJSConfig config; public DynJS(DynJSConfig config) { - compiler = new DynJSCompiler(config); + this.config = config; + compiler = new DynJSCompiler(this.config); } public void eval(DynThreadContext context, String expression) { @@ -90,10 +91,19 @@ private List parseSourceCode(DynThreadContext context, ES3Lexer lexer private void execute(DynThreadContext context, List result) { Script script = compiler.compile(result.toArray(new Statement[]{})); - script.setGlobalScope(context.getScope()); + Scope globalScope = context.getScope(); + initBuiltins(globalScope); + script.setGlobalScope(globalScope); script.execute(context); } + private void initBuiltins(Scope globalScope) { + Set builtins = config.getBuiltins(); + for (Builtin builtin : builtins) { + globalScope.define(builtin.getBindingName(), builtin.getBoundObject()); + } + } + public Function compile(CodeBlock codeBlock, final String[] args) { return this.compiler.compile(new DynFunction(codeBlock) { public String[] getArguments() { diff --git a/dynjs/src/main/java/org/dynjs/runtime/DynJSConfig.java b/dynjs/src/main/java/org/dynjs/runtime/DynJSConfig.java index e6af1dacf..2743c1f91 100644 --- a/dynjs/src/main/java/org/dynjs/runtime/DynJSConfig.java +++ b/dynjs/src/main/java/org/dynjs/runtime/DynJSConfig.java @@ -16,9 +16,15 @@ */ package org.dynjs.runtime; +import org.dynjs.runtime.loader.Builtin; + +import java.util.LinkedHashSet; +import java.util.Set; + public class DynJSConfig { private boolean debug; + private Set builtins = new LinkedHashSet<>(); public void enableDebug() { this.debug = true; @@ -28,4 +34,11 @@ public boolean isDebug() { return debug; } + public void addBuiltin(String bindingName, Object boundObject) { + builtins.add(new Builtin(bindingName, boundObject)); + } + + public Set getBuiltins() { + return builtins; + } } diff --git a/dynjs/src/main/java/org/dynjs/runtime/loader/Builtin.java b/dynjs/src/main/java/org/dynjs/runtime/loader/Builtin.java new file mode 100644 index 000000000..521a51c8e --- /dev/null +++ b/dynjs/src/main/java/org/dynjs/runtime/loader/Builtin.java @@ -0,0 +1,20 @@ +package org.dynjs.runtime.loader; + +public class Builtin { + + private final String bindingName; + private final Object boundObject; + + public Builtin(String bindingName, Object boundObject) { + this.bindingName = bindingName; + this.boundObject = boundObject; + } + + public String getBindingName() { + return bindingName; + } + + public Object getBoundObject() { + return boundObject; + } +} diff --git a/dynjs/src/test/java/org/dynjs/runtime/DynJSTest.java b/dynjs/src/test/java/org/dynjs/runtime/DynJSTest.java index 1ad20816b..56527f675 100644 --- a/dynjs/src/test/java/org/dynjs/runtime/DynJSTest.java +++ b/dynjs/src/test/java/org/dynjs/runtime/DynJSTest.java @@ -17,6 +17,7 @@ package org.dynjs.runtime; import org.dynjs.api.Function; +import org.dynjs.api.Scope; import org.dynjs.exception.ReferenceError; import org.junit.Before; import org.junit.Test; @@ -27,10 +28,11 @@ public class DynJSTest { private DynJS dynJS; private DynThreadContext context; + private DynJSConfig config; @Before public void setUp() { - DynJSConfig config = new DynJSConfig(); + config = new DynJSConfig(); // config.enableDebug(); dynJS = new DynJS(config); context = new DynThreadContext(); @@ -240,6 +242,12 @@ public void testLiteralArray() { check("var x = []; x[33] = 'lol'; var result = x[33] == 'lol';"); } + @Test + public void testBuiltinLoading() { + config.addBuiltin("sample", new BypassFunction()); + check("var result = sample(true);"); + } + private void check(String scriptlet) { check(scriptlet, true); } @@ -250,4 +258,30 @@ private void check(String scriptlet, Boolean expected) { assertThat(result).isEqualTo(expected); } + private class BypassFunction implements Function{ + @Override + public Object call(DynThreadContext context, Object[] arguments) { + return arguments[0]; + } + + @Override + public void setContext(DynThreadContext context) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public Scope getEnclosingScope() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public Object resolve(String name) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void define(String property, Object value) { + //To change body of implemented methods use File | Settings | File Templates. + } + } }