Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
5b629c1
Initial analyzer commit
Instellate Feb 27, 2024
5d6b949
Added DSP0001
Instellate Feb 27, 2024
b5bfe5b
Added MultipleOverwriteAnalyzer.cs as a analyzer
Instellate Feb 28, 2024
e816d54
fix versions
akiraveliara Feb 28, 2024
e6f453f
Reversed some booleans
Instellate Feb 28, 2024
8874213
Merge remote-tracking branch 'origin/instellate/analyzer' into instel…
Instellate Jul 7, 2024
9fd7cff
Changed to unit testing for anaylzers.
Instellate Jul 7, 2024
dceb08c
Formatting
Instellate Nov 4, 2024
8d23244
Made `SingleEntityGetRequestAnalyzer`
Instellate Nov 4, 2024
674853d
Added an analyzer that prevents users from installing user install on…
Instellate Nov 4, 2024
b9ed95e
Added an analyzer that warns about registering nested classes
Instellate Nov 4, 2024
a10a107
Added a comment
Instellate Nov 4, 2024
474772d
Started the work on DSP1003
Instellate Nov 4, 2024
36dfb0d
Merge branch 'master' into instellate/analyzer
Instellate Nov 4, 2024
04d7810
Finished implementing DSP1003
Instellate Nov 4, 2024
86c2a71
Started on writing documentation for all the rules.
Instellate Nov 5, 2024
6bf27cf
Added a package reference for ``System.Formats.Asn1`` for windows to …
Instellate Nov 5, 2024
1403ed2
Made so overwrite also warns on loop
Instellate Nov 5, 2024
79f1a70
Resolved aki's reviews
Instellate Nov 6, 2024
0b1b5fc
Fixed `HasPermissionAnalyzer` support for `SyntaxKind.EqualsExpression`
Instellate Nov 6, 2024
a079fac
Fixed consistency across files
Instellate Nov 6, 2024
c79dd36
Added a unit test for equal expressions in the `HasPermissionAnalyzer…
Instellate Nov 6, 2024
e4fab2a
Split up documentation rules so commands rules and core rules are dif…
Instellate Nov 7, 2024
c6e9ddd
Fixed various documentation issues
Instellate Nov 8, 2024
098f386
Added so `DSharpPlus.Analyzers` is not included in API references
Instellate Nov 8, 2024
729a304
Fixed so the analyzer .dll is included in the core nupkg
Instellate Nov 10, 2024
0d8c684
said i'd touch upon the docs
akiraveliara Nov 12, 2024
a183344
Merge branch 'master' into instellate/analyzer
Instellate Jan 14, 2025
3b25808
Merge remote-tracking branch 'refs/remotes/origin/master' into instel…
Instellate Feb 20, 2025
e81f054
Added DSP0008 (Use DiscordPermissions instead of DiscordPermission)
Instellate Feb 20, 2025
3e6d710
Merge remote-tracking branch 'origin/master' into instellate/analyzer
Instellate Mar 1, 2025
a73ae6a
Merge branch 'master' into instellate/analyzer
Instellate Mar 1, 2025
35c4cf9
Addressed reviews for `DSP0009`
Instellate Mar 4, 2025
c035918
Removed implementation details for DSP0009 docs
Instellate Mar 4, 2025
ec3b005
Improved docs for DSP0009
Instellate Mar 4, 2025
55e8e97
DocFX fail
Instellate Mar 4, 2025
9ad986c
Merge branch 'master' into instellate/analyzer
Instellate Mar 5, 2025
d8b2323
Seperated DSP0009 to two separate warnings.
Instellate May 17, 2025
6a27d58
Merge remote-tracking branch 'origin/master' into instellate/analyzer
Instellate May 17, 2025
1f794b7
Added Analyzer projects into the solution file (again)
Instellate May 17, 2025
643d3ba
Added logic to package the analyzer into DSharpPlus.nupkg
Instellate May 17, 2025
48479a1
Added full support for DSP0010
Instellate May 18, 2025
5d99787
document DSP0010
akiraveliara May 18, 2025
ecf8cb9
fix the test
akiraveliara May 18, 2025
345c9fb
Added all the numerical operations to trigger for DSP0009
Instellate May 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<IsPackable>false</IsPackable>
<TargetFramework>net9.0</TargetFramework>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
<GenerateDocumentationFile>false</GenerateDocumentationFile>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\DSharpPlus.Commands\DSharpPlus.Commands.csproj" />
<ProjectReference Include="..\DSharpPlus.Analyzers\DSharpPlus.Analyzers.csproj" />
<ProjectReference Include="..\..\DSharpPlus\DSharpPlus.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Basic.Reference.Assemblies.Net80" />
<PackageReference Include="Microsoft.CodeAnalysis" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Analyzer.Testing" />
<PackageReference Include="NUnit" />
<PackageReference Include="NUnit.Analyzers" />
<PackageReference Include="NUnit3TestAdapter" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using System.Threading.Tasks;
using DSharpPlus.Analyzers.Core;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Testing;
using Microsoft.CodeAnalysis.Testing;
using NUnit.Framework;
using Verifier = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerVerifier<
DSharpPlus.Analyzers.Core.HasPermissionAnalyzer,
Microsoft.CodeAnalysis.Testing.DefaultVerifier
>;

namespace DSharpPlus.Analyzers.Test;

public class HasPermissionTest
{
/// <summary>
/// Unit test to see if HasPermissionAnalyzer reports
/// </summary>
[Test]
public static async Task HasPermissionNotEquals_DiagnosticAsync()
{
CSharpAnalyzerTest<HasPermissionAnalyzer, DefaultVerifier> test =
Utility.CreateAnalyzerTest<HasPermissionAnalyzer>();

test.TestCode = """
using DSharpPlus.Entities;

public class DoesIt
{
public static bool HaveAdmin(DiscordPermission perm)
{
if ((perm & DiscordPermission.Administrator) != 0)
{
return true;
}
return false;
}
}
""";

test.ExpectedDiagnostics.Add
(
Verifier.Diagnostic()
.WithLocation(7, 13)
.WithSeverity(DiagnosticSeverity.Warning)
.WithMessage("Use 'perm.HasPermission(DiscordPermission.Administrator)' instead")
);

await test.RunAsync();
}

[Test]
public async Task HasPermissionEquals_DiagnosticAsync()
{
CSharpAnalyzerTest<HasPermissionAnalyzer, DefaultVerifier> test =
Utility.CreateAnalyzerTest<HasPermissionAnalyzer>();

test.TestCode = """
using DSharpPlus.Entities;

public class DoesIt
{
public static bool HaveNoAdmin(DiscordPermission perm)
{
if ((perm & DiscordPermission.Administrator) == 0)
{
return true;
}
return false;
}
}

""";

test.ExpectedDiagnostics.Add
(
Verifier.Diagnostic()
.WithLocation(7, 13)
.WithSeverity(DiagnosticSeverity.Warning)
.WithMessage("Use 'perm.HasPermission(DiscordPermission.Administrator)' instead")
);

await test.RunAsync();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
using System.Threading.Tasks;
using DSharpPlus.Analyzers.Core;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Testing;
using Microsoft.CodeAnalysis.Testing;
using NUnit.Framework;
using Verifier = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerVerifier<
DSharpPlus.Analyzers.Core.MultipleOverwriteAnalyzer,
Microsoft.CodeAnalysis.Testing.DefaultVerifier
>;

namespace DSharpPlus.Analyzers.Test;

/// <summary>
///
/// </summary>
public static class MultipleOverwriteTest
{
/// <summary>
/// Single diagnostic report for multiple overwrite analyzer
/// </summary>
[Test]
public static async Task DiagnosticAsync()
{
CSharpAnalyzerTest<MultipleOverwriteAnalyzer, DefaultVerifier> test =
Utility.CreateAnalyzerTest<MultipleOverwriteAnalyzer>();

test.TestCode = """
using DSharpPlus.Entities;
using System.Threading.Tasks;

public class OverwriteTest
{
public async Task AddOverwritesAsync(DiscordChannel channel, DiscordMember member, DiscordMember member2)
{
await channel.AddOverwriteAsync(member, DiscordPermission.BanMembers);
await channel.AddOverwriteAsync(member2, DiscordPermission.KickMembers);
}
}
""";

test.ExpectedDiagnostics.Add
(
Verifier.Diagnostic()
.WithLocation(9, 15)
.WithSeverity(DiagnosticSeverity.Warning)
.WithMessage("Use one 'channel.ModifyAsync(..)' instead of multiple 'channel.AddOverwriteAsync(..)'")
);
await test.RunAsync();
}

[Test]
public static async Task MultipleErrorsScenarioTestAsync()
{
CSharpAnalyzerTest<MultipleOverwriteAnalyzer, DefaultVerifier> test =
Utility.CreateAnalyzerTest<MultipleOverwriteAnalyzer>();

test.TestCode = """
using DSharpPlus.Entities;
using System.Threading.Tasks;

public class OverwriteTest
{
public async Task AddOverwritesAsync(DiscordChannel channel, DiscordMember member, DiscordMember member2)
{
await channel.AddOverwriteAsync(member, DiscordPermission.BanMembers);
await channel.AddOverwriteAsync(member2, DiscordPermission.KickMembers);
await channel.AddOverwriteAsync(member2, DiscordPermission.Administrator);
}
}
""";

test.ExpectedDiagnostics.Add
(
Verifier.Diagnostic()
.WithLocation(9, 15)
.WithSeverity(DiagnosticSeverity.Warning)
.WithMessage("Use one 'channel.ModifyAsync(..)' instead of multiple 'channel.AddOverwriteAsync(..)'")
);

test.ExpectedDiagnostics.Add
(
Verifier.Diagnostic()
.WithLocation(10, 15)
.WithSeverity(DiagnosticSeverity.Warning)
.WithMessage("Use one 'channel.ModifyAsync(..)' instead of multiple 'channel.AddOverwriteAsync(..)'")
);

await test.RunAsync();
}

[Test]
public static async Task ForEachLoopDiagnosticAsync()
{
CSharpAnalyzerTest<MultipleOverwriteAnalyzer, DefaultVerifier> test
= Utility.CreateAnalyzerTest<MultipleOverwriteAnalyzer>();

test.TestCode = """
using DSharpPlus.Entities;
using System.Threading.Tasks;
using System.Collections.Generic;

public class OverwriteTest
{
public async Task AddOverwritesAsync(DiscordChannel channel, List<DiscordMember> members)
{
foreach (DiscordMember member in members)
{
await channel.AddOverwriteAsync(member, DiscordPermission.BanMembers);
}
}
}
""";

test.ExpectedDiagnostics.Add
(
Verifier.Diagnostic()
.WithLocation(11, 19)
.WithSeverity(DiagnosticSeverity.Warning)
.WithMessage("Use one 'channel.ModifyAsync(..)' instead of multiple 'channel.AddOverwriteAsync(..)'")
);

await test.RunAsync();
}

[Test]
public static async Task ForLoopDiagnosticAsync()
{
CSharpAnalyzerTest<MultipleOverwriteAnalyzer, DefaultVerifier> test
= Utility.CreateAnalyzerTest<MultipleOverwriteAnalyzer>();

test.TestCode = """
using DSharpPlus.Entities;
using System.Threading.Tasks;
using System.Collections.Generic;

public class OverwriteTest
{
public async Task AddOverwritesAsync(DiscordChannel channel, List<DiscordMember> members)
{
for (int i = 0; i < members.Count; i++)
{
await channel.AddOverwriteAsync(members[i], DiscordPermission.BanMembers);
}
}
}
""";

test.ExpectedDiagnostics.Add
(
Verifier.Diagnostic()
.WithLocation(11, 19)
.WithSeverity(DiagnosticSeverity.Warning)
.WithMessage("Use one 'channel.ModifyAsync(..)' instead of multiple 'channel.AddOverwriteAsync(..)'")
);

await test.RunAsync();
}

[Test]
public static async Task WhileLoopDiagnosticAsync()
{
CSharpAnalyzerTest<MultipleOverwriteAnalyzer, DefaultVerifier> test
= Utility.CreateAnalyzerTest<MultipleOverwriteAnalyzer>();

test.TestCode = """
using DSharpPlus.Entities;
using System.Threading.Tasks;
using System.Collections.Generic;

public class OverwriteTest
{
public async Task AddOverwritesAsync(DiscordChannel channel, List<DiscordMember> members)
{
int i = 0;
while (i < members.Count)
{
await channel.AddOverwriteAsync(members[i], DiscordPermission.BanMembers);
i++;
}
}
}
""";

test.ExpectedDiagnostics.Add
(
Verifier.Diagnostic()
.WithLocation(12, 19)
.WithSeverity(DiagnosticSeverity.Warning)
.WithMessage("Use one 'channel.ModifyAsync(..)' instead of multiple 'channel.AddOverwriteAsync(..)'")
);

await test.RunAsync();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System.Threading.Tasks;
using DSharpPlus.Analyzers.Commands;
using DSharpPlus.Commands;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Testing;
using Microsoft.CodeAnalysis.Testing;
using NUnit.Framework;
using Verifier = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerVerifier<
DSharpPlus.Analyzers.Commands.ProcessorCheckAnalyzer,
Microsoft.CodeAnalysis.Testing.DefaultVerifier
>;

namespace DSharpPlus.Analyzers.Test;

public static class ProcessorCheckTest
{
[Test]
public static async Task DiagnosticTestAsync()
{
CSharpAnalyzerTest<ProcessorCheckAnalyzer, DefaultVerifier> test
= Utility.CreateAnalyzerTest<ProcessorCheckAnalyzer>();
test.TestState.AdditionalReferences.Add(typeof(CommandContext).Assembly);

test.TestCode = """
using System.Threading.Tasks;
using DSharpPlus.Commands.Trees.Metadata;
using DSharpPlus.Commands.Processors.TextCommands;
using DSharpPlus.Commands.Processors.SlashCommands;

public class Test
{
[AllowedProcessors<SlashCommandProcessor>()]
public async Task Tester(TextCommandContext context)
{
await context.RespondAsync("Tester!");
}
}
""";

test.ExpectedDiagnostics.Add
(
Verifier.Diagnostic()
.WithLocation(9, 30)
.WithSeverity(DiagnosticSeverity.Error)
.WithMessage("All provided processors does not support context 'TextCommandContext'")
);

await test.RunAsync();
}
}
Loading
Loading