Skip to content

Commit

Permalink
Merge pull request #491 from StefanMaron/development
Browse files Browse the repository at this point in the history
New Rule0050 unsupported operator SetFilter
  • Loading branch information
Arthurvdv authored Jan 8, 2024
2 parents c6a666b + ea9ffc5 commit f609dd4
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 3 deletions.
56 changes: 56 additions & 0 deletions Design/Rule0050SetFilterOperatorCharInFilterExpression.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using Microsoft.Dynamics.Nav.CodeAnalysis.Symbols;
using System.Collections.Immutable;

namespace BusinessCentral.LinterCop.Design
{
[DiagnosticAnalyzer]
public class Rule0050SetFilterOperatorCharInFilterExpression : DiagnosticAnalyzer
{
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create<DiagnosticDescriptor>(DiagnosticDescriptors.Rule0050SetFilterOperatorCharInFilterExpression);
private static readonly List<char> unsupportedOperators = new List<char>
{
'*', '?', '@'
};

public override void Initialize(AnalysisContext context) => context.RegisterOperationAction(new Action<OperationAnalysisContext>(this.AnalyzeInvocation), OperationKind.InvocationExpression);

private void AnalyzeInvocation(OperationAnalysisContext ctx)
{
if (ctx.ContainingSymbol.GetContainingObjectTypeSymbol().IsObsoletePending || ctx.ContainingSymbol.GetContainingObjectTypeSymbol().IsObsoleteRemoved) return;
if (ctx.ContainingSymbol.IsObsoletePending || ctx.ContainingSymbol.IsObsoleteRemoved) return;

IInvocationExpression operation = (IInvocationExpression)ctx.Operation;
if (operation.TargetMethod.MethodKind != MethodKind.BuiltInMethod) return;

if (operation.TargetMethod == null || !SemanticFacts.IsSameName(operation.TargetMethod.Name, "SetFilter") || operation.Arguments.Count() < 2)
return;

CheckParameter(operation.Arguments[1].Value, ref operation, ref ctx);
}

private void CheckParameter(IOperation operand, ref IInvocationExpression operation, ref OperationAnalysisContext ctx)
{
if (operand.Type.GetNavTypeKindSafe() != NavTypeKind.String && operand.Type.GetNavTypeKindSafe() != NavTypeKind.Joker)
return;

if (operand.Syntax.Kind != SyntaxKind.LiteralExpression)
return;

string parameterString = operand.Syntax.ToFullString();
foreach (char unsupportedOperator in unsupportedOperators)
{
ctx.CancellationToken.ThrowIfCancellationRequested();

if (parameterString.Contains(unsupportedOperator))
{
ctx.ReportDiagnostic(
Diagnostic.Create(
DiagnosticDescriptors.Rule0050SetFilterOperatorCharInFilterExpression,
operation.Syntax.GetLocation(), new object[] { unsupportedOperator }));
}
}
}
}
}
5 changes: 5 additions & 0 deletions LinterCop.ruleset.json
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,11 @@
"id": "LC0049",
"action": "Info",
"justification": "SourceTable property not defined on Page."
},
{
"id": "LC0050",
"action": "Info",
"justification": "SetFilter with unsupported operator in filter expression."
}
]
}
1 change: 1 addition & 0 deletions LinterCopAnalyzers.Generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@ public static class DiagnosticDescriptors
public static readonly DiagnosticDescriptor Rule0047LockedLabelsTok = new DiagnosticDescriptor(LinterCopAnalyzers.AnalyzerPrefix + "0047", (LocalizableString)new LocalizableResourceString("Rule0047LockedLabelsTokTitle", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), (LocalizableString)new LocalizableResourceString("Rule0047LockedLabelsTokFormat", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "Design", DiagnosticSeverity.Info, true, (LocalizableString)new LocalizableResourceString("Rule0047LockedLabelsTokDescription", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0047");
public static readonly DiagnosticDescriptor Rule0048ErrorWithTextConstant = new DiagnosticDescriptor(LinterCopAnalyzers.AnalyzerPrefix + "0048", (LocalizableString)new LocalizableResourceString("Rule0048ErrorWithTextConstantTitle", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), (LocalizableString)new LocalizableResourceString("Rule0048ErrorWithTextConstantFormat", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "Design", DiagnosticSeverity.Info, true, (LocalizableString)new LocalizableResourceString("Rule0048ErrorWithTextConstantDescription", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0048");
public static readonly DiagnosticDescriptor Rule0049PageWithoutSourceTable = new DiagnosticDescriptor(LinterCopAnalyzers.AnalyzerPrefix + "0049", (LocalizableString)new LocalizableResourceString("Rule0049PageWithoutSourceTableTitle", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), (LocalizableString)new LocalizableResourceString("Rule0049PageWithoutSourceTableFormat", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "Design", DiagnosticSeverity.Info, true, (LocalizableString)new LocalizableResourceString("Rule0049PageWithoutSourceTableDescription", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0049");
public static readonly DiagnosticDescriptor Rule0050SetFilterOperatorCharInFilterExpression = new DiagnosticDescriptor(LinterCopAnalyzers.AnalyzerPrefix + "0050", (LocalizableString)new LocalizableResourceString("Rule0050SetFilterOperatorCharInFilterExpressionTitle", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), (LocalizableString)new LocalizableResourceString("Rule0050SetFilterOperatorCharInFilterExpressionFormat", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "Design", DiagnosticSeverity.Info, true, (LocalizableString)new LocalizableResourceString("Rule0050SetFilterOperatorCharInFilterExpressionDescription", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0050");
}
}
15 changes: 12 additions & 3 deletions LinterCopAnalyzers.resx
Original file line number Diff line number Diff line change
Expand Up @@ -547,12 +547,21 @@
<value>Use Error with a ErrorInfo or Label variable to improve telemetry details.</value>
</data>
<data name="Rule0049PageWithoutSourceTableTitle" xml:space="preserve">
<value>"SourceTable property not defined on {0} '{1}'.</value>
<value>SourceTable property not defined on {0} '{1}'.</value>
</data>
<data name="Rule0049PageWithoutSourceTableFormat" xml:space="preserve">
<value>"SourceTable property not defined on {0} '{1}'.</value>
<value>SourceTable property not defined on {0} '{1}'.</value>
</data>
<data name="Rule0049PageWithoutSourceTableDescription" xml:space="preserve">
<value>"SourceTable property not defined on {0} '{1}'.</value>
<value>SourceTable property not defined on {0} '{1}'.</value>
</data>
<data name="Rule0050SetFilterOperatorCharInFilterExpressionTitle" xml:space="preserve">
<value>Operator '{0}' found in filter expression, currently treated as a literal character. Implement StrSubstNo() to apply '{0}' as operator.</value>
</data>
<data name="Rule0050SetFilterOperatorCharInFilterExpressionFormat" xml:space="preserve">
<value>Operator '{0}' found in filter expression, currently treated as a literal character. Implement StrSubstNo() to apply '{0}' as operator.</value>
</data>
<data name="Rule0050SetFilterOperatorCharInFilterExpressionDescription" xml:space="preserve">
<value>Operator '{0}' found in filter expression, currently treated as a literal character. Implement StrSubstNo() to apply '{0}' as operator.</value>
</data>
</root>
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ Further note that you should have BcContainerHelper version 2.0.16 (or newer) in
|[LC0047](https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0047)|Locked `Label` must have a suffix Tok.|Info|
|[LC0048](https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0048)|Use Error with a `ErrorInfo` or `Label` variable to improve telemetry details.|Info|
|[LC0049](https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0049)|`SourceTable` property not defined on Page.|Info|
|[LC0050](https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0050)| `SetFilter` with unsupported operator in filter expression.|Info|


## Configuration
Expand Down

0 comments on commit f609dd4

Please sign in to comment.