Skip to content

Commit

Permalink
Merge pull request #360 from StefanMaron/development
Browse files Browse the repository at this point in the history
Improve LC0025 with Accessibility and XML doc
  • Loading branch information
Arthurvdv authored Nov 22, 2023
2 parents e1dfa5d + 767d85d commit bcfaccc
Show file tree
Hide file tree
Showing 22 changed files with 70 additions and 91 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()));
}
}
}
}
}
2 changes: 0 additions & 2 deletions Design/Rule0003DoNotUseObjectIDsInVariablesOrProperties.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using System;
using System.Collections.Immutable;
using System.Threading;

namespace BusinessCentral.LinterCop.Design
{
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,13 +1,11 @@
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);

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;
}
}
}

}
23 changes: 10 additions & 13 deletions Design/Rule0008NoFilterOperatorsInSetRange.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
using Microsoft.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using Microsoft.Dynamics.Nav.CodeAnalysis.Symbols;

using System;
using System.Collections.Immutable;
using System.Linq;


namespace BusinessCentral.LinterCop.Design
{
Expand All @@ -20,17 +15,18 @@ public class Rule0008NoFilterOperatorsInSetRange : DiagnosticAnalyzer
private void AnalyzeInvocation(OperationAnalysisContext context)
{
if (context.ContainingSymbol.GetContainingObjectTypeSymbol().IsObsoletePending || context.ContainingSymbol.GetContainingObjectTypeSymbol().IsObsoleteRemoved) return;
if (context.ContainingSymbol.IsObsoletePending ||context.ContainingSymbol.IsObsoleteRemoved) return;
if (context.ContainingSymbol.IsObsoletePending || context.ContainingSymbol.IsObsoleteRemoved) return;
IInvocationExpression operation = (IInvocationExpression)context.Operation;
if (!SemanticFacts.IsSameName(operation.TargetMethod.Name,"setrange") || operation.TargetMethod == null || operation.Arguments.Count() < 2)
if (!SemanticFacts.IsSameName(operation.TargetMethod.Name, "setrange") || operation.TargetMethod == null || operation.Arguments.Count() < 2)
return;

CheckParameter(operation.Arguments[1].Value, ref operation, ref context);
if(operation.Arguments.Count() == 3)
if (operation.Arguments.Count() == 3)
CheckParameter(operation.Arguments[2].Value, ref operation, ref context);
}

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

Expand All @@ -40,15 +36,16 @@ private void CheckParameter(Microsoft.Dynamics.Nav.CodeAnalysis.IOperation opera
string parameterString = operand.Syntax.ToFullString();
if (!(parameterString.Contains('<') || parameterString.Contains('>') ||
parameterString.Contains("..") || parameterString.Contains('*') ||
parameterString.Contains('&') || parameterString.Contains('|'))) {
parameterString.Contains('&') || parameterString.Contains('|')))
{
return;
}

context.ReportDiagnostic(
Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics.Diagnostic.Create(
DiagnosticDescriptors.Rule0008NoFilterOperatorsInSetRange,
operation.Syntax.GetLocation()));
}
}

}
4 changes: 2 additions & 2 deletions Design/Rule0011AccessPropertyShouldAlwaysBeSet.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.Analyzers.Common.AppSourceCopConfiguration;
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using System.Collections.Immutable;
using BusinessCentral.LinterCop.Helpers;
using Microsoft.Dynamics.Nav.Analyzers.Common.AppSourceCopConfiguration;

namespace BusinessCentral.LinterCop.Design
{
Expand Down
3 changes: 0 additions & 3 deletions Design/Rule0012DoNotUseObjectIdInSystemFunctions.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;

namespace BusinessCentral.LinterCop.Design
{
Expand Down
2 changes: 0 additions & 2 deletions Design/Rule0013CheckForNotBlankOnSingleFieldPrimaryKeys.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using System;
using System.Linq;
using System.Collections.Immutable;

namespace BusinessCentral.LinterCop.Design
Expand Down
2 changes: 0 additions & 2 deletions Design/Rule0014PermissionSetCaptionLength.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using System;
using System.Collections.Immutable;
using System.Linq;

namespace BusinessCentral.LinterCop.Design
{
Expand Down
5 changes: 1 addition & 4 deletions Design/Rule0015PermissionSetCoverage.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using System;
using System.Collections.Immutable;
using Microsoft.Dynamics.Nav.Analyzers.Common;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Xml.XPath;

Expand Down Expand Up @@ -48,7 +45,7 @@ private void CheckPermissionSetCoverage(SymbolAnalysisContext context)
continue;
}

if(appObjTypeSymbol.Properties.Where(currentProperty => currentProperty.PropertyKind == PropertyKind.InherentPermissions).Any()) continue;
if (appObjTypeSymbol.Properties.Where(currentProperty => currentProperty.PropertyKind == PropertyKind.InherentPermissions).Any()) continue;

switch (appObjTypeSymbol.NavTypeKind)
{
Expand Down
1 change: 0 additions & 1 deletion Design/Rule0017WriteToFlowField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using Microsoft.Dynamics.Nav.CodeAnalysis.Semantics;
using Microsoft.Dynamics.Nav.CodeAnalysis.Syntax;
using System;
using System.Collections.Immutable;

namespace BusinessCentral.LinterCop.Design
Expand Down
1 change: 0 additions & 1 deletion Design/Rule0018NoEventsInInternalCodeunits.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using Microsoft.Dynamics.Nav.CodeAnalysis.InternalSyntax;
using Microsoft.Dynamics.Nav.CodeAnalysis.Symbols;
using System;
using System.Collections.Immutable;

namespace BusinessCentral.LinterCop.Design
Expand Down
1 change: 0 additions & 1 deletion Design/Rule0019DataClassificationFieldEqualsTable.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
1 change: 0 additions & 1 deletion Design/Rule0020ApplicationAreaEqualsToPage.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
2 changes: 0 additions & 2 deletions Design/Rule0023AlwaysSpecifyFieldgroups.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using Microsoft.Dynamics.Nav.CodeAnalysis.Symbols;
using Microsoft.Dynamics.Nav.CodeAnalysis.Text;
using System;
using System.Collections.Immutable;
using System.Linq;

namespace BusinessCentral.LinterCop.Design
{
Expand Down
5 changes: 2 additions & 3 deletions Design/Rule0024SemicolonAfterProcedureDeclaration.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using System;
using System.Collections.Immutable;
using Microsoft.Dynamics.Nav.CodeAnalysis;
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
{
Expand Down
18 changes: 11 additions & 7 deletions Design/Rule0025InternalProcedureModifier.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using System;
using System.Collections.Immutable;
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis;
using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics;
using Microsoft.Dynamics.Nav.CodeAnalysis.Symbols;
using Microsoft.Dynamics.Nav.CodeAnalysis.Syntax;
using System.Collections.Immutable;

namespace BusinessCentral.LinterCop.Design
{
Expand All @@ -18,12 +18,16 @@ private void AnalyzeInternalProcedures(SyntaxNodeAnalysisContext ctx)
if (ctx.ContainingSymbol.IsObsoletePending || ctx.ContainingSymbol.IsObsoleteRemoved) return;
if (ctx.ContainingSymbol.GetContainingObjectTypeSymbol().IsObsoletePending || ctx.ContainingSymbol.GetContainingObjectTypeSymbol().IsObsoleteRemoved) return;

MethodDeclarationSyntax syntax = ctx.Node as MethodDeclarationSyntax;
SyntaxNodeOrToken accessModifier = syntax.ProcedureKeyword.GetPreviousToken();
if (ctx.ContainingSymbol.GetContainingObjectTypeSymbol().DeclaredAccessibility != Accessibility.Public) return;

MethodDeclarationSyntax methodDeclarationSyntax = (MethodDeclarationSyntax)ctx.Node;
SyntaxNodeOrToken accessModifier = methodDeclarationSyntax.ProcedureKeyword.GetPreviousToken();

if (accessModifier.Kind == SyntaxKind.LocalKeyword || accessModifier.Kind == SyntaxKind.InternalKeyword) return;

if (accessModifier.Kind != SyntaxKind.LocalKeyword && accessModifier.Kind != SyntaxKind.InternalKeyword)
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0025InternalProcedureModifier, syntax.ProcedureKeyword.GetLocation()));
if (methodDeclarationSyntax.GetLeadingTrivia().Where(x => x.Kind == SyntaxKind.SingleLineDocumentationCommentTrivia).Any()) return;

ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0025InternalProcedureModifier, methodDeclarationSyntax.ProcedureKeyword.GetLocation()));
}
}
}
1 change: 0 additions & 1 deletion Design/Rule0029CompareDateTimeThroughCodeunit.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.Syntax;
Expand Down
Loading

0 comments on commit bcfaccc

Please sign in to comment.