Beispiel #1
0
        public override string ToCode(ToCodeFormat format)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("for(");
            if (Initializer != null)
            {
                sb.Append(Initializer.ToCode());
            }
            sb.Append(';');
            CodeSettings codeSettings = Parser.Settings;

            if (codeSettings.OutputMode == OutputMode.MultipleLines && codeSettings.IndentSize > 0)
            {
                sb.Append(' ');
            }
            if (Condition != null)
            {
                sb.Append(Condition.ToCode());
            }
            sb.Append(';');
            if (codeSettings.OutputMode == OutputMode.MultipleLines && codeSettings.IndentSize > 0)
            {
                sb.Append(' ');
            }
            if (Incrementer != null)
            {
                sb.Append(Incrementer.ToCode());
            }
            sb.Append(')');
            string bodyString = (
                Body == null
              ? string.Empty
              : Body.ToCode()
                );

            sb.Append(bodyString);
            return(sb.ToString());
        }
Beispiel #2
0
        internal GlobalScope(CodeSettings settings)
            : base(null, settings)
        {
            ScopeType = ScopeType.Global;

            // define the Global object's properties, and methods
            m_globalProperties = new HashSet <string> {
                "__proto__",
                "Crypto",
                "Infinity", "Intl",
                "JSON",
                "Math",
                "NaN",
                "System",
                "Windows", "WinJS",
                "applicationCache",
                "chrome", "clientInformation", "clipboardData", "closed", "console", "crypto",
                "defaultStatus", "devicePixelRatio", "document",
                "event", "external",
                "frameElement", "frames",
                "history",
                "indexedDB", "innerHeight", "innerWidth",
                "length", "localStorage", "location",
                "name", "navigator",
                "offscreenBuffering", "opener", "outerHeight", "outerWidth",
                "pageXOffset", "pageYOffset", "parent", "performance",
                "screen", "screenLeft", "screenTop", "screenX", "screenY", "self", "sessionStorage", "status",
                "top",
                "undefined",
                "window"
            };

            m_globalFunctions = new HashSet <string> {
                "ActiveXObject", "Array", "ArrayBuffer", "ArrayBufferView",
                "Boolean",
                "DataView", "Date", "Debug", "DocumentTouch", "DOMParser",
                "Error", "EvalError", "EventSource",
                "File", "FileList", "FileReader", "Float32Array", "Float64Array", "Function",
                "Image", "Int16Array", "Int32Array", "Int8Array", "Iterator",
                "Map",
                "Node", "NodeFilter", "NodeIterator", "NodeList", "NodeSelector", "Number",
                "Object",
                "Proxy",
                "RangeError", "ReferenceError", "RegExp",
                "Set", "SharedWorker", "String", "SyntaxError",
                "TypeError",
                "Uint8Array", "Uint8ClampedArray", "Uint16Array", "Uint32Array", "URIError", "URL",
                "WeakMap", "WebSocket", "Worker",
                "XDomainRequest", "XMLHttpRequest",
                "addEventListener", "alert", "attachEvent",
                "blur",
                "cancelAnimationFrame", "captureEvents", "clearImmediate", "clearInterval", "clearTimeout", "close", "confirm", "createPopup",
                "decodeURI", "decodeURIComponent", "detachEvent", "dispatchEvent",
                "encodeURI", "encodeURIComponent", "escape", "eval", "execScript",
                "focus",
                "getComputedStyle", "getSelection",
                "importScripts", "isFinite", "isNaN",
                "matchMedia", "moveBy", "moveTo",
                "navigate",
                "open",
                "parseFloat", "parseInt", "postMessage", "prompt",
                "releaseEvents", "removeEventListener", "requestAnimationFrame", "resizeBy", "resizeTo",
                "scroll", "scrollBy", "scrollTo", "setActive", "setImmediate", "setInterval", "setTimeout", "showModalDialog", "showModelessDialog", "styleMedia",
                "unescape"
            };
        }
Beispiel #3
0
 internal CatchScope(ActivationObject parent, CodeSettings settings)
     : base(parent, settings, ScopeType.Catch)
 {
 }
Beispiel #4
0
        /// <summary>
        /// Crunched JS string passed to it, returning crunched string.
        /// The ErrorList property will be set with any errors found during the minification process.
        /// </summary>
        /// <param name="source">source Javascript</param>
        /// <param name="codeSettings">code minification settings</param>
        /// <returns>minified Javascript</returns>
        public string MinifyJavaScript(string source, CodeSettings codeSettings)
        {
            // default is an empty string
            var crunched = string.Empty;

            // reset the errors builder
            m_errorList = new List <ContextError>();

            // create the parser and hook the engine error event
            var parser = new JSParser();

            parser.CompilerError += OnJavaScriptError;

            try
            {
                var preprocessOnly = codeSettings != null && codeSettings.PreprocessOnly;
                var sb             = new StringBuilder();
                using (var stringWriter = new StringWriter(sb, CultureInfo.InvariantCulture))
                {
                    if (preprocessOnly)
                    {
                        parser.EchoWriter = stringWriter;
                    }

                    // parse the input
                    var scriptBlock = parser.Parse(new DocumentContext(source)
                    {
                        FileContext = this.FileName
                    }, codeSettings);
                    if (scriptBlock != null && !preprocessOnly)
                    {
                        // we'll return the crunched code
                        if (codeSettings != null && codeSettings.Format == JavaScriptFormat.JSON)
                        {
                            // we're going to use a different output visitor -- one
                            // that specifically returns valid JSON.
                            if (!JSONOutputVisitor.Apply(stringWriter, scriptBlock, codeSettings))
                            {
                                m_errorList.Add(new ContextError()
                                {
                                    Severity = 0,
                                    File     = this.FileName,
                                    Message  = CommonStrings.InvalidJSONOutput,
                                });
                            }
                        }
                        else
                        {
                            // just use the normal output visitor
                            OutputVisitor.Apply(stringWriter, scriptBlock, codeSettings);
                        }
                    }
                }

                crunched = sb.ToString();
            }
            catch (Exception e)
            {
                m_errorList.Add(new ContextError()
                {
                    Severity = 0,
                    File     = this.FileName,
                    Message  = e.Message,
                });
                throw;
            }

            return(crunched);
        }
 public RequiresSeparatorVisitor(CodeSettings settings)
 {
     // requires by default unless a node explicitly says it doesn't need one
     DoesRequire = true;
     m_settings = settings ?? new CodeSettings();
 }
Beispiel #6
0
        /// <summary>
        /// Instantiate a new CodeSettings object with the same settings as the current object.
        /// </summary>
        /// <returns>a copy CodeSettings object</returns>
        public CodeSettings Clone()
        {
            // create a new settings object and set all the properties using this settings object
            var newSettings = new CodeSettings()
            {
                // set the field, not the property. Setting the property will set a bunch of
                // other properties, which may not represent their actual values.
                m_minify = this.m_minify,

                AllowEmbeddedAspNetBlocks = this.AllowEmbeddedAspNetBlocks,
                AlwaysEscapeNonAscii      = this.AlwaysEscapeNonAscii,
                CollapseToLiteral         = this.CollapseToLiteral,
                ConstStatementsMozilla    = this.ConstStatementsMozilla,
                DebugLookupList           = this.DebugLookupList,
                EvalLiteralExpressions    = this.EvalLiteralExpressions,
                EvalTreatment             = this.EvalTreatment,
                Format = this.Format,
                IgnoreConditionalCompilation = this.IgnoreConditionalCompilation,
                IgnoreAllErrors           = this.IgnoreAllErrors,
                IgnoreErrorList           = this.IgnoreErrorList,
                IgnorePreprocessorDefines = this.IgnorePreprocessorDefines,
                IndentSize                    = this.IndentSize,
                InlineSafeStrings             = this.InlineSafeStrings,
                KillSwitch                    = this.KillSwitch,
                KnownGlobalNamesList          = this.KnownGlobalNamesList,
                LineBreakThreshold            = this.LineBreakThreshold,
                LocalRenaming                 = this.LocalRenaming,
                MacSafariQuirks               = this.MacSafariQuirks,
                ManualRenamesProperties       = this.ManualRenamesProperties,
                NoAutoRenameList              = this.NoAutoRenameList,
                OutputMode                    = this.OutputMode,
                PreprocessOnly                = this.PreprocessOnly,
                PreprocessorDefineList        = this.PreprocessorDefineList,
                PreserveFunctionNames         = this.PreserveFunctionNames,
                PreserveImportantComments     = this.PreserveImportantComments,
                QuoteObjectLiteralProperties  = this.QuoteObjectLiteralProperties,
                RemoveFunctionExpressionNames = this.RemoveFunctionExpressionNames,
                RemoveUnneededCode            = this.RemoveUnneededCode,
                RenamePairs                   = this.RenamePairs,
                ReorderScopeDeclarations      = this.ReorderScopeDeclarations,
                SourceMode                    = this.SourceMode,
                StrictMode                    = this.StrictMode,
                StripDebugStatements          = this.StripDebugStatements,
                TermSemicolons                = this.TermSemicolons,
                BlocksStartOnSameLine         = this.BlocksStartOnSameLine,
                ErrorIfNotInlineSafe          = this.ErrorIfNotInlineSafe,
                SymbolsMap                    = this.SymbolsMap,
            };

            // set the resource strings if there are any
            newSettings.AddResourceStrings(this.ResourceStrings);

            foreach (var item in this.ReplacementTokens)
            {
                newSettings.ReplacementTokens.Add(item);
            }

            foreach (var item in this.ReplacementFallbacks)
            {
                newSettings.ReplacementTokens.Add(item);
            }

            return(newSettings);
        }
Beispiel #7
0
        public override string ToCode(ToCodeFormat format)
        {
            StringBuilder sb     = new StringBuilder();
            bool          parens = NeedsParens(m_condition, JSToken.ConditionalIf);

            if (parens)
            {
                sb.Append('(');
            }

            sb.Append(m_condition.ToCode());
            if (parens)
            {
                sb.Append(')');
            }

            CodeSettings codeSettings = Parser.Settings;

            if (codeSettings.OutputMode == OutputMode.MultipleLines && codeSettings.IndentSize > 0)
            {
                sb.Append(" ? ");
            }
            else
            {
                sb.Append('?');
            }

            // the true and false operands are parsed as assignment operators, so use that token as the
            // reference token to compare against for operator precedence to determine if we need parens
            parens = NeedsParens(m_trueExpression, JSToken.Assign);
            if (parens)
            {
                sb.Append('(');
            }

            sb.Append(m_trueExpression.ToCode());
            if (parens)
            {
                sb.Append(')');
            }

            if (codeSettings.OutputMode == OutputMode.MultipleLines && codeSettings.IndentSize > 0)
            {
                sb.Append(" : ");
            }
            else
            {
                sb.Append(':');
            }

            parens = NeedsParens(m_falseExpression, JSToken.Assign);
            if (parens)
            {
                sb.Append('(');
            }

            sb.Append(m_falseExpression.ToCode());
            if (parens)
            {
                sb.Append(')');
            }
            return(sb.ToString());
        }
Beispiel #8
0
        private bool m_preprocessOnly; // = false;

        #endregion

        #region file processing

        private int ProcessJSFile(string sourceFileName, ResourceStrings resourceStrings, StringBuilder outputBuilder, ref bool lastEndedSemicolon, ref long sourceLength)
        {
            int retVal = 0;

            // read our chunk of code
            string source;

            if (sourceFileName.Length > 0)
            {
                using (StreamReader reader = new StreamReader(sourceFileName, m_encodingInput))
                {
                    WriteProgress(
                        StringMgr.GetString("CrunchingFile", Path.GetFileName(sourceFileName))
                        );
                    source = reader.ReadToEnd();
                }
            }
            else
            {
                WriteProgress(StringMgr.GetString("CrunchingStdIn"));
                try
                {
                    // try setting the input encoding
                    Console.InputEncoding = m_encodingInput;
                }
                catch (IOException e)
                {
                    // error setting the encoding input; just use whatever the default is
                    Debug.WriteLine(e.ToString());
                }
                source = Console.In.ReadToEnd();

                if (m_analyze)
                {
                    // calculate the actual number of bytes read using the input encoding
                    // and the string that we just read and
                    // add the number of bytes read into the input length.
                    sourceLength += Console.InputEncoding.GetByteCount(source);
                }
                else
                {
                    // don't bother calculating the actual bytes -- the number of characters
                    // is sufficient if we're not doing the analysis
                    sourceLength += source.Length;
                }
            }

            // add the input length to the running total
            sourceLength += source.Length;

            // create the a parser object for our chunk of code
            JSParser parser = new JSParser(source);

            // set up the file context for the parser
            parser.FileContext = sourceFileName;

            // hook the engine events
            parser.CompilerError      += OnCompilerError;
            parser.UndefinedReference += OnUndefinedReference;

            // put the resource strings object into the parser
            parser.ResourceStrings = resourceStrings;

            // set our flags
            CodeSettings settings = new CodeSettings();

            settings.ManualRenamesProperties  = m_renameProperties;
            settings.CollapseToLiteral        = m_collapseToLiteral;
            settings.CombineDuplicateLiterals = m_combineDuplicateLiterals;
            settings.EvalLiteralExpressions   = m_evalLiteralExpressions;
            settings.EvalTreatment            = m_evalTreatment;
            settings.IndentSize                    = m_indentSize;
            settings.InlineSafeStrings             = m_safeForInline;
            settings.LocalRenaming                 = m_localRenaming;
            settings.MacSafariQuirks               = m_macSafariQuirks;
            settings.OutputMode                    = (m_prettyPrint ? OutputMode.MultipleLines : OutputMode.SingleLine);
            settings.PreserveFunctionNames         = m_preserveFunctionNames;
            settings.RemoveFunctionExpressionNames = m_removeFunctionExpressionNames;
            settings.RemoveUnneededCode            = m_removeUnneededCode;
            settings.StripDebugStatements          = m_stripDebugStatements;
            settings.AllowEmbeddedAspNetBlocks     = m_allowAspNet;
            settings.SetKnownGlobalNames(m_globals == null ? null : m_globals.ToArray());
            settings.SetNoAutoRename(m_noAutoRename == null ? null : m_noAutoRename.ToArray());
            settings.IgnoreConditionalCompilation = m_ignoreConditionalCompilation;

            // if there are defined preprocessor names
            if (m_defines != null && m_defines.Count > 0)
            {
                // set the list of defined names to our array of names
                settings.SetPreprocessorDefines(m_defines.ToArray());
            }

            // if there are rename entries...
            if (m_renameMap != null && m_renameMap.Count > 0)
            {
                // add each of them to the parser
                foreach (var sourceName in m_renameMap.Keys)
                {
                    settings.AddRenamePair(sourceName, m_renameMap[sourceName]);
                }
            }

            // cast the kill switch numeric value to the appropriate TreeModifications enumeration
            settings.KillSwitch = (TreeModifications)m_killSwitch;

            string resultingCode = null;

            if (m_preprocessOnly)
            {
                // we only want to preprocess the code. Call that api on the parser
                resultingCode = parser.PreprocessOnly(settings);
            }
            else
            {
                Block scriptBlock = parser.Parse(settings);
                if (scriptBlock != null)
                {
                    if (m_analyze)
                    {
                        // output our report
                        CreateReport(parser.GlobalScope);
                    }

                    // crunch the output and write it to debug stream
                    resultingCode = scriptBlock.ToCode();
                }
                else
                {
                    // no code?
                    WriteProgress(StringMgr.GetString("NoParsedCode"));
                }
            }

            if (!string.IsNullOrEmpty(resultingCode))
            {
                // always output the crunched code to debug stream
                System.Diagnostics.Debug.WriteLine(resultingCode);

                // if the last block of code didn't end in a semi-colon,
                // then we need to add one now
                if (!lastEndedSemicolon)
                {
                    outputBuilder.Append(';');
                }

                // we'll output either the crunched code (normal) or
                // the raw source if we're just echoing the input
                string outputCode = (m_echoInput ? source : resultingCode);

                // send the output code to the output stream
                outputBuilder.Append(outputCode);

                // check if this string ended in a semi-colon so we'll know if
                // we need to add one between this code and the next block (if any)
                lastEndedSemicolon = (outputCode[outputCode.Length - 1] == ';');
            }
            else
            {
                // resulting code is null or empty
                Debug.WriteLine(StringMgr.GetString("OutputEmpty"));
            }

            return(retVal);
        }
 private JSONOutputVisitor(TextWriter writer, CodeSettings settings)
 {
     m_writer   = writer;
     m_settings = settings;
     IsValid    = true;
 }
Beispiel #10
0
        /// <summary>
        /// Crunched JS string passed to it, returning crunched string.
        /// The ErrorList property will be set with any errors found during the minification process.
        /// </summary>
        /// <param name="source">source Javascript</param>
        /// <param name="codeSettings">code minification settings</param>
        /// <returns>minified Javascript</returns>
        public string MinifyJavaScript(string source, CodeSettings codeSettings)
        {
            // default is an empty string
            var crunched = string.Empty;

            // reset the errors builder
            m_errorList = new List <ContextError>();

            // create the parser from the source string.
            // pass null for the assumed globals array
            var parser = new JSParser(source);

            // file context is a property on the parser
            parser.FileContext = FileName;

            // hook the engine error event
            parser.CompilerError += OnJavaScriptError;

            try
            {
                if (codeSettings != null && codeSettings.PreprocessOnly)
                {
                    // just run through the preprocessor only
                    crunched = parser.PreprocessOnly(codeSettings);
                }
                else
                {
                    // parse the input
                    var scriptBlock = parser.Parse(codeSettings);
                    if (scriptBlock != null)
                    {
                        // we'll return the crunched code
                        if (codeSettings != null && codeSettings.Format == JavaScriptFormat.JSON)
                        {
                            // we're going to use a different output visitor -- one
                            // that specifically returns valid JSON.
                            var sb = new StringBuilder();
                            using (var stringWriter = new StringWriter(sb, CultureInfo.InvariantCulture))
                            {
                                if (!JSONOutputVisitor.Apply(stringWriter, scriptBlock))
                                {
                                    m_errorList.Add(new ContextError(
                                                        true,
                                                        0,
                                                        null,
                                                        null,
                                                        null,
                                                        this.FileName,
                                                        0,
                                                        0,
                                                        0,
                                                        0,
                                                        JScript.InvalidJSONOutput));
                                }
                            }

                            crunched = sb.ToString();
                        }
                        else
                        {
                            // just use the normal output visitor
                            crunched = scriptBlock.ToCode();
                        }
                    }
                }
            }
            catch (Exception e)
            {
                m_errorList.Add(new ContextError(
                                    true,
                                    0,
                                    null,
                                    null,
                                    null,
                                    this.FileName,
                                    0,
                                    0,
                                    0,
                                    0,
                                    e.Message));
                throw;
            }

            return(crunched);
        }
Beispiel #11
0
 public WithScope(ActivationObject parent, CodeSettings settings)
     : base(parent, settings, ScopeType.With)
 {
     IsInWithScope = true;
 }
Beispiel #12
0
 public BlockScope(ActivationObject parent, CodeSettings settings, ScopeType scopeType)
     : base(parent, settings)
 {
     ScopeType = scopeType;
 }
Beispiel #13
0
 public string Crunch(string source, CodeSettings codeSettings)
 {
     // just pass in default settings
     return(MinifyJavaScript(source, codeSettings));
 }