Advanced Feature

Sometimes the default behavior just might not work for your needs, and finer control over which transformations are applied to the input sources are required. In such cases, “kill bits” may be applied to the Ajax Minifier instance using the –kill switch. A kill switch is a 64-bit number, which can be represented in decimal or hexadecimal. Almost every class of transformations AjaxMin performs has a particular bit that can be flipped in that kill switch to indicate that those transformations should not be performed.

For example, one of the default transformations applied by Ajax Minifier is converting member-bracket operators into member-dot operators when the member-bracket operand is a string literal that can be a valid JavaScript operator:

A["B"]; // transforms to A.B

The TreeModifications.BracketMemberToDotMember value is 2 (bit 1), so if this transform is not desired, the switch –kill:2 can be applied to the execution instance. To turn off all the transformations at once, try –kill:-1.

If you are familiar with the Ajax Minifier sources, the enumeration that lists all the possible kill bites is TreeModifications in the file codesettings.cs:

[Flags]
public enum TreeModifications : long
{
    /// <summary>
    /// Default. No specific tree modification
    /// </summary>
    None                                        = 0x0000000000000000,

    /// <summary>
    /// Preserve "important" comments in output: /*! ... */
    /// </summary>
    PreserveImportantComments                   = 0x0000000000000001,

    /// <summary>
    /// Replace a member-bracket call with a member-dot construct if the member
    /// name is a string literal that can be an identifier.
    /// A["B"] ==&gt; A.B
    /// </summary>
    BracketMemberToDotMember                    = 0x0000000000000002,

    /// <summary>
    /// Replace a new Object constructor call with an object literal
    /// new Object() ==&gt; {}
    /// </summary>
    NewObjectToObjectLiteral                    = 0x0000000000000004,

    /// <summary>
    /// Change Array constructor calls with array literals.
    /// Does not replace constructors called with a single numeric parameter
    /// (could be a capacity contructor call).
    /// new Array() ==&gt; []
    /// new Array(A,B,C) ==&gt; [A,B,C]
    /// </summary>
    NewArrayToArrayLiteral                      = 0x0000000000000008,

    /// <summary>
    /// Remove the default case in a switch statement if the block contains
    /// only a break statement.
    /// remove default:break;
    /// </summary>
    RemoveEmptyDefaultCase                      = 0x0000000000000010,

    /// <summary>
    /// If there is no default case, remove any case statements that contain
    /// only a single break statement.
    /// remove case A:break;
    /// </summary>
    RemoveEmptyCaseWhenNoDefault                = 0x0000000000000020,

    /// <summary>
    /// Remove the break statement from the last case block of a switch statement.
    /// switch(A){case B: C;break;} ==&gt; switch(A){case B:C;}
    /// </summary>
    RemoveBreakFromLastCaseBlock                = 0x0000000000000040,

    /// <summary>
    /// Remove an empty finally statement if there is a non-empty catch block.
    /// try{...}catch(E){...}finally{} ==&gt; try{...}catch(E){...}
    /// </summary>
    RemoveEmptyFinally                          = 0x0000000000000080,

    /// <summary>
    /// Remove duplicate var declarations in a var statement that have no initializers.
    /// var A,A=B  ==&gt;  var A=B
    /// var A=B,A  ==&gt;  var A=B
    /// </summary>
    RemoveDuplicateVar                          = 0x0000000000000100,

    /// <summary>
    /// Combine adjacent var statements.
    /// var A;var B  ==&gt;  var A,B
    /// </summary>
    CombineVarStatements                        = 0x0000000000000200,

    /// <summary>
    /// Move preceeding var statement into the initializer of the for statement.
    /// var A;for(var B;;);  ==&gt;  for(var A,B;;);
    /// var A;for(;;)  ==&gt; for(var A;;)
    /// </summary>
    MoveVarIntoFor                              = 0x0000000000000400,

    /// <summary>
    /// Combine adjacent var statement and return statement to a single return statement
    /// var A=B;return A  ==&gt; return B
    /// </summary>
    VarInitializeReturnToReturnInitializer      = 0x0000000000000800,

    /// <summary>
    /// Replace an if-statement that has empty true and false branches with just the 
    /// condition expression.
    /// if(A);else;  ==&gt; A;
    /// </summary>
    IfEmptyToExpression                         = 0x0000000000001000,

    /// <summary>
    /// replace if-statement that only has a single call statement in the true branch
    /// with a logical-and statement
    /// if(A)B() ==&gt; A&amp;&amp;B()
    /// </summary>
    IfConditionCallToConditionAndCall           = 0x0000000000002000,

    /// <summary>
    /// Replace an if-else-statement where both branches are only a single return
    /// statement with a single return statement and a conditional operator.
    /// if(A)return B;else return C  ==&gt;  return A?B:C 
    /// </summary>
    IfElseReturnToReturnConditional             = 0x0000000000004000,

    /// <summary>
    /// If a function ends in an if-statement that only has a true-branch containing
    /// a single return statement with no operand, replace the if-statement with just
    /// the condition expression.
    /// function A(...){...;if(B)return}  ==&gt; function A(...){...;B}
    /// </summary>
    IfConditionReturnToCondition                = 0x0000000000008000,

    /// <summary>
    /// If the true-block of an if-statment is empty and the else-block is not,
    /// negate the condition and move the else-block to the true-block.
    /// if(A);else B  ==&gt;  if(!A)B
    /// </summary>
    IfConditionFalseToIfNotConditionTrue        = 0x0000000000010000,

    /// <summary>
    /// Combine adjacent string literals.
    /// "A"+"B"  ==&gt; "AB"
    /// </summary>
    CombineAdjacentStringLiterals               = 0x0000000000020000,

    /// <summary>
    /// Remove unary-plus operators when the operand is a numeric literal
    /// +123  ==&gt;  123
    /// </summary>
    RemoveUnaryPlusOnNumericLiteral             = 0x0000000000040000,

    /// <summary>
    /// Apply (and cascade) unary-minus operators to the value of a numeric literal
    /// -(4)  ==&gt;  -4   (unary minus applied to a numeric 4 ==&gt; numeric -4)
    /// -(-4)  ==&gt;  4   (same as above, but cascading)
    /// </summary>
    ApplyUnaryMinusToNumericLiteral             = 0x0000000000080000,

    /// <summary>
    /// Apply minification technics to string literals
    /// </summary>
    MinifyStringLiterals                        = 0x0000000000100000,

    /// <summary>
    /// Apply minification techniques to numeric literals
    /// </summary>
    MinifyNumericLiterals                       = 0x0000000000200000,

    /// <summary>
    /// Remove unused function parameters
    /// </summary>
    RemoveUnusedParameters                      = 0x0000000000400000,

    /// <summary>
    /// remove "debug" statements
    /// </summary>
    StripDebugStatements                        = 0x0000000000800000,

    /// <summary>
    /// Rename local variables and functions
    /// </summary>
    LocalRenaming                               = 0x0000000001000000,

    /// <summary>
    /// Remove unused function expression names
    /// </summary>
    RemoveFunctionExpressionNames               = 0x0000000002000000,

    /// <summary>
    /// Remove unnecessary labels from break or continue statements
    /// </summary>
    RemoveUnnecessaryLabels                     = 0x0000000004000000,

    /// <summary>
    /// Remove unnecessary @cc_on statements
    /// </summary>
    RemoveUnnecessaryCCOnStatements             = 0x0000000008000000,

    /// <summary>
    /// Convert (new Date()).getTime() to +new Date
    /// </summary>
    DateGetTimeToUnaryPlus                      = 0x0000000010000000,

    /// <summary>
    /// Evaluate numeric literal expressions.
    /// 1 + 2  ==&gt; 3
    /// </summary>
    EvaluateNumericExpressions                  = 0x0000000020000000,

    /// <summary>
    /// Simplify a common method on converting string to numeric: 
    /// lookup - 0  ==&gt; +lookup
    /// (Subtracting zero converts lookup to number, then doesn't modify
    /// it; unary plus also converts operand to numeric)
    /// </summary>
    SimplifyStringToNumericConversion           = 0x0000000040000000,

    /// <summary>
    /// Rename properties in object literals, member-dot, and member-bracket operations
    /// </summary>
    PropertyRenaming                            = 0x0000000080000000,

    /// <summary>
    /// Use preprocessor defines and the ///#IFDEF directive
    /// </summary>
    PreprocessorDefines                         = 0x0000000100000000,

    /// <summary>
    /// Remove the quotes arounf objectl literal property names when
    /// the names are valid identifiers.
    /// </summary>
    RemoveQuotesFromObjectLiteralNames          = 0x0000000200000000,

    /// <summary>
    /// Change boolean literals to not operators.
    /// true  -> !0
    /// false -> !1
    /// </summary>
    BooleanLiteralsToNotOperators               = 0x0000000400000000,

    /// <summary>
    /// Change if-statements with expression statements as their branches to expressions
    /// </summary>
    IfExpressionsToExpression                   = 0x0000000800000000,

    /// <summary>
    /// Combine adjacent expression statements into a single expression statement
    /// using the comma operator
    /// </summary>
    CombineAdjacentExpressionStatements         = 0x0000001000000000,

    /// <summary>
    /// If the types of both sides of a strict operator (=== or !==) are known
    /// to be the same, we can reduce the operators to == or !=
    /// </summary>
    ReduceStrictOperatorIfTypesAreSame          = 0x0000002000000000,

    /// <summary>
    /// If the types of both sides of a strict operator (=== or !==) are known
    /// to be different, than we can reduct the binary operator to false or true (respectively)
    /// </summary>
    ReduceStrictOperatorIfTypesAreDifferent     = 0x0000004000000000,

    /// <summary>
    /// Move function declarations to the top of the containing scope
    /// </summary>
    MoveFunctionToTopOfScope                    = 0x0000008000000000,

    /// <summary>
    /// Combine var statements at the top of the containing scope
    /// </summary>
    CombineVarStatementsToTopOfScope            = 0x0000010000000000,

    /// <summary>
    /// If the condition of an if-statement or conditional starts with a not-operator,
    /// get rid of the not-operator and swap the true/false branches.
    /// </summary>
    IfNotTrueFalseToIfFalseTrue                 = 0x0000020000000000,
}

Last edited Jun 13, 2011 at 1:46 AM by ronlo, version 3

Comments

No comments yet.