Exemplo n.º 1
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);
        }
Exemplo n.º 2
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);
        }