Skip to content

Instantly share code, notes, and snippets.

@b0urb4k1
Last active July 18, 2019 13:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save b0urb4k1/61895ccd2bde9cf859c4648c2e468db2 to your computer and use it in GitHub Desktop.
Save b0urb4k1/61895ccd2bde9cf859c4648c2e468db2 to your computer and use it in GitHub Desktop.
Roslyn Utilities
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);
}
}
}
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