/// <summary>
        /// Helper method to VerifyDiagnosticResult that checks the location of a diagnostic and compares it with the location in the expected DiagnosticResult.
        /// </summary>
        /// <param name="analyzer">The analyzer that was being run on the sources</param>
        /// <param name="diagnostic">The diagnostic that was found in the code</param>
        /// <param name="actual">The Location of the Diagnostic found in the code</param>
        /// <param name="expected">The DiagnosticResultLocation that should have been found</param>
        private static void VerifyDiagnosticLocation(DiagnosticAnalyzer analyzer, Diagnostic diagnostic, Location actual, DiagnosticResultLocation expected)
        {
            FileLinePositionSpan actualSpan = actual.GetLineSpan();

            Assert.True(actualSpan.Path == expected.Path || (actualSpan.Path != null && actualSpan.Path.Contains("Test0.") && expected.Path.Contains("Test.")),
                        string.Format("Expected diagnostic to be in file \"{0}\" was actually in file \"{1}\"\r\n\r\nDiagnostic:\r\n    {2}\r\n",
                                      expected.Path, actualSpan.Path, FormatDiagnostics(analyzer, diagnostic)));

            Microsoft.CodeAnalysis.Text.LinePosition actualLinePosition = actualSpan.StartLinePosition;

            // Only check line position if there is an actual line in the real diagnostic
            if (actualLinePosition.Line > 0)
            {
                if (actualLinePosition.Line + 1 != expected.Line)
                {
                    Assert.True(false,
                                string.Format("Expected diagnostic to be on line \"{0}\" was actually on line \"{1}\"\r\n\r\nDiagnostic:\r\n    {2}\r\n",
                                              expected.Line, actualLinePosition.Line + 1, FormatDiagnostics(analyzer, diagnostic)));
                }
            }

            // Only check column position if there is an actual column position in the real diagnostic
            if (actualLinePosition.Character > 0)
            {
                if (actualLinePosition.Character + 1 != expected.Column)
                {
                    Assert.True(false,
                                string.Format("Expected diagnostic to start at column \"{0}\" was actually at column \"{1}\"\r\n\r\nDiagnostic:\r\n    {2}\r\n",
                                              expected.Column, actualLinePosition.Character + 1, FormatDiagnostics(analyzer, diagnostic)));
                }
            }
        }
예제 #2
0
        /// <param name="isAssertEnabled">Indicates that unit test assertions are enabled for non-matches.</param>
        /// <returns>True if actual matches expected, false otherwise.</returns>
        private static bool VerifyDiagnosticLocation(DiagnosticAnalyzer analyzer, Diagnostic diagnostic, Location actual, DiagnosticLocation expected, bool isAssertEnabled)
        {
            FileLinePositionSpan actualSpan = actual.GetLineSpan();

            if (isAssertEnabled)
            {
                Assert.True(actualSpan.Path == expected.Span.Path || (actualSpan.Path != null && actualSpan.Path.Contains("Test0.") && expected.Span.Path.Contains("Test.")),
                            string.Format("Expected diagnostic to be in file \"{0}\" was actually in file \"{1}\"\r\n\r\nDiagnostic:\r\n    {2}\r\n",
                                          expected.Span.Path, actualSpan.Path, FormatDiagnostics(analyzer, diagnostic)));
            }
            else if (!(actualSpan.Path == expected.Span.Path || (actualSpan.Path != null && actualSpan.Path.Contains("Test0.") && expected.Span.Path.Contains("Test."))))
            {
                return(false);
            }

            Microsoft.CodeAnalysis.Text.LinePosition actualLinePosition = actualSpan.StartLinePosition;

            // Only check line position if there is an actual line in the real diagnostic
            if (expected.Span.StartLinePosition.Line > 0)
            {
                if (actualLinePosition.Line != expected.Span.StartLinePosition.Line)
                {
                    if (isAssertEnabled)
                    {
                        Assert.True(false,
                                    string.Format("Expected diagnostic to be on line \"{0}\" was actually on line \"{1}\"\r\n\r\nDiagnostic:\r\n    {2}\r\n",
                                                  expected.Span.StartLinePosition.Line + 1, actualLinePosition.Line + 1, FormatDiagnostics(analyzer, diagnostic)));
                    }
                    else
                    {
                        return(false);
                    }
                }
            }

            // Only check column position if there is an actual column position in the real diagnostic
            if (expected.Span.StartLinePosition.Character > 0)
            {
                if (actualLinePosition.Character != expected.Span.StartLinePosition.Character)
                {
                    if (isAssertEnabled)
                    {
                        Assert.True(false,
                                    string.Format("Expected diagnostic to start at column \"{0}\" was actually at column \"{1}\"\r\n\r\nDiagnostic:\r\n    {2}\r\n",
                                                  expected.Span.StartLinePosition.Character + 1, actualLinePosition.Character + 1, FormatDiagnostics(analyzer, diagnostic)));
                    }
                    else
                    {
                        return(false);
                    }
                }
            }

            // Matches.
            return(true);
        }
예제 #3
0
        private static string FormatDiagnostics(DiagnosticAnalyzer analyzer, params Diagnostic[] diagnostics)
        {
            var builder = new StringBuilder();

            for (int i = 0; i < diagnostics.Length; ++i)
            {
                builder.AppendLine("// " + diagnostics[i].ToString());

                Type analyzerType = analyzer.GetType();
                IEnumerable <FieldInfo> ruleFields = analyzerType
                                                     .GetFields(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)
                                                     .Where(f => f.IsStatic && f.FieldType == typeof(DiagnosticDescriptor));

                foreach (FieldInfo field in ruleFields)
                {
                    var rule = field.GetValue(null) as DiagnosticDescriptor;
                    if (rule != null && rule.Id == diagnostics[i].Id)
                    {
                        Location location = diagnostics[i].Location;
                        if (location == Location.None)
                        {
                            builder.AppendFormat("GetGlobalResult({0}.{1})", analyzerType.Name, field.Name);
                        }
                        else
                        {
                            Assert.False(location.IsInMetadata,
                                         "Test base does not currently handle diagnostics in metadata locations. Diagnostic in metadata:\r\n" + diagnostics[i]);

                            string resultMethodName = GetResultMethodName(diagnostics[i]);
                            Microsoft.CodeAnalysis.Text.LinePosition linePosition = diagnostics[i].Location.GetLineSpan().StartLinePosition;

                            builder.AppendFormat("{0}({1}, {2}, {3}.{4})",
                                                 resultMethodName,
                                                 linePosition.Line + 1,
                                                 linePosition.Character + 1,
                                                 field.DeclaringType.Name,
                                                 field.Name);
                        }

                        if (i != diagnostics.Length - 1)
                        {
                            builder.Append(',');
                        }

                        builder.AppendLine();
                        break;
                    }
                }
            }

            return(builder.ToString());
        }
        /// <summary>
        /// Helper method to format a Diagnostic into an easily readable string
        /// </summary>
        /// <param name="analyzer">The analyzer that this verifier tests</param>
        /// <param name="diagnostics">The Diagnostics to be formatted</param>
        /// <returns>The Diagnostics formatted as a string</returns>
        private static string FormatDiagnostics(DiagnosticAnalyzer analyzer, params Diagnostic[] diagnostics)
        {
            StringBuilder builder = new StringBuilder();

            for (int i = 0; i < diagnostics.Length; ++i)
            {
                builder.AppendLine("// " + diagnostics[i].ToString());

                System.Type analyzerType = analyzer.GetType();
                System.Collections.Immutable.ImmutableArray <DiagnosticDescriptor> rules = analyzer.SupportedDiagnostics;

                foreach (DiagnosticDescriptor rule in rules)
                {
                    if (rule != null && rule.Id == diagnostics[i].Id)
                    {
                        Location location = diagnostics[i].Location;
                        if (location == Location.None)
                        {
                            builder.AppendFormat("GetGlobalResult({0}.{1})", analyzerType.Name, rule.Id);
                        }
                        else
                        {
                            Assert.True(
                                location.IsInSource,
                                $"Test base does not currently handle diagnostics in metadata locations. Diagnostic in metadata: {diagnostics[i]}\r\n");

                            string resultMethodName = diagnostics[i].Location.SourceTree.FilePath.EndsWith(".cs") ? "GetCSharpResultAt" : "GetBasicResultAt";
                            Microsoft.CodeAnalysis.Text.LinePosition linePosition = diagnostics[i].Location.GetLineSpan().StartLinePosition;

                            builder.AppendFormat(
                                "{0}({1}, {2}, {3}.{4})",
                                resultMethodName,
                                linePosition.Line + 1,
                                linePosition.Character + 1,
                                analyzerType.Name,
                                rule.Id);
                        }

                        if (i != diagnostics.Length - 1)
                        {
                            builder.Append(',');
                        }

                        builder.AppendLine();
                        break;
                    }
                }
            }

            return(builder.ToString());
        }
예제 #5
0
파일: ErrBuilder.cs 프로젝트: alexfordc/Au
 /// <summary>
 /// Adds error message with a link that opens the C# file and goes to the specified position.
 /// </summary>
 /// <param name="pos">Position in code.</param>
 /// <param name="message">Text to append. Example: "error: message".</param>
 /// <param name="formatArgs">If not null/empty, calls StringBuilder.AppendFormat(message, formatArgs).</param>
 public void AddError(FileNode f, Microsoft.CodeAnalysis.Text.LinePosition pos, string message, params object[] formatArgs)
 {
     _StartAdd();
     _Append(f, pos.Line, pos.Character, message, formatArgs);
 }
예제 #6
0
 public LinePosition(Microsoft.CodeAnalysis.Text.LinePosition source)
 {
     this.Line      = source.Line;
     this.Character = source.Character;
 }