Skip to content

feat: add LC0098 - Event subscriber name does not match the configured template#135

Open
MODUSCarstenScholling wants to merge 3 commits into
ALCops:mainfrom
MODUSCarstenScholling:dev-cs-new-subscriber-naming-template
Open

feat: add LC0098 - Event subscriber name does not match the configured template#135
MODUSCarstenScholling wants to merge 3 commits into
ALCops:mainfrom
MODUSCarstenScholling:dev-cs-new-subscriber-naming-template

Conversation

@MODUSCarstenScholling

Copy link
Copy Markdown
Contributor

feat: add LC0098 - Event subscriber name does not match the configured template

Adds LinterCop rule LC0098 EventSubscriberNamingPattern with CodeFix (BatchFixer FixAll).
The rule reports when an event subscriber procedure name does not match the identifier derived from its [EventSubscriber] attribute using one configurable template.

Default template:

{Event Source}_{Event Name}[_{Element Name}]

This default matches the AL Language extension Find Event output verbatim (raw source and element names, quoted when required). Teams already using the tooling default get zero-config alignment. Severity is Info, category Naming.

Template syntax

  • Token placeholders support source object name, event name, and element name across five styles: raw, PascalCase, camelCase, snake_case, kebab-case.
  • Raw placeholders emit values verbatim with no splitting or casing transform.
  • Non-raw placeholders use shared word splitting and rendering in ALCops.Common.
  • Optional groups in brackets are emitted only when all inner token placeholders are non-empty.
  • Unknown brace sequences are emitted verbatim; new placeholders can be added via the parser placeholder map without grammar changes.

Acronym-aware rendering

For non-raw styles, rendering now produces an accepted-name set:

  • Preferred name is always first and follows original casing wins.
  • Additional accepted variants are optionally added when KnownAcronyms contains a differently cased entry for an uppercase-carrying source word with the same case-insensitive key.
  • A diagnostic is reported only when the method name matches none of the accepted variants (ordinal comparison).
  • The CodeFix always suggests the preferred name.

Per-word rules:

  • ID (any casing) becomes Id.
  • Two-letter all-uppercase words stay uppercase.
  • Words containing uppercase preserve original casing shape (first letter normalized to upper as needed).
  • All-lowercase registered words use registry canonical casing.
  • All-lowercase unregistered words use first-upper fallback.

…d template

Adds LinterCop rule LC0098 EventSubscriberNamingPattern with CodeFix
(BatchFixer FixAll). Reports when an event subscriber procedure name does
not match the identifier derived from its [EventSubscriber] attribute via
a single configurable template.

Default template: {Event Source}_{EventName}[_{Element Name}]

This produces exactly the identifier the AL Language extension's "Find
Event" feature generates verbatim (raw source and element names, quoted
when they contain characters that require AL identifier quoting). Teams
that already accept the tooling default satisfy the rule with zero
configuration. Severity Info, category Naming.

Template syntax
---------------
* Token placeholders address three tokens (source object name, event
  name, element name) and five output styles:
    Raw            {Event Source} / {Event Name} / {Element Name}
    PascalCase     {EventSource}  / {EventName}  / {ElementName}
    camelCase      {eventSource}  / {eventName}  / {elementName}
    snake_case     {event_source} / {event_name} / {element_name}
    kebab-case     {event-source} / {event-name} / {element-name}
  Raw placeholders emit the token verbatim (no word splitting, no case
  transform). Non-raw placeholders route through the shared word
  splitter and case-style renderer in ALCops.Common.
* Optional groups [...] are emitted only when every token placeholder
  inside resolves to a non-empty value. Handles the common case where
  the element name is absent without leaving orphan separators.
* Unknown {...} sequences are passed through verbatim; adding new tokens
  (e.g. {ObjectType}, {ObjectId}) is a forward-compatible dictionary
  entry in TemplateParser.KnownPlaceholders — no grammar change.

Acronym-aware canonical rendering
---------------------------------
For non-raw styles, each word is rendered to exactly one canonical
form. The renderer follows an "original casing wins" rule: as long as
the source word carries any uppercase character, its casing is
preserved and the acronym registry is not consulted. Only all-lowercase
source words fall back to the registry to recover a canonical casing.

* ID (any casing)                              -> Id
* Two-letter all-uppercase word                -> kept uppercase
                                                  (IOLog, not IoLog)
* Word contains any uppercase character        -> EnsureUpperFirst
  (VAT, Sales, Http, XYZ)                        (registry NOT consulted;
                                                  original casing wins)
* All-lowercase word, registered acronym       -> canonical casing from
  (vat, odata, acme)                             registry (VAT, OData, Acme)
* All-lowercase word, not registered           -> first-upper, remainder
  (amount, header)                               as-is (Amount, Header)

The comparison is byte-for-byte ordinal, so exactly one spelling per
subscriber is accepted; the CodeFix always suggests that canonical name.

Configuration
-------------
alcops.json:
  "SubscriberNameTemplate": "<template>"   default: null (built-in)
  "KnownAcronyms": ["Acme", "MyCo", ...]   merged into built-in list

User acronym entries are merged with the built-in defaults and take
precedence on identical case-insensitive keys. Entries only affect
all-lowercase source words: KnownAcronyms cannot re-cast Microsoft-
or partner-owned identifiers that already carry an uppercase signal
(field "VAT Amount" stays VATAmount regardless of a "Vat" entry;
field "vat amount" becomes VATAmount when VAT is registered and
VatAmount when it is not).
Document that original casing remains preferred, KnownAcronyms can add accepted variants for uppercase source words, and include LCY/Lcy examples plus rejection of third variants.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant