From 45df5208c23d02374fcdb0be85f4a7e905dec429 Mon Sep 17 00:00:00 2001 From: Arthur van de Vondervoort Date: Mon, 30 Oct 2023 15:35:20 +0100 Subject: [PATCH] Init new role 0029 Use CompareDateTime method in Type Helper codeunit for DateTime variable comparisons. --- .../Rule0029CompareDateTimeThroughCodeunit.cs | 33 +++++++++++++++++++ LinterCop.ruleset.json | 5 +++ LinterCopAnalyzers.Generated.cs | 1 + LinterCopAnalyzers.resx | 12 +++++++ README.md | 2 ++ 5 files changed, 53 insertions(+) create mode 100644 Design/Rule0029CompareDateTimeThroughCodeunit.cs diff --git a/Design/Rule0029CompareDateTimeThroughCodeunit.cs b/Design/Rule0029CompareDateTimeThroughCodeunit.cs new file mode 100644 index 00000000..0ce1387a --- /dev/null +++ b/Design/Rule0029CompareDateTimeThroughCodeunit.cs @@ -0,0 +1,33 @@ +using Microsoft.Dynamics.Nav.Analyzers.Common.AppSourceCopConfiguration; +using Microsoft.Dynamics.Nav.CodeAnalysis; +using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics; +using Microsoft.Dynamics.Nav.CodeAnalysis.Syntax; +using System.Collections.Immutable; + +namespace BusinessCentral.LinterCop.Design +{ + [DiagnosticAnalyzer] + public class Rule0029CompareDateTimeThroughCodeunit : DiagnosticAnalyzer + { + public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(DiagnosticDescriptors.Rule0029CompareDateTimeThroughCodeunit); + + public override void Initialize(AnalysisContext context) => context.RegisterOperationAction(new Action(this.CompareDateTimeWithTypeHelper), OperationKind.BinaryOperatorExpression); + + private void CompareDateTimeWithTypeHelper(OperationAnalysisContext context) + { + if (context.ContainingSymbol.GetContainingObjectTypeSymbol().IsObsoletePending || context.ContainingSymbol.GetContainingObjectTypeSymbol().IsObsoleteRemoved) return; + if (context.ContainingSymbol.IsObsoletePending || context.ContainingSymbol.IsObsoleteRemoved) return; + + IBinaryOperatorExpression operation = (IBinaryOperatorExpression)context.Operation; + + if (operation.LeftOperand.Type.NavTypeKind == NavTypeKind.DateTime && operation.RightOperand.Type.NavTypeKind == NavTypeKind.DateTime && + (operation.Syntax.IsKind(SyntaxKind.EqualsExpression) || + operation.Syntax.IsKind(SyntaxKind.NotEqualsExpression) || + operation.Syntax.IsKind(SyntaxKind.GreaterThanExpression) || + operation.Syntax.IsKind(SyntaxKind.GreaterThanOrEqualExpression) || + operation.Syntax.IsKind(SyntaxKind.LessThanExpression) || + operation.Syntax.IsKind(SyntaxKind.LessThanOrEqualExpression))) + context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0029CompareDateTimeThroughCodeunit, context.Operation.Syntax.GetLocation())); + } + } +} \ No newline at end of file diff --git a/LinterCop.ruleset.json b/LinterCop.ruleset.json index 35cdd7f0..c82739e6 100644 --- a/LinterCop.ruleset.json +++ b/LinterCop.ruleset.json @@ -116,6 +116,11 @@ "id": "LC0028", "action": "Info", "justification": "Event subscriber arguments now use identifier syntax instead of string literals. Convert the argument literal to an identifier." + }, + { + "id": "LC0029", + "action": "Info", + "justification": "Use CompareDateTime method in Type Helper codeunit for DateTime variable comparisons." } ] } \ No newline at end of file diff --git a/LinterCopAnalyzers.Generated.cs b/LinterCopAnalyzers.Generated.cs index 5f944027..45a511a2 100644 --- a/LinterCopAnalyzers.Generated.cs +++ b/LinterCopAnalyzers.Generated.cs @@ -31,5 +31,6 @@ public static class DiagnosticDescriptors public static readonly DiagnosticDescriptor Rule0022GlobalLanguageImplementTranslationHelper = new DiagnosticDescriptor(LinterCopAnalyzers.AnalyzerPrefix + "0022", (LocalizableString)new LocalizableResourceString("Rule0022GlobalLanguageImplementTranslationHelperTitle", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), (LocalizableString)new LocalizableResourceString("Rule0022GlobalLanguageImplementTranslationHelperFormat", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "Design", DiagnosticSeverity.Info, true, (LocalizableString)new LocalizableResourceString("Rule0022GlobalLanguageImplementTranslationHelperDescription", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0022"); public static readonly DiagnosticDescriptor Rule0023AlwaysSpecifyFieldgroups = new DiagnosticDescriptor(LinterCopAnalyzers.AnalyzerPrefix + "0023", (LocalizableString)new LocalizableResourceString("Rule0023AlwaysSpecifyFieldgroups", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), (LocalizableString)new LocalizableResourceString("Rule0023AlwaysSpecifyFieldgroups", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "Design", DiagnosticSeverity.Info, true, (LocalizableString)new LocalizableResourceString("Rule0023AlwaysSpecifyFieldgroups", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0023"); public static readonly DiagnosticDescriptor Rule0028CodeNavigabilityOnEventSubscribers = new DiagnosticDescriptor(LinterCopAnalyzers.AnalyzerPrefix + "0028", (LocalizableString)new LocalizableResourceString("Rule0028CodeNavigabilityOnEventSubscribersTitle", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), (LocalizableString)new LocalizableResourceString("Rule0028CodeNavigabilityOnEventSubscribersFormat", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "Design", DiagnosticSeverity.Info, true, (LocalizableString)new LocalizableResourceString("Rule0028CodeNavigabilityOnEventSubscribersDescription", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0028"); + public static readonly DiagnosticDescriptor Rule0029CompareDateTimeThroughCodeunit = new DiagnosticDescriptor(LinterCopAnalyzers.AnalyzerPrefix + "0029", (LocalizableString)new LocalizableResourceString("Rule0029CompareDateTimeThroughCodeunitTitle", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), (LocalizableString)new LocalizableResourceString("Rule0029CompareDateTimeThroughCodeunitFormat", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "Design", DiagnosticSeverity.Info, true, (LocalizableString)new LocalizableResourceString("Rule0029CompareDateTimeThroughCodeunitDescription", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0029"); } } \ No newline at end of file diff --git a/LinterCopAnalyzers.resx b/LinterCopAnalyzers.resx index fa6e8a00..ae850a14 100644 --- a/LinterCopAnalyzers.resx +++ b/LinterCopAnalyzers.resx @@ -397,4 +397,16 @@ Event subscriber arguments now use identifier syntax instead of string literals. Convert the argument literal to an identifier. + + Use CompareDateTime method in Type Helper codeunit for DateTime variable comparisons. + + + + Use CompareDateTime method in Type Helper codeunit for DateTime variable comparisons. + + + + Use CompareDateTime method in Type Helper codeunit for DateTime variable comparisons. + + \ No newline at end of file diff --git a/README.md b/README.md index fc18e244..19fa183c 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,8 @@ Further note that you should have BcContainerHelper version 2.0.16 (or newer) in |[LC0022](https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0022)|`GlobalLanguage()` must be implemented through the `Translation Helper` codeunit from the Base Application.|Info| |[LC0023](https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0023)|Always provide fieldsgroups `DropDown` and `Brick` on tables.|Info| |[LC0028](https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0028)|Event subscriber arguments now use identifier syntax instead of string literals. Convert the argument literal to an identifier.|Info| +|[LC0029](https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0029)|Use `CompareDateTime` method in `Type Helper` codeunit for DateTime variable comparisons.|Info| + ## Configuration