| File: src\roslyn\src\Analyzers\CSharp\Analyzers\RemoveUnnecessaryImports\CSharpRemoveUnnecessaryImportsDiagnosticAnalyzer.cs | Web Access |
| Project: src\roslyn\src\CodeStyle\CSharp\Analyzers\Microsoft.CodeAnalysis.CSharp.CodeStyle.csproj (Microsoft.CodeAnalysis.CSharp.CodeStyle) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Threading; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Extensions; using Microsoft.CodeAnalysis.CSharp.LanguageService; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.LanguageService; using Microsoft.CodeAnalysis.RemoveUnnecessaryImports; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.RemoveUnnecessaryImports; [DiagnosticAnalyzer(LanguageNames.CSharp)] internal sealed class CSharpRemoveUnnecessaryImportsDiagnosticAnalyzer : AbstractRemoveUnnecessaryImportsDiagnosticAnalyzer<UsingDirectiveSyntax> { public CSharpRemoveUnnecessaryImportsDiagnosticAnalyzer() : base(new LocalizableResourceString(nameof(CSharpAnalyzersResources.Using_directive_is_unnecessary), CSharpAnalyzersResources.ResourceManager, typeof(CSharpAnalyzersResources))) { } protected override GeneratedCodeAnalysisFlags GeneratedCodeAnalysisFlags => GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics; protected override ISyntaxFacts SyntaxFacts => CSharpSyntaxFacts.Instance; // C# has no need to do any merging of using statements. Only VB needs to // merge import clauses to an import statement if it all the import clauses // are unnecessary. protected override ImmutableArray<SyntaxNode> MergeImports(ImmutableArray<UsingDirectiveSyntax> unnecessaryImports) => ImmutableArray<SyntaxNode>.CastUp(unnecessaryImports); protected override IUnnecessaryImportsProvider<UsingDirectiveSyntax> UnnecessaryImportsProvider => CSharpUnnecessaryImportsProvider.Instance; protected override bool IsRegularCommentOrDocComment(SyntaxTrivia trivia) => trivia.IsRegularComment() || trivia.IsDocComment(); protected override SyntaxToken? TryGetLastToken(SyntaxNode node) // No special behavior needed for C# => null; protected override IEnumerable<TextSpan> GetFixableDiagnosticSpans( IEnumerable<SyntaxNode> nodes, SyntaxTree tree, CancellationToken cancellationToken) { Contract.ThrowIfFalse(nodes.Any()); foreach (var node in nodes.Select(n => n.GetAncestors().First(n => n is BaseNamespaceDeclarationSyntax or CompilationUnitSyntax)).Distinct()) { if (node is BaseNamespaceDeclarationSyntax namespaceDeclaration) { yield return namespaceDeclaration.Usings.GetContainedSpan(); } else if (node is CompilationUnitSyntax compilationUnit) { yield return compilationUnit.Usings.GetContainedSpan(); } } } protected override void AnalyzeSemanticModel(SemanticModelAnalysisContext context, SyntaxTree tree, CancellationToken cancellationToken) { // We've opted in to generated code analysis above, but we actually only want to analyze generated code for Razor if (context.IsGeneratedCode && tree.FilePath.IndexOf("Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator") == -1) { return; } base.AnalyzeSemanticModel(context, tree, cancellationToken); } }