Skip to content

Commit 064dae9

Browse files
committed
Roslyn Analyzer
1 parent 383f14c commit 064dae9

18 files changed

+683
-0
lines changed

CsharpLangExamples.sln

+23
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceGenerator.Tests", "So
8585
EndProject
8686
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Roslyn Source Generators", "Roslyn Source Generators", "{D661A5C6-F295-4969-8270-05BDEDD7BA79}"
8787
EndProject
88+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RoslynAnalyzer", "RoslynAnalyzer\RoslynAnalyzer\RoslynAnalyzer.csproj", "{17D24A64-EC73-4752-A750-14C0B9175AF6}"
89+
EndProject
90+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RoslynAnalyzer.Sample", "RoslynAnalyzer\RoslynAnalyzer.Sample\RoslynAnalyzer.Sample.csproj", "{8AA2549C-6595-43CB-B652-5532DBDFC734}"
91+
EndProject
92+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RoslynAnalyzer.Tests", "RoslynAnalyzer\RoslynAnalyzer.Tests\RoslynAnalyzer.Tests.csproj", "{9C9BBC19-CDBA-4851-B3D8-8C383F4742FE}"
93+
EndProject
94+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Roslyn Analyzer", "Roslyn Analyzer", "{A20B336B-C5A8-46EC-A4D3-843C257A4809}"
95+
EndProject
8896
Global
8997
GlobalSection(SolutionConfigurationPlatforms) = preSolution
9098
Debug|Any CPU = Debug|Any CPU
@@ -251,6 +259,18 @@ Global
251259
{A0ACAA9E-6608-4354-A755-A8186EDF67C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
252260
{A0ACAA9E-6608-4354-A755-A8186EDF67C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
253261
{A0ACAA9E-6608-4354-A755-A8186EDF67C5}.Release|Any CPU.Build.0 = Release|Any CPU
262+
{17D24A64-EC73-4752-A750-14C0B9175AF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
263+
{17D24A64-EC73-4752-A750-14C0B9175AF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
264+
{17D24A64-EC73-4752-A750-14C0B9175AF6}.Release|Any CPU.ActiveCfg = Release|Any CPU
265+
{17D24A64-EC73-4752-A750-14C0B9175AF6}.Release|Any CPU.Build.0 = Release|Any CPU
266+
{8AA2549C-6595-43CB-B652-5532DBDFC734}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
267+
{8AA2549C-6595-43CB-B652-5532DBDFC734}.Debug|Any CPU.Build.0 = Debug|Any CPU
268+
{8AA2549C-6595-43CB-B652-5532DBDFC734}.Release|Any CPU.ActiveCfg = Release|Any CPU
269+
{8AA2549C-6595-43CB-B652-5532DBDFC734}.Release|Any CPU.Build.0 = Release|Any CPU
270+
{9C9BBC19-CDBA-4851-B3D8-8C383F4742FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
271+
{9C9BBC19-CDBA-4851-B3D8-8C383F4742FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
272+
{9C9BBC19-CDBA-4851-B3D8-8C383F4742FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
273+
{9C9BBC19-CDBA-4851-B3D8-8C383F4742FE}.Release|Any CPU.Build.0 = Release|Any CPU
254274
EndGlobalSection
255275
GlobalSection(SolutionProperties) = preSolution
256276
HideSolutionNode = FALSE
@@ -262,5 +282,8 @@ Global
262282
{A85C3610-0CC1-42BD-A8B0-F0EEC31C05F2} = {D661A5C6-F295-4969-8270-05BDEDD7BA79}
263283
{1EB9EE63-D56D-4315-832A-89DDE9E2094B} = {D661A5C6-F295-4969-8270-05BDEDD7BA79}
264284
{A0ACAA9E-6608-4354-A755-A8186EDF67C5} = {D661A5C6-F295-4969-8270-05BDEDD7BA79}
285+
{17D24A64-EC73-4752-A750-14C0B9175AF6} = {A20B336B-C5A8-46EC-A4D3-843C257A4809}
286+
{8AA2549C-6595-43CB-B652-5532DBDFC734} = {A20B336B-C5A8-46EC-A4D3-843C257A4809}
287+
{9C9BBC19-CDBA-4851-B3D8-8C383F4742FE} = {A20B336B-C5A8-46EC-A4D3-843C257A4809}
265288
EndGlobalSection
266289
EndGlobal
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// ReSharper disable UnusedType.Global
2+
// ReSharper disable UnusedMember.Global
3+
4+
namespace RoslynAnalyzer.Sample;
5+
6+
// If you don't see warnings, build the Analyzers Project.
7+
8+
public class Examples
9+
{
10+
public class MyCompanyClass // Try to apply quick fix using the IDE.
11+
{
12+
}
13+
14+
public void ToStars()
15+
{
16+
var spaceship = new Spaceship();
17+
spaceship.SetSpeed(300000000); // Invalid value, it should be highlighted.
18+
spaceship.SetSpeed(42);
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<ProjectReference Include="..\RoslynAnalyzer\RoslynAnalyzer.csproj"
10+
OutputItemType="Analyzer" ReferenceOutputAssembly="false"/>
11+
</ItemGroup>
12+
13+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System;
2+
3+
namespace RoslynAnalyzer.Sample;
4+
5+
public class Spaceship
6+
{
7+
public void SetSpeed(long speed)
8+
{
9+
if (speed > 299_792_458)
10+
throw new ArgumentOutOfRangeException(nameof(speed));
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
7+
<IsPackable>false</IsPackable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Analyzer.Testing.XUnit" Version="1.1.1"/>
12+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeFix.Testing.XUnit" Version="1.1.1"/>
13+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2"/>
14+
<PackageReference Include="xunit" Version="2.4.2"/>
15+
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
16+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
17+
<PrivateAssets>all</PrivateAssets>
18+
</PackageReference>
19+
</ItemGroup>
20+
21+
<ItemGroup>
22+
<ProjectReference Include="..\RoslynAnalyzer\RoslynAnalyzer.csproj"/>
23+
</ItemGroup>
24+
25+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System.Threading.Tasks;
2+
using Xunit;
3+
using Verifier =
4+
Microsoft.CodeAnalysis.CSharp.Testing.XUnit.CodeFixVerifier<RoslynAnalyzer.SampleSyntaxAnalyzer,
5+
RoslynAnalyzer.SampleCodeFixProvider>;
6+
7+
namespace RoslynAnalyzer.Tests;
8+
9+
public class SampleCodeFixProviderTests
10+
{
11+
[Fact]
12+
public async Task ClassWithMyCompanyTitle_ReplaceWithCommonKeyword()
13+
{
14+
const string text = @"
15+
public class MyCompanyClass
16+
{
17+
}
18+
";
19+
20+
const string newText = @"
21+
public class CommonClass
22+
{
23+
}
24+
";
25+
26+
var expected = Verifier.Diagnostic()
27+
.WithLocation(2, 14)
28+
.WithArguments("MyCompanyClass");
29+
await Verifier.VerifyCodeFixAsync(text, expected, newText).ConfigureAwait(false);
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System.Threading.Tasks;
2+
using Xunit;
3+
using Verifier =
4+
Microsoft.CodeAnalysis.CSharp.Testing.XUnit.AnalyzerVerifier<
5+
RoslynAnalyzer.SampleSemanticAnalyzer>;
6+
7+
namespace RoslynAnalyzer.Tests;
8+
9+
public class SampleSemanticAnalyzerTests
10+
{
11+
[Fact]
12+
public async Task SetSpeedHugeSpeedSpecified_AlertDiagnostic()
13+
{
14+
const string text = @"
15+
public class Program
16+
{
17+
public void Main()
18+
{
19+
var spaceship = new Spaceship();
20+
spaceship.SetSpeed(300000000);
21+
}
22+
}
23+
24+
public class Spaceship
25+
{
26+
public void SetSpeed(long speed) {}
27+
}
28+
";
29+
30+
var expected = Verifier.Diagnostic()
31+
.WithLocation(7, 28)
32+
.WithArguments("300000000");
33+
await Verifier.VerifyAnalyzerAsync(text, expected);
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.Threading.Tasks;
2+
using Xunit;
3+
using Verifier =
4+
Microsoft.CodeAnalysis.CSharp.Testing.XUnit.AnalyzerVerifier<
5+
RoslynAnalyzer.SampleSyntaxAnalyzer>;
6+
7+
namespace RoslynAnalyzer.Tests;
8+
9+
public class SampleSyntaxAnalyzerTests
10+
{
11+
[Fact]
12+
public async Task ClassWithMyCompanyTitle_AlertDiagnostic()
13+
{
14+
const string text = @"
15+
public class MyCompanyClass
16+
{
17+
}
18+
";
19+
20+
var expected = Verifier.Diagnostic()
21+
.WithLocation(2, 14)
22+
.WithArguments("MyCompanyClass");
23+
await Verifier.VerifyAnalyzerAsync(text, expected).ConfigureAwait(false);
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
## Release 1.0
2+
3+
### New Rules
4+
5+
| Rule ID | Category | Severity | Notes |
6+
|---------|----------|----------|--------------------------------------------------|
7+
| AB0001 | Naming | Warning | Type names should not contain the company name. |
8+
| AB0002 | Usage | Warning | The speed must be lower than the Speed of Light. |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
### New Rules
2+
3+
| Rule ID | Category | Severity | Notes |
4+
|---------|----------|----------|-------|
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"$schema": "https://json.schemastore.org/launchsettings.json",
3+
"profiles": {
4+
"DebugRoslynAnalyzers": {
5+
"commandName": "DebugRoslynComponent",
6+
"targetProject": "../RoslynAnalyzer.Sample/RoslynAnalyzer.Sample.csproj"
7+
}
8+
}
9+
}
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Roslyn Analyzers Sample
2+
3+
A set of three sample projects that includes Roslyn analyzers with code fix providers. Enjoy this template to learn from and modify analyzers for your own needs.
4+
5+
## Content
6+
### RoslynAnalyzer
7+
A .NET Standard project with implementations of sample analyzers and code fix providers.
8+
**You must build this project to see the results (warnings) in the IDE.**
9+
10+
- [SampleSemanticAnalyzer.cs](SampleSemanticAnalyzer.cs): An analyzer that reports invalid values used for the `speed` parameter of the `SetSpeed` function.
11+
- [SampleSyntaxAnalyzer.cs](SampleSyntaxAnalyzer.cs): An analyzer that reports the company name used in class definitions.
12+
- [SampleCodeFixProvider.cs](SampleCodeFixProvider.cs): A code fix that renames classes with company name in their definition. The fix is linked to [SampleSyntaxAnalyzer.cs](SampleSyntaxAnalyzer.cs).
13+
14+
### RoslynAnalyzer.Sample
15+
A project that references the sample analyzers. Note the parameters of `ProjectReference` in [RoslynAnalyzer.Sample.csproj](../RoslynAnalyzer.Sample/RoslynAnalyzer.Sample.csproj), they make sure that the project is referenced as a set of analyzers.
16+
17+
### RoslynAnalyzer.Tests
18+
Unit tests for the sample analyzers and code fix provider. The easiest way to develop language-related features is to start with unit tests.
19+
20+
## How To?
21+
### How to debug?
22+
- Use the [launchSettings.json](Properties/launchSettings.json) profile.
23+
- Debug tests.
24+
25+
### How can I determine which syntax nodes I should expect?
26+
Consider installing the Roslyn syntax tree viewer plugin [Rossynt](https://plugins.jetbrains.com/plugin/16902-rossynt/).
27+
28+
### Learn more about wiring analyzers
29+
The complete set of information is available at [roslyn github repo wiki](https://github.com/dotnet/roslyn/blob/main/docs/wiki/README.md).

RoslynAnalyzer/RoslynAnalyzer/Resources.Designer.cs

+88
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)