public override string ToString() { var sb = StringBuilderPool.Acquire(); try { if (m_list.Count > 0) { // output the first one; then all subsequent, each prefaced with a comma sb.Append(m_list[0].ToString()); for (var ndx = 1; ndx < m_list.Count; ++ndx) { sb.Append(" , "); sb.Append(m_list[ndx].ToString()); } } return(sb.ToString()); } finally { sb.Release(); } }
/// <summary> /// Convert the exception to a VisualStudio format error message /// file(startline[-endline]?,startcol[-endcol]?):[ subcategory] category [errorcode]: message /// </summary> /// <returns></returns> public override string ToString() { var sb = StringBuilderPool.Acquire(); try { if (!string.IsNullOrEmpty(File)) { sb.Append(File); } // if there is a startline, then there must be a location. // no start line, then no location if (StartLine > 0) { // we will always at least start with the start line sb.AppendFormat("({0}", StartLine); if (EndLine > StartLine) { if (StartColumn > 0 && EndColumn > 0) { // all four values were specified sb.AppendFormat(",{0},{1},{2}", StartColumn, EndLine, EndColumn); } else { // one or both of the columns wasn't specified, so ignore them both sb.AppendFormat("-{0}", EndLine); } } else if (StartColumn > 0) { sb.AppendFormat(",{0}", StartColumn); if (EndColumn > StartColumn) { sb.AppendFormat("-{0}", EndColumn); } } sb.Append(')'); } // seaprate the location from the error description sb.Append(':'); // if there is a subcategory, add it prefaced with a space if (!string.IsNullOrEmpty(Subcategory)) { sb.Append(' '); sb.Append(Subcategory); } // not localizable sb.Append(IsError ? " error " : " warning "); // if there is an error code if (!string.IsNullOrEmpty(ErrorCode)) { sb.Append(ErrorCode); } // separate description from the message sb.Append(": "); if (!string.IsNullOrEmpty(Message)) { sb.Append(Message); } return(sb.ToString()); } finally { sb.Release(); } }
private static string CreateJSFromResourceStrings(ResourceStrings resourceStrings) { var sb = StringBuilderPool.Acquire(); try { // start the var statement using the requested name and open the initializer object literal sb.Append("var "); sb.Append(resourceStrings.Name); sb.Append("={"); // we're going to need to insert commas between each pair, so we'll use a boolean // flag to indicate that we're on the first pair. When we output the first pair, we'll // set the flag to false. When the flag is false, we're about to insert another pair, so // we'll add the comma just before. bool firstItem = true; // loop through all items in the collection foreach (var keyPair in resourceStrings.NameValuePairs) { // if this isn't the first item, we need to add a comma separator if (!firstItem) { sb.Append(','); } else { // next loop is no longer the first item firstItem = false; } // append the key as the name, a colon to separate the name and value, // and then the value // must quote if not valid JS identifier format, or if it is, but it's a keyword // (use strict mode just to be safe) string propertyName = keyPair.Key; if (!JSScanner.IsValidIdentifier(propertyName) || JSScanner.IsKeyword(propertyName, true)) { sb.Append("\""); // because we are using quotes for the delimiters, replace any instances // of a quote character (") with an escaped quote character (\") sb.Append(propertyName.Replace("\"", "\\\"")); sb.Append("\""); } else { sb.Append(propertyName); } sb.Append(':'); // make sure the Value is properly escaped, quoted, and whatever we // need to do to make sure it's a proper JS string. // pass false for whether this string is an argument to a RegExp constructor. // pass false for whether to use W3Strict formatting for character escapes (use maximum browser compatibility) // pass true for ecma strict mode string stringValue = ConstantWrapper.EscapeString( keyPair.Value, false, false, true ); sb.Append(stringValue); } // close the object literal and return the string sb.AppendLine("};"); return(sb.ToString()); } finally { sb.Release(); } }
/// <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; var sb = StringBuilderPool.Acquire(); try { var preprocessOnly = codeSettings != null && codeSettings.PreprocessOnly; 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); // if we are asking for a symbols map, give it a chance to output a little something // to the minified file. if (codeSettings != null && codeSettings.SymbolsMap != null) { codeSettings.SymbolsMap.EndFile(stringWriter, codeSettings.LineTerminator); } } } } crunched = sb.ToString(); } catch (Exception e) { m_errorList.Add(new ContextError() { Severity = 0, File = this.FileName, Message = e.Message, }); throw; } finally { sb.Release(); } return(crunched); }
//TYPE "NAME" - Starts at line LINE, col COLUMN STATUS [crunched to CRUNCH] // //TYPE: Function, Function getter, Function setter //STATUS: '', Unknown, Unreachable private void WriteFunctionHeader(FunctionObject funcObj, bool isKnown, bool useStrict) { // get the crunched value (if any) string crunched = string.Empty; var functionField = funcObj.Binding.IfNotNull(b => b.VariableField); if (functionField != null && functionField.CrunchedName != null) { crunched = AjaxMin.CrunchedTo.FormatInvariant(functionField.CrunchedName, functionField.RefCount); } // get the status if the function string status = null; var statusBuilder = StringBuilderPool.Acquire(); try { if (!isKnown) { statusBuilder.Append('['); statusBuilder.Append(AjaxMin.NotKnown); } if (funcObj.EnclosingScope.Parent is GlobalScope) { // global function. // if this is a named function expression, we still want to know if it's // referenced by anyone if (funcObj.FunctionType == FunctionType.Expression && funcObj.Binding != null && !funcObj.Binding.Name.IsNullOrWhiteSpace()) { // output a comma separator if not the first item, otherwise // open the square bracket if (statusBuilder.Length > 0) { statusBuilder.Append(", "); } else { statusBuilder.Append('['); } statusBuilder.Append(AjaxMin.FunctionInfoReferences.FormatInvariant( funcObj.Binding.VariableField.IfNotNull(v => v.RefCount) )); } } else if (!funcObj.IsReferenced && m_useReferenceCounts) { // local function that isn't referenced -- unreachable! // output a comma separator if not the first item, otherwise // open the square bracket if (statusBuilder.Length > 0) { statusBuilder.Append(", "); } else { statusBuilder.Append('['); } statusBuilder.Append(AjaxMin.Unreachable); } if (statusBuilder.Length > 0) { statusBuilder.Append(']'); } if (useStrict) { statusBuilder.Append(AjaxMin.ScopeIsStrictFlag); } status = statusBuilder.ToString(); } finally { statusBuilder.Release(); } string functionType; switch (funcObj.FunctionType) { case FunctionType.Getter: functionType = AjaxMin.FunctionTypePropGet; break; case FunctionType.Setter: functionType = AjaxMin.FunctionTypePropSet; break; case FunctionType.Expression: functionType = AjaxMin.FunctionTypeExpression; break; case FunctionType.ArrowFunction: functionType = AjaxMin.FunctionTypeArrow; break; case FunctionType.Method: functionType = AjaxMin.FunctionTypeMethod; break; default: functionType = AjaxMin.FunctionTypeFunction; break; } var functionName = funcObj.Binding.IfNotNull(b => b.Name); if (functionName.IsNullOrWhiteSpace()) { functionName = !funcObj.NameGuess.IsNullOrWhiteSpace() ? '"' + funcObj.NameGuess + '"' : AjaxMin.AnonymousName; } // output WriteProgress(); WriteProgress(AjaxMin.FunctionHeader.FormatInvariant( functionType, functionName, funcObj.Context.StartLineNumber, funcObj.Context.StartColumn + 1, status, crunched, funcObj.IsGenerator ? AjaxMin.FunctionTypeGenerator : string.Empty)); }