Exemplo n.º 1
0
        protected static void AnalyzeWithRule <T>(string input, string ruleId, string output = null, int issueToFix = -1, int actionToRun = 0, Action <int, Diagnostic> diagnosticCheck = null) where T : DiagnosticAnalyzer, new()
        {
            var text = new StringBuilder();

            var expectedDiagnosics = new List <TextSpan> ();
            int start = -1;

            for (int i = 0; i < input.Length; i++)
            {
                char ch = input [i];
                if (ch == '$')
                {
                    if (start < 0)
                    {
                        start = text.Length;
                        continue;
                    }
                    expectedDiagnosics.Add(TextSpan.FromBounds(start, text.Length));
                    start = -1;
                }
                else
                {
                    text.Append(ch);
                }
            }

            var syntaxTree = CSharpSyntaxTree.ParseText(text.ToString());

            Compilation compilation = CreateCompilationWithMscorlib(new [] { syntaxTree });

            var diagnostics = new List <Diagnostic>();
            var compilationWithAnalyzers = compilation.WithAnalyzers(System.Collections.Immutable.ImmutableArray <DiagnosticAnalyzer> .Empty.Add(new T()));

            diagnostics.AddRange(compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync().Result);


            if (expectedDiagnosics.Count != diagnostics.Count)
            {
                Console.WriteLine("Diagnostics: " + diagnostics.Count);
                foreach (var diag in diagnostics)
                {
                    Console.WriteLine(diag.Id + "/" + diag.GetMessage());
                }
                Assert.Fail("Diagnostic count mismatch expected: " + expectedDiagnosics.Count + " but was:" + diagnostics.Count);
            }

            for (int i = 0; i < expectedDiagnosics.Count; i++)
            {
                var d         = diagnostics [i];
                var wholeSpan = GetWholeSpan(d);
                if (wholeSpan != expectedDiagnosics [i])
                {
                    Assert.Fail("Diagnostic " + i + " span mismatch expected: " + expectedDiagnosics[i] + " but was " + wholeSpan);
                }
                if (diagnosticCheck != null)
                {
                    diagnosticCheck(i, d);
                }
            }

            if (output == null)
            {
                return;
            }

            var workspace  = new TestWorkspace();
            var projectId  = ProjectId.CreateNewId();
            var documentId = DocumentId.CreateNewId(projectId);

            workspace.Open(ProjectInfo.Create(
                               projectId,
                               VersionStamp.Create(),
                               "", "", LanguageNames.CSharp, null, null, null, null,
                               new [] {
                DocumentInfo.Create(
                    documentId,
                    "a.cs",
                    null,
                    SourceCodeKind.Regular,
                    TextLoader.From(TextAndVersion.Create(SourceText.From(text.ToString()), VersionStamp.Create())))
            }
                               ));
            if (issueToFix < 0)
            {
                diagnostics.Reverse();
                foreach (var v in diagnostics)
                {
                    RunFix(workspace, projectId, documentId, v);
                }
            }
            else
            {
                RunFix(workspace, projectId, documentId, diagnostics.ElementAt(issueToFix), actionToRun);
            }

            var txt = workspace.CurrentSolution.GetProject(projectId).GetDocument(documentId).GetTextAsync().Result.ToString();

            if (output != txt)
            {
                Console.WriteLine("expected:");
                Console.WriteLine(output);
                Console.WriteLine("got:");
                Console.WriteLine(txt);
                Assert.Fail();
            }
        }
        protected static void Analyze <T>(Func <string, SyntaxTree> parseTextFunc, Func <SyntaxTree[], Compilation> createCompilationFunc, string language, string input, string output = null, int issueToFix = -1, int actionToRun = 0, Action <int, Diagnostic> diagnosticCheck = null) where T : DiagnosticAnalyzer, new()
        {
            var text = new StringBuilder();

            var expectedDiagnosics = new List <TextSpan>();
            int start = -1;

            for (int i = 0; i < input.Length; i++)
            {
                char ch = input[i];
                if (ch == '$' && ((i > 0) && (input[i - 1] == '$')))
                {
                    // Ignore 2nd "$" in "$$"
                }
                else if (ch == '$' && (i + 1 >= input.Length || input[i + 1] != '$'))
                {
                    if (start < 0)
                    {
                        start = text.Length;
                        continue;
                    }
                    expectedDiagnosics.Add(TextSpan.FromBounds(start, text.Length));
                    start = -1;
                }
                else
                {
                    text.Append(ch);
                }
            }

            var syntaxTree = parseTextFunc(text.ToString());

            Compilation compilation = createCompilationFunc(new[] { syntaxTree });

            var diagnostics = new List <Diagnostic>();

            var compilationWithAnalyzers = compilation.WithAnalyzers(System.Collections.Immutable.ImmutableArray <DiagnosticAnalyzer> .Empty.Add(new T()));
            var result = compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync().Result;

            diagnostics.AddRange(result);

            diagnostics.Sort((d1, d2) => d1.Location.SourceSpan.Start.CompareTo(d2.Location.SourceSpan.Start));
            expectedDiagnosics.Sort((d1, d2) => d1.Start.CompareTo(d2.Start));

            if (expectedDiagnosics.Count != diagnostics.Count)
            {
                foreach (var diag in diagnostics)
                {
                    Console.WriteLine(diag.Id + "/" + diag.GetMessage() + "/" + diag.Location.SourceSpan);
                }
                Assert.Fail("Diagnostic count mismatch expected: " + expectedDiagnosics.Count + " was " + diagnostics.Count);
            }

            for (int i = 0; i < expectedDiagnosics.Count; i++)
            {
                var d         = diagnostics[i];
                var wholeSpan = GetWholeSpan(d);
                if (wholeSpan != expectedDiagnosics[i])
                {
                    Assert.Fail("Diagnostic " + i + " span mismatch expected: " + expectedDiagnosics[i] + " but was " + wholeSpan);
                }
                if (diagnosticCheck != null)
                {
                    diagnosticCheck(i, d);
                }
            }

            if (output == null)
            {
                return;
            }

            var workspace  = new TestWorkspace();
            var projectId  = ProjectId.CreateNewId();
            var documentId = DocumentId.CreateNewId(projectId);

            workspace.Open(ProjectInfo.Create(
                               projectId,
                               VersionStamp.Create(),
                               "a", "a.exe", language, null, null, null, null,
                               new[] {
                DocumentInfo.Create(
                    documentId,
                    "a.cs",
                    null,
                    SourceCodeKind.Regular,
                    TextLoader.From(TextAndVersion.Create(SourceText.From(text.ToString()), VersionStamp.Create())))
            }
                               ));
            if (issueToFix < 0)
            {
                diagnostics.Reverse();
                foreach (var v in diagnostics)
                {
                    RunFix(workspace, projectId, documentId, v);
                }
            }
            else
            {
                RunFix(workspace, projectId, documentId, diagnostics.ElementAt(issueToFix), actionToRun);
            }

            var txt = workspace.CurrentSolution.GetProject(projectId).GetDocument(documentId).GetTextAsync().Result.ToString();

            output = Utils.HomogenizeEol(output);
            txt    = Utils.HomogenizeEol(txt);
            if (output != txt)
            {
                Console.WriteLine("expected:");
                Console.WriteLine(output);
                Console.WriteLine("got:");
                Console.WriteLine(txt);
                Console.WriteLine("-----Mismatch:");
                for (int i = 0; i < txt.Length; i++)
                {
                    if (i >= output.Length)
                    {
                        Console.Write("#");
                        continue;
                    }
                    if (txt[i] != output[i])
                    {
                        Console.Write("#");
                        continue;
                    }
                    Console.Write(txt[i]);
                }
                Assert.Fail();
            }
        }