fix(LC0031): convert bare LockTable() to bare ReadIsolation in the code fix - #547
Merged
Merged
Conversation
Add the full receiver-form fixture set (named variable, Rec, bare, this, tableextension, page, TableNo OnRun, namespaced, RecordRef, LockTable with arguments) plus NoDiagnostic fixtures for the obsolete gate and both ReadIsolation forms. HasFix/BareSelfInTrigger and HasFix/BareSelfInTableExtension are expected to fail at this commit: the code fix returns the unchanged document when the invocation expression is not a MemberAccessExpression. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…de fix The code fix returned the unchanged document when the invocation expression was not a MemberAccessExpressionSyntax, which is the case for bare LockTable() inside tables and tableextensions. Add the IdentifierNameSyntax path so bare LockTable() becomes bare ReadIsolation(IsolationLevel::UpdLock). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A bare LockTable() on a page has an IdentifierNameSyntax expression like the table form, so the fix must produce a bare ReadIsolation there too. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Add the rule doc: why self LockTable() in table triggers stays reported, the per-form verdict table for analyzer and code fix, the SDK facts the decision rests on, and the code fix decisions. Extend the receiver-forms regression row with the code fix flavour of the bare-self gap. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…nsion fixtures A fresh SyntaxFactory identifier carries no trivia, so the bare form lost the indentation and comments attached to the LockTable token; the replacement now copies the trivia of the original invocation. The receiver switch is typed on CodeExpressionSyntax so both forms share one construction path. Tableextension fixtures are gated on SDK 13.0: older compilers report AL0334 for a tableextension whose target is declared in the same module. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.
Summary
Issue #530 reports LC0031 firing on bare
LockTable()inside Base App table triggers (OnInsert,OnDelete) and notes that the code action "does not update anything here".Verdict: not a false positive. The evidence:
Rec.,this.and named-variable receivers to oneTableClassTypeSymbolbuilt-in with no self-receiver special case;LockTablecarries no deprecation (unlikeFindSet(ForUpdate, UpdateKey)in the same class).LockTable()calls went from 80 to 78 (two removals, zero additions). Business Foundation, E-Document Core, Subscription Billing and Excise Taxes contain noLockTableat all.OnInsert, new code usesReadIsolationon a second instance (Customer.Table.al,SustESGStandard.Table.al).The real defect is the code fix returning the unchanged document on the bare form. The analyzer is unchanged.
What changed
RecordInstanceIsolationLevel.cs): add theIdentifierNameSyntaxpath so bareLockTable()becomes bareReadIsolation(IsolationLevel::UpdLock). TheMemberAccessExpressionSyntaxpath (named variable,Rec.,this., RecordRef) keeps its receiver; any other shape still returns the document untouched. The replacement copies the trivia of the original invocation, because a freshSyntaxFactoryidentifier would drop the indentation and comments of a bare call (found in review, pinned byHasFix/BareSelfWithLeadingComment).ReadIsolationforms..claude/rules/diagnostics/lc0031-record-instance-isolation-level.mdwith the trigger decision, the per-form verdicts, SDK facts and code fix decisions; the receiver-forms regression row now covers the code fix flavour of the gap.Receiver-form verdicts
Rec.(table, tableextension, page,TableNoOnRun)TableNoOnRunthis.(table, tableextension)RecordRefvariableLockTable(true)(arguments)Test plan
HasFix/BareSelfInTriggerfailed with an unchanged-document diff before the fixthisfixtures on runtime 14.0HasFix/BareSelfWithLeadingCommentfails withoutWithTriviaFromand passes with itnetstandard2.1;net8.0;net10.0): 0 warnings, 0 errorsdotnet format ALCops.sln --verify-no-changescleanValidate-Rules.ps1: 54 rules files pass/code-review high(Sonnet): trivia loss on the bare form fixed; doc verdict table corrected; the suggestedTryGetMethodCallreuse was tried and reverted because the helper returns the baseExpressionSyntax, which the factory methods rejectCloses #530
Related: #545
Docs companion PRs: ALCops/alcops.dev#185 (merged) and ALCops/alcops.dev#186 (tri-state version wording)
🤖 Generated with Claude Code