Skip to content

SA1200: Treat extern alias directives like using directives - #4313

Merged
AArnott merged 3 commits into
masterfrom
aarnott-sa1200-extern-alias-directives
Oct 16, 2026
Merged

AArnott merged 3 commits into
masterfrom
aarnott-sa1200-extern-alias-directives

Conversation

@AArnott

@AArnott AArnott commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

SA1200 currently ignores extern alias directives even though their placement follows the same inside/outside-namespace setting as using directives. This leaves misplaced aliases unreported and means the placement code fix cannot move them.

This change reports and moves extern aliases with the corresponding using directives for block and file-scoped namespaces, preserving comments. Aliases referenced by a global using remain at compilation-unit scope so the global using still resolves. Documentation is updated in English and the existing Czech, Russian, and Chinese translations.

Tests reproduce the missing diagnostics on the base revision and cover both placement settings, code-fix output, file-scoped namespaces, and global-using aliases. Validation: analyzer build with zero warnings; SA1200 suites pass on C# 6 (45 tests) and C# 15 (77 tests). The analyzer adds syntax checks for extern aliases and scans using directives only when an extern alias is present; the additional analysis is limited to files containing these constructs.

Fixes #1931

Treat extern alias directives like using directives for placement diagnostics and code fixes, preserving aliases required by global usings.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@AArnott
AArnott marked this pull request as ready for review October 16, 2026 00:02
Copilot AI balanced review requested due to automatic review settings October 16, 2026 00:02

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved relocation errors can break compilation or throw, and alias detection can report valid placements incorrectly.

5 open findings
What changed in this PR

Extends SA1200 and its shared code fix to treat extern alias directives like using directives, addressing #1931.

Changes:

  • Adds extern-alias placement diagnostics and relocation.
  • Adds block/file-scoped namespace and global-using tests.
  • Updates English and localized rule documentation.
File Description
test/​StyleCop.Analyzers.Test/​OrderingRules/​SA1200UnitTests.cs Tests inward relocation and comments.
test/​StyleCop.Analyzers.Test/​OrderingRules/​SA1200OutsideNamespaceUnitTests.cs Tests outward relocation and comments.
test/​StyleCop.Analyzers.Test.CSharp10/​OrderingRules/​SA1200OutsideNamespaceCSharp10UnitTests.cs Tests outward file-scoped relocation.
test/​StyleCop.Analyzers.Test.CSharp10/​OrderingRules/​SA1200CSharp10UnitTests.cs Tests file-scoped placement and global-using dependencies.
src/​StyleCop.Analyzers/​OrderingRules/​SA1200UsingDirectivesMustBePlacedCorrectly.cs Reports misplaced extern aliases.
src/​StyleCop.Analyzers/​Helpers/​UsingDirectiveSyntaxHelpers.cs Detects global-using alias references.
src/​StyleCop.Analyzers.CodeFixes/​OrderingRules/​UsingCodeFixProvider.cs Moves and formats extern aliases.
documentation/​zh-cn/​SA1200.md Updates Chinese documentation.
documentation/​SA1200.md Documents extern-alias placement.
documentation/​ru-ru/​SA1200.md Updates Russian documentation.
documentation/​cs-cz/​SA1200.md Updates Czech documentation.

🧠 Review effort: Balanced


💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@codecov

codecov Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.99538% with 26 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.62%. Comparing base (9869738) to head (e3d5d97).
⚠️ Report is 5 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4313      +/-   ##
==========================================
- Coverage   97.63%   97.62%   -0.02%     
==========================================
  Files        1308     1313       +5     
  Lines      142748   143357     +609     
  Branches     4756     4801      +45     
==========================================
+ Hits       139377   139955     +578     
- Misses       2146     2162      +16     
- Partials     1225     1240      +15     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@AArnott
AArnott marked this pull request as draft October 16, 2026 00:27
AArnott and others added 2 commits October 15, 2026 18:27
Preserve extern alias scope when applying SA1200 fixes, and avoid relocating aliases across directive spans or into collisions. Cover no-namespace handling and C# 12 global alias targets.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Verify duplicate extern aliases and conditional aliases suppress unsafe placement fixes for both inside- and outside-namespace settings.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@AArnott
AArnott marked this pull request as ready for review October 16, 2026 00:43
Copilot AI balanced review requested due to automatic review settings October 16, 2026 00:43
@AArnott
AArnott enabled auto-merge (squash) October 16, 2026 00:43
@AArnott
AArnott merged commit 1f2a075 into master Oct 16, 2026
30 checks passed
@AArnott
AArnott deleted the aarnott-sa1200-extern-alias-directives branch October 16, 2026 00:48

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Unhandled alias dependencies, collisions, directive trivia, and bypassed Fix All safeguards can produce invalid code.

0 open findings

5 resolved since last review
Previously missed (5)

In code that hasn't changed since last review

Medium severity Apply alias relocation guards during Fix All

src/​StyleCop.Analyzers.CodeFixes/​OrderingRules/​UsingCodeFixProvider.cs:142

The relocation guard only runs during individual code-action registration. FixAllInDocumentAsync calls GetTransformedDocumentAsync directly, so project/solution Fix All started in a safe file can still relocate aliases in another file with destination collisions or conditional boundaries, producing invalid code. Apply the guard in the shared transformation path too, and add a multi-document Fix All regression.

Medium severity Preserve extern aliases required by immovable conditional usings

src/​StyleCop.Analyzers.CodeFixes/​OrderingRules/​UsingCodeFixProvider.cs:345

An unconditional extern alias can be required by a non-global using that cannot move. For example, place extern alias corlib; before a #if true block containing using Core = corlib::System;, followed by a namespace. The existing using transformation leaves the conditional using outside, but this code moves the extern inside, breaking resolution of corlib. Retain aliases required by usings that remain outside, or withhold the placement fix. Add a regression for this dependency.

Medium severity Detect destination collisions with using aliases

src/​StyleCop.Analyzers.CodeFixes/​OrderingRules/​UsingCodeFixProvider.cs:462

The collision check excludes destination using aliases, which share a declaration space with extern aliases. For example, extern alias corlib; namespace N { using corlib = System; } is valid in separate scopes, but moving the extern inward introduces a duplicate alias. The outward equivalent has the same problem. Include destination using-alias identifiers in this check and add regressions for both placement settings.

Medium severity Preserve preprocessor directives when relocating extern aliases

src/​StyleCop.Analyzers.CodeFixes/​OrderingRules/​UsingCodeFixProvider.cs:467

SourceMap does not track #define or #undef. In a valid file starting with #define FEATURE, followed by extern alias corlib; and a namespace, this guard permits relocation. The directive remains leading trivia on the alias, so moving it inside places #define after C# tokens and introduces CS1032. Preserve these directives at compilation-unit scope or withhold the fix when they accompany a moved alias. Add coverage for both directive kinds.

Medium severity Recognize dotted extern alias references

src/​StyleCop.Analyzers/​Helpers/​UsingDirectiveSyntaxHelpers.cs:85

Extern aliases can also be referenced with dot qualification, such as extern alias corlib; global using Core = corlib.System;. That target contains no AliasQualifiedNameSyntax, so this helper returns false, reports SA1200 on the required extern, and permits moving it out of the global using's scope. Recognize dotted references rooted in the extern alias, including those nested in type targets, and test both the diagnostic exemption and code-fix preservation.

🧠 Review effort: Balanced

This was referenced Nov 13, 2026
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.

Update SA1200 to treat extern alias directives as using directives

2 participants