diff --git a/Design/Rule0003DoNotUseObjectIDsInVariablesOrProperties.cs b/Design/Rule0003DoNotUseObjectIDsInVariablesOrProperties.cs index 156fc2a7..7487a59d 100644 --- a/Design/Rule0003DoNotUseObjectIDsInVariablesOrProperties.cs +++ b/Design/Rule0003DoNotUseObjectIDsInVariablesOrProperties.cs @@ -99,27 +99,20 @@ private void CheckForObjectIDsInVariablesOrProperties(SyntaxNodeAnalysisContext ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0005VariableCasingShouldNotDifferFromDeclaration, ctx.Node.GetLocation(), new object[] { correctName, "" })); } } - try - { - IReturnValueSymbol returnValue = method.ReturnValueSymbol; - if (returnValue.ReturnType.NavTypeKind == NavTypeKind.DotNet) - { - return; - } + IReturnValueSymbol returnValue = method.ReturnValueSymbol; + if (returnValue == null || returnValue.ReturnType.NavTypeKind == NavTypeKind.DotNet) + return; - if (ctx.Node.GetLocation().SourceSpan.End == returnValue.DeclaringSyntaxReference.GetSyntax(CancellationToken.None).Span.End) - { - correctName = returnValue.ReturnType.Name; + if (ctx.Node.GetLocation().SourceSpan.End == returnValue.DeclaringSyntaxReference.GetSyntax(CancellationToken.None).Span.End) + { + correctName = returnValue.ReturnType.Name; - 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.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.GetLastToken().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, "" })); } - catch (System.NullReferenceException) - { } } } } diff --git a/Design/Rule0004LookupPageIdAndDrillDownPageId.cs b/Design/Rule0004LookupPageIdAndDrillDownPageId.cs index f7d7fbf4..21197200 100644 --- a/Design/Rule0004LookupPageIdAndDrillDownPageId.cs +++ b/Design/Rule0004LookupPageIdAndDrillDownPageId.cs @@ -7,7 +7,7 @@ namespace BusinessCentral.LinterCop.Design [DiagnosticAnalyzer] public class Rule0004LookupPageIdAndDrillDownPageId : DiagnosticAnalyzer { - public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(DiagnosticDescriptors.Rule0004LookupPageIdAndDrillDownPageId); + public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(DiagnosticDescriptors.Rule0004LookupPageIdAndDrillDownPageId, DiagnosticDescriptors.Rule0000ErrorInRule); public override void Initialize(AnalysisContext context) => context.RegisterSymbolAction(new Action(this.CheckForLookupPageIdAndDrillDownPageId), SymbolKind.Page); @@ -18,13 +18,13 @@ private void CheckForLookupPageIdAndDrillDownPageId(SymbolAnalysisContext contex IPageTypeSymbol pageTypeSymbol = (IPageTypeSymbol)context.Symbol; if (pageTypeSymbol.PageType != PageTypeKind.List || pageTypeSymbol.RelatedTable == null) return; if (pageTypeSymbol.RelatedTable.ContainingModule != context.Symbol.ContainingModule) return; - CheckTable(pageTypeSymbol.RelatedTable, ref context); + CheckTable(pageTypeSymbol.RelatedTable, context); } - private void CheckTable(ITableTypeSymbol table, ref SymbolAnalysisContext context) + private void CheckTable(ITableTypeSymbol table, SymbolAnalysisContext context) { if (table.IsObsoletePending || table.IsObsoleteRemoved) return; - if (!IsSymbolAccessible(table)) return; + if (!IsSymbolAccessible(table, context)) return; if (table.TableType == TableTypeKind.Temporary) return; bool exists = table.Properties.Where(e => e.PropertyKind == PropertyKind.DrillDownPageId || e.PropertyKind == PropertyKind.LookupPageId).Count() == 2; @@ -34,24 +34,24 @@ private void CheckTable(ITableTypeSymbol table, ref SymbolAnalysisContext contex Diagnostic.Create( DiagnosticDescriptors.Rule0004LookupPageIdAndDrillDownPageId, table.GetLocation(), - new object[] { GetDeclaration(table), table.Name, context.Symbol.Name })); + new object[] { GetDeclaration(table, context), table.Name, context.Symbol.Name })); } - private static string GetDeclaration(ISymbol symbol) - => symbol.Location.SourceTree.GetText(CancellationToken.None).GetSubText(symbol.DeclaringSyntaxReference.Span).ToString(); + private static string GetDeclaration(ISymbol symbol, SymbolAnalysisContext context) + => symbol.Location.SourceTree.GetText(context.CancellationToken).GetSubText(symbol.DeclaringSyntaxReference.Span).ToString(); - private static bool IsSymbolAccessible(ISymbol symbol) + private static bool IsSymbolAccessible(ISymbol symbol, SymbolAnalysisContext context) { try { - GetDeclaration(symbol); + GetDeclaration(symbol, context); return true; } catch (Exception) { + context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0000ErrorInRule, context.Symbol.GetLocation(), new Object[] { "Rule0004", "Exception", "at Line 47" })); return false; } } } - -} +} \ No newline at end of file diff --git a/Design/Rule0012DoNotUseObjectIdInSystemFunctions.cs b/Design/Rule0012DoNotUseObjectIdInSystemFunctions.cs index 9c0fb908..8b1fcf22 100644 --- a/Design/Rule0012DoNotUseObjectIdInSystemFunctions.cs +++ b/Design/Rule0012DoNotUseObjectIdInSystemFunctions.cs @@ -39,17 +39,12 @@ private void CheckForObjectIdsInFunctionInvocations(OperationAnalysisContext con if (context.ContainingSymbol.GetContainingObjectTypeSymbol().IsObsoletePending || context.ContainingSymbol.GetContainingObjectTypeSymbol().IsObsoleteRemoved) return; if (context.ContainingSymbol.IsObsoletePending || context.ContainingSymbol.IsObsoleteRemoved) return; IInvocationExpression operation = (IInvocationExpression)context.Operation; - RelevantFuntion CurrentFunction = null; - try - { - CurrentFunction = FunctionCallsWithIDParamaters.RelevantFunctions.First(o => (o.ObjectType.ToString().ToUpper() == operation.TargetMethod.ContainingSymbol.Name.ToUpper() && o.FunctionName == operation.TargetMethod.Name)); - } - catch (System.InvalidOperationException) - { } - SyntaxKind[] AllowedParameterKinds = { SyntaxKind.MemberAccessExpression, SyntaxKind.IdentifierName, SyntaxKind.InvocationExpression, SyntaxKind.QualifiedName }; + RelevantFuntion CurrentFunction = FunctionCallsWithIDParamaters.RelevantFunctions.FirstOrDefault(o => (o.ObjectType.ToString().ToUpper() == operation.TargetMethod.ContainingSymbol.Name.ToUpper() && o.FunctionName == operation.TargetMethod.Name)); + if (CurrentFunction == null) return; - if (CurrentFunction != null && operation.TargetMethod.Parameters.Length != 0 && !AllowedParameterKinds.Contains(operation.Arguments[0].Syntax.Kind) && (operation.Arguments[0].Syntax.ToString() != "0" || !CurrentFunction.ZeroIDAllowed)) + SyntaxKind[] AllowedParameterKinds = { SyntaxKind.MemberAccessExpression, SyntaxKind.IdentifierName, SyntaxKind.InvocationExpression, SyntaxKind.QualifiedName }; + if (operation.TargetMethod.Parameters.Length != 0 && !AllowedParameterKinds.Contains(operation.Arguments[0].Syntax.Kind) && (operation.Arguments[0].Syntax.ToString() != "0" || !CurrentFunction.ZeroIDAllowed)) { if (operation.TargetMethod.Parameters[0].ParameterType.NavTypeKind == NavTypeKind.Integer) { diff --git a/Design/Rule0016CheckForMissingCaptions.cs b/Design/Rule0016CheckForMissingCaptions.cs index f8ab434b..dbf252ac 100644 --- a/Design/Rule0016CheckForMissingCaptions.cs +++ b/Design/Rule0016CheckForMissingCaptions.cs @@ -11,6 +11,30 @@ class Rule0016CheckForMissingCaptions : DiagnosticAnalyzer { public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(DiagnosticDescriptors.Rule0016CheckForMissingCaptions); + private static readonly List PromotedGroupNames = new List + { + "category_new", + "category_process", + "category_report", + "category_category4", + "category_category5", + "category_category6", + "category_category7", + "category_category8", + "category_category9", + "category_category10", + "category_category11", + "category_category12", + "category_category13", + "category_category14", + "category_category15", + "category_category16", + "category_category17", + "category_category18", + "category_category19", + "category_category20", + }; + public override void Initialize(AnalysisContext context) => context.RegisterSymbolAction(new Action(this.CheckForMissingCaptions), SymbolKind.Page, @@ -30,7 +54,7 @@ private void CheckForMissingCaptions(SymbolAnalysisContext context) if (context.Symbol.Kind == SymbolKind.Control) { - var Control = ((IControlSymbol)context.Symbol); + var Control = (IControlSymbol)context.Symbol; switch (Control.ControlKind) { case ControlKind.Field: @@ -110,22 +134,20 @@ private void CheckForMissingCaptions(SymbolAnalysisContext context) private bool CaptionIsMissing(ISymbol Symbol, SymbolAnalysisContext context) { - try + if (Symbol.ContainingType?.Kind == SymbolKind.Table) { - if (Symbol.ContainingType.Kind == SymbolKind.Table) - { - if (((ITableTypeSymbol)Symbol.ContainingType).Id >= 2000000000) - return false; - if (((IFieldSymbol)Symbol).Id >= 2000000000) - return false; - } + if (((ITableTypeSymbol)Symbol.ContainingType).Id >= 2000000000) + return false; + if (((IFieldSymbol)Symbol).Id >= 2000000000) + return false; } - catch (NullReferenceException) - { } if (Symbol.GetEnumPropertyValue(PropertyKind.ShowAs) == ShowAsKind.SplitButton) return false; + if (SemanticFacts.IsSameName(Symbol.MostSpecificKind, "Group") && PromotedGroupNames.Contains(Symbol.Name.ToLowerInvariant())) + return false; + if (Symbol.GetBooleanPropertyValue(PropertyKind.ShowCaption) != false) if (Symbol.GetProperty(PropertyKind.Caption) == null && Symbol.GetProperty(PropertyKind.CaptionClass) == null) return true; diff --git a/README.md b/README.md index 5d709e7c..bbb51aab 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ Further note that you should have BcContainerHelper version 2.0.16 (or newer) in |[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| -|[LC0051](https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0050)|Do not assign a text to a target with smaller size.|Warning| +|[LC0051](https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0051)|Do not assign a text to a target with smaller size.|Warning| ## Configuration