Skip to content

Commit 12b395f

Browse files
committed
Switches to official source generator
1 parent c4e14bd commit 12b395f

17 files changed

+240
-227
lines changed

CONTRIBUTING.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,20 @@ This project is actively developed using the following software.
77
It is highly recommended that anyone contributing to this library use the same
88
software.
99

10-
1. [Visual Studio 2017][VS].
10+
1. [Visual Studio 2022][VS].
1111

1212
All other dependencies are acquired via NuGet.
1313

1414
## Building
1515

1616
Everything in the repo may be built via building the solution file
17-
either from Visual Studio 2017 or the command line:
17+
either from Visual Studio 2022 or the command line:
1818

1919
msbuild /restore src\ImmutableObjectGraph.sln /t:pack
2020

2121
## Testing
2222

23-
The Visual Studio 2017 Test Explorer will list and execute all tests.
23+
The Visual Studio 2022 Test Explorer will list and execute all tests.
2424

2525
## Pull requests
2626

src/Directory.Build.props

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<Authors>Andrew Arnott</Authors>
1313
<Owners>Andrew Arnott</Owners>
1414
<PackageProjectUrl>https://github.com/aarnott/immutableobjectgraph</PackageProjectUrl>
15-
<LicenseUrl>https://raw.githubusercontent.com/AArnott/ImmutableObjectGraph/$GitCommitIdShort$/LICENSE.txt</LicenseUrl>
15+
<PackageLicenseExpression>MS-PL</PackageLicenseExpression>
1616
<Copyright>Copyright © Andrew Arnott</Copyright>
1717
<PackageTags>immutable</PackageTags>
1818
</PropertyGroup>
@@ -23,9 +23,4 @@
2323
<ItemGroup>
2424
<AdditionalFiles Include="$(MSBuildThisFileDirectory)stylecop.json" />
2525
</ItemGroup>
26-
<Target Name="SetNuSpecProperties" BeforeTargets="GenerateNuspec" DependsOnTargets="GetBuildVersion">
27-
<PropertyGroup>
28-
<PackageLicenseUrl>https://raw.githubusercontent.com/aarnott/ImmutableObjectGraph/$(GitCommitIdShort)/LICENSE.txt</PackageLicenseUrl>
29-
</PropertyGroup>
30-
</Target>
3126
</Project>

src/Directory.Build.targets

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,17 @@
11
<Project>
22
<PropertyGroup>
3-
<CodeGenerationRoslynVersion>0.6.1</CodeGenerationRoslynVersion>
3+
<CodeAnalysisVersion>4.1.0</CodeAnalysisVersion>
44
</PropertyGroup>
55
<ItemGroup>
6-
<PackageReference Update="CodeGeneration.Roslyn.Attributes" Version="$(CodeGenerationRoslynVersion)" />
7-
<PackageReference Update="CodeGeneration.Roslyn.BuildTime" Version="$(CodeGenerationRoslynVersion)" />
8-
<PackageReference Update="CodeGeneration.Roslyn" Version="$(CodeGenerationRoslynVersion)" />
9-
<PackageReference Update="CodeGeneration.Roslyn.Engine" Version="$(CodeGenerationRoslynVersion)" />
10-
<PackageReference Update="Microsoft.Build" Version="14.3.0" />
11-
<PackageReference Update="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.1.0" />
12-
<PackageReference Update="Microsoft.NET.Test.Sdk" Version="16.2.0" />
13-
<PackageReference Update="System.Collections.Immutable" Version="1.5.0" />
6+
<PackageReference Update="Microsoft.Build" Version="17.0.0" />
7+
<PackageReference Update="Microsoft.CodeAnalysis.CSharp" Version="$(CodeAnalysisVersion)" />
8+
<PackageReference Update="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3" />
9+
<PackageReference Update="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="$(CodeAnalysisVersion)" />
10+
<PackageReference Update="Microsoft.NET.Test.Sdk" Version="17.1.0" />
11+
<PackageReference Update="System.Collections.Immutable" Version="5.0.0" />
1412
<PackageReference Update="System.Diagnostics.Contracts" Version="4.3.0" />
15-
<PackageReference Update="Validation" Version="2.4.22" />
16-
<PackageReference Update="xunit.runner.visualstudio" Version="2.4.1" />
13+
<PackageReference Update="Validation" Version="2.5.51" />
14+
<PackageReference Update="xunit.runner.visualstudio" Version="2.4.3" />
1715
<PackageReference Update="xunit" Version="2.4.1" />
1816
</ItemGroup>
19-
<ItemGroup>
20-
<DotNetCliToolReference Update="dotnet-codegen" Version="$(CodeGenerationRoslynVersion)" />
21-
</ItemGroup>
2217
</Project>

src/ImmutableObjectGraph.Generation.Attributes/GenerateImmutableAttribute.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@
22
{
33
using System;
44
using System.Diagnostics;
5-
using global::CodeGeneration.Roslyn;
65

76
[AttributeUsage(AttributeTargets.Class)]
87
[Conditional("CodeGeneration")]
9-
[CodeGenerationAttribute("ImmutableObjectGraph.Generation.CodeGenerator, ImmutableObjectGraph.Generation, Version=" + ThisAssembly.AssemblyVersion + ", Culture=neutral, PublicKeyToken=" + ThisAssembly.PublicKeyToken)]
108
public class GenerateImmutableAttribute : Attribute
119
{
1210
public GenerateImmutableAttribute()

src/ImmutableObjectGraph.Generation.Attributes/ImmutableObjectGraph.Generation.Attributes.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,5 @@
1010
<ItemGroup>
1111
<PackageReference Include="Validation" PrivateAssets="compile" />
1212
<PackageReference Include="System.Collections.Immutable" />
13-
<PackageReference Include="CodeGeneration.Roslyn.Attributes" />
1413
</ItemGroup>
1514
</Project>

src/ImmutableObjectGraph.Generation.Tests/CodeGenTests.cs

Lines changed: 54 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
using System.Text;
1010
using System.Threading;
1111
using System.Threading.Tasks;
12-
using CodeGeneration.Roslyn.Engine;
13-
using global::CodeGeneration.Roslyn;
1412
using ImmutableObjectGraph.Generation.Roslyn;
1513
using Microsoft.CodeAnalysis;
1614
using Microsoft.CodeAnalysis.CSharp;
@@ -38,7 +36,6 @@ public CodeGenTests(ITestOutputHelper logger)
3836
.WithCompilationOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
3937
.AddMetadataReferences(GetNetStandard20References())
4038
.AddMetadataReference(MetadataReference.CreateFromFile(typeof(GenerateImmutableAttribute).Assembly.Location))
41-
.AddMetadataReference(MetadataReference.CreateFromFile(typeof(CodeGenerationAttributeAttribute).Assembly.Location))
4239
.AddMetadataReference(MetadataReference.CreateFromFile(typeof(Optional).Assembly.Location))
4340
.AddMetadataReference(MetadataReference.CreateFromFile(typeof(ImmutableArray).Assembly.Location));
4441
var inputDocument = project.AddDocument("input.cs", string.Empty);
@@ -265,40 +262,49 @@ protected async Task<GenerationResult> GenerateAsync(SourceText inputSource)
265262
{
266263
var solution = this.solution.WithDocumentText(this.inputDocumentId, inputSource);
267264
var inputDocument = solution.GetDocument(this.inputDocumentId);
268-
var generatorDiagnostics = new List<Diagnostic>();
269-
var progress = new SynchronousProgress<Diagnostic>(generatorDiagnostics.Add);
270265
var inputCompilation = (CSharpCompilation)await inputDocument.Project.GetCompilationAsync();
271-
var inputSyntaxTree = await inputDocument.GetSyntaxTreeAsync();
272-
var outputSyntaxTree = await DocumentTransform.TransformAsync(inputCompilation, inputSyntaxTree, null, Assembly.Load, progress);
273-
var outputDocument = inputDocument.Project
274-
.AddDocument("output.cs", outputSyntaxTree.GetRoot());
275-
276-
// Make sure the result compiles without errors or warnings.
277-
var compilation = await outputDocument.Project.GetCompilationAsync();
278-
var compilationDiagnostics = compilation.GetDiagnostics();
266+
var driver = CSharpGeneratorDriver.Create(new CodeGenerator());
267+
var runResult = driver.RunGenerators(inputCompilation).GetRunResult();
268+
var generatorDiagnostics = runResult.Diagnostics;
269+
var project = inputDocument.Project;
270+
271+
var i = 0;
272+
var syntaxTrees = ImmutableArray.CreateBuilder<SyntaxTree>();
273+
foreach (var t in runResult.GeneratedTrees)
274+
{
275+
var document = project.AddDocument($"output{i++}.cs", t.GetRoot());
279276

280-
SourceText outputDocumentText = await outputDocument.GetTextAsync();
281-
this.logger.WriteLine("{0}", outputDocumentText);
277+
SourceText outputDocumentText = await document.GetTextAsync();
278+
this.logger.WriteLine("{0}", outputDocumentText);
282279

283-
// Verify all line endings are consistent (otherwise VS can bug the heck out of the user if they have the generated file open).
284-
string firstLineEnding = null;
285-
foreach (var line in outputDocumentText.Lines)
286-
{
287-
string actualNewLine = line.Text.GetSubText(TextSpan.FromBounds(line.End, line.EndIncludingLineBreak)).ToString();
288-
if (firstLineEnding == null)
289-
{
290-
firstLineEnding = actualNewLine;
291-
}
292-
else if (actualNewLine != firstLineEnding && actualNewLine.Length > 0)
280+
// Verify all line endings are consistent (otherwise VS can bug the heck out of the user if they have the generated file open).
281+
string firstLineEnding = null;
282+
foreach (var line in outputDocumentText.Lines)
293283
{
294-
string expected = EscapeLineEndingCharacters(firstLineEnding);
295-
string actual = EscapeLineEndingCharacters(actualNewLine);
296-
Assert.True(false, $"Expected line ending characters '{expected}' but found '{actual}' on line {line.LineNumber + 1}.\nContent: {line}");
284+
string actualNewLine = line.Text.GetSubText(TextSpan.FromBounds(line.End, line.EndIncludingLineBreak)).ToString();
285+
if (firstLineEnding == null)
286+
{
287+
firstLineEnding = actualNewLine;
288+
}
289+
else if (actualNewLine != firstLineEnding && actualNewLine.Length > 0)
290+
{
291+
string expected = EscapeLineEndingCharacters(firstLineEnding);
292+
string actual = EscapeLineEndingCharacters(actualNewLine);
293+
Assert.True(false, $"Expected line ending characters '{expected}' but found '{actual}' on line {line.LineNumber + 1}.\nContent: {line}");
294+
}
297295
}
296+
297+
var syntaxTree = await document.GetSyntaxTreeAsync();
298+
syntaxTrees.Add(syntaxTree);
299+
300+
project = document.Project;
298301
}
299302

300-
var semanticModel = await outputDocument.GetSemanticModelAsync();
301-
var result = new GenerationResult(outputDocument, semanticModel, generatorDiagnostics, compilationDiagnostics);
303+
// Make sure the result compiles without errors or warnings.
304+
var compilation = await project.GetCompilationAsync();
305+
var compilationDiagnostics = compilation.GetDiagnostics();
306+
307+
var result = new GenerationResult(compilation, syntaxTrees.ToImmutable(), generatorDiagnostics, compilationDiagnostics);
302308

303309
foreach (var diagnostic in generatorDiagnostics)
304310
{
@@ -338,32 +344,39 @@ private static string EscapeLineEndingCharacters(string whitespace)
338344

339345
private static IEnumerable<MetadataReference> GetNetStandard20References()
340346
{
341-
string nugetPackageRoot = Environment.GetEnvironmentVariable("NUGET_PACKAGES") ?? Environment.ExpandEnvironmentVariables(@"%USERPROFILE%\.nuget\packages");
342-
string netstandardRoot = Path.Combine(nugetPackageRoot, @"netstandard.library\2.0.3\build\netstandard2.0\ref");
343-
foreach (string assembly in Directory.GetFiles(netstandardRoot, "*.dll"))
347+
var nugetPackageRoot = Environment.GetEnvironmentVariable("NUGET_PACKAGES") ?? Environment.ExpandEnvironmentVariables(@"%USERPROFILE%\.nuget\packages");
348+
foreach (var dir in Directory.GetDirectories(Path.Combine(nugetPackageRoot, "netstandard.library"), "2.*"))
344349
{
345-
yield return MetadataReference.CreateFromFile(assembly);
350+
var netstandardRoot = Path.Combine(dir, @"build\netstandard2.0\ref");
351+
foreach (string assembly in Directory.GetFiles(netstandardRoot, "*.dll"))
352+
{
353+
yield return MetadataReference.CreateFromFile(assembly);
354+
}
355+
break;
346356
}
347357
}
348358

349359
protected class GenerationResult
350360
{
351361
public GenerationResult(
352-
Document document,
353-
SemanticModel semanticModel,
362+
Compilation compilation,
363+
ImmutableArray<SyntaxTree> syntaxTrees,
354364
IReadOnlyList<Diagnostic> generatorDiagnostics,
355365
IReadOnlyList<Diagnostic> compilationDiagnostics)
356366
{
357-
this.Document = document;
358-
this.SemanticModel = semanticModel;
359-
this.Declarations = CSharpDeclarationComputer.GetDeclarationsInSpan(semanticModel, TextSpan.FromBounds(0, semanticModel.SyntaxTree.Length), true, CancellationToken.None);
367+
this.Compilation = compilation;
368+
this.SyntaxTrees = syntaxTrees;
369+
this.SemanticModels = syntaxTrees.Select(s => compilation.GetSemanticModel(s)).ToImmutableArray();
370+
this.Declarations = SemanticModels.SelectMany(semanticModel => CSharpDeclarationComputer.GetDeclarationsInSpan(semanticModel, TextSpan.FromBounds(0, semanticModel.SyntaxTree.Length), true, CancellationToken.None)).ToImmutableArray();
360371
this.GeneratorDiagnostics = generatorDiagnostics;
361372
this.CompilationDiagnostics = compilationDiagnostics;
362373
}
363374

364-
public Document Document { get; private set; }
375+
public Compilation Compilation { get; }
376+
377+
public ImmutableArray<SemanticModel> SemanticModels { get; private set; }
365378

366-
public SemanticModel SemanticModel { get; private set; }
379+
public ImmutableArray<SyntaxTree> SyntaxTrees { get; }
367380

368381
internal ImmutableArray<DeclarationInfo> Declarations { get; private set; }
369382

Lines changed: 3 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,18 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<TargetFrameworks>net472</TargetFrameworks>
4+
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
45
</PropertyGroup>
56
<ItemGroup>
6-
<Compile Update="TestSources\AbstractClassMidTypeHierarchyWithRequiredField.cs">
7-
<Generator>MSBuild:GenerateCodeFromAttributes</Generator>
8-
</Compile>
97
<EmbeddedResource Include="TestSources\AlmostRecursive.cs" />
108
<EmbeddedResource Include="TestSources\ByteArray.cs" />
119
<EmbeddedResource Include="TestSources\HierarchyLevels.cs" />
1210
<EmbeddedResource Include="TestSources\IgnoreField.cs" />
1311
<EmbeddedResource Include="TestSources\ImmutableArray.cs" />
1412
<EmbeddedResource Include="TestSources\RootedStruct_Without_WithMethodsPerProperty.cs" />
15-
<Compile Update="TestSources\Generations.cs">
16-
<Generator>MSBuild:GenerateCodeFromAttributes</Generator>
17-
</Compile>
1813
<EmbeddedResource Include="TestSources\DefineRootedStruct_NotApplicable.cs" />
19-
<Compile Update="TestSources\ImmutableDictionaryHelpers.cs">
20-
<Generator>MSBuild:GenerateCodeFromAttributes</Generator>
21-
</Compile>
22-
<Compile Update="TestSources\ImmutableWithComplexStructField.cs">
23-
<Generator>MSBuild:GenerateCodeFromAttributes</Generator>
24-
</Compile>
25-
<Compile Update="TestSources\MSBuild.cs">
26-
<Generator>MSBuild:GenerateCodeFromAttributes</Generator>
27-
</Compile>
28-
<Compile Update="TestSources\Nested.cs">
29-
<Generator>MSBuild:GenerateCodeFromAttributes</Generator>
30-
</Compile>
31-
<Compile Update="TestSources\NonRecursive.cs">
32-
<Generator>MSBuild:GenerateCodeFromAttributes</Generator>
33-
</Compile>
34-
<Compile Update="TestSources\ProjectTree.cs">
35-
<Generator>MSBuild:GenerateCodeFromAttributes</Generator>
36-
</Compile>
37-
<Compile Update="TestSources\RequiresAndHierarchy.cs">
38-
<Generator>MSBuild:GenerateCodeFromAttributes</Generator>
39-
</Compile>
40-
<Compile Update="TestSources\Sealed.cs">
41-
<Generator>MSBuild:GenerateCodeFromAttributes</Generator>
42-
</Compile>
43-
<Compile Update="TestSources\TreeNode.cs">
44-
<Generator>MSBuild:GenerateCodeFromAttributes</Generator>
45-
</Compile>
4614
<EmbeddedResource Include="TestSources\UsingImmutableObjectGraph.cs" />
47-
<Compile Update="TestSources\XmlNode.cs">
48-
<Generator>MSBuild:GenerateCodeFromAttributes</Generator>
49-
</Compile>
5015
<EmbeddedResource Include="TestSources\OneImmutableFieldToAnotherWithOneScalarField.cs" />
51-
<Compile Update="TestSources\FileSystem.cs">
52-
<Generator>MSBuild:GenerateCodeFromAttributes</Generator>
53-
</Compile>
54-
<Compile Update="TestSources\AbstractClassFamilies.cs">
55-
<Generator>MSBuild:GenerateCodeFromAttributes</Generator>
56-
</Compile>
57-
<Compile Update="TestSources\DeepHierarchy.cs">
58-
<Generator>MSBuild:GenerateCodeFromAttributes</Generator>
59-
</Compile>
6016
<EmbeddedResource Include="TestSources\OneScalarFieldAndEmptyDerived.cs" />
6117
<EmbeddedResource Include="TestSources\NoFieldsAndNoFieldsDerived.cs" />
6218
<EmbeddedResource Include="TestSources\NoFieldsAndOneScalarFieldDerived.cs" />
@@ -65,12 +21,6 @@
6521
<EmbeddedResource Include="TestSources\ClassDerivesFromAnotherWithFields.cs" />
6622
<EmbeddedResource Include="TestSources\OneScalarFieldWithBuilder.cs" />
6723
<EmbeddedResource Include="TestSources\OneScalarField.cs" />
68-
<Compile Update="TestSources\Person.cs">
69-
<Generator>MSBuild:GenerateCodeFromAttributes</Generator>
70-
</Compile>
71-
<Compile Update="TestSources\Empty.cs">
72-
<Generator>MSBuild:GenerateCodeFromAttributes</Generator>
73-
</Compile>
7424
<Compile Remove="@(EmbeddedResource)" />
7525
<Compile Remove="TestSources\AlmostRecursive.cs" />
7626
<Compile Remove="TestSources\HierarchyLevels.cs" />
@@ -84,15 +34,10 @@
8434
<PackageReference Include="xunit.runner.visualstudio" />
8535
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" PrivateAssets="all" />
8636
<PackageReference Include="Microsoft.NET.Test.Sdk" />
87-
<PackageReference Include="CodeGeneration.Roslyn" PrivateAssets="all" />
88-
<PackageReference Include="CodeGeneration.Roslyn.Engine" PrivateAssets="all" />
89-
</ItemGroup>
90-
<ItemGroup>
91-
<DotNetCliToolReference Include="dotnet-codegen" />
9237
</ItemGroup>
9338
<ItemGroup>
9439
<ProjectReference Include="..\ImmutableObjectGraph.Generation.Attributes\ImmutableObjectGraph.Generation.Attributes.csproj" />
95-
<ProjectReference Include="..\ImmutableObjectGraph.Generation\ImmutableObjectGraph.Generation.csproj" />
40+
<ProjectReference Include="..\ImmutableObjectGraph.Generation\ImmutableObjectGraph.Generation.csproj" OutputItemType="Analyzer" />
9641
<ProjectReference Include="..\ImmutableObjectGraph\ImmutableObjectGraph.csproj" />
9742
</ItemGroup>
98-
</Project>
43+
</Project>

0 commit comments

Comments
 (0)