Skip to content

Commit 92ae6b8

Browse files
author
Zubin Ramlakhan
committed
FileSystems TextReplConverter and SolutionConverter are now injectable.
1 parent af13c77 commit 92ae6b8

File tree

4 files changed

+70
-56
lines changed

4 files changed

+70
-56
lines changed

CodeConverter/Shared/ProjectConversion.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,10 @@
1010
using ICSharpCode.CodeConverter.CSharp;
1111
using ICSharpCode.CodeConverter.Util;
1212
using Microsoft.CodeAnalysis;
13+
using Microsoft.CodeAnalysis.Text;
14+
1315
namespace ICSharpCode.CodeConverter.Shared
1416
{
15-
using System.IO.Abstractions;
16-
using Microsoft.CodeAnalysis.Text;
17-
1817
public class ProjectConversion
1918
{
2019
private readonly IProjectContentsConverter _projectContentsConverter;
@@ -82,7 +81,8 @@ private static ConversionResult GetSingleResultForDocument(ConversionResult[] co
8281
}
8382

8483
public static async IAsyncEnumerable<ConversionResult> ConvertProject(Project project,
85-
ILanguageConversion languageConversion, IProgress<ConversionProgress> progress,
84+
ILanguageConversion languageConversion, TextReplacementConverter textReplacementConverter,
85+
IProgress<ConversionProgress> progress,
8686
IEnumerable<IAssemblySymbol> assembliesBeingConverted,
8787
[EnumeratorCancellation] CancellationToken cancellationToken,
8888
params (string Find, string Replace, bool FirstOnly)[] replacements)
@@ -93,12 +93,14 @@ public static async IAsyncEnumerable<ConversionResult> ConvertProject(Project pr
9393
var sourceFilePaths = project.Documents.Concat(projectContentsConverter.SourceProject.AdditionalDocuments).Select(d => d.FilePath).ToImmutableHashSet();
9494
var convertProjectContents = ConvertProjectContents(projectContentsConverter, languageConversion, progress, cancellationToken);
9595

96-
var results = WithProjectFile(projectContentsConverter, languageConversion, sourceFilePaths, convertProjectContents, replacements);
96+
var results = WithProjectFile(projectContentsConverter, textReplacementConverter, languageConversion, sourceFilePaths, convertProjectContents, replacements);
9797
await foreach (var result in results.WithCancellation(cancellationToken)) yield return result;
9898
}
9999

100100
/// <remarks>Perf: Keep lazy so that we don't keep an extra copy of all files in memory at once</remarks>
101-
private static async IAsyncEnumerable<ConversionResult> WithProjectFile(IProjectContentsConverter projectContentsConverter, ILanguageConversion languageConversion, ImmutableHashSet<string> originalSourcePaths, IAsyncEnumerable<ConversionResult> convertProjectContents, (string Find, string Replace, bool FirstOnly)[] replacements)
101+
private static async IAsyncEnumerable<ConversionResult> WithProjectFile(IProjectContentsConverter projectContentsConverter, TextReplacementConverter textReplacementConverter,
102+
ILanguageConversion languageConversion, ImmutableHashSet<string> originalSourcePaths,
103+
IAsyncEnumerable<ConversionResult> convertProjectContents, (string Find, string Replace, bool FirstOnly)[] replacements)
102104
{
103105
var project = projectContentsConverter.SourceProject;
104106
var projectDir = project.GetDirectoryPath();
@@ -129,14 +131,17 @@ private static async IAsyncEnumerable<ConversionResult> WithProjectFile(IProject
129131
ChangeLanguageVersionRegex(projectContentsConverter.LanguageVersion)
130132
}).ToArray();
131133

132-
yield return ConvertProjectFile(project, languageConversion, replacementSpecs);
134+
yield return ConvertProjectFile(project, languageConversion, textReplacementConverter, replacementSpecs);
133135
}
134136

135137
public static ConversionResult ConvertProjectFile(Project project,
136138
ILanguageConversion languageConversion,
139+
TextReplacementConverter textReplacementConverter,
137140
params (string Find, string Replace, bool FirstOnly)[] textReplacements)
138141
{
139-
return new FileInfo(project.FilePath).ConversionResultFromReplacements(textReplacements,
142+
var fileInfo = new FileInfo(project.FilePath);
143+
144+
return textReplacementConverter.ConversionResultFromReplacements(fileInfo, textReplacements,
140145
languageConversion.PostTransformProjectFile);
141146
}
142147

CodeConverter/Shared/SolutionConverter.cs

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,39 +20,34 @@ public class SolutionConverter
2020
private readonly ILanguageConversion _languageConversion;
2121
private readonly SolutionFileTextEditor _solutionFileTextEditor;
2222
private readonly CancellationToken _cancellationToken;
23-
24-
public static IFileSystem FileSystem { get; set; } = new FileSystem();
25-
26-
public static SolutionConverter CreateFor<TLanguageConversion>(IReadOnlyCollection<Project> projectsToConvert, string sourceSolutionContents)
27-
where TLanguageConversion : ILanguageConversion, new()
28-
{
29-
return CreateFor<TLanguageConversion>(projectsToConvert, solutionContents: sourceSolutionContents);
30-
}
23+
private readonly TextReplacementConverter _textReplacementConverter;
3124

3225
public static SolutionConverter CreateFor<TLanguageConversion>(IReadOnlyCollection<Project> projectsToConvert,
3326
ConversionOptions conversionOptions = default,
3427
IProgress<ConversionProgress> progress = null,
3528
CancellationToken cancellationToken = default,
29+
IFileSystem fileSystem = null,
3630
string solutionContents = "") where TLanguageConversion : ILanguageConversion, new()
3731
{
3832
var conversion = new TLanguageConversion { ConversionOptions = conversionOptions };
39-
return CreateFor(conversion, projectsToConvert, progress, cancellationToken, solutionContents);
33+
return CreateFor(conversion, projectsToConvert, progress, cancellationToken, fileSystem, solutionContents);
4034
}
4135

4236
public static SolutionConverter CreateFor(ILanguageConversion languageConversion, IReadOnlyCollection<Project> projectsToConvert,
43-
IProgress<ConversionProgress> progress,
44-
CancellationToken cancellationToken, string solutionContents = "")
37+
IProgress<ConversionProgress> progress, CancellationToken cancellationToken, IFileSystem fileSystem = null, string solutionContents = "")
4538
{
4639
languageConversion.ConversionOptions ??= new ConversionOptions();
40+
fileSystem ??= new FileSystem();
41+
4742
var solutionFilePath = projectsToConvert.First().Solution.FilePath;
48-
var sourceSolutionContents = File.Exists(solutionFilePath)
49-
? FileSystem.File.ReadAllText(solutionFilePath)
43+
var sourceSolutionContents = fileSystem.File.Exists(solutionFilePath)
44+
? fileSystem.File.ReadAllText(solutionFilePath)
5045
: solutionContents;
5146

5247
var projTuples = projectsToConvert.Select(proj =>
5348
{
5449
var relativeProjPath = PathConverter.GetRelativePath(solutionFilePath, proj.FilePath);
55-
var projContents = FileSystem.File.ReadAllText(proj.FilePath);
50+
var projContents = fileSystem.File.ReadAllText(proj.FilePath);
5651

5752
return (proj.Name, RelativeProjPath: relativeProjPath, ProjContents: projContents);
5853
});
@@ -61,15 +56,15 @@ public static SolutionConverter CreateFor(ILanguageConversion languageConversion
6156
var projectReferenceReplacements = solutionFileTextEditor.GetProjectFileProjectReferenceReplacements(projTuples, sourceSolutionContents);
6257

6358
return new SolutionConverter(solutionFilePath, sourceSolutionContents, projectsToConvert, projectReferenceReplacements,
64-
progress ?? new Progress<ConversionProgress>(), cancellationToken, languageConversion, solutionFileTextEditor);
59+
progress ?? new Progress<ConversionProgress>(), cancellationToken, languageConversion, solutionFileTextEditor, fileSystem);
6560
}
6661

6762
private SolutionConverter(string solutionFilePath,
6863
string sourceSolutionContents, IReadOnlyCollection<Project> projectsToConvert,
6964
List<(string Find, string Replace, bool FirstOnly)> projectReferenceReplacements,
7065
IProgress<ConversionProgress> showProgressMessage,
7166
CancellationToken cancellationToken, ILanguageConversion languageConversion,
72-
SolutionFileTextEditor solutionFileTextEditor)
67+
SolutionFileTextEditor solutionFileTextEditor, IFileSystem fileSystem)
7368
{
7469
_solutionFilePath = solutionFilePath;
7570
_sourceSolutionContents = sourceSolutionContents;
@@ -79,6 +74,7 @@ private SolutionConverter(string solutionFilePath,
7974
_languageConversion = languageConversion;
8075
_cancellationToken = cancellationToken;
8176
_solutionFileTextEditor = solutionFileTextEditor;
77+
_textReplacementConverter = new TextReplacementConverter(fileSystem);
8278
}
8379

8480
public async IAsyncEnumerable<ConversionResult> Convert()
@@ -103,17 +99,20 @@ private IAsyncEnumerable<ConversionResult> ConvertProject(Project project, IEnum
10399
{
104100
var replacements = _projectReferenceReplacements.ToArray();
105101
_progress.Report(new ConversionProgress($"Converting {project.Name}..."));
106-
return ProjectConversion.ConvertProject(project, _languageConversion, _progress, assembliesBeingConverted, _cancellationToken, replacements);
102+
return ProjectConversion.ConvertProject(project, _languageConversion, _textReplacementConverter, _progress, assembliesBeingConverted, _cancellationToken, replacements);
107103
}
108104

109105
private IEnumerable<ConversionResult> UpdateProjectReferences(IEnumerable<Project> projectsToUpdateReferencesOnly)
110106
{
111107
var conversionResults = projectsToUpdateReferencesOnly
112108
.Where(p => p.FilePath != null) //Some project types like Websites don't have a project file
113109
.Select(project => {
114-
var withReferencesReplaced =
115-
new FileInfo(project.FilePath).ConversionResultFromReplacements(_projectReferenceReplacements);
110+
var fileInfo = new FileInfo(project.FilePath);
111+
112+
var withReferencesReplaced =
113+
_textReplacementConverter.ConversionResultFromReplacements(fileInfo, _projectReferenceReplacements);
116114
withReferencesReplaced.TargetPathOrNull = withReferencesReplaced.SourcePathOrNull;
115+
117116
return withReferencesReplaced;
118117
});
119118

@@ -129,7 +128,7 @@ public ConversionResult ConvertSolutionFile()
129128
var slnProjectReferenceReplacements = _solutionFileTextEditor.GetSolutionFileProjectReferenceReplacements(relativeProjPaths,
130129
_sourceSolutionContents, projectTypeGuidMappings);
131130

132-
var convertedSolutionContents = _sourceSolutionContents.Replace(slnProjectReferenceReplacements);
131+
var convertedSolutionContents = _textReplacementConverter.Replace(_sourceSolutionContents, slnProjectReferenceReplacements);
133132
return new ConversionResult(convertedSolutionContents) {
134133
SourcePathOrNull = _solutionFilePath,
135134
TargetPathOrNull = _solutionFilePath

CodeConverter/Shared/TextReplacementConverter.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,26 @@ namespace ICSharpCode.CodeConverter.Shared
66
using System.Text.RegularExpressions;
77
using System.IO.Abstractions;
88

9-
public static class TextReplacementConverter
9+
public class TextReplacementConverter
1010
{
11-
public static IFileSystem FileSystem { get; set; } = new FileSystem();
11+
private readonly IFileSystem _fileSystem;
1212

13-
public static ConversionResult ConversionResultFromReplacements(this FileInfo filePath, IEnumerable<(string Find, string Replace, bool FirstOnly)> replacements, Func<string, string> postReplacementTransform = null)
13+
public TextReplacementConverter(IFileSystem fileSystem)
14+
{
15+
_fileSystem = fileSystem;
16+
}
17+
18+
public ConversionResult ConversionResultFromReplacements(FileInfo filePath, IEnumerable<(string Find, string Replace, bool FirstOnly)> replacements,
19+
Func<string, string> postReplacementTransform = null)
1420
{
1521
postReplacementTransform ??= (s => s);
16-
var oldProjectText = FileSystem.File.ReadAllText(filePath.FullName);
17-
var newProjectText = oldProjectText.Replace(replacements);
22+
var oldProjectText = _fileSystem.File.ReadAllText(filePath.FullName);
23+
var newProjectText = Replace(oldProjectText, replacements);
1824
string withReplacements = postReplacementTransform(newProjectText);
1925
return new ConversionResult(withReplacements) { SourcePathOrNull = filePath.FullName, IsIdentity = oldProjectText == withReplacements};
2026
}
2127

22-
public static string Replace(this string originalText, IEnumerable<(string Find, string Replace, bool FirstOnly)> replacements)
28+
public string Replace(string originalText, IEnumerable<(string Find, string Replace, bool FirstOnly)> replacements)
2329
{
2430
foreach (var (oldValue, newValue, firstOnly) in replacements) {
2531
Regex regex = new Regex(oldValue, RegexOptions.IgnoreCase);

0 commit comments

Comments
 (0)