Last active
July 18, 2019 13:52
-
-
Save b0urb4k1/61895ccd2bde9cf859c4648c2e468db2 to your computer and use it in GitHub Desktop.
Roslyn Utilities
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Fiacre | |
{ | |
using System.Linq; | |
using System.IO; | |
using System.Text.RegularExpressions; | |
using System.Collections.Generic; | |
using System; | |
public static class Build | |
{ | |
private static (bool success, T @new) Map<T, U>(this (bool success, U old) x, Func<U, T> map) where T : class | |
{ | |
if (x.success) | |
return (true, map(x.old)); | |
else return (false, null); | |
} | |
private static (bool success, GroupCollection groups) MatchLine(Regex regEx, string line) | |
{ | |
var match = regEx.Match(line); | |
if (match.Success) | |
return(true, match.Groups); | |
else | |
return (false, null); | |
} | |
// Gibt alle csproj und vcxproj Dateien der Solution zurueck | |
public static IEnumerable<FileInfo> GetProjectsFromSolution(FileInfo solution) | |
{ | |
var projectPattern = | |
"Project.*=.*,.*\"(?<project>.*(cs|vcx)proj)"; | |
var projectRegEx = | |
new Regex(projectPattern, RegexOptions.Compiled); | |
(bool success, FileInfo project) GetProjectFromLine(string line) => | |
MatchLine(projectRegEx, line) | |
.Map | |
( m => | |
new FileInfo | |
( Path.Combine | |
( solution.DirectoryName | |
, m["project"].Value | |
) | |
) | |
); | |
return | |
File.ReadAllLines(solution.FullName) | |
.Select(GetProjectFromLine) | |
.Where(r => r.success) | |
.Select(r => r.project); | |
} | |
// Gibt alle Compile Included Files der Projektdatei zurueck | |
public static IEnumerable<FileInfo> GetFilesFromProject(FileInfo project) | |
{ | |
var includePattern = | |
@"Compile Include=""(?<filename>(.*))"""; | |
var includeRegEx = | |
new Regex(includePattern, RegexOptions.Compiled); | |
(bool success, FileInfo file) GetFile(string line) => | |
MatchLine(includeRegEx, line) | |
.Map | |
( m => | |
new FileInfo | |
( Path.Combine | |
( project.DirectoryName | |
, m["filename"].Value | |
) | |
) | |
); | |
return | |
File.ReadAllLines(project.FullName) | |
.Select(GetFile) | |
.Where(r => r.success) | |
.Select(r => r.file); | |
} | |
public static IEnumerable<string> GetProjectReferencesFromProject(string projectLocation) | |
{ | |
var referencePattern = | |
@"ProjectReference Include=""(?<projectLocation>(.*))"""; | |
var referenceRegEx = | |
new Regex(referencePattern, RegexOptions.Compiled); | |
(bool success, string reference) GetReference(string line) => | |
MatchLine(referenceRegEx, line) | |
.Map(m => Path.GetFileNameWithoutExtension(m["projectLocation"].Value)); | |
return | |
File.ReadAllLines(projectLocation) | |
.Select(GetReference) | |
.Where(r => r.success) | |
.Select(r => r.reference); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Fiacre | |
{ | |
using System.Linq; | |
using System.IO; | |
using Microsoft.CodeAnalysis; | |
using Microsoft.CodeAnalysis.Text; | |
public static class Roslyn | |
{ | |
public static Project MkProject(AdhocWorkspace workspace, FileInfo project) | |
{ | |
var projectName = Path.GetFileNameWithoutExtension(project.Name); | |
var projectId = ProjectId.CreateNewId(); | |
var versionStamp = VersionStamp.Create(); | |
var projectInfo = | |
ProjectInfo.Create | |
( projectId | |
, versionStamp | |
, projectName | |
, projectName | |
, LanguageNames.CSharp | |
, project.FullName | |
, metadataReferences: | |
new [] | |
{ MetadataReference.CreateFromFile | |
(typeof(System.Attribute).Assembly.Location) | |
} | |
); | |
var roslynProject = workspace.AddProject(projectInfo); | |
foreach (var projectFile in Build.GetFilesFromProject(project)) | |
workspace.AddDocument | |
( projectId | |
, projectFile.Name | |
, SourceText.From(File.ReadAllText(projectFile.FullName)) | |
); | |
return roslynProject; | |
} | |
public static Solution MkSolution(FileInfo solutionFile) | |
{ | |
bool IsCSProject(FileInfo project) => | |
project.FullName.EndsWith("csproj"); | |
if (solutionFile.Exists == false) | |
throw new FileNotFoundException($"{solutionFile.FullName} not found."); | |
var workspace = new AdhocWorkspace(); | |
var solution = | |
workspace.AddSolution | |
( SolutionInfo.Create(SolutionId.CreateNewId() | |
, VersionStamp.Default) | |
); | |
var projects = | |
Build | |
.GetProjectsFromSolution(solutionFile) | |
.Where(IsCSProject); | |
foreach (var project in projects) | |
MkProject(workspace, project); | |
ResolveProjectReferences(workspace); | |
return workspace.CurrentSolution; | |
} | |
public static Document GetDocument(Solution solution, string projectName, string fileName) => | |
solution.Projects.First(p => p.Name == projectName) | |
.Documents.First(d => d.Name == fileName); | |
public static void ResolveProjectReferences(Workspace workspace) | |
{ | |
ProjectId GetProjectId(Solution s, string pN) => | |
s.Projects.First(p => p.Name == pN).Id; | |
var solution = workspace.CurrentSolution; | |
foreach (var projectId in solution.ProjectIds) | |
{ | |
var project = solution.GetProject(projectId); | |
var projectReferences = | |
Build.GetProjectReferencesFromProject(project.FilePath); | |
foreach(var projectReference in projectReferences) | |
{ | |
project = | |
project.AddProjectReference | |
( new ProjectReference | |
( GetProjectId | |
( workspace.CurrentSolution | |
, projectReference | |
))); | |
} | |
solution = project.Solution; | |
} | |
if (!workspace.TryApplyChanges(solution)) | |
System.Console.WriteLine("hae?"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment