-
Notifications
You must be signed in to change notification settings - Fork 0
/
GlobalUsingsResolver.cs
79 lines (65 loc) · 3.09 KB
/
GlobalUsingsResolver.cs
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
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.IO.Abstractions;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Tbc.Host.Components.Abstractions;
using Tbc.Host.Components.GlobalUsingsResolver.Models;
namespace Tbc.Host.Components.GlobalUsingsResolver;
public class GlobalUsingsResolver : ComponentBase<GlobalUsingsResolver>, IGlobalUsingsResolver
{
private IFileSystem _fileSystem;
public GlobalUsingsResolver(ILogger<GlobalUsingsResolver> logger, IFileSystem fileSystem) : base(logger)
{
_fileSystem = fileSystem;
}
public async Task<ResolveGlobalUsingsResponse> ResolveGlobalUsings(ResolveGlobalUsingsRequest request, CancellationToken canceller = default)
{
var sources = request.Sources;
var usings = ImmutableList.Create<string>();
var diagnostics = ImmutableDictionary.Create<string, object>();
foreach (var source in sources)
{
var (newUsings, newDiagnostics) =
source.Kind switch
{
GlobalUsingsSourceKind.Text => GetUsingsFromText(source.Reference),
GlobalUsingsSourceKind.SearchPath => GetUsingsFromSearchPath(source.Reference, source.Context),
_ => throw new ArgumentOutOfRangeException()
};
usings = usings.AddRange(newUsings);
diagnostics = diagnostics.AddRange(newDiagnostics);
}
usings = usings.Distinct().ToImmutableList();
return new ResolveGlobalUsingsResponse(
sources, usings.Distinct().ToImmutableList(),
usings.Any() ? String.Join(Environment.NewLine, usings) : null,
diagnostics);
}
public (List<string> Usings, Dictionary<string, object> Diagnostics) GetUsingsFromText(string text)
{
try
{
var usings = text.Split(';').Select(x => $"global using global::{x}").ToList();
return new(usings, new() { [text] = $"{usings.Count} usings extracted" });
}
catch (Exception ex) { return (new(), new() { [text] = ex }); }
}
public (List<string> Usings, Dictionary<string, object> Diagnostics) GetUsingsFromSearchPath(
string path, string maybeResolutionMethod)
{
maybeResolutionMethod ??= KnownGlobalUsingSearchPathResolutionApproach.LastModified;
var matches = _fileSystem.Directory.GetFiles(path, "*.GlobalUsings.g.cs", SearchOption.AllDirectories)
.OrderByDescending(x => _fileSystem.FileInfo.FromFileName(x).LastWriteTime)
.ToList();
var usings = matches
.Take(maybeResolutionMethod == KnownGlobalUsingSearchPathResolutionApproach.LastModified ? 1 : Int32.MaxValue)
.Select(f => (f, u: _fileSystem.File.ReadAllLines(f).Where(x => x.StartsWith("global using ")).ToList()))
.ToList();
return (usings.SelectMany(x => x.u).ToList(), usings.ToDictionary(x => x.f, x => (object) $"{x.u.Count} usings extracted"));
}
}