diff --git a/minify.sh b/minify.sh
new file mode 100755
index 00000000..a37c8467
--- /dev/null
+++ b/minify.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+YUI=yuicompressor-2.4.2/build/yuicompressor-2.4.2.jar
+
+# minify spin button
+java -jar $YUI editor/spinbtn/JQuerySpinBtn.js > editor/spinbtn/JQuerySpinBtn.min.js
+
+# minify SVG-edit files
+java -jar $YUI editor/svg-editor.js > editor/svg-editor.min.js
+java -jar $YUI editor/svgcanvas.js > editor/svgcanvas.min.js
+
+
+# CSS files do not work remotely
+# java -jar $YUI editor/spinbtn/JQuerySpinBtn.css > editor/spinbtn/JQuerySpinBtn.min.css
+# java -jar $YUI editor/svg-editor.css > editor/svg-editor.min.css
diff --git a/yuicompressor-2.4.2/ant.properties b/yuicompressor-2.4.2/ant.properties
new file mode 100644
index 00000000..9e4dbfaf
--- /dev/null
+++ b/yuicompressor-2.4.2/ant.properties
@@ -0,0 +1,8 @@
+src.dir = src
+lib.dir = lib
+doc.dir = doc
+build.dir = build
+product.name = yuicompressor
+version.number = 2.4.2
+jar.name = ${product.name}-${version.number}.jar
+dist.package.name = ${product.name}-${version.number}
diff --git a/yuicompressor-2.4.2/build.xml b/yuicompressor-2.4.2/build.xml
new file mode 100644
index 00000000..3836cbe9
--- /dev/null
+++ b/yuicompressor-2.4.2/build.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/Bootstrap.class b/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/Bootstrap.class
new file mode 100644
index 00000000..72f9c98f
Binary files /dev/null and b/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/Bootstrap.class differ
diff --git a/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/CssCompressor.class b/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/CssCompressor.class
new file mode 100644
index 00000000..6f906417
Binary files /dev/null and b/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/CssCompressor.class differ
diff --git a/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/JarClassLoader.class b/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/JarClassLoader.class
new file mode 100644
index 00000000..2446481c
Binary files /dev/null and b/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/JarClassLoader.class differ
diff --git a/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/JavaScriptCompressor.class b/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/JavaScriptCompressor.class
new file mode 100644
index 00000000..3305aa93
Binary files /dev/null and b/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/JavaScriptCompressor.class differ
diff --git a/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/JavaScriptIdentifier.class b/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/JavaScriptIdentifier.class
new file mode 100644
index 00000000..e26a450d
Binary files /dev/null and b/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/JavaScriptIdentifier.class differ
diff --git a/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/JavaScriptToken.class b/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/JavaScriptToken.class
new file mode 100644
index 00000000..c8122046
Binary files /dev/null and b/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/JavaScriptToken.class differ
diff --git a/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/ScriptOrFnScope.class b/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/ScriptOrFnScope.class
new file mode 100644
index 00000000..1fc09257
Binary files /dev/null and b/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/ScriptOrFnScope.class differ
diff --git a/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/YUICompressor$1.class b/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/YUICompressor$1.class
new file mode 100644
index 00000000..02b907ec
Binary files /dev/null and b/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/YUICompressor$1.class differ
diff --git a/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/YUICompressor.class b/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/YUICompressor.class
new file mode 100644
index 00000000..c53963be
Binary files /dev/null and b/yuicompressor-2.4.2/build/classes/com/yahoo/platform/yui/compressor/YUICompressor.class differ
diff --git a/yuicompressor-2.4.2/build/classes/org/mozilla/javascript/Decompiler.class b/yuicompressor-2.4.2/build/classes/org/mozilla/javascript/Decompiler.class
new file mode 100644
index 00000000..7978541b
Binary files /dev/null and b/yuicompressor-2.4.2/build/classes/org/mozilla/javascript/Decompiler.class differ
diff --git a/yuicompressor-2.4.2/build/classes/org/mozilla/javascript/Parser$1.class b/yuicompressor-2.4.2/build/classes/org/mozilla/javascript/Parser$1.class
new file mode 100644
index 00000000..84a22bf4
Binary files /dev/null and b/yuicompressor-2.4.2/build/classes/org/mozilla/javascript/Parser$1.class differ
diff --git a/yuicompressor-2.4.2/build/classes/org/mozilla/javascript/Parser$ParserException.class b/yuicompressor-2.4.2/build/classes/org/mozilla/javascript/Parser$ParserException.class
new file mode 100644
index 00000000..f6e57559
Binary files /dev/null and b/yuicompressor-2.4.2/build/classes/org/mozilla/javascript/Parser$ParserException.class differ
diff --git a/yuicompressor-2.4.2/build/classes/org/mozilla/javascript/Parser.class b/yuicompressor-2.4.2/build/classes/org/mozilla/javascript/Parser.class
new file mode 100644
index 00000000..09433ead
Binary files /dev/null and b/yuicompressor-2.4.2/build/classes/org/mozilla/javascript/Parser.class differ
diff --git a/yuicompressor-2.4.2/build/classes/org/mozilla/javascript/Token.class b/yuicompressor-2.4.2/build/classes/org/mozilla/javascript/Token.class
new file mode 100644
index 00000000..f467deee
Binary files /dev/null and b/yuicompressor-2.4.2/build/classes/org/mozilla/javascript/Token.class differ
diff --git a/yuicompressor-2.4.2/build/classes/org/mozilla/javascript/TokenStream.class b/yuicompressor-2.4.2/build/classes/org/mozilla/javascript/TokenStream.class
new file mode 100644
index 00000000..83b74442
Binary files /dev/null and b/yuicompressor-2.4.2/build/classes/org/mozilla/javascript/TokenStream.class differ
diff --git a/yuicompressor-2.4.2/build/jar/META-INF/MANIFEST.MF b/yuicompressor-2.4.2/build/jar/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..37ee19b6
--- /dev/null
+++ b/yuicompressor-2.4.2/build/jar/META-INF/MANIFEST.MF
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+Ant-Version: Apache Ant 1.6.5
+Created-By: 1.5.0_07-b03 (Sun Microsystems Inc.)
+Main-Class: org.mozilla.javascript.tools.shell.Main
+Class-Path: xbean.jar
+
diff --git a/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/Bootstrap.class b/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/Bootstrap.class
new file mode 100644
index 00000000..72f9c98f
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/Bootstrap.class differ
diff --git a/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/CssCompressor.class b/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/CssCompressor.class
new file mode 100644
index 00000000..6f906417
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/CssCompressor.class differ
diff --git a/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/JarClassLoader.class b/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/JarClassLoader.class
new file mode 100644
index 00000000..2446481c
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/JarClassLoader.class differ
diff --git a/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/JavaScriptCompressor.class b/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/JavaScriptCompressor.class
new file mode 100644
index 00000000..3305aa93
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/JavaScriptCompressor.class differ
diff --git a/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/JavaScriptIdentifier.class b/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/JavaScriptIdentifier.class
new file mode 100644
index 00000000..e26a450d
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/JavaScriptIdentifier.class differ
diff --git a/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/JavaScriptToken.class b/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/JavaScriptToken.class
new file mode 100644
index 00000000..c8122046
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/JavaScriptToken.class differ
diff --git a/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/ScriptOrFnScope.class b/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/ScriptOrFnScope.class
new file mode 100644
index 00000000..1fc09257
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/ScriptOrFnScope.class differ
diff --git a/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/YUICompressor$1.class b/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/YUICompressor$1.class
new file mode 100644
index 00000000..02b907ec
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/YUICompressor$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/YUICompressor.class b/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/YUICompressor.class
new file mode 100644
index 00000000..c53963be
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/com/yahoo/platform/yui/compressor/YUICompressor.class differ
diff --git a/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$IllegalOptionValueException.class b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$IllegalOptionValueException.class
new file mode 100644
index 00000000..6e91bb4e
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$IllegalOptionValueException.class differ
diff --git a/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$NotFlagException.class b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$NotFlagException.class
new file mode 100644
index 00000000..82f271fa
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$NotFlagException.class differ
diff --git a/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$Option$BooleanOption.class b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$Option$BooleanOption.class
new file mode 100644
index 00000000..4c07f459
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$Option$BooleanOption.class differ
diff --git a/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$Option$DoubleOption.class b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$Option$DoubleOption.class
new file mode 100644
index 00000000..7f144fb4
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$Option$DoubleOption.class differ
diff --git a/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$Option$IntegerOption.class b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$Option$IntegerOption.class
new file mode 100644
index 00000000..8241bb1c
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$Option$IntegerOption.class differ
diff --git a/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$Option$LongOption.class b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$Option$LongOption.class
new file mode 100644
index 00000000..ee3c4290
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$Option$LongOption.class differ
diff --git a/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$Option$StringOption.class b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$Option$StringOption.class
new file mode 100644
index 00000000..6eace461
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$Option$StringOption.class differ
diff --git a/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$Option.class b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$Option.class
new file mode 100644
index 00000000..5f30ac9e
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$Option.class differ
diff --git a/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$OptionException.class b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$OptionException.class
new file mode 100644
index 00000000..070d5b38
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$OptionException.class differ
diff --git a/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$UnknownOptionException.class b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$UnknownOptionException.class
new file mode 100644
index 00000000..2d70774c
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$UnknownOptionException.class differ
diff --git a/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$UnknownSuboptionException.class b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$UnknownSuboptionException.class
new file mode 100644
index 00000000..70575256
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser$UnknownSuboptionException.class differ
diff --git a/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser.class b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser.class
new file mode 100644
index 00000000..f73297f7
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/jargs/gnu/CmdLineParser.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/classfile/ByteCode.class b/yuicompressor-2.4.2/build/jar/org/mozilla/classfile/ByteCode.class
new file mode 100644
index 00000000..cd65270b
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/classfile/ByteCode.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/classfile/ClassFileField.class b/yuicompressor-2.4.2/build/jar/org/mozilla/classfile/ClassFileField.class
new file mode 100644
index 00000000..9994b16f
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/classfile/ClassFileField.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/classfile/ClassFileMethod.class b/yuicompressor-2.4.2/build/jar/org/mozilla/classfile/ClassFileMethod.class
new file mode 100644
index 00000000..a2aa1183
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/classfile/ClassFileMethod.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/classfile/ClassFileWriter.class b/yuicompressor-2.4.2/build/jar/org/mozilla/classfile/ClassFileWriter.class
new file mode 100644
index 00000000..fa1b160a
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/classfile/ClassFileWriter.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/classfile/ConstantPool.class b/yuicompressor-2.4.2/build/jar/org/mozilla/classfile/ConstantPool.class
new file mode 100644
index 00000000..b3f5834e
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/classfile/ConstantPool.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/classfile/ExceptionTableEntry.class b/yuicompressor-2.4.2/build/jar/org/mozilla/classfile/ExceptionTableEntry.class
new file mode 100644
index 00000000..244e206c
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/classfile/ExceptionTableEntry.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/classfile/FieldOrMethodRef.class b/yuicompressor-2.4.2/build/jar/org/mozilla/classfile/FieldOrMethodRef.class
new file mode 100644
index 00000000..54db9cb3
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/classfile/FieldOrMethodRef.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Arguments.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Arguments.class
new file mode 100644
index 00000000..ec69bd56
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Arguments.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/BaseFunction.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/BaseFunction.class
new file mode 100644
index 00000000..1fbdd910
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/BaseFunction.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/BeanProperty.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/BeanProperty.class
new file mode 100644
index 00000000..5437a670
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/BeanProperty.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Callable.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Callable.class
new file mode 100644
index 00000000..6c20ee3f
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Callable.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ClassCache.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ClassCache.class
new file mode 100644
index 00000000..804c3c63
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ClassCache.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ClassDefinitionException.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ClassDefinitionException.class
new file mode 100644
index 00000000..d4204c4e
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ClassDefinitionException.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ClassShutter.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ClassShutter.class
new file mode 100644
index 00000000..50bdda2e
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ClassShutter.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/CompilerEnvirons.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/CompilerEnvirons.class
new file mode 100644
index 00000000..ff1d5989
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/CompilerEnvirons.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ConstProperties.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ConstProperties.class
new file mode 100644
index 00000000..864991e6
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ConstProperties.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Context.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Context.class
new file mode 100644
index 00000000..62aca3dd
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Context.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ContextAction.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ContextAction.class
new file mode 100644
index 00000000..66e5a05a
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ContextAction.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ContextFactory$Listener.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ContextFactory$Listener.class
new file mode 100644
index 00000000..99f94b67
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ContextFactory$Listener.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ContextFactory.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ContextFactory.class
new file mode 100644
index 00000000..efe83c11
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ContextFactory.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ContextListener.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ContextListener.class
new file mode 100644
index 00000000..da069e77
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ContextListener.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/DToA.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/DToA.class
new file mode 100644
index 00000000..d34d7828
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/DToA.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Decompiler.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Decompiler.class
new file mode 100644
index 00000000..7978541b
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Decompiler.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/DefaultErrorReporter.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/DefaultErrorReporter.class
new file mode 100644
index 00000000..88925ac2
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/DefaultErrorReporter.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/DefiningClassLoader.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/DefiningClassLoader.class
new file mode 100644
index 00000000..3e592889
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/DefiningClassLoader.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Delegator.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Delegator.class
new file mode 100644
index 00000000..f394e7b6
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Delegator.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/EcmaError.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/EcmaError.class
new file mode 100644
index 00000000..01ec148c
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/EcmaError.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ErrorReporter.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ErrorReporter.class
new file mode 100644
index 00000000..158b59dc
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ErrorReporter.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/EvaluatorException.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/EvaluatorException.class
new file mode 100644
index 00000000..64f3ca76
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/EvaluatorException.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/FieldAndMethods.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/FieldAndMethods.class
new file mode 100644
index 00000000..8eafd78d
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/FieldAndMethods.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Function.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Function.class
new file mode 100644
index 00000000..4248c382
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Function.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/FunctionNode.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/FunctionNode.class
new file mode 100644
index 00000000..5ad22b8c
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/FunctionNode.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/FunctionObject.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/FunctionObject.class
new file mode 100644
index 00000000..3390fdcc
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/FunctionObject.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/GeneratedClassLoader.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/GeneratedClassLoader.class
new file mode 100644
index 00000000..88c146f7
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/GeneratedClassLoader.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/IRFactory.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/IRFactory.class
new file mode 100644
index 00000000..70e19e2a
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/IRFactory.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/IdFunctionCall.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/IdFunctionCall.class
new file mode 100644
index 00000000..5b878971
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/IdFunctionCall.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/IdFunctionObject.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/IdFunctionObject.class
new file mode 100644
index 00000000..8264434b
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/IdFunctionObject.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/IdScriptableObject$PrototypeValues.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/IdScriptableObject$PrototypeValues.class
new file mode 100644
index 00000000..62c69ce1
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/IdScriptableObject$PrototypeValues.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/IdScriptableObject.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/IdScriptableObject.class
new file mode 100644
index 00000000..3f9a5def
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/IdScriptableObject.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ImporterTopLevel.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ImporterTopLevel.class
new file mode 100644
index 00000000..e3e1401d
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ImporterTopLevel.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/InterfaceAdapter$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/InterfaceAdapter$1.class
new file mode 100644
index 00000000..35e18ee9
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/InterfaceAdapter$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/InterfaceAdapter.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/InterfaceAdapter.class
new file mode 100644
index 00000000..665b3f0e
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/InterfaceAdapter.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/InterpretedFunction.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/InterpretedFunction.class
new file mode 100644
index 00000000..f51aac94
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/InterpretedFunction.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Interpreter$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Interpreter$1.class
new file mode 100644
index 00000000..afa33587
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Interpreter$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Interpreter$CallFrame.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Interpreter$CallFrame.class
new file mode 100644
index 00000000..2f5b518b
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Interpreter$CallFrame.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Interpreter$ContinuationJump.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Interpreter$ContinuationJump.class
new file mode 100644
index 00000000..7c3010bb
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Interpreter$ContinuationJump.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Interpreter.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Interpreter.class
new file mode 100644
index 00000000..94b6ab09
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Interpreter.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/InterpreterData.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/InterpreterData.class
new file mode 100644
index 00000000..a89a13df
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/InterpreterData.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/JavaAdapter$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/JavaAdapter$1.class
new file mode 100644
index 00000000..2ff00527
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/JavaAdapter$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/JavaAdapter$2.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/JavaAdapter$2.class
new file mode 100644
index 00000000..04e541e2
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/JavaAdapter$2.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/JavaAdapter$JavaAdapterSignature.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/JavaAdapter$JavaAdapterSignature.class
new file mode 100644
index 00000000..dc6fd902
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/JavaAdapter$JavaAdapterSignature.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/JavaAdapter.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/JavaAdapter.class
new file mode 100644
index 00000000..976547ef
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/JavaAdapter.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/JavaMembers$MethodSignature.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/JavaMembers$MethodSignature.class
new file mode 100644
index 00000000..f6d1702c
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/JavaMembers$MethodSignature.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/JavaMembers.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/JavaMembers.class
new file mode 100644
index 00000000..488620cb
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/JavaMembers.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/JavaScriptException.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/JavaScriptException.class
new file mode 100644
index 00000000..b74303d9
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/JavaScriptException.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Kit$ComplexKey.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Kit$ComplexKey.class
new file mode 100644
index 00000000..74798b6a
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Kit$ComplexKey.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Kit.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Kit.class
new file mode 100644
index 00000000..b1c40f76
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Kit.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/LazilyLoadedCtor.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/LazilyLoadedCtor.class
new file mode 100644
index 00000000..30007e94
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/LazilyLoadedCtor.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/MemberBox.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/MemberBox.class
new file mode 100644
index 00000000..1cad2611
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/MemberBox.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeArray.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeArray.class
new file mode 100644
index 00000000..61c75f88
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeArray.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeBoolean.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeBoolean.class
new file mode 100644
index 00000000..0bec7296
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeBoolean.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeCall.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeCall.class
new file mode 100644
index 00000000..078620da
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeCall.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeDate.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeDate.class
new file mode 100644
index 00000000..7bbe23bb
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeDate.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeError.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeError.class
new file mode 100644
index 00000000..e26bbfea
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeError.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeFunction.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeFunction.class
new file mode 100644
index 00000000..aa8ffbce
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeFunction.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeGlobal.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeGlobal.class
new file mode 100644
index 00000000..2238ea7a
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeGlobal.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeJavaArray.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeJavaArray.class
new file mode 100644
index 00000000..385fad2c
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeJavaArray.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeJavaClass.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeJavaClass.class
new file mode 100644
index 00000000..380ed2b3
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeJavaClass.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeJavaConstructor.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeJavaConstructor.class
new file mode 100644
index 00000000..a59eb151
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeJavaConstructor.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeJavaMethod.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeJavaMethod.class
new file mode 100644
index 00000000..4dda04d0
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeJavaMethod.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeJavaObject.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeJavaObject.class
new file mode 100644
index 00000000..90058c4d
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeJavaObject.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeJavaPackage.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeJavaPackage.class
new file mode 100644
index 00000000..19d33a7d
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeJavaPackage.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeJavaTopPackage.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeJavaTopPackage.class
new file mode 100644
index 00000000..1ee466d2
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeJavaTopPackage.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeMath.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeMath.class
new file mode 100644
index 00000000..300bbe4b
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeMath.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeNumber.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeNumber.class
new file mode 100644
index 00000000..6e15c6ae
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeNumber.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeObject.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeObject.class
new file mode 100644
index 00000000..5b241956
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeObject.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeScript.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeScript.class
new file mode 100644
index 00000000..b89a337f
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeScript.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeString.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeString.class
new file mode 100644
index 00000000..21ff35f8
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeString.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeWith.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeWith.class
new file mode 100644
index 00000000..a6faf2d9
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NativeWith.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Node$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Node$1.class
new file mode 100644
index 00000000..62e71383
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Node$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Node$Jump.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Node$Jump.class
new file mode 100644
index 00000000..b32d7d99
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Node$Jump.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Node$NumberNode.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Node$NumberNode.class
new file mode 100644
index 00000000..b9ad3a2d
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Node$NumberNode.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Node$PropListItem.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Node$PropListItem.class
new file mode 100644
index 00000000..4fb43a88
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Node$PropListItem.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Node$StringNode.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Node$StringNode.class
new file mode 100644
index 00000000..a79c3681
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Node$StringNode.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Node.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Node.class
new file mode 100644
index 00000000..df7dda72
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Node.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NodeTransformer.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NodeTransformer.class
new file mode 100644
index 00000000..6347cb0c
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NodeTransformer.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NotAFunctionException.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NotAFunctionException.class
new file mode 100644
index 00000000..2245eca8
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/NotAFunctionException.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ObjArray.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ObjArray.class
new file mode 100644
index 00000000..694837e7
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ObjArray.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ObjToIntMap$Iterator.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ObjToIntMap$Iterator.class
new file mode 100644
index 00000000..fe2a82b9
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ObjToIntMap$Iterator.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ObjToIntMap.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ObjToIntMap.class
new file mode 100644
index 00000000..6b128814
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ObjToIntMap.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Parser$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Parser$1.class
new file mode 100644
index 00000000..84a22bf4
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Parser$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Parser$ParserException.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Parser$ParserException.class
new file mode 100644
index 00000000..f6e57559
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Parser$ParserException.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Parser.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Parser.class
new file mode 100644
index 00000000..09433ead
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Parser.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/PolicySecurityController$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/PolicySecurityController$1.class
new file mode 100644
index 00000000..0c7a3f02
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/PolicySecurityController$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/PolicySecurityController$2.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/PolicySecurityController$2.class
new file mode 100644
index 00000000..dbf2ce4b
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/PolicySecurityController$2.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/PolicySecurityController$3.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/PolicySecurityController$3.class
new file mode 100644
index 00000000..e495945c
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/PolicySecurityController$3.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/PolicySecurityController$Loader.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/PolicySecurityController$Loader.class
new file mode 100644
index 00000000..6089a711
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/PolicySecurityController$Loader.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/PolicySecurityController$SecureCaller.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/PolicySecurityController$SecureCaller.class
new file mode 100644
index 00000000..a9f73a08
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/PolicySecurityController$SecureCaller.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/PolicySecurityController.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/PolicySecurityController.class
new file mode 100644
index 00000000..1dcaf00b
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/PolicySecurityController.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/PropertyException.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/PropertyException.class
new file mode 100644
index 00000000..baf54faa
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/PropertyException.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Ref.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Ref.class
new file mode 100644
index 00000000..dc5fb86a
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Ref.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/RefCallable.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/RefCallable.class
new file mode 100644
index 00000000..76265804
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/RefCallable.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/RegExpProxy.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/RegExpProxy.class
new file mode 100644
index 00000000..a32e87ff
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/RegExpProxy.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/RhinoException$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/RhinoException$1.class
new file mode 100644
index 00000000..c91eadf9
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/RhinoException$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/RhinoException.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/RhinoException.class
new file mode 100644
index 00000000..9cc29aaf
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/RhinoException.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Script.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Script.class
new file mode 100644
index 00000000..7fa2075a
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Script.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptOrFnNode.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptOrFnNode.class
new file mode 100644
index 00000000..93480382
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptOrFnNode.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptRuntime$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptRuntime$1.class
new file mode 100644
index 00000000..271c3341
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptRuntime$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptRuntime$IdEnumeration.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptRuntime$IdEnumeration.class
new file mode 100644
index 00000000..b754c6ce
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptRuntime$IdEnumeration.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptRuntime$NoSuchMethodShim.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptRuntime$NoSuchMethodShim.class
new file mode 100644
index 00000000..6e744688
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptRuntime$NoSuchMethodShim.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptRuntime.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptRuntime.class
new file mode 100644
index 00000000..c3a106bd
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptRuntime.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Scriptable.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Scriptable.class
new file mode 100644
index 00000000..50a5fdd9
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Scriptable.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptableObject$GetterSlot.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptableObject$GetterSlot.class
new file mode 100644
index 00000000..f57a4d7c
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptableObject$GetterSlot.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptableObject$Slot.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptableObject$Slot.class
new file mode 100644
index 00000000..ce721fef
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptableObject$Slot.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptableObject.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptableObject.class
new file mode 100644
index 00000000..ad7fcc43
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/ScriptableObject.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecureCaller$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecureCaller$1.class
new file mode 100644
index 00000000..3f4cb025
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecureCaller$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecureCaller$2.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecureCaller$2.class
new file mode 100644
index 00000000..7387b2f4
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecureCaller$2.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecureCaller$3.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecureCaller$3.class
new file mode 100644
index 00000000..1cee643b
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecureCaller$3.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecureCaller$SecureClassLoaderImpl.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecureCaller$SecureClassLoaderImpl.class
new file mode 100644
index 00000000..6c7da3a0
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecureCaller$SecureClassLoaderImpl.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecureCaller.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecureCaller.class
new file mode 100644
index 00000000..1dfe5ffc
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecureCaller.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecurityController$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecurityController$1.class
new file mode 100644
index 00000000..8f579344
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecurityController$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecurityController.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecurityController.class
new file mode 100644
index 00000000..418e8c9b
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecurityController.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecurityUtilities$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecurityUtilities$1.class
new file mode 100644
index 00000000..fa27d8ab
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecurityUtilities$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecurityUtilities$2.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecurityUtilities$2.class
new file mode 100644
index 00000000..2373c027
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecurityUtilities$2.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecurityUtilities.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecurityUtilities.class
new file mode 100644
index 00000000..fd288747
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SecurityUtilities.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SpecialRef.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SpecialRef.class
new file mode 100644
index 00000000..02381c2e
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/SpecialRef.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Synchronizer.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Synchronizer.class
new file mode 100644
index 00000000..81ec58fa
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Synchronizer.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Token.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Token.class
new file mode 100644
index 00000000..f467deee
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Token.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/TokenStream.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/TokenStream.class
new file mode 100644
index 00000000..83b74442
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/TokenStream.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/UintMap.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/UintMap.class
new file mode 100644
index 00000000..b66a5930
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/UintMap.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Undefined.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Undefined.class
new file mode 100644
index 00000000..70a425f0
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Undefined.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/UniqueTag.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/UniqueTag.class
new file mode 100644
index 00000000..c8578371
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/UniqueTag.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/VMBridge.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/VMBridge.class
new file mode 100644
index 00000000..737f3bff
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/VMBridge.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/WrapFactory.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/WrapFactory.class
new file mode 100644
index 00000000..a2805e36
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/WrapFactory.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/WrappedException.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/WrappedException.class
new file mode 100644
index 00000000..fdb15892
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/WrappedException.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Wrapper.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Wrapper.class
new file mode 100644
index 00000000..bc50ba25
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/Wrapper.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/continuations/Continuation.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/continuations/Continuation.class
new file mode 100644
index 00000000..2e713f51
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/continuations/Continuation.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/debug/DebugFrame.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/debug/DebugFrame.class
new file mode 100644
index 00000000..afbff3f7
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/debug/DebugFrame.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/debug/DebuggableObject.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/debug/DebuggableObject.class
new file mode 100644
index 00000000..bf0e8e22
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/debug/DebuggableObject.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/debug/DebuggableScript.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/debug/DebuggableScript.class
new file mode 100644
index 00000000..a1275951
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/debug/DebuggableScript.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/debug/Debugger.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/debug/Debugger.class
new file mode 100644
index 00000000..6cf041c8
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/debug/Debugger.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/jdk11/VMBridge_jdk11.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/jdk11/VMBridge_jdk11.class
new file mode 100644
index 00000000..094417b5
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/jdk11/VMBridge_jdk11.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/jdk13/VMBridge_jdk13$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/jdk13/VMBridge_jdk13$1.class
new file mode 100644
index 00000000..debeec8a
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/jdk13/VMBridge_jdk13$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/jdk13/VMBridge_jdk13.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/jdk13/VMBridge_jdk13.class
new file mode 100644
index 00000000..0accdda3
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/jdk13/VMBridge_jdk13.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/jdk15/VMBridge_jdk15.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/jdk15/VMBridge_jdk15.class
new file mode 100644
index 00000000..15ab17d1
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/jdk15/VMBridge_jdk15.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/Block$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/Block$1.class
new file mode 100644
index 00000000..1ab5f386
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/Block$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/Block$FatBlock.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/Block$FatBlock.class
new file mode 100644
index 00000000..c26d23e7
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/Block$FatBlock.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/Block.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/Block.class
new file mode 100644
index 00000000..40a0561a
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/Block.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/BodyCodegen.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/BodyCodegen.class
new file mode 100644
index 00000000..b4681eb7
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/BodyCodegen.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/ClassCompiler.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/ClassCompiler.class
new file mode 100644
index 00000000..251ed7cd
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/ClassCompiler.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/Codegen.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/Codegen.class
new file mode 100644
index 00000000..10dc387c
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/Codegen.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/DataFlowBitSet.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/DataFlowBitSet.class
new file mode 100644
index 00000000..33a135b9
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/DataFlowBitSet.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/OptFunctionNode.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/OptFunctionNode.class
new file mode 100644
index 00000000..709202b1
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/OptFunctionNode.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/OptRuntime$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/OptRuntime$1.class
new file mode 100644
index 00000000..a7b4cbb8
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/OptRuntime$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/OptRuntime.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/OptRuntime.class
new file mode 100644
index 00000000..27f63d42
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/OptRuntime.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/OptTransformer.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/OptTransformer.class
new file mode 100644
index 00000000..5b979a2c
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/OptTransformer.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/Optimizer.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/Optimizer.class
new file mode 100644
index 00000000..167aa1bc
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/optimizer/Optimizer.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/CompilerState.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/CompilerState.class
new file mode 100644
index 00000000..fa20566e
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/CompilerState.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/GlobData.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/GlobData.class
new file mode 100644
index 00000000..746a5f3c
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/GlobData.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/NativeRegExp.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/NativeRegExp.class
new file mode 100644
index 00000000..2f1c6eb2
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/NativeRegExp.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/NativeRegExpCtor.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/NativeRegExpCtor.class
new file mode 100644
index 00000000..1f8161c6
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/NativeRegExpCtor.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/REBackTrackData.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/REBackTrackData.class
new file mode 100644
index 00000000..f1f1a0e4
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/REBackTrackData.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/RECharSet.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/RECharSet.class
new file mode 100644
index 00000000..c9e7c5ca
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/RECharSet.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/RECompiled.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/RECompiled.class
new file mode 100644
index 00000000..bcda6d22
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/RECompiled.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/REGlobalData.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/REGlobalData.class
new file mode 100644
index 00000000..eb6bf4d2
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/REGlobalData.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/RENode.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/RENode.class
new file mode 100644
index 00000000..c7f5582e
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/RENode.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/REProgState.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/REProgState.class
new file mode 100644
index 00000000..99b36256
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/REProgState.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/RegExpImpl.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/RegExpImpl.class
new file mode 100644
index 00000000..3fde702b
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/RegExpImpl.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/SubString.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/SubString.class
new file mode 100644
index 00000000..dcc87358
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/regexp/SubString.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/resources/Messages.properties b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/resources/Messages.properties
new file mode 100644
index 00000000..6c4645d7
--- /dev/null
+++ b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/resources/Messages.properties
@@ -0,0 +1,696 @@
+#
+# Default JavaScript messages file.
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Rhino code, released
+# May 6, 1999.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1997-1999
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Norris Boyd
+# Bob Jervis
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 or later (the "GPL"), in which
+# case the provisions of the GPL are applicable instead of those above. If
+# you wish to allow use of your version of this file only under the terms of
+# the GPL and not to allow others to use your version of this file under the
+# MPL, indicate your decision by deleting the provisions above and replacing
+# them with the notice and other provisions required by the GPL. If you do
+# not delete the provisions above, a recipient may use your version of this
+# file under either the MPL or the GPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# This is replaced during jar assembly from property string
+# and should not be translated
+implementation.version = Rhino 1.6 release 7 2007 08 19
+
+#
+# To add JavaScript error messages for a particular locale, create a
+# new Messages_[locale].properties file, where [locale] is the Java
+# string abbreviation for that locale. For example, JavaScript
+# messages for the Polish locale should be located in
+# Messages_pl.properties, and messages for the Italian Swiss locale
+# should be located in Messages_it_CH.properties. Message properties
+# files should be accessible through the classpath under
+# org.mozilla.javascript.resources
+#
+# See:
+# java.util.ResourceBundle
+# java.text.MessageFormat
+#
+
+# SomeJavaClassWhereUsed
+
+# Codegen
+msg.dup.parms =\
+ Duplicate parameter name "{0}".
+
+msg.too.big.jump =\
+ Program too complex: too big jump offset.
+
+msg.too.big.index =\
+ Program too complex: internal index exceeds 64K limit.
+
+
+# Context
+msg.ctor.not.found =\
+ Constructor for "{0}" not found.
+
+msg.not.ctor =\
+ "{0}" is not a constructor.
+
+# FunctionObject
+msg.varargs.ctor =\
+ Method or constructor "{0}" must be static with the signature \
+ "(Context cx, Object[] args, Function ctorObj, boolean inNewExpr)" \
+ to define a variable arguments constructor.
+
+msg.varargs.fun =\
+ Method "{0}" must be static with the signature \
+ "(Context cx, Scriptable thisObj, Object[] args, Function funObj)" \
+ to define a variable arguments function.
+
+msg.incompat.call =\
+ Method "{0}" called on incompatible object.
+
+msg.bad.parms =\
+ Unsupported parameter type "{0}" in method "{1}".
+
+msg.bad.method.return =\
+ Unsupported return type "{0}" in method "{1}".
+
+msg.bad.ctor.return =\
+ Construction of objects of type "{0}" is not supported.
+
+msg.no.overload =\
+ Method "{0}" occurs multiple times in class "{1}".
+
+msg.method.not.found =\
+ Method "{0}" not found in "{1}".
+
+# IRFactory
+
+msg.bad.for.in.lhs =\
+ Invalid left-hand side of for..in loop.
+
+msg.mult.index =\
+ Only one variable allowed in for..in loop.
+
+msg.cant.convert =\
+ Can''t convert to type "{0}".
+
+msg.bad.assign.left =\
+ Invalid assignment left-hand side.
+
+msg.bad.decr =\
+ Invalid decerement operand.
+
+msg.bad.incr =\
+ Invalid increment operand.
+
+# NativeGlobal
+msg.cant.call.indirect =\
+ Function "{0}" must be called directly, and not by way of a \
+ function of another name.
+
+msg.eval.nonstring =\
+ Calling eval() with anything other than a primitive string value will \
+ simply return the value. Is this what you intended?
+
+msg.eval.nonstring.strict =\
+ Calling eval() with anything other than a primitive string value is not \
+ allowed in strict mode.
+
+# NativeCall
+msg.only.from.new =\
+ "{0}" may only be invoked from a "new" expression.
+
+msg.deprec.ctor =\
+ The "{0}" constructor is deprecated.
+
+# NativeFunction
+msg.no.function.ref.found =\
+ no source found to decompile function reference {0}
+
+msg.arg.isnt.array =\
+ second argument to Function.prototype.apply must be an array
+
+# NativeGlobal
+msg.bad.esc.mask =\
+ invalid string escape mask
+
+# NativeJavaClass
+msg.cant.instantiate =\
+ error instantiating ({0}): class {1} is interface or abstract
+
+msg.bad.ctor.sig =\
+ Found constructor with wrong signature: \
+ {0} calling {1} with signature {2}
+
+msg.not.java.obj =\
+ Expected argument to getClass() to be a Java object.
+
+msg.no.java.ctor =\
+ Java constructor for "{0}" with arguments "{1}" not found.
+
+# NativeJavaMethod
+msg.method.ambiguous =\
+ The choice of Java method {0}.{1} matching JavaScript argument types ({2}) is ambiguous; \
+ candidate methods are: {3}
+
+msg.constructor.ambiguous =\
+ The choice of Java constructor {0} matching JavaScript argument types ({1}) is ambiguous; \
+ candidate constructors are: {2}
+
+# NativeJavaObject
+msg.conversion.not.allowed =\
+ Cannot convert {0} to {1}
+
+msg.no.empty.interface.conversion =\
+ Cannot convert {0} to interface {1} with no methods
+
+msg.no.function.interface.conversion =\
+ Cannot convert function {0} to interface since it contains methods with \
+ different signatures
+
+# NativeJavaPackage
+msg.not.classloader =\
+ Constructor for "Packages" expects argument of type java.lang.Classloader
+
+# NativeRegExp
+msg.bad.quant =\
+ Invalid quantifier {0}
+
+msg.overlarge.backref =\
+ Overly large back reference {0}
+
+msg.overlarge.min =\
+ Overly large minimum {0}
+
+msg.overlarge.max =\
+ Overly large maximum {0}
+
+msg.zero.quant =\
+ Zero quantifier {0}
+
+msg.max.lt.min =\
+ Maximum {0} less than minimum
+
+msg.unterm.quant =\
+ Unterminated quantifier {0}
+
+msg.unterm.paren =\
+ Unterminated parenthetical {0}
+
+msg.unterm.class =\
+ Unterminated character class {0}
+
+msg.bad.range =\
+ Invalid range in character class.
+
+msg.trail.backslash =\
+ Trailing \\ in regular expression.
+
+msg.re.unmatched.right.paren =\
+ unmatched ) in regular expression.
+
+msg.no.regexp =\
+ Regular expressions are not available.
+
+msg.bad.backref =\
+ back-reference exceeds number of capturing parentheses.
+
+msg.bad.regexp.compile =\
+ Only one argument may be specified if the first argument to \
+ RegExp.prototype.compile is a RegExp object.
+
+# Parser
+msg.got.syntax.errors = \
+ Compilation produced {0} syntax errors.
+
+msg.var.redecl =\
+ TypeError: redeclaration of var {0}.
+
+msg.const.redecl =\
+ TypeError: redeclaration of const {0}.
+
+# NodeTransformer
+msg.dup.label =\
+ duplicated label
+
+msg.undef.label =\
+ undefined label
+
+msg.bad.break =\
+ unlabelled break must be inside loop or switch
+
+msg.continue.outside =\
+ continue must be inside loop
+
+msg.continue.nonloop =\
+ continue can only use labeles of iteration statements
+
+msg.fn.redecl =\
+ function "{0}" redeclared; prior definition will be ignored
+
+msg.bad.throw.eol =\
+ Line terminator is not allowed between the throw keyword and throw \
+ expression.
+
+msg.no.paren.parms =\
+ missing ( before function parameters.
+
+msg.no.parm =\
+ missing formal parameter
+
+msg.no.paren.after.parms =\
+ missing ) after formal parameters
+
+msg.no.brace.body =\
+ missing '{' before function body
+
+msg.no.brace.after.body =\
+ missing } after function body
+
+msg.no.paren.cond =\
+ missing ( before condition
+
+msg.no.paren.after.cond =\
+ missing ) after condition
+
+msg.no.semi.stmt =\
+ missing ; before statement
+
+msg.no.name.after.dot =\
+ missing name after . operator
+
+msg.no.name.after.coloncolon =\
+ missing name after :: operator
+
+msg.no.name.after.dotdot =\
+ missing name after .. operator
+
+msg.no.name.after.xmlAttr =\
+ missing name after .@
+
+msg.no.bracket.index =\
+ missing ] in index expression
+
+msg.no.paren.switch =\
+ missing ( before switch expression
+
+msg.no.paren.after.switch =\
+ missing ) after switch expression
+
+msg.no.brace.switch =\
+ missing '{' before switch body
+
+msg.bad.switch =\
+ invalid switch statement
+
+msg.no.colon.case =\
+ missing : after case expression
+
+msg.double.switch.default =\
+ double default label in the switch statement
+
+msg.no.while.do =\
+ missing while after do-loop body
+
+msg.no.paren.for =\
+ missing ( after for
+
+msg.no.semi.for =\
+ missing ; after for-loop initializer
+
+msg.no.semi.for.cond =\
+ missing ; after for-loop condition
+
+msg.no.paren.for.ctrl =\
+ missing ) after for-loop control
+
+msg.no.paren.with =\
+ missing ( before with-statement object
+
+msg.no.paren.after.with =\
+ missing ) after with-statement object
+
+msg.bad.return =\
+ invalid return
+
+msg.no.brace.block =\
+ missing } in compound statement
+
+msg.bad.label =\
+ invalid label
+
+msg.bad.var =\
+ missing variable name
+
+msg.bad.var.init =\
+ invalid variable initialization
+
+msg.no.colon.cond =\
+ missing : in conditional expression
+
+msg.no.paren.arg =\
+ missing ) after argument list
+
+msg.no.bracket.arg =\
+ missing ] after element list
+
+msg.bad.prop =\
+ invalid property id
+
+msg.no.colon.prop =\
+ missing : after property id
+
+msg.no.brace.prop =\
+ missing } after property list
+
+msg.no.paren =\
+ missing ) in parenthetical
+
+msg.reserved.id =\
+ identifier is a reserved word
+
+msg.no.paren.catch =\
+ missing ( before catch-block condition
+
+msg.bad.catchcond =\
+ invalid catch block condition
+
+msg.catch.unreachable =\
+ any catch clauses following an unqualified catch are unreachable
+
+msg.no.brace.catchblock =\
+ missing '{' before catch-block body
+
+msg.try.no.catchfinally =\
+ ''try'' without ''catch'' or ''finally''
+
+msg.no.return.value =\
+ function {0} does not always return a value
+
+msg.anon.no.return.value =\
+ anonymous function does not always return a value
+
+msg.return.inconsistent =\
+ return statement is inconsistent with previous usage
+
+msg.syntax =\
+ syntax error
+
+msg.unexpected.eof =\
+ Unexpected end of file
+
+msg.XML.bad.form =\
+ illegally formed XML syntax
+
+msg.XML.not.available =\
+ XML runtime not available
+
+msg.too.deep.parser.recursion =\
+ Too deep recursion while parsing
+
+msg.no.side.effects =\
+ Code has no side effects
+
+msg.extra.trailing.comma =\
+ Trailing comma is not legal in an ECMA-262 object initializer
+
+msg.equal.as.assign =\
+ Test for equality (==) mistyped as assignment (=)?
+
+msg.var.hides.arg =\
+ Variable {0} hides argument
+
+# ScriptRuntime
+msg.assn.create.strict =\
+ Assignment to undeclared variable {0}
+
+msg.ref.undefined.prop =\
+ Referenced to undefined property "{0}"
+
+msg.prop.not.found =\
+ Property {0} not found.
+
+msg.invalid.type =\
+ Invalid JavaScript value of type {0}
+
+msg.primitive.expected =\
+ Primitive type expected (had {0} instead)
+
+msg.namespace.expected =\
+ Namespace object expected to left of :: (found {0} instead)
+
+msg.null.to.object =\
+ Cannot convert null to an object.
+
+msg.undef.to.object =\
+ Cannot convert undefined to an object.
+
+msg.cyclic.value =\
+ Cyclic {0} value not allowed.
+
+msg.is.not.defined =\
+ "{0}" is not defined.
+
+msg.undef.prop.read =\
+ Cannot read property "{1}" from {0}
+
+msg.undef.prop.write =\
+ Cannot set property "{1}" of {0} to "{2}"
+
+msg.undef.prop.delete =\
+ Cannot delete property "{1}" of {0}
+
+msg.undef.method.call =\
+ Cannot call method "{1}" of {0}
+
+msg.undef.with =\
+ Cannot apply "with" to {0}
+
+msg.isnt.function =\
+ {0} is not a function, it is {1}.
+
+msg.function.not.found =\
+ Cannot find function {0}.
+
+msg.isnt.xml.object =\
+ {0} is not an xml object.
+
+msg.no.ref.to.get =\
+ {0} is not a reference to read reference value.
+
+msg.no.ref.to.set =\
+ {0} is not a reference to set reference value tpo {1}.
+
+msg.no.ref.from.function =\
+ Function {0} can not be used as the left-hand side of assignment \
+ or as an operand of ++ or -- operator.
+
+msg.bad.default.value =\
+ Object''s getDefaultValue() method returned an object.
+
+msg.instanceof.not.object = \
+ Can''t use instanceof on a non-object.
+
+msg.instanceof.bad.prototype = \
+ ''prototype'' property of {0} is not an object.
+
+msg.bad.radix = \
+ illegal radix {0}.
+
+# ScriptableObject
+msg.default.value =\
+ Cannot find default value for object.
+
+msg.zero.arg.ctor =\
+ Cannot load class "{0}" which has no zero-parameter constructor.
+
+msg.ctor.multiple.parms =\
+ Can''t define constructor or class {0} since more than one \
+ constructor has multiple parameters.
+
+msg.extend.scriptable =\
+ {0} must extend ScriptableObject in order to define property {1}.
+
+msg.bad.getter.parms =\
+ In order to define a property, getter {0} must have zero parameters \
+ or a single ScriptableObject parameter.
+
+msg.obj.getter.parms =\
+ Expected static or delegated getter {0} to take a ScriptableObject parameter.
+
+msg.getter.static =\
+ Getter and setter must both be static or neither be static.
+
+msg.setter.return =\
+ Setter must have void return type: {0}
+
+msg.setter2.parms =\
+ Two-parameter setter must take a ScriptableObject as its first parameter.
+
+msg.setter1.parms =\
+ Expected single parameter setter for {0}
+
+msg.setter2.expected =\
+ Expected static or delegated setter {0} to take two parameters.
+
+msg.setter.parms =\
+ Expected either one or two parameters for setter.
+
+msg.setter.bad.type =\
+ Unsupported parameter type "{0}" in setter "{1}".
+
+msg.add.sealed =\
+ Cannot add a property to a sealed object: {0}.
+
+msg.remove.sealed =\
+ Cannot remove a property from a sealed object: {0}.
+
+msg.modify.sealed =\
+ Cannot modify a property of a sealed object: {0}.
+
+msg.modify.readonly =\
+ Cannot modify readonly property: {0}.
+
+# TokenStream
+msg.missing.exponent =\
+ missing exponent
+
+msg.caught.nfe =\
+ number format error
+
+msg.unterminated.string.lit =\
+ unterminated string literal
+
+msg.unterminated.comment =\
+ unterminated comment
+
+msg.unterminated.re.lit =\
+ unterminated regular expression literal
+
+msg.invalid.re.flag =\
+ invalid flag after regular expression
+
+msg.no.re.input.for =\
+ no input for {0}
+
+msg.illegal.character =\
+ illegal character
+
+msg.invalid.escape =\
+ invalid Unicode escape sequence
+
+msg.bad.namespace =\
+ not a valid default namespace statement. \
+ Syntax is: default xml namespace = EXPRESSION;
+
+# TokensStream warnings
+msg.bad.octal.literal =\
+ illegal octal literal digit {0}; interpreting it as a decimal digit
+
+msg.reserved.keyword =\
+ illegal usage of future reserved keyword {0}; interpreting it as ordinary identifier
+
+# Undefined
+msg.undefined =\
+ The undefined value has no properties.
+
+# LiveConnect errors
+msg.java.internal.field.type =\
+ Internal error: type conversion of {0} to assign to {1} on {2} failed.
+
+msg.java.conversion.implicit_method =\
+ Can''t find converter method "{0}" on class {1}.
+
+msg.java.method.assign =\
+ Java method "{0}" cannot be assigned to.
+
+msg.java.internal.private =\
+ Internal error: attempt to access private/protected field "{0}".
+
+msg.java.no_such_method =\
+ Can''t find method {0}.
+
+msg.script.is.not.constructor =\
+ Script objects are not constructors.
+
+msg.nonjava.method =\
+ Java method "{0}" was invoked with {1} as "this" value that can not be converted to Java type {2}.
+
+msg.java.member.not.found =\
+ Java class "{0}" has no public instance field or method named "{1}".
+
+msg.java.array.index.out.of.bounds =\
+ Array index {0} is out of bounds [0..{1}].
+
+msg.pkg.int =\
+ Java package names may not be numbers.
+
+msg.access.prohibited =\
+ Access to Java class "{0}" is prohibited.
+
+# ImporterTopLevel
+msg.ambig.import =\
+ Ambiguous import: "{0}" and and "{1}".
+
+msg.not.pkg =\
+ Function importPackage must be called with a package; had "{0}" instead.
+
+msg.not.class =\
+ Function importClass must be called with a class; had "{0}" instead.
+
+msg.not.class.not.pkg =\
+ "{0}" is neither a class nor a package.
+
+msg.prop.defined =\
+ Cannot import "{0}" since a property by that name is already defined.
+
+#JavaAdapter
+msg.adapter.zero.args =\
+ JavaAdapter requires at least one argument.
+
+msg.not.java.class.arg = \
+Argument {0} is not Java class: {1}.
+
+#JavaAdapter
+msg.only.one.super = \
+Only one class may be extended by a JavaAdapter. Had {0} and {1}.
+
+
+# Arrays
+msg.arraylength.bad =\
+ Inappropriate array length.
+
+# Arrays
+msg.arraylength.too.big =\
+ Array length {0} exceeds supported capacity limit.
+
+# URI
+msg.bad.uri =\
+ Malformed URI sequence.
+
+# Number
+msg.bad.precision =\
+ Precision {0} out of range.
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/resources/Messages_fr.properties b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/resources/Messages_fr.properties
new file mode 100644
index 00000000..fc87c975
--- /dev/null
+++ b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/resources/Messages_fr.properties
@@ -0,0 +1,329 @@
+#
+# French JavaScript messages file.
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Aviva Inc. code, released
+# March 5, 2004.
+#
+# The Initial Developer of the Original Code is
+# Aviva Inc.
+# Portions created by the Initial Developer are Copyright (C) 2004
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Eugene Aresteanu
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 or later (the "GPL"), in which
+# case the provisions of the GPL are applicable instead of those above. If
+# you wish to allow use of your version of this file only under the terms of
+# the GPL and not to allow others to use your version of this file under the
+# MPL, indicate your decision by deleting the provisions above and replacing
+# them with the notice and other provisions required by the GPL. If you do
+# not delete the provisions above, a recipient may use your version of this
+# file under either the MPL or the GPL.
+#
+# ***** END LICENSE BLOCK *****
+
+msg.dup.parms =\
+ Le nom de param\u00E8tre "{0}" existe d\u00E9j\u00E0.
+msg.too.big.jump =\
+ Programme trop complexe : d\u00E9calage de saut trop important
+msg.too.big.index =\
+ Programme trop complexe : l''indice interne d\u00E9passe la limite de 64 ko
+msg.ctor.not.found =\
+ Le constructeur de "{0}" est introuvable
+msg.not.ctor =\
+ {0} n''est pas un constructeur
+msg.varargs.ctor =\
+ La m\u00E9thode ou le constructeur "{0}" doit \u00EAtre statique avec la signature "(Context cx, arguments Object[], Function ctorObj, boolean inNewExpr)" pour d\u00E9finir un constructeur d''arguments de variable.
+msg.varargs.fun =\
+ La m\u00E9thode "{0}" doit \u00EAtre statique avec la signature "(Context cx, Scriptable thisObj, arguments Object[], Function funObj)" pour d\u00E9finir une fonction d''arguments de variable
+msg.incompat.call =\
+ La m\u00E9thode "{0}" a \u00E9t\u00E9 appel\u00E9e dans un objet non compatible
+msg.bad.parms =\
+ Les param\u00E8tres de la m\u00E9thode sont incorrects pour "{0}"
+msg.no.overload =\
+ La m\u00E9thode "{0}" appara\u00EEt plusieurs fois dans la classe "{1}"
+msg.method.not.found =\
+ La m\u00E9thode "{0}" est introuvable dans "{1}"
+msg.bad.for.in.lhs =\
+ La partie gauche de la boucle for..in est incorrecte
+msg.bad.lhs.assign =\
+ La partie gauche de l''affectation est incorrecte
+msg.mult.index =\
+ Une seule variable est autoris\u00E9e dans la boucle for..in
+msg.cant.convert =\
+ La conversion en type "{0}" est impossible
+msg.cant.call.indirect =\
+ La fonction "{0}" doit \u00EAtre appel\u00E9e directement et non par l''interm\u00E9diaire d''une fonction portant un autre nom
+msg.eval.nonstring =\
+ Si vous appelez la fonction eval() avec une valeur qui n''appartient pas \u00E0 une cha\u00EEne primitive, c''est la valeur en question qui est renvoy\u00E9e. \u00E9tait-ce votre intention ?
+msg.only.from.new =\
+ {0} ne peut \u00EAtre appel\u00E9e qu''\u00E0 partir d''une "nouvelle" expression.
+msg.deprec.ctor =\
+ Le constructeur "{0}" est d\u00E9conseill\u00E9
+msg.no.function.ref.found =\
+ aucune source n''a \u00E9t\u00E9 trouv\u00E9e pour d\u00E9compiler la r\u00E9f\u00E9rence de fonction {0}
+msg.arg.isnt.array =\
+ le second argument de la m\u00E9thode Function.prototype.apply doit \u00EAtre un tableau
+msg.bad.esc.mask =\
+ le masque d''\u00E9chappement de cha\u00EEne est incorrect
+msg.cant.instantiate =\
+ erreur lors de l''instanciation ({0}) : la classe {1} est une classe interface ou abstract
+msg.bad.ctor.sig =\
+ Un constructeur avec une signature incorrecte a \u00E9t\u00E9 d\u00E9tect\u00E9 : {0} qui appelle {1} avec la signature {2}
+msg.not.java.obj =\
+ L''argument attendu pour la fonction getClass() doit \u00EAtre un objet Java
+msg.no.java.ctor =\
+ Le constructeur Java de "{0}" avec les arguments "{1}" est introuvable
+msg.method.ambiguous =\
+ Le choix de la m\u00E9thode Java {0}.{1} correspondant aux types d''argument JavaScript ({2}) est ambigu. Les m\u00E9thodes propos\u00E9es sont les suivantes : {3}
+msg.constructor.ambiguous =\
+ Le choix du constructeur Java {0} correspondant aux types d''argument JavaScript ({1}) est ambigu. Les constructeurs propos\u00E9s sont les suivants : {2}
+msg.conversion.not.allowed =\
+ Impossible de convertir {0} en {1}
+msg.not.classloader =\
+ Le constructeur de "Packages" attend un argument de type java.lang.Classloader
+msg.bad.quant =\
+ Le quantificateur {0} est incorrect
+msg.overlarge.max =\
+ Le maximum {0} est trop important
+msg.zero.quant =\
+ Le quantificateur {0} est nul
+msg.max.lt.min =\
+ Le maximum {0} est inf\u00E9rieur au minimum
+msg.unterm.quant =\
+ Le quantificateur {0} n''a pas de limite
+msg.unterm.paren =\
+ Les parenth\u00E8ses {0} n''ont pas de limite
+msg.unterm.class =\
+ La classe de caract\u00E8res {0} n''a pas de limite
+msg.bad.range =\
+ La classe de caract\u00E8res contient une plage de valeurs incorrecte
+msg.trail.backslash =\
+ \\ au d\u00E9but d''une expression r\u00E9guli\u00E8re
+msg.no.regexp =\
+ Les expressions r\u00E9guli\u00E8res ne sont pas disponibles
+msg.bad.backref =\
+ la r\u00E9f\u00E9rence ant\u00E9rieure d\u00E9passe le nombre de parenth\u00E8ses de capture
+msg.dup.label =\
+ Le libell\u00E9 {0} existe d\u00E9j\u00E0
+msg.undef.label =\
+ Le libell\u00E9 {0} n''est pas d\u00E9fini
+msg.bad.break =\
+ Le saut non libell\u00E9 doit se trouver dans la boucle ou dans l''aiguillage
+msg.continue.outside =\
+ continue doit se trouver dans la boucle
+msg.continue.nonloop =\
+ Il n''est possible de continuer que dans l''instruction d''it\u00E9ration libell\u00E9e
+msg.fn.redecl =\
+ La fonction "{0}" a \u00E9t\u00E9 de nouveau d\u00E9clar\u00E9e. La d\u00E9finition pr\u00E9c\u00E9dente sera ignor\u00E9e
+msg.no.paren.parms =\
+ il manque ''('' avant les param\u00E8tres de la fonction
+msg.no.parm =\
+ il manque un param\u00E8tre de forme
+msg.no.paren.after.parms =\
+ il manque '')'' apr\u00E8s les param\u00E8tres de forme
+msg.no.brace.body =\
+ il manque '{' avant le corps d''une fonction
+msg.no.brace.after.body =\
+ il manque ''}'' apr\u00E8s le corps d''une fonction
+msg.no.paren.cond =\
+ il manque ''('' avant une condition
+msg.no.paren.after.cond =\
+ il manque '')'' apr\u00E8s une condition
+msg.no.semi.stmt =\
+ il manque '';'' avant une instruction
+msg.no.name.after.dot =\
+ il manque un nom apr\u00E8s un op\u00E9rateur ''.''
+msg.no.bracket.index =\
+ il manque '']'' dans l''expression de l''indice
+msg.no.paren.switch =\
+ il manque ''('' avant l''expression d''un aiguillage
+msg.no.paren.after.switch =\
+ il manque '')'' apr\u00E8s l''expression d''un aiguillage
+msg.no.brace.switch =\
+ il manque '{' avant le corps d''un aiguillage
+msg.bad.switch =\
+ l''instruction d''aiguillage est incorrecte
+msg.no.colon.case =\
+ il manque '':'' apr\u00E8s l''expression d''un cas
+msg.no.while.do =\
+ il manque ''while'' apr\u00E8s le corps d''une boucle do-loop
+msg.no.paren.for =\
+ il manque ''('' apr\u00E8s for
+msg.no.semi.for =\
+ Il manque '';'' apr\u00E8s l''initialiseur for-loop
+msg.no.semi.for.cond =\
+ il manque '';'' apr\u00E8s la condition for-loop
+msg.no.paren.for.ctrl =\
+ il manque '')'' apr\u00E8s le contrôle for-loop
+msg.no.paren.with =\
+ il manque ''('' avant un objet with-statement
+msg.no.paren.after.with =\
+ il manque '')'' apr\u00E8s un objet with-statement
+msg.bad.return =\
+ la valeur renvoy\u00E9e est incorrecte
+msg.no.brace.block =\
+ il manque ''}'' dans une instruction compos\u00E9e
+msg.bad.label =\
+ le libell\u00E9 est incorrect
+msg.bad.var =\
+ il manque un nom de variable
+msg.bad.var.init =\
+ l''initialisation de la variable est incorrecte
+msg.no.colon.cond =\
+ il manque '':'' dans une expression conditionnelle
+msg.no.paren.arg =\
+ il manque '')'' apr\u00E8s une liste d''arguments
+msg.no.bracket.arg =\
+ il manque '']'' apr\u00E8s une liste d''\u00E9l\u00E9ments
+msg.bad.prop =\
+ l''identifiant de propri\u00E9t\u00E9 est incorrect
+msg.no.colon.prop =\
+ il manque '':'' apr\u00E8s un identifiant de propri\u00E9t\u00E9
+msg.no.brace.prop =\
+ il manque ''}'' apr\u00E8s une liste de propri\u00E9t\u00E9s
+msg.no.paren =\
+ il manque '')'' dans des parenth\u00E8ses
+msg.reserved.id =\
+ l''identifiant est un mot r\u00E9serv\u00E9
+msg.no.paren.catch =\
+ il manque ''('' avant une condition catch-block
+msg.bad.catchcond =\
+ la condition catch-block est incorrecte
+msg.catch.unreachable =\
+ aucune clause catch suivant une interception non qualifi\u00E9e ne peut \u00EAtre atteinte
+msg.no.brace.catchblock =\
+ il manque '{' avant le corps catch-block
+msg.try.no.catchfinally =\
+ ''try'' a \u00E9t\u00E9 d\u00E9tect\u00E9 sans ''catch'' ni ''finally''
+msg.syntax =\
+ erreur de syntaxe
+msg.assn.create =\
+ Une variable va \u00EAtre cr\u00E9\u00E9e en raison de l''affectation \u00E0 un ''{0}'' non d\u00E9fini. Ajoutez une instruction de variable \u00E0 la port\u00E9e sup\u00E9rieure pour que cet avertissement ne soit plus affich\u00E9
+msg.prop.not.found =\
+ La propri\u00E9t\u00E9 est introuvable
+msg.invalid.type =\
+ Valeur JavaScript de type {0} incorrecte
+msg.primitive.expected =\
+ Un type primitif \u00E9tait attendu (et non {0})
+msg.null.to.object =\
+ Il est impossible de convertir la valeur null en objet
+msg.undef.to.object =\
+ Il est impossible de convertir une valeur non d\u00E9finie en objet
+msg.cyclic.value =\
+ La valeur cyclique {0} n''est pas autoris\u00E9e
+msg.is.not.defined =\
+ "{0}" n''est pas d\u00E9fini
+msg.isnt.function =\
+ {0} n''est pas une fonction, est un {1}
+msg.bad.default.value =\
+ La m\u00E9thode getDefaultValue() de l''objet a renvoy\u00E9 un objet
+msg.instanceof.not.object =\
+ Il est impossible d''utiliser une instance d''un \u00E9l\u00E9ment autre qu''un objet
+msg.instanceof.bad.prototype =\
+ La propri\u00E9t\u00E9 ''prototype'' de {0} n''est pas un objet
+msg.bad.radix =\
+ la base {0} n''est pas autoris\u00E9e
+msg.default.value =\
+ La valeur par d\u00E9faut de l''objet est introuvable
+msg.zero.arg.ctor =\
+ Il est impossible de charger la classe "{0}", qui ne poss\u00E8de pas de constructeur de param\u00E8tre z\u00E9ro
+msg.multiple.ctors =\
+ Les m\u00E9thodes {0} et {1} ont \u00E9t\u00E9 d\u00E9tect\u00E9es alors qu''il est impossible d''utiliser plusieurs m\u00E9thodes constructor
+msg.ctor.multiple.parms =\
+ Il est impossible de d\u00E9finir le constructeur ou la classe {0} car plusieurs constructeurs poss\u00E8dent plusieurs param\u00E8tres
+msg.extend.scriptable =\
+ {0} doit \u00E9tendre ScriptableObject afin de d\u00E9finir la propri\u00E9t\u00E9 {1}
+msg.bad.getter.parms =\
+ Pour d\u00E9finir une propri\u00E9t\u00E9, la m\u00E9thode d''obtention {0} doit avoir des param\u00E8tres z\u00E9ro ou un seul param\u00E8tre ScriptableObject
+msg.obj.getter.parms =\
+ La m\u00E9thode d''obtention statique ou d\u00E9l\u00E9gu\u00E9e {0} doit utiliser un param\u00E8tre ScriptableObject
+msg.getter.static =\
+ La m\u00E9thode d''obtention et la m\u00E9thode de d\u00E9finition doivent toutes deux avoir le m\u00EAme \u00E9tat (statique ou non)
+msg.setter2.parms =\
+ La m\u00E9thode de d\u00E9finition \u00E0 deux param\u00E8tres doit utiliser un param\u00E8tre ScriptableObject comme premier param\u00E8tre
+msg.setter1.parms =\
+ Une m\u00E9thode d''obtention \u00E0 param\u00E8tre unique est attendue pour {0}
+msg.setter2.expected =\
+ La m\u00E9thode de d\u00E9finition statique ou d\u00E9l\u00E9gu\u00E9e {0} doit utiliser deux param\u00E8tres
+msg.setter.parms =\
+ Un ou deux param\u00E8tres sont attendus pour la m\u00E9thode de d\u00E9finition
+msg.add.sealed =\
+ Il est impossible d''ajouter une propri\u00E9t\u00E9 \u00E0 un objet ferm\u00E9
+msg.remove.sealed =\
+ Il est impossible de supprimer une propri\u00E9t\u00E9 d''un objet ferm\u00E9
+msg.token.replaces.pushback =\
+ le jeton de non-obtention {0} remplace le jeton de renvoi {1}
+msg.missing.exponent =\
+ il manque un exposant
+msg.caught.nfe =\
+ erreur de format de nombre : {0}
+msg.unterminated.string.lit =\
+ le litt\u00E9ral de la cha\u00EEne n''a pas de limite
+msg.unterminated.comment =\
+ le commentaire n''a pas de limite
+msg.unterminated.re.lit =\
+ le litt\u00E9ral de l''expression r\u00E9guli\u00E8re n''a pas de limite
+msg.invalid.re.flag =\
+ une expression r\u00E9guli\u00E8re est suivie d''un indicateur incorrect
+msg.no.re.input.for =\
+ il n''y a pas d''entr\u00E9e pour {0}
+msg.illegal.character =\
+ caract\u00E8re non autoris\u00E9
+msg.invalid.escape =\
+ la s\u00E9quence d''\u00E9chappement Unicode est incorrecte
+msg.bad.octal.literal =\
+ le chiffre octal du litt\u00E9ral, {0}, n''est pas autoris\u00E9 et sera interpr\u00E9t\u00E9 comme un chiffre d\u00E9cimal
+msg.reserved.keyword =\
+ l''utilisation du futur mot-cl\u00E9 r\u00E9serv\u00E9 {0} n''est pas autoris\u00E9e et celui-ci sera interpr\u00E9t\u00E9 comme un identifiant ordinaire
+msg.undefined =\
+ La valeur non d\u00E9finie ne poss\u00E8de pas de propri\u00E9t\u00E9
+msg.java.internal.field.type =\
+ Erreur interne : la conversion de type de {0} afin d''affecter {1} \u00E0 {2} a \u00E9chou\u00E9
+msg.java.conversion.implicit_method =\
+ La m\u00E9thode de conversion "{0}" est introuvable dans la classe {1}
+sg.java.method.assign =\
+ La m\u00E9thode Java "{0}" ne peut pas \u00EAtre affect\u00E9e \u00E0
+msg.java.internal.private =\
+ Erreur interne : une tentative d''acc\u00E9der \u00E0 un champ "{0}" priv\u00E9/prot\u00E9g\u00E9 a \u00E9t\u00E9 d\u00E9tect\u00E9e
+msg.java.no_such_method =\
+ La m\u00E9thode ''{0}'' est introuvable
+msg.script.is.not.constructor =\
+ Les objets Script ne sont pas des constructeurs
+msg.nonjava.method =\
+ La m\u00E9thode Java "{0}" a \u00E9t\u00E9 appel\u00E9e avec une valeur ''this'' qui n''est pas un objet Java
+msg.java.member.not.found =\
+ La classe Java "{0}" ne poss\u00E8de aucun champ ou aucune m\u00E9thode d''instance publique appel\u00E9 "{1}"
+msg.java.array.index.out.of.bounds =\
+ Array index {0} is out of bounds [0..{1}].
+msg.pkg.int =\
+ Les noms de package Java ne peuvent pas \u00EAtre des nombres
+msg.ambig.import =\
+ Importation ambigu\u00EB : "{0}" et "{1}"
+msg.not.pkg =\
+ La fonction importPackage doit \u00EAtre appel\u00E9e avec un package et non avec "{0}"
+msg.not.class =\
+ La fonction importClass doit \u00EAtre appel\u00E9e avec une classe et non avec "{0}"
+msg.prop.defined =\
+ Il est impossible d''importer "{0}" car une propri\u00E9t\u00E9 portant le m\u00EAme nom a d\u00E9j\u00E0 \u00E9t\u00E9 d\u00E9finie
+sg.arraylength.bad =\
+ La longueur du tableau n''est pas appropri\u00E9e
+msg.bad.uri =\
+ La s\u00E9quence URI n''est pas form\u00E9e correctement
+msg.bad.precision =\
+ La pr\u00E9cision {0} ne se trouve pas dans la plage de valeurs
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/serialize/ScriptableInputStream.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/serialize/ScriptableInputStream.class
new file mode 100644
index 00000000..c6720e58
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/serialize/ScriptableInputStream.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/serialize/ScriptableOutputStream$PendingLookup.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/serialize/ScriptableOutputStream$PendingLookup.class
new file mode 100644
index 00000000..5ca63ac0
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/serialize/ScriptableOutputStream$PendingLookup.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/serialize/ScriptableOutputStream.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/serialize/ScriptableOutputStream.class
new file mode 100644
index 00000000..d5edf31b
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/serialize/ScriptableOutputStream.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/ToolErrorReporter.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/ToolErrorReporter.class
new file mode 100644
index 00000000..cff46c05
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/ToolErrorReporter.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/ContextWindow$1$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/ContextWindow$1$1.class
new file mode 100644
index 00000000..d1e6c614
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/ContextWindow$1$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/ContextWindow$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/ContextWindow$1.class
new file mode 100644
index 00000000..c05914c8
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/ContextWindow$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/ContextWindow$2.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/ContextWindow$2.class
new file mode 100644
index 00000000..50a253d5
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/ContextWindow$2.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/ContextWindow.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/ContextWindow.class
new file mode 100644
index 00000000..6f792c88
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/ContextWindow.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Dim$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Dim$1.class
new file mode 100644
index 00000000..3298a390
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Dim$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Dim$ContextData.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Dim$ContextData.class
new file mode 100644
index 00000000..a06e4f16
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Dim$ContextData.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Dim$DimIProxy.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Dim$DimIProxy.class
new file mode 100644
index 00000000..3e216cf5
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Dim$DimIProxy.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Dim$FunctionSource.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Dim$FunctionSource.class
new file mode 100644
index 00000000..3ee7e3f3
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Dim$FunctionSource.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Dim$SourceInfo.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Dim$SourceInfo.class
new file mode 100644
index 00000000..5deb7126
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Dim$SourceInfo.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Dim$StackFrame.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Dim$StackFrame.class
new file mode 100644
index 00000000..7e33c398
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Dim$StackFrame.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Dim.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Dim.class
new file mode 100644
index 00000000..97e0da8f
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Dim.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/EvalTextArea.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/EvalTextArea.class
new file mode 100644
index 00000000..8029159a
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/EvalTextArea.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/EvalWindow.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/EvalWindow.class
new file mode 100644
index 00000000..01a9d3cf
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/EvalWindow.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Evaluator.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Evaluator.class
new file mode 100644
index 00000000..907802cd
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Evaluator.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/FileHeader.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/FileHeader.class
new file mode 100644
index 00000000..305c55b3
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/FileHeader.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/FilePopupMenu.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/FilePopupMenu.class
new file mode 100644
index 00000000..d5df1cc1
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/FilePopupMenu.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/FileTextArea.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/FileTextArea.class
new file mode 100644
index 00000000..14095a02
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/FileTextArea.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/FileWindow.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/FileWindow.class
new file mode 100644
index 00000000..42ba5106
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/FileWindow.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/FindFunction$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/FindFunction$1.class
new file mode 100644
index 00000000..8bc8996a
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/FindFunction$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/FindFunction$MouseHandler.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/FindFunction$MouseHandler.class
new file mode 100644
index 00000000..51f80ef9
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/FindFunction$MouseHandler.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/FindFunction.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/FindFunction.class
new file mode 100644
index 00000000..a68bf6d7
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/FindFunction.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/GuiCallback.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/GuiCallback.class
new file mode 100644
index 00000000..5966d54b
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/GuiCallback.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/JSInternalConsole$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/JSInternalConsole$1.class
new file mode 100644
index 00000000..e02295e8
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/JSInternalConsole$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/JSInternalConsole.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/JSInternalConsole.class
new file mode 100644
index 00000000..1971eee1
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/JSInternalConsole.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Main$IProxy.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Main$IProxy.class
new file mode 100644
index 00000000..770087e5
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Main$IProxy.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Main.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Main.class
new file mode 100644
index 00000000..caf638fa
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Main.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Menubar.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Menubar.class
new file mode 100644
index 00000000..40a23978
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/Menubar.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/MessageDialogWrapper.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/MessageDialogWrapper.class
new file mode 100644
index 00000000..a5752a38
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/MessageDialogWrapper.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/MoreWindows$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/MoreWindows$1.class
new file mode 100644
index 00000000..b6327f58
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/MoreWindows$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/MoreWindows$MouseHandler.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/MoreWindows$MouseHandler.class
new file mode 100644
index 00000000..e342c16f
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/MoreWindows$MouseHandler.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/MoreWindows.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/MoreWindows.class
new file mode 100644
index 00000000..99777280
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/MoreWindows.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/MyTableModel.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/MyTableModel.class
new file mode 100644
index 00000000..f4cfcc59
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/MyTableModel.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/MyTreeTable.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/MyTreeTable.class
new file mode 100644
index 00000000..41f38b7d
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/MyTreeTable.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/RunProxy.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/RunProxy.class
new file mode 100644
index 00000000..04ee83bc
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/RunProxy.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/ScopeProvider.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/ScopeProvider.class
new file mode 100644
index 00000000..571fa1a6
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/ScopeProvider.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/SwingGui$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/SwingGui$1.class
new file mode 100644
index 00000000..087296e2
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/SwingGui$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/SwingGui$2.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/SwingGui$2.class
new file mode 100644
index 00000000..6b89906c
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/SwingGui$2.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/SwingGui.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/SwingGui.class
new file mode 100644
index 00000000..1864ba4f
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/SwingGui.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/VariableModel$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/VariableModel$1.class
new file mode 100644
index 00000000..a54b9447
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/VariableModel$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/VariableModel$VariableNode.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/VariableModel$VariableNode.class
new file mode 100644
index 00000000..ad3d8c09
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/VariableModel$VariableNode.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/VariableModel.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/VariableModel.class
new file mode 100644
index 00000000..2772c1b3
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/VariableModel.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/AbstractCellEditor.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/AbstractCellEditor.class
new file mode 100644
index 00000000..a3c68909
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/AbstractCellEditor.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/JTreeTable$ListToTreeSelectionModelWrapper$ListSelectionHandler.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/JTreeTable$ListToTreeSelectionModelWrapper$ListSelectionHandler.class
new file mode 100644
index 00000000..e3b49a7c
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/JTreeTable$ListToTreeSelectionModelWrapper$ListSelectionHandler.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/JTreeTable$ListToTreeSelectionModelWrapper.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/JTreeTable$ListToTreeSelectionModelWrapper.class
new file mode 100644
index 00000000..ae307ad0
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/JTreeTable$ListToTreeSelectionModelWrapper.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/JTreeTable$TreeTableCellEditor.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/JTreeTable$TreeTableCellEditor.class
new file mode 100644
index 00000000..118020fc
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/JTreeTable$TreeTableCellEditor.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/JTreeTable$TreeTableCellRenderer.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/JTreeTable$TreeTableCellRenderer.class
new file mode 100644
index 00000000..34df3341
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/JTreeTable$TreeTableCellRenderer.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/JTreeTable.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/JTreeTable.class
new file mode 100644
index 00000000..33b6d895
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/JTreeTable.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/TreeTableModel.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/TreeTableModel.class
new file mode 100644
index 00000000..6f9b6020
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/TreeTableModel.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/TreeTableModelAdapter$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/TreeTableModelAdapter$1.class
new file mode 100644
index 00000000..272c7af1
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/TreeTableModelAdapter$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/TreeTableModelAdapter$2.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/TreeTableModelAdapter$2.class
new file mode 100644
index 00000000..7a21510e
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/TreeTableModelAdapter$2.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/TreeTableModelAdapter$3.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/TreeTableModelAdapter$3.class
new file mode 100644
index 00000000..5f011b8f
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/TreeTableModelAdapter$3.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/TreeTableModelAdapter.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/TreeTableModelAdapter.class
new file mode 100644
index 00000000..6eba2f90
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/debugger/downloaded/TreeTableModelAdapter.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/idswitch/CodePrinter.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/idswitch/CodePrinter.class
new file mode 100644
index 00000000..ca969054
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/idswitch/CodePrinter.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/idswitch/FileBody$ReplaceItem.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/idswitch/FileBody$ReplaceItem.class
new file mode 100644
index 00000000..fbd50d76
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/idswitch/FileBody$ReplaceItem.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/idswitch/FileBody.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/idswitch/FileBody.class
new file mode 100644
index 00000000..fa0a5440
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/idswitch/FileBody.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/idswitch/IdValuePair.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/idswitch/IdValuePair.class
new file mode 100644
index 00000000..629cff4b
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/idswitch/IdValuePair.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/idswitch/Main.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/idswitch/Main.class
new file mode 100644
index 00000000..b8d33f2e
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/idswitch/Main.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/idswitch/SwitchGenerator.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/idswitch/SwitchGenerator.class
new file mode 100644
index 00000000..e9b48890
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/idswitch/SwitchGenerator.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/jsc/Main.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/jsc/Main.class
new file mode 100644
index 00000000..b60b3c91
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/jsc/Main.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/resources/Messages.properties b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/resources/Messages.properties
new file mode 100644
index 00000000..8c178a40
--- /dev/null
+++ b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/resources/Messages.properties
@@ -0,0 +1,265 @@
+#
+# JavaScript tools messages file.
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Rhino code, released
+# May 6, 1999.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1997-1999
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 or later (the "GPL"), in which
+# case the provisions of the GPL are applicable instead of those above. If
+# you wish to allow use of your version of this file only under the terms of
+# the GPL and not to allow others to use your version of this file under the
+# MPL, indicate your decision by deleting the provisions above and replacing
+# them with the notice and other provisions required by the GPL. If you do
+# not delete the provisions above, a recipient may use your version of this
+# file under either the MPL or the GPL.
+#
+# ***** END LICENSE BLOCK *****
+
+msg.expected.string.arg =\
+ Expected a string argument.
+
+msg.class.not.found =\
+ Class "{0}" not found.
+
+msg.couldnt.open =\
+ Couldn''t open file "{0}".
+
+msg.couldnt.open.url =\
+ Couldn''t open URL "{0}: {1}".
+
+msg.no-opt =\
+ Must have the org.mozilla.javascript.optimizer package available \
+ to compile to class files.
+
+msg.shell.invalid =\
+ Invalid option "{0}"
+
+msg.shell.usage =\
+ Usage: java {0} [options...] [files]\n\
+ Valid options are:\n\
+ \ -?, -help Displays help messages.\n\
+ \ -w Enable warnings.\n\
+ \ -version 100|110|120|130|140|150|160\n\
+ \ Set a specific language version.\n\
+ \ -opt [-1|0-9] Set optimization level.\n\
+ \ -f script-filename Execute script file.\n\
+ \ -e script-source Evaluate inline script.\n\
+ \ -debug Generate debug code.\n\
+ \ -strict Enable strict mode warnings.\n\
+ \ -fatal-warnings Treat warnings as errors.
+
+
+msg.help =\
+ \n\
+ Command Description \n\
+ ======= =========== \n\
+ help() Display usage and help messages. \n\
+ defineClass(className) Define an extension using the Java class \n\
+ \ named with the string argument. \n\
+ \ Uses ScriptableObject.defineClass(). \n\
+ load(["foo.js", ...]) Load JavaScript source files named by \n\
+ \ string arguments. \n\
+ loadClass(className) Load a class named by a string argument. \n\
+ \ The class must be a script compiled to a \n\
+ \ class file. \n\
+ print([expr ...]) Evaluate and print expressions. \n\
+ quit() Quit the shell. \n\
+ version([number]) Get or set the JavaScript version number. \n\
+ gc() Runs the garbage collector.\n\
+ spawn(arg) Evaluate function or scriptname on a new thread \n\
+ sync(function) Creates a synchronized version of the function, \n\
+ \ where the synchronization object is "this" \n\
+ readFile(fileName [, encoding])\n\
+ \ Returns the content of the file as a string. \n\
+ \ Encoding of the string can be optionally specified. \n\
+ readUrl(url [, encoding]) \n\
+ \ Similar to readFile, reads the contents of the url.\n\
+ runCommand(name ...) Runs a specified shell command. Additional arguments are \n\
+ \ passed to the command \n\
+ seal(args ...) Seals the supplied objects \n\
+ toint32(arg) Converts the argument into a 32-bit integer \n\
+ serialize(obj, fileName) \n\
+ \ Serializes an object and saves it to a file \n\
+ deserialise(fileName) Reconstructs a serialized object \n\
+ environment Returns the current environment object \n\
+ history Displays the shell command history \n\
+ \n\
+ For full description of all available commands see shell.html in\n\
+ the docs directory of Rhino distribution.\n\
+
+msg.warning =\
+ warning: {0}
+
+msg.format1 =\
+ {0}
+
+msg.format2 =\
+ line {0}: {1}
+
+msg.format3 =\
+ "{0}", line {1}: {2}
+
+msg.uncaughtJSException =\
+ exception from uncaught JavaScript throw: {0}
+
+msg.uncaughtEcmaError =\
+ uncaught JavaScript runtime exception: {0}
+
+msg.jsc.bad.usage =\
+ Didn''t understand "{1}". \n\
+ For more information, try java {0} -h
+
+msg.jsc.usage =\
+Usage: java {0} [OPTION]... SOURCE...\n\
+Valid options are: \n\
+\ -version VERSION Use the specified language version.\n\
+\ VERSION should be one of 100|110|120|130|140|150|160.\n\
+\ -opt LEVEL Use optimization with the specified level.\n\
+\ LEVEL should be one of 0..9.\n\
+\ -debug, -g Include debug information.\n\
+\ -nosource Do not include source to function objects.\n\
+\ It makes f.toString() useless and violates ECMAScript\n\
+\ standard but makes generated classes smaller and\n\
+\ saves memory.\n\
+\ -o CLASSNAME Use specified name as the last component of the main\n\
+\ generated class name. When specified, only one script\n\
+\ SOURCE is allowed. If omitted, it defaults to source\n\
+\ name with stripped .js suffix.\n\
+\ -package PACKAGE Place generated classes in the specified package.\n\
+\ -d DIRECTORY Use DIRECTORY as destination directory for generated\n\
+\ classes. If omitted, it defaults to parent directory\n\
+\ of SOURCE.\n\
+\ -extends CLASS The main generated class will extend the specified\n\
+\ class CLASS.\n\
+\ -implements INTERFACE1,INTERFACE2,... The main generated class will\n\
+\ implement the specified list of interfaces.\n\
+\ -main-method-class CLASS Specify the class name used for main method \n\
+\ implementation. The class must have a method matching\n\
+\ "public static void main(Script sc, String[] args)"\n\
+\ -help, --help, -h Print this help and exit.\n\
+
+
+msg.no.file =\
+ A file name must be specified to compile.
+
+msg.invalid.classfile.name =\
+ File "{0}" is not a valid class file name.
+
+msg.extension.not.js =\
+ File "{0}" is not a valid js file name.
+
+msg.jsfile.not.found=\
+ File "{0}" not found.
+
+msg.multiple.js.to.file =\
+ Cannot compile multiple js files to "{0}".
+
+msg.package.name =\
+ "{0}" is not a valid package name.
+
+msg.spawn.args =\
+ Argument to spawn() must be a function or script.
+
+msg.must.implement.Script =\
+ Argument to loadClass() must be the name of a class that implements \
+ the Script interface. Class files generated by compiling scripts \
+ will implement Script.
+
+msg.runCommand.bad.args =\
+ The first argument to runCommand must be a command name.
+
+msg.runCommand.bad.env =\
+ A value of the env property of option object for runCommnad must be an \
+ object.
+
+msg.shell.seal.not.object =\
+ seal function can only be applied to objects
+
+msg.shell.seal.not.scriptable =\
+ seal function supports only sealing of ScriptableObject instances
+
+msg.shell.readFile.bad.args =\
+ readFile require at least file path to be specified
+
+msg.shell.readUrl.bad.args =\
+ readUrl require at least file path to be specified
+
+msg.shell.bad.function.scope =\
+ Wrong scope object for shell function: {0}
+
+msg.idswitch.same_string =\
+ The string {0} is used second time in the switch code. \
+ Previous occurrence was at line {1}
+
+msg.idswitch.file_end_in_switch =\
+ End of file inside tag {0}
+
+msg.idswitch.bad_tag_order =\
+ String switch tag {0} is not allowed here
+
+msg.idswitch.no_end_with_value =\
+ End for tag {0} can not contain value
+
+msg.idswitch.no_value_allowed =\
+ Tag {0} can not contain value
+
+msg.idswitch.no_end_usage =\
+ Tag {0} can not be used as end tag
+
+msg.idswitch.no_file_argument =\
+ File argument should be given
+
+msg.idswitch.too_many_arguments =\
+ Too many arguments are given
+
+msg.idswitch.bad_option =\
+ Invalid option {0}
+
+msg.idswitch.bad_option_char =\
+ Invalid option letter {0}
+
+msg.idswitch.bad_invocation =\
+StringIdMap: {0}\n\
+For more information, try\n\
+java org.mozilla.javascript.tools.idswitch.StringIdMap --help
+
+msg.idswitch.io_error =\
+StringIdMap: IO error, {0}
+
+msg.idswitch.usage = \
+Usage: java org.mozilla.javascript.tools.idswitch.StringIdMap [OPTIONS] JAVA_SOURCE_FILE\n\
+Generates efficient string dispatch code in JAVA_SOURCE_FILE.\n\
+The resulting Java source fragment replaces the old dispatch code.\n\
+If JAVA_SOURCE_FILE is -, standard input is used for Java source and the\n\
+result is sent to standard output.\n\
+\n\
+\ -h, --help display this help and exit\n\
+\ --version display version information and exit\n\
+\n\
+Note: the original file will be overwritten without any backup actions\n\
+\ and all code inside #generated# tag will be replaced by new one.
+
+msg.idswitch.version = \
+org.mozilla.javascript.tools.idswitch.StringIdMap version 0.2
+
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/ConsoleTextArea.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/ConsoleTextArea.class
new file mode 100644
index 00000000..898be9f4
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/ConsoleTextArea.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/ConsoleWrite.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/ConsoleWrite.class
new file mode 100644
index 00000000..0c826a46
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/ConsoleWrite.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/ConsoleWriter.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/ConsoleWriter.class
new file mode 100644
index 00000000..3419d391
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/ConsoleWriter.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/Environment.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/Environment.class
new file mode 100644
index 00000000..16569855
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/Environment.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/Global$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/Global$1.class
new file mode 100644
index 00000000..fd98d5a1
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/Global$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/Global.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/Global.class
new file mode 100644
index 00000000..22060ca6
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/Global.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JSConsole$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JSConsole$1.class
new file mode 100644
index 00000000..91999a70
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JSConsole$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JSConsole$2.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JSConsole$2.class
new file mode 100644
index 00000000..dcb9a3d3
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JSConsole$2.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JSConsole.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JSConsole.class
new file mode 100644
index 00000000..92fa7777
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JSConsole.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JavaPolicySecurity$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JavaPolicySecurity$1.class
new file mode 100644
index 00000000..b531daab
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JavaPolicySecurity$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JavaPolicySecurity$2.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JavaPolicySecurity$2.class
new file mode 100644
index 00000000..0318a447
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JavaPolicySecurity$2.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JavaPolicySecurity$ContextPermissions$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JavaPolicySecurity$ContextPermissions$1.class
new file mode 100644
index 00000000..73c31cf4
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JavaPolicySecurity$ContextPermissions$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JavaPolicySecurity$ContextPermissions.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JavaPolicySecurity$ContextPermissions.class
new file mode 100644
index 00000000..ed0c8f29
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JavaPolicySecurity$ContextPermissions.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JavaPolicySecurity$Loader.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JavaPolicySecurity$Loader.class
new file mode 100644
index 00000000..2f7d0d7b
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JavaPolicySecurity$Loader.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JavaPolicySecurity.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JavaPolicySecurity.class
new file mode 100644
index 00000000..1897f9f7
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/JavaPolicySecurity.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/Main$IProxy.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/Main$IProxy.class
new file mode 100644
index 00000000..b471499c
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/Main$IProxy.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/Main.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/Main.class
new file mode 100644
index 00000000..6db84c8c
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/Main.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/PipeThread.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/PipeThread.class
new file mode 100644
index 00000000..884dcf2d
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/PipeThread.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/QuitAction.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/QuitAction.class
new file mode 100644
index 00000000..99726373
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/QuitAction.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/Runner.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/Runner.class
new file mode 100644
index 00000000..dbc087bb
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/Runner.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/SecurityProxy.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/SecurityProxy.class
new file mode 100644
index 00000000..e90c73df
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/SecurityProxy.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/ShellContextFactory.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/ShellContextFactory.class
new file mode 100644
index 00000000..7e6f883b
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/tools/shell/ShellContextFactory.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/XMLLib$Factory$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/XMLLib$Factory$1.class
new file mode 100644
index 00000000..cfdfa4d7
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/XMLLib$Factory$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/XMLLib$Factory.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/XMLLib$Factory.class
new file mode 100644
index 00000000..5958f38a
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/XMLLib$Factory.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/XMLLib.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/XMLLib.class
new file mode 100644
index 00000000..22d81f6a
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/XMLLib.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/XMLObject.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/XMLObject.class
new file mode 100644
index 00000000..e9efc997
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/XMLObject.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/LogicalEquality.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/LogicalEquality.class
new file mode 100644
index 00000000..85b7a881
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/LogicalEquality.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/Namespace.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/Namespace.class
new file mode 100644
index 00000000..ee393468
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/Namespace.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/NamespaceHelper.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/NamespaceHelper.class
new file mode 100644
index 00000000..d3c51971
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/NamespaceHelper.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/QName.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/QName.class
new file mode 100644
index 00000000..1bba40a3
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/QName.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XML$NamespaceDeclarations.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XML$NamespaceDeclarations.class
new file mode 100644
index 00000000..526cf663
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XML$NamespaceDeclarations.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XML$XScriptAnnotation.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XML$XScriptAnnotation.class
new file mode 100644
index 00000000..621aeda1
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XML$XScriptAnnotation.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XML.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XML.class
new file mode 100644
index 00000000..d40075af
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XML.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XMLCtor.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XMLCtor.class
new file mode 100644
index 00000000..60a59e62
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XMLCtor.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XMLLibImpl.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XMLLibImpl.class
new file mode 100644
index 00000000..b7cf33af
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XMLLibImpl.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XMLList$AnnotationList.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XMLList$AnnotationList.class
new file mode 100644
index 00000000..74c8627c
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XMLList$AnnotationList.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XMLList.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XMLList.class
new file mode 100644
index 00000000..0f3e8d7b
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XMLList.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XMLName.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XMLName.class
new file mode 100644
index 00000000..351624b6
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XMLName.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XMLObjectImpl.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XMLObjectImpl.class
new file mode 100644
index 00000000..772e7dae
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XMLObjectImpl.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XMLWithScope.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XMLWithScope.class
new file mode 100644
index 00000000..ff257b54
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xml/impl/xmlbeans/XMLWithScope.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/Namespace.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/Namespace.class
new file mode 100644
index 00000000..2b6c8d08
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/Namespace.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/QName.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/QName.class
new file mode 100644
index 00000000..65e92482
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/QName.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XML.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XML.class
new file mode 100644
index 00000000..65d84bc6
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XML.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XMLCtor.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XMLCtor.class
new file mode 100644
index 00000000..2fb3d997
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XMLCtor.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XMLLibImpl.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XMLLibImpl.class
new file mode 100644
index 00000000..e09c962b
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XMLLibImpl.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XMLList.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XMLList.class
new file mode 100644
index 00000000..1ee2712f
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XMLList.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XMLName.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XMLName.class
new file mode 100644
index 00000000..5a2e3a0e
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XMLName.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XMLObjectImpl.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XMLObjectImpl.class
new file mode 100644
index 00000000..b590d8da
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XMLObjectImpl.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XMLWithScope.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XMLWithScope.class
new file mode 100644
index 00000000..40594a84
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XMLWithScope.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$1.class
new file mode 100644
index 00000000..e55c5bef
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Filter$1.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Filter$1.class
new file mode 100644
index 00000000..52a88223
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Filter$1.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Filter$2.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Filter$2.class
new file mode 100644
index 00000000..35362f94
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Filter$2.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Filter$3.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Filter$3.class
new file mode 100644
index 00000000..771376c3
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Filter$3.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Filter$4.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Filter$4.class
new file mode 100644
index 00000000..c36a0b68
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Filter$4.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Filter$5.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Filter$5.class
new file mode 100644
index 00000000..f53bd175
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Filter$5.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Filter.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Filter.class
new file mode 100644
index 00000000..e7f4396f
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Filter.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$List.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$List.class
new file mode 100644
index 00000000..94fe74af
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$List.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Namespace.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Namespace.class
new file mode 100644
index 00000000..a02fd3bc
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Namespace.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Namespaces.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Namespaces.class
new file mode 100644
index 00000000..d4594dcf
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$Namespaces.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$QName.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$QName.class
new file mode 100644
index 00000000..fa9bc30b
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode$QName.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode.class
new file mode 100644
index 00000000..5d6a4873
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlNode.class differ
diff --git a/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlProcessor.class b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlProcessor.class
new file mode 100644
index 00000000..26ae4b95
Binary files /dev/null and b/yuicompressor-2.4.2/build/jar/org/mozilla/javascript/xmlimpl/XmlProcessor.class differ
diff --git a/yuicompressor-2.4.2/build/yuicompressor-2.4.2.jar b/yuicompressor-2.4.2/build/yuicompressor-2.4.2.jar
new file mode 100644
index 00000000..b48f3973
Binary files /dev/null and b/yuicompressor-2.4.2/build/yuicompressor-2.4.2.jar differ
diff --git a/yuicompressor-2.4.2/doc/CHANGELOG b/yuicompressor-2.4.2/doc/CHANGELOG
new file mode 100644
index 00000000..714fdcc8
--- /dev/null
+++ b/yuicompressor-2.4.2/doc/CHANGELOG
@@ -0,0 +1,226 @@
+YUI Compressor 2.4.2, 2008-11-10
+--------------------------------
+
++ Preserved comments shouldn't prevent obfuscation (Thanks to Matjaz Lipus)
+
+YUI Compressor 2.4.1, 2008-10-28
+--------------------------------
+
++ Use preferentially lower case letters for obfuscated variable names.
+ Since JavaScript keywords use lower case letters most often, this
+ improves the efficiency of any compression algorithm (gzipping)
+ used after minification.
++ Don't append a semi-colon at the end of a JavaScript file when the
+ last token is a special comment.
+
+YUI Compressor 2.4, 2008-10-21
+------------------------------
+
++ Allowed the YUI Compressor (which uses a modified version of Rhino)
+ to work alongside the original (unmodified) rhino library by using
+ a custom class loader.
++ Added all that's necessary to build the YUI Compressor to the
+ downloable package.
++ Fixed unnecessary white space after return / typeof when possible.
+
+YUI Compressor 2.3.6, 2008-07-10
+--------------------------------
+
++ Fixed a few minor bugs with the CSS compressor
++ Changed packaging. The original Rhino library, which is used to build the
+ YUI Compressor, is not part of the downloadable archive. Too many people
+ put it in their classpath, generating a lot of invalid bugs.
+
+YUI Compressor 2.3.5, 2008-02-08
+--------------------------------
+
++ Added a warning when more than one 'var' statement is used in a single scope.
+ Automatic coalescence is extremely complicated, and would be unsafe if not
+ done properly.
+
+YUI Compressor 2.3.4, 2008-02-07
+--------------------------------
+
++ Expanded the list of reserved words used by isValidIdentifier()
+
+YUI Compressor 2.3.3, 2008-02-04
+--------------------------------
+
++ C-style comments starting with /*! are preserved. This is especially
+ useful with comments containing copyright/license information.
+
+YUI Compressor 2.3.2, 2008-02-01
+--------------------------------
+
++ Compressing an empty JS file throws an error [SourceForge bug #1884207]
++ When a string is the first token in a function body, it was removed from
+ the compressed file [SourceForge bug #1884314]
+
+YUI Compressor 2.3.1, 2008-01-30
+--------------------------------
+
++ Added test against list of reserved words in method isValidIdentifier.
+
+YUI Compressor 2.3, 2008-01-28
+------------------------------
+
++ Always output a ';' at the end of a minified JavaScript file. This allows
+ the concatenating of several minified files without the fear of introducing
+ a syntax error.
++ Removed all System.exit() statements. Throw exceptions instead. This is
+ especially useful when running the compressor from within a J2EE container.
+ [SourceForge bug #1834750]
++ Transform obj["foo"] into obj.foo whenever possible, saving 3 bytes.
++ Transform 'foo': ... into foo: ... whenever possible, saving 2 bytes.
++ Added support for multi-line string literals [SourceForge bug #1871453]
++ Added support for unescaped slashes inside character classes in regexp.
++ Minor performance improvements.
++ Preserve the escaping for an octal representation of a character in string
+ literals [SourceForge bug #1844894]
+
+ var a = '\001';
+
++ CSS: Preserve comments that hide CSS rules from IE Mac:
+
+ /* Hides from IE-mac \*/
+ ...
+ /* End hide from IE-mac */
+
++ CSS: Added support for box model hack [SourceForge bug #1862107]
+
+ div.content {
+ width:400px;
+ voice-family: "\"}\"";
+ voice-family:inherit;
+ width:300px;
+ }
+
+YUI Compressor 2.2.5, 2007-10-09
+--------------------------------
+
++ Remove line terminator after escape in string literals.
+
+YUI Compressor 2.2.4, 2007-10-01
+--------------------------------
+
++ Fixed the way quote characters are counted in string literals
+ [SourceForge bug #1804576]
++ Do not use a regular expression using non-greedy matching to remove CSS
+ comments (if the comment is more than 800 characters long or so, a stack
+ overflow exception gets thrown) Instead, use good old parsing...
++ Fix unnecessary quote escaping in string literals.
+
+YUI Compressor 2.2.3, 2007-09-28
+--------------------------------
+
++ Transform <'+'/script>' completely useless.
++ When converting decimal rgb color values to hexadecimal color values,
+ prepend a '0' if the value is less than 16. Otherwise, rgb(0,124,114)
+ for instance becomes #07c72, which is incorrect.
++ In CSS files, do not change color names into their corresponding color
+ codes (and vice-versa) due to the high potential of introducing bugs
+ (rolled back from 2.2.1)
+
+YUI Compressor 2.2.1, 2007-09-25
+--------------------------------
+
++ Optimize quote escaping in JavaScript string literals by using the best quote
+ character (' or " depending on the occurrence of this character in the string)
++ Fixed minor bug in the CSS compressor. Colors should not be shortened in
+ filter: chroma(color="#FFFFFF");
+ Otherwise, it makes the filter break in Internet Explorer.
++ In CSS files, change color names into their corresponding color codes
+ (and vice-versa) if that change yields any savings.
+
+YUI Compressor 2.2, 2007-09-18
+------------------------------
+
++ Don't obfuscate function argument named $super if it is the first function
+ argument listed. This is to support Prototype 1.6's heretic implementation.
++ Added support for stdin/stdout (see README for more info)
++ Shorten colors from rgb(51,102,153) to #336699 in CSS files.
++ Shorten values from 0.8em to .8em in CSS files.
++ Added support for Internet Explorer's conditional comments in JavaScript
+ files. Note that the presence of a conditional comment inside a function
+ (i.e. not in the global scope) will reduce the level of compression for the
+ same reason the use of 'eval' or 'with' reduces the level of compression
+ (conditional comments, which do not get parsed, may refer to local variables,
+ which get obfuscated) In any case, the use of Internet Explorer's conditional
+ comment is to be avoided.
+
+YUI Compressor 2.1.2, 2007-08-31
+--------------------------------
+
++ Added --preserve-semi option
++ Modified --line-break option
+
+YUI Compressor 2.1.1, 2007-08-30
+--------------------------------
+
++ Fixed missing space in CSS background:url('foo.png')no-repeat
+ causing a background not to appear on Internet Explorer.
+
+YUI Compressor 2.1, 2007-08-29
+------------------------------
+
++ Pass the --line-break option to the CSS compressor.
++ Allow the output file to overwrite the input file (with version 2.0,
+ in this case, the output file was always empty)
++ Remove spaces before and after '(' and ')' as in background:url('xxx');
++ Merge (if possible) string literals that are appended in JavaScript files.
+ This not only makes the code smaller, it makes the code faster,
+ but allows you to maintain some readability in your source code.
++ Handle constructs such as a + ++ b or a + + "1" (in which case the
+ space between the operators must be kept!) and other similar cases...
++ Pass ErrorReporter instance to the constructor of class JavaScriptCompressor
+ (as suggested by David Bernard for his integration of the YUI Compressor
+ as a maven plugin)
+
+YUI Compressor 2.0, 2007-08-27
+------------------------------
+
++ Switched from Rhino 1.6R6 to Rhino 1.6R7
++ Integrated Isaac Schlueter's CSS compressor.
++ Refactored code to make it easier to use the compressor from a servlet
+ environment or another Java app (no need to pass in file names anymore)
++ Output a white-space character after 'throw' only when necessary.
++ Output a white-space character after 'break' and 'continue' when followed
+ by a label.
+
+YUI Compressor 1.1, 2007-08-20
+------------------------------
+
++ Java source now in package com.yahoo.platform.yui.compressor
++ Added --line-break option that adds a line feed character after each
+ semi-colon character (may help debugging with the MS Script debugger)
++ Added support for missing JavaScript features (get, set, const)
++ Do not show the entire stack trace when the input file cannot be found.
++ Removed the randomization of obfuscated symbols. When compressed code is
+ checked in CVS, unchanged files would otherwise end up being versioned.
++ Added web-based front-end to the YUI Compressor as part of the dist package.
++ Added a public entry point that makes the YUI Compressor easy to integrate
+ with an already existing Java application.
++ Simplified code by using the same parsing routines used to build the symbol
+ tree while looking for undeclared symbols.
++ Count how many times each identifier is used, and display a warning when an
+ identifier seems to be unused (code cannot safely be removed automatically)
++ Remove ';' when followed by a '}'. This yields an additional ~1.5% savings
+ on yahoo-dom-event.js compared to the JSMin version.
++ Output a white-space character after 'return' and 'case' only when necessary.
diff --git a/yuicompressor-2.4.2/doc/README b/yuicompressor-2.4.2/doc/README
new file mode 100644
index 00000000..1604846c
--- /dev/null
+++ b/yuicompressor-2.4.2/doc/README
@@ -0,0 +1,140 @@
+==============================================================================
+YUI Compressor
+==============================================================================
+
+NAME
+
+ YUI Compressor - The Yahoo! JavaScript and CSS Compressor
+
+SYNOPSIS
+
+ Usage: java -jar yuicompressor-x.y.z.jar [options] [input file]
+
+ Global Options
+ -h, --help Displays this information
+ --type Specifies the type of the input file
+ --charset Read the input file using
+ --line-break Insert a line break after the specified column number
+ -v, --verbose Display informational messages and warnings
+ -o Place the output into . Defaults to stdout.
+
+ JavaScript Options
+ --nomunge Minify only, do not obfuscate
+ --preserve-semi Preserve all semicolons
+ --disable-optimizations Disable all micro optimizations
+
+DESCRIPTION
+
+ The YUI Compressor is a JavaScript compressor which, in addition to removing
+ comments and white-spaces, obfuscates local variables using the smallest
+ possible variable name. This obfuscation is safe, even when using constructs
+ such as 'eval' or 'with' (although the compression is not optimal is those
+ cases) Compared to jsmin, the average savings is around 20%.
+
+ The YUI Compressor is also able to safely compress CSS files. The decision
+ on which compressor is being used is made on the file extension (js or css)
+
+GLOBAL OPTIONS
+
+ -h, --help
+ Prints help on how to use the YUI Compressor
+
+ --line-break
+ Some source control tools don't like files containing lines longer than,
+ say 8000 characters. The linebreak option is used in that case to split
+ long lines after a specific column. It can also be used to make the code
+ more readable, easier to debug (especially with the MS Script Debugger)
+ Specify 0 to get a line break after each semi-colon in JavaScript, and
+ after each rule in CSS.
+
+ --type js|css
+ The type of compressor (JavaScript or CSS) is chosen based on the
+ extension of the input file name (.js or .css) This option is required
+ if no input file has been specified. Otherwise, this option is only
+ required if the input file extension is neither 'js' nor 'css'.
+
+ --charset character-set
+ If a supported character set is specified, the YUI Compressor will use it
+ to read the input file. Otherwise, it will assume that the platform's
+ default character set is being used. The output file is encoded using
+ the same character set.
+
+ -o outfile
+ Place output in file outfile. If not specified, the YUI Compressor will
+ default to the standard output, which you can redirect to a file.
+
+ -v, --verbose
+ Display informational messages and warnings.
+
+JAVASCRIPT ONLY OPTIONS
+
+ --nomunge
+ Minify only. Do not obfuscate local symbols.
+
+ --preserve-semi
+ Preserve unnecessary semicolons (such as right before a '}') This option
+ is useful when compressed code has to be run through JSLint (which is the
+ case of YUI for example)
+
+ --disable-optimizations
+ Disable all the built-in micro optimizations.
+
+NOTES
+
+ + If no input file is specified, it defaults to stdin.
+
+ + The YUI Compressor requires Java version >= 1.4.
+
+ + It is possible to prevent a local variable, nested function or function
+ argument from being obfuscated by using "hints". A hint is a string that
+ is located at the very beginning of a function body like so:
+
+ function fn (arg1, arg2, arg3) {
+ "arg2:nomunge, localVar:nomunge, nestedFn:nomunge";
+
+ ...
+ var localVar;
+ ...
+
+ function nestedFn () {
+ ....
+ }
+
+ ...
+ }
+
+ The hint itself disappears from the compressed file.
+
+ + C-style comments starting with /*! are preserved. This is useful with
+ comments containing copyright/license information. For example:
+
+ /*!
+ * TERMS OF USE - EASING EQUATIONS
+ * Open source under the BSD License.
+ * Copyright 2001 Robert Penner All rights reserved.
+ */
+
+ becomes:
+
+ /*
+ * TERMS OF USE - EASING EQUATIONS
+ * Open source under the BSD License.
+ * Copyright 2001 Robert Penner All rights reserved.
+ */
+
+AUTHOR
+
+ The YUI Compressor was written and is maintained by:
+ Julien Lecomte
+ The CSS portion is a port of Isaac Schlueter's cssmin utility.
+
+COPYRIGHT
+
+ Copyright (c) 2007-2009, Yahoo! Inc. All rights reserved.
+
+LICENSE
+
+ All code specific to YUI Compressor is issued under a BSD license.
+ YUI Compressor extends and implements code from Mozilla's Rhino project.
+ Rhino is issued under the Mozilla Public License (MPL), and MPL applies
+ to the Rhino source and binaries that are distributed with YUI Compressor.
\ No newline at end of file
diff --git a/yuicompressor-2.4.2/lib/jargs-1.0.jar b/yuicompressor-2.4.2/lib/jargs-1.0.jar
new file mode 100644
index 00000000..cdbc80bb
Binary files /dev/null and b/yuicompressor-2.4.2/lib/jargs-1.0.jar differ
diff --git a/yuicompressor-2.4.2/lib/rhino-1.6R7.jar b/yuicompressor-2.4.2/lib/rhino-1.6R7.jar
new file mode 100644
index 00000000..2e0d1e8f
Binary files /dev/null and b/yuicompressor-2.4.2/lib/rhino-1.6R7.jar differ
diff --git a/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/Bootstrap.java b/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/Bootstrap.java
new file mode 100644
index 00000000..1b95aca1
--- /dev/null
+++ b/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/Bootstrap.java
@@ -0,0 +1,22 @@
+/*
+ * YUI Compressor
+ * Author: Julien Lecomte
+ * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ */
+
+package com.yahoo.platform.yui.compressor;
+
+import java.lang.reflect.Method;
+
+public class Bootstrap {
+
+ public static void main(String args[]) throws Exception {
+ ClassLoader loader = new JarClassLoader();
+ Thread.currentThread().setContextClassLoader(loader);
+ Class c = loader.loadClass(YUICompressor.class.getName());
+ Method main = c.getMethod("main", new Class[]{String[].class});
+ main.invoke(null, new Object[]{args});
+ }
+}
\ No newline at end of file
diff --git a/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/CssCompressor.java b/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/CssCompressor.java
new file mode 100644
index 00000000..68b4de99
--- /dev/null
+++ b/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/CssCompressor.java
@@ -0,0 +1,188 @@
+/*
+ * YUI Compressor
+ * Author: Julien Lecomte
+ * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ *
+ * This code is a port of Isaac Schlueter's cssmin utility.
+ */
+
+package com.yahoo.platform.yui.compressor;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+public class CssCompressor {
+
+ private StringBuffer srcsb = new StringBuffer();
+
+ public CssCompressor(Reader in) throws IOException {
+ // Read the stream...
+ int c;
+ while ((c = in.read()) != -1) {
+ srcsb.append((char) c);
+ }
+ }
+
+ public void compress(Writer out, int linebreakpos)
+ throws IOException {
+
+ Pattern p;
+ Matcher m;
+ String css;
+ StringBuffer sb;
+ int startIndex, endIndex;
+
+ // Remove all comment blocks...
+ startIndex = 0;
+ boolean iemac = false;
+ boolean preserve = false;
+ sb = new StringBuffer(srcsb.toString());
+ while ((startIndex = sb.indexOf("/*", startIndex)) >= 0) {
+ preserve = sb.length() > startIndex + 2 && sb.charAt(startIndex + 2) == '!';
+ endIndex = sb.indexOf("*/", startIndex + 2);
+ if (endIndex < 0) {
+ if (!preserve) {
+ sb.delete(startIndex, sb.length());
+ }
+ } else if (endIndex >= startIndex + 2) {
+ if (sb.charAt(endIndex-1) == '\\') {
+ // Looks like a comment to hide rules from IE Mac.
+ // Leave this comment, and the following one, alone...
+ startIndex = endIndex + 2;
+ iemac = true;
+ } else if (iemac) {
+ startIndex = endIndex + 2;
+ iemac = false;
+ } else if (!preserve) {
+ sb.delete(startIndex, endIndex + 2);
+ } else {
+ startIndex = endIndex + 2;
+ }
+ }
+ }
+
+ css = sb.toString();
+
+ // Normalize all whitespace strings to single spaces. Easier to work with that way.
+ css = css.replaceAll("\\s+", " ");
+
+ // Make a pseudo class for the Box Model Hack
+ css = css.replaceAll("\"\\\\\"}\\\\\"\"", "___PSEUDOCLASSBMH___");
+
+ // Remove the spaces before the things that should not have spaces before them.
+ // But, be careful not to turn "p :link {...}" into "p:link{...}"
+ // Swap out any pseudo-class colons with the token, and then swap back.
+ sb = new StringBuffer();
+ p = Pattern.compile("(^|\\})(([^\\{:])+:)+([^\\{]*\\{)");
+ m = p.matcher(css);
+ while (m.find()) {
+ String s = m.group();
+ s = s.replaceAll(":", "___PSEUDOCLASSCOLON___");
+ m.appendReplacement(sb, s);
+ }
+ m.appendTail(sb);
+ css = sb.toString();
+ css = css.replaceAll("\\s+([!{};:>+\\(\\)\\],])", "$1");
+ css = css.replaceAll("___PSEUDOCLASSCOLON___", ":");
+
+ // Remove the spaces after the things that should not have spaces after them.
+ css = css.replaceAll("([!{}:;>+\\(\\[,])\\s+", "$1");
+
+ // Add the semicolon where it's missing.
+ css = css.replaceAll("([^;\\}])}", "$1;}");
+
+ // Replace 0(px,em,%) with 0.
+ css = css.replaceAll("([\\s:])(0)(px|em|%|in|cm|mm|pc|pt|ex)", "$1$2");
+
+ // Replace 0 0 0 0; with 0.
+ css = css.replaceAll(":0 0 0 0;", ":0;");
+ css = css.replaceAll(":0 0 0;", ":0;");
+ css = css.replaceAll(":0 0;", ":0;");
+ // Replace background-position:0; with background-position:0 0;
+ css = css.replaceAll("background-position:0;", "background-position:0 0;");
+
+ // Replace 0.6 to .6, but only when preceded by : or a white-space
+ css = css.replaceAll("(:|\\s)0+\\.(\\d+)", "$1.$2");
+
+ // Shorten colors from rgb(51,102,153) to #336699
+ // This makes it more likely that it'll get further compressed in the next step.
+ p = Pattern.compile("rgb\\s*\\(\\s*([0-9,\\s]+)\\s*\\)");
+ m = p.matcher(css);
+ sb = new StringBuffer();
+ while (m.find()) {
+ String[] rgbcolors = m.group(1).split(",");
+ StringBuffer hexcolor = new StringBuffer("#");
+ for (int i = 0; i < rgbcolors.length; i++) {
+ int val = Integer.parseInt(rgbcolors[i]);
+ if (val < 16) {
+ hexcolor.append("0");
+ }
+ hexcolor.append(Integer.toHexString(val));
+ }
+ m.appendReplacement(sb, hexcolor.toString());
+ }
+ m.appendTail(sb);
+ css = sb.toString();
+
+ // Shorten colors from #AABBCC to #ABC. Note that we want to make sure
+ // the color is not preceded by either ", " or =. Indeed, the property
+ // filter: chroma(color="#FFFFFF");
+ // would become
+ // filter: chroma(color="#FFF");
+ // which makes the filter break in IE.
+ p = Pattern.compile("([^\"'=\\s])(\\s*)#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])");
+ m = p.matcher(css);
+ sb = new StringBuffer();
+ while (m.find()) {
+ // Test for AABBCC pattern
+ if (m.group(3).equalsIgnoreCase(m.group(4)) &&
+ m.group(5).equalsIgnoreCase(m.group(6)) &&
+ m.group(7).equalsIgnoreCase(m.group(8))) {
+ m.appendReplacement(sb, m.group(1) + m.group(2) + "#" + m.group(3) + m.group(5) + m.group(7));
+ } else {
+ m.appendReplacement(sb, m.group());
+ }
+ }
+ m.appendTail(sb);
+ css = sb.toString();
+
+ // Remove empty rules.
+ css = css.replaceAll("[^\\}]+\\{;\\}", "");
+
+ if (linebreakpos >= 0) {
+ // Some source control tools don't like it when files containing lines longer
+ // than, say 8000 characters, are checked in. The linebreak option is used in
+ // that case to split long lines after a specific column.
+ int i = 0;
+ int linestartpos = 0;
+ sb = new StringBuffer(css);
+ while (i < sb.length()) {
+ char c = sb.charAt(i++);
+ if (c == '}' && i - linestartpos > linebreakpos) {
+ sb.insert(i, '\n');
+ linestartpos = i;
+ }
+ }
+
+ css = sb.toString();
+ }
+
+ // Replace the pseudo class for the Box Model Hack
+ css = css.replaceAll("___PSEUDOCLASSBMH___", "\"\\\\\"}\\\\\"\"");
+
+ // Replace multiple semi-colons in a row by a single one
+ // See SF bug #1980989
+ css = css.replaceAll(";;+", ";");
+
+ // Trim the final string (for any leading or trailing white spaces)
+ css = css.trim();
+
+ // Write the output...
+ out.write(css);
+ }
+}
diff --git a/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/JarClassLoader.java b/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/JarClassLoader.java
new file mode 100644
index 00000000..a6d3e13f
--- /dev/null
+++ b/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/JarClassLoader.java
@@ -0,0 +1,158 @@
+/*
+ * YUI Compressor
+ * Author: Julien Lecomte
+ * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ */
+
+package com.yahoo.platform.yui.compressor;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Enumeration;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+public class JarClassLoader extends ClassLoader {
+
+ private static String jarPath;
+
+ public Class loadClass(String name) throws ClassNotFoundException {
+
+ // First check if the class is already loaded
+ Class c = findLoadedClass(name);
+ if (c == null) {
+ c = findClass(name);
+ }
+
+ if (c == null) {
+ c = ClassLoader.getSystemClassLoader().loadClass(name);
+ }
+
+ return c;
+ }
+
+ private static String getJarPath() {
+
+ if (jarPath != null) {
+ return jarPath;
+ }
+
+ String classname = JarClassLoader.class.getName().replace('.', '/') + ".class";
+ String classpath = System.getProperty("java.class.path");
+ String classpaths[] = classpath.split(System.getProperty("path.separator"));
+
+ for (int i = 0; i < classpaths.length; i++) {
+
+ String path = classpaths[i];
+ JarFile jarFile = null;
+ JarEntry jarEntry = null;
+
+ try {
+ jarFile = new JarFile(path);
+ jarEntry = findJarEntry(jarFile, classname);
+ } catch (IOException ioe) {
+ /* ignore */
+ } finally {
+ if (jarFile != null) {
+ try {
+ jarFile.close();
+ } catch (IOException ioe) {
+ /* ignore */
+ }
+ }
+ }
+
+ if (jarEntry != null) {
+ jarPath = path;
+ break;
+ }
+ }
+
+ return jarPath;
+ }
+
+ private static JarEntry findJarEntry(JarFile jarFile, String entryName) {
+
+ Enumeration entries = jarFile.entries();
+
+ while (entries.hasMoreElements()) {
+ JarEntry entry = (JarEntry) entries.nextElement();
+ if (entry.getName().equals(entryName)) {
+ return entry;
+ }
+ }
+
+ return null;
+ }
+
+ protected Class findClass(String name) {
+
+ Class c = null;
+ String jarPath = getJarPath();
+
+ if (jarPath != null) {
+ JarFile jarFile = null;
+ try {
+ jarFile = new JarFile(jarPath);
+ c = loadClassData(jarFile, name);
+ } catch (IOException ioe) {
+ /* ignore */
+ } finally {
+ if (jarFile != null) {
+ try {
+ jarFile.close();
+ } catch (IOException ioe) {
+ /* ignore */
+ }
+ }
+ }
+ }
+
+ return c;
+ }
+
+ private Class loadClassData(JarFile jarFile, String className) {
+
+ String entryName = className.replace('.', '/') + ".class";
+ JarEntry jarEntry = findJarEntry(jarFile, entryName);
+ if (jarEntry == null) {
+ return null;
+ }
+
+ // Create the necessary package if needed...
+ int index = className.lastIndexOf('.');
+ if (index >= 0) {
+ String packageName = className.substring(0, index);
+ if (getPackage(packageName) == null) {
+ definePackage(packageName, "", "", "", "", "", "", null);
+ }
+ }
+
+ // Read the Jar File entry and define the class...
+ Class c = null;
+ try {
+ InputStream is = jarFile.getInputStream(jarEntry);
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ copy(is, os);
+ byte[] bytes = os.toByteArray();
+ c = defineClass(className, bytes, 0, bytes.length);
+ } catch (IOException ioe) {
+ /* ignore */
+ }
+
+ return c;
+ }
+
+ private void copy(InputStream in, OutputStream out) throws IOException {
+ byte[] buf = new byte[1024];
+ while (true) {
+ int len = in.read(buf);
+ if (len < 0) break;
+ out.write(buf, 0, len);
+ }
+ }
+}
\ No newline at end of file
diff --git a/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/JavaScriptCompressor.java b/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/JavaScriptCompressor.java
new file mode 100644
index 00000000..38c5e38c
--- /dev/null
+++ b/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/JavaScriptCompressor.java
@@ -0,0 +1,1309 @@
+/*
+ * YUI Compressor
+ * Author: Julien Lecomte
+ * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ */
+
+package com.yahoo.platform.yui.compressor;
+
+import org.mozilla.javascript.*;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class JavaScriptCompressor {
+
+ static final ArrayList ones;
+ static final ArrayList twos;
+ static final ArrayList threes;
+
+ static final Set builtin = new HashSet();
+ static final Map literals = new Hashtable();
+ static final Set reserved = new HashSet();
+
+ static {
+
+ // This list contains all the 3 characters or less built-in global
+ // symbols available in a browser. Please add to this list if you
+ // see anything missing.
+ builtin.add("NaN");
+ builtin.add("top");
+
+ ones = new ArrayList();
+ for (char c = 'a'; c <= 'z'; c++)
+ ones.add(Character.toString(c));
+ for (char c = 'A'; c <= 'Z'; c++)
+ ones.add(Character.toString(c));
+
+ twos = new ArrayList();
+ for (int i = 0; i < ones.size(); i++) {
+ String one = (String) ones.get(i);
+ for (char c = 'a'; c <= 'z'; c++)
+ twos.add(one + Character.toString(c));
+ for (char c = 'A'; c <= 'Z'; c++)
+ twos.add(one + Character.toString(c));
+ for (char c = '0'; c <= '9'; c++)
+ twos.add(one + Character.toString(c));
+ }
+
+ // Remove two-letter JavaScript reserved words and built-in globals...
+ twos.remove("as");
+ twos.remove("is");
+ twos.remove("do");
+ twos.remove("if");
+ twos.remove("in");
+ twos.removeAll(builtin);
+
+ threes = new ArrayList();
+ for (int i = 0; i < twos.size(); i++) {
+ String two = (String) twos.get(i);
+ for (char c = 'a'; c <= 'z'; c++)
+ threes.add(two + Character.toString(c));
+ for (char c = 'A'; c <= 'Z'; c++)
+ threes.add(two + Character.toString(c));
+ for (char c = '0'; c <= '9'; c++)
+ threes.add(two + Character.toString(c));
+ }
+
+ // Remove three-letter JavaScript reserved words and built-in globals...
+ threes.remove("for");
+ threes.remove("int");
+ threes.remove("new");
+ threes.remove("try");
+ threes.remove("use");
+ threes.remove("var");
+ threes.removeAll(builtin);
+
+ // That's up to ((26+26)*(1+(26+26+10)))*(1+(26+26+10))-8
+ // (206,380 symbols per scope)
+
+ // The following list comes from org/mozilla/javascript/Decompiler.java...
+ literals.put(new Integer(Token.GET), "get ");
+ literals.put(new Integer(Token.SET), "set ");
+ literals.put(new Integer(Token.TRUE), "true");
+ literals.put(new Integer(Token.FALSE), "false");
+ literals.put(new Integer(Token.NULL), "null");
+ literals.put(new Integer(Token.THIS), "this");
+ literals.put(new Integer(Token.FUNCTION), "function");
+ literals.put(new Integer(Token.COMMA), ",");
+ literals.put(new Integer(Token.LC), "{");
+ literals.put(new Integer(Token.RC), "}");
+ literals.put(new Integer(Token.LP), "(");
+ literals.put(new Integer(Token.RP), ")");
+ literals.put(new Integer(Token.LB), "[");
+ literals.put(new Integer(Token.RB), "]");
+ literals.put(new Integer(Token.DOT), ".");
+ literals.put(new Integer(Token.NEW), "new ");
+ literals.put(new Integer(Token.DELPROP), "delete ");
+ literals.put(new Integer(Token.IF), "if");
+ literals.put(new Integer(Token.ELSE), "else");
+ literals.put(new Integer(Token.FOR), "for");
+ literals.put(new Integer(Token.IN), " in ");
+ literals.put(new Integer(Token.WITH), "with");
+ literals.put(new Integer(Token.WHILE), "while");
+ literals.put(new Integer(Token.DO), "do");
+ literals.put(new Integer(Token.TRY), "try");
+ literals.put(new Integer(Token.CATCH), "catch");
+ literals.put(new Integer(Token.FINALLY), "finally");
+ literals.put(new Integer(Token.THROW), "throw");
+ literals.put(new Integer(Token.SWITCH), "switch");
+ literals.put(new Integer(Token.BREAK), "break");
+ literals.put(new Integer(Token.CONTINUE), "continue");
+ literals.put(new Integer(Token.CASE), "case");
+ literals.put(new Integer(Token.DEFAULT), "default");
+ literals.put(new Integer(Token.RETURN), "return");
+ literals.put(new Integer(Token.VAR), "var ");
+ literals.put(new Integer(Token.SEMI), ";");
+ literals.put(new Integer(Token.ASSIGN), "=");
+ literals.put(new Integer(Token.ASSIGN_ADD), "+=");
+ literals.put(new Integer(Token.ASSIGN_SUB), "-=");
+ literals.put(new Integer(Token.ASSIGN_MUL), "*=");
+ literals.put(new Integer(Token.ASSIGN_DIV), "/=");
+ literals.put(new Integer(Token.ASSIGN_MOD), "%=");
+ literals.put(new Integer(Token.ASSIGN_BITOR), "|=");
+ literals.put(new Integer(Token.ASSIGN_BITXOR), "^=");
+ literals.put(new Integer(Token.ASSIGN_BITAND), "&=");
+ literals.put(new Integer(Token.ASSIGN_LSH), "<<=");
+ literals.put(new Integer(Token.ASSIGN_RSH), ">>=");
+ literals.put(new Integer(Token.ASSIGN_URSH), ">>>=");
+ literals.put(new Integer(Token.HOOK), "?");
+ literals.put(new Integer(Token.OBJECTLIT), ":");
+ literals.put(new Integer(Token.COLON), ":");
+ literals.put(new Integer(Token.OR), "||");
+ literals.put(new Integer(Token.AND), "&&");
+ literals.put(new Integer(Token.BITOR), "|");
+ literals.put(new Integer(Token.BITXOR), "^");
+ literals.put(new Integer(Token.BITAND), "&");
+ literals.put(new Integer(Token.SHEQ), "===");
+ literals.put(new Integer(Token.SHNE), "!==");
+ literals.put(new Integer(Token.EQ), "==");
+ literals.put(new Integer(Token.NE), "!=");
+ literals.put(new Integer(Token.LE), "<=");
+ literals.put(new Integer(Token.LT), "<");
+ literals.put(new Integer(Token.GE), ">=");
+ literals.put(new Integer(Token.GT), ">");
+ literals.put(new Integer(Token.INSTANCEOF), " instanceof ");
+ literals.put(new Integer(Token.LSH), "<<");
+ literals.put(new Integer(Token.RSH), ">>");
+ literals.put(new Integer(Token.URSH), ">>>");
+ literals.put(new Integer(Token.TYPEOF), "typeof");
+ literals.put(new Integer(Token.VOID), "void ");
+ literals.put(new Integer(Token.CONST), "const ");
+ literals.put(new Integer(Token.NOT), "!");
+ literals.put(new Integer(Token.BITNOT), "~");
+ literals.put(new Integer(Token.POS), "+");
+ literals.put(new Integer(Token.NEG), "-");
+ literals.put(new Integer(Token.INC), "++");
+ literals.put(new Integer(Token.DEC), "--");
+ literals.put(new Integer(Token.ADD), "+");
+ literals.put(new Integer(Token.SUB), "-");
+ literals.put(new Integer(Token.MUL), "*");
+ literals.put(new Integer(Token.DIV), "/");
+ literals.put(new Integer(Token.MOD), "%");
+ literals.put(new Integer(Token.COLONCOLON), "::");
+ literals.put(new Integer(Token.DOTDOT), "..");
+ literals.put(new Integer(Token.DOTQUERY), ".(");
+ literals.put(new Integer(Token.XMLATTR), "@");
+
+ // See http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Reserved_Words
+
+ // JavaScript 1.5 reserved words
+ reserved.add("break");
+ reserved.add("case");
+ reserved.add("catch");
+ reserved.add("continue");
+ reserved.add("default");
+ reserved.add("delete");
+ reserved.add("do");
+ reserved.add("else");
+ reserved.add("finally");
+ reserved.add("for");
+ reserved.add("function");
+ reserved.add("if");
+ reserved.add("in");
+ reserved.add("instanceof");
+ reserved.add("new");
+ reserved.add("return");
+ reserved.add("switch");
+ reserved.add("this");
+ reserved.add("throw");
+ reserved.add("try");
+ reserved.add("typeof");
+ reserved.add("var");
+ reserved.add("void");
+ reserved.add("while");
+ reserved.add("with");
+ // Words reserved for future use
+ reserved.add("abstract");
+ reserved.add("boolean");
+ reserved.add("byte");
+ reserved.add("char");
+ reserved.add("class");
+ reserved.add("const");
+ reserved.add("debugger");
+ reserved.add("double");
+ reserved.add("enum");
+ reserved.add("export");
+ reserved.add("extends");
+ reserved.add("final");
+ reserved.add("float");
+ reserved.add("goto");
+ reserved.add("implements");
+ reserved.add("import");
+ reserved.add("int");
+ reserved.add("interface");
+ reserved.add("long");
+ reserved.add("native");
+ reserved.add("package");
+ reserved.add("private");
+ reserved.add("protected");
+ reserved.add("public");
+ reserved.add("short");
+ reserved.add("static");
+ reserved.add("super");
+ reserved.add("synchronized");
+ reserved.add("throws");
+ reserved.add("transient");
+ reserved.add("volatile");
+ // These are not reserved, but should be taken into account
+ // in isValidIdentifier (See jslint source code)
+ reserved.add("arguments");
+ reserved.add("eval");
+ reserved.add("true");
+ reserved.add("false");
+ reserved.add("Infinity");
+ reserved.add("NaN");
+ reserved.add("null");
+ reserved.add("undefined");
+ }
+
+ private static int countChar(String haystack, char needle) {
+ int idx = 0;
+ int count = 0;
+ int length = haystack.length();
+ while (idx < length) {
+ char c = haystack.charAt(idx++);
+ if (c == needle) {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ private static int printSourceString(String source, int offset, StringBuffer sb) {
+ int length = source.charAt(offset);
+ ++offset;
+ if ((0x8000 & length) != 0) {
+ length = ((0x7FFF & length) << 16) | source.charAt(offset);
+ ++offset;
+ }
+ if (sb != null) {
+ String str = source.substring(offset, offset + length);
+ sb.append(str);
+ }
+ return offset + length;
+ }
+
+ private static int printSourceNumber(String source,
+ int offset, StringBuffer sb) {
+ double number = 0.0;
+ char type = source.charAt(offset);
+ ++offset;
+ if (type == 'S') {
+ if (sb != null) {
+ number = source.charAt(offset);
+ }
+ ++offset;
+ } else if (type == 'J' || type == 'D') {
+ if (sb != null) {
+ long lbits;
+ lbits = (long) source.charAt(offset) << 48;
+ lbits |= (long) source.charAt(offset + 1) << 32;
+ lbits |= (long) source.charAt(offset + 2) << 16;
+ lbits |= (long) source.charAt(offset + 3);
+ if (type == 'J') {
+ number = lbits;
+ } else {
+ number = Double.longBitsToDouble(lbits);
+ }
+ }
+ offset += 4;
+ } else {
+ // Bad source
+ throw new RuntimeException();
+ }
+ if (sb != null) {
+ sb.append(ScriptRuntime.numberToString(number, 10));
+ }
+ return offset;
+ }
+
+ private static ArrayList parse(Reader in, ErrorReporter reporter)
+ throws IOException, EvaluatorException {
+
+ CompilerEnvirons env = new CompilerEnvirons();
+ Parser parser = new Parser(env, reporter);
+ parser.parse(in, null, 1);
+ String source = parser.getEncodedSource();
+
+ int offset = 0;
+ int length = source.length();
+ ArrayList tokens = new ArrayList();
+ StringBuffer sb = new StringBuffer();
+
+ while (offset < length) {
+ int tt = source.charAt(offset++);
+ switch (tt) {
+
+ case Token.CONDCOMMENT:
+ case Token.KEEPCOMMENT:
+ case Token.NAME:
+ case Token.REGEXP:
+ case Token.STRING:
+ sb.setLength(0);
+ offset = printSourceString(source, offset, sb);
+ tokens.add(new JavaScriptToken(tt, sb.toString()));
+ break;
+
+ case Token.NUMBER:
+ sb.setLength(0);
+ offset = printSourceNumber(source, offset, sb);
+ tokens.add(new JavaScriptToken(tt, sb.toString()));
+ break;
+
+ default:
+ String literal = (String) literals.get(new Integer(tt));
+ if (literal != null) {
+ tokens.add(new JavaScriptToken(tt, literal));
+ }
+ break;
+ }
+ }
+
+ return tokens;
+ }
+
+ private static void processStringLiterals(ArrayList tokens, boolean merge) {
+
+ String tv;
+ int i, length = tokens.size();
+ JavaScriptToken token, prevToken, nextToken;
+
+ if (merge) {
+
+ // Concatenate string literals that are being appended wherever
+ // it is safe to do so. Note that we take care of the case:
+ // "a" + "b".toUpperCase()
+
+ for (i = 0; i < length; i++) {
+ token = (JavaScriptToken) tokens.get(i);
+ switch (token.getType()) {
+
+ case Token.ADD:
+ if (i > 0 && i < length) {
+ prevToken = (JavaScriptToken) tokens.get(i - 1);
+ nextToken = (JavaScriptToken) tokens.get(i + 1);
+ if (prevToken.getType() == Token.STRING && nextToken.getType() == Token.STRING &&
+ (i == length - 1 || ((JavaScriptToken) tokens.get(i + 2)).getType() != Token.DOT)) {
+ tokens.set(i - 1, new JavaScriptToken(Token.STRING,
+ prevToken.getValue() + nextToken.getValue()));
+ tokens.remove(i + 1);
+ tokens.remove(i);
+ i = i - 1;
+ length = length - 2;
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ // Second pass...
+
+ for (i = 0; i < length; i++) {
+ token = (JavaScriptToken) tokens.get(i);
+ if (token.getType() == Token.STRING) {
+ tv = token.getValue();
+
+ // Finally, add the quoting characters and escape the string. We use
+ // the quoting character that minimizes the amount of escaping to save
+ // a few additional bytes.
+
+ char quotechar;
+ int singleQuoteCount = countChar(tv, '\'');
+ int doubleQuoteCount = countChar(tv, '"');
+ if (doubleQuoteCount <= singleQuoteCount) {
+ quotechar = '"';
+ } else {
+ quotechar = '\'';
+ }
+
+ tv = quotechar + escapeString(tv, quotechar) + quotechar;
+
+ // String concatenation transforms the old script scheme:
+ // '<'+'/script>'
+ // into the following:
+ // ''
+ // which breaks if this code is embedded inside an HTML document.
+ // Since this is not the right way to do this, let's fix the code by
+ // transforming all "= 0) {
+ tv = tv.replaceAll("<\\/script", "<\\\\/script");
+ }
+
+ tokens.set(i, new JavaScriptToken(Token.STRING, tv));
+ }
+ }
+ }
+
+ // Add necessary escaping that was removed in Rhino's tokenizer.
+ private static String escapeString(String s, char quotechar) {
+
+ assert quotechar == '"' || quotechar == '\'';
+
+ if (s == null) {
+ return null;
+ }
+
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0, L = s.length(); i < L; i++) {
+ int c = s.charAt(i);
+ if (c == quotechar) {
+ sb.append("\\");
+ }
+ sb.append((char) c);
+ }
+
+ return sb.toString();
+ }
+
+ /*
+ * Simple check to see whether a string is a valid identifier name.
+ * If a string matches this pattern, it means it IS a valid
+ * identifier name. If a string doesn't match it, it does not
+ * necessarily mean it is not a valid identifier name.
+ */
+ private static final Pattern SIMPLE_IDENTIFIER_NAME_PATTERN = Pattern.compile("^[a-zA-Z_][a-zA-Z0-9_]*$");
+
+ private static boolean isValidIdentifier(String s) {
+ Matcher m = SIMPLE_IDENTIFIER_NAME_PATTERN.matcher(s);
+ return (m.matches() && !reserved.contains(s));
+ }
+
+ /*
+ * Transforms obj["foo"] into obj.foo whenever possible, saving 3 bytes.
+ */
+ private static void optimizeObjectMemberAccess(ArrayList tokens) {
+
+ String tv;
+ int i, length;
+ JavaScriptToken token;
+
+ for (i = 0, length = tokens.size(); i < length; i++) {
+
+ if (((JavaScriptToken) tokens.get(i)).getType() == Token.LB &&
+ i > 0 && i < length - 2 &&
+ ((JavaScriptToken) tokens.get(i - 1)).getType() == Token.NAME &&
+ ((JavaScriptToken) tokens.get(i + 1)).getType() == Token.STRING &&
+ ((JavaScriptToken) tokens.get(i + 2)).getType() == Token.RB) {
+ token = (JavaScriptToken) tokens.get(i + 1);
+ tv = token.getValue();
+ tv = tv.substring(1, tv.length() - 1);
+ if (isValidIdentifier(tv)) {
+ tokens.set(i, new JavaScriptToken(Token.DOT, "."));
+ tokens.set(i + 1, new JavaScriptToken(Token.NAME, tv));
+ tokens.remove(i + 2);
+ i = i + 2;
+ length = length - 1;
+ }
+ }
+ }
+ }
+
+ /*
+ * Transforms 'foo': ... into foo: ... whenever possible, saving 2 bytes.
+ */
+ private static void optimizeObjLitMemberDecl(ArrayList tokens) {
+
+ String tv;
+ int i, length;
+ JavaScriptToken token;
+
+ for (i = 0, length = tokens.size(); i < length; i++) {
+ if (((JavaScriptToken) tokens.get(i)).getType() == Token.OBJECTLIT &&
+ i > 0 && ((JavaScriptToken) tokens.get(i - 1)).getType() == Token.STRING) {
+ token = (JavaScriptToken) tokens.get(i - 1);
+ tv = token.getValue();
+ tv = tv.substring(1, tv.length() - 1);
+ if (isValidIdentifier(tv)) {
+ tokens.set(i - 1, new JavaScriptToken(Token.NAME, tv));
+ }
+ }
+ }
+ }
+
+ private ErrorReporter logger;
+
+ private boolean munge;
+ private boolean verbose;
+
+ private static final int BUILDING_SYMBOL_TREE = 1;
+ private static final int CHECKING_SYMBOL_TREE = 2;
+
+ private int mode;
+ private int offset;
+ private int braceNesting;
+ private ArrayList tokens;
+ private Stack scopes = new Stack();
+ private ScriptOrFnScope globalScope = new ScriptOrFnScope(-1, null);
+ private Hashtable indexedScopes = new Hashtable();
+
+ public JavaScriptCompressor(Reader in, ErrorReporter reporter)
+ throws IOException, EvaluatorException {
+
+ this.logger = reporter;
+ this.tokens = parse(in, reporter);
+ }
+
+ public void compress(Writer out, int linebreak, boolean munge, boolean verbose,
+ boolean preserveAllSemiColons, boolean disableOptimizations)
+ throws IOException {
+
+ this.munge = munge;
+ this.verbose = verbose;
+
+ processStringLiterals(this.tokens, !disableOptimizations);
+
+ if (!disableOptimizations) {
+ optimizeObjectMemberAccess(this.tokens);
+ optimizeObjLitMemberDecl(this.tokens);
+ }
+
+ buildSymbolTree();
+ // DO NOT TOUCH this.tokens BETWEEN THESE TWO PHASES (BECAUSE OF this.indexedScopes)
+ mungeSymboltree();
+ StringBuffer sb = printSymbolTree(linebreak, preserveAllSemiColons);
+
+ out.write(sb.toString());
+ }
+
+ private ScriptOrFnScope getCurrentScope() {
+ return (ScriptOrFnScope) scopes.peek();
+ }
+
+ private void enterScope(ScriptOrFnScope scope) {
+ scopes.push(scope);
+ }
+
+ private void leaveCurrentScope() {
+ scopes.pop();
+ }
+
+ private JavaScriptToken consumeToken() {
+ return (JavaScriptToken) tokens.get(offset++);
+ }
+
+ private JavaScriptToken getToken(int delta) {
+ return (JavaScriptToken) tokens.get(offset + delta);
+ }
+
+ /*
+ * Returns the identifier for the specified symbol defined in
+ * the specified scope or in any scope above it. Returns null
+ * if this symbol does not have a corresponding identifier.
+ */
+ private JavaScriptIdentifier getIdentifier(String symbol, ScriptOrFnScope scope) {
+ JavaScriptIdentifier identifier;
+ while (scope != null) {
+ identifier = scope.getIdentifier(symbol);
+ if (identifier != null) {
+ return identifier;
+ }
+ scope = scope.getParentScope();
+ }
+ return null;
+ }
+
+ /*
+ * If either 'eval' or 'with' is used in a local scope, we must make
+ * sure that all containing local scopes don't get munged. Otherwise,
+ * the obfuscation would potentially introduce bugs.
+ */
+ private void protectScopeFromObfuscation(ScriptOrFnScope scope) {
+ assert scope != null;
+
+ if (scope == globalScope) {
+ // The global scope does not get obfuscated,
+ // so we don't need to worry about it...
+ return;
+ }
+
+ // Find the highest local scope containing the specified scope.
+ while (scope.getParentScope() != globalScope) {
+ scope = scope.getParentScope();
+ }
+
+ assert scope.getParentScope() == globalScope;
+ scope.preventMunging();
+ }
+
+ private String getDebugString(int max) {
+ assert max > 0;
+ StringBuffer result = new StringBuffer();
+ int start = Math.max(offset - max, 0);
+ int end = Math.min(offset + max, tokens.size());
+ for (int i = start; i < end; i++) {
+ JavaScriptToken token = (JavaScriptToken) tokens.get(i);
+ if (i == offset - 1) {
+ result.append(" ---> ");
+ }
+ result.append(token.getValue());
+ if (i == offset - 1) {
+ result.append(" <--- ");
+ }
+ }
+ return result.toString();
+ }
+
+ private void warn(String message, boolean showDebugString) {
+ if (verbose) {
+ if (showDebugString) {
+ message = message + "\n" + getDebugString(10);
+ }
+ logger.warning(message, null, -1, null, -1);
+ }
+ }
+
+ private void parseFunctionDeclaration() {
+
+ String symbol;
+ JavaScriptToken token;
+ ScriptOrFnScope currentScope, fnScope;
+ JavaScriptIdentifier identifier;
+
+ currentScope = getCurrentScope();
+
+ token = consumeToken();
+ if (token.getType() == Token.NAME) {
+ if (mode == BUILDING_SYMBOL_TREE) {
+ // Get the name of the function and declare it in the current scope.
+ symbol = token.getValue();
+ if (currentScope.getIdentifier(symbol) != null) {
+ warn("The function " + symbol + " has already been declared in the same scope...", true);
+ }
+ currentScope.declareIdentifier(symbol);
+ }
+ token = consumeToken();
+ }
+
+ assert token.getType() == Token.LP;
+ if (mode == BUILDING_SYMBOL_TREE) {
+ fnScope = new ScriptOrFnScope(braceNesting, currentScope);
+ indexedScopes.put(new Integer(offset), fnScope);
+ } else {
+ fnScope = (ScriptOrFnScope) indexedScopes.get(new Integer(offset));
+ }
+
+ // Parse function arguments.
+ int argpos = 0;
+ while ((token = consumeToken()).getType() != Token.RP) {
+ assert token.getType() == Token.NAME ||
+ token.getType() == Token.COMMA;
+ if (token.getType() == Token.NAME && mode == BUILDING_SYMBOL_TREE) {
+ symbol = token.getValue();
+ identifier = fnScope.declareIdentifier(symbol);
+ if (symbol.equals("$super") && argpos == 0) {
+ // Exception for Prototype 1.6...
+ identifier.preventMunging();
+ }
+ argpos++;
+ }
+ }
+
+ token = consumeToken();
+ assert token.getType() == Token.LC;
+ braceNesting++;
+
+ token = getToken(0);
+ if (token.getType() == Token.STRING &&
+ getToken(1).getType() == Token.SEMI) {
+ // This is a hint. Hints are empty statements that look like
+ // "localvar1:nomunge, localvar2:nomunge"; They allow developers
+ // to prevent specific symbols from getting obfuscated (some heretic
+ // implementations, such as Prototype 1.6, require specific variable
+ // names, such as $super for example, in order to work appropriately.
+ // Note: right now, only "nomunge" is supported in the right hand side
+ // of a hint. However, in the future, the right hand side may contain
+ // other values.
+ consumeToken();
+ String hints = token.getValue();
+ // Remove the leading and trailing quotes...
+ hints = hints.substring(1, hints.length() - 1).trim();
+ StringTokenizer st1 = new StringTokenizer(hints, ",");
+ while (st1.hasMoreTokens()) {
+ String hint = st1.nextToken();
+ int idx = hint.indexOf(':');
+ if (idx <= 0 || idx >= hint.length() - 1) {
+ if (mode == BUILDING_SYMBOL_TREE) {
+ // No need to report the error twice, hence the test...
+ warn("Invalid hint syntax: " + hint, true);
+ }
+ break;
+ }
+ String variableName = hint.substring(0, idx).trim();
+ String variableType = hint.substring(idx + 1).trim();
+ if (mode == BUILDING_SYMBOL_TREE) {
+ fnScope.addHint(variableName, variableType);
+ } else if (mode == CHECKING_SYMBOL_TREE) {
+ identifier = fnScope.getIdentifier(variableName);
+ if (identifier != null) {
+ if (variableType.equals("nomunge")) {
+ identifier.preventMunging();
+ } else {
+ warn("Unsupported hint value: " + hint, true);
+ }
+ } else {
+ warn("Hint refers to an unknown identifier: " + hint, true);
+ }
+ }
+ }
+ }
+
+ parseScope(fnScope);
+ }
+
+ private void parseCatch() {
+
+ String symbol;
+ JavaScriptToken token;
+ ScriptOrFnScope currentScope;
+ JavaScriptIdentifier identifier;
+
+ token = getToken(-1);
+ assert token.getType() == Token.CATCH;
+ token = consumeToken();
+ assert token.getType() == Token.LP;
+ token = consumeToken();
+ assert token.getType() == Token.NAME;
+
+ symbol = token.getValue();
+ currentScope = getCurrentScope();
+
+ if (mode == BUILDING_SYMBOL_TREE) {
+ // We must declare the exception identifier in the containing function
+ // scope to avoid errors related to the obfuscation process. No need to
+ // display a warning if the symbol was already declared here...
+ currentScope.declareIdentifier(symbol);
+ } else {
+ identifier = getIdentifier(symbol, currentScope);
+ identifier.incrementRefcount();
+ }
+
+ token = consumeToken();
+ assert token.getType() == Token.RP;
+ }
+
+ private void parseExpression() {
+
+ // Parse the expression until we encounter a comma or a semi-colon
+ // in the same brace nesting, bracket nesting and paren nesting.
+ // Parse functions if any...
+
+ String symbol;
+ JavaScriptToken token;
+ ScriptOrFnScope currentScope;
+ JavaScriptIdentifier identifier;
+
+ int expressionBraceNesting = braceNesting;
+ int bracketNesting = 0;
+ int parensNesting = 0;
+
+ int length = tokens.size();
+
+ while (offset < length) {
+
+ token = consumeToken();
+ currentScope = getCurrentScope();
+
+ switch (token.getType()) {
+
+ case Token.SEMI:
+ case Token.COMMA:
+ if (braceNesting == expressionBraceNesting &&
+ bracketNesting == 0 &&
+ parensNesting == 0) {
+ return;
+ }
+ break;
+
+ case Token.FUNCTION:
+ parseFunctionDeclaration();
+ break;
+
+ case Token.LC:
+ braceNesting++;
+ break;
+
+ case Token.RC:
+ braceNesting--;
+ assert braceNesting >= expressionBraceNesting;
+ break;
+
+ case Token.LB:
+ bracketNesting++;
+ break;
+
+ case Token.RB:
+ bracketNesting--;
+ break;
+
+ case Token.LP:
+ parensNesting++;
+ break;
+
+ case Token.RP:
+ parensNesting--;
+ break;
+
+ case Token.CONDCOMMENT:
+ if (mode == BUILDING_SYMBOL_TREE) {
+ protectScopeFromObfuscation(currentScope);
+ warn("Using JScript conditional comments is not recommended." + (munge ? " Moreover, using JScript conditional comments reduces the level of compression!" : ""), true);
+ }
+ break;
+
+ case Token.NAME:
+ symbol = token.getValue();
+
+ if (mode == BUILDING_SYMBOL_TREE) {
+
+ if (symbol.equals("eval")) {
+
+ protectScopeFromObfuscation(currentScope);
+ warn("Using 'eval' is not recommended." + (munge ? " Moreover, using 'eval' reduces the level of compression!" : ""), true);
+
+ }
+
+ } else if (mode == CHECKING_SYMBOL_TREE) {
+
+ if ((offset < 2 ||
+ (getToken(-2).getType() != Token.DOT &&
+ getToken(-2).getType() != Token.GET &&
+ getToken(-2).getType() != Token.SET)) &&
+ getToken(0).getType() != Token.OBJECTLIT) {
+
+ identifier = getIdentifier(symbol, currentScope);
+
+ if (identifier == null) {
+
+ if (symbol.length() <= 3 && !builtin.contains(symbol)) {
+ // Here, we found an undeclared and un-namespaced symbol that is
+ // 3 characters or less in length. Declare it in the global scope.
+ // We don't need to declare longer symbols since they won't cause
+ // any conflict with other munged symbols.
+ globalScope.declareIdentifier(symbol);
+ warn("Found an undeclared symbol: " + symbol, true);
+ }
+
+ } else {
+
+ identifier.incrementRefcount();
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ private void parseScope(ScriptOrFnScope scope) {
+
+ String symbol;
+ JavaScriptToken token;
+ JavaScriptIdentifier identifier;
+
+ int length = tokens.size();
+
+ enterScope(scope);
+
+ while (offset < length) {
+
+ token = consumeToken();
+
+ switch (token.getType()) {
+
+ case Token.VAR:
+
+ if (mode == BUILDING_SYMBOL_TREE && scope.incrementVarCount() > 1) {
+ warn("Try to use a single 'var' statement per scope.", true);
+ }
+
+ /* FALLSTHROUGH */
+
+ case Token.CONST:
+
+ // The var keyword is followed by at least one symbol name.
+ // If several symbols follow, they are comma separated.
+ for (; ;) {
+ token = consumeToken();
+
+ assert token.getType() == Token.NAME;
+
+ if (mode == BUILDING_SYMBOL_TREE) {
+ symbol = token.getValue();
+ if (scope.getIdentifier(symbol) == null) {
+ scope.declareIdentifier(symbol);
+ } else {
+ warn("The variable " + symbol + " has already been declared in the same scope...", true);
+ }
+ }
+
+ token = getToken(0);
+
+ assert token.getType() == Token.SEMI ||
+ token.getType() == Token.ASSIGN ||
+ token.getType() == Token.COMMA ||
+ token.getType() == Token.IN;
+
+ if (token.getType() == Token.IN) {
+ break;
+ } else {
+ parseExpression();
+ token = getToken(-1);
+ if (token.getType() == Token.SEMI) {
+ break;
+ }
+ }
+ }
+ break;
+
+ case Token.FUNCTION:
+ parseFunctionDeclaration();
+ break;
+
+ case Token.LC:
+ braceNesting++;
+ break;
+
+ case Token.RC:
+ braceNesting--;
+ assert braceNesting >= scope.getBraceNesting();
+ if (braceNesting == scope.getBraceNesting()) {
+ leaveCurrentScope();
+ return;
+ }
+ break;
+
+ case Token.WITH:
+ if (mode == BUILDING_SYMBOL_TREE) {
+ // Inside a 'with' block, it is impossible to figure out
+ // statically whether a symbol is a local variable or an
+ // object member. As a consequence, the only thing we can
+ // do is turn the obfuscation off for the highest scope
+ // containing the 'with' block.
+ protectScopeFromObfuscation(scope);
+ warn("Using 'with' is not recommended." + (munge ? " Moreover, using 'with' reduces the level of compression!" : ""), true);
+ }
+ break;
+
+ case Token.CATCH:
+ parseCatch();
+ break;
+
+ case Token.CONDCOMMENT:
+ if (mode == BUILDING_SYMBOL_TREE) {
+ protectScopeFromObfuscation(scope);
+ warn("Using JScript conditional comments is not recommended." + (munge ? " Moreover, using JScript conditional comments reduces the level of compression." : ""), true);
+ }
+ break;
+
+ case Token.NAME:
+ symbol = token.getValue();
+
+ if (mode == BUILDING_SYMBOL_TREE) {
+
+ if (symbol.equals("eval")) {
+
+ protectScopeFromObfuscation(scope);
+ warn("Using 'eval' is not recommended." + (munge ? " Moreover, using 'eval' reduces the level of compression!" : ""), true);
+
+ }
+
+ } else if (mode == CHECKING_SYMBOL_TREE) {
+
+ if ((offset < 2 || getToken(-2).getType() != Token.DOT) &&
+ getToken(0).getType() != Token.OBJECTLIT) {
+
+ identifier = getIdentifier(symbol, scope);
+
+ if (identifier == null) {
+
+ if (symbol.length() <= 3 && !builtin.contains(symbol)) {
+ // Here, we found an undeclared and un-namespaced symbol that is
+ // 3 characters or less in length. Declare it in the global scope.
+ // We don't need to declare longer symbols since they won't cause
+ // any conflict with other munged symbols.
+ globalScope.declareIdentifier(symbol);
+ warn("Found an undeclared symbol: " + symbol, true);
+ }
+
+ } else {
+
+ identifier.incrementRefcount();
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ private void buildSymbolTree() {
+ offset = 0;
+ braceNesting = 0;
+ scopes.clear();
+ indexedScopes.clear();
+ indexedScopes.put(new Integer(0), globalScope);
+ mode = BUILDING_SYMBOL_TREE;
+ parseScope(globalScope);
+ }
+
+ private void mungeSymboltree() {
+
+ if (!munge) {
+ return;
+ }
+
+ // One problem with obfuscation resides in the use of undeclared
+ // and un-namespaced global symbols that are 3 characters or less
+ // in length. Here is an example:
+ //
+ // var declaredGlobalVar;
+ //
+ // function declaredGlobalFn() {
+ // var localvar;
+ // localvar = abc; // abc is an undeclared global symbol
+ // }
+ //
+ // In the example above, there is a slim chance that localvar may be
+ // munged to 'abc', conflicting with the undeclared global symbol
+ // abc, creating a potential bug. The following code detects such
+ // global symbols. This must be done AFTER the entire file has been
+ // parsed, and BEFORE munging the symbol tree. Note that declaring
+ // extra symbols in the global scope won't hurt.
+ //
+ // Note: Since we go through all the tokens to do this, we also use
+ // the opportunity to count how many times each identifier is used.
+
+ offset = 0;
+ braceNesting = 0;
+ scopes.clear();
+ mode = CHECKING_SYMBOL_TREE;
+ parseScope(globalScope);
+ globalScope.munge();
+ }
+
+ private StringBuffer printSymbolTree(int linebreakpos, boolean preserveAllSemiColons)
+ throws IOException {
+
+ offset = 0;
+ braceNesting = 0;
+ scopes.clear();
+
+ String symbol;
+ JavaScriptToken token;
+ ScriptOrFnScope currentScope;
+ JavaScriptIdentifier identifier;
+
+ int length = tokens.size();
+ StringBuffer result = new StringBuffer();
+
+ int linestartpos = 0;
+
+ enterScope(globalScope);
+
+ while (offset < length) {
+
+ token = consumeToken();
+ symbol = token.getValue();
+ currentScope = getCurrentScope();
+
+ switch (token.getType()) {
+
+ case Token.NAME:
+
+ if (offset >= 2 && getToken(-2).getType() == Token.DOT ||
+ getToken(0).getType() == Token.OBJECTLIT) {
+
+ result.append(symbol);
+
+ } else {
+
+ identifier = getIdentifier(symbol, currentScope);
+ if (identifier != null) {
+ if (identifier.getMungedValue() != null) {
+ result.append(identifier.getMungedValue());
+ } else {
+ result.append(symbol);
+ }
+ if (currentScope != globalScope && identifier.getRefcount() == 0) {
+ warn("The symbol " + symbol + " is declared but is apparently never used.\nThis code can probably be written in a more compact way.", true);
+ }
+ } else {
+ result.append(symbol);
+ }
+ }
+ break;
+
+ case Token.REGEXP:
+ case Token.NUMBER:
+ case Token.STRING:
+ result.append(symbol);
+ break;
+
+ case Token.ADD:
+ case Token.SUB:
+ result.append((String) literals.get(new Integer(token.getType())));
+ if (offset < length) {
+ token = getToken(0);
+ if (token.getType() == Token.INC ||
+ token.getType() == Token.DEC ||
+ token.getType() == Token.ADD ||
+ token.getType() == Token.DEC) {
+ // Handle the case x +/- ++/-- y
+ // We must keep a white space here. Otherwise, x +++ y would be
+ // interpreted as x ++ + y by the compiler, which is a bug (due
+ // to the implicit assignment being done on the wrong variable)
+ result.append(' ');
+ } else if (token.getType() == Token.POS && getToken(-1).getType() == Token.ADD ||
+ token.getType() == Token.NEG && getToken(-1).getType() == Token.SUB) {
+ // Handle the case x + + y and x - - y
+ result.append(' ');
+ }
+ }
+ break;
+
+ case Token.FUNCTION:
+ result.append("function");
+ token = consumeToken();
+ if (token.getType() == Token.NAME) {
+ result.append(' ');
+ symbol = token.getValue();
+ identifier = getIdentifier(symbol, currentScope);
+ assert identifier != null;
+ if (identifier.getMungedValue() != null) {
+ result.append(identifier.getMungedValue());
+ } else {
+ result.append(symbol);
+ }
+ if (currentScope != globalScope && identifier.getRefcount() == 0) {
+ warn("The symbol " + symbol + " is declared but is apparently never used.\nThis code can probably be written in a more compact way.", true);
+ }
+ token = consumeToken();
+ }
+ assert token.getType() == Token.LP;
+ result.append('(');
+ currentScope = (ScriptOrFnScope) indexedScopes.get(new Integer(offset));
+ enterScope(currentScope);
+ while ((token = consumeToken()).getType() != Token.RP) {
+ assert token.getType() == Token.NAME || token.getType() == Token.COMMA;
+ if (token.getType() == Token.NAME) {
+ symbol = token.getValue();
+ identifier = getIdentifier(symbol, currentScope);
+ assert identifier != null;
+ if (identifier.getMungedValue() != null) {
+ result.append(identifier.getMungedValue());
+ } else {
+ result.append(symbol);
+ }
+ } else if (token.getType() == Token.COMMA) {
+ result.append(',');
+ }
+ }
+ result.append(')');
+ token = consumeToken();
+ assert token.getType() == Token.LC;
+ result.append('{');
+ braceNesting++;
+ token = getToken(0);
+ if (token.getType() == Token.STRING &&
+ getToken(1).getType() == Token.SEMI) {
+ // This is a hint. Skip it!
+ consumeToken();
+ consumeToken();
+ }
+ break;
+
+ case Token.RETURN:
+ case Token.TYPEOF:
+ result.append(literals.get(new Integer(token.getType())));
+ // No space needed after 'return' and 'typeof' when followed
+ // by '(', '[', '{', a string or a regexp.
+ if (offset < length) {
+ token = getToken(0);
+ if (token.getType() != Token.LP &&
+ token.getType() != Token.LB &&
+ token.getType() != Token.LC &&
+ token.getType() != Token.STRING &&
+ token.getType() != Token.REGEXP &&
+ token.getType() != Token.SEMI) {
+ result.append(' ');
+ }
+ }
+ break;
+
+ case Token.CASE:
+ case Token.THROW:
+ result.append(literals.get(new Integer(token.getType())));
+ // White-space needed after 'case' and 'throw' when not followed by a string.
+ if (offset < length && getToken(0).getType() != Token.STRING) {
+ result.append(' ');
+ }
+ break;
+
+ case Token.BREAK:
+ case Token.CONTINUE:
+ result.append(literals.get(new Integer(token.getType())));
+ if (offset < length && getToken(0).getType() != Token.SEMI) {
+ // If 'break' or 'continue' is not followed by a semi-colon, it must
+ // be followed by a label, hence the need for a white space.
+ result.append(' ');
+ }
+ break;
+
+ case Token.LC:
+ result.append('{');
+ braceNesting++;
+ break;
+
+ case Token.RC:
+ result.append('}');
+ braceNesting--;
+ assert braceNesting >= currentScope.getBraceNesting();
+ if (braceNesting == currentScope.getBraceNesting()) {
+ leaveCurrentScope();
+ }
+ break;
+
+ case Token.SEMI:
+ // No need to output a semi-colon if the next character is a right-curly...
+ if (preserveAllSemiColons || offset < length && getToken(0).getType() != Token.RC) {
+ result.append(';');
+ }
+
+ if (linebreakpos >= 0 && result.length() - linestartpos > linebreakpos) {
+ // Some source control tools don't like it when files containing lines longer
+ // than, say 8000 characters, are checked in. The linebreak option is used in
+ // that case to split long lines after a specific column.
+ result.append('\n');
+ linestartpos = result.length();
+ }
+ break;
+
+ case Token.CONDCOMMENT:
+ case Token.KEEPCOMMENT:
+ if (result.length() > 0 && result.charAt(result.length() - 1) != '\n') {
+ result.append("\n");
+ }
+ result.append("/*");
+ result.append(symbol);
+ result.append("*/\n");
+ break;
+
+ default:
+ String literal = (String) literals.get(new Integer(token.getType()));
+ if (literal != null) {
+ result.append(literal);
+ } else {
+ warn("This symbol cannot be printed: " + symbol, true);
+ }
+ break;
+ }
+ }
+
+ // Append a semi-colon at the end, even if unnecessary semi-colons are
+ // supposed to be removed. This is especially useful when concatenating
+ // several minified files (the absence of an ending semi-colon at the
+ // end of one file may very likely cause a syntax error)
+ if (!preserveAllSemiColons &&
+ result.length() > 0 &&
+ getToken(-1).getType() != Token.CONDCOMMENT &&
+ getToken(-1).getType() != Token.KEEPCOMMENT) {
+ if (result.charAt(result.length() - 1) == '\n') {
+ result.setCharAt(result.length() - 1, ';');
+ } else {
+ result.append(';');
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/JavaScriptIdentifier.java b/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/JavaScriptIdentifier.java
new file mode 100644
index 00000000..127fe231
--- /dev/null
+++ b/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/JavaScriptIdentifier.java
@@ -0,0 +1,55 @@
+/*
+ * YUI Compressor
+ * Author: Julien Lecomte
+ * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ */
+
+package com.yahoo.platform.yui.compressor;
+
+import org.mozilla.javascript.Token;
+
+/**
+ * JavaScriptIdentifier represents a variable/function identifier.
+ */
+class JavaScriptIdentifier extends JavaScriptToken {
+
+ private int refcount = 0;
+ private String mungedValue;
+ private ScriptOrFnScope declaredScope;
+ private boolean markedForMunging = true;
+
+ JavaScriptIdentifier(String value, ScriptOrFnScope declaredScope) {
+ super(Token.NAME, value);
+ this.declaredScope = declaredScope;
+ }
+
+ ScriptOrFnScope getDeclaredScope() {
+ return declaredScope;
+ }
+
+ void setMungedValue(String value) {
+ mungedValue = value;
+ }
+
+ String getMungedValue() {
+ return mungedValue;
+ }
+
+ void preventMunging() {
+ markedForMunging = false;
+ }
+
+ boolean isMarkedForMunging() {
+ return markedForMunging;
+ }
+
+ void incrementRefcount() {
+ refcount++;
+ }
+
+ int getRefcount() {
+ return refcount;
+ }
+}
diff --git a/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/JavaScriptToken.java b/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/JavaScriptToken.java
new file mode 100644
index 00000000..fee21d9e
--- /dev/null
+++ b/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/JavaScriptToken.java
@@ -0,0 +1,28 @@
+/*
+ * YUI Compressor
+ * Author: Julien Lecomte
+ * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ */
+
+package com.yahoo.platform.yui.compressor;
+
+public class JavaScriptToken {
+
+ private int type;
+ private String value;
+
+ JavaScriptToken(int type, String value) {
+ this.type = type;
+ this.value = value;
+ }
+
+ int getType() {
+ return type;
+ }
+
+ String getValue() {
+ return value;
+ }
+}
diff --git a/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java b/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java
new file mode 100644
index 00000000..83945cbe
--- /dev/null
+++ b/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java
@@ -0,0 +1,160 @@
+/*
+ * YUI Compressor
+ * Author: Julien Lecomte
+ * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ */
+
+package com.yahoo.platform.yui.compressor;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+class ScriptOrFnScope {
+
+ private int braceNesting;
+ private ScriptOrFnScope parentScope;
+ private ArrayList subScopes;
+ private Hashtable identifiers = new Hashtable();
+ private Hashtable hints = new Hashtable();
+ private boolean markedForMunging = true;
+ private int varcount = 0;
+
+ ScriptOrFnScope(int braceNesting, ScriptOrFnScope parentScope) {
+ this.braceNesting = braceNesting;
+ this.parentScope = parentScope;
+ this.subScopes = new ArrayList();
+ if (parentScope != null) {
+ parentScope.subScopes.add(this);
+ }
+ }
+
+ int getBraceNesting() {
+ return braceNesting;
+ }
+
+ ScriptOrFnScope getParentScope() {
+ return parentScope;
+ }
+
+ JavaScriptIdentifier declareIdentifier(String symbol) {
+ JavaScriptIdentifier identifier = (JavaScriptIdentifier) identifiers.get(symbol);
+ if (identifier == null) {
+ identifier = new JavaScriptIdentifier(symbol, this);
+ identifiers.put(symbol, identifier);
+ }
+ return identifier;
+ }
+
+ JavaScriptIdentifier getIdentifier(String symbol) {
+ return (JavaScriptIdentifier) identifiers.get(symbol);
+ }
+
+ void addHint(String variableName, String variableType) {
+ hints.put(variableName, variableType);
+ }
+
+ void preventMunging() {
+ if (parentScope != null) {
+ // The symbols in the global scope don't get munged,
+ // but the sub-scopes it contains do get munged.
+ markedForMunging = false;
+ }
+ }
+
+ private ArrayList getUsedSymbols() {
+ ArrayList result = new ArrayList();
+ Enumeration elements = identifiers.elements();
+ while (elements.hasMoreElements()) {
+ JavaScriptIdentifier identifier = (JavaScriptIdentifier) elements.nextElement();
+ String mungedValue = identifier.getMungedValue();
+ if (mungedValue == null) {
+ mungedValue = identifier.getValue();
+ }
+ result.add(mungedValue);
+ }
+ return result;
+ }
+
+ private ArrayList getAllUsedSymbols() {
+ ArrayList result = new ArrayList();
+ ScriptOrFnScope scope = this;
+ while (scope != null) {
+ result.addAll(scope.getUsedSymbols());
+ scope = scope.parentScope;
+ }
+ return result;
+ }
+
+ int incrementVarCount() {
+ varcount++;
+ return varcount;
+ }
+
+ void munge() {
+
+ if (!markedForMunging) {
+ // Stop right here if this scope was flagged as unsafe for munging.
+ return;
+ }
+
+ int pickFromSet = 1;
+
+ // Do not munge symbols in the global scope!
+ if (parentScope != null) {
+
+ ArrayList freeSymbols = new ArrayList();
+
+ freeSymbols.addAll(JavaScriptCompressor.ones);
+ freeSymbols.removeAll(getAllUsedSymbols());
+ if (freeSymbols.size() == 0) {
+ pickFromSet = 2;
+ freeSymbols.addAll(JavaScriptCompressor.twos);
+ freeSymbols.removeAll(getAllUsedSymbols());
+ }
+ if (freeSymbols.size() == 0) {
+ pickFromSet = 3;
+ freeSymbols.addAll(JavaScriptCompressor.threes);
+ freeSymbols.removeAll(getAllUsedSymbols());
+ }
+ if (freeSymbols.size() == 0) {
+ throw new IllegalStateException("The YUI Compressor ran out of symbols. Aborting...");
+ }
+
+ Enumeration elements = identifiers.elements();
+ while (elements.hasMoreElements()) {
+ if (freeSymbols.size() == 0) {
+ pickFromSet++;
+ if (pickFromSet == 2) {
+ freeSymbols.addAll(JavaScriptCompressor.twos);
+ } else if (pickFromSet == 3) {
+ freeSymbols.addAll(JavaScriptCompressor.threes);
+ } else {
+ throw new IllegalStateException("The YUI Compressor ran out of symbols. Aborting...");
+ }
+ // It is essential to remove the symbols already used in
+ // the containing scopes, or some of the variables declared
+ // in the containing scopes will be redeclared, which can
+ // lead to errors.
+ freeSymbols.removeAll(getAllUsedSymbols());
+ }
+
+ String mungedValue;
+ JavaScriptIdentifier identifier = (JavaScriptIdentifier) elements.nextElement();
+ if (identifier.isMarkedForMunging()) {
+ mungedValue = (String) freeSymbols.remove(0);
+ } else {
+ mungedValue = identifier.getValue();
+ }
+ identifier.setMungedValue(mungedValue);
+ }
+ }
+
+ for (int i = 0; i < subScopes.size(); i++) {
+ ScriptOrFnScope scope = (ScriptOrFnScope) subScopes.get(i);
+ scope.munge();
+ }
+ }
+}
diff --git a/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/YUICompressor.java b/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/YUICompressor.java
new file mode 100644
index 00000000..a5b4f83c
--- /dev/null
+++ b/yuicompressor-2.4.2/src/com/yahoo/platform/yui/compressor/YUICompressor.java
@@ -0,0 +1,232 @@
+/*
+ * YUI Compressor
+ * Author: Julien Lecomte
+ * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ */
+
+package com.yahoo.platform.yui.compressor;
+
+import jargs.gnu.CmdLineParser;
+import org.mozilla.javascript.ErrorReporter;
+import org.mozilla.javascript.EvaluatorException;
+
+import java.io.*;
+import java.nio.charset.Charset;
+
+public class YUICompressor {
+
+ public static void main(String args[]) {
+
+ CmdLineParser parser = new CmdLineParser();
+ CmdLineParser.Option typeOpt = parser.addStringOption("type");
+ CmdLineParser.Option verboseOpt = parser.addBooleanOption('v', "verbose");
+ CmdLineParser.Option nomungeOpt = parser.addBooleanOption("nomunge");
+ CmdLineParser.Option linebreakOpt = parser.addStringOption("line-break");
+ CmdLineParser.Option preserveSemiOpt = parser.addBooleanOption("preserve-semi");
+ CmdLineParser.Option disableOptimizationsOpt = parser.addBooleanOption("disable-optimizations");
+ CmdLineParser.Option helpOpt = parser.addBooleanOption('h', "help");
+ CmdLineParser.Option charsetOpt = parser.addStringOption("charset");
+ CmdLineParser.Option outputFilenameOpt = parser.addStringOption('o', "output");
+
+ Reader in = null;
+ Writer out = null;
+
+ try {
+
+ parser.parse(args);
+
+ Boolean help = (Boolean) parser.getOptionValue(helpOpt);
+ if (help != null && help.booleanValue()) {
+ usage();
+ System.exit(0);
+ }
+
+ boolean verbose = parser.getOptionValue(verboseOpt) != null;
+
+ String charset = (String) parser.getOptionValue(charsetOpt);
+ if (charset == null || !Charset.isSupported(charset)) {
+ charset = System.getProperty("file.encoding");
+ if (charset == null) {
+ charset = "UTF-8";
+ }
+ if (verbose) {
+ System.err.println("\n[INFO] Using charset " + charset);
+ }
+ }
+
+ String[] fileArgs = parser.getRemainingArgs();
+ String type = (String) parser.getOptionValue(typeOpt);
+
+ if (fileArgs.length == 0) {
+
+ if (type == null || !type.equalsIgnoreCase("js") && !type.equalsIgnoreCase("css")) {
+ usage();
+ System.exit(1);
+ }
+
+ in = new InputStreamReader(System.in, charset);
+
+ } else {
+
+ if (type != null && !type.equalsIgnoreCase("js") && !type.equalsIgnoreCase("css")) {
+ usage();
+ System.exit(1);
+ }
+
+ String inputFilename = fileArgs[0];
+
+ if (type == null) {
+ int idx = inputFilename.lastIndexOf('.');
+ if (idx >= 0 && idx < inputFilename.length() - 1) {
+ type = inputFilename.substring(idx + 1);
+ }
+ }
+
+ if (type == null || !type.equalsIgnoreCase("js") && !type.equalsIgnoreCase("css")) {
+ usage();
+ System.exit(1);
+ }
+
+ in = new InputStreamReader(new FileInputStream(inputFilename), charset);
+ }
+
+ int linebreakpos = -1;
+ String linebreakstr = (String) parser.getOptionValue(linebreakOpt);
+ if (linebreakstr != null) {
+ try {
+ linebreakpos = Integer.parseInt(linebreakstr, 10);
+ } catch (NumberFormatException e) {
+ usage();
+ System.exit(1);
+ }
+ }
+
+ String outputFilename = (String) parser.getOptionValue(outputFilenameOpt);
+
+ if (type.equalsIgnoreCase("js")) {
+
+ try {
+
+ JavaScriptCompressor compressor = new JavaScriptCompressor(in, new ErrorReporter() {
+
+ public void warning(String message, String sourceName,
+ int line, String lineSource, int lineOffset) {
+ if (line < 0) {
+ System.err.println("\n[WARNING] " + message);
+ } else {
+ System.err.println("\n[WARNING] " + line + ':' + lineOffset + ':' + message);
+ }
+ }
+
+ public void error(String message, String sourceName,
+ int line, String lineSource, int lineOffset) {
+ if (line < 0) {
+ System.err.println("\n[ERROR] " + message);
+ } else {
+ System.err.println("\n[ERROR] " + line + ':' + lineOffset + ':' + message);
+ }
+ }
+
+ public EvaluatorException runtimeError(String message, String sourceName,
+ int line, String lineSource, int lineOffset) {
+ error(message, sourceName, line, lineSource, lineOffset);
+ return new EvaluatorException(message);
+ }
+ });
+
+ // Close the input stream first, and then open the output stream,
+ // in case the output file should override the input file.
+ in.close(); in = null;
+
+ if (outputFilename == null) {
+ out = new OutputStreamWriter(System.out, charset);
+ } else {
+ out = new OutputStreamWriter(new FileOutputStream(outputFilename), charset);
+ }
+
+ boolean munge = parser.getOptionValue(nomungeOpt) == null;
+ boolean preserveAllSemiColons = parser.getOptionValue(preserveSemiOpt) != null;
+ boolean disableOptimizations = parser.getOptionValue(disableOptimizationsOpt) != null;
+
+ compressor.compress(out, linebreakpos, munge, verbose,
+ preserveAllSemiColons, disableOptimizations);
+
+ } catch (EvaluatorException e) {
+
+ e.printStackTrace();
+ // Return a special error code used specifically by the web front-end.
+ System.exit(2);
+
+ }
+
+ } else if (type.equalsIgnoreCase("css")) {
+
+ CssCompressor compressor = new CssCompressor(in);
+
+ // Close the input stream first, and then open the output stream,
+ // in case the output file should override the input file.
+ in.close(); in = null;
+
+ if (outputFilename == null) {
+ out = new OutputStreamWriter(System.out, charset);
+ } else {
+ out = new OutputStreamWriter(new FileOutputStream(outputFilename), charset);
+ }
+
+ compressor.compress(out, linebreakpos);
+ }
+
+ } catch (CmdLineParser.OptionException e) {
+
+ usage();
+ System.exit(1);
+
+ } catch (IOException e) {
+
+ e.printStackTrace();
+ System.exit(1);
+
+ } finally {
+
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (out != null) {
+ try {
+ out.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private static void usage() {
+ System.out.println(
+ "\nUsage: java -jar yuicompressor-x.y.z.jar [options] [input file]\n\n"
+
+ + "Global Options\n"
+ + " -h, --help Displays this information\n"
+ + " --type Specifies the type of the input file\n"
+ + " --charset Read the input file using \n"
+ + " --line-break Insert a line break after the specified column number\n"
+ + " -v, --verbose Display informational messages and warnings\n"
+ + " -o Place the output into . Defaults to stdout.\n\n"
+
+ + "JavaScript Options\n"
+ + " --nomunge Minify only, do not obfuscate\n"
+ + " --preserve-semi Preserve all semicolons\n"
+ + " --disable-optimizations Disable all micro optimizations\n\n"
+
+ + "If no input file is specified, it defaults to stdin. In this case, the 'type'\n"
+ + "option is required. Otherwise, the 'type' option is required only if the input\n"
+ + "file extension is neither 'js' nor 'css'.");
+ }
+}
diff --git a/yuicompressor-2.4.2/src/org/mozilla/javascript/Decompiler.java b/yuicompressor-2.4.2/src/org/mozilla/javascript/Decompiler.java
new file mode 100644
index 00000000..05185aec
--- /dev/null
+++ b/yuicompressor-2.4.2/src/org/mozilla/javascript/Decompiler.java
@@ -0,0 +1,922 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Ang
+ * Igor Bukanov
+ * Bob Jervis
+ * Mike McCabe
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * The following class save decompilation information about the source.
+ * Source information is returned from the parser as a String
+ * associated with function nodes and with the toplevel script. When
+ * saved in the constant pool of a class, this string will be UTF-8
+ * encoded, and token values will occupy a single byte.
+
+ * Source is saved (mostly) as token numbers. The tokens saved pretty
+ * much correspond to the token stream of a 'canonical' representation
+ * of the input program, as directed by the parser. (There were a few
+ * cases where tokens could have been left out where decompiler could
+ * easily reconstruct them, but I left them in for clarity). (I also
+ * looked adding source collection to TokenStream instead, where I
+ * could have limited the changes to a few lines in getToken... but
+ * this wouldn't have saved any space in the resulting source
+ * representation, and would have meant that I'd have to duplicate
+ * parser logic in the decompiler to disambiguate situations where
+ * newlines are important.) The function decompile expands the
+ * tokens back into their string representations, using simple
+ * lookahead to correct spacing and indentation.
+ *
+ * Assignments are saved as two-token pairs (Token.ASSIGN, op). Number tokens
+ * are stored inline, as a NUMBER token, a character representing the type, and
+ * either 1 or 4 characters representing the bit-encoding of the number. String
+ * types NAME, STRING and OBJECT are currently stored as a token type,
+ * followed by a character giving the length of the string (assumed to
+ * be less than 2^16), followed by the characters of the string
+ * inlined into the source string. Changing this to some reference to
+ * to the string in the compiled class' constant pool would probably
+ * save a lot of space... but would require some method of deriving
+ * the final constant pool entry from information available at parse
+ * time.
+ */
+public class Decompiler
+{
+ /**
+ * Flag to indicate that the decompilation should omit the
+ * function header and trailing brace.
+ */
+ public static final int ONLY_BODY_FLAG = 1 << 0;
+
+ /**
+ * Flag to indicate that the decompilation generates toSource result.
+ */
+ public static final int TO_SOURCE_FLAG = 1 << 1;
+
+ /**
+ * Decompilation property to specify initial ident value.
+ */
+ public static final int INITIAL_INDENT_PROP = 1;
+
+ /**
+ * Decompilation property to specify default identation offset.
+ */
+ public static final int INDENT_GAP_PROP = 2;
+
+ /**
+ * Decompilation property to specify identation offset for case labels.
+ */
+ public static final int CASE_GAP_PROP = 3;
+
+ // Marker to denote the last RC of function so it can be distinguished from
+ // the last RC of object literals in case of function expressions
+ private static final int FUNCTION_END = Token.LAST_TOKEN + 1;
+
+ String getEncodedSource()
+ {
+ return sourceToString(0);
+ }
+
+ int getCurrentOffset()
+ {
+ return sourceTop;
+ }
+
+ int markFunctionStart(int functionType)
+ {
+ int savedOffset = getCurrentOffset();
+ addToken(Token.FUNCTION);
+ append((char)functionType);
+ return savedOffset;
+ }
+
+ int markFunctionEnd(int functionStart)
+ {
+ int offset = getCurrentOffset();
+ append((char)FUNCTION_END);
+ return offset;
+ }
+
+ void addToken(int token)
+ {
+ if (!(0 <= token && token <= Token.LAST_TOKEN))
+ throw new IllegalArgumentException();
+
+ append((char)token);
+ }
+
+ void addEOL(int token)
+ {
+ if (!(0 <= token && token <= Token.LAST_TOKEN))
+ throw new IllegalArgumentException();
+
+ append((char)token);
+ append((char)Token.EOL);
+ }
+
+ void addName(String str)
+ {
+ addToken(Token.NAME);
+ appendString(str);
+ }
+
+ void addString(String str)
+ {
+ addToken(Token.STRING);
+ appendString(str);
+ }
+
+ void addRegexp(String regexp, String flags)
+ {
+ addToken(Token.REGEXP);
+ appendString('/' + regexp + '/' + flags);
+ }
+
+ void addJScriptConditionalComment(String str)
+ {
+ addToken(Token.CONDCOMMENT);
+ appendString(str);
+ }
+
+ void addPreservedComment(String str)
+ {
+ addToken(Token.KEEPCOMMENT);
+ appendString(str);
+ }
+
+ void addNumber(double n)
+ {
+ addToken(Token.NUMBER);
+
+ /* encode the number in the source stream.
+ * Save as NUMBER type (char | char char char char)
+ * where type is
+ * 'D' - double, 'S' - short, 'J' - long.
+
+ * We need to retain float vs. integer type info to keep the
+ * behavior of liveconnect type-guessing the same after
+ * decompilation. (Liveconnect tries to present 1.0 to Java
+ * as a float/double)
+ * OPT: This is no longer true. We could compress the format.
+
+ * This may not be the most space-efficient encoding;
+ * the chars created below may take up to 3 bytes in
+ * constant pool UTF-8 encoding, so a Double could take
+ * up to 12 bytes.
+ */
+
+ long lbits = (long)n;
+ if (lbits != n) {
+ // if it's floating point, save as a Double bit pattern.
+ // (12/15/97 our scanner only returns Double for f.p.)
+ lbits = Double.doubleToLongBits(n);
+ append('D');
+ append((char)(lbits >> 48));
+ append((char)(lbits >> 32));
+ append((char)(lbits >> 16));
+ append((char)lbits);
+ }
+ else {
+ // we can ignore negative values, bc they're already prefixed
+ // by NEG
+ if (lbits < 0) Kit.codeBug();
+
+ // will it fit in a char?
+ // this gives a short encoding for integer values up to 2^16.
+ if (lbits <= Character.MAX_VALUE) {
+ append('S');
+ append((char)lbits);
+ }
+ else { // Integral, but won't fit in a char. Store as a long.
+ append('J');
+ append((char)(lbits >> 48));
+ append((char)(lbits >> 32));
+ append((char)(lbits >> 16));
+ append((char)lbits);
+ }
+ }
+ }
+
+ private void appendString(String str)
+ {
+ int L = str.length();
+ int lengthEncodingSize = 1;
+ if (L >= 0x8000) {
+ lengthEncodingSize = 2;
+ }
+ int nextTop = sourceTop + lengthEncodingSize + L;
+ if (nextTop > sourceBuffer.length) {
+ increaseSourceCapacity(nextTop);
+ }
+ if (L >= 0x8000) {
+ // Use 2 chars to encode strings exceeding 32K, were the highest
+ // bit in the first char indicates presence of the next byte
+ sourceBuffer[sourceTop] = (char)(0x8000 | (L >>> 16));
+ ++sourceTop;
+ }
+ sourceBuffer[sourceTop] = (char)L;
+ ++sourceTop;
+ str.getChars(0, L, sourceBuffer, sourceTop);
+ sourceTop = nextTop;
+ }
+
+ private void append(char c)
+ {
+ if (sourceTop == sourceBuffer.length) {
+ increaseSourceCapacity(sourceTop + 1);
+ }
+ sourceBuffer[sourceTop] = c;
+ ++sourceTop;
+ }
+
+ private void increaseSourceCapacity(int minimalCapacity)
+ {
+ // Call this only when capacity increase is must
+ if (minimalCapacity <= sourceBuffer.length) Kit.codeBug();
+ int newCapacity = sourceBuffer.length * 2;
+ if (newCapacity < minimalCapacity) {
+ newCapacity = minimalCapacity;
+ }
+ char[] tmp = new char[newCapacity];
+ System.arraycopy(sourceBuffer, 0, tmp, 0, sourceTop);
+ sourceBuffer = tmp;
+ }
+
+ private String sourceToString(int offset)
+ {
+ if (offset < 0 || sourceTop < offset) Kit.codeBug();
+ return new String(sourceBuffer, offset, sourceTop - offset);
+ }
+
+ /**
+ * Decompile the source information associated with this js
+ * function/script back into a string. For the most part, this
+ * just means translating tokens back to their string
+ * representations; there's a little bit of lookahead logic to
+ * decide the proper spacing/indentation. Most of the work in
+ * mapping the original source to the prettyprinted decompiled
+ * version is done by the parser.
+ *
+ * @param source encoded source tree presentation
+ *
+ * @param flags flags to select output format
+ *
+ * @param properties indentation properties
+ *
+ */
+ public static String decompile(String source, int flags,
+ UintMap properties)
+ {
+ int length = source.length();
+ if (length == 0) { return ""; }
+
+ int indent = properties.getInt(INITIAL_INDENT_PROP, 0);
+ if (indent < 0) throw new IllegalArgumentException();
+ int indentGap = properties.getInt(INDENT_GAP_PROP, 4);
+ if (indentGap < 0) throw new IllegalArgumentException();
+ int caseGap = properties.getInt(CASE_GAP_PROP, 2);
+ if (caseGap < 0) throw new IllegalArgumentException();
+
+ StringBuffer result = new StringBuffer();
+ boolean justFunctionBody = (0 != (flags & Decompiler.ONLY_BODY_FLAG));
+ boolean toSource = (0 != (flags & Decompiler.TO_SOURCE_FLAG));
+
+ // Spew tokens in source, for debugging.
+ // as TYPE number char
+ if (printSource) {
+ System.err.println("length:" + length);
+ for (int i = 0; i < length; ++i) {
+ // Note that tokenToName will fail unless Context.printTrees
+ // is true.
+ String tokenname = null;
+ if (Token.printNames) {
+ tokenname = Token.name(source.charAt(i));
+ }
+ if (tokenname == null) {
+ tokenname = "---";
+ }
+ String pad = tokenname.length() > 7
+ ? "\t"
+ : "\t\t";
+ System.err.println
+ (tokenname
+ + pad + (int)source.charAt(i)
+ + "\t'" + ScriptRuntime.escapeString
+ (source.substring(i, i+1))
+ + "'");
+ }
+ System.err.println();
+ }
+
+ int braceNesting = 0;
+ boolean afterFirstEOL = false;
+ int i = 0;
+ int topFunctionType;
+ if (source.charAt(i) == Token.SCRIPT) {
+ ++i;
+ topFunctionType = -1;
+ } else {
+ topFunctionType = source.charAt(i + 1);
+ }
+
+ if (!toSource) {
+ // add an initial newline to exactly match js.
+ result.append('\n');
+ for (int j = 0; j < indent; j++)
+ result.append(' ');
+ } else {
+ if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) {
+ result.append('(');
+ }
+ }
+
+ while (i < length) {
+ switch(source.charAt(i)) {
+ case Token.GET:
+ case Token.SET:
+ result.append(source.charAt(i) == Token.GET ? "get " : "set ");
+ ++i;
+ i = printSourceString(source, i + 1, false, result);
+ // Now increment one more to get past the FUNCTION token
+ ++i;
+ break;
+
+ case Token.NAME:
+ case Token.REGEXP: // re-wrapped in '/'s in parser...
+ i = printSourceString(source, i + 1, false, result);
+ continue;
+
+ case Token.STRING:
+ i = printSourceString(source, i + 1, true, result);
+ continue;
+
+ case Token.NUMBER:
+ i = printSourceNumber(source, i + 1, result);
+ continue;
+
+ case Token.TRUE:
+ result.append("true");
+ break;
+
+ case Token.FALSE:
+ result.append("false");
+ break;
+
+ case Token.NULL:
+ result.append("null");
+ break;
+
+ case Token.THIS:
+ result.append("this");
+ break;
+
+ case Token.FUNCTION:
+ ++i; // skip function type
+ result.append("function ");
+ break;
+
+ case FUNCTION_END:
+ // Do nothing
+ break;
+
+ case Token.COMMA:
+ result.append(", ");
+ break;
+
+ case Token.LC:
+ ++braceNesting;
+ if (Token.EOL == getNext(source, length, i))
+ indent += indentGap;
+ result.append('{');
+ break;
+
+ case Token.RC: {
+ --braceNesting;
+ /* don't print the closing RC if it closes the
+ * toplevel function and we're called from
+ * decompileFunctionBody.
+ */
+ if (justFunctionBody && braceNesting == 0)
+ break;
+
+ result.append('}');
+ switch (getNext(source, length, i)) {
+ case Token.EOL:
+ case FUNCTION_END:
+ indent -= indentGap;
+ break;
+ case Token.WHILE:
+ case Token.ELSE:
+ indent -= indentGap;
+ result.append(' ');
+ break;
+ }
+ break;
+ }
+ case Token.LP:
+ result.append('(');
+ break;
+
+ case Token.RP:
+ result.append(')');
+ if (Token.LC == getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.LB:
+ result.append('[');
+ break;
+
+ case Token.RB:
+ result.append(']');
+ break;
+
+ case Token.EOL: {
+ if (toSource) break;
+ boolean newLine = true;
+ if (!afterFirstEOL) {
+ afterFirstEOL = true;
+ if (justFunctionBody) {
+ /* throw away just added 'function name(...) {'
+ * and restore the original indent
+ */
+ result.setLength(0);
+ indent -= indentGap;
+ newLine = false;
+ }
+ }
+ if (newLine) {
+ result.append('\n');
+ }
+
+ /* add indent if any tokens remain,
+ * less setback if next token is
+ * a label, case or default.
+ */
+ if (i + 1 < length) {
+ int less = 0;
+ int nextToken = source.charAt(i + 1);
+ if (nextToken == Token.CASE
+ || nextToken == Token.DEFAULT)
+ {
+ less = indentGap - caseGap;
+ } else if (nextToken == Token.RC) {
+ less = indentGap;
+ }
+
+ /* elaborate check against label... skip past a
+ * following inlined NAME and look for a COLON.
+ */
+ else if (nextToken == Token.NAME) {
+ int afterName = getSourceStringEnd(source, i + 2);
+ if (source.charAt(afterName) == Token.COLON)
+ less = indentGap;
+ }
+
+ for (; less < indent; less++)
+ result.append(' ');
+ }
+ break;
+ }
+ case Token.DOT:
+ result.append('.');
+ break;
+
+ case Token.NEW:
+ result.append("new ");
+ break;
+
+ case Token.DELPROP:
+ result.append("delete ");
+ break;
+
+ case Token.IF:
+ result.append("if ");
+ break;
+
+ case Token.ELSE:
+ result.append("else ");
+ break;
+
+ case Token.FOR:
+ result.append("for ");
+ break;
+
+ case Token.IN:
+ result.append(" in ");
+ break;
+
+ case Token.WITH:
+ result.append("with ");
+ break;
+
+ case Token.WHILE:
+ result.append("while ");
+ break;
+
+ case Token.DO:
+ result.append("do ");
+ break;
+
+ case Token.TRY:
+ result.append("try ");
+ break;
+
+ case Token.CATCH:
+ result.append("catch ");
+ break;
+
+ case Token.FINALLY:
+ result.append("finally ");
+ break;
+
+ case Token.THROW:
+ result.append("throw ");
+ break;
+
+ case Token.SWITCH:
+ result.append("switch ");
+ break;
+
+ case Token.BREAK:
+ result.append("break");
+ if (Token.NAME == getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.CONTINUE:
+ result.append("continue");
+ if (Token.NAME == getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.CASE:
+ result.append("case ");
+ break;
+
+ case Token.DEFAULT:
+ result.append("default");
+ break;
+
+ case Token.RETURN:
+ result.append("return");
+ if (Token.SEMI != getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.VAR:
+ result.append("var ");
+ break;
+
+ case Token.SEMI:
+ result.append(';');
+ if (Token.EOL != getNext(source, length, i)) {
+ // separators in FOR
+ result.append(' ');
+ }
+ break;
+
+ case Token.ASSIGN:
+ result.append(" = ");
+ break;
+
+ case Token.ASSIGN_ADD:
+ result.append(" += ");
+ break;
+
+ case Token.ASSIGN_SUB:
+ result.append(" -= ");
+ break;
+
+ case Token.ASSIGN_MUL:
+ result.append(" *= ");
+ break;
+
+ case Token.ASSIGN_DIV:
+ result.append(" /= ");
+ break;
+
+ case Token.ASSIGN_MOD:
+ result.append(" %= ");
+ break;
+
+ case Token.ASSIGN_BITOR:
+ result.append(" |= ");
+ break;
+
+ case Token.ASSIGN_BITXOR:
+ result.append(" ^= ");
+ break;
+
+ case Token.ASSIGN_BITAND:
+ result.append(" &= ");
+ break;
+
+ case Token.ASSIGN_LSH:
+ result.append(" <<= ");
+ break;
+
+ case Token.ASSIGN_RSH:
+ result.append(" >>= ");
+ break;
+
+ case Token.ASSIGN_URSH:
+ result.append(" >>>= ");
+ break;
+
+ case Token.HOOK:
+ result.append(" ? ");
+ break;
+
+ case Token.OBJECTLIT:
+ // pun OBJECTLIT to mean colon in objlit property
+ // initialization.
+ // This needs to be distinct from COLON in the general case
+ // to distinguish from the colon in a ternary... which needs
+ // different spacing.
+ result.append(':');
+ break;
+
+ case Token.COLON:
+ if (Token.EOL == getNext(source, length, i))
+ // it's the end of a label
+ result.append(':');
+ else
+ // it's the middle part of a ternary
+ result.append(" : ");
+ break;
+
+ case Token.OR:
+ result.append(" || ");
+ break;
+
+ case Token.AND:
+ result.append(" && ");
+ break;
+
+ case Token.BITOR:
+ result.append(" | ");
+ break;
+
+ case Token.BITXOR:
+ result.append(" ^ ");
+ break;
+
+ case Token.BITAND:
+ result.append(" & ");
+ break;
+
+ case Token.SHEQ:
+ result.append(" === ");
+ break;
+
+ case Token.SHNE:
+ result.append(" !== ");
+ break;
+
+ case Token.EQ:
+ result.append(" == ");
+ break;
+
+ case Token.NE:
+ result.append(" != ");
+ break;
+
+ case Token.LE:
+ result.append(" <= ");
+ break;
+
+ case Token.LT:
+ result.append(" < ");
+ break;
+
+ case Token.GE:
+ result.append(" >= ");
+ break;
+
+ case Token.GT:
+ result.append(" > ");
+ break;
+
+ case Token.INSTANCEOF:
+ result.append(" instanceof ");
+ break;
+
+ case Token.LSH:
+ result.append(" << ");
+ break;
+
+ case Token.RSH:
+ result.append(" >> ");
+ break;
+
+ case Token.URSH:
+ result.append(" >>> ");
+ break;
+
+ case Token.TYPEOF:
+ result.append("typeof ");
+ break;
+
+ case Token.VOID:
+ result.append("void ");
+ break;
+
+ case Token.CONST:
+ result.append("const ");
+ break;
+
+ case Token.NOT:
+ result.append('!');
+ break;
+
+ case Token.BITNOT:
+ result.append('~');
+ break;
+
+ case Token.POS:
+ result.append('+');
+ break;
+
+ case Token.NEG:
+ result.append('-');
+ break;
+
+ case Token.INC:
+ result.append("++");
+ break;
+
+ case Token.DEC:
+ result.append("--");
+ break;
+
+ case Token.ADD:
+ result.append(" + ");
+ break;
+
+ case Token.SUB:
+ result.append(" - ");
+ break;
+
+ case Token.MUL:
+ result.append(" * ");
+ break;
+
+ case Token.DIV:
+ result.append(" / ");
+ break;
+
+ case Token.MOD:
+ result.append(" % ");
+ break;
+
+ case Token.COLONCOLON:
+ result.append("::");
+ break;
+
+ case Token.DOTDOT:
+ result.append("..");
+ break;
+
+ case Token.DOTQUERY:
+ result.append(".(");
+ break;
+
+ case Token.XMLATTR:
+ result.append('@');
+ break;
+
+ default:
+ // If we don't know how to decompile it, raise an exception.
+ throw new RuntimeException("Token: " +
+ Token.name(source.charAt(i)));
+ }
+ ++i;
+ }
+
+ if (!toSource) {
+ // add that trailing newline if it's an outermost function.
+ if (!justFunctionBody)
+ result.append('\n');
+ } else {
+ if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) {
+ result.append(')');
+ }
+ }
+
+ return result.toString();
+ }
+
+ private static int getNext(String source, int length, int i)
+ {
+ return (i + 1 < length) ? source.charAt(i + 1) : Token.EOF;
+ }
+
+ private static int getSourceStringEnd(String source, int offset)
+ {
+ return printSourceString(source, offset, false, null);
+ }
+
+ private static int printSourceString(String source, int offset,
+ boolean asQuotedString,
+ StringBuffer sb)
+ {
+ int length = source.charAt(offset);
+ ++offset;
+ if ((0x8000 & length) != 0) {
+ length = ((0x7FFF & length) << 16) | source.charAt(offset);
+ ++offset;
+ }
+ if (sb != null) {
+ String str = source.substring(offset, offset + length);
+ if (!asQuotedString) {
+ sb.append(str);
+ } else {
+ sb.append('"');
+ sb.append(ScriptRuntime.escapeString(str));
+ sb.append('"');
+ }
+ }
+ return offset + length;
+ }
+
+ private static int printSourceNumber(String source, int offset,
+ StringBuffer sb)
+ {
+ double number = 0.0;
+ char type = source.charAt(offset);
+ ++offset;
+ if (type == 'S') {
+ if (sb != null) {
+ int ival = source.charAt(offset);
+ number = ival;
+ }
+ ++offset;
+ } else if (type == 'J' || type == 'D') {
+ if (sb != null) {
+ long lbits;
+ lbits = (long)source.charAt(offset) << 48;
+ lbits |= (long)source.charAt(offset + 1) << 32;
+ lbits |= (long)source.charAt(offset + 2) << 16;
+ lbits |= source.charAt(offset + 3);
+ if (type == 'J') {
+ number = lbits;
+ } else {
+ number = Double.longBitsToDouble(lbits);
+ }
+ }
+ offset += 4;
+ } else {
+ // Bad source
+ throw new RuntimeException();
+ }
+ if (sb != null) {
+ sb.append(ScriptRuntime.numberToString(number, 10));
+ }
+ return offset;
+ }
+
+ private char[] sourceBuffer = new char[128];
+
+// Per script/function source buffer top: parent source does not include a
+// nested functions source and uses function index as a reference instead.
+ private int sourceTop;
+
+// whether to do a debug print of the source information, when decompiling.
+ private static final boolean printSource = false;
+
+}
diff --git a/yuicompressor-2.4.2/src/org/mozilla/javascript/Decompiler.java.orig b/yuicompressor-2.4.2/src/org/mozilla/javascript/Decompiler.java.orig
new file mode 100644
index 00000000..cdb00b76
--- /dev/null
+++ b/yuicompressor-2.4.2/src/org/mozilla/javascript/Decompiler.java.orig
@@ -0,0 +1,910 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Ang
+ * Igor Bukanov
+ * Bob Jervis
+ * Mike McCabe
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * The following class save decompilation information about the source.
+ * Source information is returned from the parser as a String
+ * associated with function nodes and with the toplevel script. When
+ * saved in the constant pool of a class, this string will be UTF-8
+ * encoded, and token values will occupy a single byte.
+
+ * Source is saved (mostly) as token numbers. The tokens saved pretty
+ * much correspond to the token stream of a 'canonical' representation
+ * of the input program, as directed by the parser. (There were a few
+ * cases where tokens could have been left out where decompiler could
+ * easily reconstruct them, but I left them in for clarity). (I also
+ * looked adding source collection to TokenStream instead, where I
+ * could have limited the changes to a few lines in getToken... but
+ * this wouldn't have saved any space in the resulting source
+ * representation, and would have meant that I'd have to duplicate
+ * parser logic in the decompiler to disambiguate situations where
+ * newlines are important.) The function decompile expands the
+ * tokens back into their string representations, using simple
+ * lookahead to correct spacing and indentation.
+ *
+ * Assignments are saved as two-token pairs (Token.ASSIGN, op). Number tokens
+ * are stored inline, as a NUMBER token, a character representing the type, and
+ * either 1 or 4 characters representing the bit-encoding of the number. String
+ * types NAME, STRING and OBJECT are currently stored as a token type,
+ * followed by a character giving the length of the string (assumed to
+ * be less than 2^16), followed by the characters of the string
+ * inlined into the source string. Changing this to some reference to
+ * to the string in the compiled class' constant pool would probably
+ * save a lot of space... but would require some method of deriving
+ * the final constant pool entry from information available at parse
+ * time.
+ */
+public class Decompiler
+{
+ /**
+ * Flag to indicate that the decompilation should omit the
+ * function header and trailing brace.
+ */
+ public static final int ONLY_BODY_FLAG = 1 << 0;
+
+ /**
+ * Flag to indicate that the decompilation generates toSource result.
+ */
+ public static final int TO_SOURCE_FLAG = 1 << 1;
+
+ /**
+ * Decompilation property to specify initial ident value.
+ */
+ public static final int INITIAL_INDENT_PROP = 1;
+
+ /**
+ * Decompilation property to specify default identation offset.
+ */
+ public static final int INDENT_GAP_PROP = 2;
+
+ /**
+ * Decompilation property to specify identation offset for case labels.
+ */
+ public static final int CASE_GAP_PROP = 3;
+
+ // Marker to denote the last RC of function so it can be distinguished from
+ // the last RC of object literals in case of function expressions
+ private static final int FUNCTION_END = Token.LAST_TOKEN + 1;
+
+ String getEncodedSource()
+ {
+ return sourceToString(0);
+ }
+
+ int getCurrentOffset()
+ {
+ return sourceTop;
+ }
+
+ int markFunctionStart(int functionType)
+ {
+ int savedOffset = getCurrentOffset();
+ addToken(Token.FUNCTION);
+ append((char)functionType);
+ return savedOffset;
+ }
+
+ int markFunctionEnd(int functionStart)
+ {
+ int offset = getCurrentOffset();
+ append((char)FUNCTION_END);
+ return offset;
+ }
+
+ void addToken(int token)
+ {
+ if (!(0 <= token && token <= Token.LAST_TOKEN))
+ throw new IllegalArgumentException();
+
+ append((char)token);
+ }
+
+ void addEOL(int token)
+ {
+ if (!(0 <= token && token <= Token.LAST_TOKEN))
+ throw new IllegalArgumentException();
+
+ append((char)token);
+ append((char)Token.EOL);
+ }
+
+ void addName(String str)
+ {
+ addToken(Token.NAME);
+ appendString(str);
+ }
+
+ void addString(String str)
+ {
+ addToken(Token.STRING);
+ appendString(str);
+ }
+
+ void addRegexp(String regexp, String flags)
+ {
+ addToken(Token.REGEXP);
+ appendString('/' + regexp + '/' + flags);
+ }
+
+ void addNumber(double n)
+ {
+ addToken(Token.NUMBER);
+
+ /* encode the number in the source stream.
+ * Save as NUMBER type (char | char char char char)
+ * where type is
+ * 'D' - double, 'S' - short, 'J' - long.
+
+ * We need to retain float vs. integer type info to keep the
+ * behavior of liveconnect type-guessing the same after
+ * decompilation. (Liveconnect tries to present 1.0 to Java
+ * as a float/double)
+ * OPT: This is no longer true. We could compress the format.
+
+ * This may not be the most space-efficient encoding;
+ * the chars created below may take up to 3 bytes in
+ * constant pool UTF-8 encoding, so a Double could take
+ * up to 12 bytes.
+ */
+
+ long lbits = (long)n;
+ if (lbits != n) {
+ // if it's floating point, save as a Double bit pattern.
+ // (12/15/97 our scanner only returns Double for f.p.)
+ lbits = Double.doubleToLongBits(n);
+ append('D');
+ append((char)(lbits >> 48));
+ append((char)(lbits >> 32));
+ append((char)(lbits >> 16));
+ append((char)lbits);
+ }
+ else {
+ // we can ignore negative values, bc they're already prefixed
+ // by NEG
+ if (lbits < 0) Kit.codeBug();
+
+ // will it fit in a char?
+ // this gives a short encoding for integer values up to 2^16.
+ if (lbits <= Character.MAX_VALUE) {
+ append('S');
+ append((char)lbits);
+ }
+ else { // Integral, but won't fit in a char. Store as a long.
+ append('J');
+ append((char)(lbits >> 48));
+ append((char)(lbits >> 32));
+ append((char)(lbits >> 16));
+ append((char)lbits);
+ }
+ }
+ }
+
+ private void appendString(String str)
+ {
+ int L = str.length();
+ int lengthEncodingSize = 1;
+ if (L >= 0x8000) {
+ lengthEncodingSize = 2;
+ }
+ int nextTop = sourceTop + lengthEncodingSize + L;
+ if (nextTop > sourceBuffer.length) {
+ increaseSourceCapacity(nextTop);
+ }
+ if (L >= 0x8000) {
+ // Use 2 chars to encode strings exceeding 32K, were the highest
+ // bit in the first char indicates presence of the next byte
+ sourceBuffer[sourceTop] = (char)(0x8000 | (L >>> 16));
+ ++sourceTop;
+ }
+ sourceBuffer[sourceTop] = (char)L;
+ ++sourceTop;
+ str.getChars(0, L, sourceBuffer, sourceTop);
+ sourceTop = nextTop;
+ }
+
+ private void append(char c)
+ {
+ if (sourceTop == sourceBuffer.length) {
+ increaseSourceCapacity(sourceTop + 1);
+ }
+ sourceBuffer[sourceTop] = c;
+ ++sourceTop;
+ }
+
+ private void increaseSourceCapacity(int minimalCapacity)
+ {
+ // Call this only when capacity increase is must
+ if (minimalCapacity <= sourceBuffer.length) Kit.codeBug();
+ int newCapacity = sourceBuffer.length * 2;
+ if (newCapacity < minimalCapacity) {
+ newCapacity = minimalCapacity;
+ }
+ char[] tmp = new char[newCapacity];
+ System.arraycopy(sourceBuffer, 0, tmp, 0, sourceTop);
+ sourceBuffer = tmp;
+ }
+
+ private String sourceToString(int offset)
+ {
+ if (offset < 0 || sourceTop < offset) Kit.codeBug();
+ return new String(sourceBuffer, offset, sourceTop - offset);
+ }
+
+ /**
+ * Decompile the source information associated with this js
+ * function/script back into a string. For the most part, this
+ * just means translating tokens back to their string
+ * representations; there's a little bit of lookahead logic to
+ * decide the proper spacing/indentation. Most of the work in
+ * mapping the original source to the prettyprinted decompiled
+ * version is done by the parser.
+ *
+ * @param source encoded source tree presentation
+ *
+ * @param flags flags to select output format
+ *
+ * @param properties indentation properties
+ *
+ */
+ public static String decompile(String source, int flags,
+ UintMap properties)
+ {
+ int length = source.length();
+ if (length == 0) { return ""; }
+
+ int indent = properties.getInt(INITIAL_INDENT_PROP, 0);
+ if (indent < 0) throw new IllegalArgumentException();
+ int indentGap = properties.getInt(INDENT_GAP_PROP, 4);
+ if (indentGap < 0) throw new IllegalArgumentException();
+ int caseGap = properties.getInt(CASE_GAP_PROP, 2);
+ if (caseGap < 0) throw new IllegalArgumentException();
+
+ StringBuffer result = new StringBuffer();
+ boolean justFunctionBody = (0 != (flags & Decompiler.ONLY_BODY_FLAG));
+ boolean toSource = (0 != (flags & Decompiler.TO_SOURCE_FLAG));
+
+ // Spew tokens in source, for debugging.
+ // as TYPE number char
+ if (printSource) {
+ System.err.println("length:" + length);
+ for (int i = 0; i < length; ++i) {
+ // Note that tokenToName will fail unless Context.printTrees
+ // is true.
+ String tokenname = null;
+ if (Token.printNames) {
+ tokenname = Token.name(source.charAt(i));
+ }
+ if (tokenname == null) {
+ tokenname = "---";
+ }
+ String pad = tokenname.length() > 7
+ ? "\t"
+ : "\t\t";
+ System.err.println
+ (tokenname
+ + pad + (int)source.charAt(i)
+ + "\t'" + ScriptRuntime.escapeString
+ (source.substring(i, i+1))
+ + "'");
+ }
+ System.err.println();
+ }
+
+ int braceNesting = 0;
+ boolean afterFirstEOL = false;
+ int i = 0;
+ int topFunctionType;
+ if (source.charAt(i) == Token.SCRIPT) {
+ ++i;
+ topFunctionType = -1;
+ } else {
+ topFunctionType = source.charAt(i + 1);
+ }
+
+ if (!toSource) {
+ // add an initial newline to exactly match js.
+ result.append('\n');
+ for (int j = 0; j < indent; j++)
+ result.append(' ');
+ } else {
+ if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) {
+ result.append('(');
+ }
+ }
+
+ while (i < length) {
+ switch(source.charAt(i)) {
+ case Token.GET:
+ case Token.SET:
+ result.append(source.charAt(i) == Token.GET ? "get " : "set ");
+ ++i;
+ i = printSourceString(source, i + 1, false, result);
+ // Now increment one more to get past the FUNCTION token
+ ++i;
+ break;
+
+ case Token.NAME:
+ case Token.REGEXP: // re-wrapped in '/'s in parser...
+ i = printSourceString(source, i + 1, false, result);
+ continue;
+
+ case Token.STRING:
+ i = printSourceString(source, i + 1, true, result);
+ continue;
+
+ case Token.NUMBER:
+ i = printSourceNumber(source, i + 1, result);
+ continue;
+
+ case Token.TRUE:
+ result.append("true");
+ break;
+
+ case Token.FALSE:
+ result.append("false");
+ break;
+
+ case Token.NULL:
+ result.append("null");
+ break;
+
+ case Token.THIS:
+ result.append("this");
+ break;
+
+ case Token.FUNCTION:
+ ++i; // skip function type
+ result.append("function ");
+ break;
+
+ case FUNCTION_END:
+ // Do nothing
+ break;
+
+ case Token.COMMA:
+ result.append(", ");
+ break;
+
+ case Token.LC:
+ ++braceNesting;
+ if (Token.EOL == getNext(source, length, i))
+ indent += indentGap;
+ result.append('{');
+ break;
+
+ case Token.RC: {
+ --braceNesting;
+ /* don't print the closing RC if it closes the
+ * toplevel function and we're called from
+ * decompileFunctionBody.
+ */
+ if (justFunctionBody && braceNesting == 0)
+ break;
+
+ result.append('}');
+ switch (getNext(source, length, i)) {
+ case Token.EOL:
+ case FUNCTION_END:
+ indent -= indentGap;
+ break;
+ case Token.WHILE:
+ case Token.ELSE:
+ indent -= indentGap;
+ result.append(' ');
+ break;
+ }
+ break;
+ }
+ case Token.LP:
+ result.append('(');
+ break;
+
+ case Token.RP:
+ result.append(')');
+ if (Token.LC == getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.LB:
+ result.append('[');
+ break;
+
+ case Token.RB:
+ result.append(']');
+ break;
+
+ case Token.EOL: {
+ if (toSource) break;
+ boolean newLine = true;
+ if (!afterFirstEOL) {
+ afterFirstEOL = true;
+ if (justFunctionBody) {
+ /* throw away just added 'function name(...) {'
+ * and restore the original indent
+ */
+ result.setLength(0);
+ indent -= indentGap;
+ newLine = false;
+ }
+ }
+ if (newLine) {
+ result.append('\n');
+ }
+
+ /* add indent if any tokens remain,
+ * less setback if next token is
+ * a label, case or default.
+ */
+ if (i + 1 < length) {
+ int less = 0;
+ int nextToken = source.charAt(i + 1);
+ if (nextToken == Token.CASE
+ || nextToken == Token.DEFAULT)
+ {
+ less = indentGap - caseGap;
+ } else if (nextToken == Token.RC) {
+ less = indentGap;
+ }
+
+ /* elaborate check against label... skip past a
+ * following inlined NAME and look for a COLON.
+ */
+ else if (nextToken == Token.NAME) {
+ int afterName = getSourceStringEnd(source, i + 2);
+ if (source.charAt(afterName) == Token.COLON)
+ less = indentGap;
+ }
+
+ for (; less < indent; less++)
+ result.append(' ');
+ }
+ break;
+ }
+ case Token.DOT:
+ result.append('.');
+ break;
+
+ case Token.NEW:
+ result.append("new ");
+ break;
+
+ case Token.DELPROP:
+ result.append("delete ");
+ break;
+
+ case Token.IF:
+ result.append("if ");
+ break;
+
+ case Token.ELSE:
+ result.append("else ");
+ break;
+
+ case Token.FOR:
+ result.append("for ");
+ break;
+
+ case Token.IN:
+ result.append(" in ");
+ break;
+
+ case Token.WITH:
+ result.append("with ");
+ break;
+
+ case Token.WHILE:
+ result.append("while ");
+ break;
+
+ case Token.DO:
+ result.append("do ");
+ break;
+
+ case Token.TRY:
+ result.append("try ");
+ break;
+
+ case Token.CATCH:
+ result.append("catch ");
+ break;
+
+ case Token.FINALLY:
+ result.append("finally ");
+ break;
+
+ case Token.THROW:
+ result.append("throw ");
+ break;
+
+ case Token.SWITCH:
+ result.append("switch ");
+ break;
+
+ case Token.BREAK:
+ result.append("break");
+ if (Token.NAME == getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.CONTINUE:
+ result.append("continue");
+ if (Token.NAME == getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.CASE:
+ result.append("case ");
+ break;
+
+ case Token.DEFAULT:
+ result.append("default");
+ break;
+
+ case Token.RETURN:
+ result.append("return");
+ if (Token.SEMI != getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.VAR:
+ result.append("var ");
+ break;
+
+ case Token.SEMI:
+ result.append(';');
+ if (Token.EOL != getNext(source, length, i)) {
+ // separators in FOR
+ result.append(' ');
+ }
+ break;
+
+ case Token.ASSIGN:
+ result.append(" = ");
+ break;
+
+ case Token.ASSIGN_ADD:
+ result.append(" += ");
+ break;
+
+ case Token.ASSIGN_SUB:
+ result.append(" -= ");
+ break;
+
+ case Token.ASSIGN_MUL:
+ result.append(" *= ");
+ break;
+
+ case Token.ASSIGN_DIV:
+ result.append(" /= ");
+ break;
+
+ case Token.ASSIGN_MOD:
+ result.append(" %= ");
+ break;
+
+ case Token.ASSIGN_BITOR:
+ result.append(" |= ");
+ break;
+
+ case Token.ASSIGN_BITXOR:
+ result.append(" ^= ");
+ break;
+
+ case Token.ASSIGN_BITAND:
+ result.append(" &= ");
+ break;
+
+ case Token.ASSIGN_LSH:
+ result.append(" <<= ");
+ break;
+
+ case Token.ASSIGN_RSH:
+ result.append(" >>= ");
+ break;
+
+ case Token.ASSIGN_URSH:
+ result.append(" >>>= ");
+ break;
+
+ case Token.HOOK:
+ result.append(" ? ");
+ break;
+
+ case Token.OBJECTLIT:
+ // pun OBJECTLIT to mean colon in objlit property
+ // initialization.
+ // This needs to be distinct from COLON in the general case
+ // to distinguish from the colon in a ternary... which needs
+ // different spacing.
+ result.append(':');
+ break;
+
+ case Token.COLON:
+ if (Token.EOL == getNext(source, length, i))
+ // it's the end of a label
+ result.append(':');
+ else
+ // it's the middle part of a ternary
+ result.append(" : ");
+ break;
+
+ case Token.OR:
+ result.append(" || ");
+ break;
+
+ case Token.AND:
+ result.append(" && ");
+ break;
+
+ case Token.BITOR:
+ result.append(" | ");
+ break;
+
+ case Token.BITXOR:
+ result.append(" ^ ");
+ break;
+
+ case Token.BITAND:
+ result.append(" & ");
+ break;
+
+ case Token.SHEQ:
+ result.append(" === ");
+ break;
+
+ case Token.SHNE:
+ result.append(" !== ");
+ break;
+
+ case Token.EQ:
+ result.append(" == ");
+ break;
+
+ case Token.NE:
+ result.append(" != ");
+ break;
+
+ case Token.LE:
+ result.append(" <= ");
+ break;
+
+ case Token.LT:
+ result.append(" < ");
+ break;
+
+ case Token.GE:
+ result.append(" >= ");
+ break;
+
+ case Token.GT:
+ result.append(" > ");
+ break;
+
+ case Token.INSTANCEOF:
+ result.append(" instanceof ");
+ break;
+
+ case Token.LSH:
+ result.append(" << ");
+ break;
+
+ case Token.RSH:
+ result.append(" >> ");
+ break;
+
+ case Token.URSH:
+ result.append(" >>> ");
+ break;
+
+ case Token.TYPEOF:
+ result.append("typeof ");
+ break;
+
+ case Token.VOID:
+ result.append("void ");
+ break;
+
+ case Token.CONST:
+ result.append("const ");
+ break;
+
+ case Token.NOT:
+ result.append('!');
+ break;
+
+ case Token.BITNOT:
+ result.append('~');
+ break;
+
+ case Token.POS:
+ result.append('+');
+ break;
+
+ case Token.NEG:
+ result.append('-');
+ break;
+
+ case Token.INC:
+ result.append("++");
+ break;
+
+ case Token.DEC:
+ result.append("--");
+ break;
+
+ case Token.ADD:
+ result.append(" + ");
+ break;
+
+ case Token.SUB:
+ result.append(" - ");
+ break;
+
+ case Token.MUL:
+ result.append(" * ");
+ break;
+
+ case Token.DIV:
+ result.append(" / ");
+ break;
+
+ case Token.MOD:
+ result.append(" % ");
+ break;
+
+ case Token.COLONCOLON:
+ result.append("::");
+ break;
+
+ case Token.DOTDOT:
+ result.append("..");
+ break;
+
+ case Token.DOTQUERY:
+ result.append(".(");
+ break;
+
+ case Token.XMLATTR:
+ result.append('@');
+ break;
+
+ default:
+ // If we don't know how to decompile it, raise an exception.
+ throw new RuntimeException("Token: " +
+ Token.name(source.charAt(i)));
+ }
+ ++i;
+ }
+
+ if (!toSource) {
+ // add that trailing newline if it's an outermost function.
+ if (!justFunctionBody)
+ result.append('\n');
+ } else {
+ if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) {
+ result.append(')');
+ }
+ }
+
+ return result.toString();
+ }
+
+ private static int getNext(String source, int length, int i)
+ {
+ return (i + 1 < length) ? source.charAt(i + 1) : Token.EOF;
+ }
+
+ private static int getSourceStringEnd(String source, int offset)
+ {
+ return printSourceString(source, offset, false, null);
+ }
+
+ private static int printSourceString(String source, int offset,
+ boolean asQuotedString,
+ StringBuffer sb)
+ {
+ int length = source.charAt(offset);
+ ++offset;
+ if ((0x8000 & length) != 0) {
+ length = ((0x7FFF & length) << 16) | source.charAt(offset);
+ ++offset;
+ }
+ if (sb != null) {
+ String str = source.substring(offset, offset + length);
+ if (!asQuotedString) {
+ sb.append(str);
+ } else {
+ sb.append('"');
+ sb.append(ScriptRuntime.escapeString(str));
+ sb.append('"');
+ }
+ }
+ return offset + length;
+ }
+
+ private static int printSourceNumber(String source, int offset,
+ StringBuffer sb)
+ {
+ double number = 0.0;
+ char type = source.charAt(offset);
+ ++offset;
+ if (type == 'S') {
+ if (sb != null) {
+ int ival = source.charAt(offset);
+ number = ival;
+ }
+ ++offset;
+ } else if (type == 'J' || type == 'D') {
+ if (sb != null) {
+ long lbits;
+ lbits = (long)source.charAt(offset) << 48;
+ lbits |= (long)source.charAt(offset + 1) << 32;
+ lbits |= (long)source.charAt(offset + 2) << 16;
+ lbits |= source.charAt(offset + 3);
+ if (type == 'J') {
+ number = lbits;
+ } else {
+ number = Double.longBitsToDouble(lbits);
+ }
+ }
+ offset += 4;
+ } else {
+ // Bad source
+ throw new RuntimeException();
+ }
+ if (sb != null) {
+ sb.append(ScriptRuntime.numberToString(number, 10));
+ }
+ return offset;
+ }
+
+ private char[] sourceBuffer = new char[128];
+
+// Per script/function source buffer top: parent source does not include a
+// nested functions source and uses function index as a reference instead.
+ private int sourceTop;
+
+// whether to do a debug print of the source information, when decompiling.
+ private static final boolean printSource = false;
+
+}
diff --git a/yuicompressor-2.4.2/src/org/mozilla/javascript/Parser.java b/yuicompressor-2.4.2/src/org/mozilla/javascript/Parser.java
new file mode 100644
index 00000000..9acfab20
--- /dev/null
+++ b/yuicompressor-2.4.2/src/org/mozilla/javascript/Parser.java
@@ -0,0 +1,2178 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Ang
+ * Igor Bukanov
+ * Yuh-Ruey Chen
+ * Ethan Hugg
+ * Bob Jervis
+ * Terry Lucas
+ * Mike McCabe
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.Reader;
+import java.io.IOException;
+import java.util.Hashtable;
+
+/**
+ * This class implements the JavaScript parser.
+ *
+ * It is based on the C source files jsparse.c and jsparse.h
+ * in the jsref package.
+ *
+ * @see TokenStream
+ *
+ * @author Mike McCabe
+ * @author Brendan Eich
+ */
+
+public class Parser
+{
+ // TokenInformation flags : currentFlaggedToken stores them together
+ // with token type
+ final static int
+ CLEAR_TI_MASK = 0xFFFF, // mask to clear token information bits
+ TI_AFTER_EOL = 1 << 16, // first token of the source line
+ TI_CHECK_LABEL = 1 << 17; // indicates to check for label
+
+ CompilerEnvirons compilerEnv;
+ private ErrorReporter errorReporter;
+ private String sourceURI;
+ boolean calledByCompileFunction;
+
+ private TokenStream ts;
+ private int currentFlaggedToken;
+ private int syntaxErrorCount;
+
+ private IRFactory nf;
+
+ private int nestingOfFunction;
+
+ private Decompiler decompiler;
+ private String encodedSource;
+
+// The following are per function variables and should be saved/restored
+// during function parsing.
+// XXX Move to separated class?
+ ScriptOrFnNode currentScriptOrFn;
+ private int nestingOfWith;
+ private Hashtable labelSet; // map of label names into nodes
+ private ObjArray loopSet;
+ private ObjArray loopAndSwitchSet;
+ private boolean hasReturnValue;
+ private int functionEndFlags;
+// end of per function variables
+
+ // Exception to unwind
+ private static class ParserException extends RuntimeException
+ {
+ static final long serialVersionUID = 5882582646773765630L;
+ }
+
+ public Parser(CompilerEnvirons compilerEnv, ErrorReporter errorReporter)
+ {
+ this.compilerEnv = compilerEnv;
+ this.errorReporter = errorReporter;
+ }
+
+ protected Decompiler createDecompiler(CompilerEnvirons compilerEnv)
+ {
+ return new Decompiler();
+ }
+
+ void addStrictWarning(String messageId, String messageArg)
+ {
+ if (compilerEnv.isStrictMode())
+ addWarning(messageId, messageArg);
+ }
+
+ void addWarning(String messageId, String messageArg)
+ {
+ String message = ScriptRuntime.getMessage1(messageId, messageArg);
+ if (compilerEnv.reportWarningAsError()) {
+ ++syntaxErrorCount;
+ errorReporter.error(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ } else
+ errorReporter.warning(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ void addError(String messageId)
+ {
+ ++syntaxErrorCount;
+ String message = ScriptRuntime.getMessage0(messageId);
+ errorReporter.error(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ void addError(String messageId, String messageArg)
+ {
+ ++syntaxErrorCount;
+ String message = ScriptRuntime.getMessage1(messageId, messageArg);
+ errorReporter.error(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ RuntimeException reportError(String messageId)
+ {
+ addError(messageId);
+
+ // Throw a ParserException exception to unwind the recursive descent
+ // parse.
+ throw new ParserException();
+ }
+
+ private int peekToken()
+ throws IOException
+ {
+ int tt = currentFlaggedToken;
+ if (tt == Token.EOF) {
+
+ while ((tt = ts.getToken()) == Token.CONDCOMMENT || tt == Token.KEEPCOMMENT) {
+ if (tt == Token.CONDCOMMENT) {
+ /* Support for JScript conditional comments */
+ decompiler.addJScriptConditionalComment(ts.getString());
+ } else {
+ /* Support for preserved comments */
+ decompiler.addPreservedComment(ts.getString());
+ }
+ }
+
+ if (tt == Token.EOL) {
+ do {
+ tt = ts.getToken();
+
+ if (tt == Token.CONDCOMMENT) {
+ /* Support for JScript conditional comments */
+ decompiler.addJScriptConditionalComment(ts.getString());
+ } else if (tt == Token.KEEPCOMMENT) {
+ /* Support for preserved comments */
+ decompiler.addPreservedComment(ts.getString());
+ }
+
+ } while (tt == Token.EOL || tt == Token.CONDCOMMENT || tt == Token.KEEPCOMMENT);
+ tt |= TI_AFTER_EOL;
+ }
+ currentFlaggedToken = tt;
+ }
+ return tt & CLEAR_TI_MASK;
+ }
+
+ private int peekFlaggedToken()
+ throws IOException
+ {
+ peekToken();
+ return currentFlaggedToken;
+ }
+
+ private void consumeToken()
+ {
+ currentFlaggedToken = Token.EOF;
+ }
+
+ private int nextToken()
+ throws IOException
+ {
+ int tt = peekToken();
+ consumeToken();
+ return tt;
+ }
+
+ private int nextFlaggedToken()
+ throws IOException
+ {
+ peekToken();
+ int ttFlagged = currentFlaggedToken;
+ consumeToken();
+ return ttFlagged;
+ }
+
+ private boolean matchToken(int toMatch)
+ throws IOException
+ {
+ int tt = peekToken();
+ if (tt != toMatch) {
+ return false;
+ }
+ consumeToken();
+ return true;
+ }
+
+ private int peekTokenOrEOL()
+ throws IOException
+ {
+ int tt = peekToken();
+ // Check for last peeked token flags
+ if ((currentFlaggedToken & TI_AFTER_EOL) != 0) {
+ tt = Token.EOL;
+ }
+ return tt;
+ }
+
+ private void setCheckForLabel()
+ {
+ if ((currentFlaggedToken & CLEAR_TI_MASK) != Token.NAME)
+ throw Kit.codeBug();
+ currentFlaggedToken |= TI_CHECK_LABEL;
+ }
+
+ private void mustMatchToken(int toMatch, String messageId)
+ throws IOException, ParserException
+ {
+ if (!matchToken(toMatch)) {
+ reportError(messageId);
+ }
+ }
+
+ private void mustHaveXML()
+ {
+ if (!compilerEnv.isXmlAvailable()) {
+ reportError("msg.XML.not.available");
+ }
+ }
+
+ public String getEncodedSource()
+ {
+ return encodedSource;
+ }
+
+ public boolean eof()
+ {
+ return ts.eof();
+ }
+
+ boolean insideFunction()
+ {
+ return nestingOfFunction != 0;
+ }
+
+ private Node enterLoop(Node loopLabel)
+ {
+ Node loop = nf.createLoopNode(loopLabel, ts.getLineno());
+ if (loopSet == null) {
+ loopSet = new ObjArray();
+ if (loopAndSwitchSet == null) {
+ loopAndSwitchSet = new ObjArray();
+ }
+ }
+ loopSet.push(loop);
+ loopAndSwitchSet.push(loop);
+ return loop;
+ }
+
+ private void exitLoop()
+ {
+ loopSet.pop();
+ loopAndSwitchSet.pop();
+ }
+
+ private Node enterSwitch(Node switchSelector, int lineno)
+ {
+ Node switchNode = nf.createSwitch(switchSelector, lineno);
+ if (loopAndSwitchSet == null) {
+ loopAndSwitchSet = new ObjArray();
+ }
+ loopAndSwitchSet.push(switchNode);
+ return switchNode;
+ }
+
+ private void exitSwitch()
+ {
+ loopAndSwitchSet.pop();
+ }
+
+ /*
+ * Build a parse tree from the given sourceString.
+ *
+ * @return an Object representing the parsed
+ * program. If the parse fails, null will be returned. (The
+ * parse failure will result in a call to the ErrorReporter from
+ * CompilerEnvirons.)
+ */
+ public ScriptOrFnNode parse(String sourceString,
+ String sourceURI, int lineno)
+ {
+ this.sourceURI = sourceURI;
+ this.ts = new TokenStream(this, null, sourceString, lineno);
+ try {
+ return parse();
+ } catch (IOException ex) {
+ // Should never happen
+ throw new IllegalStateException();
+ }
+ }
+
+ /*
+ * Build a parse tree from the given sourceString.
+ *
+ * @return an Object representing the parsed
+ * program. If the parse fails, null will be returned. (The
+ * parse failure will result in a call to the ErrorReporter from
+ * CompilerEnvirons.)
+ */
+ public ScriptOrFnNode parse(Reader sourceReader,
+ String sourceURI, int lineno)
+ throws IOException
+ {
+ this.sourceURI = sourceURI;
+ this.ts = new TokenStream(this, sourceReader, null, lineno);
+ return parse();
+ }
+
+ private ScriptOrFnNode parse()
+ throws IOException
+ {
+ this.decompiler = createDecompiler(compilerEnv);
+ this.nf = new IRFactory(this);
+ currentScriptOrFn = nf.createScript();
+ int sourceStartOffset = decompiler.getCurrentOffset();
+ this.encodedSource = null;
+ decompiler.addToken(Token.SCRIPT);
+
+ this.currentFlaggedToken = Token.EOF;
+ this.syntaxErrorCount = 0;
+
+ int baseLineno = ts.getLineno(); // line number where source starts
+
+ /* so we have something to add nodes to until
+ * we've collected all the source */
+ Node pn = nf.createLeaf(Token.BLOCK);
+
+ try {
+ for (;;) {
+ int tt = peekToken();
+
+ if (tt <= Token.EOF) {
+ break;
+ }
+
+ Node n;
+ if (tt == Token.FUNCTION) {
+ consumeToken();
+ try {
+ n = function(calledByCompileFunction
+ ? FunctionNode.FUNCTION_EXPRESSION
+ : FunctionNode.FUNCTION_STATEMENT);
+ } catch (ParserException e) {
+ break;
+ }
+ } else {
+ n = statement();
+ }
+ nf.addChildToBack(pn, n);
+ }
+ } catch (StackOverflowError ex) {
+ String msg = ScriptRuntime.getMessage0(
+ "msg.too.deep.parser.recursion");
+ throw Context.reportRuntimeError(msg, sourceURI,
+ ts.getLineno(), null, 0);
+ }
+
+ if (this.syntaxErrorCount != 0) {
+ String msg = String.valueOf(this.syntaxErrorCount);
+ msg = ScriptRuntime.getMessage1("msg.got.syntax.errors", msg);
+ throw errorReporter.runtimeError(msg, sourceURI, baseLineno,
+ null, 0);
+ }
+
+ currentScriptOrFn.setSourceName(sourceURI);
+ currentScriptOrFn.setBaseLineno(baseLineno);
+ currentScriptOrFn.setEndLineno(ts.getLineno());
+
+ int sourceEndOffset = decompiler.getCurrentOffset();
+ currentScriptOrFn.setEncodedSourceBounds(sourceStartOffset,
+ sourceEndOffset);
+
+ nf.initScript(currentScriptOrFn, pn);
+
+ if (compilerEnv.isGeneratingSource()) {
+ encodedSource = decompiler.getEncodedSource();
+ }
+ this.decompiler = null; // It helps GC
+
+ return currentScriptOrFn;
+ }
+
+ /*
+ * The C version of this function takes an argument list,
+ * which doesn't seem to be needed for tree generation...
+ * it'd only be useful for checking argument hiding, which
+ * I'm not doing anyway...
+ */
+ private Node parseFunctionBody()
+ throws IOException
+ {
+ ++nestingOfFunction;
+ Node pn = nf.createBlock(ts.getLineno());
+ try {
+ bodyLoop: for (;;) {
+ Node n;
+ int tt = peekToken();
+ switch (tt) {
+ case Token.ERROR:
+ case Token.EOF:
+ case Token.RC:
+ break bodyLoop;
+
+ case Token.FUNCTION:
+ consumeToken();
+ n = function(FunctionNode.FUNCTION_STATEMENT);
+ break;
+ default:
+ n = statement();
+ break;
+ }
+ nf.addChildToBack(pn, n);
+ }
+ } catch (ParserException e) {
+ // Ignore it
+ } finally {
+ --nestingOfFunction;
+ }
+
+ return pn;
+ }
+
+ private Node function(int functionType)
+ throws IOException, ParserException
+ {
+ int syntheticType = functionType;
+ int baseLineno = ts.getLineno(); // line number where source starts
+
+ int functionSourceStart = decompiler.markFunctionStart(functionType);
+ String name;
+ Node memberExprNode = null;
+ if (matchToken(Token.NAME)) {
+ name = ts.getString();
+ decompiler.addName(name);
+ if (!matchToken(Token.LP)) {
+ if (compilerEnv.isAllowMemberExprAsFunctionName()) {
+ // Extension to ECMA: if 'function ' does not follow
+ // by '(', assume starts memberExpr
+ Node memberExprHead = nf.createName(name);
+ name = "";
+ memberExprNode = memberExprTail(false, memberExprHead);
+ }
+ mustMatchToken(Token.LP, "msg.no.paren.parms");
+ }
+ } else if (matchToken(Token.LP)) {
+ // Anonymous function
+ name = "";
+ } else {
+ name = "";
+ if (compilerEnv.isAllowMemberExprAsFunctionName()) {
+ // Note that memberExpr can not start with '(' like
+ // in function (1+2).toString(), because 'function (' already
+ // processed as anonymous function
+ memberExprNode = memberExpr(false);
+ }
+ mustMatchToken(Token.LP, "msg.no.paren.parms");
+ }
+
+ if (memberExprNode != null) {
+ syntheticType = FunctionNode.FUNCTION_EXPRESSION;
+ }
+
+ boolean nested = insideFunction();
+
+ FunctionNode fnNode = nf.createFunction(name);
+ if (nested || nestingOfWith > 0) {
+ // 1. Nested functions are not affected by the dynamic scope flag
+ // as dynamic scope is already a parent of their scope.
+ // 2. Functions defined under the with statement also immune to
+ // this setup, in which case dynamic scope is ignored in favor
+ // of with object.
+ fnNode.itsIgnoreDynamicScope = true;
+ }
+
+ int functionIndex = currentScriptOrFn.addFunction(fnNode);
+
+ int functionSourceEnd;
+
+ ScriptOrFnNode savedScriptOrFn = currentScriptOrFn;
+ currentScriptOrFn = fnNode;
+ int savedNestingOfWith = nestingOfWith;
+ nestingOfWith = 0;
+ Hashtable savedLabelSet = labelSet;
+ labelSet = null;
+ ObjArray savedLoopSet = loopSet;
+ loopSet = null;
+ ObjArray savedLoopAndSwitchSet = loopAndSwitchSet;
+ loopAndSwitchSet = null;
+ boolean savedHasReturnValue = hasReturnValue;
+ int savedFunctionEndFlags = functionEndFlags;
+
+ Node body;
+ try {
+ decompiler.addToken(Token.LP);
+ if (!matchToken(Token.RP)) {
+ boolean first = true;
+ do {
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ first = false;
+ mustMatchToken(Token.NAME, "msg.no.parm");
+ String s = ts.getString();
+ if (fnNode.hasParamOrVar(s)) {
+ addWarning("msg.dup.parms", s);
+ }
+ fnNode.addParam(s);
+ decompiler.addName(s);
+ } while (matchToken(Token.COMMA));
+
+ mustMatchToken(Token.RP, "msg.no.paren.after.parms");
+ }
+ decompiler.addToken(Token.RP);
+
+ mustMatchToken(Token.LC, "msg.no.brace.body");
+ decompiler.addEOL(Token.LC);
+ body = parseFunctionBody();
+ mustMatchToken(Token.RC, "msg.no.brace.after.body");
+
+ if (compilerEnv.isStrictMode() && !body.hasConsistentReturnUsage())
+ {
+ String msg = name.length() > 0 ? "msg.no.return.value"
+ : "msg.anon.no.return.value";
+ addStrictWarning(msg, name);
+ }
+
+ decompiler.addToken(Token.RC);
+ functionSourceEnd = decompiler.markFunctionEnd(functionSourceStart);
+ if (functionType != FunctionNode.FUNCTION_EXPRESSION) {
+ // Add EOL only if function is not part of expression
+ // since it gets SEMI + EOL from Statement in that case
+ decompiler.addToken(Token.EOL);
+ }
+ }
+ finally {
+ hasReturnValue = savedHasReturnValue;
+ functionEndFlags = savedFunctionEndFlags;
+ loopAndSwitchSet = savedLoopAndSwitchSet;
+ loopSet = savedLoopSet;
+ labelSet = savedLabelSet;
+ nestingOfWith = savedNestingOfWith;
+ currentScriptOrFn = savedScriptOrFn;
+ }
+
+ fnNode.setEncodedSourceBounds(functionSourceStart, functionSourceEnd);
+ fnNode.setSourceName(sourceURI);
+ fnNode.setBaseLineno(baseLineno);
+ fnNode.setEndLineno(ts.getLineno());
+
+ if (name != null) {
+ int index = currentScriptOrFn.getParamOrVarIndex(name);
+ if (index >= 0 && index < currentScriptOrFn.getParamCount())
+ addStrictWarning("msg.var.hides.arg", name);
+ }
+
+ Node pn = nf.initFunction(fnNode, functionIndex, body, syntheticType);
+ if (memberExprNode != null) {
+ pn = nf.createAssignment(Token.ASSIGN, memberExprNode, pn);
+ if (functionType != FunctionNode.FUNCTION_EXPRESSION) {
+ // XXX check JScript behavior: should it be createExprStatement?
+ pn = nf.createExprStatementNoReturn(pn, baseLineno);
+ }
+ }
+ return pn;
+ }
+
+ private Node statements()
+ throws IOException
+ {
+ Node pn = nf.createBlock(ts.getLineno());
+
+ int tt;
+ while((tt = peekToken()) > Token.EOF && tt != Token.RC) {
+ nf.addChildToBack(pn, statement());
+ }
+
+ return pn;
+ }
+
+ private Node condition()
+ throws IOException, ParserException
+ {
+ mustMatchToken(Token.LP, "msg.no.paren.cond");
+ decompiler.addToken(Token.LP);
+ Node pn = expr(false);
+ mustMatchToken(Token.RP, "msg.no.paren.after.cond");
+ decompiler.addToken(Token.RP);
+
+ // Report strict warning on code like "if (a = 7) ...". Suppress the
+ // warning if the condition is parenthesized, like "if ((a = 7)) ...".
+ if (pn.getProp(Node.PARENTHESIZED_PROP) == null &&
+ (pn.getType() == Token.SETNAME || pn.getType() == Token.SETPROP ||
+ pn.getType() == Token.SETELEM))
+ {
+ addStrictWarning("msg.equal.as.assign", "");
+ }
+ return pn;
+ }
+
+ // match a NAME; return null if no match.
+ private Node matchJumpLabelName()
+ throws IOException, ParserException
+ {
+ Node label = null;
+
+ int tt = peekTokenOrEOL();
+ if (tt == Token.NAME) {
+ consumeToken();
+ String name = ts.getString();
+ decompiler.addName(name);
+ if (labelSet != null) {
+ label = (Node)labelSet.get(name);
+ }
+ if (label == null) {
+ reportError("msg.undef.label");
+ }
+ }
+
+ return label;
+ }
+
+ private Node statement()
+ throws IOException
+ {
+ try {
+ Node pn = statementHelper(null);
+ if (pn != null) {
+ if (compilerEnv.isStrictMode() && !pn.hasSideEffects())
+ addStrictWarning("msg.no.side.effects", "");
+ return pn;
+ }
+ } catch (ParserException e) { }
+
+ // skip to end of statement
+ int lineno = ts.getLineno();
+ guessingStatementEnd: for (;;) {
+ int tt = peekTokenOrEOL();
+ consumeToken();
+ switch (tt) {
+ case Token.ERROR:
+ case Token.EOF:
+ case Token.EOL:
+ case Token.SEMI:
+ break guessingStatementEnd;
+ }
+ }
+ return nf.createExprStatement(nf.createName("error"), lineno);
+ }
+
+ /**
+ * Whether the "catch (e: e instanceof Exception) { ... }" syntax
+ * is implemented.
+ */
+
+ private Node statementHelper(Node statementLabel)
+ throws IOException, ParserException
+ {
+ Node pn = null;
+
+ int tt;
+
+ tt = peekToken();
+
+ switch(tt) {
+ case Token.IF: {
+ consumeToken();
+
+ decompiler.addToken(Token.IF);
+ int lineno = ts.getLineno();
+ Node cond = condition();
+ decompiler.addEOL(Token.LC);
+ Node ifTrue = statement();
+ Node ifFalse = null;
+ if (matchToken(Token.ELSE)) {
+ decompiler.addToken(Token.RC);
+ decompiler.addToken(Token.ELSE);
+ decompiler.addEOL(Token.LC);
+ ifFalse = statement();
+ }
+ decompiler.addEOL(Token.RC);
+ pn = nf.createIf(cond, ifTrue, ifFalse, lineno);
+ return pn;
+ }
+
+ case Token.SWITCH: {
+ consumeToken();
+
+ decompiler.addToken(Token.SWITCH);
+ int lineno = ts.getLineno();
+ mustMatchToken(Token.LP, "msg.no.paren.switch");
+ decompiler.addToken(Token.LP);
+ pn = enterSwitch(expr(false), lineno);
+ try {
+ mustMatchToken(Token.RP, "msg.no.paren.after.switch");
+ decompiler.addToken(Token.RP);
+ mustMatchToken(Token.LC, "msg.no.brace.switch");
+ decompiler.addEOL(Token.LC);
+
+ boolean hasDefault = false;
+ switchLoop: for (;;) {
+ tt = nextToken();
+ Node caseExpression;
+ switch (tt) {
+ case Token.RC:
+ break switchLoop;
+
+ case Token.CASE:
+ decompiler.addToken(Token.CASE);
+ caseExpression = expr(false);
+ mustMatchToken(Token.COLON, "msg.no.colon.case");
+ decompiler.addEOL(Token.COLON);
+ break;
+
+ case Token.DEFAULT:
+ if (hasDefault) {
+ reportError("msg.double.switch.default");
+ }
+ decompiler.addToken(Token.DEFAULT);
+ hasDefault = true;
+ caseExpression = null;
+ mustMatchToken(Token.COLON, "msg.no.colon.case");
+ decompiler.addEOL(Token.COLON);
+ break;
+
+ default:
+ reportError("msg.bad.switch");
+ break switchLoop;
+ }
+
+ Node block = nf.createLeaf(Token.BLOCK);
+ while ((tt = peekToken()) != Token.RC
+ && tt != Token.CASE
+ && tt != Token.DEFAULT
+ && tt != Token.EOF)
+ {
+ nf.addChildToBack(block, statement());
+ }
+
+ // caseExpression == null => add default lable
+ nf.addSwitchCase(pn, caseExpression, block);
+ }
+ decompiler.addEOL(Token.RC);
+ nf.closeSwitch(pn);
+ } finally {
+ exitSwitch();
+ }
+ return pn;
+ }
+
+ case Token.WHILE: {
+ consumeToken();
+ decompiler.addToken(Token.WHILE);
+
+ Node loop = enterLoop(statementLabel);
+ try {
+ Node cond = condition();
+ decompiler.addEOL(Token.LC);
+ Node body = statement();
+ decompiler.addEOL(Token.RC);
+ pn = nf.createWhile(loop, cond, body);
+ } finally {
+ exitLoop();
+ }
+ return pn;
+ }
+
+ case Token.DO: {
+ consumeToken();
+ decompiler.addToken(Token.DO);
+ decompiler.addEOL(Token.LC);
+
+ Node loop = enterLoop(statementLabel);
+ try {
+ Node body = statement();
+ decompiler.addToken(Token.RC);
+ mustMatchToken(Token.WHILE, "msg.no.while.do");
+ decompiler.addToken(Token.WHILE);
+ Node cond = condition();
+ pn = nf.createDoWhile(loop, body, cond);
+ } finally {
+ exitLoop();
+ }
+ // Always auto-insert semicon to follow SpiderMonkey:
+ // It is required by EMAScript but is ignored by the rest of
+ // world, see bug 238945
+ matchToken(Token.SEMI);
+ decompiler.addEOL(Token.SEMI);
+ return pn;
+ }
+
+ case Token.FOR: {
+ consumeToken();
+ boolean isForEach = false;
+ decompiler.addToken(Token.FOR);
+
+ Node loop = enterLoop(statementLabel);
+ try {
+
+ Node init; // Node init is also foo in 'foo in Object'
+ Node cond; // Node cond is also object in 'foo in Object'
+ Node incr = null; // to kill warning
+ Node body;
+
+ // See if this is a for each () instead of just a for ()
+ if (matchToken(Token.NAME)) {
+ decompiler.addName(ts.getString());
+ if (ts.getString().equals("each")) {
+ isForEach = true;
+ } else {
+ reportError("msg.no.paren.for");
+ }
+ }
+
+ mustMatchToken(Token.LP, "msg.no.paren.for");
+ decompiler.addToken(Token.LP);
+ tt = peekToken();
+ if (tt == Token.SEMI) {
+ init = nf.createLeaf(Token.EMPTY);
+ } else {
+ if (tt == Token.VAR) {
+ // set init to a var list or initial
+ consumeToken(); // consume the 'var' token
+ init = variables(Token.FOR);
+ }
+ else {
+ init = expr(true);
+ }
+ }
+
+ if (matchToken(Token.IN)) {
+ decompiler.addToken(Token.IN);
+ // 'cond' is the object over which we're iterating
+ cond = expr(false);
+ } else { // ordinary for loop
+ mustMatchToken(Token.SEMI, "msg.no.semi.for");
+ decompiler.addToken(Token.SEMI);
+ if (peekToken() == Token.SEMI) {
+ // no loop condition
+ cond = nf.createLeaf(Token.EMPTY);
+ } else {
+ cond = expr(false);
+ }
+
+ mustMatchToken(Token.SEMI, "msg.no.semi.for.cond");
+ decompiler.addToken(Token.SEMI);
+ if (peekToken() == Token.RP) {
+ incr = nf.createLeaf(Token.EMPTY);
+ } else {
+ incr = expr(false);
+ }
+ }
+
+ mustMatchToken(Token.RP, "msg.no.paren.for.ctrl");
+ decompiler.addToken(Token.RP);
+ decompiler.addEOL(Token.LC);
+ body = statement();
+ decompiler.addEOL(Token.RC);
+
+ if (incr == null) {
+ // cond could be null if 'in obj' got eaten
+ // by the init node.
+ pn = nf.createForIn(loop, init, cond, body, isForEach);
+ } else {
+ pn = nf.createFor(loop, init, cond, incr, body);
+ }
+ } finally {
+ exitLoop();
+ }
+ return pn;
+ }
+
+ case Token.TRY: {
+ consumeToken();
+ int lineno = ts.getLineno();
+
+ Node tryblock;
+ Node catchblocks = null;
+ Node finallyblock = null;
+
+ decompiler.addToken(Token.TRY);
+ decompiler.addEOL(Token.LC);
+ tryblock = statement();
+ decompiler.addEOL(Token.RC);
+
+ catchblocks = nf.createLeaf(Token.BLOCK);
+
+ boolean sawDefaultCatch = false;
+ int peek = peekToken();
+ if (peek == Token.CATCH) {
+ while (matchToken(Token.CATCH)) {
+ if (sawDefaultCatch) {
+ reportError("msg.catch.unreachable");
+ }
+ decompiler.addToken(Token.CATCH);
+ mustMatchToken(Token.LP, "msg.no.paren.catch");
+ decompiler.addToken(Token.LP);
+
+ mustMatchToken(Token.NAME, "msg.bad.catchcond");
+ String varName = ts.getString();
+ decompiler.addName(varName);
+
+ Node catchCond = null;
+ if (matchToken(Token.IF)) {
+ decompiler.addToken(Token.IF);
+ catchCond = expr(false);
+ } else {
+ sawDefaultCatch = true;
+ }
+
+ mustMatchToken(Token.RP, "msg.bad.catchcond");
+ decompiler.addToken(Token.RP);
+ mustMatchToken(Token.LC, "msg.no.brace.catchblock");
+ decompiler.addEOL(Token.LC);
+
+ nf.addChildToBack(catchblocks,
+ nf.createCatch(varName, catchCond,
+ statements(),
+ ts.getLineno()));
+
+ mustMatchToken(Token.RC, "msg.no.brace.after.body");
+ decompiler.addEOL(Token.RC);
+ }
+ } else if (peek != Token.FINALLY) {
+ mustMatchToken(Token.FINALLY, "msg.try.no.catchfinally");
+ }
+
+ if (matchToken(Token.FINALLY)) {
+ decompiler.addToken(Token.FINALLY);
+ decompiler.addEOL(Token.LC);
+ finallyblock = statement();
+ decompiler.addEOL(Token.RC);
+ }
+
+ pn = nf.createTryCatchFinally(tryblock, catchblocks,
+ finallyblock, lineno);
+
+ return pn;
+ }
+
+ case Token.THROW: {
+ consumeToken();
+ if (peekTokenOrEOL() == Token.EOL) {
+ // ECMAScript does not allow new lines before throw expression,
+ // see bug 256617
+ reportError("msg.bad.throw.eol");
+ }
+
+ int lineno = ts.getLineno();
+ decompiler.addToken(Token.THROW);
+ pn = nf.createThrow(expr(false), lineno);
+ break;
+ }
+
+ case Token.BREAK: {
+ consumeToken();
+ int lineno = ts.getLineno();
+
+ decompiler.addToken(Token.BREAK);
+
+ // matchJumpLabelName only matches if there is one
+ Node breakStatement = matchJumpLabelName();
+ if (breakStatement == null) {
+ if (loopAndSwitchSet == null || loopAndSwitchSet.size() == 0) {
+ reportError("msg.bad.break");
+ return null;
+ }
+ breakStatement = (Node)loopAndSwitchSet.peek();
+ }
+ pn = nf.createBreak(breakStatement, lineno);
+ break;
+ }
+
+ case Token.CONTINUE: {
+ consumeToken();
+ int lineno = ts.getLineno();
+
+ decompiler.addToken(Token.CONTINUE);
+
+ Node loop;
+ // matchJumpLabelName only matches if there is one
+ Node label = matchJumpLabelName();
+ if (label == null) {
+ if (loopSet == null || loopSet.size() == 0) {
+ reportError("msg.continue.outside");
+ return null;
+ }
+ loop = (Node)loopSet.peek();
+ } else {
+ loop = nf.getLabelLoop(label);
+ if (loop == null) {
+ reportError("msg.continue.nonloop");
+ return null;
+ }
+ }
+ pn = nf.createContinue(loop, lineno);
+ break;
+ }
+
+ case Token.WITH: {
+ consumeToken();
+
+ decompiler.addToken(Token.WITH);
+ int lineno = ts.getLineno();
+ mustMatchToken(Token.LP, "msg.no.paren.with");
+ decompiler.addToken(Token.LP);
+ Node obj = expr(false);
+ mustMatchToken(Token.RP, "msg.no.paren.after.with");
+ decompiler.addToken(Token.RP);
+ decompiler.addEOL(Token.LC);
+
+ ++nestingOfWith;
+ Node body;
+ try {
+ body = statement();
+ } finally {
+ --nestingOfWith;
+ }
+
+ decompiler.addEOL(Token.RC);
+
+ pn = nf.createWith(obj, body, lineno);
+ return pn;
+ }
+
+ case Token.CONST:
+ case Token.VAR: {
+ consumeToken();
+ pn = variables(tt);
+ break;
+ }
+
+ case Token.RETURN: {
+ if (!insideFunction()) {
+ reportError("msg.bad.return");
+ }
+ consumeToken();
+ decompiler.addToken(Token.RETURN);
+ int lineno = ts.getLineno();
+
+ Node retExpr;
+ /* This is ugly, but we don't want to require a semicolon. */
+ tt = peekTokenOrEOL();
+ switch (tt) {
+ case Token.SEMI:
+ case Token.RC:
+ case Token.EOF:
+ case Token.EOL:
+ case Token.ERROR:
+ retExpr = null;
+ break;
+ default:
+ retExpr = expr(false);
+ hasReturnValue = true;
+ }
+ pn = nf.createReturn(retExpr, lineno);
+
+ // see if we need a strict mode warning
+ if (retExpr == null) {
+ if (functionEndFlags == Node.END_RETURNS_VALUE)
+ addStrictWarning("msg.return.inconsistent", "");
+
+ functionEndFlags |= Node.END_RETURNS;
+ } else {
+ if (functionEndFlags == Node.END_RETURNS)
+ addStrictWarning("msg.return.inconsistent", "");
+
+ functionEndFlags |= Node.END_RETURNS_VALUE;
+ }
+
+ break;
+ }
+
+ case Token.LC:
+ consumeToken();
+ if (statementLabel != null) {
+ decompiler.addToken(Token.LC);
+ }
+ pn = statements();
+ mustMatchToken(Token.RC, "msg.no.brace.block");
+ if (statementLabel != null) {
+ decompiler.addEOL(Token.RC);
+ }
+ return pn;
+
+ case Token.ERROR:
+ // Fall thru, to have a node for error recovery to work on
+ case Token.SEMI:
+ consumeToken();
+ pn = nf.createLeaf(Token.EMPTY);
+ return pn;
+
+ case Token.FUNCTION: {
+ consumeToken();
+ pn = function(FunctionNode.FUNCTION_EXPRESSION_STATEMENT);
+ return pn;
+ }
+
+ case Token.DEFAULT :
+ consumeToken();
+ mustHaveXML();
+
+ decompiler.addToken(Token.DEFAULT);
+ int nsLine = ts.getLineno();
+
+ if (!(matchToken(Token.NAME)
+ && ts.getString().equals("xml")))
+ {
+ reportError("msg.bad.namespace");
+ }
+ decompiler.addName(" xml");
+
+ if (!(matchToken(Token.NAME)
+ && ts.getString().equals("namespace")))
+ {
+ reportError("msg.bad.namespace");
+ }
+ decompiler.addName(" namespace");
+
+ if (!matchToken(Token.ASSIGN)) {
+ reportError("msg.bad.namespace");
+ }
+ decompiler.addToken(Token.ASSIGN);
+
+ Node expr = expr(false);
+ pn = nf.createDefaultNamespace(expr, nsLine);
+ break;
+
+ case Token.NAME: {
+ int lineno = ts.getLineno();
+ String name = ts.getString();
+ setCheckForLabel();
+ pn = expr(false);
+ if (pn.getType() != Token.LABEL) {
+ pn = nf.createExprStatement(pn, lineno);
+ } else {
+ // Parsed the label: push back token should be
+ // colon that primaryExpr left untouched.
+ if (peekToken() != Token.COLON) Kit.codeBug();
+ consumeToken();
+ // depend on decompiling lookahead to guess that that
+ // last name was a label.
+ decompiler.addName(name);
+ decompiler.addEOL(Token.COLON);
+
+ if (labelSet == null) {
+ labelSet = new Hashtable();
+ } else if (labelSet.containsKey(name)) {
+ reportError("msg.dup.label");
+ }
+
+ boolean firstLabel;
+ if (statementLabel == null) {
+ firstLabel = true;
+ statementLabel = pn;
+ } else {
+ // Discard multiple label nodes and use only
+ // the first: it allows to simplify IRFactory
+ firstLabel = false;
+ }
+ labelSet.put(name, statementLabel);
+ try {
+ pn = statementHelper(statementLabel);
+ } finally {
+ labelSet.remove(name);
+ }
+ if (firstLabel) {
+ pn = nf.createLabeledStatement(statementLabel, pn);
+ }
+ return pn;
+ }
+ break;
+ }
+
+ default: {
+ int lineno = ts.getLineno();
+ pn = expr(false);
+ pn = nf.createExprStatement(pn, lineno);
+ break;
+ }
+ }
+
+ int ttFlagged = peekFlaggedToken();
+ switch (ttFlagged & CLEAR_TI_MASK) {
+ case Token.SEMI:
+ // Consume ';' as a part of expression
+ consumeToken();
+ break;
+ case Token.ERROR:
+ case Token.EOF:
+ case Token.RC:
+ // Autoinsert ;
+ break;
+ default:
+ if ((ttFlagged & TI_AFTER_EOL) == 0) {
+ // Report error if no EOL or autoinsert ; otherwise
+ reportError("msg.no.semi.stmt");
+ }
+ break;
+ }
+ decompiler.addEOL(Token.SEMI);
+
+ return pn;
+ }
+
+ /**
+ * Parse a 'var' or 'const' statement, or a 'var' init list in a for
+ * statement.
+ * @param context A token value: either VAR, CONST or FOR depending on
+ * context.
+ * @return The parsed statement
+ * @throws IOException
+ * @throws ParserException
+ */
+ private Node variables(int context)
+ throws IOException, ParserException
+ {
+ Node pn;
+ boolean first = true;
+
+ if (context == Token.CONST){
+ pn = nf.createVariables(Token.CONST, ts.getLineno());
+ decompiler.addToken(Token.CONST);
+ } else {
+ pn = nf.createVariables(Token.VAR, ts.getLineno());
+ decompiler.addToken(Token.VAR);
+ }
+
+ for (;;) {
+ Node name;
+ Node init;
+ mustMatchToken(Token.NAME, "msg.bad.var");
+ String s = ts.getString();
+
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ first = false;
+
+ decompiler.addName(s);
+
+ if (context == Token.CONST) {
+ if (!currentScriptOrFn.addConst(s)) {
+ // We know it's already defined, since addConst passes if
+ // it's not defined at all. The addVar call just confirms
+ // what it is.
+ if (currentScriptOrFn.addVar(s) != ScriptOrFnNode.DUPLICATE_CONST)
+ addError("msg.var.redecl", s);
+ else
+ addError("msg.const.redecl", s);
+ }
+ } else {
+ int dupState = currentScriptOrFn.addVar(s);
+ if (dupState == ScriptOrFnNode.DUPLICATE_CONST)
+ addError("msg.const.redecl", s);
+ else if (dupState == ScriptOrFnNode.DUPLICATE_PARAMETER)
+ addStrictWarning("msg.var.hides.arg", s);
+ else if (dupState == ScriptOrFnNode.DUPLICATE_VAR)
+ addStrictWarning("msg.var.redecl", s);
+ }
+ name = nf.createName(s);
+
+ // omitted check for argument hiding
+
+ if (matchToken(Token.ASSIGN)) {
+ decompiler.addToken(Token.ASSIGN);
+
+ init = assignExpr(context == Token.FOR);
+ nf.addChildToBack(name, init);
+ }
+ nf.addChildToBack(pn, name);
+ if (!matchToken(Token.COMMA))
+ break;
+ }
+ return pn;
+ }
+
+ private Node expr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = assignExpr(inForInit);
+ while (matchToken(Token.COMMA)) {
+ decompiler.addToken(Token.COMMA);
+ if (compilerEnv.isStrictMode() && !pn.hasSideEffects())
+ addStrictWarning("msg.no.side.effects", "");
+ pn = nf.createBinary(Token.COMMA, pn, assignExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node assignExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = condExpr(inForInit);
+
+ int tt = peekToken();
+ if (Token.FIRST_ASSIGN <= tt && tt <= Token.LAST_ASSIGN) {
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createAssignment(tt, pn, assignExpr(inForInit));
+ }
+
+ return pn;
+ }
+
+ private Node condExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = orExpr(inForInit);
+
+ if (matchToken(Token.HOOK)) {
+ decompiler.addToken(Token.HOOK);
+ Node ifTrue = assignExpr(false);
+ mustMatchToken(Token.COLON, "msg.no.colon.cond");
+ decompiler.addToken(Token.COLON);
+ Node ifFalse = assignExpr(inForInit);
+ return nf.createCondExpr(pn, ifTrue, ifFalse);
+ }
+
+ return pn;
+ }
+
+ private Node orExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = andExpr(inForInit);
+ if (matchToken(Token.OR)) {
+ decompiler.addToken(Token.OR);
+ pn = nf.createBinary(Token.OR, pn, orExpr(inForInit));
+ }
+
+ return pn;
+ }
+
+ private Node andExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = bitOrExpr(inForInit);
+ if (matchToken(Token.AND)) {
+ decompiler.addToken(Token.AND);
+ pn = nf.createBinary(Token.AND, pn, andExpr(inForInit));
+ }
+
+ return pn;
+ }
+
+ private Node bitOrExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = bitXorExpr(inForInit);
+ while (matchToken(Token.BITOR)) {
+ decompiler.addToken(Token.BITOR);
+ pn = nf.createBinary(Token.BITOR, pn, bitXorExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node bitXorExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = bitAndExpr(inForInit);
+ while (matchToken(Token.BITXOR)) {
+ decompiler.addToken(Token.BITXOR);
+ pn = nf.createBinary(Token.BITXOR, pn, bitAndExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node bitAndExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = eqExpr(inForInit);
+ while (matchToken(Token.BITAND)) {
+ decompiler.addToken(Token.BITAND);
+ pn = nf.createBinary(Token.BITAND, pn, eqExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node eqExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = relExpr(inForInit);
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.EQ:
+ case Token.NE:
+ case Token.SHEQ:
+ case Token.SHNE:
+ consumeToken();
+ int decompilerToken = tt;
+ int parseToken = tt;
+ if (compilerEnv.getLanguageVersion() == Context.VERSION_1_2) {
+ // JavaScript 1.2 uses shallow equality for == and != .
+ // In addition, convert === and !== for decompiler into
+ // == and != since the decompiler is supposed to show
+ // canonical source and in 1.2 ===, !== are allowed
+ // only as an alias to ==, !=.
+ switch (tt) {
+ case Token.EQ:
+ parseToken = Token.SHEQ;
+ break;
+ case Token.NE:
+ parseToken = Token.SHNE;
+ break;
+ case Token.SHEQ:
+ decompilerToken = Token.EQ;
+ break;
+ case Token.SHNE:
+ decompilerToken = Token.NE;
+ break;
+ }
+ }
+ decompiler.addToken(decompilerToken);
+ pn = nf.createBinary(parseToken, pn, relExpr(inForInit));
+ continue;
+ }
+ break;
+ }
+ return pn;
+ }
+
+ private Node relExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = shiftExpr();
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.IN:
+ if (inForInit)
+ break;
+ // fall through
+ case Token.INSTANCEOF:
+ case Token.LE:
+ case Token.LT:
+ case Token.GE:
+ case Token.GT:
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createBinary(tt, pn, shiftExpr());
+ continue;
+ }
+ break;
+ }
+ return pn;
+ }
+
+ private Node shiftExpr()
+ throws IOException, ParserException
+ {
+ Node pn = addExpr();
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.LSH:
+ case Token.URSH:
+ case Token.RSH:
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createBinary(tt, pn, addExpr());
+ continue;
+ }
+ break;
+ }
+ return pn;
+ }
+
+ private Node addExpr()
+ throws IOException, ParserException
+ {
+ Node pn = mulExpr();
+ for (;;) {
+ int tt = peekToken();
+ if (tt == Token.ADD || tt == Token.SUB) {
+ consumeToken();
+ decompiler.addToken(tt);
+ // flushNewLines
+ pn = nf.createBinary(tt, pn, mulExpr());
+ continue;
+ }
+ break;
+ }
+
+ return pn;
+ }
+
+ private Node mulExpr()
+ throws IOException, ParserException
+ {
+ Node pn = unaryExpr();
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.MUL:
+ case Token.DIV:
+ case Token.MOD:
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createBinary(tt, pn, unaryExpr());
+ continue;
+ }
+ break;
+ }
+
+ return pn;
+ }
+
+ private Node unaryExpr()
+ throws IOException, ParserException
+ {
+ int tt;
+
+ tt = peekToken();
+
+ switch(tt) {
+ case Token.VOID:
+ case Token.NOT:
+ case Token.BITNOT:
+ case Token.TYPEOF:
+ consumeToken();
+ decompiler.addToken(tt);
+ return nf.createUnary(tt, unaryExpr());
+
+ case Token.ADD:
+ consumeToken();
+ // Convert to special POS token in decompiler and parse tree
+ decompiler.addToken(Token.POS);
+ return nf.createUnary(Token.POS, unaryExpr());
+
+ case Token.SUB:
+ consumeToken();
+ // Convert to special NEG token in decompiler and parse tree
+ decompiler.addToken(Token.NEG);
+ return nf.createUnary(Token.NEG, unaryExpr());
+
+ case Token.INC:
+ case Token.DEC:
+ consumeToken();
+ decompiler.addToken(tt);
+ return nf.createIncDec(tt, false, memberExpr(true));
+
+ case Token.DELPROP:
+ consumeToken();
+ decompiler.addToken(Token.DELPROP);
+ return nf.createUnary(Token.DELPROP, unaryExpr());
+
+ case Token.ERROR:
+ consumeToken();
+ break;
+
+ // XML stream encountered in expression.
+ case Token.LT:
+ if (compilerEnv.isXmlAvailable()) {
+ consumeToken();
+ Node pn = xmlInitializer();
+ return memberExprTail(true, pn);
+ }
+ // Fall thru to the default handling of RELOP
+
+ default:
+ Node pn = memberExpr(true);
+
+ // Don't look across a newline boundary for a postfix incop.
+ tt = peekTokenOrEOL();
+ if (tt == Token.INC || tt == Token.DEC) {
+ consumeToken();
+ decompiler.addToken(tt);
+ return nf.createIncDec(tt, true, pn);
+ }
+ return pn;
+ }
+ return nf.createName("err"); // Only reached on error. Try to continue.
+
+ }
+
+ private Node xmlInitializer() throws IOException
+ {
+ int tt = ts.getFirstXMLToken();
+ if (tt != Token.XML && tt != Token.XMLEND) {
+ reportError("msg.syntax");
+ return null;
+ }
+
+ /* Make a NEW node to append to. */
+ Node pnXML = nf.createLeaf(Token.NEW);
+
+ String xml = ts.getString();
+ boolean fAnonymous = xml.trim().startsWith("<>");
+
+ Node pn = nf.createName(fAnonymous ? "XMLList" : "XML");
+ nf.addChildToBack(pnXML, pn);
+
+ pn = null;
+ Node expr;
+ for (;;tt = ts.getNextXMLToken()) {
+ switch (tt) {
+ case Token.XML:
+ xml = ts.getString();
+ decompiler.addName(xml);
+ mustMatchToken(Token.LC, "msg.syntax");
+ decompiler.addToken(Token.LC);
+ expr = (peekToken() == Token.RC)
+ ? nf.createString("")
+ : expr(false);
+ mustMatchToken(Token.RC, "msg.syntax");
+ decompiler.addToken(Token.RC);
+ if (pn == null) {
+ pn = nf.createString(xml);
+ } else {
+ pn = nf.createBinary(Token.ADD, pn, nf.createString(xml));
+ }
+ if (ts.isXMLAttribute()) {
+ /* Need to put the result in double quotes */
+ expr = nf.createUnary(Token.ESCXMLATTR, expr);
+ Node prepend = nf.createBinary(Token.ADD,
+ nf.createString("\""),
+ expr);
+ expr = nf.createBinary(Token.ADD,
+ prepend,
+ nf.createString("\""));
+ } else {
+ expr = nf.createUnary(Token.ESCXMLTEXT, expr);
+ }
+ pn = nf.createBinary(Token.ADD, pn, expr);
+ break;
+ case Token.XMLEND:
+ xml = ts.getString();
+ decompiler.addName(xml);
+ if (pn == null) {
+ pn = nf.createString(xml);
+ } else {
+ pn = nf.createBinary(Token.ADD, pn, nf.createString(xml));
+ }
+
+ nf.addChildToBack(pnXML, pn);
+ return pnXML;
+ default:
+ reportError("msg.syntax");
+ return null;
+ }
+ }
+ }
+
+ private void argumentList(Node listNode)
+ throws IOException, ParserException
+ {
+ boolean matched;
+ matched = matchToken(Token.RP);
+ if (!matched) {
+ boolean first = true;
+ do {
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ first = false;
+ nf.addChildToBack(listNode, assignExpr(false));
+ } while (matchToken(Token.COMMA));
+
+ mustMatchToken(Token.RP, "msg.no.paren.arg");
+ }
+ decompiler.addToken(Token.RP);
+ }
+
+ private Node memberExpr(boolean allowCallSyntax)
+ throws IOException, ParserException
+ {
+ int tt;
+
+ Node pn;
+
+ /* Check for new expressions. */
+ tt = peekToken();
+ if (tt == Token.NEW) {
+ /* Eat the NEW token. */
+ consumeToken();
+ decompiler.addToken(Token.NEW);
+
+ /* Make a NEW node to append to. */
+ pn = nf.createCallOrNew(Token.NEW, memberExpr(false));
+
+ if (matchToken(Token.LP)) {
+ decompiler.addToken(Token.LP);
+ /* Add the arguments to pn, if any are supplied. */
+ argumentList(pn);
+ }
+
+ /* XXX there's a check in the C source against
+ * "too many constructor arguments" - how many
+ * do we claim to support?
+ */
+
+ /* Experimental syntax: allow an object literal to follow a new expression,
+ * which will mean a kind of anonymous class built with the JavaAdapter.
+ * the object literal will be passed as an additional argument to the constructor.
+ */
+ tt = peekToken();
+ if (tt == Token.LC) {
+ nf.addChildToBack(pn, primaryExpr());
+ }
+ } else {
+ pn = primaryExpr();
+ }
+
+ return memberExprTail(allowCallSyntax, pn);
+ }
+
+ private Node memberExprTail(boolean allowCallSyntax, Node pn)
+ throws IOException, ParserException
+ {
+ tailLoop:
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+
+ case Token.DOT:
+ case Token.DOTDOT:
+ {
+ int memberTypeFlags;
+ String s;
+
+ consumeToken();
+ decompiler.addToken(tt);
+ memberTypeFlags = 0;
+ if (tt == Token.DOTDOT) {
+ mustHaveXML();
+ memberTypeFlags = Node.DESCENDANTS_FLAG;
+ }
+ if (!compilerEnv.isXmlAvailable()) {
+ mustMatchToken(Token.NAME, "msg.no.name.after.dot");
+ s = ts.getString();
+ decompiler.addName(s);
+ pn = nf.createPropertyGet(pn, null, s, memberTypeFlags);
+ break;
+ }
+
+ tt = nextToken();
+ switch (tt) {
+ // handles: name, ns::name, ns::*, ns::[expr]
+ case Token.NAME:
+ s = ts.getString();
+ decompiler.addName(s);
+ pn = propertyName(pn, s, memberTypeFlags);
+ break;
+
+ // handles: *, *::name, *::*, *::[expr]
+ case Token.MUL:
+ decompiler.addName("*");
+ pn = propertyName(pn, "*", memberTypeFlags);
+ break;
+
+ // handles: '@attr', '@ns::attr', '@ns::*', '@ns::*',
+ // '@::attr', '@::*', '@*', '@*::attr', '@*::*'
+ case Token.XMLATTR:
+ decompiler.addToken(Token.XMLATTR);
+ pn = attributeAccess(pn, memberTypeFlags);
+ break;
+
+ default:
+ reportError("msg.no.name.after.dot");
+ }
+ }
+ break;
+
+ case Token.DOTQUERY:
+ consumeToken();
+ mustHaveXML();
+ decompiler.addToken(Token.DOTQUERY);
+ pn = nf.createDotQuery(pn, expr(false), ts.getLineno());
+ mustMatchToken(Token.RP, "msg.no.paren");
+ decompiler.addToken(Token.RP);
+ break;
+
+ case Token.LB:
+ consumeToken();
+ decompiler.addToken(Token.LB);
+ pn = nf.createElementGet(pn, null, expr(false), 0);
+ mustMatchToken(Token.RB, "msg.no.bracket.index");
+ decompiler.addToken(Token.RB);
+ break;
+
+ case Token.LP:
+ if (!allowCallSyntax) {
+ break tailLoop;
+ }
+ consumeToken();
+ decompiler.addToken(Token.LP);
+ pn = nf.createCallOrNew(Token.CALL, pn);
+ /* Add the arguments to pn, if any are supplied. */
+ argumentList(pn);
+ break;
+
+ default:
+ break tailLoop;
+ }
+ }
+ return pn;
+ }
+
+ /*
+ * Xml attribute expression:
+ * '@attr', '@ns::attr', '@ns::*', '@ns::*', '@*', '@*::attr', '@*::*'
+ */
+ private Node attributeAccess(Node pn, int memberTypeFlags)
+ throws IOException
+ {
+ memberTypeFlags |= Node.ATTRIBUTE_FLAG;
+ int tt = nextToken();
+
+ switch (tt) {
+ // handles: @name, @ns::name, @ns::*, @ns::[expr]
+ case Token.NAME:
+ {
+ String s = ts.getString();
+ decompiler.addName(s);
+ pn = propertyName(pn, s, memberTypeFlags);
+ }
+ break;
+
+ // handles: @*, @*::name, @*::*, @*::[expr]
+ case Token.MUL:
+ decompiler.addName("*");
+ pn = propertyName(pn, "*", memberTypeFlags);
+ break;
+
+ // handles @[expr]
+ case Token.LB:
+ decompiler.addToken(Token.LB);
+ pn = nf.createElementGet(pn, null, expr(false), memberTypeFlags);
+ mustMatchToken(Token.RB, "msg.no.bracket.index");
+ decompiler.addToken(Token.RB);
+ break;
+
+ default:
+ reportError("msg.no.name.after.xmlAttr");
+ pn = nf.createPropertyGet(pn, null, "?", memberTypeFlags);
+ break;
+ }
+
+ return pn;
+ }
+
+ /**
+ * Check if :: follows name in which case it becomes qualified name
+ */
+ private Node propertyName(Node pn, String name, int memberTypeFlags)
+ throws IOException, ParserException
+ {
+ String namespace = null;
+ if (matchToken(Token.COLONCOLON)) {
+ decompiler.addToken(Token.COLONCOLON);
+ namespace = name;
+
+ int tt = nextToken();
+ switch (tt) {
+ // handles name::name
+ case Token.NAME:
+ name = ts.getString();
+ decompiler.addName(name);
+ break;
+
+ // handles name::*
+ case Token.MUL:
+ decompiler.addName("*");
+ name = "*";
+ break;
+
+ // handles name::[expr]
+ case Token.LB:
+ decompiler.addToken(Token.LB);
+ pn = nf.createElementGet(pn, namespace, expr(false),
+ memberTypeFlags);
+ mustMatchToken(Token.RB, "msg.no.bracket.index");
+ decompiler.addToken(Token.RB);
+ return pn;
+
+ default:
+ reportError("msg.no.name.after.coloncolon");
+ name = "?";
+ }
+ }
+
+ pn = nf.createPropertyGet(pn, namespace, name, memberTypeFlags);
+ return pn;
+ }
+
+ private Node primaryExpr()
+ throws IOException, ParserException
+ {
+ Node pn;
+
+ int ttFlagged = nextFlaggedToken();
+ int tt = ttFlagged & CLEAR_TI_MASK;
+
+ switch(tt) {
+
+ case Token.FUNCTION:
+ return function(FunctionNode.FUNCTION_EXPRESSION);
+
+ case Token.LB: {
+ ObjArray elems = new ObjArray();
+ int skipCount = 0;
+ decompiler.addToken(Token.LB);
+ boolean after_lb_or_comma = true;
+ for (;;) {
+ tt = peekToken();
+
+ if (tt == Token.COMMA) {
+ consumeToken();
+ decompiler.addToken(Token.COMMA);
+ if (!after_lb_or_comma) {
+ after_lb_or_comma = true;
+ } else {
+ elems.add(null);
+ ++skipCount;
+ }
+ } else if (tt == Token.RB) {
+ consumeToken();
+ decompiler.addToken(Token.RB);
+ break;
+ } else {
+ if (!after_lb_or_comma) {
+ reportError("msg.no.bracket.arg");
+ }
+ elems.add(assignExpr(false));
+ after_lb_or_comma = false;
+ }
+ }
+ return nf.createArrayLiteral(elems, skipCount);
+ }
+
+ case Token.LC: {
+ ObjArray elems = new ObjArray();
+ decompiler.addToken(Token.LC);
+ if (!matchToken(Token.RC)) {
+
+ boolean first = true;
+ commaloop:
+ do {
+ Object property;
+
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ else
+ first = false;
+
+ tt = peekToken();
+ switch(tt) {
+ case Token.NAME:
+ case Token.STRING:
+ consumeToken();
+ // map NAMEs to STRINGs in object literal context
+ // but tell the decompiler the proper type
+ String s = ts.getString();
+ if (tt == Token.NAME) {
+ if (s.equals("get") &&
+ peekToken() == Token.NAME) {
+ decompiler.addToken(Token.GET);
+ consumeToken();
+ s = ts.getString();
+ decompiler.addName(s);
+ property = ScriptRuntime.getIndexObject(s);
+ if (!getterSetterProperty(elems, property,
+ true))
+ break commaloop;
+ break;
+ } else if (s.equals("set") &&
+ peekToken() == Token.NAME) {
+ decompiler.addToken(Token.SET);
+ consumeToken();
+ s = ts.getString();
+ decompiler.addName(s);
+ property = ScriptRuntime.getIndexObject(s);
+ if (!getterSetterProperty(elems, property,
+ false))
+ break commaloop;
+ break;
+ }
+ decompiler.addName(s);
+ } else {
+ decompiler.addString(s);
+ }
+ property = ScriptRuntime.getIndexObject(s);
+ plainProperty(elems, property);
+ break;
+
+ case Token.NUMBER:
+ consumeToken();
+ double n = ts.getNumber();
+ decompiler.addNumber(n);
+ property = ScriptRuntime.getIndexObject(n);
+ plainProperty(elems, property);
+ break;
+
+ case Token.RC:
+ // trailing comma is OK.
+ break commaloop;
+ default:
+ reportError("msg.bad.prop");
+ break commaloop;
+ }
+ } while (matchToken(Token.COMMA));
+
+ mustMatchToken(Token.RC, "msg.no.brace.prop");
+ }
+ decompiler.addToken(Token.RC);
+ return nf.createObjectLiteral(elems);
+ }
+
+ case Token.LP:
+
+ /* Brendan's IR-jsparse.c makes a new node tagged with
+ * TOK_LP here... I'm not sure I understand why. Isn't
+ * the grouping already implicit in the structure of the
+ * parse tree? also TOK_LP is already overloaded (I
+ * think) in the C IR as 'function call.' */
+ decompiler.addToken(Token.LP);
+ pn = expr(false);
+ pn.putProp(Node.PARENTHESIZED_PROP, Boolean.TRUE);
+ decompiler.addToken(Token.RP);
+ mustMatchToken(Token.RP, "msg.no.paren");
+ return pn;
+
+ case Token.XMLATTR:
+ mustHaveXML();
+ decompiler.addToken(Token.XMLATTR);
+ pn = attributeAccess(null, 0);
+ return pn;
+
+ case Token.NAME: {
+ String name = ts.getString();
+ if ((ttFlagged & TI_CHECK_LABEL) != 0) {
+ if (peekToken() == Token.COLON) {
+ // Do not consume colon, it is used as unwind indicator
+ // to return to statementHelper.
+ // XXX Better way?
+ return nf.createLabel(ts.getLineno());
+ }
+ }
+
+ decompiler.addName(name);
+ if (compilerEnv.isXmlAvailable()) {
+ pn = propertyName(null, name, 0);
+ } else {
+ pn = nf.createName(name);
+ }
+ return pn;
+ }
+
+ case Token.NUMBER: {
+ double n = ts.getNumber();
+ decompiler.addNumber(n);
+ return nf.createNumber(n);
+ }
+
+ case Token.STRING: {
+ String s = ts.getString();
+ decompiler.addString(s);
+ return nf.createString(s);
+ }
+
+ case Token.DIV:
+ case Token.ASSIGN_DIV: {
+ // Got / or /= which should be treated as regexp in fact
+ ts.readRegExp(tt);
+ String flags = ts.regExpFlags;
+ ts.regExpFlags = null;
+ String re = ts.getString();
+ decompiler.addRegexp(re, flags);
+ int index = currentScriptOrFn.addRegexp(re, flags);
+ return nf.createRegExp(index);
+ }
+
+ case Token.NULL:
+ case Token.THIS:
+ case Token.FALSE:
+ case Token.TRUE:
+ decompiler.addToken(tt);
+ return nf.createLeaf(tt);
+
+ case Token.RESERVED:
+ reportError("msg.reserved.id");
+ break;
+
+ case Token.ERROR:
+ /* the scanner or one of its subroutines reported the error. */
+ break;
+
+ case Token.EOF:
+ reportError("msg.unexpected.eof");
+ break;
+
+ default:
+ reportError("msg.syntax");
+ break;
+ }
+ return null; // should never reach here
+ }
+
+ private void plainProperty(ObjArray elems, Object property)
+ throws IOException {
+ mustMatchToken(Token.COLON, "msg.no.colon.prop");
+
+ // OBJLIT is used as ':' in object literal for
+ // decompilation to solve spacing ambiguity.
+ decompiler.addToken(Token.OBJECTLIT);
+ elems.add(property);
+ elems.add(assignExpr(false));
+ }
+
+ private boolean getterSetterProperty(ObjArray elems, Object property,
+ boolean isGetter) throws IOException {
+ Node f = function(FunctionNode.FUNCTION_EXPRESSION);
+ if (f.getType() != Token.FUNCTION) {
+ reportError("msg.bad.prop");
+ return false;
+ }
+ int fnIndex = f.getExistingIntProp(Node.FUNCTION_PROP);
+ FunctionNode fn = currentScriptOrFn.getFunctionNode(fnIndex);
+ if (fn.getFunctionName().length() != 0) {
+ reportError("msg.bad.prop");
+ return false;
+ }
+ elems.add(property);
+ if (isGetter) {
+ elems.add(nf.createUnary(Token.GET, f));
+ } else {
+ elems.add(nf.createUnary(Token.SET, f));
+ }
+ return true;
+ }
+}
diff --git a/yuicompressor-2.4.2/src/org/mozilla/javascript/Parser.java.orig b/yuicompressor-2.4.2/src/org/mozilla/javascript/Parser.java.orig
new file mode 100644
index 00000000..628bb42f
--- /dev/null
+++ b/yuicompressor-2.4.2/src/org/mozilla/javascript/Parser.java.orig
@@ -0,0 +1,2159 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Ang
+ * Igor Bukanov
+ * Yuh-Ruey Chen
+ * Ethan Hugg
+ * Bob Jervis
+ * Terry Lucas
+ * Mike McCabe
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.Reader;
+import java.io.IOException;
+import java.util.Hashtable;
+
+/**
+ * This class implements the JavaScript parser.
+ *
+ * It is based on the C source files jsparse.c and jsparse.h
+ * in the jsref package.
+ *
+ * @see TokenStream
+ *
+ * @author Mike McCabe
+ * @author Brendan Eich
+ */
+
+public class Parser
+{
+ // TokenInformation flags : currentFlaggedToken stores them together
+ // with token type
+ final static int
+ CLEAR_TI_MASK = 0xFFFF, // mask to clear token information bits
+ TI_AFTER_EOL = 1 << 16, // first token of the source line
+ TI_CHECK_LABEL = 1 << 17; // indicates to check for label
+
+ CompilerEnvirons compilerEnv;
+ private ErrorReporter errorReporter;
+ private String sourceURI;
+ boolean calledByCompileFunction;
+
+ private TokenStream ts;
+ private int currentFlaggedToken;
+ private int syntaxErrorCount;
+
+ private IRFactory nf;
+
+ private int nestingOfFunction;
+
+ private Decompiler decompiler;
+ private String encodedSource;
+
+// The following are per function variables and should be saved/restored
+// during function parsing.
+// XXX Move to separated class?
+ ScriptOrFnNode currentScriptOrFn;
+ private int nestingOfWith;
+ private Hashtable labelSet; // map of label names into nodes
+ private ObjArray loopSet;
+ private ObjArray loopAndSwitchSet;
+ private boolean hasReturnValue;
+ private int functionEndFlags;
+// end of per function variables
+
+ // Exception to unwind
+ private static class ParserException extends RuntimeException
+ {
+ static final long serialVersionUID = 5882582646773765630L;
+ }
+
+ public Parser(CompilerEnvirons compilerEnv, ErrorReporter errorReporter)
+ {
+ this.compilerEnv = compilerEnv;
+ this.errorReporter = errorReporter;
+ }
+
+ protected Decompiler createDecompiler(CompilerEnvirons compilerEnv)
+ {
+ return new Decompiler();
+ }
+
+ void addStrictWarning(String messageId, String messageArg)
+ {
+ if (compilerEnv.isStrictMode())
+ addWarning(messageId, messageArg);
+ }
+
+ void addWarning(String messageId, String messageArg)
+ {
+ String message = ScriptRuntime.getMessage1(messageId, messageArg);
+ if (compilerEnv.reportWarningAsError()) {
+ ++syntaxErrorCount;
+ errorReporter.error(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ } else
+ errorReporter.warning(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ void addError(String messageId)
+ {
+ ++syntaxErrorCount;
+ String message = ScriptRuntime.getMessage0(messageId);
+ errorReporter.error(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ void addError(String messageId, String messageArg)
+ {
+ ++syntaxErrorCount;
+ String message = ScriptRuntime.getMessage1(messageId, messageArg);
+ errorReporter.error(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ RuntimeException reportError(String messageId)
+ {
+ addError(messageId);
+
+ // Throw a ParserException exception to unwind the recursive descent
+ // parse.
+ throw new ParserException();
+ }
+
+ private int peekToken()
+ throws IOException
+ {
+ int tt = currentFlaggedToken;
+ if (tt == Token.EOF) {
+ tt = ts.getToken();
+ if (tt == Token.EOL) {
+ do {
+ tt = ts.getToken();
+ } while (tt == Token.EOL);
+ tt |= TI_AFTER_EOL;
+ }
+ currentFlaggedToken = tt;
+ }
+ return tt & CLEAR_TI_MASK;
+ }
+
+ private int peekFlaggedToken()
+ throws IOException
+ {
+ peekToken();
+ return currentFlaggedToken;
+ }
+
+ private void consumeToken()
+ {
+ currentFlaggedToken = Token.EOF;
+ }
+
+ private int nextToken()
+ throws IOException
+ {
+ int tt = peekToken();
+ consumeToken();
+ return tt;
+ }
+
+ private int nextFlaggedToken()
+ throws IOException
+ {
+ peekToken();
+ int ttFlagged = currentFlaggedToken;
+ consumeToken();
+ return ttFlagged;
+ }
+
+ private boolean matchToken(int toMatch)
+ throws IOException
+ {
+ int tt = peekToken();
+ if (tt != toMatch) {
+ return false;
+ }
+ consumeToken();
+ return true;
+ }
+
+ private int peekTokenOrEOL()
+ throws IOException
+ {
+ int tt = peekToken();
+ // Check for last peeked token flags
+ if ((currentFlaggedToken & TI_AFTER_EOL) != 0) {
+ tt = Token.EOL;
+ }
+ return tt;
+ }
+
+ private void setCheckForLabel()
+ {
+ if ((currentFlaggedToken & CLEAR_TI_MASK) != Token.NAME)
+ throw Kit.codeBug();
+ currentFlaggedToken |= TI_CHECK_LABEL;
+ }
+
+ private void mustMatchToken(int toMatch, String messageId)
+ throws IOException, ParserException
+ {
+ if (!matchToken(toMatch)) {
+ reportError(messageId);
+ }
+ }
+
+ private void mustHaveXML()
+ {
+ if (!compilerEnv.isXmlAvailable()) {
+ reportError("msg.XML.not.available");
+ }
+ }
+
+ public String getEncodedSource()
+ {
+ return encodedSource;
+ }
+
+ public boolean eof()
+ {
+ return ts.eof();
+ }
+
+ boolean insideFunction()
+ {
+ return nestingOfFunction != 0;
+ }
+
+ private Node enterLoop(Node loopLabel)
+ {
+ Node loop = nf.createLoopNode(loopLabel, ts.getLineno());
+ if (loopSet == null) {
+ loopSet = new ObjArray();
+ if (loopAndSwitchSet == null) {
+ loopAndSwitchSet = new ObjArray();
+ }
+ }
+ loopSet.push(loop);
+ loopAndSwitchSet.push(loop);
+ return loop;
+ }
+
+ private void exitLoop()
+ {
+ loopSet.pop();
+ loopAndSwitchSet.pop();
+ }
+
+ private Node enterSwitch(Node switchSelector, int lineno)
+ {
+ Node switchNode = nf.createSwitch(switchSelector, lineno);
+ if (loopAndSwitchSet == null) {
+ loopAndSwitchSet = new ObjArray();
+ }
+ loopAndSwitchSet.push(switchNode);
+ return switchNode;
+ }
+
+ private void exitSwitch()
+ {
+ loopAndSwitchSet.pop();
+ }
+
+ /*
+ * Build a parse tree from the given sourceString.
+ *
+ * @return an Object representing the parsed
+ * program. If the parse fails, null will be returned. (The
+ * parse failure will result in a call to the ErrorReporter from
+ * CompilerEnvirons.)
+ */
+ public ScriptOrFnNode parse(String sourceString,
+ String sourceURI, int lineno)
+ {
+ this.sourceURI = sourceURI;
+ this.ts = new TokenStream(this, null, sourceString, lineno);
+ try {
+ return parse();
+ } catch (IOException ex) {
+ // Should never happen
+ throw new IllegalStateException();
+ }
+ }
+
+ /*
+ * Build a parse tree from the given sourceString.
+ *
+ * @return an Object representing the parsed
+ * program. If the parse fails, null will be returned. (The
+ * parse failure will result in a call to the ErrorReporter from
+ * CompilerEnvirons.)
+ */
+ public ScriptOrFnNode parse(Reader sourceReader,
+ String sourceURI, int lineno)
+ throws IOException
+ {
+ this.sourceURI = sourceURI;
+ this.ts = new TokenStream(this, sourceReader, null, lineno);
+ return parse();
+ }
+
+ private ScriptOrFnNode parse()
+ throws IOException
+ {
+ this.decompiler = createDecompiler(compilerEnv);
+ this.nf = new IRFactory(this);
+ currentScriptOrFn = nf.createScript();
+ int sourceStartOffset = decompiler.getCurrentOffset();
+ this.encodedSource = null;
+ decompiler.addToken(Token.SCRIPT);
+
+ this.currentFlaggedToken = Token.EOF;
+ this.syntaxErrorCount = 0;
+
+ int baseLineno = ts.getLineno(); // line number where source starts
+
+ /* so we have something to add nodes to until
+ * we've collected all the source */
+ Node pn = nf.createLeaf(Token.BLOCK);
+
+ try {
+ for (;;) {
+ int tt = peekToken();
+
+ if (tt <= Token.EOF) {
+ break;
+ }
+
+ Node n;
+ if (tt == Token.FUNCTION) {
+ consumeToken();
+ try {
+ n = function(calledByCompileFunction
+ ? FunctionNode.FUNCTION_EXPRESSION
+ : FunctionNode.FUNCTION_STATEMENT);
+ } catch (ParserException e) {
+ break;
+ }
+ } else {
+ n = statement();
+ }
+ nf.addChildToBack(pn, n);
+ }
+ } catch (StackOverflowError ex) {
+ String msg = ScriptRuntime.getMessage0(
+ "msg.too.deep.parser.recursion");
+ throw Context.reportRuntimeError(msg, sourceURI,
+ ts.getLineno(), null, 0);
+ }
+
+ if (this.syntaxErrorCount != 0) {
+ String msg = String.valueOf(this.syntaxErrorCount);
+ msg = ScriptRuntime.getMessage1("msg.got.syntax.errors", msg);
+ throw errorReporter.runtimeError(msg, sourceURI, baseLineno,
+ null, 0);
+ }
+
+ currentScriptOrFn.setSourceName(sourceURI);
+ currentScriptOrFn.setBaseLineno(baseLineno);
+ currentScriptOrFn.setEndLineno(ts.getLineno());
+
+ int sourceEndOffset = decompiler.getCurrentOffset();
+ currentScriptOrFn.setEncodedSourceBounds(sourceStartOffset,
+ sourceEndOffset);
+
+ nf.initScript(currentScriptOrFn, pn);
+
+ if (compilerEnv.isGeneratingSource()) {
+ encodedSource = decompiler.getEncodedSource();
+ }
+ this.decompiler = null; // It helps GC
+
+ return currentScriptOrFn;
+ }
+
+ /*
+ * The C version of this function takes an argument list,
+ * which doesn't seem to be needed for tree generation...
+ * it'd only be useful for checking argument hiding, which
+ * I'm not doing anyway...
+ */
+ private Node parseFunctionBody()
+ throws IOException
+ {
+ ++nestingOfFunction;
+ Node pn = nf.createBlock(ts.getLineno());
+ try {
+ bodyLoop: for (;;) {
+ Node n;
+ int tt = peekToken();
+ switch (tt) {
+ case Token.ERROR:
+ case Token.EOF:
+ case Token.RC:
+ break bodyLoop;
+
+ case Token.FUNCTION:
+ consumeToken();
+ n = function(FunctionNode.FUNCTION_STATEMENT);
+ break;
+ default:
+ n = statement();
+ break;
+ }
+ nf.addChildToBack(pn, n);
+ }
+ } catch (ParserException e) {
+ // Ignore it
+ } finally {
+ --nestingOfFunction;
+ }
+
+ return pn;
+ }
+
+ private Node function(int functionType)
+ throws IOException, ParserException
+ {
+ int syntheticType = functionType;
+ int baseLineno = ts.getLineno(); // line number where source starts
+
+ int functionSourceStart = decompiler.markFunctionStart(functionType);
+ String name;
+ Node memberExprNode = null;
+ if (matchToken(Token.NAME)) {
+ name = ts.getString();
+ decompiler.addName(name);
+ if (!matchToken(Token.LP)) {
+ if (compilerEnv.isAllowMemberExprAsFunctionName()) {
+ // Extension to ECMA: if 'function ' does not follow
+ // by '(', assume starts memberExpr
+ Node memberExprHead = nf.createName(name);
+ name = "";
+ memberExprNode = memberExprTail(false, memberExprHead);
+ }
+ mustMatchToken(Token.LP, "msg.no.paren.parms");
+ }
+ } else if (matchToken(Token.LP)) {
+ // Anonymous function
+ name = "";
+ } else {
+ name = "";
+ if (compilerEnv.isAllowMemberExprAsFunctionName()) {
+ // Note that memberExpr can not start with '(' like
+ // in function (1+2).toString(), because 'function (' already
+ // processed as anonymous function
+ memberExprNode = memberExpr(false);
+ }
+ mustMatchToken(Token.LP, "msg.no.paren.parms");
+ }
+
+ if (memberExprNode != null) {
+ syntheticType = FunctionNode.FUNCTION_EXPRESSION;
+ }
+
+ boolean nested = insideFunction();
+
+ FunctionNode fnNode = nf.createFunction(name);
+ if (nested || nestingOfWith > 0) {
+ // 1. Nested functions are not affected by the dynamic scope flag
+ // as dynamic scope is already a parent of their scope.
+ // 2. Functions defined under the with statement also immune to
+ // this setup, in which case dynamic scope is ignored in favor
+ // of with object.
+ fnNode.itsIgnoreDynamicScope = true;
+ }
+
+ int functionIndex = currentScriptOrFn.addFunction(fnNode);
+
+ int functionSourceEnd;
+
+ ScriptOrFnNode savedScriptOrFn = currentScriptOrFn;
+ currentScriptOrFn = fnNode;
+ int savedNestingOfWith = nestingOfWith;
+ nestingOfWith = 0;
+ Hashtable savedLabelSet = labelSet;
+ labelSet = null;
+ ObjArray savedLoopSet = loopSet;
+ loopSet = null;
+ ObjArray savedLoopAndSwitchSet = loopAndSwitchSet;
+ loopAndSwitchSet = null;
+ boolean savedHasReturnValue = hasReturnValue;
+ int savedFunctionEndFlags = functionEndFlags;
+
+ Node body;
+ try {
+ decompiler.addToken(Token.LP);
+ if (!matchToken(Token.RP)) {
+ boolean first = true;
+ do {
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ first = false;
+ mustMatchToken(Token.NAME, "msg.no.parm");
+ String s = ts.getString();
+ if (fnNode.hasParamOrVar(s)) {
+ addWarning("msg.dup.parms", s);
+ }
+ fnNode.addParam(s);
+ decompiler.addName(s);
+ } while (matchToken(Token.COMMA));
+
+ mustMatchToken(Token.RP, "msg.no.paren.after.parms");
+ }
+ decompiler.addToken(Token.RP);
+
+ mustMatchToken(Token.LC, "msg.no.brace.body");
+ decompiler.addEOL(Token.LC);
+ body = parseFunctionBody();
+ mustMatchToken(Token.RC, "msg.no.brace.after.body");
+
+ if (compilerEnv.isStrictMode() && !body.hasConsistentReturnUsage())
+ {
+ String msg = name.length() > 0 ? "msg.no.return.value"
+ : "msg.anon.no.return.value";
+ addStrictWarning(msg, name);
+ }
+
+ decompiler.addToken(Token.RC);
+ functionSourceEnd = decompiler.markFunctionEnd(functionSourceStart);
+ if (functionType != FunctionNode.FUNCTION_EXPRESSION) {
+ // Add EOL only if function is not part of expression
+ // since it gets SEMI + EOL from Statement in that case
+ decompiler.addToken(Token.EOL);
+ }
+ }
+ finally {
+ hasReturnValue = savedHasReturnValue;
+ functionEndFlags = savedFunctionEndFlags;
+ loopAndSwitchSet = savedLoopAndSwitchSet;
+ loopSet = savedLoopSet;
+ labelSet = savedLabelSet;
+ nestingOfWith = savedNestingOfWith;
+ currentScriptOrFn = savedScriptOrFn;
+ }
+
+ fnNode.setEncodedSourceBounds(functionSourceStart, functionSourceEnd);
+ fnNode.setSourceName(sourceURI);
+ fnNode.setBaseLineno(baseLineno);
+ fnNode.setEndLineno(ts.getLineno());
+
+ if (name != null) {
+ int index = currentScriptOrFn.getParamOrVarIndex(name);
+ if (index >= 0 && index < currentScriptOrFn.getParamCount())
+ addStrictWarning("msg.var.hides.arg", name);
+ }
+
+ Node pn = nf.initFunction(fnNode, functionIndex, body, syntheticType);
+ if (memberExprNode != null) {
+ pn = nf.createAssignment(Token.ASSIGN, memberExprNode, pn);
+ if (functionType != FunctionNode.FUNCTION_EXPRESSION) {
+ // XXX check JScript behavior: should it be createExprStatement?
+ pn = nf.createExprStatementNoReturn(pn, baseLineno);
+ }
+ }
+ return pn;
+ }
+
+ private Node statements()
+ throws IOException
+ {
+ Node pn = nf.createBlock(ts.getLineno());
+
+ int tt;
+ while((tt = peekToken()) > Token.EOF && tt != Token.RC) {
+ nf.addChildToBack(pn, statement());
+ }
+
+ return pn;
+ }
+
+ private Node condition()
+ throws IOException, ParserException
+ {
+ mustMatchToken(Token.LP, "msg.no.paren.cond");
+ decompiler.addToken(Token.LP);
+ Node pn = expr(false);
+ mustMatchToken(Token.RP, "msg.no.paren.after.cond");
+ decompiler.addToken(Token.RP);
+
+ // Report strict warning on code like "if (a = 7) ...". Suppress the
+ // warning if the condition is parenthesized, like "if ((a = 7)) ...".
+ if (pn.getProp(Node.PARENTHESIZED_PROP) == null &&
+ (pn.getType() == Token.SETNAME || pn.getType() == Token.SETPROP ||
+ pn.getType() == Token.SETELEM))
+ {
+ addStrictWarning("msg.equal.as.assign", "");
+ }
+ return pn;
+ }
+
+ // match a NAME; return null if no match.
+ private Node matchJumpLabelName()
+ throws IOException, ParserException
+ {
+ Node label = null;
+
+ int tt = peekTokenOrEOL();
+ if (tt == Token.NAME) {
+ consumeToken();
+ String name = ts.getString();
+ decompiler.addName(name);
+ if (labelSet != null) {
+ label = (Node)labelSet.get(name);
+ }
+ if (label == null) {
+ reportError("msg.undef.label");
+ }
+ }
+
+ return label;
+ }
+
+ private Node statement()
+ throws IOException
+ {
+ try {
+ Node pn = statementHelper(null);
+ if (pn != null) {
+ if (compilerEnv.isStrictMode() && !pn.hasSideEffects())
+ addStrictWarning("msg.no.side.effects", "");
+ return pn;
+ }
+ } catch (ParserException e) { }
+
+ // skip to end of statement
+ int lineno = ts.getLineno();
+ guessingStatementEnd: for (;;) {
+ int tt = peekTokenOrEOL();
+ consumeToken();
+ switch (tt) {
+ case Token.ERROR:
+ case Token.EOF:
+ case Token.EOL:
+ case Token.SEMI:
+ break guessingStatementEnd;
+ }
+ }
+ return nf.createExprStatement(nf.createName("error"), lineno);
+ }
+
+ /**
+ * Whether the "catch (e: e instanceof Exception) { ... }" syntax
+ * is implemented.
+ */
+
+ private Node statementHelper(Node statementLabel)
+ throws IOException, ParserException
+ {
+ Node pn = null;
+
+ int tt;
+
+ tt = peekToken();
+
+ switch(tt) {
+ case Token.IF: {
+ consumeToken();
+
+ decompiler.addToken(Token.IF);
+ int lineno = ts.getLineno();
+ Node cond = condition();
+ decompiler.addEOL(Token.LC);
+ Node ifTrue = statement();
+ Node ifFalse = null;
+ if (matchToken(Token.ELSE)) {
+ decompiler.addToken(Token.RC);
+ decompiler.addToken(Token.ELSE);
+ decompiler.addEOL(Token.LC);
+ ifFalse = statement();
+ }
+ decompiler.addEOL(Token.RC);
+ pn = nf.createIf(cond, ifTrue, ifFalse, lineno);
+ return pn;
+ }
+
+ case Token.SWITCH: {
+ consumeToken();
+
+ decompiler.addToken(Token.SWITCH);
+ int lineno = ts.getLineno();
+ mustMatchToken(Token.LP, "msg.no.paren.switch");
+ decompiler.addToken(Token.LP);
+ pn = enterSwitch(expr(false), lineno);
+ try {
+ mustMatchToken(Token.RP, "msg.no.paren.after.switch");
+ decompiler.addToken(Token.RP);
+ mustMatchToken(Token.LC, "msg.no.brace.switch");
+ decompiler.addEOL(Token.LC);
+
+ boolean hasDefault = false;
+ switchLoop: for (;;) {
+ tt = nextToken();
+ Node caseExpression;
+ switch (tt) {
+ case Token.RC:
+ break switchLoop;
+
+ case Token.CASE:
+ decompiler.addToken(Token.CASE);
+ caseExpression = expr(false);
+ mustMatchToken(Token.COLON, "msg.no.colon.case");
+ decompiler.addEOL(Token.COLON);
+ break;
+
+ case Token.DEFAULT:
+ if (hasDefault) {
+ reportError("msg.double.switch.default");
+ }
+ decompiler.addToken(Token.DEFAULT);
+ hasDefault = true;
+ caseExpression = null;
+ mustMatchToken(Token.COLON, "msg.no.colon.case");
+ decompiler.addEOL(Token.COLON);
+ break;
+
+ default:
+ reportError("msg.bad.switch");
+ break switchLoop;
+ }
+
+ Node block = nf.createLeaf(Token.BLOCK);
+ while ((tt = peekToken()) != Token.RC
+ && tt != Token.CASE
+ && tt != Token.DEFAULT
+ && tt != Token.EOF)
+ {
+ nf.addChildToBack(block, statement());
+ }
+
+ // caseExpression == null => add default lable
+ nf.addSwitchCase(pn, caseExpression, block);
+ }
+ decompiler.addEOL(Token.RC);
+ nf.closeSwitch(pn);
+ } finally {
+ exitSwitch();
+ }
+ return pn;
+ }
+
+ case Token.WHILE: {
+ consumeToken();
+ decompiler.addToken(Token.WHILE);
+
+ Node loop = enterLoop(statementLabel);
+ try {
+ Node cond = condition();
+ decompiler.addEOL(Token.LC);
+ Node body = statement();
+ decompiler.addEOL(Token.RC);
+ pn = nf.createWhile(loop, cond, body);
+ } finally {
+ exitLoop();
+ }
+ return pn;
+ }
+
+ case Token.DO: {
+ consumeToken();
+ decompiler.addToken(Token.DO);
+ decompiler.addEOL(Token.LC);
+
+ Node loop = enterLoop(statementLabel);
+ try {
+ Node body = statement();
+ decompiler.addToken(Token.RC);
+ mustMatchToken(Token.WHILE, "msg.no.while.do");
+ decompiler.addToken(Token.WHILE);
+ Node cond = condition();
+ pn = nf.createDoWhile(loop, body, cond);
+ } finally {
+ exitLoop();
+ }
+ // Always auto-insert semicon to follow SpiderMonkey:
+ // It is required by EMAScript but is ignored by the rest of
+ // world, see bug 238945
+ matchToken(Token.SEMI);
+ decompiler.addEOL(Token.SEMI);
+ return pn;
+ }
+
+ case Token.FOR: {
+ consumeToken();
+ boolean isForEach = false;
+ decompiler.addToken(Token.FOR);
+
+ Node loop = enterLoop(statementLabel);
+ try {
+
+ Node init; // Node init is also foo in 'foo in Object'
+ Node cond; // Node cond is also object in 'foo in Object'
+ Node incr = null; // to kill warning
+ Node body;
+
+ // See if this is a for each () instead of just a for ()
+ if (matchToken(Token.NAME)) {
+ decompiler.addName(ts.getString());
+ if (ts.getString().equals("each")) {
+ isForEach = true;
+ } else {
+ reportError("msg.no.paren.for");
+ }
+ }
+
+ mustMatchToken(Token.LP, "msg.no.paren.for");
+ decompiler.addToken(Token.LP);
+ tt = peekToken();
+ if (tt == Token.SEMI) {
+ init = nf.createLeaf(Token.EMPTY);
+ } else {
+ if (tt == Token.VAR) {
+ // set init to a var list or initial
+ consumeToken(); // consume the 'var' token
+ init = variables(Token.FOR);
+ }
+ else {
+ init = expr(true);
+ }
+ }
+
+ if (matchToken(Token.IN)) {
+ decompiler.addToken(Token.IN);
+ // 'cond' is the object over which we're iterating
+ cond = expr(false);
+ } else { // ordinary for loop
+ mustMatchToken(Token.SEMI, "msg.no.semi.for");
+ decompiler.addToken(Token.SEMI);
+ if (peekToken() == Token.SEMI) {
+ // no loop condition
+ cond = nf.createLeaf(Token.EMPTY);
+ } else {
+ cond = expr(false);
+ }
+
+ mustMatchToken(Token.SEMI, "msg.no.semi.for.cond");
+ decompiler.addToken(Token.SEMI);
+ if (peekToken() == Token.RP) {
+ incr = nf.createLeaf(Token.EMPTY);
+ } else {
+ incr = expr(false);
+ }
+ }
+
+ mustMatchToken(Token.RP, "msg.no.paren.for.ctrl");
+ decompiler.addToken(Token.RP);
+ decompiler.addEOL(Token.LC);
+ body = statement();
+ decompiler.addEOL(Token.RC);
+
+ if (incr == null) {
+ // cond could be null if 'in obj' got eaten
+ // by the init node.
+ pn = nf.createForIn(loop, init, cond, body, isForEach);
+ } else {
+ pn = nf.createFor(loop, init, cond, incr, body);
+ }
+ } finally {
+ exitLoop();
+ }
+ return pn;
+ }
+
+ case Token.TRY: {
+ consumeToken();
+ int lineno = ts.getLineno();
+
+ Node tryblock;
+ Node catchblocks = null;
+ Node finallyblock = null;
+
+ decompiler.addToken(Token.TRY);
+ decompiler.addEOL(Token.LC);
+ tryblock = statement();
+ decompiler.addEOL(Token.RC);
+
+ catchblocks = nf.createLeaf(Token.BLOCK);
+
+ boolean sawDefaultCatch = false;
+ int peek = peekToken();
+ if (peek == Token.CATCH) {
+ while (matchToken(Token.CATCH)) {
+ if (sawDefaultCatch) {
+ reportError("msg.catch.unreachable");
+ }
+ decompiler.addToken(Token.CATCH);
+ mustMatchToken(Token.LP, "msg.no.paren.catch");
+ decompiler.addToken(Token.LP);
+
+ mustMatchToken(Token.NAME, "msg.bad.catchcond");
+ String varName = ts.getString();
+ decompiler.addName(varName);
+
+ Node catchCond = null;
+ if (matchToken(Token.IF)) {
+ decompiler.addToken(Token.IF);
+ catchCond = expr(false);
+ } else {
+ sawDefaultCatch = true;
+ }
+
+ mustMatchToken(Token.RP, "msg.bad.catchcond");
+ decompiler.addToken(Token.RP);
+ mustMatchToken(Token.LC, "msg.no.brace.catchblock");
+ decompiler.addEOL(Token.LC);
+
+ nf.addChildToBack(catchblocks,
+ nf.createCatch(varName, catchCond,
+ statements(),
+ ts.getLineno()));
+
+ mustMatchToken(Token.RC, "msg.no.brace.after.body");
+ decompiler.addEOL(Token.RC);
+ }
+ } else if (peek != Token.FINALLY) {
+ mustMatchToken(Token.FINALLY, "msg.try.no.catchfinally");
+ }
+
+ if (matchToken(Token.FINALLY)) {
+ decompiler.addToken(Token.FINALLY);
+ decompiler.addEOL(Token.LC);
+ finallyblock = statement();
+ decompiler.addEOL(Token.RC);
+ }
+
+ pn = nf.createTryCatchFinally(tryblock, catchblocks,
+ finallyblock, lineno);
+
+ return pn;
+ }
+
+ case Token.THROW: {
+ consumeToken();
+ if (peekTokenOrEOL() == Token.EOL) {
+ // ECMAScript does not allow new lines before throw expression,
+ // see bug 256617
+ reportError("msg.bad.throw.eol");
+ }
+
+ int lineno = ts.getLineno();
+ decompiler.addToken(Token.THROW);
+ pn = nf.createThrow(expr(false), lineno);
+ break;
+ }
+
+ case Token.BREAK: {
+ consumeToken();
+ int lineno = ts.getLineno();
+
+ decompiler.addToken(Token.BREAK);
+
+ // matchJumpLabelName only matches if there is one
+ Node breakStatement = matchJumpLabelName();
+ if (breakStatement == null) {
+ if (loopAndSwitchSet == null || loopAndSwitchSet.size() == 0) {
+ reportError("msg.bad.break");
+ return null;
+ }
+ breakStatement = (Node)loopAndSwitchSet.peek();
+ }
+ pn = nf.createBreak(breakStatement, lineno);
+ break;
+ }
+
+ case Token.CONTINUE: {
+ consumeToken();
+ int lineno = ts.getLineno();
+
+ decompiler.addToken(Token.CONTINUE);
+
+ Node loop;
+ // matchJumpLabelName only matches if there is one
+ Node label = matchJumpLabelName();
+ if (label == null) {
+ if (loopSet == null || loopSet.size() == 0) {
+ reportError("msg.continue.outside");
+ return null;
+ }
+ loop = (Node)loopSet.peek();
+ } else {
+ loop = nf.getLabelLoop(label);
+ if (loop == null) {
+ reportError("msg.continue.nonloop");
+ return null;
+ }
+ }
+ pn = nf.createContinue(loop, lineno);
+ break;
+ }
+
+ case Token.WITH: {
+ consumeToken();
+
+ decompiler.addToken(Token.WITH);
+ int lineno = ts.getLineno();
+ mustMatchToken(Token.LP, "msg.no.paren.with");
+ decompiler.addToken(Token.LP);
+ Node obj = expr(false);
+ mustMatchToken(Token.RP, "msg.no.paren.after.with");
+ decompiler.addToken(Token.RP);
+ decompiler.addEOL(Token.LC);
+
+ ++nestingOfWith;
+ Node body;
+ try {
+ body = statement();
+ } finally {
+ --nestingOfWith;
+ }
+
+ decompiler.addEOL(Token.RC);
+
+ pn = nf.createWith(obj, body, lineno);
+ return pn;
+ }
+
+ case Token.CONST:
+ case Token.VAR: {
+ consumeToken();
+ pn = variables(tt);
+ break;
+ }
+
+ case Token.RETURN: {
+ if (!insideFunction()) {
+ reportError("msg.bad.return");
+ }
+ consumeToken();
+ decompiler.addToken(Token.RETURN);
+ int lineno = ts.getLineno();
+
+ Node retExpr;
+ /* This is ugly, but we don't want to require a semicolon. */
+ tt = peekTokenOrEOL();
+ switch (tt) {
+ case Token.SEMI:
+ case Token.RC:
+ case Token.EOF:
+ case Token.EOL:
+ case Token.ERROR:
+ retExpr = null;
+ break;
+ default:
+ retExpr = expr(false);
+ hasReturnValue = true;
+ }
+ pn = nf.createReturn(retExpr, lineno);
+
+ // see if we need a strict mode warning
+ if (retExpr == null) {
+ if (functionEndFlags == Node.END_RETURNS_VALUE)
+ addStrictWarning("msg.return.inconsistent", "");
+
+ functionEndFlags |= Node.END_RETURNS;
+ } else {
+ if (functionEndFlags == Node.END_RETURNS)
+ addStrictWarning("msg.return.inconsistent", "");
+
+ functionEndFlags |= Node.END_RETURNS_VALUE;
+ }
+
+ break;
+ }
+
+ case Token.LC:
+ consumeToken();
+ if (statementLabel != null) {
+ decompiler.addToken(Token.LC);
+ }
+ pn = statements();
+ mustMatchToken(Token.RC, "msg.no.brace.block");
+ if (statementLabel != null) {
+ decompiler.addEOL(Token.RC);
+ }
+ return pn;
+
+ case Token.ERROR:
+ // Fall thru, to have a node for error recovery to work on
+ case Token.SEMI:
+ consumeToken();
+ pn = nf.createLeaf(Token.EMPTY);
+ return pn;
+
+ case Token.FUNCTION: {
+ consumeToken();
+ pn = function(FunctionNode.FUNCTION_EXPRESSION_STATEMENT);
+ return pn;
+ }
+
+ case Token.DEFAULT :
+ consumeToken();
+ mustHaveXML();
+
+ decompiler.addToken(Token.DEFAULT);
+ int nsLine = ts.getLineno();
+
+ if (!(matchToken(Token.NAME)
+ && ts.getString().equals("xml")))
+ {
+ reportError("msg.bad.namespace");
+ }
+ decompiler.addName(" xml");
+
+ if (!(matchToken(Token.NAME)
+ && ts.getString().equals("namespace")))
+ {
+ reportError("msg.bad.namespace");
+ }
+ decompiler.addName(" namespace");
+
+ if (!matchToken(Token.ASSIGN)) {
+ reportError("msg.bad.namespace");
+ }
+ decompiler.addToken(Token.ASSIGN);
+
+ Node expr = expr(false);
+ pn = nf.createDefaultNamespace(expr, nsLine);
+ break;
+
+ case Token.NAME: {
+ int lineno = ts.getLineno();
+ String name = ts.getString();
+ setCheckForLabel();
+ pn = expr(false);
+ if (pn.getType() != Token.LABEL) {
+ pn = nf.createExprStatement(pn, lineno);
+ } else {
+ // Parsed the label: push back token should be
+ // colon that primaryExpr left untouched.
+ if (peekToken() != Token.COLON) Kit.codeBug();
+ consumeToken();
+ // depend on decompiling lookahead to guess that that
+ // last name was a label.
+ decompiler.addName(name);
+ decompiler.addEOL(Token.COLON);
+
+ if (labelSet == null) {
+ labelSet = new Hashtable();
+ } else if (labelSet.containsKey(name)) {
+ reportError("msg.dup.label");
+ }
+
+ boolean firstLabel;
+ if (statementLabel == null) {
+ firstLabel = true;
+ statementLabel = pn;
+ } else {
+ // Discard multiple label nodes and use only
+ // the first: it allows to simplify IRFactory
+ firstLabel = false;
+ }
+ labelSet.put(name, statementLabel);
+ try {
+ pn = statementHelper(statementLabel);
+ } finally {
+ labelSet.remove(name);
+ }
+ if (firstLabel) {
+ pn = nf.createLabeledStatement(statementLabel, pn);
+ }
+ return pn;
+ }
+ break;
+ }
+
+ default: {
+ int lineno = ts.getLineno();
+ pn = expr(false);
+ pn = nf.createExprStatement(pn, lineno);
+ break;
+ }
+ }
+
+ int ttFlagged = peekFlaggedToken();
+ switch (ttFlagged & CLEAR_TI_MASK) {
+ case Token.SEMI:
+ // Consume ';' as a part of expression
+ consumeToken();
+ break;
+ case Token.ERROR:
+ case Token.EOF:
+ case Token.RC:
+ // Autoinsert ;
+ break;
+ default:
+ if ((ttFlagged & TI_AFTER_EOL) == 0) {
+ // Report error if no EOL or autoinsert ; otherwise
+ reportError("msg.no.semi.stmt");
+ }
+ break;
+ }
+ decompiler.addEOL(Token.SEMI);
+
+ return pn;
+ }
+
+ /**
+ * Parse a 'var' or 'const' statement, or a 'var' init list in a for
+ * statement.
+ * @param context A token value: either VAR, CONST or FOR depending on
+ * context.
+ * @return The parsed statement
+ * @throws IOException
+ * @throws ParserException
+ */
+ private Node variables(int context)
+ throws IOException, ParserException
+ {
+ Node pn;
+ boolean first = true;
+
+ if (context == Token.CONST){
+ pn = nf.createVariables(Token.CONST, ts.getLineno());
+ decompiler.addToken(Token.CONST);
+ } else {
+ pn = nf.createVariables(Token.VAR, ts.getLineno());
+ decompiler.addToken(Token.VAR);
+ }
+
+ for (;;) {
+ Node name;
+ Node init;
+ mustMatchToken(Token.NAME, "msg.bad.var");
+ String s = ts.getString();
+
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ first = false;
+
+ decompiler.addName(s);
+
+ if (context == Token.CONST) {
+ if (!currentScriptOrFn.addConst(s)) {
+ // We know it's already defined, since addConst passes if
+ // it's not defined at all. The addVar call just confirms
+ // what it is.
+ if (currentScriptOrFn.addVar(s) != ScriptOrFnNode.DUPLICATE_CONST)
+ addError("msg.var.redecl", s);
+ else
+ addError("msg.const.redecl", s);
+ }
+ } else {
+ int dupState = currentScriptOrFn.addVar(s);
+ if (dupState == ScriptOrFnNode.DUPLICATE_CONST)
+ addError("msg.const.redecl", s);
+ else if (dupState == ScriptOrFnNode.DUPLICATE_PARAMETER)
+ addStrictWarning("msg.var.hides.arg", s);
+ else if (dupState == ScriptOrFnNode.DUPLICATE_VAR)
+ addStrictWarning("msg.var.redecl", s);
+ }
+ name = nf.createName(s);
+
+ // omitted check for argument hiding
+
+ if (matchToken(Token.ASSIGN)) {
+ decompiler.addToken(Token.ASSIGN);
+
+ init = assignExpr(context == Token.FOR);
+ nf.addChildToBack(name, init);
+ }
+ nf.addChildToBack(pn, name);
+ if (!matchToken(Token.COMMA))
+ break;
+ }
+ return pn;
+ }
+
+ private Node expr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = assignExpr(inForInit);
+ while (matchToken(Token.COMMA)) {
+ decompiler.addToken(Token.COMMA);
+ if (compilerEnv.isStrictMode() && !pn.hasSideEffects())
+ addStrictWarning("msg.no.side.effects", "");
+ pn = nf.createBinary(Token.COMMA, pn, assignExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node assignExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = condExpr(inForInit);
+
+ int tt = peekToken();
+ if (Token.FIRST_ASSIGN <= tt && tt <= Token.LAST_ASSIGN) {
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createAssignment(tt, pn, assignExpr(inForInit));
+ }
+
+ return pn;
+ }
+
+ private Node condExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = orExpr(inForInit);
+
+ if (matchToken(Token.HOOK)) {
+ decompiler.addToken(Token.HOOK);
+ Node ifTrue = assignExpr(false);
+ mustMatchToken(Token.COLON, "msg.no.colon.cond");
+ decompiler.addToken(Token.COLON);
+ Node ifFalse = assignExpr(inForInit);
+ return nf.createCondExpr(pn, ifTrue, ifFalse);
+ }
+
+ return pn;
+ }
+
+ private Node orExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = andExpr(inForInit);
+ if (matchToken(Token.OR)) {
+ decompiler.addToken(Token.OR);
+ pn = nf.createBinary(Token.OR, pn, orExpr(inForInit));
+ }
+
+ return pn;
+ }
+
+ private Node andExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = bitOrExpr(inForInit);
+ if (matchToken(Token.AND)) {
+ decompiler.addToken(Token.AND);
+ pn = nf.createBinary(Token.AND, pn, andExpr(inForInit));
+ }
+
+ return pn;
+ }
+
+ private Node bitOrExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = bitXorExpr(inForInit);
+ while (matchToken(Token.BITOR)) {
+ decompiler.addToken(Token.BITOR);
+ pn = nf.createBinary(Token.BITOR, pn, bitXorExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node bitXorExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = bitAndExpr(inForInit);
+ while (matchToken(Token.BITXOR)) {
+ decompiler.addToken(Token.BITXOR);
+ pn = nf.createBinary(Token.BITXOR, pn, bitAndExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node bitAndExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = eqExpr(inForInit);
+ while (matchToken(Token.BITAND)) {
+ decompiler.addToken(Token.BITAND);
+ pn = nf.createBinary(Token.BITAND, pn, eqExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node eqExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = relExpr(inForInit);
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.EQ:
+ case Token.NE:
+ case Token.SHEQ:
+ case Token.SHNE:
+ consumeToken();
+ int decompilerToken = tt;
+ int parseToken = tt;
+ if (compilerEnv.getLanguageVersion() == Context.VERSION_1_2) {
+ // JavaScript 1.2 uses shallow equality for == and != .
+ // In addition, convert === and !== for decompiler into
+ // == and != since the decompiler is supposed to show
+ // canonical source and in 1.2 ===, !== are allowed
+ // only as an alias to ==, !=.
+ switch (tt) {
+ case Token.EQ:
+ parseToken = Token.SHEQ;
+ break;
+ case Token.NE:
+ parseToken = Token.SHNE;
+ break;
+ case Token.SHEQ:
+ decompilerToken = Token.EQ;
+ break;
+ case Token.SHNE:
+ decompilerToken = Token.NE;
+ break;
+ }
+ }
+ decompiler.addToken(decompilerToken);
+ pn = nf.createBinary(parseToken, pn, relExpr(inForInit));
+ continue;
+ }
+ break;
+ }
+ return pn;
+ }
+
+ private Node relExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = shiftExpr();
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.IN:
+ if (inForInit)
+ break;
+ // fall through
+ case Token.INSTANCEOF:
+ case Token.LE:
+ case Token.LT:
+ case Token.GE:
+ case Token.GT:
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createBinary(tt, pn, shiftExpr());
+ continue;
+ }
+ break;
+ }
+ return pn;
+ }
+
+ private Node shiftExpr()
+ throws IOException, ParserException
+ {
+ Node pn = addExpr();
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.LSH:
+ case Token.URSH:
+ case Token.RSH:
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createBinary(tt, pn, addExpr());
+ continue;
+ }
+ break;
+ }
+ return pn;
+ }
+
+ private Node addExpr()
+ throws IOException, ParserException
+ {
+ Node pn = mulExpr();
+ for (;;) {
+ int tt = peekToken();
+ if (tt == Token.ADD || tt == Token.SUB) {
+ consumeToken();
+ decompiler.addToken(tt);
+ // flushNewLines
+ pn = nf.createBinary(tt, pn, mulExpr());
+ continue;
+ }
+ break;
+ }
+
+ return pn;
+ }
+
+ private Node mulExpr()
+ throws IOException, ParserException
+ {
+ Node pn = unaryExpr();
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.MUL:
+ case Token.DIV:
+ case Token.MOD:
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createBinary(tt, pn, unaryExpr());
+ continue;
+ }
+ break;
+ }
+
+ return pn;
+ }
+
+ private Node unaryExpr()
+ throws IOException, ParserException
+ {
+ int tt;
+
+ tt = peekToken();
+
+ switch(tt) {
+ case Token.VOID:
+ case Token.NOT:
+ case Token.BITNOT:
+ case Token.TYPEOF:
+ consumeToken();
+ decompiler.addToken(tt);
+ return nf.createUnary(tt, unaryExpr());
+
+ case Token.ADD:
+ consumeToken();
+ // Convert to special POS token in decompiler and parse tree
+ decompiler.addToken(Token.POS);
+ return nf.createUnary(Token.POS, unaryExpr());
+
+ case Token.SUB:
+ consumeToken();
+ // Convert to special NEG token in decompiler and parse tree
+ decompiler.addToken(Token.NEG);
+ return nf.createUnary(Token.NEG, unaryExpr());
+
+ case Token.INC:
+ case Token.DEC:
+ consumeToken();
+ decompiler.addToken(tt);
+ return nf.createIncDec(tt, false, memberExpr(true));
+
+ case Token.DELPROP:
+ consumeToken();
+ decompiler.addToken(Token.DELPROP);
+ return nf.createUnary(Token.DELPROP, unaryExpr());
+
+ case Token.ERROR:
+ consumeToken();
+ break;
+
+ // XML stream encountered in expression.
+ case Token.LT:
+ if (compilerEnv.isXmlAvailable()) {
+ consumeToken();
+ Node pn = xmlInitializer();
+ return memberExprTail(true, pn);
+ }
+ // Fall thru to the default handling of RELOP
+
+ default:
+ Node pn = memberExpr(true);
+
+ // Don't look across a newline boundary for a postfix incop.
+ tt = peekTokenOrEOL();
+ if (tt == Token.INC || tt == Token.DEC) {
+ consumeToken();
+ decompiler.addToken(tt);
+ return nf.createIncDec(tt, true, pn);
+ }
+ return pn;
+ }
+ return nf.createName("err"); // Only reached on error. Try to continue.
+
+ }
+
+ private Node xmlInitializer() throws IOException
+ {
+ int tt = ts.getFirstXMLToken();
+ if (tt != Token.XML && tt != Token.XMLEND) {
+ reportError("msg.syntax");
+ return null;
+ }
+
+ /* Make a NEW node to append to. */
+ Node pnXML = nf.createLeaf(Token.NEW);
+
+ String xml = ts.getString();
+ boolean fAnonymous = xml.trim().startsWith("<>");
+
+ Node pn = nf.createName(fAnonymous ? "XMLList" : "XML");
+ nf.addChildToBack(pnXML, pn);
+
+ pn = null;
+ Node expr;
+ for (;;tt = ts.getNextXMLToken()) {
+ switch (tt) {
+ case Token.XML:
+ xml = ts.getString();
+ decompiler.addName(xml);
+ mustMatchToken(Token.LC, "msg.syntax");
+ decompiler.addToken(Token.LC);
+ expr = (peekToken() == Token.RC)
+ ? nf.createString("")
+ : expr(false);
+ mustMatchToken(Token.RC, "msg.syntax");
+ decompiler.addToken(Token.RC);
+ if (pn == null) {
+ pn = nf.createString(xml);
+ } else {
+ pn = nf.createBinary(Token.ADD, pn, nf.createString(xml));
+ }
+ if (ts.isXMLAttribute()) {
+ /* Need to put the result in double quotes */
+ expr = nf.createUnary(Token.ESCXMLATTR, expr);
+ Node prepend = nf.createBinary(Token.ADD,
+ nf.createString("\""),
+ expr);
+ expr = nf.createBinary(Token.ADD,
+ prepend,
+ nf.createString("\""));
+ } else {
+ expr = nf.createUnary(Token.ESCXMLTEXT, expr);
+ }
+ pn = nf.createBinary(Token.ADD, pn, expr);
+ break;
+ case Token.XMLEND:
+ xml = ts.getString();
+ decompiler.addName(xml);
+ if (pn == null) {
+ pn = nf.createString(xml);
+ } else {
+ pn = nf.createBinary(Token.ADD, pn, nf.createString(xml));
+ }
+
+ nf.addChildToBack(pnXML, pn);
+ return pnXML;
+ default:
+ reportError("msg.syntax");
+ return null;
+ }
+ }
+ }
+
+ private void argumentList(Node listNode)
+ throws IOException, ParserException
+ {
+ boolean matched;
+ matched = matchToken(Token.RP);
+ if (!matched) {
+ boolean first = true;
+ do {
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ first = false;
+ nf.addChildToBack(listNode, assignExpr(false));
+ } while (matchToken(Token.COMMA));
+
+ mustMatchToken(Token.RP, "msg.no.paren.arg");
+ }
+ decompiler.addToken(Token.RP);
+ }
+
+ private Node memberExpr(boolean allowCallSyntax)
+ throws IOException, ParserException
+ {
+ int tt;
+
+ Node pn;
+
+ /* Check for new expressions. */
+ tt = peekToken();
+ if (tt == Token.NEW) {
+ /* Eat the NEW token. */
+ consumeToken();
+ decompiler.addToken(Token.NEW);
+
+ /* Make a NEW node to append to. */
+ pn = nf.createCallOrNew(Token.NEW, memberExpr(false));
+
+ if (matchToken(Token.LP)) {
+ decompiler.addToken(Token.LP);
+ /* Add the arguments to pn, if any are supplied. */
+ argumentList(pn);
+ }
+
+ /* XXX there's a check in the C source against
+ * "too many constructor arguments" - how many
+ * do we claim to support?
+ */
+
+ /* Experimental syntax: allow an object literal to follow a new expression,
+ * which will mean a kind of anonymous class built with the JavaAdapter.
+ * the object literal will be passed as an additional argument to the constructor.
+ */
+ tt = peekToken();
+ if (tt == Token.LC) {
+ nf.addChildToBack(pn, primaryExpr());
+ }
+ } else {
+ pn = primaryExpr();
+ }
+
+ return memberExprTail(allowCallSyntax, pn);
+ }
+
+ private Node memberExprTail(boolean allowCallSyntax, Node pn)
+ throws IOException, ParserException
+ {
+ tailLoop:
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+
+ case Token.DOT:
+ case Token.DOTDOT:
+ {
+ int memberTypeFlags;
+ String s;
+
+ consumeToken();
+ decompiler.addToken(tt);
+ memberTypeFlags = 0;
+ if (tt == Token.DOTDOT) {
+ mustHaveXML();
+ memberTypeFlags = Node.DESCENDANTS_FLAG;
+ }
+ if (!compilerEnv.isXmlAvailable()) {
+ mustMatchToken(Token.NAME, "msg.no.name.after.dot");
+ s = ts.getString();
+ decompiler.addName(s);
+ pn = nf.createPropertyGet(pn, null, s, memberTypeFlags);
+ break;
+ }
+
+ tt = nextToken();
+ switch (tt) {
+ // handles: name, ns::name, ns::*, ns::[expr]
+ case Token.NAME:
+ s = ts.getString();
+ decompiler.addName(s);
+ pn = propertyName(pn, s, memberTypeFlags);
+ break;
+
+ // handles: *, *::name, *::*, *::[expr]
+ case Token.MUL:
+ decompiler.addName("*");
+ pn = propertyName(pn, "*", memberTypeFlags);
+ break;
+
+ // handles: '@attr', '@ns::attr', '@ns::*', '@ns::*',
+ // '@::attr', '@::*', '@*', '@*::attr', '@*::*'
+ case Token.XMLATTR:
+ decompiler.addToken(Token.XMLATTR);
+ pn = attributeAccess(pn, memberTypeFlags);
+ break;
+
+ default:
+ reportError("msg.no.name.after.dot");
+ }
+ }
+ break;
+
+ case Token.DOTQUERY:
+ consumeToken();
+ mustHaveXML();
+ decompiler.addToken(Token.DOTQUERY);
+ pn = nf.createDotQuery(pn, expr(false), ts.getLineno());
+ mustMatchToken(Token.RP, "msg.no.paren");
+ decompiler.addToken(Token.RP);
+ break;
+
+ case Token.LB:
+ consumeToken();
+ decompiler.addToken(Token.LB);
+ pn = nf.createElementGet(pn, null, expr(false), 0);
+ mustMatchToken(Token.RB, "msg.no.bracket.index");
+ decompiler.addToken(Token.RB);
+ break;
+
+ case Token.LP:
+ if (!allowCallSyntax) {
+ break tailLoop;
+ }
+ consumeToken();
+ decompiler.addToken(Token.LP);
+ pn = nf.createCallOrNew(Token.CALL, pn);
+ /* Add the arguments to pn, if any are supplied. */
+ argumentList(pn);
+ break;
+
+ default:
+ break tailLoop;
+ }
+ }
+ return pn;
+ }
+
+ /*
+ * Xml attribute expression:
+ * '@attr', '@ns::attr', '@ns::*', '@ns::*', '@*', '@*::attr', '@*::*'
+ */
+ private Node attributeAccess(Node pn, int memberTypeFlags)
+ throws IOException
+ {
+ memberTypeFlags |= Node.ATTRIBUTE_FLAG;
+ int tt = nextToken();
+
+ switch (tt) {
+ // handles: @name, @ns::name, @ns::*, @ns::[expr]
+ case Token.NAME:
+ {
+ String s = ts.getString();
+ decompiler.addName(s);
+ pn = propertyName(pn, s, memberTypeFlags);
+ }
+ break;
+
+ // handles: @*, @*::name, @*::*, @*::[expr]
+ case Token.MUL:
+ decompiler.addName("*");
+ pn = propertyName(pn, "*", memberTypeFlags);
+ break;
+
+ // handles @[expr]
+ case Token.LB:
+ decompiler.addToken(Token.LB);
+ pn = nf.createElementGet(pn, null, expr(false), memberTypeFlags);
+ mustMatchToken(Token.RB, "msg.no.bracket.index");
+ decompiler.addToken(Token.RB);
+ break;
+
+ default:
+ reportError("msg.no.name.after.xmlAttr");
+ pn = nf.createPropertyGet(pn, null, "?", memberTypeFlags);
+ break;
+ }
+
+ return pn;
+ }
+
+ /**
+ * Check if :: follows name in which case it becomes qualified name
+ */
+ private Node propertyName(Node pn, String name, int memberTypeFlags)
+ throws IOException, ParserException
+ {
+ String namespace = null;
+ if (matchToken(Token.COLONCOLON)) {
+ decompiler.addToken(Token.COLONCOLON);
+ namespace = name;
+
+ int tt = nextToken();
+ switch (tt) {
+ // handles name::name
+ case Token.NAME:
+ name = ts.getString();
+ decompiler.addName(name);
+ break;
+
+ // handles name::*
+ case Token.MUL:
+ decompiler.addName("*");
+ name = "*";
+ break;
+
+ // handles name::[expr]
+ case Token.LB:
+ decompiler.addToken(Token.LB);
+ pn = nf.createElementGet(pn, namespace, expr(false),
+ memberTypeFlags);
+ mustMatchToken(Token.RB, "msg.no.bracket.index");
+ decompiler.addToken(Token.RB);
+ return pn;
+
+ default:
+ reportError("msg.no.name.after.coloncolon");
+ name = "?";
+ }
+ }
+
+ pn = nf.createPropertyGet(pn, namespace, name, memberTypeFlags);
+ return pn;
+ }
+
+ private Node primaryExpr()
+ throws IOException, ParserException
+ {
+ Node pn;
+
+ int ttFlagged = nextFlaggedToken();
+ int tt = ttFlagged & CLEAR_TI_MASK;
+
+ switch(tt) {
+
+ case Token.FUNCTION:
+ return function(FunctionNode.FUNCTION_EXPRESSION);
+
+ case Token.LB: {
+ ObjArray elems = new ObjArray();
+ int skipCount = 0;
+ decompiler.addToken(Token.LB);
+ boolean after_lb_or_comma = true;
+ for (;;) {
+ tt = peekToken();
+
+ if (tt == Token.COMMA) {
+ consumeToken();
+ decompiler.addToken(Token.COMMA);
+ if (!after_lb_or_comma) {
+ after_lb_or_comma = true;
+ } else {
+ elems.add(null);
+ ++skipCount;
+ }
+ } else if (tt == Token.RB) {
+ consumeToken();
+ decompiler.addToken(Token.RB);
+ break;
+ } else {
+ if (!after_lb_or_comma) {
+ reportError("msg.no.bracket.arg");
+ }
+ elems.add(assignExpr(false));
+ after_lb_or_comma = false;
+ }
+ }
+ return nf.createArrayLiteral(elems, skipCount);
+ }
+
+ case Token.LC: {
+ ObjArray elems = new ObjArray();
+ decompiler.addToken(Token.LC);
+ if (!matchToken(Token.RC)) {
+
+ boolean first = true;
+ commaloop:
+ do {
+ Object property;
+
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ else
+ first = false;
+
+ tt = peekToken();
+ switch(tt) {
+ case Token.NAME:
+ case Token.STRING:
+ consumeToken();
+ // map NAMEs to STRINGs in object literal context
+ // but tell the decompiler the proper type
+ String s = ts.getString();
+ if (tt == Token.NAME) {
+ if (s.equals("get") &&
+ peekToken() == Token.NAME) {
+ decompiler.addToken(Token.GET);
+ consumeToken();
+ s = ts.getString();
+ decompiler.addName(s);
+ property = ScriptRuntime.getIndexObject(s);
+ if (!getterSetterProperty(elems, property,
+ true))
+ break commaloop;
+ break;
+ } else if (s.equals("set") &&
+ peekToken() == Token.NAME) {
+ decompiler.addToken(Token.SET);
+ consumeToken();
+ s = ts.getString();
+ decompiler.addName(s);
+ property = ScriptRuntime.getIndexObject(s);
+ if (!getterSetterProperty(elems, property,
+ false))
+ break commaloop;
+ break;
+ }
+ decompiler.addName(s);
+ } else {
+ decompiler.addString(s);
+ }
+ property = ScriptRuntime.getIndexObject(s);
+ plainProperty(elems, property);
+ break;
+
+ case Token.NUMBER:
+ consumeToken();
+ double n = ts.getNumber();
+ decompiler.addNumber(n);
+ property = ScriptRuntime.getIndexObject(n);
+ plainProperty(elems, property);
+ break;
+
+ case Token.RC:
+ // trailing comma is OK.
+ break commaloop;
+ default:
+ reportError("msg.bad.prop");
+ break commaloop;
+ }
+ } while (matchToken(Token.COMMA));
+
+ mustMatchToken(Token.RC, "msg.no.brace.prop");
+ }
+ decompiler.addToken(Token.RC);
+ return nf.createObjectLiteral(elems);
+ }
+
+ case Token.LP:
+
+ /* Brendan's IR-jsparse.c makes a new node tagged with
+ * TOK_LP here... I'm not sure I understand why. Isn't
+ * the grouping already implicit in the structure of the
+ * parse tree? also TOK_LP is already overloaded (I
+ * think) in the C IR as 'function call.' */
+ decompiler.addToken(Token.LP);
+ pn = expr(false);
+ pn.putProp(Node.PARENTHESIZED_PROP, Boolean.TRUE);
+ decompiler.addToken(Token.RP);
+ mustMatchToken(Token.RP, "msg.no.paren");
+ return pn;
+
+ case Token.XMLATTR:
+ mustHaveXML();
+ decompiler.addToken(Token.XMLATTR);
+ pn = attributeAccess(null, 0);
+ return pn;
+
+ case Token.NAME: {
+ String name = ts.getString();
+ if ((ttFlagged & TI_CHECK_LABEL) != 0) {
+ if (peekToken() == Token.COLON) {
+ // Do not consume colon, it is used as unwind indicator
+ // to return to statementHelper.
+ // XXX Better way?
+ return nf.createLabel(ts.getLineno());
+ }
+ }
+
+ decompiler.addName(name);
+ if (compilerEnv.isXmlAvailable()) {
+ pn = propertyName(null, name, 0);
+ } else {
+ pn = nf.createName(name);
+ }
+ return pn;
+ }
+
+ case Token.NUMBER: {
+ double n = ts.getNumber();
+ decompiler.addNumber(n);
+ return nf.createNumber(n);
+ }
+
+ case Token.STRING: {
+ String s = ts.getString();
+ decompiler.addString(s);
+ return nf.createString(s);
+ }
+
+ case Token.DIV:
+ case Token.ASSIGN_DIV: {
+ // Got / or /= which should be treated as regexp in fact
+ ts.readRegExp(tt);
+ String flags = ts.regExpFlags;
+ ts.regExpFlags = null;
+ String re = ts.getString();
+ decompiler.addRegexp(re, flags);
+ int index = currentScriptOrFn.addRegexp(re, flags);
+ return nf.createRegExp(index);
+ }
+
+ case Token.NULL:
+ case Token.THIS:
+ case Token.FALSE:
+ case Token.TRUE:
+ decompiler.addToken(tt);
+ return nf.createLeaf(tt);
+
+ case Token.RESERVED:
+ reportError("msg.reserved.id");
+ break;
+
+ case Token.ERROR:
+ /* the scanner or one of its subroutines reported the error. */
+ break;
+
+ case Token.EOF:
+ reportError("msg.unexpected.eof");
+ break;
+
+ default:
+ reportError("msg.syntax");
+ break;
+ }
+ return null; // should never reach here
+ }
+
+ private void plainProperty(ObjArray elems, Object property)
+ throws IOException {
+ mustMatchToken(Token.COLON, "msg.no.colon.prop");
+
+ // OBJLIT is used as ':' in object literal for
+ // decompilation to solve spacing ambiguity.
+ decompiler.addToken(Token.OBJECTLIT);
+ elems.add(property);
+ elems.add(assignExpr(false));
+ }
+
+ private boolean getterSetterProperty(ObjArray elems, Object property,
+ boolean isGetter) throws IOException {
+ Node f = function(FunctionNode.FUNCTION_EXPRESSION);
+ if (f.getType() != Token.FUNCTION) {
+ reportError("msg.bad.prop");
+ return false;
+ }
+ int fnIndex = f.getExistingIntProp(Node.FUNCTION_PROP);
+ FunctionNode fn = currentScriptOrFn.getFunctionNode(fnIndex);
+ if (fn.getFunctionName().length() != 0) {
+ reportError("msg.bad.prop");
+ return false;
+ }
+ elems.add(property);
+ if (isGetter) {
+ elems.add(nf.createUnary(Token.GET, f));
+ } else {
+ elems.add(nf.createUnary(Token.SET, f));
+ }
+ return true;
+ }
+}
diff --git a/yuicompressor-2.4.2/src/org/mozilla/javascript/Token.java b/yuicompressor-2.4.2/src/org/mozilla/javascript/Token.java
new file mode 100644
index 00000000..5749465b
--- /dev/null
+++ b/yuicompressor-2.4.2/src/org/mozilla/javascript/Token.java
@@ -0,0 +1,421 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Roger Lawrence
+ * Mike McCabe
+ * Igor Bukanov
+ * Bob Jervis
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * This class implements the JavaScript scanner.
+ *
+ * It is based on the C source files jsscan.c and jsscan.h
+ * in the jsref package.
+ *
+ * @see org.mozilla.javascript.Parser
+ *
+ * @author Mike McCabe
+ * @author Brendan Eich
+ */
+
+public class Token
+{
+
+ // debug flags
+ public static final boolean printTrees = false;
+ static final boolean printICode = false;
+ static final boolean printNames = printTrees || printICode;
+
+ /**
+ * Token types. These values correspond to JSTokenType values in
+ * jsscan.c.
+ */
+
+ public final static int
+ // start enum
+ ERROR = -1, // well-known as the only code < EOF
+ EOF = 0, // end of file token - (not EOF_CHAR)
+ EOL = 1, // end of line
+
+ // Interpreter reuses the following as bytecodes
+ FIRST_BYTECODE_TOKEN = 2,
+
+ ENTERWITH = 2,
+ LEAVEWITH = 3,
+ RETURN = 4,
+ GOTO = 5,
+ IFEQ = 6,
+ IFNE = 7,
+ SETNAME = 8,
+ BITOR = 9,
+ BITXOR = 10,
+ BITAND = 11,
+ EQ = 12,
+ NE = 13,
+ LT = 14,
+ LE = 15,
+ GT = 16,
+ GE = 17,
+ LSH = 18,
+ RSH = 19,
+ URSH = 20,
+ ADD = 21,
+ SUB = 22,
+ MUL = 23,
+ DIV = 24,
+ MOD = 25,
+ NOT = 26,
+ BITNOT = 27,
+ POS = 28,
+ NEG = 29,
+ NEW = 30,
+ DELPROP = 31,
+ TYPEOF = 32,
+ GETPROP = 33,
+ SETPROP = 34,
+ GETELEM = 35,
+ SETELEM = 36,
+ CALL = 37,
+ NAME = 38,
+ NUMBER = 39,
+ STRING = 40,
+ NULL = 41,
+ THIS = 42,
+ FALSE = 43,
+ TRUE = 44,
+ SHEQ = 45, // shallow equality (===)
+ SHNE = 46, // shallow inequality (!==)
+ REGEXP = 47,
+ BINDNAME = 48,
+ THROW = 49,
+ RETHROW = 50, // rethrow caught execetion: catch (e if ) use it
+ IN = 51,
+ INSTANCEOF = 52,
+ LOCAL_LOAD = 53,
+ GETVAR = 54,
+ SETVAR = 55,
+ CATCH_SCOPE = 56,
+ ENUM_INIT_KEYS = 57,
+ ENUM_INIT_VALUES = 58,
+ ENUM_NEXT = 59,
+ ENUM_ID = 60,
+ THISFN = 61,
+ RETURN_RESULT = 62, // to return prevoisly stored return result
+ ARRAYLIT = 63, // array literal
+ OBJECTLIT = 64, // object literal
+ GET_REF = 65, // *reference
+ SET_REF = 66, // *reference = something
+ DEL_REF = 67, // delete reference
+ REF_CALL = 68, // f(args) = something or f(args)++
+ REF_SPECIAL = 69, // reference for special properties like __proto
+
+ // For XML support:
+ DEFAULTNAMESPACE = 70, // default xml namespace =
+ ESCXMLATTR = 71,
+ ESCXMLTEXT = 72,
+ REF_MEMBER = 73, // Reference for x.@y, x..y etc.
+ REF_NS_MEMBER = 74, // Reference for x.ns::y, x..ns::y etc.
+ REF_NAME = 75, // Reference for @y, @[y] etc.
+ REF_NS_NAME = 76; // Reference for ns::y, @ns::y@[y] etc.
+
+ // End of interpreter bytecodes
+ public final static int
+ LAST_BYTECODE_TOKEN = REF_NS_NAME,
+
+ TRY = 77,
+ SEMI = 78, // semicolon
+ LB = 79, // left and right brackets
+ RB = 80,
+ LC = 81, // left and right curlies (braces)
+ RC = 82,
+ LP = 83, // left and right parentheses
+ RP = 84,
+ COMMA = 85, // comma operator
+
+ ASSIGN = 86, // simple assignment (=)
+ ASSIGN_BITOR = 87, // |=
+ ASSIGN_BITXOR = 88, // ^=
+ ASSIGN_BITAND = 89, // |=
+ ASSIGN_LSH = 90, // <<=
+ ASSIGN_RSH = 91, // >>=
+ ASSIGN_URSH = 92, // >>>=
+ ASSIGN_ADD = 93, // +=
+ ASSIGN_SUB = 94, // -=
+ ASSIGN_MUL = 95, // *=
+ ASSIGN_DIV = 96, // /=
+ ASSIGN_MOD = 97; // %=
+
+ public final static int
+ FIRST_ASSIGN = ASSIGN,
+ LAST_ASSIGN = ASSIGN_MOD,
+
+ HOOK = 98, // conditional (?:)
+ COLON = 99,
+ OR = 100, // logical or (||)
+ AND = 101, // logical and (&&)
+ INC = 102, // increment/decrement (++ --)
+ DEC = 103,
+ DOT = 104, // member operator (.)
+ FUNCTION = 105, // function keyword
+ EXPORT = 106, // export keyword
+ IMPORT = 107, // import keyword
+ IF = 108, // if keyword
+ ELSE = 109, // else keyword
+ SWITCH = 110, // switch keyword
+ CASE = 111, // case keyword
+ DEFAULT = 112, // default keyword
+ WHILE = 113, // while keyword
+ DO = 114, // do keyword
+ FOR = 115, // for keyword
+ BREAK = 116, // break keyword
+ CONTINUE = 117, // continue keyword
+ VAR = 118, // var keyword
+ WITH = 119, // with keyword
+ CATCH = 120, // catch keyword
+ FINALLY = 121, // finally keyword
+ VOID = 122, // void keyword
+ RESERVED = 123, // reserved keywords
+
+ EMPTY = 124,
+
+ /* types used for the parse tree - these never get returned
+ * by the scanner.
+ */
+
+ BLOCK = 125, // statement block
+ LABEL = 126, // label
+ TARGET = 127,
+ LOOP = 128,
+ EXPR_VOID = 129, // expression statement in functions
+ EXPR_RESULT = 130, // expression statement in scripts
+ JSR = 131,
+ SCRIPT = 132, // top-level node for entire script
+ TYPEOFNAME = 133, // for typeof(simple-name)
+ USE_STACK = 134,
+ SETPROP_OP = 135, // x.y op= something
+ SETELEM_OP = 136, // x[y] op= something
+ LOCAL_BLOCK = 137,
+ SET_REF_OP = 138, // *reference op= something
+
+ // For XML support:
+ DOTDOT = 139, // member operator (..)
+ COLONCOLON = 140, // namespace::name
+ XML = 141, // XML type
+ DOTQUERY = 142, // .() -- e.g., x.emps.emp.(name == "terry")
+ XMLATTR = 143, // @
+ XMLEND = 144,
+
+ // Optimizer-only-tokens
+ TO_OBJECT = 145,
+ TO_DOUBLE = 146,
+
+ GET = 147, // JS 1.5 get pseudo keyword
+ SET = 148, // JS 1.5 set pseudo keyword
+ CONST = 149,
+ SETCONST = 150,
+ SETCONSTVAR = 151,
+
+ CONDCOMMENT = 152, // JScript conditional comment
+ KEEPCOMMENT = 153, // /*! ... */ comment
+
+ LAST_TOKEN = 154;
+
+ public static String name(int token)
+ {
+ if (!printNames) {
+ return String.valueOf(token);
+ }
+ switch (token) {
+ case ERROR: return "ERROR";
+ case EOF: return "EOF";
+ case EOL: return "EOL";
+ case ENTERWITH: return "ENTERWITH";
+ case LEAVEWITH: return "LEAVEWITH";
+ case RETURN: return "RETURN";
+ case GOTO: return "GOTO";
+ case IFEQ: return "IFEQ";
+ case IFNE: return "IFNE";
+ case SETNAME: return "SETNAME";
+ case BITOR: return "BITOR";
+ case BITXOR: return "BITXOR";
+ case BITAND: return "BITAND";
+ case EQ: return "EQ";
+ case NE: return "NE";
+ case LT: return "LT";
+ case LE: return "LE";
+ case GT: return "GT";
+ case GE: return "GE";
+ case LSH: return "LSH";
+ case RSH: return "RSH";
+ case URSH: return "URSH";
+ case ADD: return "ADD";
+ case SUB: return "SUB";
+ case MUL: return "MUL";
+ case DIV: return "DIV";
+ case MOD: return "MOD";
+ case NOT: return "NOT";
+ case BITNOT: return "BITNOT";
+ case POS: return "POS";
+ case NEG: return "NEG";
+ case NEW: return "NEW";
+ case DELPROP: return "DELPROP";
+ case TYPEOF: return "TYPEOF";
+ case GETPROP: return "GETPROP";
+ case SETPROP: return "SETPROP";
+ case GETELEM: return "GETELEM";
+ case SETELEM: return "SETELEM";
+ case CALL: return "CALL";
+ case NAME: return "NAME";
+ case NUMBER: return "NUMBER";
+ case STRING: return "STRING";
+ case NULL: return "NULL";
+ case THIS: return "THIS";
+ case FALSE: return "FALSE";
+ case TRUE: return "TRUE";
+ case SHEQ: return "SHEQ";
+ case SHNE: return "SHNE";
+ case REGEXP: return "OBJECT";
+ case BINDNAME: return "BINDNAME";
+ case THROW: return "THROW";
+ case RETHROW: return "RETHROW";
+ case IN: return "IN";
+ case INSTANCEOF: return "INSTANCEOF";
+ case LOCAL_LOAD: return "LOCAL_LOAD";
+ case GETVAR: return "GETVAR";
+ case SETVAR: return "SETVAR";
+ case CATCH_SCOPE: return "CATCH_SCOPE";
+ case ENUM_INIT_KEYS: return "ENUM_INIT_KEYS";
+ case ENUM_INIT_VALUES: return "ENUM_INIT_VALUES";
+ case ENUM_NEXT: return "ENUM_NEXT";
+ case ENUM_ID: return "ENUM_ID";
+ case THISFN: return "THISFN";
+ case RETURN_RESULT: return "RETURN_RESULT";
+ case ARRAYLIT: return "ARRAYLIT";
+ case OBJECTLIT: return "OBJECTLIT";
+ case GET_REF: return "GET_REF";
+ case SET_REF: return "SET_REF";
+ case DEL_REF: return "DEL_REF";
+ case REF_CALL: return "REF_CALL";
+ case REF_SPECIAL: return "REF_SPECIAL";
+ case DEFAULTNAMESPACE:return "DEFAULTNAMESPACE";
+ case ESCXMLTEXT: return "ESCXMLTEXT";
+ case ESCXMLATTR: return "ESCXMLATTR";
+ case REF_MEMBER: return "REF_MEMBER";
+ case REF_NS_MEMBER: return "REF_NS_MEMBER";
+ case REF_NAME: return "REF_NAME";
+ case REF_NS_NAME: return "REF_NS_NAME";
+ case TRY: return "TRY";
+ case SEMI: return "SEMI";
+ case LB: return "LB";
+ case RB: return "RB";
+ case LC: return "LC";
+ case RC: return "RC";
+ case LP: return "LP";
+ case RP: return "RP";
+ case COMMA: return "COMMA";
+ case ASSIGN: return "ASSIGN";
+ case ASSIGN_BITOR: return "ASSIGN_BITOR";
+ case ASSIGN_BITXOR: return "ASSIGN_BITXOR";
+ case ASSIGN_BITAND: return "ASSIGN_BITAND";
+ case ASSIGN_LSH: return "ASSIGN_LSH";
+ case ASSIGN_RSH: return "ASSIGN_RSH";
+ case ASSIGN_URSH: return "ASSIGN_URSH";
+ case ASSIGN_ADD: return "ASSIGN_ADD";
+ case ASSIGN_SUB: return "ASSIGN_SUB";
+ case ASSIGN_MUL: return "ASSIGN_MUL";
+ case ASSIGN_DIV: return "ASSIGN_DIV";
+ case ASSIGN_MOD: return "ASSIGN_MOD";
+ case HOOK: return "HOOK";
+ case COLON: return "COLON";
+ case OR: return "OR";
+ case AND: return "AND";
+ case INC: return "INC";
+ case DEC: return "DEC";
+ case DOT: return "DOT";
+ case FUNCTION: return "FUNCTION";
+ case EXPORT: return "EXPORT";
+ case IMPORT: return "IMPORT";
+ case IF: return "IF";
+ case ELSE: return "ELSE";
+ case SWITCH: return "SWITCH";
+ case CASE: return "CASE";
+ case DEFAULT: return "DEFAULT";
+ case WHILE: return "WHILE";
+ case DO: return "DO";
+ case FOR: return "FOR";
+ case BREAK: return "BREAK";
+ case CONTINUE: return "CONTINUE";
+ case VAR: return "VAR";
+ case WITH: return "WITH";
+ case CATCH: return "CATCH";
+ case FINALLY: return "FINALLY";
+ case RESERVED: return "RESERVED";
+ case EMPTY: return "EMPTY";
+ case BLOCK: return "BLOCK";
+ case LABEL: return "LABEL";
+ case TARGET: return "TARGET";
+ case LOOP: return "LOOP";
+ case EXPR_VOID: return "EXPR_VOID";
+ case EXPR_RESULT: return "EXPR_RESULT";
+ case JSR: return "JSR";
+ case SCRIPT: return "SCRIPT";
+ case TYPEOFNAME: return "TYPEOFNAME";
+ case USE_STACK: return "USE_STACK";
+ case SETPROP_OP: return "SETPROP_OP";
+ case SETELEM_OP: return "SETELEM_OP";
+ case LOCAL_BLOCK: return "LOCAL_BLOCK";
+ case SET_REF_OP: return "SET_REF_OP";
+ case DOTDOT: return "DOTDOT";
+ case COLONCOLON: return "COLONCOLON";
+ case XML: return "XML";
+ case DOTQUERY: return "DOTQUERY";
+ case XMLATTR: return "XMLATTR";
+ case XMLEND: return "XMLEND";
+ case TO_OBJECT: return "TO_OBJECT";
+ case TO_DOUBLE: return "TO_DOUBLE";
+ case GET: return "GET";
+ case SET: return "SET";
+ case CONST: return "CONST";
+ case SETCONST: return "SETCONST";
+ }
+
+ // Token without name
+ throw new IllegalStateException(String.valueOf(token));
+ }
+}
diff --git a/yuicompressor-2.4.2/src/org/mozilla/javascript/Token.java.orig b/yuicompressor-2.4.2/src/org/mozilla/javascript/Token.java.orig
new file mode 100644
index 00000000..7f7cdc2a
--- /dev/null
+++ b/yuicompressor-2.4.2/src/org/mozilla/javascript/Token.java.orig
@@ -0,0 +1,417 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Roger Lawrence
+ * Mike McCabe
+ * Igor Bukanov
+ * Bob Jervis
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * This class implements the JavaScript scanner.
+ *
+ * It is based on the C source files jsscan.c and jsscan.h
+ * in the jsref package.
+ *
+ * @see org.mozilla.javascript.Parser
+ *
+ * @author Mike McCabe
+ * @author Brendan Eich
+ */
+
+public class Token
+{
+
+ // debug flags
+ public static final boolean printTrees = false;
+ static final boolean printICode = false;
+ static final boolean printNames = printTrees || printICode;
+
+ /**
+ * Token types. These values correspond to JSTokenType values in
+ * jsscan.c.
+ */
+
+ public final static int
+ // start enum
+ ERROR = -1, // well-known as the only code < EOF
+ EOF = 0, // end of file token - (not EOF_CHAR)
+ EOL = 1, // end of line
+
+ // Interpreter reuses the following as bytecodes
+ FIRST_BYTECODE_TOKEN = 2,
+
+ ENTERWITH = 2,
+ LEAVEWITH = 3,
+ RETURN = 4,
+ GOTO = 5,
+ IFEQ = 6,
+ IFNE = 7,
+ SETNAME = 8,
+ BITOR = 9,
+ BITXOR = 10,
+ BITAND = 11,
+ EQ = 12,
+ NE = 13,
+ LT = 14,
+ LE = 15,
+ GT = 16,
+ GE = 17,
+ LSH = 18,
+ RSH = 19,
+ URSH = 20,
+ ADD = 21,
+ SUB = 22,
+ MUL = 23,
+ DIV = 24,
+ MOD = 25,
+ NOT = 26,
+ BITNOT = 27,
+ POS = 28,
+ NEG = 29,
+ NEW = 30,
+ DELPROP = 31,
+ TYPEOF = 32,
+ GETPROP = 33,
+ SETPROP = 34,
+ GETELEM = 35,
+ SETELEM = 36,
+ CALL = 37,
+ NAME = 38,
+ NUMBER = 39,
+ STRING = 40,
+ NULL = 41,
+ THIS = 42,
+ FALSE = 43,
+ TRUE = 44,
+ SHEQ = 45, // shallow equality (===)
+ SHNE = 46, // shallow inequality (!==)
+ REGEXP = 47,
+ BINDNAME = 48,
+ THROW = 49,
+ RETHROW = 50, // rethrow caught execetion: catch (e if ) use it
+ IN = 51,
+ INSTANCEOF = 52,
+ LOCAL_LOAD = 53,
+ GETVAR = 54,
+ SETVAR = 55,
+ CATCH_SCOPE = 56,
+ ENUM_INIT_KEYS = 57,
+ ENUM_INIT_VALUES = 58,
+ ENUM_NEXT = 59,
+ ENUM_ID = 60,
+ THISFN = 61,
+ RETURN_RESULT = 62, // to return prevoisly stored return result
+ ARRAYLIT = 63, // array literal
+ OBJECTLIT = 64, // object literal
+ GET_REF = 65, // *reference
+ SET_REF = 66, // *reference = something
+ DEL_REF = 67, // delete reference
+ REF_CALL = 68, // f(args) = something or f(args)++
+ REF_SPECIAL = 69, // reference for special properties like __proto
+
+ // For XML support:
+ DEFAULTNAMESPACE = 70, // default xml namespace =
+ ESCXMLATTR = 71,
+ ESCXMLTEXT = 72,
+ REF_MEMBER = 73, // Reference for x.@y, x..y etc.
+ REF_NS_MEMBER = 74, // Reference for x.ns::y, x..ns::y etc.
+ REF_NAME = 75, // Reference for @y, @[y] etc.
+ REF_NS_NAME = 76; // Reference for ns::y, @ns::y@[y] etc.
+
+ // End of interpreter bytecodes
+ public final static int
+ LAST_BYTECODE_TOKEN = REF_NS_NAME,
+
+ TRY = 77,
+ SEMI = 78, // semicolon
+ LB = 79, // left and right brackets
+ RB = 80,
+ LC = 81, // left and right curlies (braces)
+ RC = 82,
+ LP = 83, // left and right parentheses
+ RP = 84,
+ COMMA = 85, // comma operator
+
+ ASSIGN = 86, // simple assignment (=)
+ ASSIGN_BITOR = 87, // |=
+ ASSIGN_BITXOR = 88, // ^=
+ ASSIGN_BITAND = 89, // |=
+ ASSIGN_LSH = 90, // <<=
+ ASSIGN_RSH = 91, // >>=
+ ASSIGN_URSH = 92, // >>>=
+ ASSIGN_ADD = 93, // +=
+ ASSIGN_SUB = 94, // -=
+ ASSIGN_MUL = 95, // *=
+ ASSIGN_DIV = 96, // /=
+ ASSIGN_MOD = 97; // %=
+
+ public final static int
+ FIRST_ASSIGN = ASSIGN,
+ LAST_ASSIGN = ASSIGN_MOD,
+
+ HOOK = 98, // conditional (?:)
+ COLON = 99,
+ OR = 100, // logical or (||)
+ AND = 101, // logical and (&&)
+ INC = 102, // increment/decrement (++ --)
+ DEC = 103,
+ DOT = 104, // member operator (.)
+ FUNCTION = 105, // function keyword
+ EXPORT = 106, // export keyword
+ IMPORT = 107, // import keyword
+ IF = 108, // if keyword
+ ELSE = 109, // else keyword
+ SWITCH = 110, // switch keyword
+ CASE = 111, // case keyword
+ DEFAULT = 112, // default keyword
+ WHILE = 113, // while keyword
+ DO = 114, // do keyword
+ FOR = 115, // for keyword
+ BREAK = 116, // break keyword
+ CONTINUE = 117, // continue keyword
+ VAR = 118, // var keyword
+ WITH = 119, // with keyword
+ CATCH = 120, // catch keyword
+ FINALLY = 121, // finally keyword
+ VOID = 122, // void keyword
+ RESERVED = 123, // reserved keywords
+
+ EMPTY = 124,
+
+ /* types used for the parse tree - these never get returned
+ * by the scanner.
+ */
+
+ BLOCK = 125, // statement block
+ LABEL = 126, // label
+ TARGET = 127,
+ LOOP = 128,
+ EXPR_VOID = 129, // expression statement in functions
+ EXPR_RESULT = 130, // expression statement in scripts
+ JSR = 131,
+ SCRIPT = 132, // top-level node for entire script
+ TYPEOFNAME = 133, // for typeof(simple-name)
+ USE_STACK = 134,
+ SETPROP_OP = 135, // x.y op= something
+ SETELEM_OP = 136, // x[y] op= something
+ LOCAL_BLOCK = 137,
+ SET_REF_OP = 138, // *reference op= something
+
+ // For XML support:
+ DOTDOT = 139, // member operator (..)
+ COLONCOLON = 140, // namespace::name
+ XML = 141, // XML type
+ DOTQUERY = 142, // .() -- e.g., x.emps.emp.(name == "terry")
+ XMLATTR = 143, // @
+ XMLEND = 144,
+
+ // Optimizer-only-tokens
+ TO_OBJECT = 145,
+ TO_DOUBLE = 146,
+
+ GET = 147, // JS 1.5 get pseudo keyword
+ SET = 148, // JS 1.5 set pseudo keyword
+ CONST = 149,
+ SETCONST = 150,
+ SETCONSTVAR = 151,
+ LAST_TOKEN = 152;
+
+ public static String name(int token)
+ {
+ if (!printNames) {
+ return String.valueOf(token);
+ }
+ switch (token) {
+ case ERROR: return "ERROR";
+ case EOF: return "EOF";
+ case EOL: return "EOL";
+ case ENTERWITH: return "ENTERWITH";
+ case LEAVEWITH: return "LEAVEWITH";
+ case RETURN: return "RETURN";
+ case GOTO: return "GOTO";
+ case IFEQ: return "IFEQ";
+ case IFNE: return "IFNE";
+ case SETNAME: return "SETNAME";
+ case BITOR: return "BITOR";
+ case BITXOR: return "BITXOR";
+ case BITAND: return "BITAND";
+ case EQ: return "EQ";
+ case NE: return "NE";
+ case LT: return "LT";
+ case LE: return "LE";
+ case GT: return "GT";
+ case GE: return "GE";
+ case LSH: return "LSH";
+ case RSH: return "RSH";
+ case URSH: return "URSH";
+ case ADD: return "ADD";
+ case SUB: return "SUB";
+ case MUL: return "MUL";
+ case DIV: return "DIV";
+ case MOD: return "MOD";
+ case NOT: return "NOT";
+ case BITNOT: return "BITNOT";
+ case POS: return "POS";
+ case NEG: return "NEG";
+ case NEW: return "NEW";
+ case DELPROP: return "DELPROP";
+ case TYPEOF: return "TYPEOF";
+ case GETPROP: return "GETPROP";
+ case SETPROP: return "SETPROP";
+ case GETELEM: return "GETELEM";
+ case SETELEM: return "SETELEM";
+ case CALL: return "CALL";
+ case NAME: return "NAME";
+ case NUMBER: return "NUMBER";
+ case STRING: return "STRING";
+ case NULL: return "NULL";
+ case THIS: return "THIS";
+ case FALSE: return "FALSE";
+ case TRUE: return "TRUE";
+ case SHEQ: return "SHEQ";
+ case SHNE: return "SHNE";
+ case REGEXP: return "OBJECT";
+ case BINDNAME: return "BINDNAME";
+ case THROW: return "THROW";
+ case RETHROW: return "RETHROW";
+ case IN: return "IN";
+ case INSTANCEOF: return "INSTANCEOF";
+ case LOCAL_LOAD: return "LOCAL_LOAD";
+ case GETVAR: return "GETVAR";
+ case SETVAR: return "SETVAR";
+ case CATCH_SCOPE: return "CATCH_SCOPE";
+ case ENUM_INIT_KEYS: return "ENUM_INIT_KEYS";
+ case ENUM_INIT_VALUES: return "ENUM_INIT_VALUES";
+ case ENUM_NEXT: return "ENUM_NEXT";
+ case ENUM_ID: return "ENUM_ID";
+ case THISFN: return "THISFN";
+ case RETURN_RESULT: return "RETURN_RESULT";
+ case ARRAYLIT: return "ARRAYLIT";
+ case OBJECTLIT: return "OBJECTLIT";
+ case GET_REF: return "GET_REF";
+ case SET_REF: return "SET_REF";
+ case DEL_REF: return "DEL_REF";
+ case REF_CALL: return "REF_CALL";
+ case REF_SPECIAL: return "REF_SPECIAL";
+ case DEFAULTNAMESPACE:return "DEFAULTNAMESPACE";
+ case ESCXMLTEXT: return "ESCXMLTEXT";
+ case ESCXMLATTR: return "ESCXMLATTR";
+ case REF_MEMBER: return "REF_MEMBER";
+ case REF_NS_MEMBER: return "REF_NS_MEMBER";
+ case REF_NAME: return "REF_NAME";
+ case REF_NS_NAME: return "REF_NS_NAME";
+ case TRY: return "TRY";
+ case SEMI: return "SEMI";
+ case LB: return "LB";
+ case RB: return "RB";
+ case LC: return "LC";
+ case RC: return "RC";
+ case LP: return "LP";
+ case RP: return "RP";
+ case COMMA: return "COMMA";
+ case ASSIGN: return "ASSIGN";
+ case ASSIGN_BITOR: return "ASSIGN_BITOR";
+ case ASSIGN_BITXOR: return "ASSIGN_BITXOR";
+ case ASSIGN_BITAND: return "ASSIGN_BITAND";
+ case ASSIGN_LSH: return "ASSIGN_LSH";
+ case ASSIGN_RSH: return "ASSIGN_RSH";
+ case ASSIGN_URSH: return "ASSIGN_URSH";
+ case ASSIGN_ADD: return "ASSIGN_ADD";
+ case ASSIGN_SUB: return "ASSIGN_SUB";
+ case ASSIGN_MUL: return "ASSIGN_MUL";
+ case ASSIGN_DIV: return "ASSIGN_DIV";
+ case ASSIGN_MOD: return "ASSIGN_MOD";
+ case HOOK: return "HOOK";
+ case COLON: return "COLON";
+ case OR: return "OR";
+ case AND: return "AND";
+ case INC: return "INC";
+ case DEC: return "DEC";
+ case DOT: return "DOT";
+ case FUNCTION: return "FUNCTION";
+ case EXPORT: return "EXPORT";
+ case IMPORT: return "IMPORT";
+ case IF: return "IF";
+ case ELSE: return "ELSE";
+ case SWITCH: return "SWITCH";
+ case CASE: return "CASE";
+ case DEFAULT: return "DEFAULT";
+ case WHILE: return "WHILE";
+ case DO: return "DO";
+ case FOR: return "FOR";
+ case BREAK: return "BREAK";
+ case CONTINUE: return "CONTINUE";
+ case VAR: return "VAR";
+ case WITH: return "WITH";
+ case CATCH: return "CATCH";
+ case FINALLY: return "FINALLY";
+ case RESERVED: return "RESERVED";
+ case EMPTY: return "EMPTY";
+ case BLOCK: return "BLOCK";
+ case LABEL: return "LABEL";
+ case TARGET: return "TARGET";
+ case LOOP: return "LOOP";
+ case EXPR_VOID: return "EXPR_VOID";
+ case EXPR_RESULT: return "EXPR_RESULT";
+ case JSR: return "JSR";
+ case SCRIPT: return "SCRIPT";
+ case TYPEOFNAME: return "TYPEOFNAME";
+ case USE_STACK: return "USE_STACK";
+ case SETPROP_OP: return "SETPROP_OP";
+ case SETELEM_OP: return "SETELEM_OP";
+ case LOCAL_BLOCK: return "LOCAL_BLOCK";
+ case SET_REF_OP: return "SET_REF_OP";
+ case DOTDOT: return "DOTDOT";
+ case COLONCOLON: return "COLONCOLON";
+ case XML: return "XML";
+ case DOTQUERY: return "DOTQUERY";
+ case XMLATTR: return "XMLATTR";
+ case XMLEND: return "XMLEND";
+ case TO_OBJECT: return "TO_OBJECT";
+ case TO_DOUBLE: return "TO_DOUBLE";
+ case GET: return "GET";
+ case SET: return "SET";
+ case CONST: return "CONST";
+ case SETCONST: return "SETCONST";
+ }
+
+ // Token without name
+ throw new IllegalStateException(String.valueOf(token));
+ }
+}
diff --git a/yuicompressor-2.4.2/src/org/mozilla/javascript/TokenStream.java b/yuicompressor-2.4.2/src/org/mozilla/javascript/TokenStream.java
new file mode 100644
index 00000000..6a776cce
--- /dev/null
+++ b/yuicompressor-2.4.2/src/org/mozilla/javascript/TokenStream.java
@@ -0,0 +1,1380 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Roger Lawrence
+ * Mike McCabe
+ * Igor Bukanov
+ * Ethan Hugg
+ * Bob Jervis
+ * Terry Lucas
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.*;
+
+/**
+ * This class implements the JavaScript scanner.
+ *
+ * It is based on the C source files jsscan.c and jsscan.h
+ * in the jsref package.
+ *
+ * @see org.mozilla.javascript.Parser
+ *
+ * @author Mike McCabe
+ * @author Brendan Eich
+ */
+
+class TokenStream
+{
+ /*
+ * For chars - because we need something out-of-range
+ * to check. (And checking EOF by exception is annoying.)
+ * Note distinction from EOF token type!
+ */
+ private final static int
+ EOF_CHAR = -1;
+
+ TokenStream(Parser parser, Reader sourceReader, String sourceString,
+ int lineno)
+ {
+ this.parser = parser;
+ this.lineno = lineno;
+ if (sourceReader != null) {
+ if (sourceString != null) Kit.codeBug();
+ this.sourceReader = sourceReader;
+ this.sourceBuffer = new char[512];
+ this.sourceEnd = 0;
+ } else {
+ if (sourceString == null) Kit.codeBug();
+ this.sourceString = sourceString;
+ this.sourceEnd = sourceString.length();
+ }
+ this.sourceCursor = 0;
+ }
+
+ /* This function uses the cached op, string and number fields in
+ * TokenStream; if getToken has been called since the passed token
+ * was scanned, the op or string printed may be incorrect.
+ */
+ String tokenToString(int token)
+ {
+ if (Token.printTrees) {
+ String name = Token.name(token);
+
+ switch (token) {
+ case Token.STRING:
+ case Token.REGEXP:
+ case Token.NAME:
+ return name + " `" + this.string + "'";
+
+ case Token.NUMBER:
+ return "NUMBER " + this.number;
+ }
+
+ return name;
+ }
+ return "";
+ }
+
+ static boolean isKeyword(String s)
+ {
+ return Token.EOF != stringToKeyword(s);
+ }
+
+ private static int stringToKeyword(String name)
+ {
+// #string_id_map#
+// The following assumes that Token.EOF == 0
+ final int
+ Id_break = Token.BREAK,
+ Id_case = Token.CASE,
+ Id_continue = Token.CONTINUE,
+ Id_default = Token.DEFAULT,
+ Id_delete = Token.DELPROP,
+ Id_do = Token.DO,
+ Id_else = Token.ELSE,
+ Id_export = Token.EXPORT,
+ Id_false = Token.FALSE,
+ Id_for = Token.FOR,
+ Id_function = Token.FUNCTION,
+ Id_if = Token.IF,
+ Id_in = Token.IN,
+ Id_new = Token.NEW,
+ Id_null = Token.NULL,
+ Id_return = Token.RETURN,
+ Id_switch = Token.SWITCH,
+ Id_this = Token.THIS,
+ Id_true = Token.TRUE,
+ Id_typeof = Token.TYPEOF,
+ Id_var = Token.VAR,
+ Id_void = Token.VOID,
+ Id_while = Token.WHILE,
+ Id_with = Token.WITH,
+
+ // the following are #ifdef RESERVE_JAVA_KEYWORDS in jsscan.c
+ Id_abstract = Token.RESERVED,
+ Id_boolean = Token.RESERVED,
+ Id_byte = Token.RESERVED,
+ Id_catch = Token.CATCH,
+ Id_char = Token.RESERVED,
+ Id_class = Token.RESERVED,
+ Id_const = Token.CONST,
+ Id_debugger = Token.RESERVED,
+ Id_double = Token.RESERVED,
+ Id_enum = Token.RESERVED,
+ Id_extends = Token.RESERVED,
+ Id_final = Token.RESERVED,
+ Id_finally = Token.FINALLY,
+ Id_float = Token.RESERVED,
+ Id_goto = Token.RESERVED,
+ Id_implements = Token.RESERVED,
+ Id_import = Token.IMPORT,
+ Id_instanceof = Token.INSTANCEOF,
+ Id_int = Token.RESERVED,
+ Id_interface = Token.RESERVED,
+ Id_long = Token.RESERVED,
+ Id_native = Token.RESERVED,
+ Id_package = Token.RESERVED,
+ Id_private = Token.RESERVED,
+ Id_protected = Token.RESERVED,
+ Id_public = Token.RESERVED,
+ Id_short = Token.RESERVED,
+ Id_static = Token.RESERVED,
+ Id_super = Token.RESERVED,
+ Id_synchronized = Token.RESERVED,
+ Id_throw = Token.THROW,
+ Id_throws = Token.RESERVED,
+ Id_transient = Token.RESERVED,
+ Id_try = Token.TRY,
+ Id_volatile = Token.RESERVED;
+
+ int id;
+ String s = name;
+// #generated# Last update: 2001-06-01 17:45:01 CEST
+ L0: { id = 0; String X = null; int c;
+ L: switch (s.length()) {
+ case 2: c=s.charAt(1);
+ if (c=='f') { if (s.charAt(0)=='i') {id=Id_if; break L0;} }
+ else if (c=='n') { if (s.charAt(0)=='i') {id=Id_in; break L0;} }
+ else if (c=='o') { if (s.charAt(0)=='d') {id=Id_do; break L0;} }
+ break L;
+ case 3: switch (s.charAt(0)) {
+ case 'f': if (s.charAt(2)=='r' && s.charAt(1)=='o') {id=Id_for; break L0;} break L;
+ case 'i': if (s.charAt(2)=='t' && s.charAt(1)=='n') {id=Id_int; break L0;} break L;
+ case 'n': if (s.charAt(2)=='w' && s.charAt(1)=='e') {id=Id_new; break L0;} break L;
+ case 't': if (s.charAt(2)=='y' && s.charAt(1)=='r') {id=Id_try; break L0;} break L;
+ case 'v': if (s.charAt(2)=='r' && s.charAt(1)=='a') {id=Id_var; break L0;} break L;
+ } break L;
+ case 4: switch (s.charAt(0)) {
+ case 'b': X="byte";id=Id_byte; break L;
+ case 'c': c=s.charAt(3);
+ if (c=='e') { if (s.charAt(2)=='s' && s.charAt(1)=='a') {id=Id_case; break L0;} }
+ else if (c=='r') { if (s.charAt(2)=='a' && s.charAt(1)=='h') {id=Id_char; break L0;} }
+ break L;
+ case 'e': c=s.charAt(3);
+ if (c=='e') { if (s.charAt(2)=='s' && s.charAt(1)=='l') {id=Id_else; break L0;} }
+ else if (c=='m') { if (s.charAt(2)=='u' && s.charAt(1)=='n') {id=Id_enum; break L0;} }
+ break L;
+ case 'g': X="goto";id=Id_goto; break L;
+ case 'l': X="long";id=Id_long; break L;
+ case 'n': X="null";id=Id_null; break L;
+ case 't': c=s.charAt(3);
+ if (c=='e') { if (s.charAt(2)=='u' && s.charAt(1)=='r') {id=Id_true; break L0;} }
+ else if (c=='s') { if (s.charAt(2)=='i' && s.charAt(1)=='h') {id=Id_this; break L0;} }
+ break L;
+ case 'v': X="void";id=Id_void; break L;
+ case 'w': X="with";id=Id_with; break L;
+ } break L;
+ case 5: switch (s.charAt(2)) {
+ case 'a': X="class";id=Id_class; break L;
+ case 'e': X="break";id=Id_break; break L;
+ case 'i': X="while";id=Id_while; break L;
+ case 'l': X="false";id=Id_false; break L;
+ case 'n': c=s.charAt(0);
+ if (c=='c') { X="const";id=Id_const; }
+ else if (c=='f') { X="final";id=Id_final; }
+ break L;
+ case 'o': c=s.charAt(0);
+ if (c=='f') { X="float";id=Id_float; }
+ else if (c=='s') { X="short";id=Id_short; }
+ break L;
+ case 'p': X="super";id=Id_super; break L;
+ case 'r': X="throw";id=Id_throw; break L;
+ case 't': X="catch";id=Id_catch; break L;
+ } break L;
+ case 6: switch (s.charAt(1)) {
+ case 'a': X="native";id=Id_native; break L;
+ case 'e': c=s.charAt(0);
+ if (c=='d') { X="delete";id=Id_delete; }
+ else if (c=='r') { X="return";id=Id_return; }
+ break L;
+ case 'h': X="throws";id=Id_throws; break L;
+ case 'm': X="import";id=Id_import; break L;
+ case 'o': X="double";id=Id_double; break L;
+ case 't': X="static";id=Id_static; break L;
+ case 'u': X="public";id=Id_public; break L;
+ case 'w': X="switch";id=Id_switch; break L;
+ case 'x': X="export";id=Id_export; break L;
+ case 'y': X="typeof";id=Id_typeof; break L;
+ } break L;
+ case 7: switch (s.charAt(1)) {
+ case 'a': X="package";id=Id_package; break L;
+ case 'e': X="default";id=Id_default; break L;
+ case 'i': X="finally";id=Id_finally; break L;
+ case 'o': X="boolean";id=Id_boolean; break L;
+ case 'r': X="private";id=Id_private; break L;
+ case 'x': X="extends";id=Id_extends; break L;
+ } break L;
+ case 8: switch (s.charAt(0)) {
+ case 'a': X="abstract";id=Id_abstract; break L;
+ case 'c': X="continue";id=Id_continue; break L;
+ case 'd': X="debugger";id=Id_debugger; break L;
+ case 'f': X="function";id=Id_function; break L;
+ case 'v': X="volatile";id=Id_volatile; break L;
+ } break L;
+ case 9: c=s.charAt(0);
+ if (c=='i') { X="interface";id=Id_interface; }
+ else if (c=='p') { X="protected";id=Id_protected; }
+ else if (c=='t') { X="transient";id=Id_transient; }
+ break L;
+ case 10: c=s.charAt(1);
+ if (c=='m') { X="implements";id=Id_implements; }
+ else if (c=='n') { X="instanceof";id=Id_instanceof; }
+ break L;
+ case 12: X="synchronized";id=Id_synchronized; break L;
+ }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ }
+// #/generated#
+// #/string_id_map#
+ if (id == 0) { return Token.EOF; }
+ return id & 0xff;
+ }
+
+ final int getLineno() { return lineno; }
+
+ final String getString() { return string; }
+
+ final double getNumber() { return number; }
+
+ final boolean eof() { return hitEOF; }
+
+ final int getToken() throws IOException
+ {
+ int c;
+
+ retry:
+ for (;;) {
+ // Eat whitespace, possibly sensitive to newlines.
+ for (;;) {
+ c = getChar();
+ if (c == EOF_CHAR) {
+ return Token.EOF;
+ } else if (c == '\n') {
+ dirtyLine = false;
+ return Token.EOL;
+ } else if (!isJSSpace(c)) {
+ if (c != '-') {
+ dirtyLine = true;
+ }
+ break;
+ }
+ }
+
+ if (c == '@') return Token.XMLATTR;
+
+ // identifier/keyword/instanceof?
+ // watch out for starting with a
+ boolean identifierStart;
+ boolean isUnicodeEscapeStart = false;
+ if (c == '\\') {
+ c = getChar();
+ if (c == 'u') {
+ identifierStart = true;
+ isUnicodeEscapeStart = true;
+ stringBufferTop = 0;
+ } else {
+ identifierStart = false;
+ ungetChar(c);
+ c = '\\';
+ }
+ } else {
+ identifierStart = Character.isJavaIdentifierStart((char)c);
+ if (identifierStart) {
+ stringBufferTop = 0;
+ addToString(c);
+ }
+ }
+
+ if (identifierStart) {
+ boolean containsEscape = isUnicodeEscapeStart;
+ for (;;) {
+ if (isUnicodeEscapeStart) {
+ // strictly speaking we should probably push-back
+ // all the bad characters if the uXXXX
+ // sequence is malformed. But since there isn't a
+ // correct context(is there?) for a bad Unicode
+ // escape sequence in an identifier, we can report
+ // an error here.
+ int escapeVal = 0;
+ for (int i = 0; i != 4; ++i) {
+ c = getChar();
+ escapeVal = Kit.xDigitToInt(c, escapeVal);
+ // Next check takes care about c < 0 and bad escape
+ if (escapeVal < 0) { break; }
+ }
+ if (escapeVal < 0) {
+ parser.addError("msg.invalid.escape");
+ return Token.ERROR;
+ }
+ addToString(escapeVal);
+ isUnicodeEscapeStart = false;
+ } else {
+ c = getChar();
+ if (c == '\\') {
+ c = getChar();
+ if (c == 'u') {
+ isUnicodeEscapeStart = true;
+ containsEscape = true;
+ } else {
+ parser.addError("msg.illegal.character");
+ return Token.ERROR;
+ }
+ } else {
+ if (c == EOF_CHAR
+ || !Character.isJavaIdentifierPart((char)c))
+ {
+ break;
+ }
+ addToString(c);
+ }
+ }
+ }
+ ungetChar(c);
+
+ String str = getStringFromBuffer();
+ if (!containsEscape) {
+ // OPT we shouldn't have to make a string (object!) to
+ // check if it's a keyword.
+
+ // Return the corresponding token if it's a keyword
+ int result = stringToKeyword(str);
+ if (result != Token.EOF) {
+ if (result != Token.RESERVED) {
+ return result;
+ } else if (!parser.compilerEnv.
+ isReservedKeywordAsIdentifier())
+ {
+ return result;
+ } else {
+ // If implementation permits to use future reserved
+ // keywords in violation with the EcmaScript,
+ // treat it as name but issue warning
+ parser.addWarning("msg.reserved.keyword", str);
+ }
+ }
+ }
+ this.string = (String)allStrings.intern(str);
+ return Token.NAME;
+ }
+
+ // is it a number?
+ if (isDigit(c) || (c == '.' && isDigit(peekChar()))) {
+
+ stringBufferTop = 0;
+ int base = 10;
+
+ if (c == '0') {
+ c = getChar();
+ if (c == 'x' || c == 'X') {
+ base = 16;
+ c = getChar();
+ } else if (isDigit(c)) {
+ base = 8;
+ } else {
+ addToString('0');
+ }
+ }
+
+ if (base == 16) {
+ while (0 <= Kit.xDigitToInt(c, 0)) {
+ addToString(c);
+ c = getChar();
+ }
+ } else {
+ while ('0' <= c && c <= '9') {
+ /*
+ * We permit 08 and 09 as decimal numbers, which
+ * makes our behavior a superset of the ECMA
+ * numeric grammar. We might not always be so
+ * permissive, so we warn about it.
+ */
+ if (base == 8 && c >= '8') {
+ parser.addWarning("msg.bad.octal.literal",
+ c == '8' ? "8" : "9");
+ base = 10;
+ }
+ addToString(c);
+ c = getChar();
+ }
+ }
+
+ boolean isInteger = true;
+
+ if (base == 10 && (c == '.' || c == 'e' || c == 'E')) {
+ isInteger = false;
+ if (c == '.') {
+ do {
+ addToString(c);
+ c = getChar();
+ } while (isDigit(c));
+ }
+ if (c == 'e' || c == 'E') {
+ addToString(c);
+ c = getChar();
+ if (c == '+' || c == '-') {
+ addToString(c);
+ c = getChar();
+ }
+ if (!isDigit(c)) {
+ parser.addError("msg.missing.exponent");
+ return Token.ERROR;
+ }
+ do {
+ addToString(c);
+ c = getChar();
+ } while (isDigit(c));
+ }
+ }
+ ungetChar(c);
+ String numString = getStringFromBuffer();
+
+ double dval;
+ if (base == 10 && !isInteger) {
+ try {
+ // Use Java conversion to number from string...
+ dval = Double.valueOf(numString).doubleValue();
+ }
+ catch (NumberFormatException ex) {
+ parser.addError("msg.caught.nfe");
+ return Token.ERROR;
+ }
+ } else {
+ dval = ScriptRuntime.stringToNumber(numString, 0, base);
+ }
+
+ this.number = dval;
+ return Token.NUMBER;
+ }
+
+ // is it a string?
+ if (c == '"' || c == '\'') {
+ // We attempt to accumulate a string the fast way, by
+ // building it directly out of the reader. But if there
+ // are any escaped characters in the string, we revert to
+ // building it out of a StringBuffer.
+
+ int quoteChar = c;
+ stringBufferTop = 0;
+
+ c = getChar();
+ while (c != quoteChar) {
+ if (c == '\n' || c == EOF_CHAR) {
+ ungetChar(c);
+ parser.addError("msg.unterminated.string.lit");
+ return Token.ERROR;
+ }
+
+ if (c == '\\') {
+ // We've hit an escaped character
+
+ c = getChar();
+
+ switch (c) {
+
+ case '\\': // backslash
+ case 'b': // backspace
+ case 'f': // form feed
+ case 'n': // line feed
+ case 'r': // carriage return
+ case 't': // horizontal tab
+ case 'v': // vertical tab
+ case 'd': // octal sequence
+ case 'u': // unicode sequence
+ case 'x': // hexadecimal sequence
+ // Only keep the '\' character for those
+ // characters that need to be escaped...
+ // Don't escape quoting characters...
+ addToString('\\');
+ addToString(c);
+ break;
+
+ case '\n':
+ // Remove line terminator after escape
+ break;
+
+ default:
+ if (isDigit(c)) {
+ // Octal representation of a character.
+ // Preserve the escaping (see Y! bug #1637286)
+ addToString('\\');
+ }
+ addToString(c);
+ break;
+ }
+
+ } else {
+
+ addToString(c);
+ }
+
+ c = getChar();
+ }
+
+ String str = getStringFromBuffer();
+ this.string = (String)allStrings.intern(str);
+ return Token.STRING;
+ }
+
+ switch (c) {
+ case ';': return Token.SEMI;
+ case '[': return Token.LB;
+ case ']': return Token.RB;
+ case '{': return Token.LC;
+ case '}': return Token.RC;
+ case '(': return Token.LP;
+ case ')': return Token.RP;
+ case ',': return Token.COMMA;
+ case '?': return Token.HOOK;
+ case ':':
+ if (matchChar(':')) {
+ return Token.COLONCOLON;
+ } else {
+ return Token.COLON;
+ }
+ case '.':
+ if (matchChar('.')) {
+ return Token.DOTDOT;
+ } else if (matchChar('(')) {
+ return Token.DOTQUERY;
+ } else {
+ return Token.DOT;
+ }
+
+ case '|':
+ if (matchChar('|')) {
+ return Token.OR;
+ } else if (matchChar('=')) {
+ return Token.ASSIGN_BITOR;
+ } else {
+ return Token.BITOR;
+ }
+
+ case '^':
+ if (matchChar('=')) {
+ return Token.ASSIGN_BITXOR;
+ } else {
+ return Token.BITXOR;
+ }
+
+ case '&':
+ if (matchChar('&')) {
+ return Token.AND;
+ } else if (matchChar('=')) {
+ return Token.ASSIGN_BITAND;
+ } else {
+ return Token.BITAND;
+ }
+
+ case '=':
+ if (matchChar('=')) {
+ if (matchChar('='))
+ return Token.SHEQ;
+ else
+ return Token.EQ;
+ } else {
+ return Token.ASSIGN;
+ }
+
+ case '!':
+ if (matchChar('=')) {
+ if (matchChar('='))
+ return Token.SHNE;
+ else
+ return Token.NE;
+ } else {
+ return Token.NOT;
+ }
+
+ case '<':
+ /* NB:treat HTML begin-comment as comment-till-eol */
+ if (matchChar('!')) {
+ if (matchChar('-')) {
+ if (matchChar('-')) {
+ skipLine();
+ continue retry;
+ }
+ ungetChar('-');
+ }
+ ungetChar('!');
+ }
+ if (matchChar('<')) {
+ if (matchChar('=')) {
+ return Token.ASSIGN_LSH;
+ } else {
+ return Token.LSH;
+ }
+ } else {
+ if (matchChar('=')) {
+ return Token.LE;
+ } else {
+ return Token.LT;
+ }
+ }
+
+ case '>':
+ if (matchChar('>')) {
+ if (matchChar('>')) {
+ if (matchChar('=')) {
+ return Token.ASSIGN_URSH;
+ } else {
+ return Token.URSH;
+ }
+ } else {
+ if (matchChar('=')) {
+ return Token.ASSIGN_RSH;
+ } else {
+ return Token.RSH;
+ }
+ }
+ } else {
+ if (matchChar('=')) {
+ return Token.GE;
+ } else {
+ return Token.GT;
+ }
+ }
+
+ case '*':
+ if (matchChar('=')) {
+ return Token.ASSIGN_MUL;
+ } else {
+ return Token.MUL;
+ }
+
+ case '/':
+ // is it a // comment?
+ if (matchChar('/')) {
+ skipLine();
+ continue retry;
+ }
+ if (matchChar('*')) {
+ boolean lookForSlash = false;
+ StringBuffer sb = new StringBuffer();
+ for (;;) {
+ c = getChar();
+ if (c == EOF_CHAR) {
+ parser.addError("msg.unterminated.comment");
+ return Token.ERROR;
+ }
+ sb.append((char) c);
+ if (c == '*') {
+ lookForSlash = true;
+ } else if (c == '/') {
+ if (lookForSlash) {
+ sb.delete(sb.length()-2, sb.length());
+ String s1 = sb.toString();
+ String s2 = s1.trim();
+ if (s1.startsWith("!")) {
+ // Remove the leading '!'
+ this.string = s1.substring(1);
+ return Token.KEEPCOMMENT;
+ } else if (s2.startsWith("@cc_on") ||
+ s2.startsWith("@if") ||
+ s2.startsWith("@elif") ||
+ s2.startsWith("@else") ||
+ s2.startsWith("@end")) {
+ this.string = s1;
+ return Token.CONDCOMMENT;
+ } else {
+ continue retry;
+ }
+ }
+ } else {
+ lookForSlash = false;
+ }
+ }
+ }
+
+ if (matchChar('=')) {
+ return Token.ASSIGN_DIV;
+ } else {
+ return Token.DIV;
+ }
+
+ case '%':
+ if (matchChar('=')) {
+ return Token.ASSIGN_MOD;
+ } else {
+ return Token.MOD;
+ }
+
+ case '~':
+ return Token.BITNOT;
+
+ case '+':
+ if (matchChar('=')) {
+ return Token.ASSIGN_ADD;
+ } else if (matchChar('+')) {
+ return Token.INC;
+ } else {
+ return Token.ADD;
+ }
+
+ case '-':
+ if (matchChar('=')) {
+ c = Token.ASSIGN_SUB;
+ } else if (matchChar('-')) {
+ if (!dirtyLine) {
+ // treat HTML end-comment after possible whitespace
+ // after line start as comment-utill-eol
+ if (matchChar('>')) {
+ skipLine();
+ continue retry;
+ }
+ }
+ c = Token.DEC;
+ } else {
+ c = Token.SUB;
+ }
+ dirtyLine = true;
+ return c;
+
+ default:
+ parser.addError("msg.illegal.character");
+ return Token.ERROR;
+ }
+ }
+ }
+
+ private static boolean isAlpha(int c)
+ {
+ // Use 'Z' < 'a'
+ if (c <= 'Z') {
+ return 'A' <= c;
+ } else {
+ return 'a' <= c && c <= 'z';
+ }
+ }
+
+ static boolean isDigit(int c)
+ {
+ return '0' <= c && c <= '9';
+ }
+
+ /* As defined in ECMA. jsscan.c uses C isspace() (which allows
+ * \v, I think.) note that code in getChar() implicitly accepts
+ * '\r' == \u000D as well.
+ */
+ static boolean isJSSpace(int c)
+ {
+ if (c <= 127) {
+ return c == 0x20 || c == 0x9 || c == 0xC || c == 0xB;
+ } else {
+ return c == 0xA0
+ || Character.getType((char)c) == Character.SPACE_SEPARATOR;
+ }
+ }
+
+ private static boolean isJSFormatChar(int c)
+ {
+ return c > 127 && Character.getType((char)c) == Character.FORMAT;
+ }
+
+ /**
+ * Parser calls the method when it gets / or /= in literal context.
+ */
+ void readRegExp(int startToken)
+ throws IOException
+ {
+ stringBufferTop = 0;
+ if (startToken == Token.ASSIGN_DIV) {
+ // Miss-scanned /=
+ addToString('=');
+ } else {
+ if (startToken != Token.DIV) Kit.codeBug();
+ }
+
+ int c;
+ boolean inClass = false;
+ while ((c = getChar()) != '/' || inClass) {
+ if (c == '\n' || c == EOF_CHAR) {
+ ungetChar(c);
+ throw parser.reportError("msg.unterminated.re.lit");
+ }
+ if (c == '\\') {
+ addToString(c);
+ c = getChar();
+ } else if (c == '[') {
+ inClass = true;
+ } else if (c == ']') {
+ inClass = false;
+ }
+
+ addToString(c);
+ }
+ int reEnd = stringBufferTop;
+
+ while (true) {
+ if (matchChar('g'))
+ addToString('g');
+ else if (matchChar('i'))
+ addToString('i');
+ else if (matchChar('m'))
+ addToString('m');
+ else
+ break;
+ }
+
+ if (isAlpha(peekChar())) {
+ throw parser.reportError("msg.invalid.re.flag");
+ }
+
+ this.string = new String(stringBuffer, 0, reEnd);
+ this.regExpFlags = new String(stringBuffer, reEnd,
+ stringBufferTop - reEnd);
+ }
+
+ boolean isXMLAttribute()
+ {
+ return xmlIsAttribute;
+ }
+
+ int getFirstXMLToken() throws IOException
+ {
+ xmlOpenTagsCount = 0;
+ xmlIsAttribute = false;
+ xmlIsTagContent = false;
+ ungetChar('<');
+ return getNextXMLToken();
+ }
+
+ int getNextXMLToken() throws IOException
+ {
+ stringBufferTop = 0; // remember the XML
+
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ if (xmlIsTagContent) {
+ switch (c) {
+ case '>':
+ addToString(c);
+ xmlIsTagContent = false;
+ xmlIsAttribute = false;
+ break;
+ case '/':
+ addToString(c);
+ if (peekChar() == '>') {
+ c = getChar();
+ addToString(c);
+ xmlIsTagContent = false;
+ xmlOpenTagsCount--;
+ }
+ break;
+ case '{':
+ ungetChar(c);
+ this.string = getStringFromBuffer();
+ return Token.XML;
+ case '\'':
+ case '"':
+ addToString(c);
+ if (!readQuotedString(c)) return Token.ERROR;
+ break;
+ case '=':
+ addToString(c);
+ xmlIsAttribute = true;
+ break;
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n':
+ addToString(c);
+ break;
+ default:
+ addToString(c);
+ xmlIsAttribute = false;
+ break;
+ }
+
+ if (!xmlIsTagContent && xmlOpenTagsCount == 0) {
+ this.string = getStringFromBuffer();
+ return Token.XMLEND;
+ }
+ } else {
+ switch (c) {
+ case '<':
+ addToString(c);
+ c = peekChar();
+ switch (c) {
+ case '!':
+ c = getChar(); // Skip !
+ addToString(c);
+ c = peekChar();
+ switch (c) {
+ case '-':
+ c = getChar(); // Skip -
+ addToString(c);
+ c = getChar();
+ if (c == '-') {
+ addToString(c);
+ if(!readXmlComment()) return Token.ERROR;
+ } else {
+ // throw away the string in progress
+ stringBufferTop = 0;
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+ break;
+ case '[':
+ c = getChar(); // Skip [
+ addToString(c);
+ if (getChar() == 'C' &&
+ getChar() == 'D' &&
+ getChar() == 'A' &&
+ getChar() == 'T' &&
+ getChar() == 'A' &&
+ getChar() == '[')
+ {
+ addToString('C');
+ addToString('D');
+ addToString('A');
+ addToString('T');
+ addToString('A');
+ addToString('[');
+ if (!readCDATA()) return Token.ERROR;
+
+ } else {
+ // throw away the string in progress
+ stringBufferTop = 0;
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+ break;
+ default:
+ if(!readEntity()) return Token.ERROR;
+ break;
+ }
+ break;
+ case '?':
+ c = getChar(); // Skip ?
+ addToString(c);
+ if (!readPI()) return Token.ERROR;
+ break;
+ case '/':
+ // End tag
+ c = getChar(); // Skip /
+ addToString(c);
+ if (xmlOpenTagsCount == 0) {
+ // throw away the string in progress
+ stringBufferTop = 0;
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+ xmlIsTagContent = true;
+ xmlOpenTagsCount--;
+ break;
+ default:
+ // Start tag
+ xmlIsTagContent = true;
+ xmlOpenTagsCount++;
+ break;
+ }
+ break;
+ case '{':
+ ungetChar(c);
+ this.string = getStringFromBuffer();
+ return Token.XML;
+ default:
+ addToString(c);
+ break;
+ }
+ }
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+
+ /**
+ *
+ */
+ private boolean readQuotedString(int quote) throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ addToString(c);
+ if (c == quote) return true;
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readXmlComment() throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR;) {
+ addToString(c);
+ if (c == '-' && peekChar() == '-') {
+ c = getChar();
+ addToString(c);
+ if (peekChar() == '>') {
+ c = getChar(); // Skip >
+ addToString(c);
+ return true;
+ } else {
+ continue;
+ }
+ }
+ c = getChar();
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readCDATA() throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR;) {
+ addToString(c);
+ if (c == ']' && peekChar() == ']') {
+ c = getChar();
+ addToString(c);
+ if (peekChar() == '>') {
+ c = getChar(); // Skip >
+ addToString(c);
+ return true;
+ } else {
+ continue;
+ }
+ }
+ c = getChar();
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readEntity() throws IOException
+ {
+ int declTags = 1;
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ addToString(c);
+ switch (c) {
+ case '<':
+ declTags++;
+ break;
+ case '>':
+ declTags--;
+ if (declTags == 0) return true;
+ break;
+ }
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readPI() throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ addToString(c);
+ if (c == '?' && peekChar() == '>') {
+ c = getChar(); // Skip >
+ addToString(c);
+ return true;
+ }
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ private String getStringFromBuffer()
+ {
+ return new String(stringBuffer, 0, stringBufferTop);
+ }
+
+ private void addToString(int c)
+ {
+ int N = stringBufferTop;
+ if (N == stringBuffer.length) {
+ char[] tmp = new char[stringBuffer.length * 2];
+ System.arraycopy(stringBuffer, 0, tmp, 0, N);
+ stringBuffer = tmp;
+ }
+ stringBuffer[N] = (char)c;
+ stringBufferTop = N + 1;
+ }
+
+ private void ungetChar(int c)
+ {
+ // can not unread past across line boundary
+ if (ungetCursor != 0 && ungetBuffer[ungetCursor - 1] == '\n')
+ Kit.codeBug();
+ ungetBuffer[ungetCursor++] = c;
+ }
+
+ private boolean matchChar(int test) throws IOException
+ {
+ int c = getChar();
+ if (c == test) {
+ return true;
+ } else {
+ ungetChar(c);
+ return false;
+ }
+ }
+
+ private int peekChar() throws IOException
+ {
+ int c = getChar();
+ ungetChar(c);
+ return c;
+ }
+
+ private int getChar() throws IOException
+ {
+ if (ungetCursor != 0) {
+ return ungetBuffer[--ungetCursor];
+ }
+
+ for(;;) {
+ int c;
+ if (sourceString != null) {
+ if (sourceCursor == sourceEnd) {
+ hitEOF = true;
+ return EOF_CHAR;
+ }
+ c = sourceString.charAt(sourceCursor++);
+ } else {
+ if (sourceCursor == sourceEnd) {
+ if (!fillSourceBuffer()) {
+ hitEOF = true;
+ return EOF_CHAR;
+ }
+ }
+ c = sourceBuffer[sourceCursor++];
+ }
+
+ if (lineEndChar >= 0) {
+ if (lineEndChar == '\r' && c == '\n') {
+ lineEndChar = '\n';
+ continue;
+ }
+ lineEndChar = -1;
+ lineStart = sourceCursor - 1;
+ lineno++;
+ }
+
+ if (c <= 127) {
+ if (c == '\n' || c == '\r') {
+ lineEndChar = c;
+ c = '\n';
+ }
+ } else {
+ if (isJSFormatChar(c)) {
+ continue;
+ }
+ if (ScriptRuntime.isJSLineTerminator(c)) {
+ lineEndChar = c;
+ c = '\n';
+ }
+ }
+ return c;
+ }
+ }
+
+ private void skipLine() throws IOException
+ {
+ // skip to end of line
+ int c;
+ while ((c = getChar()) != EOF_CHAR && c != '\n') { }
+ ungetChar(c);
+ }
+
+ final int getOffset()
+ {
+ int n = sourceCursor - lineStart;
+ if (lineEndChar >= 0) { --n; }
+ return n;
+ }
+
+ final String getLine()
+ {
+ if (sourceString != null) {
+ // String case
+ int lineEnd = sourceCursor;
+ if (lineEndChar >= 0) {
+ --lineEnd;
+ } else {
+ for (; lineEnd != sourceEnd; ++lineEnd) {
+ int c = sourceString.charAt(lineEnd);
+ if (ScriptRuntime.isJSLineTerminator(c)) {
+ break;
+ }
+ }
+ }
+ return sourceString.substring(lineStart, lineEnd);
+ } else {
+ // Reader case
+ int lineLength = sourceCursor - lineStart;
+ if (lineEndChar >= 0) {
+ --lineLength;
+ } else {
+ // Read until the end of line
+ for (;; ++lineLength) {
+ int i = lineStart + lineLength;
+ if (i == sourceEnd) {
+ try {
+ if (!fillSourceBuffer()) { break; }
+ } catch (IOException ioe) {
+ // ignore it, we're already displaying an error...
+ break;
+ }
+ // i recalculuation as fillSourceBuffer can move saved
+ // line buffer and change lineStart
+ i = lineStart + lineLength;
+ }
+ int c = sourceBuffer[i];
+ if (ScriptRuntime.isJSLineTerminator(c)) {
+ break;
+ }
+ }
+ }
+ return new String(sourceBuffer, lineStart, lineLength);
+ }
+ }
+
+ private boolean fillSourceBuffer() throws IOException
+ {
+ if (sourceString != null) Kit.codeBug();
+ if (sourceEnd == sourceBuffer.length) {
+ if (lineStart != 0) {
+ System.arraycopy(sourceBuffer, lineStart, sourceBuffer, 0,
+ sourceEnd - lineStart);
+ sourceEnd -= lineStart;
+ sourceCursor -= lineStart;
+ lineStart = 0;
+ } else {
+ char[] tmp = new char[sourceBuffer.length * 2];
+ System.arraycopy(sourceBuffer, 0, tmp, 0, sourceEnd);
+ sourceBuffer = tmp;
+ }
+ }
+ int n = sourceReader.read(sourceBuffer, sourceEnd,
+ sourceBuffer.length - sourceEnd);
+ if (n < 0) {
+ return false;
+ }
+ sourceEnd += n;
+ return true;
+ }
+
+ // stuff other than whitespace since start of line
+ private boolean dirtyLine;
+
+ String regExpFlags;
+
+ // Set this to an inital non-null value so that the Parser has
+ // something to retrieve even if an error has occured and no
+ // string is found. Fosters one class of error, but saves lots of
+ // code.
+ private String string = "";
+ private double number;
+
+ private char[] stringBuffer = new char[128];
+ private int stringBufferTop;
+ private ObjToIntMap allStrings = new ObjToIntMap(50);
+
+ // Room to backtrace from to < on failed match of the last - in