Skip to content

Commit

Permalink
Created analyzer projects.
Browse files Browse the repository at this point in the history
  • Loading branch information
tacosontitan committed Feb 3, 2024
1 parent 9d707cb commit 28c6270
Show file tree
Hide file tree
Showing 18 changed files with 686 additions and 0 deletions.
21 changes: 21 additions & 0 deletions Hussy.Net.sln
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hussy.Net.Tests", "test\Hus
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{A9FCA40E-6E3D-408C-B5A0-429AA5F5BF6F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hussy.Net.Analyzers", "src\Hussy.Net.Analyzers\Hussy.Net.Analyzers\Hussy.Net.Analyzers.csproj", "{D49D68BE-9D42-4B2B-9736-B4CAE29492F0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hussy.Net.Analyzers.Sample", "src\Hussy.Net.Analyzers\Hussy.Net.Analyzers.Sample\Hussy.Net.Analyzers.Sample.csproj", "{5FFFABC4-F2A8-42DB-AF7D-32FB18EA5E51}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hussy.Net.Analyzers.Tests", "src\Hussy.Net.Analyzers\Hussy.Net.Analyzers.Tests\Hussy.Net.Analyzers.Tests.csproj", "{C9B503C5-B89A-49F2-83DD-81C601CDE806}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -54,6 +60,18 @@ Global
{B5087B86-C43C-43F3-B0A2-D23B0480F203}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B5087B86-C43C-43F3-B0A2-D23B0480F203}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B5087B86-C43C-43F3-B0A2-D23B0480F203}.Release|Any CPU.Build.0 = Release|Any CPU
{D49D68BE-9D42-4B2B-9736-B4CAE29492F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D49D68BE-9D42-4B2B-9736-B4CAE29492F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D49D68BE-9D42-4B2B-9736-B4CAE29492F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D49D68BE-9D42-4B2B-9736-B4CAE29492F0}.Release|Any CPU.Build.0 = Release|Any CPU
{5FFFABC4-F2A8-42DB-AF7D-32FB18EA5E51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5FFFABC4-F2A8-42DB-AF7D-32FB18EA5E51}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5FFFABC4-F2A8-42DB-AF7D-32FB18EA5E51}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5FFFABC4-F2A8-42DB-AF7D-32FB18EA5E51}.Release|Any CPU.Build.0 = Release|Any CPU
{C9B503C5-B89A-49F2-83DD-81C601CDE806}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C9B503C5-B89A-49F2-83DD-81C601CDE806}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C9B503C5-B89A-49F2-83DD-81C601CDE806}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C9B503C5-B89A-49F2-83DD-81C601CDE806}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{14788585-4CAA-415C-8B29-B4E2BBDC9C66} = {B43C73D9-7CA0-4D59-8ABE-AFD9A3F54361}
Expand All @@ -63,5 +81,8 @@ Global
{B62492A5-ABE3-46EF-BE5F-D85A871857BD} = {C08B73E3-E9BB-44DE-AE74-647A442780D9}
{8F248FF3-378D-4F9C-8A25-3ED95961A4AB} = {C08B73E3-E9BB-44DE-AE74-647A442780D9}
{B5087B86-C43C-43F3-B0A2-D23B0480F203} = {A9FCA40E-6E3D-408C-B5A0-429AA5F5BF6F}
{D49D68BE-9D42-4B2B-9736-B4CAE29492F0} = {B43C73D9-7CA0-4D59-8ABE-AFD9A3F54361}
{5FFFABC4-F2A8-42DB-AF7D-32FB18EA5E51} = {B43C73D9-7CA0-4D59-8ABE-AFD9A3F54361}
{C9B503C5-B89A-49F2-83DD-81C601CDE806} = {B43C73D9-7CA0-4D59-8ABE-AFD9A3F54361}
EndGlobalSection
EndGlobal
20 changes: 20 additions & 0 deletions src/Hussy.Net.Analyzers/Hussy.Net.Analyzers.Sample/Examples.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global

namespace Hussy.Net.Analyzers.Sample;

// If you don't see warnings, build the Analyzers Project.

public class Examples
{
public class MyCompanyClass // Try to apply quick fix using the IDE.

Check warning on line 10 in src/Hussy.Net.Analyzers/Hussy.Net.Analyzers.Sample/Examples.cs

View workflow job for this annotation

GitHub Actions / build

Type name 'MyCompanyClass' contains the company name

Check warning on line 10 in src/Hussy.Net.Analyzers/Hussy.Net.Analyzers.Sample/Examples.cs

View workflow job for this annotation

GitHub Actions / build

Type name 'MyCompanyClass' contains the company name
{
}

public void ToStars()
{
var spaceship = new Spaceship();
spaceship.SetSpeed(300000000); // Invalid value, it should be highlighted.

Check warning on line 17 in src/Hussy.Net.Analyzers/Hussy.Net.Analyzers.Sample/Examples.cs

View workflow job for this annotation

GitHub Actions / build

The specified speed '300000000' must be lower than the Speed of Light

Check warning on line 17 in src/Hussy.Net.Analyzers/Hussy.Net.Analyzers.Sample/Examples.cs

View workflow job for this annotation

GitHub Actions / build

The specified speed '300000000' must be lower than the Speed of Light
spaceship.SetSpeed(42);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\Hussy.Net\Hussy.Net.csproj" />
<ProjectReference Include="..\Hussy.Net.Analyzers\Hussy.Net.Analyzers.csproj"
OutputItemType="Analyzer" ReferenceOutputAssembly="false"/>
</ItemGroup>

</Project>
12 changes: 12 additions & 0 deletions src/Hussy.Net.Analyzers/Hussy.Net.Analyzers.Sample/Spaceship.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;

namespace Hussy.Net.Analyzers.Sample;

public class Spaceship
{
public void SetSpeed(long speed)
{
if (speed > 299_792_458)
throw new ArgumentOutOfRangeException(nameof(speed));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Analyzer.Testing.XUnit" Version="1.1.1"/>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeFix.Testing.XUnit" Version="1.1.1"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2"/>
<PackageReference Include="xunit" Version="2.4.2"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Hussy.Net.Analyzers\Hussy.Net.Analyzers.csproj"/>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Threading.Tasks;
using Xunit;
using Verifier =
Microsoft.CodeAnalysis.CSharp.Testing.XUnit.CodeFixVerifier<Hussy.Net.Analyzers.SampleSyntaxAnalyzer,
Hussy.Net.Analyzers.SampleCodeFixProvider>;

namespace Hussy.Net.Analyzers.Tests;

public class SampleCodeFixProviderTests
{
[Fact]
public async Task ClassWithMyCompanyTitle_ReplaceWithCommonKeyword()
{
const string text = @"
public class MyCompanyClass
{
}
";

const string newText = @"
public class CommonClass
{
}
";

var expected = Verifier.Diagnostic()
.WithLocation(2, 14)
.WithArguments("MyCompanyClass");
await Verifier.VerifyCodeFixAsync(text, expected, newText).ConfigureAwait(false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Threading.Tasks;
using Xunit;
using Verifier =
Microsoft.CodeAnalysis.CSharp.Testing.XUnit.AnalyzerVerifier<
Hussy.Net.Analyzers.SampleSemanticAnalyzer>;

namespace Hussy.Net.Analyzers.Tests;

public class SampleSemanticAnalyzerTests
{
[Fact]
public async Task SetSpeedHugeSpeedSpecified_AlertDiagnostic()
{
const string text = @"
public class Program
{
public void Main()
{
var spaceship = new Spaceship();
spaceship.SetSpeed(300000000);
}
}
public class Spaceship
{
public void SetSpeed(long speed) {}
}
";

var expected = Verifier.Diagnostic()
.WithLocation(7, 28)
.WithArguments("300000000");
await Verifier.VerifyAnalyzerAsync(text, expected);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.Threading.Tasks;
using Xunit;
using Verifier =
Microsoft.CodeAnalysis.CSharp.Testing.XUnit.AnalyzerVerifier<
Hussy.Net.Analyzers.SampleSyntaxAnalyzer>;

namespace Hussy.Net.Analyzers.Tests;

public class SampleSyntaxAnalyzerTests
{
[Fact]
public async Task ClassWithMyCompanyTitle_AlertDiagnostic()
{
const string text = @"
public class MyCompanyClass
{
}
";

var expected = Verifier.Diagnostic()
.WithLocation(2, 14)
.WithArguments("MyCompanyClass");
await Verifier.VerifyAnalyzerAsync(text, expected).ConfigureAwait(false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## Release 1.0

### New Rules

Rule ID | Category | Severity | Notes
--------|----------|----------|------------------------------------------------
AB0001 | Naming | Warning | Type names should not contain the company name.
AB0002 | Usage | Warning | The speed must be lower than the Speed of Light.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
### New Rules

Rule ID | Category | Severity | Notes
--------|----------|----------|-------
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<IsPackable>false</IsPackable>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>

<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
<IsRoslynComponent>true</IsRoslynComponent>

<RootNamespace>Hussy.Net.Analyzers</RootNamespace>
<AssemblyName>Hussy.Net.Analyzers</AssemblyName>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.3.0"/>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.3.0"/>
</ItemGroup>

<ItemGroup>
<EmbeddedResource Update="Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>

<ItemGroup>
<Compile Update="Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\Hussy.Net\Hussy.Net.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"DebugRoslynAnalyzers": {
"commandName": "DebugRoslynComponent",
"targetProject": "../Hussy.Net.Analyzers.Sample/Hussy.Net.Analyzers.Sample.csproj"
}
}
}
29 changes: 29 additions & 0 deletions src/Hussy.Net.Analyzers/Hussy.Net.Analyzers/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Roslyn Analyzers Sample

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.

## Content
### Hussy.Net.Analyzers
A .NET Standard project with implementations of sample analyzers and code fix providers.
**You must build this project to see the results (warnings) in the IDE.**

- [SampleSemanticAnalyzer.cs](SampleSemanticAnalyzer.cs): An analyzer that reports invalid values used for the `speed` parameter of the `SetSpeed` function.
- [SampleSyntaxAnalyzer.cs](SampleSyntaxAnalyzer.cs): An analyzer that reports the company name used in class definitions.
- [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).

### Hussy.Net.Analyzers.Sample
A project that references the sample analyzers. Note the parameters of `ProjectReference` in [Hussy.Net.Analyzers.Sample.csproj](../Hussy.Net.Analyzers.Sample/Hussy.Net.Analyzers.Sample.csproj), they make sure that the project is referenced as a set of analyzers.

### Hussy.Net.Analyzers.Tests
Unit tests for the sample analyzers and code fix provider. The easiest way to develop language-related features is to start with unit tests.

## How To?
### How to debug?
- Use the [launchSettings.json](Properties/launchSettings.json) profile.
- Debug tests.

### How can I determine which syntax nodes I should expect?
Consider installing the Roslyn syntax tree viewer plugin [Rossynt](https://plugins.jetbrains.com/plugin/16902-rossynt/).

### Learn more about wiring analyzers
The complete set of information is available at [roslyn github repo wiki](https://github.com/dotnet/roslyn/blob/main/docs/wiki/README.md).
Loading

0 comments on commit 28c6270

Please sign in to comment.