public void GetMessageInlines_RendersTwoLinksAndHandlesLinkAtTheEnd()
        {
            const string message = @"The quick [brown fox](1) jumps over the [lazy dog](2)";

            var link1 = new Hyperlink();

            link1.Tag = 1;
            link1.Inlines.Add(new Run("brown fox"));

            var link2 = new Hyperlink();

            link2.Tag = 2;
            link2.Inlines.Add(new Run("lazy dog"));

            var expected = new List <Inline>
            {
                new Run("The quick "),
                link1,
                new Run(" jumps over the "),
                link2,
            };

            var actual = SdkUIUtilities.GetMessageInlines(message, clickHandler: this.Hyperlink_Click);

            actual.Count.Should().Be(expected.Count);

            VerifyTextRun(expected[0], actual[0]);
            VerifyHyperlink(expected[1], actual[1]);
            VerifyTextRun(expected[2], actual[2]);
            VerifyHyperlink(expected[3], actual[3]);
        }
示例#2
0
        public void GetMessageInlines_RendersWebLinkWithBackslashesInLinkText()
        {
            const string url     = "http://example.com";
            string       message = $@"The file [..\directory\file.cpp]({url}) has a problem.";

            var link = new Hyperlink();

            link.Tag = new Uri(url, UriKind.Absolute);
            link.Inlines.Add(new Run(@"..\directory\file.cpp"));

            var expected = new List <Inline>
            {
                new Run("The file "),
                link,
                new Run(" has a problem."),
            };

            List <Inline> actual = SdkUIUtilities.GetMessageInlines(message, clickHandler: this.Hyperlink_Click);

            actual.Count.Should().Be(expected.Count);

            VerifyTextRun(expected[0], actual[0]);
            VerifyHyperlink(expected[1], actual[1]);
            VerifyTextRun(expected[2], actual[2]);
        }
示例#3
0
        public void GetMessageInlines_RendersWebLink()
        {
            const string url     = "http://example.com";
            string       message = $"The quick [brown fox]({url}) jumps over the lazy dog.";

            var link = new Hyperlink();

            link.Tag = new Uri(url, UriKind.Absolute);
            link.Inlines.Add(new Run("brown fox"));

            var expected = new List <Inline>
            {
                new Run("The quick "),
                link,
                new Run(" jumps over the lazy dog."),
            };

            List <Inline> actual = SdkUIUtilities.GetMessageInlines(message, clickHandler: this.Hyperlink_Click);

            actual.Count.Should().Be(expected.Count);

            VerifyTextRun(expected[0], actual[0]);
            VerifyHyperlink(expected[1], actual[1]);
            VerifyTextRun(expected[2], actual[2]);
        }
示例#4
0
        public void GetMessageInlines_RendersOneLinkPlusLiteralBrackets()
        {
            const string message = @"The quick [brown fox](1) jumps over the \[lazy dog\].";

            var link = new Hyperlink {
                Tag = 1
            };

            link.Inlines.Add(new Run("brown fox"));

            var expected = new List <Inline>
            {
                new Run("The quick "),
                link,
                new Run(" jumps over the [lazy dog]."),
            };

            List <Inline> actual = SdkUIUtilities.GetMessageInlines(message, clickHandler: this.Hyperlink_Click);

            actual.Count.Should().Be(expected.Count);

            VerifyTextRun(expected[0], actual[0]);
            VerifyHyperlink(expected[1], actual[1]);
            VerifyTextRun(expected[2], actual[2]);
        }
        public void SarifSnapshot_GetMessageEmbeddedLinkInlines_TwoLinksAndEndsWithLink()
        {
            string message = @"The quick [brown fox](1) jumps over the [lazy dog](2)";

            var link1 = new Hyperlink();

            link1.Tag = new Tuple <int, int>(1, 1);
            link1.Inlines.Add(new Run("brown fox"));

            var link2 = new Hyperlink();

            link2.Tag = new Tuple <int, int>(1, 2);
            link2.Inlines.Add(new Run("lazy dog"));

            var expected = new List <Inline>
            {
                new Run("The quick "),
                link1,
                new Run(" jumps over the "),
                link2
            };

            var actual = SdkUIUtilities.GetMessageInlines(message, index: 1, clickHandler: Hyperlink_Click);

            actual.Count.Should().Be(expected.Count);

            VerifyTextRun(expected[0], actual[0]);
            VerifyHyperlink(expected[1], actual[1]);
            VerifyTextRun(expected[2], actual[2]);
            VerifyHyperlink(expected[3], actual[3]);
        }
示例#6
0
        public void GetMessageInlines_DoesNotGenerateLinkForEscapedBrackets()
        {
            string message = @"The quick \[brown fox\] jumps over the lazy dog.";

            // Because there are no embedded links, we shouldn't get anything back
            var actual = SdkUIUtilities.GetMessageInlines(message, index: 1, clickHandler: Hyperlink_Click);

            actual.Count.Should().Be(0);
        }
示例#7
0
        public void SarifSnapshot_GetMessageEmbeddedLinkInlines_ZeroLinksEscapedBrackets()
        {
            string message = @"The quick \[brown fox\] jumps over the lazy dog.";

            var expected = new List <Inline>
            {
                new Run("The quick [brown fox] jumps over the lazy dog.")
            };

            var actual = SdkUIUtilities.GetMessageInlines(message, index: 1, clickHandler: Hyperlink_Click);

            VerifyTextRun(expected[0], actual[0]);
        }
示例#8
0
        public void SarifSnapshot_GetMessageEmbeddedLinkInlines_OneLinkPlusEscapedBrackets()
        {
            string message = @"The quick [brown fox](1) jumps over the \[lazy dog\].";

            var link = new Hyperlink();

            link.Tag = new Tuple <int, int>(1, 1);
            link.Inlines.Add(new Run("brown fox"));

            var expected = new List <Inline>
            {
                new Run("The quick "),
                link,
                new Run(" jumps over the [lazy dog].")
            };

            var actual = SdkUIUtilities.GetMessageInlines(message, index: 1, clickHandler: Hyperlink_Click);

            actual.Count.Should().Be(expected.Count);

            VerifyTextRun(expected[0], actual[0]);
            VerifyHyperlink(expected[1], actual[1]);
            VerifyTextRun(expected[2], actual[2]);
        }
示例#9
0
        public void GetMessageInlines_RendersOneLink()
        {
            string message = @"The quick [brown fox](1) jumps over the lazy dog.";

            var link = new Hyperlink();

            link.Tag = new Tuple <int, object>(1, 1);
            link.Inlines.Add(new Run("brown fox"));

            var expected = new List <Inline>
            {
                new Run("The quick "),
                link,
                new Run(" jumps over the lazy dog.")
            };

            var actual = SdkUIUtilities.GetMessageInlines(message, index: 1, clickHandler: Hyperlink_Click);

            actual.Count.Should().Be(expected.Count);

            VerifyTextRun(expected[0], actual[0]);
            VerifyHyperlink(expected[1], actual[1]);
            VerifyTextRun(expected[2], actual[2]);
        }
示例#10
0
        public override bool TryGetValue(int index, string columnName, out object content)
        {
            content = null;

            if ((index >= 0) && (index < _errors.Count))
            {
                SarifErrorListItem error = _errors[index];

                if (columnName == StandardTableKeyNames2.TextInlines)
                {
                    string        message = error.Message;
                    List <Inline> inlines = SdkUIUtilities.GetMessageInlines(message, index, ErrorListInlineLink_Click);

                    if (inlines.Count > 0)
                    {
                        content = inlines;
                    }
                }
                else if (columnName == StandardTableKeyNames.DocumentName)
                {
                    content = FilePath;
                }
                else if (columnName == StandardTableKeyNames.ErrorCategory)
                {
                    content = error.Category;
                }
                else if (columnName == StandardTableKeyNames.Line)
                {
                    // The error list assumes the line number provided will be zero based and adds one before displaying the value.
                    // i.e. if we pass 5, the error list will display 6.
                    // Subtract one from the line number so the error list displays the correct value.
                    int lineNumber = error.LineNumber - 1;
                    content = lineNumber;
                }
                else if (columnName == StandardTableKeyNames.Column)
                {
                    content = error.ColumnNumber;
                }
                else if (columnName == StandardTableKeyNames.Text)
                {
                    content = SdkUIUtilities.UnescapeBrackets(error.ShortMessage);
                }
                else if (columnName == StandardTableKeyNames.FullText)
                {
                    if (error.HasDetailsContent)
                    {
                        content = SdkUIUtilities.UnescapeBrackets(error.Message);
                    }
                }
                else if (columnName == StandardTableKeyNames.ErrorSeverity)
                {
                    content = GetSeverity(error.Level);
                }
                else if (columnName == StandardTableKeyNames.Priority)
                {
                    content = GetSeverity(error.Level) == __VSERRORCATEGORY.EC_ERROR
                        ? vsTaskPriority.vsTaskPriorityHigh
                        : vsTaskPriority.vsTaskPriorityMedium;
                }
                else if (columnName == StandardTableKeyNames.ErrorSource)
                {
                    content = ErrorSource.Build;
                }
                else if (columnName == StandardTableKeyNames.BuildTool)
                {
                    content = error.Tool.Name;
                }
                else if (columnName == StandardTableKeyNames.ErrorCode)
                {
                    if (error.Rule != null)
                    {
                        content = error.Rule.Id;
                    }
                }
                else if (columnName == StandardTableKeyNames.ProjectName)
                {
                    content = error.ProjectName;
                }
                else if (columnName == StandardTableKeyNames.HelpLink)
                {
                    string url = null;
                    if (!string.IsNullOrEmpty(error.HelpLink))
                    {
                        url = error.HelpLink;
                    }

                    if (url != null)
                    {
                        content = Uri.EscapeUriString(url);
                    }
                }
                else if (columnName == StandardTableKeyNames.ErrorCodeToolTip)
                {
                    if (error.Rule != null)
                    {
                        content = error.Rule.Id + ":" + error.Rule.Name;
                    }
                }
                else if (columnName == "suppressionstatus" ||
                         columnName == "suppressionstate" ||
                         columnName == "suppression")
                {
                    content = error.VSSuppressionState.ToString();
                }
            }

            return(content != null);
        }
示例#11
0
        public SarifResultTableEntry(SarifErrorListItem error)
        {
            this.Identity = error.GetHashCode();
            this.Error    = error;

            // Set the data that's fast to retrieve into the dictionary of values.
            this.columnKeyToContent[StandardTableKeyNames.DocumentName]  = this.Error.FileName;
            this.columnKeyToContent[StandardTableKeyNames.ErrorCategory] = this.Error.Category;

            // The error list assumes the line number provided will be zero based and adds one before displaying the value.
            // i.e. if we pass 5, the error list will display 6.
            // Subtract one from the line number so the error list displays the correct value.
            this.columnKeyToContent[StandardTableKeyNames.Line]   = this.Error.LineNumber - 1;
            this.columnKeyToContent[StandardTableKeyNames.Column] = this.Error.ColumnNumber - 1;

            this.columnKeyToContent[StandardTableKeyNames.ErrorSeverity] = GetSeverity(this.Error.Level);
            this.columnKeyToContent[StandardTableKeyNames.Priority]      = GetSeverity(this.Error.Level) == __VSERRORCATEGORY.EC_ERROR
                    ? vsTaskPriority.vsTaskPriorityHigh
                    : vsTaskPriority.vsTaskPriorityMedium;
            this.columnKeyToContent[StandardTableKeyNames.ErrorSource] = ErrorSource.Build;
            this.columnKeyToContent[StandardTableKeyNames.BuildTool]   = this.Error.Tool?.Name;

            if (this.Error.Rule != null)
            {
                this.columnKeyToContent[StandardTableKeyNames.ErrorCode]        = this.Error.Rule.Id;
                this.columnKeyToContent[StandardTableKeyNames.ErrorCodeToolTip] = string.IsNullOrEmpty(this.Error.Rule.Name)
                    ? this.Error.Rule.Id
                    : this.Error.Rule.Id + "." + this.Error.Rule.Name;
            }

            this.columnKeyToContent[StandardTableKeyNames.ProjectName] = this.Error.ProjectName;

            string supressionState = this.Error.VSSuppressionState.ToString();

            this.columnKeyToContent[SuppressionStateColumnName] = supressionState;

            // Anything that's a bit more complex, we will make a "lazy" value and evaluate
            // it when it's asked for.
            // In WPF all the content elements including Inlines can only have one parent element.
            // If the Inlines are binded to multiple elements, only 1 can show the Inlines.
            // Create duplicated message inline objects for ErrorList table entry since
            // Error.MessageInlines is already binded to an element in SARIF explorer.
            this.columnKeyToContent[StandardTableKeyNames2.TextInlines] = new Lazy <object>(() =>
                                                                                            this.Error.MessageInlines?.Any() == true
                ? SdkUIUtilities.GetMessageInlines(this.Error.ShortMessage, this.Error.MessageInlineLink_Click)
                : null);

            this.columnKeyToContent[FullTextInlinesColumnName] = new Lazy <object>(() =>
                                                                                   this.Error.MessageInlines?.Any() == true
                ? SdkUIUtilities.GetMessageInlines(this.Error.RawMessage, this.Error.MessageInlineLink_Click)
                : null);

            this.columnKeyToContent[StandardTableKeyNames.Text] = new Lazy <object>(() =>
                                                                                    SdkUIUtilities.UnescapeBrackets(this.Error.ShortMessage));

            this.columnKeyToContent[StandardTableKeyNames.FullText] = new Lazy <object>(() =>
                                                                                        this.Error.HasDetailsContent
                ? SdkUIUtilities.UnescapeBrackets(this.Error.Message)
                : null);

            this.columnKeyToContent[StandardTableKeyNames.HelpLink] = new Lazy <object>(() =>
                                                                                        !string.IsNullOrEmpty(this.Error.HelpLink)
                ? Uri.EscapeUriString(this.Error.HelpLink)
                : null);
        }
        public SarifResultTableEntry(SarifErrorListItem error)
        {
            this.Identity = error.GetHashCode();
            this.Error    = error;

            // Set the data that's fast to retrieve into the dictionary of values.
            this.columnKeyToContent[StandardTableKeyNames.DocumentName]  = this.Error.FileName;
            this.columnKeyToContent[StandardTableKeyNames.ErrorCategory] = this.Error.Category;

            // The error list assumes the line number provided will be zero based and adds one before displaying the value.
            // i.e. if we pass 5, the error list will display 6.
            // Subtract one from the line number so the error list displays the correct value.
            this.columnKeyToContent[StandardTableKeyNames.Line] = this.Error.LineNumber - 1;

            this.columnKeyToContent[StandardTableKeyNames.Column]        = this.Error.ColumnNumber;
            this.columnKeyToContent[StandardTableKeyNames.ErrorSeverity] = GetSeverity(this.Error.Level);
            this.columnKeyToContent[StandardTableKeyNames.Priority]      = GetSeverity(this.Error.Level) == __VSERRORCATEGORY.EC_ERROR
                    ? vsTaskPriority.vsTaskPriorityHigh
                    : vsTaskPriority.vsTaskPriorityMedium;
            this.columnKeyToContent[StandardTableKeyNames.ErrorSource] = ErrorSource.Build;
            this.columnKeyToContent[StandardTableKeyNames.BuildTool]   = this.Error.Tool?.Name;

            if (this.Error.Rule != null)
            {
                this.columnKeyToContent[StandardTableKeyNames.ErrorCode]        = this.Error.Rule.Id;
                this.columnKeyToContent[StandardTableKeyNames.ErrorCodeToolTip] = string.IsNullOrEmpty(this.Error.Rule.Name) ?
                                                                                  this.Error.Rule.Id : this.Error.Rule.Id + "." + this.Error.Rule.Name;
            }

            this.columnKeyToContent[StandardTableKeyNames.ProjectName] = this.Error.ProjectName;

            string supressionState = this.Error.VSSuppressionState.ToString();

            this.columnKeyToContent[SuppressionStateColumnName] = supressionState;

            // Anything that's a bit more complex, we will make a "lazy" value and evaluate
            // it when it's asked for.
            this.columnKeyToContent[StandardTableKeyNames2.TextInlines] = new Lazy <object>(() =>
            {
                string message        = this.Error.Message;
                List <Inline> inlines = SdkUIUtilities.GetMessageInlines(message, this.ErrorListInlineLink_Click);

                if (inlines.Count > 0)
                {
                    return(inlines);
                }

                return(null);
            });

            this.columnKeyToContent[StandardTableKeyNames.Text] = new Lazy <object>(() =>
            {
                return(SdkUIUtilities.UnescapeBrackets(this.Error.ShortMessage));
            });

            this.columnKeyToContent[StandardTableKeyNames.FullText] = new Lazy <object>(() =>
            {
                if (this.Error.HasDetailsContent)
                {
                    return(SdkUIUtilities.UnescapeBrackets(this.Error.Message));
                }

                return(null);
            });

            this.columnKeyToContent[StandardTableKeyNames.HelpLink] = new Lazy <object>(() =>
            {
                return(!string.IsNullOrEmpty(this.Error.HelpLink) ? Uri.EscapeUriString(this.Error.HelpLink) : null);
            });
        }