diff options
author | Egil Moeller <egil.moller@freecode.no> | 2010-03-21 23:33:06 +0100 |
---|---|---|
committer | Egil Moeller <egil.moller@freecode.no> | 2010-03-21 23:33:06 +0100 |
commit | d56b9b3b82cdebcaeb00eec0fcb4326ad21adaa8 (patch) | |
tree | b1dfe31956f3fc86e3408f1efac5e12acf65b11a /infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java | |
parent | c1894c8e0a52f4e3d2f89fa92f0066bbf0fcf1b1 (diff) | |
parent | 103d4926ae6c61824dc0b48be7bf66f08830ed47 (diff) | |
download | etherpad-d56b9b3b82cdebcaeb00eec0fcb4326ad21adaa8.tar.gz etherpad-d56b9b3b82cdebcaeb00eec0fcb4326ad21adaa8.tar.bz2 etherpad-d56b9b3b82cdebcaeb00eec0fcb4326ad21adaa8.zip |
Merge branch 'master' of git@github.com:ether/pad
Diffstat (limited to 'infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java')
-rw-r--r-- | infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java b/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java new file mode 100644 index 0000000..c1a2e47 --- /dev/null +++ b/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java @@ -0,0 +1,169 @@ +/* + * YUI Compressor + * Author: Julien Lecomte <jlecomte@yahoo-inc.com> + * 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..."); + } + + // APPJET: sort identifiers by popularity + JavaScriptIdentifier idArray[] = ((Hashtable<String,JavaScriptIdentifier>)identifiers).values().toArray(new JavaScriptIdentifier[0]); + java.util.Arrays.sort(idArray, new java.util.Comparator<JavaScriptIdentifier>() { + public int compare(JavaScriptIdentifier i1, JavaScriptIdentifier i2) { + return i2.getRefcount() - i1.getRefcount(); // positive if i2 is more popular, indicating i2 should come first + } + }); + java.util.Iterator<JavaScriptIdentifier> elements = java.util.Arrays.asList(idArray).iterator(); + + //Enumeration elements = identifiers.elements(); + while (elements.hasNext()) { + 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.next(); + 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(); + } + } +} |