Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

analyze the catch statement #1158

Merged
merged 1 commit into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Expand Up @@ -23,3 +23,4 @@ NC4020 | Naming | Warning | SmartContractMethodNamingAnalyzerUnderline
NC4021 | Usage | Warning | SupportedStandardsAnalyzer
NC4022 | Usage | Warning | BigIntegerUsingUsageAnalyzer
NC4023 | Usage | Error | StaticFieldInitializationAnalyzer
NC4024 | Usage | Error | MultipleCatchBlockAnalyzer
48 changes: 48 additions & 0 deletions src/Neo.SmartContract.Analyzer/MultipleCatchBlockAnalyzer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using System.Collections.Immutable;

namespace Neo.SmartContract.Analyzer
{
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class MultipleCatchBlockAnalyzer : DiagnosticAnalyzer
{
public const string DiagnosticId = "NC4024";

private static readonly LocalizableString Title = "Multiple catch blocks are not allowed in Neo smart contracts";
private static readonly LocalizableString MessageFormat = "Neo smart contracts only support a single catch block: {0}";
private static readonly LocalizableString Description = "Neo smart contracts are limited to one catch block per try statement.";
private const string Category = "Usage";

private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(
DiagnosticId,
Title,
MessageFormat,
Category,
DiagnosticSeverity.Error,
isEnabledByDefault: true,
description: Description);

public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);

public override void Initialize(AnalysisContext context)
{
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
context.EnableConcurrentExecution();
context.RegisterSyntaxNodeAction(AnalyzeTryStatement, SyntaxKind.TryStatement);
}

private static void AnalyzeTryStatement(SyntaxNodeAnalysisContext context)
{
var tryStatement = (TryStatementSyntax)context.Node;

if (tryStatement.Catches.Count > 1)
{
var diagnostic = Diagnostic.Create(Rule, tryStatement.GetLocation(), tryStatement.Catches.Count);
context.ReportDiagnostic(diagnostic);
}
}
}
}
3 changes: 2 additions & 1 deletion src/Neo.SmartContract.Analyzer/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ This repository contains a set of Roslyn analyzers and code fix providers for Ne
- [SupportedStandardsAnalyzer.cs](NeoContractAnalyzer/SupportedStandardsAnalyzer.cs): This analyzer checks for correct implementation of supported standards in smart contracts.
- [BigIntegerUsingUsageAnalyzer.cs](NeoContractAnalyzer/BigIntegerUsingUsageAnalyzer.cs): This analyzer warns about incorrect usage of BigInteger in using statements.
- [StaticFieldInitializationAnalyzer.cs](NeoContractAnalyzer/StaticFieldInitializationAnalyzer.cs): This analyzer checks for proper initialization of static fields in smart contracts.
- [MultipleCatchBlockAnalyzer.cs](NeoContractAnalyzer/MultipleCatchBlockAnalyzer.cs): This analyzer checks for multiple catch blocks in try statements.

## How to Use

Expand All @@ -41,4 +42,4 @@ Contributions to improve existing analyzers or add new ones are welcome. Please

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Verifier = Microsoft.CodeAnalysis.CSharp.Testing.XUnit.AnalyzerVerifier<Neo.SmartContract.Analyzer.MultipleCatchBlockAnalyzer>;

namespace Neo.SmartContract.Analyzer.UnitTests
{
[TestClass]
public class MultipleCatchBlockAnalyzerUnitTest
{
[TestMethod]
public async Task MultipleCatchBlockAnalyzer_DetectMultipleCatchBlocks()
{
const string sourceCode = """
using System;

public class TestClass
{
public void TestMethod()
{
try
{
// Some code that might throw an exception
}
catch (FormatException ex)
{
// Handle general exception
}
catch (Exception ex)
{
// Handle specific exception
}
}
}
""";

var expected = Verifier.Diagnostic(MultipleCatchBlockAnalyzer.DiagnosticId)
.WithSpan(7, 9, 18, 10)
.WithArguments("2");

await Verifier.VerifyAnalyzerAsync(sourceCode, expected);
}
}
}
Loading