26
26
import com .diffplug .jscriptbox .Language ;
27
27
28
28
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
+ */
30
35
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 ) {
31
41
return map -> {
32
42
ScriptEngine jsEngine = new ScriptEngineManager ().getEngineByName ("nashorn" );
33
43
ScriptContext context = jsEngine .getContext ();
@@ -36,30 +46,45 @@ public static Language language() {
36
46
context .setAttribute (mapName , map , ScriptContext .ENGINE_SCOPE );
37
47
38
48
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
+ }
40
63
builder .append ("var " );
41
- builder .append (normalize ( entry . getKey ()) );
64
+ builder .append (key );
42
65
builder .append ("=" );
43
66
builder .append (mapName );
44
67
builder .append (".get('" );
45
- builder .append (entry . getKey () );
68
+ builder .append (key );
46
69
builder .append ("');\n " );
47
- });
70
+ }
48
71
builder .append ("delete " + mapName + ";\n " );
49
72
jsEngine .eval (builder .toString ());
50
73
return jsEngine ;
51
74
};
52
75
}
53
76
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 );
60
85
}
61
86
62
- private static final Set <String > restrictedWords = new HashSet <>(Arrays .asList (
87
+ private static final Set <String > reservedKeywords = new HashSet <>(Arrays .asList (
63
88
// JavaScript Reserved Words
64
89
"abstract" , "arguments" , "boolean" , "break" , "byte" ,
65
90
"case" , "catch" , "char" , "class" , "const" ,
0 commit comments