2626import com .diffplug .jscriptbox .Language ;
2727
2828public 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