Skip to content

fix(PC0021): match TransferFields relations case-insensitively for namespaces#370

Merged
Arthurvdv merged 1 commit into
release/v1.0.0from
fix/transferfields-case-insensitive-namespace
Jun 26, 2026
Merged

fix(PC0021): match TransferFields relations case-insensitively for namespaces#370
Arthurvdv merged 1 commit into
release/v1.0.0from
fix/transferfields-case-insensitive-namespace

Conversation

@Arthurvdv

Copy link
Copy Markdown
Member

Problem

TransferFieldsRelations.Matches compared the stored relation namespace and object name against the runtime-resolved values using StringComparer.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.EDocument vs Microsoft.eServices.EDocument).

When the stored and runtime casing differ, Matches returned false. On the table-extension path (AnalyzeTableExtensionTryFindBySource) this silently dropped the schema-compatibility diagnostic — a false negative.

Changes

  • TransferFieldsRelations.Matches: compare both namespace and object Name with SemanticFacts.IsSameName (repo convention; internally OrdinalIgnoreCase), 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.
  • New regression test TableExt_NamespaceCasingMismatch exercising 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 use SemanticFacts for all AL identifier comparisons, and the sibling file already does. Verified in the NAV SDK source that SemanticFacts.NameEqualityComparer is internally StringComparer.OrdinalIgnoreCase, so behaviour matches the doc's intent while staying convention-consistent and self-documenting. No culture-aware comparison introduced; Matches stays allocation-free; ObjectName shape and #if NETSTANDARD2_1 guards unchanged.

Validation

  • Regression test fails before the fix (no issue reported for PC0021) and passes after, proving it's genuine.
  • Full ALCops.PlatformCop.Test suite 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

…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>
@Arthurvdv Arthurvdv merged commit 6558cdc into release/v1.0.0 Jun 26, 2026
48 checks passed
@Arthurvdv Arthurvdv deleted the fix/transferfields-case-insensitive-namespace branch June 26, 2026 10:53
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