Skip to content

Commit

Permalink
Merge pull request #400 from StefanMaron/development
Browse files Browse the repository at this point in the history
Merge branch 'Development' into master
  • Loading branch information
Arthurvdv authored Dec 5, 2023
2 parents f83ddeb + 2204dd1 commit 66c993d
Show file tree
Hide file tree
Showing 15 changed files with 366 additions and 70 deletions.
4 changes: 2 additions & 2 deletions Design/Rule0003DoNotUseObjectIDsInVariablesOrProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,10 @@ private void CheckForObjectIDsInVariablesOrProperties(SyntaxNodeAnalysisContext
{
correctName = returnValue.ReturnType.Name;

if (ctx.Node.ToString().Trim('"').ToUpper() != correctName.ToUpper())
if (ctx.Node.GetLastToken().ToString().Trim('"').ToUpper() != correctName.ToUpper())
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0003DoNotUseObjectIDsInVariablesOrProperties, ctx.Node.GetLocation(), new object[] { ctx.Node.ToString().Trim('"'), correctName }));

if (ctx.Node.ToString().Trim('"') != correctName)
if (ctx.Node.GetLastToken().ToString().Trim('"') != correctName)
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0005VariableCasingShouldNotDifferFromDeclaration, ctx.Node.GetLocation(), new object[] { correctName, "" }));
}
}
Expand Down
6 changes: 2 additions & 4 deletions Design/Rule0011AccessPropertyShouldAlwaysBeSet.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Microsoft.Dynamics.Nav.Analyzers.Common.AppSourceCopConfiguration;
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using System.Collections.Immutable;
using BusinessCentral.LinterCop.Helpers;
Expand All @@ -16,8 +15,7 @@ public override void Initialize(AnalysisContext context)

private void CheckForMissingAccessProperty(SymbolAnalysisContext context)
{
var manifest = AppSourceCopConfigurationProvider.GetManifest(context.Compilation);
if (manifest.Runtime < RuntimeVersion.Spring2021 && (context.Symbol.Kind == SymbolKind.Enum || context.Symbol.Kind == SymbolKind.Interface))
if (!VersionChecker.IsSupported(context.Symbol, VersionCompatibility.Spring2021OrGreater) && (context.Symbol.Kind == SymbolKind.Enum || context.Symbol.Kind == SymbolKind.Interface))
return;

if (context.Symbol.IsObsoletePending || context.Symbol.IsObsoleteRemoved) return;
Expand Down
2 changes: 1 addition & 1 deletion Design/Rule0012DoNotUseObjectIdInSystemFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ private void CheckForObjectIdsInFunctionInvocations(OperationAnalysisContext con
catch (System.InvalidOperationException)
{ }

SyntaxKind[] AllowedParameterKinds = { SyntaxKind.MemberAccessExpression, SyntaxKind.IdentifierName, SyntaxKind.InvocationExpression };
SyntaxKind[] AllowedParameterKinds = { SyntaxKind.MemberAccessExpression, SyntaxKind.IdentifierName, SyntaxKind.InvocationExpression, SyntaxKind.QualifiedName };

if (CurrentFunction != null && operation.TargetMethod.Parameters.Length != 0 && !AllowedParameterKinds.Contains(operation.Arguments[0].Syntax.Kind) && (operation.Arguments[0].Syntax.ToString() != "0" || !CurrentFunction.ZeroIDAllowed))
{
Expand Down
1 change: 1 addition & 0 deletions Design/Rule0016CheckForMissingCaptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ private bool CaptionIsMissing(ISymbol Symbol, SymbolAnalysisContext context)

private static bool SuppressCaptionWarning(SymbolAnalysisContext context)
{
if (context.Symbol.GetContainingObjectTypeSymbol().GetTypeSymbol().GetNavTypeKindSafe() != NavTypeKind.Page) return false;
IPageTypeSymbol pageTypeSymbol = (IPageTypeSymbol)context.Symbol.GetContainingObjectTypeSymbol();
if (pageTypeSymbol.GetNavTypeKindSafe() != NavTypeKind.Page || pageTypeSymbol.PageType != PageTypeKind.API) return false;
LinterSettings.Create(context.Compilation.FileSystem.GetDirectoryPath());
Expand Down
18 changes: 14 additions & 4 deletions Design/Rule0026ToolTipPunctuation.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
using System.Collections.Immutable;
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using Microsoft.Dynamics.Nav.CodeAnalysis.Symbols;
using Microsoft.Dynamics.Nav.CodeAnalysis.Syntax;

namespace BusinessCentral.LinterCop.Design
{
[DiagnosticAnalyzer]
public class Rule0026ToolTipPunctuation : DiagnosticAnalyzer
{
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create<DiagnosticDescriptor>(DiagnosticDescriptors.Rule0026ToolTipPunctuation);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create<DiagnosticDescriptor>(DiagnosticDescriptors.Rule0026ToolTipMustEndWithDot, DiagnosticDescriptors.Rule0036ToolTipShouldStartWithSpecifies, DiagnosticDescriptors.Rule0037ToolTipDoNotUseLineBreaks, DiagnosticDescriptors.Rule0038ToolTipMaximumLength);

public override void Initialize(AnalysisContext context) => context.RegisterSyntaxNodeAction(new Action<SyntaxNodeAnalysisContext>(this.AnalyzeToolTipPunctuation), SyntaxKind.PageField, SyntaxKind.PageAction);

Expand All @@ -18,12 +19,21 @@ private void AnalyzeToolTipPunctuation(SyntaxNodeAnalysisContext ctx)
if (ctx.ContainingSymbol.GetContainingObjectTypeSymbol().IsObsoletePending || ctx.ContainingSymbol.GetContainingObjectTypeSymbol().IsObsoleteRemoved) return;

PropertyValueSyntax tooltipProperty = ctx.Node.GetPropertyValue(PropertyKind.ToolTip);
if (tooltipProperty == null)
return;
if (tooltipProperty == null) return;

StringLiteralValueSyntax tooltipLabel = ((LabelPropertyValueSyntax)tooltipProperty).Value.LabelText;
if (!tooltipLabel.Value.ToString().EndsWith(".'"))
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0026ToolTipPunctuation, tooltipProperty.GetLocation()));
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0026ToolTipMustEndWithDot, tooltipProperty.GetLocation()));

if (ctx.ContainingSymbol.Kind == SymbolKind.Control && ((IControlSymbol)ctx.ContainingSymbol).ControlKind == ControlKind.Field)
if (!tooltipLabel.Value.ToString().StartsWith("'Specifies"))
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0036ToolTipShouldStartWithSpecifies, tooltipProperty.GetLocation()));

if (tooltipLabel.Value.ToString().Contains("\\"))
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0037ToolTipDoNotUseLineBreaks, tooltipProperty.GetLocation()));

if (tooltipLabel.Value.ToString().Length > 202)
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0038ToolTipMaximumLength, tooltipProperty.GetLocation()));
}
}
}
35 changes: 0 additions & 35 deletions Design/Rule0028CodeNavigabilityOnEventSubscribers.cs

This file was deleted.

39 changes: 39 additions & 0 deletions Design/Rule0028IdentifiersInEventSubscribers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
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 Rule0028CodeNavigabilityOnEventSubscribers : DiagnosticAnalyzer
{
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create<DiagnosticDescriptor>(DiagnosticDescriptors.Rule0028IdentifiersInEventSubscribers);

public override void Initialize(AnalysisContext context) => context.RegisterCodeBlockAction(new Action<CodeBlockAnalysisContext>(this.AnalyzeIdentifiersInEventSubscribers));

private void AnalyzeIdentifiersInEventSubscribers(CodeBlockAnalysisContext context)
{
if (!VersionChecker.IsSupported(context.OwningSymbol, Feature.IdentifiersInEventSubscribers)) return;

if (context.OwningSymbol.GetContainingObjectTypeSymbol().IsObsoletePending || context.OwningSymbol.GetContainingObjectTypeSymbol().IsObsoleteRemoved) return;
if (context.OwningSymbol.IsObsoletePending || context.OwningSymbol.IsObsoleteRemoved) return;

if (!context.CodeBlock.IsKind(SyntaxKind.MethodDeclaration)) return;

var SyntaxList = ((MethodDeclarationSyntax)context.CodeBlock).Attributes.Where(value => SemanticFacts.IsSameName(value.GetIdentifierOrLiteralValue(), "EventSubscriber"));

if (SyntaxList.Where(value => value.ArgumentList.Arguments[2].IsKind(SyntaxKind.LiteralAttributeArgument)).Any())
{
context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0028IdentifiersInEventSubscribers, context.OwningSymbol.GetLocation()));
return;
}

if (SyntaxList.Where(value => !(value.ArgumentList.Arguments[3].GetIdentifierOrLiteralValue() == "") && value.ArgumentList.Arguments[3].IsKind(SyntaxKind.LiteralAttributeArgument)).Any())
{
context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0028IdentifiersInEventSubscribers, context.OwningSymbol.GetLocation()));
return;
}
}
}
}
10 changes: 4 additions & 6 deletions Design/Rule0031RecordInstanceIsolationLevel.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using Microsoft.Dynamics.Nav.Analyzers.Common.AppSourceCopConfiguration;
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using System.Collections.Immutable;
Expand All @@ -14,18 +13,17 @@ public class Rule0031RecordInstanceIsolationLevel : DiagnosticAnalyzer

private void CheckLockTable(OperationAnalysisContext ctx)
{
// ReadIsolation is supported from runtime versions 11.0 or greater.
var manifest = AppSourceCopConfigurationProvider.GetManifest(ctx.Compilation);
if (manifest.Runtime < RuntimeVersion.Spring2023) return;
if (!VersionChecker.IsSupported(ctx.ContainingSymbol, VersionCompatibility.Spring2023OrGreater)) return;

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 (SemanticFacts.IsSameName(operation.TargetMethod.Name, "LockTable"))
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0031RecordInstanceIsolationLevel, ctx.Operation.Syntax.GetLocation()));
if (!SemanticFacts.IsSameName(operation.TargetMethod.Name, "LockTable")) return;

ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0031RecordInstanceIsolationLevel, ctx.Operation.Syntax.GetLocation()));
}
}
}
10 changes: 4 additions & 6 deletions Design/Rule0034ExtensiblePropertyShouldAlwaysBeSet.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using Microsoft.Dynamics.Nav.Analyzers.Common.AppSourceCopConfiguration;
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using Microsoft.Dynamics.Nav.CodeAnalysis.Symbols;
Expand All @@ -20,17 +19,16 @@ public override void Initialize(AnalysisContext context)

private void CheckForMissingExtensibleProperty(SymbolAnalysisContext ctx)
{
// The Extensible property (and DeclaredAccessibility) is supported from runtime versions 4.0 or greater.
var manifest = AppSourceCopConfigurationProvider.GetManifest(ctx.Compilation);
if (manifest.Runtime < RuntimeVersion.Fall2019) return;
if (!VersionChecker.IsSupported(ctx.Symbol, VersionCompatibility.Fall2019OrGreater)) return;

if (ctx.Symbol.IsObsoletePending || ctx.Symbol.IsObsoleteRemoved) return;

if (ctx.Symbol.GetTypeSymbol().Kind == SymbolKind.Table && ctx.Symbol.DeclaredAccessibility != Accessibility.Public) return;
if (ctx.Symbol.GetTypeSymbol().Kind == SymbolKind.Page && ((IPageTypeSymbol)ctx.Symbol.GetTypeSymbol()).PageType == PageTypeKind.API) return;

if (ctx.Symbol.GetProperty(PropertyKind.Extensible) is null)
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0034ExtensiblePropertyShouldAlwaysBeSet, ctx.Symbol.GetLocation(), new object[] { Accessibility.Public.ToString().ToLower() }));
if (ctx.Symbol.GetProperty(PropertyKind.Extensible) != null) return;

ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0034ExtensiblePropertyShouldAlwaysBeSet, ctx.Symbol.GetLocation(), new object[] { Accessibility.Public.ToString().ToLower() }));
}
}
}
Loading

0 comments on commit 66c993d

Please sign in to comment.