1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Composition;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Formatting;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Internal.Log;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
using Microsoft.CodeAnalysis;
namespace ICSharpCode.NRefactory6.CSharp.Features.RemoveUnnecessaryImports
{
partial class CSharpRemoveUnnecessaryImportsService
{
public static IEnumerable<SyntaxNode> GetUnnecessaryImports(SemanticModel semanticModel, SyntaxNode root, CancellationToken cancellationToken)
{
var diagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken);
if (!diagnostics.Any())
{
return null;
}
var unnecessaryImports = new HashSet<UsingDirectiveSyntax>();
foreach (var diagnostic in diagnostics)
{
if (diagnostic.Id == "CS8019")
{
var node = root.FindNode(diagnostic.Location.SourceSpan) as UsingDirectiveSyntax;
if (node != null)
{
unnecessaryImports.Add(node);
}
}
}
if (cancellationToken.IsCancellationRequested || !unnecessaryImports.Any())
{
return null;
}
return unnecessaryImports;
}
public Document RemoveUnnecessaryImports(Document document, SemanticModel model, SyntaxNode root, CancellationToken cancellationToken)
{
var unnecessaryImports = GetUnnecessaryImports(model, root, cancellationToken) as ISet<UsingDirectiveSyntax>;
if (unnecessaryImports == null)
{
return document;
}
var oldRoot = (CompilationUnitSyntax)root;
if (unnecessaryImports.Any(import => oldRoot.OverlapsHiddenPosition(cancellationToken)))
{
return document;
}
var newRoot = (CompilationUnitSyntax)new Rewriter(unnecessaryImports, cancellationToken).Visit(oldRoot);
if (cancellationToken.IsCancellationRequested)
{
return null;
}
return document.WithSyntaxRoot(FormatResult(document, newRoot, cancellationToken));
}
private SyntaxNode FormatResult(Document document, CompilationUnitSyntax newRoot, CancellationToken cancellationToken)
{
var spans = new List<TextSpan>();
AddFormattingSpans(newRoot, spans, cancellationToken);
return Formatter.Format(newRoot, spans, document.Project.Solution.Workspace, document.Project.Solution.Workspace.Options, cancellationToken: cancellationToken);
}
private void AddFormattingSpans(
CompilationUnitSyntax compilationUnit,
List<TextSpan> spans,
CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
spans.Add(TextSpan.FromBounds(0, GetEndPosition(compilationUnit, compilationUnit.Members)));
foreach (var @namespace in compilationUnit.Members.OfType<NamespaceDeclarationSyntax>())
{
AddFormattingSpans(@namespace, spans, cancellationToken);
}
}
private void AddFormattingSpans(
NamespaceDeclarationSyntax namespaceMember,
List<TextSpan> spans,
CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
spans.Add(TextSpan.FromBounds(namespaceMember.SpanStart, GetEndPosition(namespaceMember, namespaceMember.Members)));
foreach (var @namespace in namespaceMember.Members.OfType<NamespaceDeclarationSyntax>())
{
AddFormattingSpans(@namespace, spans, cancellationToken);
}
}
private int GetEndPosition(SyntaxNode container, SyntaxList<MemberDeclarationSyntax> list)
{
return list.Count > 0 ? list[0].SpanStart : container.Span.End;
}
}
}
|