예제 #1
0
 internal void ParseVBErrorOrWarning(string singleLine, MessageImportance messageImportance)
 {
     if (this.vbErrorLines.Count > 0)
     {
         if (!this.isDoneOutputtingErrorMessage && (singleLine.Length == 0))
         {
             this.isDoneOutputtingErrorMessage = true;
             this.numberOfLinesInErrorMessage  = this.vbErrorLines.Count;
         }
         this.vbErrorLines.Enqueue(new VBError(singleLine, messageImportance));
         if (this.isDoneOutputtingErrorMessage && (this.vbErrorLines.Count == (this.numberOfLinesInErrorMessage + 3)))
         {
             VBError error   = this.vbErrorLines.Dequeue();
             string  message = error.Message;
             int     num     = singleLine.IndexOf('~') + 1;
             int     index   = message.IndexOf(')');
             if ((num < 0) || (index < 0))
             {
                 base.Log.LogMessageFromText(message, error.MessageImportance);
                 foreach (VBError error2 in this.vbErrorLines)
                 {
                     base.LogEventsFromTextOutput(error2.Message, error2.MessageImportance);
                 }
                 this.vbErrorLines.Clear();
             }
             else
             {
                 string lineOfText = null;
                 lineOfText = string.Concat(new object[] { message.Substring(0, index), ",", num, message.Substring(index) });
                 base.Log.LogMessageFromText(lineOfText, error.MessageImportance);
                 foreach (VBError error3 in this.vbErrorLines)
                 {
                     base.LogEventsFromTextOutput(error3.Message, error3.MessageImportance);
                 }
                 this.vbErrorLines.Clear();
             }
         }
     }
     else
     {
         Microsoft.Build.Utilities.CanonicalError.Parts parts = Microsoft.Build.Utilities.CanonicalError.Parse(singleLine);
         if (parts == null)
         {
             base.LogEventsFromTextOutput(singleLine, messageImportance);
         }
         else if (((parts.category == Microsoft.Build.Utilities.CanonicalError.Parts.Category.Error) || (parts.category == Microsoft.Build.Utilities.CanonicalError.Parts.Category.Warning)) && (parts.column == 0))
         {
             if (parts.line != 0)
             {
                 this.vbErrorLines.Enqueue(new VBError(singleLine, messageImportance));
                 this.isDoneOutputtingErrorMessage = false;
                 this.numberOfLinesInErrorMessage  = 0;
             }
             else
             {
                 base.LogEventsFromTextOutput(singleLine, messageImportance);
             }
         }
     }
 }
예제 #2
0
        /// <summary>
        /// Given a string, parses it to find out whether it's an error or warning and, if so,
        /// make sure it's validated properly.
        /// </summary>
        /// <comments>
        /// INTERNAL FOR UNITTESTING ONLY
        /// </comments>
        /// <param name="singleLine">The line to parse</param>
        /// <param name="messageImportance">The MessageImportance to use when reporting the error.</param>
        internal void ParseVBErrorOrWarning(string singleLine, MessageImportance messageImportance)
        {
            // if this string is empty then we haven't seen the first line of an error yet
            if (_vbErrorLines.Count > 0)
            {
                // vbc separates the error message from the source text with an empty line, so
                // we can check for an empty line to see if vbc finished outputting the error message
                if (!_isDoneOutputtingErrorMessage && singleLine.Length == 0)
                {
                    _isDoneOutputtingErrorMessage = true;
                    _numberOfLinesInErrorMessage  = _vbErrorLines.Count;
                }

                _vbErrorLines.Enqueue(new VBError(singleLine, messageImportance));

                // We are looking for the line that indicates the column (contains the '~'),
                // which vbc outputs 3 lines below the error message:
                //
                // <error message>
                // <blank line>
                // <line with the source text>
                // <line with the '~'>
                if (_isDoneOutputtingErrorMessage &&
                    _vbErrorLines.Count == _numberOfLinesInErrorMessage + 3)
                {
                    // Once we have the 4th line (error line + 3), then parse it for the first ~
                    // which will correspond to the column of the token with the error because
                    // VBC respects the users's indentation settings in the file it is compiling
                    // and only outputs SPACE chars to STDOUT.

                    // The +1 is to translate the index into user columns which are 1 based.

                    VBError originalVBError       = _vbErrorLines.Dequeue();
                    string  originalVBErrorString = originalVBError.Message;

                    int column = singleLine.IndexOf('~') + 1;
                    int endParenthesisLocation = originalVBErrorString.IndexOf(')');

                    // If for some reason the line does not contain any ~ then something went wrong
                    // so abort and return the origional string.
                    if (column < 0 || endParenthesisLocation < 0)
                    {
                        // we need to output all of the original lines we ate.
                        Log.LogMessageFromText(originalVBErrorString, originalVBError.MessageImportance);
                        foreach (VBError vberror in _vbErrorLines)
                        {
                            base.LogEventsFromTextOutput(vberror.Message, vberror.MessageImportance);
                        }

                        _vbErrorLines.Clear();
                        return;
                    }

                    string newLine = null;
                    newLine = originalVBErrorString.Substring(0, endParenthesisLocation) + "," + column + originalVBErrorString.Substring(endParenthesisLocation);

                    // Output all of the lines of the error, but with the modified first line as well.
                    Log.LogMessageFromText(newLine, originalVBError.MessageImportance);
                    foreach (VBError vberror in _vbErrorLines)
                    {
                        base.LogEventsFromTextOutput(vberror.Message, vberror.MessageImportance);
                    }

                    _vbErrorLines.Clear();
                }
            }
            else
            {
                CanonicalError.Parts parts = CanonicalError.Parse(singleLine);
                if (parts == null)
                {
                    base.LogEventsFromTextOutput(singleLine, messageImportance);
                }
                else if ((parts.category == CanonicalError.Parts.Category.Error ||
                          parts.category == CanonicalError.Parts.Category.Warning) &&
                         parts.column == CanonicalError.Parts.numberNotSpecified)
                {
                    if (parts.line != CanonicalError.Parts.numberNotSpecified)
                    {
                        // If we got here, then this is a standard VBC error or warning.
                        _vbErrorLines.Enqueue(new VBError(singleLine, messageImportance));
                        _isDoneOutputtingErrorMessage = false;
                        _numberOfLinesInErrorMessage  = 0;
                    }
                    else
                    {
                        // Project-level errors don't have line numbers -- just output now.
                        base.LogEventsFromTextOutput(singleLine, messageImportance);
                    }
                }
            }
        }