public DiagnosticTaggerWrapper( TestWorkspace workspace, IReadOnlyDictionary <string, ImmutableArray <DiagnosticAnalyzer> >?analyzerMap = null, IDiagnosticUpdateSource?updateSource = null, bool createTaggerProvider = true) { _threadingContext = workspace.GetService <IThreadingContext>(); _listenerProvider = workspace.GetService <IAsynchronousOperationListenerProvider>(); var analyzerReference = new TestAnalyzerReferenceByLanguage(analyzerMap ?? DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap()); workspace.TryApplyChanges(workspace.CurrentSolution.WithAnalyzerReferences(new[] { analyzerReference })); // Change the background analysis scope to OpenFiles instead of ActiveFile (default), // so that every diagnostic tagger test does not need to mark test files as "active" file. var csKey = new OptionKey2(SolutionCrawlerOptions.BackgroundAnalysisScopeOption, LanguageNames.CSharp); var vbKey = new OptionKey2(SolutionCrawlerOptions.BackgroundAnalysisScopeOption, LanguageNames.VisualBasic); workspace.SetOptions(workspace.Options .WithChangedOption(csKey, BackgroundAnalysisScope.OpenFiles) .WithChangedOption(vbKey, BackgroundAnalysisScope.OpenFiles)); _workspace = workspace; _registrationService = (SolutionCrawlerRegistrationService)workspace.Services.GetRequiredService <ISolutionCrawlerRegistrationService>(); _registrationService.Register(workspace); if (!_registrationService.GetTestAccessor().TryGetWorkCoordinator(workspace, out var coordinator)) { throw new InvalidOperationException(); } AnalyzerService = (DiagnosticAnalyzerService?)_registrationService.GetTestAccessor().AnalyzerProviders.SelectMany(pair => pair.Value).SingleOrDefault(lazyProvider => lazyProvider.Metadata.Name == WellKnownSolutionCrawlerAnalyzers.Diagnostic && lazyProvider.Metadata.HighPriorityForActiveFile)?.Value; DiagnosticService = (DiagnosticService)workspace.ExportProvider.GetExportedValue <IDiagnosticService>(); if (updateSource is object) { DiagnosticService.Register(updateSource); } if (createTaggerProvider) { _ = TaggerProvider; } }
public async Task CustomizableTagsForUnnecessaryCode() { var workspaceXml = @"<Workspace> <Project Language=""C#"" CommonReferences=""true""> <Document FilePath = ""Test.cs"" > // System is used - rest are unused. using System.Collections; using System; using System.Diagnostics; using System.Collections.Generic; class Program { void Test() { Int32 x = 2; // Int32 can be simplified. x += 1; } } </Document> </Project> </Workspace>"; using var workspace = TestWorkspace.Create(workspaceXml, composition: SquiggleUtilities.CompositionWithSolutionCrawler); var options = new Dictionary <OptionKey2, object>(); var language = workspace.Projects.Single().Language; var preferIntrinsicPredefinedTypeOption = new OptionKey2(CodeStyleOptions2.PreferIntrinsicPredefinedTypeKeywordInDeclaration, language); var preferIntrinsicPredefinedTypeOptionValue = new CodeStyleOption2 <bool>(value: true, notification: NotificationOption2.Error); options.Add(preferIntrinsicPredefinedTypeOption, preferIntrinsicPredefinedTypeOptionValue); workspace.ApplyOptions(options); var analyzerMap = new Dictionary <string, ImmutableArray <DiagnosticAnalyzer> > { { LanguageNames.CSharp, ImmutableArray.Create <DiagnosticAnalyzer>( new CSharpSimplifyTypeNamesDiagnosticAnalyzer(), new CSharpRemoveUnnecessaryImportsDiagnosticAnalyzer(), new ReportOnClassWithLink()) } }; var diagnosticsAndSpans = await TestDiagnosticTagProducer <DiagnosticsSquiggleTaggerProvider> .GetDiagnosticsAndErrorSpans(workspace, analyzerMap); var spans = diagnosticsAndSpans.Item1 .Zip(diagnosticsAndSpans.Item2, (diagnostic, span) => (diagnostic, span)) .OrderBy(s => s.span.Span.Span.Start).ToImmutableArray(); Assert.Equal(4, spans.Length); var first = spans[0].span; var second = spans[1].span; var third = spans[2].span; var fourth = spans[3].span; var expectedToolTip = new ContainerElement( ContainerElementStyle.Wrapped, new ClassifiedTextElement( new ClassifiedTextRun(ClassificationTypeNames.Text, "IDE0005"), new ClassifiedTextRun(ClassificationTypeNames.Punctuation, ":"), new ClassifiedTextRun(ClassificationTypeNames.WhiteSpace, " "), new ClassifiedTextRun(ClassificationTypeNames.Text, CSharpAnalyzersResources.Using_directive_is_unnecessary))); Assert.Equal(PredefinedErrorTypeNames.Suggestion, first.Tag.ErrorType); ToolTipAssert.EqualContent(expectedToolTip, first.Tag.ToolTipContent); Assert.Equal(40, first.Span.Start); Assert.Equal(25, first.Span.Length); expectedToolTip = new ContainerElement( ContainerElementStyle.Wrapped, new ClassifiedTextElement( new ClassifiedTextRun(ClassificationTypeNames.Text, "IDE0005"), new ClassifiedTextRun(ClassificationTypeNames.Punctuation, ":"), new ClassifiedTextRun(ClassificationTypeNames.WhiteSpace, " "), new ClassifiedTextRun(ClassificationTypeNames.Text, CSharpAnalyzersResources.Using_directive_is_unnecessary))); Assert.Equal(PredefinedErrorTypeNames.Suggestion, second.Tag.ErrorType); ToolTipAssert.EqualContent(expectedToolTip, second.Tag.ToolTipContent); Assert.Equal(82, second.Span.Start); Assert.Equal(60, second.Span.Length); expectedToolTip = new ContainerElement( ContainerElementStyle.Wrapped, new ClassifiedTextElement( new ClassifiedTextRun(ClassificationTypeNames.Text, "id", QuickInfoHyperLink.TestAccessor.CreateNavigationAction(new Uri("https://github.com/dotnet/roslyn", UriKind.Absolute)), "https://github.com/dotnet/roslyn"), new ClassifiedTextRun(ClassificationTypeNames.Punctuation, ":"), new ClassifiedTextRun(ClassificationTypeNames.WhiteSpace, " "), new ClassifiedTextRun(ClassificationTypeNames.Text, "messageFormat"))); Assert.Equal(PredefinedErrorTypeNames.Warning, third.Tag.ErrorType); ToolTipAssert.EqualContent(expectedToolTip, third.Tag.ToolTipContent); Assert.Equal(152, third.Span.Start); Assert.Equal(7, third.Span.Length); expectedToolTip = new ContainerElement( ContainerElementStyle.Wrapped, new ClassifiedTextElement( new ClassifiedTextRun(ClassificationTypeNames.Text, "IDE0049"), new ClassifiedTextRun(ClassificationTypeNames.Punctuation, ":"), new ClassifiedTextRun(ClassificationTypeNames.WhiteSpace, " "), new ClassifiedTextRun(ClassificationTypeNames.Text, WorkspacesResources.Name_can_be_simplified))); Assert.Equal(PredefinedErrorTypeNames.SyntaxError, fourth.Tag.ErrorType); ToolTipAssert.EqualContent(expectedToolTip, fourth.Tag.ToolTipContent); Assert.Equal(196, fourth.Span.Start); Assert.Equal(5, fourth.Span.Length); }
public async Task CustomizableTagsForUnnecessaryCode() { var workspaceXml = @"<Workspace> <Project Language=""C#"" CommonReferences=""true""> <Document FilePath = ""Test.cs"" > // System is used - rest are unused. using System.Collections; using System; using System.Diagnostics; using System.Collections.Generic; class Program { void Test() { Int32 x = 2; // Int32 can be simplified. x += 1; } } </Document> </Project> </Workspace>"; using var workspace = TestWorkspace.Create(workspaceXml); var options = new Dictionary <OptionKey2, object>(); var language = workspace.Projects.Single().Language; var preferIntrinsicPredefinedTypeOption = new OptionKey2(CodeStyleOptions2.PreferIntrinsicPredefinedTypeKeywordInDeclaration, language); var preferIntrinsicPredefinedTypeOptionValue = new CodeStyleOption2 <bool>(value: true, notification: NotificationOption2.Error); options.Add(preferIntrinsicPredefinedTypeOption, preferIntrinsicPredefinedTypeOptionValue); workspace.ApplyOptions(options); var analyzerMap = new Dictionary <string, ImmutableArray <DiagnosticAnalyzer> > { { LanguageNames.CSharp, ImmutableArray.Create <DiagnosticAnalyzer>( new CSharpSimplifyTypeNamesDiagnosticAnalyzer(), new CSharpRemoveUnnecessaryImportsDiagnosticAnalyzer()) } }; var spans = (await _producer.GetDiagnosticsAndErrorSpans(workspace, analyzerMap)).Item2 .OrderBy(s => s.Span.Span.Start).ToImmutableArray(); Assert.Equal(3, spans.Length); var first = spans[0]; var second = spans[1]; var third = spans[2]; Assert.Equal(PredefinedErrorTypeNames.Suggestion, first.Tag.ErrorType); Assert.Equal(CSharpAnalyzersResources.Using_directive_is_unnecessary, first.Tag.ToolTipContent); Assert.Equal(40, first.Span.Start); Assert.Equal(25, first.Span.Length); Assert.Equal(PredefinedErrorTypeNames.Suggestion, second.Tag.ErrorType); Assert.Equal(CSharpAnalyzersResources.Using_directive_is_unnecessary, second.Tag.ToolTipContent); Assert.Equal(82, second.Span.Start); Assert.Equal(60, second.Span.Length); Assert.Equal(PredefinedErrorTypeNames.SyntaxError, third.Tag.ErrorType); Assert.Equal(WorkspacesResources.Name_can_be_simplified, third.Tag.ToolTipContent); Assert.Equal(196, third.Span.Start); Assert.Equal(5, third.Span.Length); }
public NamingStylesTestOptionSets(string languageName) { _languageName = languageName; _optionKey = NamingStyleOptions.GetNamingPreferencesOptionKey(languageName); }
public bool IsSupported(OptionKey2 key) => _key == key;
public IndentationSizeVViewModelFactory() { _key = new OptionKey2(FormattingOptions2.IndentationSize, LanguageNames.CSharp); }
public NewLineViewModelFactory() { _key = new OptionKey2(FormattingOptions2.NewLine, LanguageNames.CSharp); }
public OperatorPlacementWhenWrappingViewModelFactory() { _key = new OptionKey2(CodeStyleOptions2.OperatorPlacementWhenWrapping); }
private IOptionsCollection Options(OptionKey2 option, object value) => Options(new[] { (option, value) });
public bool IsSupported(OptionKey2 key) => key.Option.Type == typeof(BinaryOperatorSpacingOptions);
public OperatorPlacementWhenWrappingViewModelFactory() { _key = new OptionKey2(CodeStyleOptions2.OperatorPlacementWhenWrapping, LanguageNames.CSharp); }
public bool IsSupported(OptionKey2 key) => key.Option.Type == typeof(LabelPositionOptions);
public TabSizeViewModelFactory() { _key = new OptionKey2(FormattingOptions2.TabSize, LanguageNames.CSharp); }