diff --git a/.classpath b/.classpath new file mode 100644 index 00000000..b19323c6 --- /dev/null +++ b/.classpath @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 00000000..b0157db8 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + yuicompressor + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/src/com/yahoo/platform/yui/compressor/JavaScriptCompressor.java b/src/com/yahoo/platform/yui/compressor/JavaScriptCompressor.java index c123f9bb..acb5ef9d 100644 --- a/src/com/yahoo/platform/yui/compressor/JavaScriptCompressor.java +++ b/src/com/yahoo/platform/yui/compressor/JavaScriptCompressor.java @@ -8,242 +8,31 @@ */ 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.lang.ref.SoftReference; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Map; +import java.util.Set; +import java.util.Stack; +import java.util.StringTokenizer; 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)); - } +import org.mozilla.javascript.CompilerEnvirons; +import org.mozilla.javascript.Context; +import org.mozilla.javascript.ErrorReporter; +import org.mozilla.javascript.EvaluatorException; +import org.mozilla.javascript.Parser; +import org.mozilla.javascript.ScriptRuntime; +import org.mozilla.javascript.Token; - // 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)); - } +public class JavaScriptCompressor { - // 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), "@"); - literals.put(new Integer(Token.LET), "let "); - literals.put(new Integer(Token.YIELD), "yield "); - - // 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 SoftReference sharedJavaScriptWords; private static int countChar(String haystack, char needle) { int idx = 0; @@ -341,7 +130,7 @@ private static ArrayList parse(Reader in, ErrorReporter reporter) break; default: - String literal = (String) literals.get(new Integer(tt)); + String literal = (String) javaScriptWords().literals.get(new Integer(tt)); if (literal != null) { tokens.add(new JavaScriptToken(tt, literal)); } @@ -458,7 +247,7 @@ private static String escapeString(String s, char quotechar) { private static boolean isValidIdentifier(String s) { Matcher m = SIMPLE_IDENTIFIER_NAME_PATTERN.matcher(s); - return (m.matches() && !reserved.contains(s)); + return (m.matches() && !javaScriptWords().reserved.contains(s)); } /* @@ -528,13 +317,46 @@ private static void optimizeObjLitMemberDecl(ArrayList tokens) { private Stack scopes = new Stack(); private ScriptOrFnScope globalScope = new ScriptOrFnScope(-1, null); private Hashtable indexedScopes = new Hashtable(); + + private JavaScriptWords words; + + private ArrayList ones; + private ArrayList twos; + private ArrayList threes; + + private Set builtin = new HashSet(); + private Map literals = new Hashtable(); + private Set reserved = new HashSet(); public JavaScriptCompressor(Reader in, ErrorReporter reporter) throws IOException, EvaluatorException { + prepareJavaScriptWords(); + this.logger = reporter; this.tokens = parse(in, reporter); } + + private void prepareJavaScriptWords() { + /* Create a strong reference to the precompute so that it isn't gc'd while we're alive */ + words = javaScriptWords(); + + ones = words.ones; + twos = words.twos; + threes = words.threes; + builtin = words.builtin; + literals = words.literals; + reserved = words.reserved; + } + + static JavaScriptWords javaScriptWords() { + JavaScriptWords words = sharedJavaScriptWords != null ? (JavaScriptWords) sharedJavaScriptWords.get() : null; + if (words == null) { + words = new JavaScriptWords(); + sharedJavaScriptWords = new SoftReference(words); + } + return words; + } public void compress(Writer out, Writer mungemap, int linebreak, boolean munge, boolean verbose, boolean preserveAllSemiColons, boolean disableOptimizations) @@ -1083,15 +905,18 @@ private void mungeSymboltree() { scopes.clear(); mode = CHECKING_SYMBOL_TREE; parseScope(globalScope); - globalScope.munge(); + globalScope.munge(words); } private StringBuffer printSymbolTree(int linebreakpos, boolean preserveAllSemiColons) throws IOException { - + offset = 0; braceNesting = 0; scopes.clear(); + + if (tokens.isEmpty()) + return new StringBuffer(); String symbol; JavaScriptToken token; diff --git a/src/com/yahoo/platform/yui/compressor/JavaScriptWords.java b/src/com/yahoo/platform/yui/compressor/JavaScriptWords.java new file mode 100644 index 00000000..49fc15fd --- /dev/null +++ b/src/com/yahoo/platform/yui/compressor/JavaScriptWords.java @@ -0,0 +1,238 @@ +package com.yahoo.platform.yui.compressor; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Map; +import java.util.Set; + +import org.mozilla.javascript.Token; + +public class JavaScriptWords { + + final ArrayList ones; + final ArrayList twos; + final ArrayList threes; + + final Set builtin = new HashSet(); + final Map literals = new Hashtable(); + final Set reserved = new HashSet(); + + public JavaScriptWords() { + // 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), "@"); + literals.put(new Integer(Token.LET), "let "); + literals.put(new Integer(Token.YIELD), "yield "); + + // 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"); + } + +} diff --git a/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java b/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java index 4b7b836b..bb47885c 100644 --- a/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java +++ b/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java @@ -112,7 +112,7 @@ public void getFullMapping(StringBuffer outBuffer, String mungedPrefix) { } } - void munge() { + void munge(JavaScriptWords words) { if (!markedForMunging) { // Stop right here if this scope was flagged as unsafe for munging. @@ -126,16 +126,16 @@ void munge() { ArrayList freeSymbols = new ArrayList(); - freeSymbols.addAll(JavaScriptCompressor.ones); + freeSymbols.addAll(words.ones); freeSymbols.removeAll(getAllUsedSymbols()); if (freeSymbols.size() == 0) { pickFromSet = 2; - freeSymbols.addAll(JavaScriptCompressor.twos); + freeSymbols.addAll(words.twos); freeSymbols.removeAll(getAllUsedSymbols()); } if (freeSymbols.size() == 0) { pickFromSet = 3; - freeSymbols.addAll(JavaScriptCompressor.threes); + freeSymbols.addAll(words.threes); freeSymbols.removeAll(getAllUsedSymbols()); } if (freeSymbols.size() == 0) { @@ -147,9 +147,9 @@ void munge() { if (freeSymbols.size() == 0) { pickFromSet++; if (pickFromSet == 2) { - freeSymbols.addAll(JavaScriptCompressor.twos); + freeSymbols.addAll(words.twos); } else if (pickFromSet == 3) { - freeSymbols.addAll(JavaScriptCompressor.threes); + freeSymbols.addAll(words.threes); } else { throw new IllegalStateException("The YUI Compressor ran out of symbols. Aborting..."); } @@ -173,7 +173,7 @@ void munge() { for (int i = 0; i < subScopes.size(); i++) { ScriptOrFnScope scope = (ScriptOrFnScope) subScopes.get(i); - scope.munge(); + scope.munge(words); } } } diff --git a/src/org/mozilla/javascript/Parser.java b/src/org/mozilla/javascript/Parser.java index 984358a6..e406f4dd 100644 --- a/src/org/mozilla/javascript/Parser.java +++ b/src/org/mozilla/javascript/Parser.java @@ -150,11 +150,26 @@ private int peekToken() { int tt = currentFlaggedToken; if (tt == Token.EOF) { - tt = ts.getToken(); + 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(); - } while (tt == Token.EOL); + 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;