fix(LC0092): skip platform-named action areas, system actions and layout areas - #541
Merged
Merged
Conversation
…out areas Every node inside an actions block is one SymbolKind.Action symbol, and every node inside a layout block is one SymbolKind.Control symbol, so the rule checked area, group, actionref, separator and systemaction names against the Action target and layout areas against the Control target. Those names are picked by the platform, not by the developer: an action area name comes from ActionAreaKind, a system action name from SystemActionKind, a layout area name from the page layout, and a group named Category_Process binds the group to that promoted-category slot. AnalyzeAction and AnalyzeControl now read IActionSymbol.ActionKind and IControlSymbol.ControlKind and skip those kinds. Ordinary groups, separators, action references, custom and file-upload actions stay checked under Action, and every other control kind under Control, so no new naming target and no settings-schema change is needed. EnumProvider gains ActionKind.SystemAction, resolved through the string overload with an out-of-range sentinel because the member is absent from the oldest supported SDK and default(ActionKind) is Area. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ConfigurationDialog SDKs 14.0 through 16.2.28 reject PageType = ConfigurationDialog as a feature under development (AL0574), so the fixture only compiles from 16.2.31, where the compiler downgrades that to a public-preview warning. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…inel Both enums have a dispatchable zero member (Area), so a member absent from the loaded SDK fell back to it and made every comparison against an action or layout area true. Route every member of both nested classes through a Parse helper with an out-of-range Unresolved sentinel, the way SymbolKind already does. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
AC0011 kept a hand-lowercased copy of SyntaxFacts.PredefinedActionCategoryNames and lowercased every name it tested, while LC0092 queried the SDK set directly. Both now call IActionSymbol.IsPredefinedPromotedCategoryGroup(), which wraps the SDK's own case-insensitive set, so the two cops cannot drift apart. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The 12.1 and 14.0 claims about systemaction and the ConfigurationDialog page type had no evidence behind them; the availability tables only record absent at 12.0 and present by 16.0. Also removes a deliberate non-report bullet that restated the design-decision row and listed what the rule checks, not why. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Both custom-settings test methods built the same MemoryFileSystem fixture inline; CreateFixtureWithSettings mirrors the helper the sibling EventSubscriberNamingPattern tests already use. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #537
Root cause
Every node inside an
actions { }block is a singleSymbolKind.Actionsymbol;IActionSymbol.ActionKindis the only thing that tellsareaapart fromgroup,action,separator,actionref,customaction,systemactionandfileuploadaction.SymbolKind.Controlis shaped the same way, withIControlSymbol.ControlKindseparating the layoutareafrom groups, fields and parts.AnalyzeActionandAnalyzeControlnever read those kinds, so a customNamingPatterns.Actionpattern such asact[A-Za-z0-9]was applied toarea(Processing)— a name the platform fixes — and theControlpattern toarea(Content). With the built-in defaults the same bug fires whenever an area is written lowercase (area(processing)), because^[A-Z]fails.Change
AnalyzeActionnow skips:ActionKind.Area— the name selects anActionAreaKindmember.ActionKind.SystemAction— the name selects aSystemActionKindmember.ActionKind.Groupwhose name is a predefined promoted category (Category_New,Category_Process,Category_Report,Category_Category4..Category_Category20) — the name binds the group to that platform category slot. This is the same skip AC0011 already applies; the names come fromSyntaxFacts.PromotedCategoriesSynthesizedSymbolNames, which the SDK builds withSemanticFacts.NameEqualityComparer.AnalyzeControlskipsControlKind.Area.Everything else stays as it was: ordinary groups, separators, action references, custom and file-upload actions remain checked under
Action, and every control kind other than the layout area underControl. No new naming targets, soalcops.jsonandalcops.schema.jsonare unchanged.EnumProvider.ActionKindgainsSystemAction. The member is absent from the oldest supported SDK, so it is resolved through the string overload with an explicit out-of-range sentinel —default(ActionKind)isArea, and falling back to it would make every action area read as a system action on the netstandard2.1 build.Tests
New fixtures under
src/ALCops.LinterCop.Test/Rules/NamingPattern/, all of which failed before the analyzer change:NoDiagnostic/ActionAreaLowerCase.alarea(processing)is not flagged by the default patternNoDiagnostic/ControlAreaLowerCase.alarea(content)is not flagged by the default patternNoDiagnostic/ActionAreaCustomPattern.alalcops.jsonNoDiagnostic/ControlAreaCustomPattern.alControlpatternNoDiagnostic/PromotedCategoryGroupCustomPattern.alarea(Promoted) { group(Category_Process) }NoDiagnostic/SystemActionCustomPattern.alsystemaction(OK)on aConfigurationDialogpage (gated at SDK 16.2.31: earlier SDKs reject the page type as a feature under development, AL0574)HasDiagnostic/ActionGroupCustomPattern.alThe custom-settings fixtures share one
alcops.jsonthat carries the issue'sActionpattern, aControlpattern and the pre-existingEnumValuepattern.Verification
dotnet test src/ALCops.LinterCop.Test/— 359 passed, 2 skipped, 0 failed.dotnet build ALCops.sln— succeeded, 0 errors.dotnet format ALCops.sln --verify-no-changes— clean.dotnet build src/ALCops.Commonandsrc/ALCops.LinterCopwith-c Release -p:ContinuousIntegrationBuild=true—netstandard2.1,net8.0andnet10.0all succeed with 0 warnings.pwsh .claude/scripts/Validate-Rules.ps1— OK.Documentation for alcops.dev: ALCops/alcops.dev#181
🤖 Generated with Claude Code