public async Task AnalyzerCreatedAtCompilationLevelNeedNotBeCompilationAnalyzer() { var source = @"x"; using var workspace = TestWorkspace.CreateCSharp(source); var analyzer = new CompilationAnalyzerWithSyntaxTreeAnalyzer(); var analyzerReference = new AnalyzerImageReference(ImmutableArray.Create <DiagnosticAnalyzer>(analyzer)); workspace.TryApplyChanges(workspace.CurrentSolution.WithAnalyzerReferences(new[] { analyzerReference })); var ideEngineDocument = workspace.CurrentSolution.Projects.Single().Documents.Single(); var diagnostics = await DiagnosticProviderTestUtilities.GetAllDiagnosticsAsync(ideEngineDocument, new TextSpan(0, ideEngineDocument.GetTextAsync().Result.Length)); var diagnosticsFromAnalyzer = diagnostics.Where(d => d.Id == "SyntaxDiagnostic"); Assert.Equal(1, diagnosticsFromAnalyzer.Count()); }
public async Task DiagnosticAnalyzerDriverVsAnalyzerDriverOnCodeBlock() { var methodNames = new string[] { "Initialize", "AnalyzeCodeBlock" }; var source = @" [System.Obsolete] class C { int P { get; set; } delegate void A(); delegate string F(); } "; var ideEngineAnalyzer = new CSharpTrackingDiagnosticAnalyzer(); using (var ideEngineWorkspace = await TestWorkspace.CreateCSharpAsync(source)) { var ideEngineDocument = ideEngineWorkspace.CurrentSolution.Projects.Single().Documents.Single(); await DiagnosticProviderTestUtilities.GetAllDiagnosticsAsync(ideEngineAnalyzer, ideEngineDocument, new Text.TextSpan(0, ideEngineDocument.GetTextAsync().Result.Length)); foreach (var method in methodNames) { Assert.False(ideEngineAnalyzer.CallLog.Any(e => e.CallerName == method && e.MethodKind == MethodKind.DelegateInvoke && e.ReturnsVoid)); Assert.False(ideEngineAnalyzer.CallLog.Any(e => e.CallerName == method && e.MethodKind == MethodKind.DelegateInvoke && !e.ReturnsVoid)); Assert.False(ideEngineAnalyzer.CallLog.Any(e => e.CallerName == method && e.SymbolKind == SymbolKind.NamedType)); Assert.False(ideEngineAnalyzer.CallLog.Any(e => e.CallerName == method && e.SymbolKind == SymbolKind.Property)); } } var compilerEngineAnalyzer = new CSharpTrackingDiagnosticAnalyzer(); using (var compilerEngineWorkspace = await TestWorkspace.CreateCSharpAsync(source)) { var compilerEngineCompilation = (CSharpCompilation)compilerEngineWorkspace.CurrentSolution.Projects.Single().GetCompilationAsync().Result; compilerEngineCompilation.GetAnalyzerDiagnostics(new[] { compilerEngineAnalyzer }); foreach (var method in methodNames) { Assert.False(compilerEngineAnalyzer.CallLog.Any(e => e.CallerName == method && e.MethodKind == MethodKind.DelegateInvoke && e.ReturnsVoid)); Assert.False(compilerEngineAnalyzer.CallLog.Any(e => e.CallerName == method && e.MethodKind == MethodKind.DelegateInvoke && !e.ReturnsVoid)); Assert.False(compilerEngineAnalyzer.CallLog.Any(e => e.CallerName == method && e.SymbolKind == SymbolKind.NamedType)); Assert.False(compilerEngineAnalyzer.CallLog.Any(e => e.CallerName == method && e.SymbolKind == SymbolKind.Property)); } } }
public void AnalyzerOptionsArePassedToAllAnalyzers() { using (var workspace = CSharpWorkspaceFactory.CreateWorkspaceFromFile(TestResource.AllInOneCSharpCode, TestOptions.Regular)) { var currentProject = workspace.CurrentSolution.Projects.Single(); var additionalDocId = DocumentId.CreateNewId(currentProject.Id); var newSln = workspace.CurrentSolution.AddAdditionalDocument(additionalDocId, "add.config", SourceText.From("random text")); currentProject = newSln.Projects.Single(); var additionalDocument = currentProject.GetAdditionalDocument(additionalDocId); AdditionalText additionalStream = new AdditionalTextDocument(additionalDocument.GetDocumentState()); AnalyzerOptions options = new AnalyzerOptions(ImmutableArray.Create(additionalStream)); var analyzer = new OptionsDiagnosticAnalyzer <SyntaxKind>(expectedOptions: options); var sourceDocument = currentProject.Documents.Single(); DiagnosticProviderTestUtilities.GetAllDiagnostics(analyzer, sourceDocument, new Text.TextSpan(0, sourceDocument.GetTextAsync().Result.Length)); analyzer.VerifyAnalyzerOptions(); } }
public async Task CodeBlockAnalyzersOnlyAnalyzeExecutableCode() { var source = @" using System; class C { void F(int x = 0) { Console.WriteLine(0); } } "; var analyzer = new CodeBlockAnalyzerFactory(); using (var ideEngineWorkspace = await TestWorkspace.CreateCSharpAsync(source)) { var ideEngineDocument = ideEngineWorkspace.CurrentSolution.Projects.Single().Documents.Single(); var diagnostics = await DiagnosticProviderTestUtilities.GetAllDiagnosticsAsync(analyzer, ideEngineDocument, new Text.TextSpan(0, ideEngineDocument.GetTextAsync().Result.Length)); var diagnosticsFromAnalyzer = diagnostics.Where(d => d.Id == CodeBlockAnalyzerFactory.Descriptor.Id); Assert.Equal(2, diagnosticsFromAnalyzer.Count()); } source = @" using System; class C { void F(int x = 0, int y = 1, int z = 2) { Console.WriteLine(0); } } "; using (var compilerEngineWorkspace = await TestWorkspace.CreateCSharpAsync(source)) { var compilerEngineCompilation = (CSharpCompilation)compilerEngineWorkspace.CurrentSolution.Projects.Single().GetCompilationAsync().Result; var diagnostics = compilerEngineCompilation.GetAnalyzerDiagnostics(new[] { analyzer }); var diagnosticsFromAnalyzer = diagnostics.Where(d => d.Id == CodeBlockAnalyzerFactory.Descriptor.Id); Assert.Equal(4, diagnosticsFromAnalyzer.Count()); } }
public async Task AnalyzerOptionsArePassedToAllAnalyzers() { using var workspace = TestWorkspace.CreateCSharp(TestResource.AllInOneCSharpCode, TestOptions.Regular, composition: s_compositionWithMockDiagnosticUpdateSourceRegistrationService); var additionalDocId = DocumentId.CreateNewId(workspace.CurrentSolution.Projects.Single().Id); var additionalText = new TestAdditionalText("add.config", SourceText.From("random text")); var options = new AnalyzerOptions(ImmutableArray.Create <AdditionalText>(additionalText)); var analyzer = new OptionsDiagnosticAnalyzer <SyntaxKind>(expectedOptions: options); var analyzerReference = new AnalyzerImageReference(ImmutableArray.Create <DiagnosticAnalyzer>(analyzer)); workspace.TryApplyChanges(workspace.CurrentSolution .WithAnalyzerReferences(new[] { analyzerReference }) .AddAdditionalDocument(additionalDocId, "add.config", additionalText.GetText() !)); var sourceDocument = workspace.CurrentSolution.Projects.Single().Documents.Single(); await DiagnosticProviderTestUtilities.GetAllDiagnosticsAsync(workspace, sourceDocument, new TextSpan(0, sourceDocument.GetTextAsync().Result.Length)); analyzer.VerifyAnalyzerOptions(); }
public void AssertTag(string expectedFromName, string expectedToName, bool invokeAction = false, int actionIndex = 0) { WaitForAsyncOperations(); var tags = _tagger.GetTags(new NormalizedSnapshotSpanCollection(new SnapshotSpan(_view.TextBuffer.CurrentSnapshot, new Span(0, _view.TextBuffer.CurrentSnapshot.Length)))); // There should only ever be one tag Assert.Equal(1, tags.Count()); var tag = tags.Single(); var document = this.Workspace.CurrentSolution.GetDocument(_hostDocument.Id); var analyzer = new RenameTrackingDiagnosticAnalyzer(); var diagnostics = DiagnosticProviderTestUtilities.GetDocumentDiagnostics(analyzer, document, tag.Span.Span.ToTextSpan()).ToList(); // There should be a single rename tracking diagnostic Assert.Equal(1, diagnostics.Count); Assert.Equal(RenameTrackingDiagnosticAnalyzer.DiagnosticId, diagnostics[0].Id); var actions = new List <CodeAction>(); var context = new CodeFixContext(document, diagnostics[0], (a, d) => actions.Add(a), CancellationToken.None); _codeFixProvider.RegisterCodeFixesAsync(context).Wait(); // There should be two actions Assert.Equal(2, actions.Count); Assert.Equal(string.Format("Rename '{0}' to '{1}'", expectedFromName, expectedToName), actions[0].Title); Assert.Equal(string.Format("Rename '{0}' to '{1}' with preview...", expectedFromName, expectedToName), actions[1].Title); if (invokeAction) { var operations = actions[actionIndex] .GetOperationsAsync(CancellationToken.None) .WaitAndGetResult(CancellationToken.None) .ToArray(); Assert.Equal(1, operations.Length); operations[0].Apply(this.Workspace, CancellationToken.None); } }
public void DiagnosticAnalyzerDriverAllInOne() { var source = TestResource.AllInOneCSharpCode; // AllInOneCSharpCode has no properties with initializers or named types with primary constructors. var symbolKindsWithNoCodeBlocks = new HashSet <SymbolKind>(); symbolKindsWithNoCodeBlocks.Add(SymbolKind.Property); symbolKindsWithNoCodeBlocks.Add(SymbolKind.NamedType); var analyzer = new CSharpTrackingDiagnosticAnalyzer(); using (var workspace = CSharpWorkspaceFactory.CreateWorkspaceFromFile(source, TestOptions.Regular)) { var document = workspace.CurrentSolution.Projects.Single().Documents.Single(); AccessSupportedDiagnostics(analyzer); DiagnosticProviderTestUtilities.GetAllDiagnostics(analyzer, document, new Text.TextSpan(0, document.GetTextAsync().Result.Length)); analyzer.VerifyAllAnalyzerMembersWereCalled(); analyzer.VerifyAnalyzeSymbolCalledForAllSymbolKinds(); analyzer.VerifyAnalyzeNodeCalledForAllSyntaxKinds(); analyzer.VerifyOnCodeBlockCalledForAllSymbolAndMethodKinds(symbolKindsWithNoCodeBlocks, true); } }
public async Task DiagnosticAnalyzerDriverAllInOne() { var source = TestResource.AllInOneCSharpCode; // AllInOneCSharpCode has no properties with initializers or named types with primary constructors. var symbolKindsWithNoCodeBlocks = new HashSet <SymbolKind>(); symbolKindsWithNoCodeBlocks.Add(SymbolKind.Property); symbolKindsWithNoCodeBlocks.Add(SymbolKind.NamedType); var missingSyntaxNodes = new HashSet <SyntaxKind>(); // https://github.com/dotnet/roslyn/issues/44682 - Add to all in one missingSyntaxNodes.Add(SyntaxKind.WithExpression); missingSyntaxNodes.Add(SyntaxKind.RecordDeclaration); missingSyntaxNodes.Add(SyntaxKind.FunctionPointerType); var analyzer = new CSharpTrackingDiagnosticAnalyzer(); using var workspace = TestWorkspace.CreateCSharp(source, TestOptions.Regular); var analyzerReference = new AnalyzerImageReference(ImmutableArray.Create <DiagnosticAnalyzer>(analyzer)); var newSolution = workspace.CurrentSolution.WithAnalyzerReferences(new[] { analyzerReference }) .Projects.Single().AddAdditionalDocument(name: "dummy.txt", text: "", filePath: "dummy.txt").Project.Solution; workspace.TryApplyChanges(newSolution); var document = workspace.CurrentSolution.Projects.Single().Documents.Single(); AccessSupportedDiagnostics(analyzer); await DiagnosticProviderTestUtilities.GetAllDiagnosticsAsync(document, new TextSpan(0, document.GetTextAsync().Result.Length)); analyzer.VerifyAllAnalyzerMembersWereCalled(); analyzer.VerifyAnalyzeSymbolCalledForAllSymbolKinds(); analyzer.VerifyAnalyzeNodeCalledForAllSyntaxKinds(missingSyntaxNodes); analyzer.VerifyOnCodeBlockCalledForAllSymbolAndMethodKinds(symbolKindsWithNoCodeBlocks, true); }
internal override IEnumerable <Tuple <Diagnostic, CodeFixCollection> > GetDiagnosticAndFixes(TestWorkspace workspace, string fixAllActionId) { var providerAndFixer = CreateDiagnosticProviderAndFixer(workspace); var provider = providerAndFixer.Item1; TextSpan span; var document = GetDocumentAndSelectSpan(workspace, out span); var diagnostics = DiagnosticProviderTestUtilities.GetAllDiagnostics(provider, document, span); var fixer = providerAndFixer.Item2; foreach (var diagnostic in diagnostics) { if (fixer.CanBeSuppressed(diagnostic)) { var fixes = fixer.GetSuppressionsAsync(document, diagnostic.Location.SourceSpan, SpecializedCollections.SingletonEnumerable(diagnostic), CancellationToken.None).Result; if (fixes != null && fixes.Any()) { yield return(Tuple.Create(diagnostic, new CodeFixCollection(fixer, diagnostic.Location.SourceSpan, fixes))); } } } }
public async Task DiagnosticAnalyzerDriverAllInOne() { var source = TestResource.AllInOneCSharpCode; // AllInOneCSharpCode has no properties with initializers or named types with primary constructors. var symbolKindsWithNoCodeBlocks = new HashSet <SymbolKind>(); symbolKindsWithNoCodeBlocks.Add(SymbolKind.Property); symbolKindsWithNoCodeBlocks.Add(SymbolKind.NamedType); var syntaxKindsMissing = new HashSet <SyntaxKind>(); // AllInOneCSharpCode has no deconstruction or declaration expression syntaxKindsMissing.Add(SyntaxKind.TypedVariableComponent); syntaxKindsMissing.Add(SyntaxKind.ParenthesizedVariableComponent); syntaxKindsMissing.Add(SyntaxKind.SingleVariableDesignation); syntaxKindsMissing.Add(SyntaxKind.ParenthesizedVariableDesignation); syntaxKindsMissing.Add(SyntaxKind.DeconstructionDeclarationStatement); syntaxKindsMissing.Add(SyntaxKind.VariableComponentAssignment); syntaxKindsMissing.Add(SyntaxKind.ForEachComponentStatement); syntaxKindsMissing.Add(SyntaxKind.DeclarationExpression); var analyzer = new CSharpTrackingDiagnosticAnalyzer(); using (var workspace = await TestWorkspace.CreateCSharpAsync(source, TestOptions.Regular)) { var document = workspace.CurrentSolution.Projects.Single().Documents.Single(); AccessSupportedDiagnostics(analyzer); await DiagnosticProviderTestUtilities.GetAllDiagnosticsAsync(analyzer, document, new Text.TextSpan(0, document.GetTextAsync().Result.Length)); analyzer.VerifyAllAnalyzerMembersWereCalled(); analyzer.VerifyAnalyzeSymbolCalledForAllSymbolKinds(); analyzer.VerifyAnalyzeNodeCalledForAllSyntaxKinds(syntaxKindsMissing); analyzer.VerifyOnCodeBlockCalledForAllSymbolAndMethodKinds(symbolKindsWithNoCodeBlocks, true); } }
public async Task DiagnosticAnalyzerDriverAllInOne() { var source = TestResource.AllInOneCSharpCode; // AllInOneCSharpCode has no properties with initializers or named types with primary constructors. var symbolKindsWithNoCodeBlocks = new HashSet <SymbolKind>(); symbolKindsWithNoCodeBlocks.Add(SymbolKind.Property); symbolKindsWithNoCodeBlocks.Add(SymbolKind.NamedType); // AllInOneCSharpCode has no pattern matching. var syntaxKindsPatterns = new HashSet <SyntaxKind>(); syntaxKindsPatterns.Add(SyntaxKind.IsPatternExpression); syntaxKindsPatterns.Add(SyntaxKind.DeclarationPattern); syntaxKindsPatterns.Add(SyntaxKind.ConstantPattern); syntaxKindsPatterns.Add(SyntaxKind.WhenClause); syntaxKindsPatterns.Add(SyntaxKind.CasePatternSwitchLabel); // AllInOneCSharpCode has no replace/original. syntaxKindsPatterns.Add(SyntaxKind.OriginalExpression); var analyzer = new CSharpTrackingDiagnosticAnalyzer(); using (var workspace = await TestWorkspace.CreateCSharpAsync(source, TestOptions.Regular.WithLocalFunctionsFeature().WithRefsFeature())) { var document = workspace.CurrentSolution.Projects.Single().Documents.Single(); AccessSupportedDiagnostics(analyzer); await DiagnosticProviderTestUtilities.GetAllDiagnosticsAsync(analyzer, document, new Text.TextSpan(0, document.GetTextAsync().Result.Length)); analyzer.VerifyAllAnalyzerMembersWereCalled(); analyzer.VerifyAnalyzeSymbolCalledForAllSymbolKinds(); analyzer.VerifyAnalyzeNodeCalledForAllSyntaxKinds(syntaxKindsPatterns); analyzer.VerifyOnCodeBlockCalledForAllSymbolAndMethodKinds(symbolKindsWithNoCodeBlocks, true); } }
public void DiagnosticAnalyzerDriverIsSafeAgainstAnalyzerExceptions() { var source = TestResource.AllInOneCSharpCode; using (var workspace = CSharpWorkspaceFactory.CreateWorkspaceFromFile(source, TestOptions.Regular)) { var document = workspace.CurrentSolution.Projects.Single().Documents.Single(); ThrowingDiagnosticAnalyzer <SyntaxKind> .VerifyAnalyzerEngineIsSafeAgainstExceptions(analyzer => DiagnosticProviderTestUtilities.GetAllDiagnostics(analyzer, document, new Text.TextSpan(0, document.GetTextAsync().Result.Length), logAnalyzerExceptionAsDiagnostics: true)); } }
public async Task DiagnosticAnalyzerDriverIsSafeAgainstAnalyzerExceptions() { var source = TestResource.AllInOneCSharpCode; using var workspace = TestWorkspace.CreateCSharp(source, TestOptions.Regular); var document = workspace.CurrentSolution.Projects.Single().Documents.Single(); await ThrowingDiagnosticAnalyzer <SyntaxKind> .VerifyAnalyzerEngineIsSafeAgainstExceptionsAsync(async analyzer => await DiagnosticProviderTestUtilities.GetAllDiagnosticsAsync(analyzer, document, new TextSpan(0, document.GetTextAsync().Result.Length))); }
internal override IEnumerable <Tuple <Diagnostic, CodeFixCollection> > GetDiagnosticAndFixes(TestWorkspace workspace, string fixAllActionId) { var providerAndFixer = CreateDiagnosticProviderAndFixer(workspace); var provider = providerAndFixer.Item1; Document document; TextSpan span; string annotation = null; if (!TryGetDocumentAndSelectSpan(workspace, out document, out span)) { document = GetDocumentAndAnnotatedSpan(workspace, out annotation, out span); } var diagnostics = DiagnosticProviderTestUtilities.GetAllDiagnostics(provider, document, span); var fixer = providerAndFixer.Item2; var ids = new HashSet <string>(fixer.FixableDiagnosticIds); var dxs = diagnostics.Where(d => ids.Contains(d.Id)).ToList(); foreach (var diagnostic in dxs) { if (annotation == null) { var fixes = new List <CodeFix>(); var context = new CodeFixContext(document, diagnostic, (a, d) => fixes.Add(new CodeFix(a, d)), CancellationToken.None); fixer.RegisterCodeFixesAsync(context).Wait(); if (fixes.Any()) { var codeFix = new CodeFixCollection(fixer, diagnostic.Location.SourceSpan, fixes); yield return(Tuple.Create(diagnostic, codeFix)); } } else { var fixAllProvider = fixer.GetFixAllProvider(); Assert.NotNull(fixAllProvider); FixAllScope scope = GetFixAllScope(annotation); Func <Document, ImmutableHashSet <string>, CancellationToken, Task <IEnumerable <Diagnostic> > > getDocumentDiagnosticsAsync = (d, diagIds, c) => { var root = d.GetSyntaxRootAsync().Result; var diags = DiagnosticProviderTestUtilities.GetDocumentDiagnostics(provider, d, root.FullSpan); diags = diags.Where(diag => diagIds.Contains(diag.Id)); return(Task.FromResult(diags)); }; Func <Project, bool, ImmutableHashSet <string>, CancellationToken, Task <IEnumerable <Diagnostic> > > getProjectDiagnosticsAsync = (p, includeAllDocumentDiagnostics, diagIds, c) => { var diags = includeAllDocumentDiagnostics ? DiagnosticProviderTestUtilities.GetAllDiagnostics(provider, p) : DiagnosticProviderTestUtilities.GetProjectDiagnostics(provider, p); diags = diags.Where(diag => diagIds.Contains(diag.Id)); return(Task.FromResult(diags)); }; var diagnosticIds = ImmutableHashSet.Create(diagnostic.Id); var fixAllDiagnosticProvider = new FixAllCodeActionContext.FixAllDiagnosticProvider(diagnosticIds, getDocumentDiagnosticsAsync, getProjectDiagnosticsAsync); var fixAllContext = new FixAllContext(document, fixer, scope, fixAllActionId, diagnosticIds, fixAllDiagnosticProvider, CancellationToken.None); var fixAllFix = fixAllProvider.GetFixAsync(fixAllContext).WaitAndGetResult(CancellationToken.None); if (fixAllFix != null) { var codeFix = new CodeFixCollection(fixAllProvider, diagnostic.Location.SourceSpan, ImmutableArray.Create(new CodeFix(fixAllFix, diagnostic))); yield return(Tuple.Create(diagnostic, codeFix)); } } } }
protected async Task TestPragmaOrAttributeAsync( string code, ParseOptions options, bool pragma, Func <SyntaxNode, bool> digInto, Func <string, bool> verifier, Func <CodeAction, bool> fixChecker ) { using (var workspace = CreateWorkspaceFromFile(code, options)) { var(analyzer, fixer) = CreateDiagnosticProviderAndFixer(workspace); var analyzerReference = new AnalyzerImageReference( ImmutableArray.Create <DiagnosticAnalyzer>(analyzer) ); workspace.TryApplyChanges( workspace.CurrentSolution.WithAnalyzerReferences(new[] { analyzerReference }) ); var document = workspace.CurrentSolution.Projects.Single().Documents.Single(); var root = document.GetSyntaxRootAsync().GetAwaiter().GetResult(); var existingDiagnostics = root.GetDiagnostics().ToArray(); var descendants = root.DescendantNodesAndSelf(digInto).ToImmutableArray(); analyzer.AllNodes = descendants; var diagnostics = await DiagnosticProviderTestUtilities.GetAllDiagnosticsAsync( workspace, document, root.FullSpan ); foreach (var diagnostic in diagnostics) { if (!fixer.IsFixableDiagnostic(diagnostic)) { continue; } var fixes = fixer .GetFixesAsync( document, diagnostic.Location.SourceSpan, SpecializedCollections.SingletonEnumerable(diagnostic), CancellationToken.None ) .GetAwaiter() .GetResult(); if (fixes == null || fixes.Count() <= 0) { continue; } var fix = GetFix(fixes.Select(f => f.Action), pragma); if (fix == null) { continue; } // already same fix has been tested if (fixChecker(fix)) { continue; } var operations = fix.GetOperationsAsync(CancellationToken.None) .GetAwaiter() .GetResult(); var applyChangesOperation = operations.OfType <ApplyChangesOperation>().Single(); var newDocument = applyChangesOperation.ChangedSolution.Projects .Single() .Documents.Single(); var newTree = newDocument.GetSyntaxTreeAsync().GetAwaiter().GetResult(); var newText = newTree.GetText().ToString(); Assert.True(verifier(newText)); var newDiagnostics = newTree.GetDiagnostics(); Assert.Equal(0, existingDiagnostics.Except(newDiagnostics, this).Count()); } } }