Skip to content

Commit 0faec8c

Browse files
committed
Removed some bad ideas from the API.
1 parent 106f840 commit 0faec8c

File tree

3 files changed

+48
-34
lines changed

3 files changed

+48
-34
lines changed

gradle.properties

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
stable=2.0.0
2-
version=2.1.0-SNAPSHOT
1+
stable=3.0.0
2+
version=3.0.0
33
name=jscriptbox
44
group=com.diffplug.jscriptbox
55
description=JScriptBox: Make your scripting API language-independent
@@ -11,5 +11,8 @@ VER_JAVA=1.8
1111
VER_BINTRAY=1.1
1212
VER_FINDBUGS=3.0.1
1313

14+
# Dependencies
15+
VER_GUAVA=18.0
16+
1417
# Testing
1518
VER_JUNIT=4.12

src/main/java/com/diffplug/jscriptbox/JScriptBox.java

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,36 +34,22 @@ public static JScriptBox create() {
3434
return new JScriptBox();
3535
}
3636

37-
/** Sets all of the properties contained in the given map. Throws an error if one of the entry keys isn't a valid identifier. */
38-
public JScriptBox setAll(Map<String, ?> map) {
39-
for (Map.Entry<String, ?> entry : map.entrySet()) {
40-
set(entry.getKey()).toValue(entry.getValue());
41-
}
42-
return this;
43-
}
44-
45-
/** Sets all of the properties contained in the given map for which the key is a valid identifier. */
46-
public JScriptBox setAllValid(Map<String, ?> map) {
47-
for (Map.Entry<String, ?> entry : map.entrySet()) {
48-
if (isValidIdentifier(entry.getKey())) {
49-
set(entry.getKey()).toValue(entry.getValue());
50-
}
51-
}
52-
return this;
53-
}
54-
5537
/** Sets a name in the script environment to be a value or a function. */
5638
public NameSetter set(String name) {
5739
return new NameSetter(name);
5840
}
5941

60-
/** Checks that the given name is a valid identifier. */
42+
/**
43+
* Checks that the given name is a valid Java identifier. It's still possible that
44+
* the name is a restricted keyword in the scripting language that you are creating a
45+
* binding for, but there's no way to know at this point.
46+
*/
6147
static String checkValidIdentifier(String name) {
6248
Check.that(isValidIdentifier(name), "'%0' is not a valid identifier", name);
6349
return name;
6450
}
6551

66-
/** Checks that the given name is a valid identifier. */
52+
/** Returns true if the given name is a valid Java identifier. */
6753
public static boolean isValidIdentifier(String name) {
6854
return name.length() > 0 &&
6955
Character.isJavaIdentifierStart(name.codePointAt(0)) &&

src/main/java/com/diffplug/jscriptbox/javascript/Nashorn.java

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,18 @@
2626
import com.diffplug.jscriptbox.Language;
2727

2828
public class Nashorn {
29-
/** Language implementation for javascript using the nashorn engine. */
29+
/**
30+
* Language implementation for javascript using the nashorn engine.
31+
* <p>
32+
* If any bindings are created which conflict with reserved
33+
* keywords, an IllegalArgumentException will be thrown.
34+
*/
3035
public static Language language() {
36+
return language(OnReservedKeyword.ERROR);
37+
}
38+
39+
/** Language implementation for javascript using the given policy for resolving any potential conflicts with reserved keywords. */
40+
public static Language language(OnReservedKeyword policy) {
3141
return map -> {
3242
ScriptEngine jsEngine = new ScriptEngineManager().getEngineByName("nashorn");
3343
ScriptContext context = jsEngine.getContext();
@@ -36,30 +46,45 @@ public static Language language() {
3646
context.setAttribute(mapName, map, ScriptContext.ENGINE_SCOPE);
3747

3848
StringBuilder builder = new StringBuilder();
39-
map.entrySet().forEach(entry -> {
49+
for (String key : map.keySet()) {
50+
if (isReserved(key)) {
51+
switch (policy) {
52+
case ERROR:
53+
throw new IllegalArgumentException("'" + key + "' is a reserved keyword.");
54+
case MANGLE:
55+
key = key + "_";
56+
break;
57+
case SKIP:
58+
continue;
59+
default:
60+
throw new IllegalArgumentException("Unhandled enum value '" + policy + "'");
61+
}
62+
}
4063
builder.append("var ");
41-
builder.append(normalize(entry.getKey()));
64+
builder.append(key);
4265
builder.append("=");
4366
builder.append(mapName);
4467
builder.append(".get('");
45-
builder.append(entry.getKey());
68+
builder.append(key);
4669
builder.append("');\n");
47-
});
70+
}
4871
builder.append("delete " + mapName + ";\n");
4972
jsEngine.eval(builder.toString());
5073
return jsEngine;
5174
};
5275
}
5376

54-
private static String normalize(String input) {
55-
if (restrictedWords.contains(input)) {
56-
return "_" + input;
57-
} else {
58-
return input;
59-
}
77+
/** Describes a policy for dealing with reserved keywords. */
78+
public enum OnReservedKeyword {
79+
ERROR, MANGLE, SKIP;
80+
}
81+
82+
/** Returns true if the given identifier is a JavaScript reserved keyword. */
83+
public static boolean isReserved(String word) {
84+
return reservedKeywords.contains(word);
6085
}
6186

62-
private static final Set<String> restrictedWords = new HashSet<>(Arrays.asList(
87+
private static final Set<String> reservedKeywords = new HashSet<>(Arrays.asList(
6388
// JavaScript Reserved Words
6489
"abstract", "arguments", "boolean", "break", "byte",
6590
"case", "catch", "char", "class", "const",

0 commit comments

Comments
 (0)