mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2025-04-28 15:39:46 +00:00
Added an analyzer for static and const field naming
This commit is contained in:
parent
4aba041c40
commit
a33347ddb7
@ -5,3 +5,4 @@
|
|||||||
Rule ID | Category | Severity | Notes
|
Rule ID | Category | Severity | Notes
|
||||||
-----------|----------|----------|------------------------
|
-----------|----------|----------|------------------------
|
||||||
MWAIS0001 | Usage | Error | ProviderAccessAnalyzer
|
MWAIS0001 | Usage | Error | ProviderAccessAnalyzer
|
||||||
|
MWAIS0002 | Naming | Error | ConstStaticAnalyzer
|
@ -0,0 +1,67 @@
|
|||||||
|
using System.Collections.Immutable;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
|
using Microsoft.CodeAnalysis.Diagnostics;
|
||||||
|
|
||||||
|
namespace SourceCodeRules.NamingAnalyzers;
|
||||||
|
|
||||||
|
#pragma warning disable RS1038
|
||||||
|
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
||||||
|
#pragma warning restore RS1038
|
||||||
|
public sealed class ConstStaticAnalyzer : DiagnosticAnalyzer
|
||||||
|
{
|
||||||
|
private const string DIAGNOSTIC_ID = $"{Tools.ID_PREFIX}0002";
|
||||||
|
|
||||||
|
private static readonly string TITLE = "Constant and static fields must be in UPPER_CASE";
|
||||||
|
|
||||||
|
private static readonly string MESSAGE_FORMAT = "Field '{0}' must be in UPPER_CASE";
|
||||||
|
|
||||||
|
private static readonly string DESCRIPTION = "All constant and static fields should be named using UPPER_CASE.";
|
||||||
|
|
||||||
|
private const string CATEGORY = "Naming";
|
||||||
|
|
||||||
|
private static readonly DiagnosticDescriptor RULE = new(DIAGNOSTIC_ID, TITLE, MESSAGE_FORMAT, CATEGORY, DiagnosticSeverity.Error, isEnabledByDefault: true, description: DESCRIPTION);
|
||||||
|
|
||||||
|
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => [RULE];
|
||||||
|
|
||||||
|
public override void Initialize(AnalysisContext context)
|
||||||
|
{
|
||||||
|
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
|
||||||
|
context.EnableConcurrentExecution();
|
||||||
|
context.RegisterSyntaxNodeAction(this.AnalyzeField, SyntaxKind.FieldDeclaration);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AnalyzeField(SyntaxNodeAnalysisContext context)
|
||||||
|
{
|
||||||
|
var fieldDeclaration = (FieldDeclarationSyntax)context.Node;
|
||||||
|
|
||||||
|
// Prüfen ob das Feld static oder const ist
|
||||||
|
if (!fieldDeclaration.Modifiers.Any(m => m.IsKind(SyntaxKind.StaticKeyword) || m.IsKind(SyntaxKind.ConstKeyword)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var variable in fieldDeclaration.Declaration.Variables)
|
||||||
|
{
|
||||||
|
var fieldName = variable.Identifier.Text;
|
||||||
|
|
||||||
|
// Prüfen ob der Name bereits in UPPER_CASE ist
|
||||||
|
if (!IsUpperCase(fieldName))
|
||||||
|
{
|
||||||
|
var diagnostic = Diagnostic.Create(
|
||||||
|
RULE,
|
||||||
|
variable.Identifier.GetLocation(),
|
||||||
|
fieldName);
|
||||||
|
|
||||||
|
context.ReportDiagnostic(diagnostic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsUpperCase(string name)
|
||||||
|
{
|
||||||
|
// Erlaubt: Nur Großbuchstaben, Zahlen und Unterstriche
|
||||||
|
return name.All(c => char.IsUpper(c) || char.IsDigit(c) || c == '_');
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
using System.Collections.Immutable;
|
||||||
|
using System.Composition;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
using Microsoft.CodeAnalysis.CodeActions;
|
||||||
|
using Microsoft.CodeAnalysis.CodeFixes;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
|
using Microsoft.CodeAnalysis.Rename;
|
||||||
|
|
||||||
|
namespace SourceCodeRules.NamingCodeFixes;
|
||||||
|
|
||||||
|
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(ConstStaticCodeFixProvider)), Shared]
|
||||||
|
public sealed class ConstStaticCodeFixProvider : CodeFixProvider
|
||||||
|
{
|
||||||
|
public override ImmutableArray<string> FixableDiagnosticIds => [$"{Tools.ID_PREFIX}0002"];
|
||||||
|
|
||||||
|
public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
|
||||||
|
|
||||||
|
public override async Task RegisterCodeFixesAsync(CodeFixContext context)
|
||||||
|
{
|
||||||
|
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken);
|
||||||
|
var diagnostic = context.Diagnostics.First();
|
||||||
|
var diagnosticSpan = diagnostic.Location.SourceSpan;
|
||||||
|
var declaration = root?.FindToken(diagnosticSpan.Start).Parent?.AncestorsAndSelf().OfType<VariableDeclaratorSyntax>().First();
|
||||||
|
if (declaration is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
context.RegisterCodeFix(CodeAction.Create(title: "Convert to UPPER_CASE", createChangedDocument: c => this.ConvertToUpperCaseAsync(context.Document, declaration, c), equivalenceKey: nameof(ConstStaticCodeFixProvider)), diagnostic);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<Document> ConvertToUpperCaseAsync(Document document, VariableDeclaratorSyntax declarator, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var oldName = declarator.Identifier.Text;
|
||||||
|
var newName = ConvertToUpperCase(oldName);
|
||||||
|
|
||||||
|
var semanticModel = await document.GetSemanticModelAsync(cancellationToken);
|
||||||
|
var symbol = semanticModel?.GetDeclaredSymbol(declarator, cancellationToken);
|
||||||
|
if (symbol is null)
|
||||||
|
return document;
|
||||||
|
|
||||||
|
var solution = document.Project.Solution;
|
||||||
|
var newSolution = await Renamer.RenameSymbolAsync(solution, symbol, new SymbolRenameOptions(), newName, cancellationToken);
|
||||||
|
|
||||||
|
return newSolution.GetDocument(document.Id) ?? document;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ConvertToUpperCase(string name)
|
||||||
|
{
|
||||||
|
var result = new StringBuilder();
|
||||||
|
for (var i = 0; i < name.Length; i++)
|
||||||
|
{
|
||||||
|
var current = name[i];
|
||||||
|
|
||||||
|
// Insert an underscore before each uppercase letter, except the first one:
|
||||||
|
if (i > 0 && char.IsUpper(current) && !char.IsUpper(name[i - 1]))
|
||||||
|
result.Append('_');
|
||||||
|
|
||||||
|
result.Append(char.ToUpper(current));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.ToString();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user