Skip to content

Commit 972e742

Browse files
committed
feat: must be partial
1 parent a8d03c3 commit 972e742

18 files changed

+312
-63
lines changed

Directory.Packages.props

+2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
1111
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="4.5.0" />
1212
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Analyzer.Testing.XUnit" Version="1.1.1" />
13+
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.CodeFix.Testing.XUnit" Version="1.1.1" />
1314
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.5.0" />
1415
<PackageVersion Include="Microsoft.CodeAnalysis.Workspaces.Common" Version="4.5.0" />
16+
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.5.0"/>
1517
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
1618
<PackageVersion Include="PolySharp" Version="1.13.1" />
1719
<PackageVersion Include="Sigil" Version="5.0.0" />

NuGet.config

-7
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using SourceKit.Analyzers.MustBePartial.Annotations;
22

3-
namespace SourceKit.Sample.MustBePartial;
3+
namespace SourceKit.Sample.Analyzers.MustBePartial;
44

55
[DerivativesMustBePartial]
66
public interface IPartialBase { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace SourceKit.Sample.Analyzers.MustBePartial;
2+
3+
public class NonPartialDerivative : IPartialBase
4+
{
5+
6+
}

SourceKit.Sample/MustBePartial/PartialDerivative.cs renamed to SourceKit.Sample/Analyzers/MustBePartial/PartialDerivative.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace SourceKit.Sample.MustBePartial;
1+
namespace SourceKit.Sample.Analyzers.MustBePartial;
22

33
public partial class PartialDerivative : IPartialBase
44
{

SourceKit.Sample/Class1.cs

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4-
using System.Runtime.CompilerServices;
54
using SourceKit.Sample.Models;
65

76
namespace SourceKit.Sample;

SourceKit.Sample/MustBePartial/NotPartialDerivative.cs

-6
This file was deleted.

SourceKit.Sample/Playground.cs

+1-4
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,7 @@ public class Playground
88
private static IEnumerable<int> A(IEnumerable<int> e)
99
=> e.Where(x => new[] { x }.Where(y => y > 1).Any());
1010

11-
public static void A()
11+
public static void Main()
1212
{
13-
var x = new int[,]
14-
{
15-
};
1613
}
1714
}

SourceKit.Sample/SourceKit.Sample.csproj

+12-3
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,18 @@
55
<LangVersion>11</LangVersion>
66
<Nullable>enable</Nullable>
77
</PropertyGroup>
8-
8+
9+
<ItemGroup>
10+
<ProjectReference Include="..\src\analyzers\SourceKit.Analyzers.MustBePartial\SourceKit.Analyzers.MustBePartial.csproj"
11+
OutputItemType="Analyzer"/>
12+
13+
<ProjectReference Include="..\src\SourceKit\SourceKit.csproj"
14+
OutputItemType="Analyzer"/>
15+
</ItemGroup>
16+
917
<ItemGroup>
10-
<PackageReference Include="SourceKit.Analyzers.MustBePartial" />
18+
<Folder Include="Analyzers\"/>
1119
</ItemGroup>
1220

13-
</Project>
21+
22+
</Project>
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,93 @@
11
using Microsoft.CodeAnalysis.CSharp.Testing;
22
using Microsoft.CodeAnalysis.Testing.Verifiers;
33
using SourceKit.Analyzers.MustBePartial.Analyzers;
4+
using SourceKit.Analyzers.MustBePartial.Annotations;
5+
using SourceKit.Sample.Analyzers.MustBePartial;
6+
using SourceKit.Tests.Tools;
47
using Xunit;
5-
using Verify = Microsoft.CodeAnalysis.CSharp.Testing.XUnit.AnalyzerVerifier<
8+
using AnalyzerVerifier = Microsoft.CodeAnalysis.CSharp.Testing.XUnit.AnalyzerVerifier<
69
SourceKit.Analyzers.MustBePartial.Analyzers.DerivativesMustBePartialAnalyzer>;
10+
using CodeFixTest = Microsoft.CodeAnalysis.CSharp.Testing.CSharpCodeFixTest<
11+
SourceKit.Analyzers.MustBePartial.Analyzers.DerivativesMustBePartialAnalyzer,
12+
SourceKit.Analyzers.MustBePartial.CodeFixes.MakeTypePartialCodeFixProvider,
13+
Microsoft.CodeAnalysis.Testing.Verifiers.XUnitVerifier>;
714

815
namespace SourceKit.Tests.Analyzers;
916

1017
public class MustBePartialTests
1118
{
1219
[Fact]
13-
public async Task A()
20+
public async Task DerivativesMustBePartial_ShouldReportDiagnostic_WhenTypeIsNotPartial()
1421
{
15-
var subject = File.ReadAllText("MustBePartial/NotPartialDerivative.cs");
22+
var sourceFile = await SourceFile.LoadAsync("SourceKit.Sample/Analyzers/MustBePartial/NonPartialDerivative.cs");
23+
24+
var diagnostic = AnalyzerVerifier.Diagnostic(DerivativesMustBePartialAnalyzer.Descriptor)
25+
.WithLocation(sourceFile.Name, 3, 14)
26+
.WithArguments(nameof(NonPartialDerivative));
1627

1728
var test = new CSharpAnalyzerTest<DerivativesMustBePartialAnalyzer, XUnitVerifier>
1829
{
1930
TestState =
2031
{
21-
Sources = { subject },
22-
AdditionalFiles = { await LoadFileAsync("MustBePartial/IPartialBase.cs") },
23-
ExpectedDiagnostics = { Verify.Diagnostic(DerivativesMustBePartialAnalyzer.Descriptor) },
32+
Sources =
33+
{
34+
sourceFile,
35+
await SourceFile.LoadAsync("SourceKit.Sample/Analyzers/MustBePartial/IPartialBase.cs"),
36+
},
37+
AdditionalReferences = { typeof(DerivativesMustBePartialAttribute).Assembly },
2438
},
39+
ExpectedDiagnostics = { diagnostic },
2540
};
2641

2742
await test.RunAsync();
2843
}
2944

30-
private static Task<(string name, string content)> LoadFileAsync(string path)
45+
[Fact]
46+
public async Task DerivativesMustBePartial_ShouldReportNoDiagnostic_WhenTypeIsPartial()
3147
{
32-
var name = Path.ChangeExtension(Path.GetFileName(path), null);
33-
var content = File.ReadAllText(path);
48+
var test = new CSharpAnalyzerTest<DerivativesMustBePartialAnalyzer, XUnitVerifier>
49+
{
50+
TestState =
51+
{
52+
Sources =
53+
{
54+
await SourceFile.LoadAsync("SourceKit.Sample/Analyzers/MustBePartial/PartialDerivative.cs"),
55+
await SourceFile.LoadAsync("SourceKit.Sample/Analyzers/MustBePartial/IPartialBase.cs"),
56+
},
57+
AdditionalReferences = { typeof(DerivativesMustBePartialAttribute).Assembly },
58+
},
59+
};
60+
61+
await test.RunAsync();
62+
}
3463

35-
return Task.FromResult((name, content));
64+
[Fact]
65+
public async Task MakeTypePartial_ShouldMakeTypePartial_WhenDiagnosticReported()
66+
{
67+
var interfaceSource = await SourceFile.LoadAsync("SourceKit.Sample/Analyzers/MustBePartial/IPartialBase.cs");
68+
var sourceFile = await SourceFile.LoadAsync("SourceKit.Sample/Analyzers/MustBePartial/NonPartialDerivative.cs");
69+
var fixedContent = sourceFile.Content.Replace("public class", "public partial class");
70+
71+
var fixedSource = sourceFile with { Content = fixedContent };
72+
73+
var diagnostic = AnalyzerVerifier.Diagnostic(DerivativesMustBePartialAnalyzer.Descriptor)
74+
.WithLocation(sourceFile.Name, 3, 14)
75+
.WithArguments(nameof(NonPartialDerivative));
76+
77+
var test = new CodeFixTest
78+
{
79+
TestState =
80+
{
81+
Sources = { sourceFile, interfaceSource, },
82+
AdditionalReferences = { typeof(DerivativesMustBePartialAttribute).Assembly },
83+
},
84+
FixedState =
85+
{
86+
Sources = { fixedSource, interfaceSource },
87+
},
88+
ExpectedDiagnostics = { diagnostic },
89+
};
90+
91+
await test.RunAsync();
3692
}
3793
}
+3-12
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,23 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>netstandard2.0</TargetFramework>
4+
<TargetFramework>net7.0</TargetFramework>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
7-
<LangVersion>11</LangVersion>
8-
97
<IsPackable>false</IsPackable>
108
</PropertyGroup>
119

1210
<ItemGroup>
1311
<PackageReference Include="Ben.Demystifier" />
1412
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Analyzer.Testing.XUnit" />
13+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeFix.Testing.XUnit" />
1514
<PackageReference Include="Sigil" />
1615
<PackageReference Include="FluentAssertions" />
1716
<PackageReference Include="Microsoft.CodeAnalysis.Common" />
1817
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" />
1918
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" VersionOverride="4.5.0" />
2019
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.Common" />
2120
<PackageReference Include="Microsoft.NET.Test.Sdk" />
22-
<PackageReference Include="SourceKit.Analyzers.MustBePartial" />
2321
<PackageReference Include="xunit" />
2422
<PackageReference Include="Xunit.DependencyInjection.Demystifier" />
2523

@@ -37,19 +35,12 @@
3735

3836
<ItemGroup>
3937
<ProjectReference Include="..\SourceKit.Sample\SourceKit.Sample.csproj" />
38+
<ProjectReference Include="..\src\analyzers\SourceKit.Analyzers.MustBePartial\SourceKit.Analyzers.MustBePartial.csproj" />
4039
<ProjectReference Include="..\src\SourceKit.Reflect\SourceKit.Reflect.csproj" />
4140
</ItemGroup>
4241

4342
<ItemGroup>
4443
<Content Include="..\SourceKit.Sample\**\*.cs" Exclude="..\SourceKit.Sample\obj\**\*.*" LinkBase="SourceKit.Sample\" CopyToOutputDirectory="Always" />
4544
</ItemGroup>
4645

47-
<!--
48-
<ItemGroup>
49-
<Reference Include="assembly_1">
50-
<HintPath>a.dll</HintPath>
51-
</Reference>
52-
</ItemGroup>
53-
-->
54-
5546
</Project>

SourceKit.Tests/Tools/CompilationBuilder.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public static Task<Compilation> CompileSampleProjectAsync()
3838
typeof(IEnumerable<>),
3939
typeof(Enumerable),
4040
};
41-
41+
4242
var project = solution.GetProject(projectId)!;
4343
project = project.WithCompilationOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
4444
project = project.AddMetadataReferences(GetAllReferencesNeededForTypes(referencedTypes));

SourceKit.Tests/Tools/SourceFile.cs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
namespace SourceKit.Tests.Tools;
2+
3+
public record struct SourceFile(string Name, string Content)
4+
{
5+
public static async Task<SourceFile> LoadAsync(string path)
6+
{
7+
var name = Path.GetFileName(path);
8+
var content = await File.ReadAllTextAsync(path);
9+
10+
return new SourceFile(name, content);
11+
}
12+
13+
public static implicit operator (string, string)(SourceFile sourceFile)
14+
=> (sourceFile.Name, sourceFile.Content);
15+
}

0 commit comments

Comments
 (0)