public static bool Apply(TextWriter writer, AstNode node, CodeSettings settings) { if (node != null) { var visitor = new JSONOutputVisitor(writer, settings); node.Accept(visitor); return(visitor.IsValid); } return(false); }
/// <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); }
private int ProcessJSFile(IList <InputGroup> inputGroups, SwitchParser switchParser, StringBuilder outputBuilder) { var returnCode = 0; var settings = switchParser.JSSettings; var currentSourceOrigin = SourceOrigin.Project; // blank line before WriteProgress(); // create our parser object and hook up some events var parser = new JSParser(); parser.UndefinedReference += OnUndefinedReference; parser.CompilerError += (sender, ea) => { var error = ea.Error; if (currentSourceOrigin == SourceOrigin.Project || error.Severity == 0) { // ignore severity values greater than our severity level // also ignore errors that are in our ignore list (if any) if (error.Severity <= switchParser.WarningLevel) { // we found an error m_errorsFound = true; // write the error out WriteError(error.ToString()); } } }; // output visitor requires a text writer, so make one from the string builder using (var writer = new StringWriter(outputBuilder, CultureInfo.InvariantCulture)) { var outputIndex = 0; var originalTermSetting = settings.TermSemicolons; for (var inputGroupIndex = 0; inputGroupIndex < inputGroups.Count; ++inputGroupIndex) { var inputGroup = inputGroups[inputGroupIndex]; currentSourceOrigin = inputGroup.Origin; // for all but the last item, we want the term-semicolons setting to be true. // but for the last entry, set it back to its original value settings.TermSemicolons = inputGroupIndex < inputGroups.Count - 1 ? true : originalTermSetting; // if this is preprocess-only or echo-input, then set up the writer as the echo writer for the parser if (settings.PreprocessOnly || m_echoInput) { parser.EchoWriter = writer; if (inputGroupIndex > 0) { // separate subsequent input groups with an appropriate line terminator writer.Write(settings.LineTerminator); writer.Write(';'); writer.Write(settings.LineTerminator); } } else { // not a preprocess-only or echo - make sure the echo writer is null parser.EchoWriter = null; } // parse the input code. Don't use a source context because it should already be // in the source using ///#SOURCE comments as we assembled the input groups. var scriptBlock = parser.Parse(inputGroup.Source, settings); if (m_errorsFound) { WriteProgress(); } if (m_outputTimer) { OutputTimingPoints(parser, inputGroupIndex, inputGroups.Count); } if (!settings.PreprocessOnly && !m_echoInput) { if (scriptBlock != null) { if (outputIndex++ > 0) { // separate subsequent input groups with an appropriate line terminator writer.Write(settings.LineTerminator); } // crunch the output and write it to debug stream, but make sure // the settings we use to output THIS chunk are correct if (settings.Format == JavaScriptFormat.JSON) { if (!JSONOutputVisitor.Apply(writer, scriptBlock, settings)) { returnCode = 1; } } else { OutputVisitor.Apply(writer, scriptBlock, settings); } } else { // no code? WriteProgress(AjaxMin.NoParsedCode); } } } // give the symbols map a chance to write something at the bottom of the source file // (and if this isn't preprocess-only or echo) if (settings.SymbolsMap != null && !settings.PreprocessOnly && !m_echoInput) { settings.SymbolsMap.EndFile(writer, settings.LineTerminator); } } if (switchParser.AnalyzeMode) { // blank line before WriteProgress(); // output our report CreateReport(parser.GlobalScope, switchParser); } return(returnCode); }
/// <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); }