You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
SA1200: Treat extern alias directives like using directives - #4313
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.
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>
❌ 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.
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>
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.
Preserve extern aliases required by immovable conditional usings
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.
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.
Preserve preprocessor directives when relocating extern aliases
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.
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.
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
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.
SA1200 currently ignores
extern aliasdirectives even though their placement follows the same inside/outside-namespace setting asusingdirectives. This leaves misplaced aliases unreported and means the placement code fix cannot move them.This change reports and moves extern aliases with the corresponding
usingdirectives 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