@@ -30,26 +30,29 @@ public class FileNameRuleAnalyzer : IIncrementalGenerator
3030 "Directory.Build.props" ,
3131 "Directory.Build.targets" ,
3232 "Directory.Packages.props" ,
33- "AssemblyInfo.cs" ,
33+ "*AssemblyInfo.cs" ,
34+ "*.AssemblyInfo.cs" ,
35+ "*.AssemblyAttributes.cs" ,
36+ "*.GlobalUsings.g.cs" ,
3437 "AnalyzerReleases.Shipped.md" ,
3538 "AnalyzerReleases.Unshipped.md"
3639 ] ;
3740
3841 public void Initialize ( IncrementalGeneratorInitializationContext context )
3942 {
4043 // Create a value provider that provides all syntax trees with config options
41- var syntaxTreesWithConfig = context . CompilationProvider
44+ IncrementalValuesProvider < ( SyntaxTree tree , AnalyzerConfigOptionsProvider configOptions ) > syntaxTreesWithConfig = context . CompilationProvider
4245 . Combine ( context . AnalyzerConfigOptionsProvider )
4346 . SelectMany ( ( source , _ ) =>
4447 {
45- var ( compilation , configOptions ) = source ;
48+ ( Compilation compilation , AnalyzerConfigOptionsProvider configOptions ) = source ;
4649 return compilation . SyntaxTrees . Select ( tree => ( tree , configOptions ) ) ;
4750 } ) ;
4851
4952 // Register diagnostics for each syntax tree
5053 context . RegisterSourceOutput ( syntaxTreesWithConfig , ( spc , source ) =>
5154 {
52- var ( tree , configOptions ) = source ;
55+ ( SyntaxTree tree , AnalyzerConfigOptionsProvider configOptions ) = source ;
5356 AnalyzeFileNaming ( spc , tree , configOptions ) ;
5457 } ) ;
5558 }
@@ -69,7 +72,7 @@ private void AnalyzeFileNaming(SourceProductionContext context, SyntaxTree tree,
6972 return ;
7073
7174 // Get configured exceptions
72- string [ ] exceptions = GetConfiguredExceptions ( configOptions ) ;
75+ string [ ] exceptions = GetConfiguredExceptions ( configOptions , tree ) ;
7376
7477 // Check if file matches any exception pattern
7578 if ( IsFileExcepted ( fileName , exceptions ) )
@@ -78,28 +81,33 @@ private void AnalyzeFileNaming(SourceProductionContext context, SyntaxTree tree,
7881 // Check if file name follows kebab-case pattern
7982 if ( ! KebabCasePattern . IsMatch ( fileName ) )
8083 {
81- Location location = Location . Create (
84+ var location = Location . Create (
8285 tree ,
83- Microsoft . CodeAnalysis . Text . TextSpan . FromBounds ( 0 , 0 )
86+ TextSpan . FromBounds ( 0 , 0 )
8487 ) ;
8588
86- Diagnostic diagnostic = Diagnostic . Create ( Rule , location , fileName ) ;
89+ var diagnostic = Diagnostic . Create ( Rule , location , fileName ) ;
8790 context . ReportDiagnostic ( diagnostic ) ;
8891 }
8992 }
9093
91- private string [ ] GetConfiguredExceptions ( AnalyzerConfigOptionsProvider configOptions )
94+ private string [ ] GetConfiguredExceptions ( AnalyzerConfigOptionsProvider configOptions , SyntaxTree tree )
9295 {
96+ // Get file-specific options
97+ AnalyzerConfigOptions options = configOptions . GetOptions ( tree ) ;
98+
9399 // Try to get configured exceptions from .editorconfig
94- if ( configOptions . GlobalOptions . TryGetValue (
100+ if ( options . TryGetValue (
95101 "dotnet_diagnostic.TW0003.excluded_files" ,
96102 out string ? configuredExceptions ) && ! string . IsNullOrEmpty ( configuredExceptions ) )
97103 {
98104 // Split by semicolon and trim whitespace
99- return configuredExceptions
100- . Split ( new [ ] { ';' } , StringSplitOptions . RemoveEmptyEntries )
101- . Select ( s => s . Trim ( ) )
102- . ToArray ( ) ;
105+ IEnumerable < string > additionalExceptions = configuredExceptions
106+ . Split ( [ ';' ] , StringSplitOptions . RemoveEmptyEntries )
107+ . Select ( s => s . Trim ( ) ) ;
108+
109+ // Merge defaults with configured exceptions
110+ return [ .. DefaultExceptions , .. additionalExceptions ] ;
103111 }
104112
105113 // Return default exceptions if not configured
0 commit comments