Example #1
0
        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();
            }
        }
Example #2
0
        /// <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();
            }
        }
Example #3
0
        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();
            }
        }
Example #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;

            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);
        }
Example #5
0
        //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));
        }