From 7ab27742afd59465a4a5e05adac612df1b39f2bd Mon Sep 17 00:00:00 2001 From: Arthur van de Vondervoort Date: Sun, 26 Nov 2023 19:38:15 +0100 Subject: [PATCH 1/2] Optimize performance --- ...e0028CodeNavigabilityOnEventSubscribers.cs | 19 +++++++++---------- .../Rule0031RecordInstanceIsolationLevel.cs | 13 +++++++------ ...0034ExtensiblePropertyShouldAlwaysBeSet.cs | 13 +++++++------ ...ule0035ExplicitSetAllowInCustomizations.cs | 6 +++--- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/Design/Rule0028CodeNavigabilityOnEventSubscribers.cs b/Design/Rule0028CodeNavigabilityOnEventSubscribers.cs index e713d91f..4164564a 100644 --- a/Design/Rule0028CodeNavigabilityOnEventSubscribers.cs +++ b/Design/Rule0028CodeNavigabilityOnEventSubscribers.cs @@ -15,21 +15,20 @@ public class Rule0028CodeNavigabilityOnEventSubscribers : DiagnosticAnalyzer private void CodeNavigabilityOnEventSubscribers(CodeBlockAnalysisContext context) { - // Support for using Identifiers instead of Literals in event subscribers is supported from runtime versions: '11.0' or greater. - var manifest = AppSourceCopConfigurationProvider.GetManifest(context.SemanticModel.Compilation); - if (manifest.Runtime < RuntimeVersion.Spring2023) 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 => value.GetIdentifierOrLiteralValue().ToUpper() == "EVENTSUBSCRIBER"); - foreach (var Syntax in SyntaxList) - { - if (Syntax.ArgumentList.Arguments[2].IsKind(SyntaxKind.LiteralAttributeArgument)) - context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0028CodeNavigabilityOnEventSubscribers, context.OwningSymbol.GetLocation())); - } + IEnumerable MemberAttributeSyntaxList = ((MethodDeclarationSyntax)context.CodeBlock).Attributes.Where(value => SemanticFacts.IsSameName(value.GetIdentifierOrLiteralValue(), "EventSubscriber")); + if (!MemberAttributeSyntaxList.Select(value => value.ArgumentList.Arguments[2]).Where(syntax => syntax.IsKind(SyntaxKind.LiteralAttributeArgument)).Any() && + !MemberAttributeSyntaxList.Select(value => value.ArgumentList.Arguments[3]).Where(syntax => syntax.IsKind(SyntaxKind.LiteralAttributeArgument)).Any()) return; + + // Support for using Identifiers instead of Literals in event subscribers is supported from runtime versions: '11.0' or greater. + var manifest = AppSourceCopConfigurationProvider.GetManifest(context.SemanticModel.Compilation); + if (manifest.Runtime < RuntimeVersion.Spring2023) return; + + context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0028CodeNavigabilityOnEventSubscribers, context.OwningSymbol.GetLocation())); } } } \ No newline at end of file diff --git a/Design/Rule0031RecordInstanceIsolationLevel.cs b/Design/Rule0031RecordInstanceIsolationLevel.cs index e18e0d88..9d2099e5 100644 --- a/Design/Rule0031RecordInstanceIsolationLevel.cs +++ b/Design/Rule0031RecordInstanceIsolationLevel.cs @@ -14,18 +14,19 @@ 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 (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; + + // ReadIsolation is supported from runtime versions 11.0 or greater. + var manifest = AppSourceCopConfigurationProvider.GetManifest(ctx.Compilation); + if (manifest.Runtime < RuntimeVersion.Spring2023) return; + + ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0031RecordInstanceIsolationLevel, ctx.Operation.Syntax.GetLocation())); } } } \ No newline at end of file diff --git a/Design/Rule0034ExtensiblePropertyShouldAlwaysBeSet.cs b/Design/Rule0034ExtensiblePropertyShouldAlwaysBeSet.cs index f0baf03b..81253a06 100644 --- a/Design/Rule0034ExtensiblePropertyShouldAlwaysBeSet.cs +++ b/Design/Rule0034ExtensiblePropertyShouldAlwaysBeSet.cs @@ -20,17 +20,18 @@ 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 (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; + + // 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; + + ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0034ExtensiblePropertyShouldAlwaysBeSet, ctx.Symbol.GetLocation(), new object[] { Accessibility.Public.ToString().ToLower() })); } } } \ No newline at end of file diff --git a/Design/Rule0035ExplicitSetAllowInCustomizations.cs b/Design/Rule0035ExplicitSetAllowInCustomizations.cs index 102bae2c..7beabc37 100644 --- a/Design/Rule0035ExplicitSetAllowInCustomizations.cs +++ b/Design/Rule0035ExplicitSetAllowInCustomizations.cs @@ -20,13 +20,13 @@ public override void Initialize(AnalysisContext context) private void AnalyzeAllowInCustomization(SymbolAnalysisContext ctx) { + if (ctx.Symbol.IsObsoletePending || ctx.Symbol.IsObsoleteRemoved) return; + if (ctx.Symbol.GetContainingObjectTypeSymbol().IsObsoletePending || ctx.Symbol.GetContainingObjectTypeSymbol().IsObsoleteRemoved) return; + // The AllowInCustomizations property is supported from runtime versions 12.0 or greater. var manifest = AppSourceCopConfigurationProvider.GetManifest(ctx.Compilation); if (manifest.Runtime < RuntimeVersion.Fall2023) return; - if (ctx.Symbol.IsObsoletePending || ctx.Symbol.IsObsoleteRemoved) return; - if (ctx.Symbol.GetContainingObjectTypeSymbol().IsObsoletePending || ctx.Symbol.GetContainingObjectTypeSymbol().IsObsoleteRemoved) return; - ICollection tableFields = GetTableFields(ctx.Symbol).Where(x => x.Id > 0 && x.Id < 2000000000) .Where(x => x.GetProperty(PropertyKind.AllowInCustomizations) is null) .ToList(); From ea1018ca6f94827e963cb0b6c668ad4c6df80d1d Mon Sep 17 00:00:00 2001 From: Arthur van de Vondervoort Date: Sun, 26 Nov 2023 20:49:58 +0100 Subject: [PATCH 2/2] Extend rule0026 with guidelines for tooltip text --- Design/Rule0026ToolTipPunctuation.cs | 18 +++++++++++---- LinterCop.ruleset.json | 2 +- LinterCopAnalyzers.Generated.cs | 5 ++++- LinterCopAnalyzers.resx | 33 +++++++++++++++++++++++++--- README.md | 2 +- 5 files changed, 50 insertions(+), 10 deletions(-) diff --git a/Design/Rule0026ToolTipPunctuation.cs b/Design/Rule0026ToolTipPunctuation.cs index 13b9a4fc..37f33867 100644 --- a/Design/Rule0026ToolTipPunctuation.cs +++ b/Design/Rule0026ToolTipPunctuation.cs @@ -1,6 +1,7 @@ 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 @@ -8,7 +9,7 @@ namespace BusinessCentral.LinterCop.Design [DiagnosticAnalyzer] public class Rule0026ToolTipPunctuation : DiagnosticAnalyzer { - public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(DiagnosticDescriptors.Rule0026ToolTipPunctuation); + public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(DiagnosticDescriptors.Rule0026ToolTipMustEndWithDot, DiagnosticDescriptors.Rule0026ToolTipMaximumLength, DiagnosticDescriptors.Rule0026ToolTipDoNotUseLineBreaks, DiagnosticDescriptors.Rule0026ToolTipShouldStartWithSpecifies); public override void Initialize(AnalysisContext context) => context.RegisterSyntaxNodeAction(new Action(this.AnalyzeToolTipPunctuation), SyntaxKind.PageField, SyntaxKind.PageAction); @@ -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 (tooltipLabel.Value.ToString().Count() > 200) + ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0026ToolTipMaximumLength, tooltipProperty.GetLocation())); + + if (tooltipLabel.Value.ToString().Contains("\\")) + ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0026ToolTipDoNotUseLineBreaks, tooltipProperty.GetLocation())); + + if (((IControlSymbol)ctx.ContainingSymbol).ControlKind == ControlKind.Field) + if (!tooltipLabel.Value.ToString().StartsWith("Specifies")) + ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0026ToolTipShouldStartWithSpecifies, tooltipProperty.GetLocation())); } } } \ No newline at end of file diff --git a/LinterCop.ruleset.json b/LinterCop.ruleset.json index 40dbc7ea..22e28e69 100644 --- a/LinterCop.ruleset.json +++ b/LinterCop.ruleset.json @@ -130,7 +130,7 @@ { "id": "LC0026", "action": "Info", - "justification": "ToolTip must end with a dot." + "justification": "Guidelines for ToolTip text." }, { "id": "LC0027", diff --git a/LinterCopAnalyzers.Generated.cs b/LinterCopAnalyzers.Generated.cs index 27731d88..db3f5650 100644 --- a/LinterCopAnalyzers.Generated.cs +++ b/LinterCopAnalyzers.Generated.cs @@ -32,7 +32,10 @@ public static class DiagnosticDescriptors public static readonly DiagnosticDescriptor Rule0023AlwaysSpecifyFieldgroups = new DiagnosticDescriptor(LinterCopAnalyzers.AnalyzerPrefix + "0023", (LocalizableString)new LocalizableResourceString("Rule0023AlwaysSpecifyFieldgroups", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), (LocalizableString)new LocalizableResourceString("Rule0023AlwaysSpecifyFieldgroups", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "Design", DiagnosticSeverity.Info, true, (LocalizableString)new LocalizableResourceString("Rule0023AlwaysSpecifyFieldgroups", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0023"); public static readonly DiagnosticDescriptor Rule0024SemicolonAfterProcedureDeclaration = new DiagnosticDescriptor(LinterCopAnalyzers.AnalyzerPrefix + "0024", (LocalizableString)new LocalizableResourceString("Rule0024SemicolonAfterProcedureDeclarationTitle", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), (LocalizableString)new LocalizableResourceString("Rule0024SemicolonAfterProcedureDeclarationFormat", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "Design", DiagnosticSeverity.Info, true, (LocalizableString)new LocalizableResourceString("Rule0024SemicolonAfterProcedureDeclarationDescription", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0024"); public static readonly DiagnosticDescriptor Rule0025InternalProcedureModifier = new DiagnosticDescriptor(LinterCopAnalyzers.AnalyzerPrefix + "0025", (LocalizableString)new LocalizableResourceString("Rule0025InternalProcedureModifierTitle", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), (LocalizableString)new LocalizableResourceString("Rule0025InternalProcedureModifierFormat", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "Design", DiagnosticSeverity.Hidden, true, (LocalizableString)new LocalizableResourceString("Rule0025InternalProcedureModifierDescription", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0025"); - public static readonly DiagnosticDescriptor Rule0026ToolTipPunctuation = new DiagnosticDescriptor(LinterCopAnalyzers.AnalyzerPrefix + "0026", (LocalizableString)new LocalizableResourceString("Rule0026ToolTipPunctuationTitle", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), (LocalizableString)new LocalizableResourceString("Rule0026ToolTipPunctuationFormat", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "Design", DiagnosticSeverity.Info, true, (LocalizableString)new LocalizableResourceString("Rule0026ToolTipPunctuationDescription", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0026"); + public static readonly DiagnosticDescriptor Rule0026ToolTipMustEndWithDot = new DiagnosticDescriptor(LinterCopAnalyzers.AnalyzerPrefix + "0026", (LocalizableString)new LocalizableResourceString("Rule0026ToolTipMustEndWithDotTitle", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), (LocalizableString)new LocalizableResourceString("Rule0026ToolTipMustEndWithDotFormat", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "Design", DiagnosticSeverity.Info, true, (LocalizableString)new LocalizableResourceString("Rule0026ToolTipMustEndWithDotDescription", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0026"); + public static readonly DiagnosticDescriptor Rule0026ToolTipMaximumLength = new DiagnosticDescriptor(LinterCopAnalyzers.AnalyzerPrefix + "0026", (LocalizableString)new LocalizableResourceString("Rule0026ToolTipMaximumLengthTitle", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), (LocalizableString)new LocalizableResourceString("Rule0026ToolTipMaximumLengthFormat", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "Design", DiagnosticSeverity.Info, true, (LocalizableString)new LocalizableResourceString("Rule0026ToolTipMaximumLengthDescription", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0026"); + public static readonly DiagnosticDescriptor Rule0026ToolTipDoNotUseLineBreaks = new DiagnosticDescriptor(LinterCopAnalyzers.AnalyzerPrefix + "0026", (LocalizableString)new LocalizableResourceString("Rule0026ToolTipDoNotUseLineBreaksTitle", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), (LocalizableString)new LocalizableResourceString("Rule0026ToolTipDoNotUseLineBreaksFormat", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "Design", DiagnosticSeverity.Info, true, (LocalizableString)new LocalizableResourceString("Rule0026ToolTipDoNotUseLineBreaksDescription", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0026"); + public static readonly DiagnosticDescriptor Rule0026ToolTipShouldStartWithSpecifies = new DiagnosticDescriptor(LinterCopAnalyzers.AnalyzerPrefix + "0026", (LocalizableString)new LocalizableResourceString("Rule0026ToolTipShouldStartWithSpecifiesTitle", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), (LocalizableString)new LocalizableResourceString("Rule0026ToolTipShouldStartWithSpecifiesFormat", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "Design", DiagnosticSeverity.Info, true, (LocalizableString)new LocalizableResourceString("Rule0026ToolTipShouldStartWithSpecifiesDescription", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0026"); public static readonly DiagnosticDescriptor Rule0027RunPageImplementPageManagement = new DiagnosticDescriptor(LinterCopAnalyzers.AnalyzerPrefix + "0027", (LocalizableString)new LocalizableResourceString("Rule0027RunPageImplementPageManagement", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), (LocalizableString)new LocalizableResourceString("Rule0027RunPageImplementPageManagement", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "Design", DiagnosticSeverity.Info, true, (LocalizableString)new LocalizableResourceString("Rule0027RunPageImplementPageManagement", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0027"); public static readonly DiagnosticDescriptor Rule0028CodeNavigabilityOnEventSubscribers = new DiagnosticDescriptor(LinterCopAnalyzers.AnalyzerPrefix + "0028", (LocalizableString)new LocalizableResourceString("Rule0028CodeNavigabilityOnEventSubscribersTitle", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), (LocalizableString)new LocalizableResourceString("Rule0028CodeNavigabilityOnEventSubscribersFormat", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "Design", DiagnosticSeverity.Info, true, (LocalizableString)new LocalizableResourceString("Rule0028CodeNavigabilityOnEventSubscribersDescription", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0028"); public static readonly DiagnosticDescriptor Rule0029CompareDateTimeThroughCodeunit = new DiagnosticDescriptor(LinterCopAnalyzers.AnalyzerPrefix + "0029", (LocalizableString)new LocalizableResourceString("Rule0029CompareDateTimeThroughCodeunitTitle", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), (LocalizableString)new LocalizableResourceString("Rule0029CompareDateTimeThroughCodeunitFormat", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "Design", DiagnosticSeverity.Info, true, (LocalizableString)new LocalizableResourceString("Rule0029CompareDateTimeThroughCodeunitDescription", LinterCopAnalyzers.ResourceManager, typeof(LinterCopAnalyzers)), "https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0029"); diff --git a/LinterCopAnalyzers.resx b/LinterCopAnalyzers.resx index 20cac5c9..5e214cf0 100644 --- a/LinterCopAnalyzers.resx +++ b/LinterCopAnalyzers.resx @@ -336,15 +336,42 @@ Procedure must be either local or internal. - + ToolTip must end with a dot. - + ToolTip must end with a dot. - + ToolTip must end with a dot. + + Try to not exceed 200 characters including spaces. + + + Try to not exceed 200 characters including spaces. + + + Try to not exceed 200 characters including spaces. + + + Do not use line breaks in ToolTip. + + + Do not use line breaks in ToolTip. + + + Do not use line breaks in ToolTip. + + + For fields specifically, the ToolTip must start with the verb "Specifies". + + + For fields specifically, the ToolTip must start with the verb "Specifies". + + + For fields specifically, the ToolTip must start with the verb "Specifies". + Utilize the "Page Management" codeunit for launching page. diff --git a/README.md b/README.md index aae368df..e1c3ec81 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ Further note that you should have BcContainerHelper version 2.0.16 (or newer) in |[LC0023](https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0023)|Always provide fieldsgroups `DropDown` and `Brick` on tables.|Info| |[LC0024](https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0024)|Procedure declaration should not end with semicolon.|Info| |[LC0025](https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0025)|Procedure must be either local or internal.|Info| -|[LC0026](https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0026)|ToolTip must end with a dot.|Info| +|[LC0026](https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0026)|Guidelines for ToolTip text.|Info| |[LC0027](https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0027)|Utilize the `Page Management` codeunit for launching page.|Info| |[LC0028](https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0028)|Event subscriber arguments now use identifier syntax instead of string literals.|Info| |[LC0029](https://github.com/StefanMaron/BusinessCentral.LinterCop/wiki/LC0029)|Use `CompareDateTime` method in `Type Helper` codeunit for DateTime variable comparisons.|Info|