fix(PC0021): match TransferFields relations case-insensitively for namespaces#370
Merged
Arthurvdv merged 1 commit intoJun 26, 2026
Conversation
…mespaces AL namespaces and object identifiers are case-insensitive, but the runtime-resolved namespace casing (symbol.ContainingNamespace.QualifiedName) is not stable across compilations. The same logical namespace ships with different literal casing across Microsoft apps (e.g. Microsoft.EServices.EDocument vs Microsoft.eServices.EDocument). TransferFieldsRelations.Matches compared the stored namespace and object name with StringComparer.Ordinal, so a casing difference made the relation lookup fail. On the table-extension path (AnalyzeTableExtension -> TryFindBySource) this silently dropped the schema-compatibility diagnostic (false negative). - Matches: compare both namespace and Name with SemanticFacts.IsSameName (repo convention; internally OrdinalIgnoreCase), keeping the empty-namespace fallback. - TransferFieldsSchemaCompatibility: same fix for the table-extension name lookups. - Add regression test TableExt_NamespaceCasingMismatch proving the diagnostic fires regardless of namespace casing (fails before the fix, passes after). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.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.
Problem
TransferFieldsRelations.Matchescompared the stored relation namespace and object name against the runtime-resolved values usingStringComparer.Ordinal(case-sensitive). AL namespaces and object identifiers are case-insensitive, and the runtime-resolved namespace casing (symbol.ContainingNamespace.QualifiedName) is not stable across compilations: the same logical namespace ships with different literal casing across Microsoft apps (e.g.Microsoft.EServices.EDocumentvsMicrosoft.eServices.EDocument).When the stored and runtime casing differ,
Matchesreturnedfalse. On the table-extension path (AnalyzeTableExtension→TryFindBySource) this silently dropped the schema-compatibility diagnostic — a false negative.Changes
TransferFieldsRelations.Matches: compare both namespace and objectNamewithSemanticFacts.IsSameName(repo convention; internallyOrdinalIgnoreCase), keeping the empty-namespace backwards-compatibility branch unchanged.TransferFieldsSchemaCompatibility(lines 223/228): same fix for the table-extension name lookups, which had the same latent ordinal bug.TableExt_NamespaceCasingMismatchexercising the table-extension false-negative with a namespace declared in different literal casing than the stored relation.Design decision
The Fix1 doc recommended
StringComparer.OrdinalIgnoreCase. This repo's convention (CLAUDE.md) is to useSemanticFactsfor all AL identifier comparisons, and the sibling file already does. Verified in the NAV SDK source thatSemanticFacts.NameEqualityCompareris internallyStringComparer.OrdinalIgnoreCase, so behaviour matches the doc's intent while staying convention-consistent and self-documenting. No culture-aware comparison introduced;Matchesstays allocation-free;ObjectNameshape and#if NETSTANDARD2_1guards unchanged.Validation
no issue reported for PC0021) and passes after, proving it's genuine.ALCops.PlatformCop.Testsuite green: 457/457.Instruction files
No existing TransferFields rule instruction file; per the maintenance policy a small bug fix does not require creating a new one. Rationale is captured in inline code comments.
Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com