Skip to content

Commit

Permalink
Merge pull request #364 from StefanMaron/prerelease
Browse files Browse the repository at this point in the history
Merge branch 'prerelease' into master
  • Loading branch information
Arthurvdv authored Nov 26, 2023
2 parents baafaff + 93d89d2 commit f83ddeb
Show file tree
Hide file tree
Showing 27 changed files with 250 additions and 120 deletions.
1 change: 0 additions & 1 deletion Design/Rule0001FlowFieldsShouldNotBeEditable.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using System;
using System.Collections.Immutable;

namespace BusinessCentral.LinterCop.Design
Expand Down
27 changes: 13 additions & 14 deletions Design/Rule0002CommitMustBeExplainedByComment.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using Microsoft.Dynamics.Nav.CodeAnalysis.Syntax;
using System;
using System.Collections.Immutable;

namespace BusinessCentral.LinterCop.Design
{
[DiagnosticAnalyzer]
public class Rule0002CommitMustBeExplainedByComment : DiagnosticAnalyzer
{
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create<DiagnosticDescriptor>(DiagnosticDescriptors.Rule0002CommitMustBeExplainedByComment);

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

private void CheckCommitForExplainingComment(OperationAnalysisContext ctx)
[DiagnosticAnalyzer]
public class Rule0002CommitMustBeExplainedByComment : DiagnosticAnalyzer
{
if (ctx.ContainingSymbol.GetContainingObjectTypeSymbol().IsObsoletePending || ctx.ContainingSymbol.GetContainingObjectTypeSymbol().IsObsoleteRemoved) return;
if (ctx.ContainingSymbol.IsObsoletePending ||ctx.ContainingSymbol.IsObsoleteRemoved) return;
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create<DiagnosticDescriptor>(DiagnosticDescriptors.Rule0002CommitMustBeExplainedByComment);

IInvocationExpression operation = (IInvocationExpression)ctx.Operation;
if (operation.TargetMethod.Name.ToUpper() == "COMMIT" && operation.TargetMethod.MethodKind == MethodKind.BuiltInMethod)
public override void Initialize(AnalysisContext context) => context.RegisterOperationAction(new Action<OperationAnalysisContext>(this.CheckCommitForExplainingComment), OperationKind.InvocationExpression);

private void CheckCommitForExplainingComment(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.Name.ToUpper() == "COMMIT" && operation.TargetMethod.MethodKind == MethodKind.BuiltInMethod)
{
foreach (SyntaxTrivia trivia in operation.Syntax.Parent.GetLeadingTrivia())
{
if (trivia.IsKind(SyntaxKind.LineCommentTrivia))
Expand All @@ -38,6 +37,6 @@ private void CheckCommitForExplainingComment(OperationAnalysisContext ctx)

ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0002CommitMustBeExplainedByComment, ctx.Operation.Syntax.GetLocation()));
}
}
}
}
}
16 changes: 7 additions & 9 deletions Design/Rule0003DoNotUseObjectIDsInVariablesOrProperties.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using System;
using System.Collections.Immutable;
using System.Threading;

namespace BusinessCentral.LinterCop.Design
{
[DiagnosticAnalyzer]
public class Rule0003DoNotUseObjectIDsInVariablesOrProperties : DiagnosticAnalyzer
{
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create<DiagnosticDescriptor>(DiagnosticDescriptors.Rule0003DoNotUseObjectIDsInVariablesOrProperties, DiagnosticDescriptors.Rule0005VariableCasingShouldNotDIfferFromDeclaration);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create<DiagnosticDescriptor>(DiagnosticDescriptors.Rule0003DoNotUseObjectIDsInVariablesOrProperties, DiagnosticDescriptors.Rule0005VariableCasingShouldNotDifferFromDeclaration);

public override void Initialize(AnalysisContext context)
{
Expand Down Expand Up @@ -40,7 +38,7 @@ private void CheckForObjectIDsInVariablesOrProperties(SyntaxNodeAnalysisContext
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0003DoNotUseObjectIDsInVariablesOrProperties, ctx.Node.GetLocation(), new object[] { ctx.Node.ToString().Trim('"'), correctName }));

if (ctx.Node.GetLastToken().ToString().Trim('"') != correctName)
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0005VariableCasingShouldNotDIfferFromDeclaration, ctx.Node.GetLocation(), new object[] { correctName, "" }));
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0005VariableCasingShouldNotDifferFromDeclaration, ctx.Node.GetLocation(), new object[] { correctName, "" }));
}
if (ctx.ContainingSymbol.Kind == SymbolKind.Property)
{
Expand Down Expand Up @@ -72,7 +70,7 @@ private void CheckForObjectIDsInVariablesOrProperties(SyntaxNodeAnalysisContext
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0003DoNotUseObjectIDsInVariablesOrProperties, ctx.Node.GetLocation(), new object[] { ctx.Node.ToString().Trim('"'), property.ValueText }));

if (ctx.Node.GetLastToken().ToString().Trim('"') != property.ValueText)
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0005VariableCasingShouldNotDIfferFromDeclaration, ctx.Node.GetLocation(), new object[] { property.ValueText, "" }));
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0005VariableCasingShouldNotDifferFromDeclaration, ctx.Node.GetLocation(), new object[] { property.ValueText, "" }));
}
}

Expand All @@ -94,11 +92,11 @@ private void CheckForObjectIDsInVariablesOrProperties(SyntaxNodeAnalysisContext
else
correctName = parameter.ParameterType.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)
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0005VariableCasingShouldNotDIfferFromDeclaration, ctx.Node.GetLocation(), new object[] { correctName, "" }));
if (ctx.Node.GetLastToken().ToString().Trim('"') != correctName)
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0005VariableCasingShouldNotDifferFromDeclaration, ctx.Node.GetLocation(), new object[] { correctName, "" }));
}
}
try
Expand All @@ -117,7 +115,7 @@ private void CheckForObjectIDsInVariablesOrProperties(SyntaxNodeAnalysisContext
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0003DoNotUseObjectIDsInVariablesOrProperties, ctx.Node.GetLocation(), new object[] { ctx.Node.ToString().Trim('"'), correctName }));

if (ctx.Node.ToString().Trim('"') != correctName)
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0005VariableCasingShouldNotDIfferFromDeclaration, ctx.Node.GetLocation(), new object[] { correctName, "" }));
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0005VariableCasingShouldNotDifferFromDeclaration, ctx.Node.GetLocation(), new object[] { correctName, "" }));
}
}
catch (System.NullReferenceException)
Expand Down
20 changes: 10 additions & 10 deletions Design/Rule0004LookupPageIdAndDrillDownPageId.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using Microsoft.Dynamics.Nav.CodeAnalysis.Syntax;
using System;
using System.Collections.Immutable;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;

namespace BusinessCentral.LinterCop.Design
{
Expand All @@ -25,7 +20,8 @@ private void CheckForLookupPageIdAndDrilldownPageId(SymbolAnalysisContext contex
CheckTable(pageTypeSymbol.RelatedTable, ref context);
}

private void CheckTable(ITableTypeSymbol table, ref SymbolAnalysisContext context) {
private void CheckTable(ITableTypeSymbol table, ref SymbolAnalysisContext context)
{
if (table.IsObsoletePending || table.IsObsoleteRemoved) return;
if (!IsSymbolAccessible(table)) return;
if (table.TableType == TableTypeKind.Temporary) return;
Expand All @@ -43,14 +39,18 @@ private void CheckTable(ITableTypeSymbol table, ref SymbolAnalysisContext contex
private static string GetDeclaration(ISymbol symbol)
=> symbol.Location.SourceTree.GetText(CancellationToken.None).GetSubText(symbol.DeclaringSyntaxReference.Span).ToString();

private static bool IsSymbolAccessible(ISymbol symbol) {
try {
private static bool IsSymbolAccessible(ISymbol symbol)
{
try
{
GetDeclaration(symbol);
return true;
} catch(Exception) {
}
catch (Exception)
{
return false;
}
}
}

}
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using System;
using System.Collections.Immutable;
using System.Linq;

namespace BusinessCentral.LinterCop.Design
{
[DiagnosticAnalyzer]
public class Rule0005VariableCasingShouldNotDIfferFromDeclaration : DiagnosticAnalyzer
public class Rule0005VariableCasingShouldNotDifferFromDeclaration : DiagnosticAnalyzer
{
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create<DiagnosticDescriptor>(DiagnosticDescriptors.Rule0005VariableCasingShouldNotDIfferFromDeclaration);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create<DiagnosticDescriptor>(DiagnosticDescriptors.Rule0005VariableCasingShouldNotDifferFromDeclaration);

public override void Initialize(AnalysisContext context)
{
Expand Down Expand Up @@ -56,21 +54,21 @@ private void CheckForBuiltInTypeCasingMismatch(SymbolAnalysisContext ctx)

if (node.IsToken)
if (SyntaxFactory.Token(node.Kind).ToString() != node.ToString())
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0005VariableCasingShouldNotDIfferFromDeclaration, node.GetLocation(), new object[] { SyntaxFactory.Token(node.Kind), "" }));
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0005VariableCasingShouldNotDifferFromDeclaration, node.GetLocation(), new object[] { SyntaxFactory.Token(node.Kind), "" }));
if (node.IsNode && !node.AsNode().ToString().StartsWith("array"))
{
if ((node.AsNode().IsKind(SyntaxKind.SimpleTypeReference) || node.Kind.ToString().Contains("DataType")) && !node.Kind.ToString().StartsWith("Codeunit") && !node.Kind.ToString().StartsWith("Enum") && !node.Kind.ToString().StartsWith("Label"))
{
var targetName = Enum.GetValues(typeof(NavTypeKind)).Cast<NavTypeKind>().FirstOrDefault(Kind => Kind.ToString().ToUpper() == node.AsNode().ToString().ToUpper() && Kind.ToString() != node.AsNode().ToString());
if (targetName != NavTypeKind.None)
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0005VariableCasingShouldNotDIfferFromDeclaration, node.GetLocation(), new object[] { targetName, "" }));
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0005VariableCasingShouldNotDifferFromDeclaration, node.GetLocation(), new object[] { targetName, "" }));
}
if (node.AsNode().IsKind(SyntaxKind.SubtypedDataType) || node.AsNode().IsKind(SyntaxKind.GenericDataType) || node.AsNode().IsKind(SyntaxKind.OptionAccessExpression) ||
(node.AsNode().IsKind(SyntaxKind.SimpleTypeReference) && (node.Kind.ToString().StartsWith("Codeunit") || !node.Kind.ToString().StartsWith("Enum") || !node.Kind.ToString().StartsWith("Label"))))
{
var targetName = Enum.GetValues(typeof(NavTypeKind)).Cast<NavTypeKind>().FirstOrDefault(Kind => node.AsNode().ToString().ToUpper().StartsWith(Kind.ToString().ToUpper()) && !node.AsNode().ToString().StartsWith(Kind.ToString()));
if (targetName != NavTypeKind.None)
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0005VariableCasingShouldNotDIfferFromDeclaration, node.GetLocation(), new object[] { targetName, "" }));
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0005VariableCasingShouldNotDifferFromDeclaration, node.GetLocation(), new object[] { targetName, "" }));
}
}
}
Expand Down Expand Up @@ -152,13 +150,13 @@ private void CheckForBuiltInMethodsWithCasingMismatch(OperationAnalysisContext c

if (OnlyDiffersInCasing(ctx.Operation.Syntax.ToString(), targetName))
{
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0005VariableCasingShouldNotDIfferFromDeclaration, ctx.Operation.Syntax.GetLocation(), new object[] { targetName, "" }));
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0005VariableCasingShouldNotDifferFromDeclaration, ctx.Operation.Syntax.GetLocation(), new object[] { targetName, "" }));
return;
}

var nodes = Array.Find(ctx.Operation.Syntax.DescendantNodes((SyntaxNode e) => true).ToArray(), element => OnlyDiffersInCasing(element.ToString(), targetName));
if (nodes != null)
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0005VariableCasingShouldNotDIfferFromDeclaration, ctx.Operation.Syntax.GetLocation(), new object[] { targetName, "" }));
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0005VariableCasingShouldNotDifferFromDeclaration, ctx.Operation.Syntax.GetLocation(), new object[] { targetName, "" }));
}
private bool OnlyDiffersInCasing(string left, string right)
{
Expand Down
30 changes: 16 additions & 14 deletions Design/Rule0006FieldNotAutoIncrementInTemporaryTable.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using Microsoft.Dynamics.Nav.CodeAnalysis.Syntax;
using System;
using System.Collections.Immutable;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;

namespace BusinessCentral.LinterCop.Design
{
Expand All @@ -19,24 +14,27 @@ public override void Initialize(AnalysisContext context)

private void CheckTablePrimaryKeyIsNotAutoIncrement(SymbolAnalysisContext context)
{
if (context.Symbol.IsObsoletePending ||context.Symbol.IsObsoleteRemoved) return;
if (context.Symbol.IsObsoletePending || context.Symbol.IsObsoleteRemoved) return;
ITableTypeSymbol tableTypeSymbol = (ITableTypeSymbol)context.Symbol;
if (!IsSymbolAccessible(tableTypeSymbol))
return;

CheckTable(tableTypeSymbol, ref context);
}

private void CheckTable(ITableTypeSymbol table, ref SymbolAnalysisContext context) {
private void CheckTable(ITableTypeSymbol table, ref SymbolAnalysisContext context)
{
if (table.TableType != TableTypeKind.Temporary)
return;

foreach (var field in table.Fields) {
foreach (var field in table.Fields)
{
IPropertySymbol propertySymbol = field.GetProperty(PropertyKind.AutoIncrement);
if(propertySymbol == null)
if (propertySymbol == null)
continue;

if (propertySymbol?.ValueText != "0") {
if (propertySymbol?.ValueText != "0")
{
context.ReportDiagnostic(
Diagnostic.Create(
DiagnosticDescriptors.Rule0006FieldNotAutoIncrementInTemporaryTable,
Expand All @@ -48,14 +46,18 @@ private void CheckTable(ITableTypeSymbol table, ref SymbolAnalysisContext contex
private static string GetDeclaration(ISymbol symbol)
=> symbol.Location.SourceTree.GetText(CancellationToken.None).GetSubText(symbol.DeclaringSyntaxReference.Span).ToString();

private static bool IsSymbolAccessible(ISymbol symbol) {
try {
private static bool IsSymbolAccessible(ISymbol symbol)
{
try
{
GetDeclaration(symbol);
return true;
} catch(Exception) {
}
catch (Exception)
{
return false;
}
}
}

}
24 changes: 11 additions & 13 deletions Design/Rule0007DataPerCompanyShouldAlwaysBeSet.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using Microsoft.Dynamics.Nav.CodeAnalysis.Syntax;
using System;
using System.Collections.Immutable;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;

namespace BusinessCentral.LinterCop.Design
{
Expand All @@ -15,11 +10,11 @@ public class Rule0007DataPerCompanyShouldAlwaysBeSet : DiagnosticAnalyzer
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create<DiagnosticDescriptor>(DiagnosticDescriptors.Rule0007DataPerCompanyShouldAlwaysBeSet);

public override void Initialize(AnalysisContext context)
=> context.RegisterSymbolAction(new Action<SymbolAnalysisContext>(this.CheckforMissingDataPerCompanyOnTables), SymbolKind.Table);
=> context.RegisterSymbolAction(new Action<SymbolAnalysisContext>(this.CheckForMissingDataPerCompanyOnTables), SymbolKind.Table);

private void CheckforMissingDataPerCompanyOnTables(SymbolAnalysisContext context)
private void CheckForMissingDataPerCompanyOnTables(SymbolAnalysisContext context)
{
if (context.Symbol.IsObsoletePending ||context.Symbol.IsObsoleteRemoved) return;
if (context.Symbol.IsObsoletePending || context.Symbol.IsObsoleteRemoved) return;
ITableTypeSymbol table = (ITableTypeSymbol)context.Symbol;
if (table.TableType == TableTypeKind.Temporary)
return;
Expand All @@ -33,17 +28,20 @@ private void CheckforMissingDataPerCompanyOnTables(SymbolAnalysisContext context
}
}

private static bool IsSymbolAccessible(ISymbol symbol) {
try {
private static bool IsSymbolAccessible(ISymbol symbol)
{
try
{
GetDeclaration(symbol);
return true;
} catch(Exception) {
}
catch (Exception)
{
return false;
}
}

private static string GetDeclaration(ISymbol symbol)
=> symbol.Location.SourceTree.GetText(CancellationToken.None).GetSubText(symbol.DeclaringSyntaxReference.Span).ToString();
}

}
}
Loading

0 comments on commit f83ddeb

Please sign in to comment.