Skip to content

Commit

Permalink
update CompilationExpander
Browse files Browse the repository at this point in the history
  • Loading branch information
kzrnm committed Oct 4, 2020
1 parent e2efbe6 commit 77ff1df
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 61 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<PackageProjectUrl>https://github.com/naminodarie/SourceExpander</PackageProjectUrl>
<RepositoryUrl>https://github.com/naminodarie/SourceExpander</RepositoryUrl>

<Version>1.1.0-beta.2</Version>
<Version>1.1.0-beta.5</Version>

<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)key.snk</AssemblyOriginatorKeyFile>
Expand Down
2 changes: 1 addition & 1 deletion Sample/Generator/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;
using SampleLibrary;

using System.Reflection;
class Program
{
static void Main()
Expand Down
39 changes: 25 additions & 14 deletions Source/SourceExpander.Generator/ExpandGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization.Json;
using System.Text;
using Microsoft.CodeAnalysis;
Expand All @@ -18,14 +15,7 @@ public class ExpandGenerator : ISourceGenerator
{
public void Execute(GeneratorExecutionContext context)
{
var embeddeds = context.Compilation.References
.Select(context.Compilation.GetAssemblyOrModuleSymbol)
.OfType<ISymbol>()
.SelectMany(symbol => symbol.GetAttributes())
.Select(GetAttributeSourceCode)
.OfType<string>()
.SelectMany(ParseEmbeddedJson)
.ToArray();
var (compilation, embeddeds) = Build((CSharpCompilation)context.Compilation);
if (embeddeds.Length == 0)
{
var diagnosticDescriptor = new DiagnosticDescriptor("EXPAND0001", "not found embedded source", "not found embedded source", "ExpandGenerator", DiagnosticSeverity.Info, true);
Expand All @@ -35,11 +25,32 @@ public void Execute(GeneratorExecutionContext context)

context.AddSource("SourceExpander.Expanded.cs",
SourceText.From(
MakeExpanded(context.Compilation.SyntaxTrees.OfType<CSharpSyntaxTree>(), context.Compilation, embeddeds),
MakeExpanded(compilation.SyntaxTrees.OfType<CSharpSyntaxTree>(), compilation, embeddeds),
Encoding.UTF8));
}
static (CSharpCompilation, SourceFileInfo[]) Build(CSharpCompilation compilation)
{
var result = new List<SourceFileInfo>();
foreach (var reference in compilation.References)
{
var symbol = compilation.GetAssemblyOrModuleSymbol(reference);
if (symbol is null) continue;
foreach (var info in symbol.GetAttributes().Select(GetAttributeSourceCode).OfType<string>().SelectMany(ParseEmbeddedJson))
{
result.Add(info);
}
}

var trees = compilation.SyntaxTrees;
foreach (var tree in trees)
{
var opts = tree.Options.WithDocumentationMode(DocumentationMode.Diagnose);
compilation = compilation.ReplaceSyntaxTree(tree, tree.WithRootAndOptions(tree.GetRoot(), opts));
}

static string MakeExpanded(IEnumerable<CSharpSyntaxTree> trees, Compilation compilation, SourceFileInfo[] infos)
return (compilation, result.ToArray());
}
static string MakeExpanded(IEnumerable<CSharpSyntaxTree> trees, CSharpCompilation compilation, SourceFileInfo[] infos)
{
var sb = new StringBuilder();
sb.AppendLine("using System.Collections.Generic;");
Expand Down
10 changes: 0 additions & 10 deletions Source/SourceExpander.Generator/MetadataLoader.cs

This file was deleted.

19 changes: 13 additions & 6 deletions Source/SourceExpander/Expanders/CompilationExpander.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,35 @@ public CompilationExpander(string code, SourceFileContainer sourceFileContainer)
.OfType<CSharpSyntaxTree>(),
references: dllPathes.Select(p => MetadataReference.CreateFromFile(p)));
}
public CompilationExpander(SyntaxTree tree, Compilation compilation, SourceFileContainer sourceFileContainer)
public CompilationExpander(SyntaxTree tree, CSharpCompilation compilation, SourceFileContainer sourceFileContainer)
: base(sourceFileContainer)
{
Compilation = compilation;
var specificDiagnosticOptions = new Dictionary<string, ReportDiagnostic>
{
{ "CS8019", ReportDiagnostic.Error },
{ "CS0105", ReportDiagnostic.Error },
};
var opts = compilation.Options
.WithSpecificDiagnosticOptions(specificDiagnosticOptions);
Compilation = compilation.WithOptions(opts);
OrigTree = tree;
}

private Compilation Compilation { get; }
private CSharpCompilation Compilation { get; }
protected SyntaxTree OrigTree { get; }
private ReadOnlyCollection<string>? linesCache;
public override IEnumerable<string> ExpandedLines()
{
IEnumerable<string> Impl()
{
var semanticModel = Compilation.GetSemanticModel(OrigTree);

var origRoot = OrigTree.GetRoot();
var requiedFiles = SourceFileContainer.ResolveDependency(GetRequiredSources(semanticModel, origRoot));

var newRoot = (CompilationUnitSyntax)(new MatchSyntaxRemover(semanticModel
var newRoot = (CompilationUnitSyntax)(new MatchSyntaxRemover(
semanticModel
.GetDiagnostics(null)
.Where(d => d.Id == "CS8019" || d.Id == "CS0105")
.Where(d => d.Id == "CS8019" || d.Id == "CS0105" || d.Id == "CS0246")
.Select(d => origRoot.FindNode(d.Location.SourceSpan))
.OfType<UsingDirectiveSyntax>())
.Visit(origRoot) ?? throw new InvalidOperationException());
Expand Down
2 changes: 1 addition & 1 deletion Source/SourceExpander/Expanders/Utils/ExpanderUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public static string ToSimpleClassName(string className)
}


private static readonly Regex usingRegex = new Regex(@"using\s+(.+);", RegexOptions.Compiled);
private static readonly Regex usingRegex = new Regex(@"using\s+(\S+);", RegexOptions.Compiled);
public static string? ParseNamespace(string usingDirective)
{
var g = usingRegex.Match(usingDirective).Groups;
Expand Down
70 changes: 42 additions & 28 deletions Test/SourceExpander.Generator.Test/ExpandGeneratorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,10 @@ public class ExpandGeneratorTest
[Fact]
public void GenerateTest()
{
var sampleReference = MetadataReference.CreateFromFile(GetSampleDllPath());
var compilation = CSharpCompilation.Create(
assemblyName: "TestAssembly",
syntaxTrees: GetSyntaxes(),
references: defaultMetadatas.Append(sampleReference),
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
compilation.SyntaxTrees.Should().HaveCount(TestSyntaxes.Length);
compilation.GetDiagnostics().Should().BeEmpty();

var generator = new ExpandGenerator();
var driver = CSharpGeneratorDriver.Create(new[] { generator }, parseOptions: new CSharpParseOptions(kind: SourceCodeKind.Regular, documentationMode: DocumentationMode.Parse));
driver.RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out var diagnostics);
diagnostics.Should().BeEmpty();
outputCompilation.SyntaxTrees.Should().HaveCount(TestSyntaxes.Length + 1);
}

static string GetSampleDllPath()
=> Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "SampleLibrary.dll");

static readonly SyntaxTree[] TestSyntaxes = GetSyntaxes().ToArray();
static IEnumerable<SyntaxTree> GetSyntaxes()
{
yield return CSharpSyntaxTree.ParseText(
@"using System;
var syntaxTrees = new[]
{
CSharpSyntaxTree.ParseText(
@"using System;
using SampleLibrary;
class Program
Expand All @@ -49,10 +29,14 @@ static void Main()
Put.WriteRandom();
}
}",
path: "/home/source/Program.cs");
yield return CSharpSyntaxTree.ParseText(
@"using System;
options: new CSharpParseOptions(documentationMode:DocumentationMode.None),
path: "/home/source/Program.cs"),
CSharpSyntaxTree.ParseText(
@"using System;
using System.Reflection;
using SampleLibrary;
using static System.MathF;
using M = System.Math;
class Program2
{
Expand All @@ -62,9 +46,39 @@ static void Main()
Put.WriteRandom();
}
}",
path: "/home/source/Program.cs");
options: new CSharpParseOptions(documentationMode:DocumentationMode.None),
path: "/home/source/Program2.cs"),
};

var sampleReference = MetadataReference.CreateFromFile(GetSampleDllPath());
var compilation = CSharpCompilation.Create(
assemblyName: "TestAssembly",
syntaxTrees: syntaxTrees,
references: defaultMetadatas.Append(sampleReference),
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
.WithSpecificDiagnosticOptions(new Dictionary<string, ReportDiagnostic> {
{ "CS8019", ReportDiagnostic.Suppress },
}));
compilation.SyntaxTrees.Should().HaveCount(syntaxTrees.Length);

var generator = new ExpandGenerator();
var driver = CSharpGeneratorDriver.Create(new[] { generator }, parseOptions: new CSharpParseOptions(kind: SourceCodeKind.Regular, documentationMode: DocumentationMode.Parse));
driver.RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out var diagnostics);
diagnostics.Should().BeEmpty();
outputCompilation.SyntaxTrees.Should().HaveCount(syntaxTrees.Length + 1);
outputCompilation.SyntaxTrees
.Single(tree => tree.FilePath.EndsWith("SourceExpander.Expanded.cs"))
.ToString()
.Should()
.NotContain("System.Reflection")
.And
.NotContain("System.Math");
}

static string GetSampleDllPath()
=> Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "SampleLibrary.dll");


static readonly MetadataReference[] defaultMetadatas = GetDefaulMetadatas().ToArray();
static IEnumerable<MetadataReference> GetDefaulMetadatas()
{
Expand Down

0 comments on commit 77ff1df

Please sign in to comment.