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()); }
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" }; }
internal CatchScope(ActivationObject parent, CodeSettings settings) : base(parent, settings, ScopeType.Catch) { }
/// <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(); }
/// <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); }
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()); }
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; }
/// <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); }
public WithScope(ActivationObject parent, CodeSettings settings) : base(parent, settings, ScopeType.With) { IsInWithScope = true; }
public BlockScope(ActivationObject parent, CodeSettings settings, ScopeType scopeType) : base(parent, settings) { ScopeType = scopeType; }
public string Crunch(string source, CodeSettings codeSettings) { // just pass in default settings return(MinifyJavaScript(source, codeSettings)); }