@@ -11,7 +11,6 @@ namespace StyleCop.Analyzers.DocumentationRules
1111 using Microsoft . CodeAnalysis . CSharp ;
1212 using Microsoft . CodeAnalysis . CSharp . Syntax ;
1313 using Microsoft . CodeAnalysis . Diagnostics ;
14- using Microsoft . CodeAnalysis . Text ;
1514 using StyleCop . Analyzers . Settings . ObjectModel ;
1615
1716 /// <summary>
@@ -53,71 +52,84 @@ public override void Initialize(AnalysisContext context)
5352
5453 private static void HandleCompilationStart ( CompilationStartAnalysisContext context )
5554 {
56- context . RegisterSyntaxTreeActionHonorExclusions ( HandleSyntaxTreeAction ) ;
55+ var analyzer = new Analyzer ( context . Options ) ;
56+ context . RegisterSyntaxTreeActionHonorExclusions ( analyzer . HandleSyntaxTreeAction ) ;
5757 }
5858
59- private static void HandleSyntaxTreeAction ( SyntaxTreeAnalysisContext context )
59+ private class Analyzer
6060 {
61- var syntaxRoot = context . Tree . GetRoot ( context . CancellationToken ) ;
62- var settings = context . GetStyleCopSettings ( ) ;
61+ private readonly FileNamingConvention fileNamingConvention ;
6362
64- var firstTypeDeclaration = GetFirstTypeDeclaration ( syntaxRoot ) ;
65- if ( firstTypeDeclaration == null )
63+ public Analyzer ( AnalyzerOptions options )
6664 {
67- return ;
65+ StyleCopSettings settings = options . GetStyleCopSettings ( ) ;
66+ this . fileNamingConvention = settings . DocumentationRules . FileNamingConvention ;
6867 }
6968
70- if ( firstTypeDeclaration . Modifiers . Any ( SyntaxKind . PartialKeyword ) )
69+ public void HandleSyntaxTreeAction ( SyntaxTreeAnalysisContext context )
7170 {
72- return ;
71+ var syntaxRoot = context . Tree . GetRoot ( context . CancellationToken ) ;
72+
73+ var firstTypeDeclaration = GetFirstTypeDeclaration ( syntaxRoot ) ;
74+ if ( firstTypeDeclaration == null )
75+ {
76+ return ;
77+ }
78+
79+ if ( firstTypeDeclaration . Modifiers . Any ( SyntaxKind . PartialKeyword ) )
80+ {
81+ return ;
82+ }
83+
84+ var fileName = Path . GetFileName ( context . Tree . FilePath ) ;
85+ string expectedFileName ;
86+ switch ( this . fileNamingConvention )
87+ {
88+ case FileNamingConvention . Metadata :
89+ expectedFileName = GetMetadataFileName ( firstTypeDeclaration ) ;
90+ break ;
91+
92+ default :
93+ expectedFileName = GetStyleCopFileName ( firstTypeDeclaration ) ;
94+ break ;
95+ }
96+
97+ if ( string . Compare ( fileName , expectedFileName , StringComparison . OrdinalIgnoreCase ) != 0 )
98+ {
99+ var properties = ImmutableDictionary . Create < string , string > ( )
100+ . Add ( ExpectedFileNameKey , expectedFileName ) ;
101+
102+ context . ReportDiagnostic ( Diagnostic . Create ( Descriptor , firstTypeDeclaration . Identifier . GetLocation ( ) , properties ) ) ;
103+ }
73104 }
74105
75- var fileName = Path . GetFileName ( context . Tree . FilePath ) ;
76- string expectedFileName ;
77- switch ( settings . DocumentationRules . FileNamingConvention )
106+ private static TypeDeclarationSyntax GetFirstTypeDeclaration ( SyntaxNode root )
78107 {
79- case FileNamingConvention . Metadata :
80- expectedFileName = GetMetadataFileName ( firstTypeDeclaration ) ;
81- break ;
82-
83- default :
84- expectedFileName = GetStyleCopFileName ( firstTypeDeclaration ) ;
85- break ;
108+ return root . DescendantNodes ( descendIntoChildren : node => node . IsKind ( SyntaxKind . CompilationUnit ) || node . IsKind ( SyntaxKind . NamespaceDeclaration ) )
109+ . OfType < TypeDeclarationSyntax > ( )
110+ . FirstOrDefault ( ) ;
86111 }
87112
88- if ( string . Compare ( fileName , expectedFileName , StringComparison . OrdinalIgnoreCase ) != 0 )
113+ private static string GetStyleCopFileName ( TypeDeclarationSyntax firstTypeDeclaration )
89114 {
90- var properties = ImmutableDictionary . Create < string , string > ( )
91- . Add ( ExpectedFileNameKey , expectedFileName ) ;
115+ if ( firstTypeDeclaration . TypeParameterList == null )
116+ {
117+ return $ "{ firstTypeDeclaration . Identifier . ValueText } .cs";
118+ }
92119
93- context . ReportDiagnostic ( Diagnostic . Create ( Descriptor , firstTypeDeclaration . Identifier . GetLocation ( ) , properties ) ) ;
120+ var typeParameterList = string . Join ( "," , firstTypeDeclaration . TypeParameterList . Parameters . Select ( p => p . Identifier . ValueText ) ) ;
121+ return $ "{ firstTypeDeclaration . Identifier . ValueText } {{{typeParameterList}}}.cs";
94122 }
95- }
96-
97- private static TypeDeclarationSyntax GetFirstTypeDeclaration ( SyntaxNode root )
98- {
99- return ( TypeDeclarationSyntax ) root . DescendantNodes ( ) . FirstOrDefault ( node => node is TypeDeclarationSyntax ) ;
100- }
101123
102- private static string GetStyleCopFileName ( TypeDeclarationSyntax firstTypeDeclaration )
103- {
104- if ( firstTypeDeclaration . TypeParameterList == null )
124+ private static string GetMetadataFileName ( TypeDeclarationSyntax firstTypeDeclaration )
105125 {
106- return $ "{ firstTypeDeclaration . Identifier . ValueText } .cs";
107- }
108-
109- var typeParameterList = string . Join ( "," , firstTypeDeclaration . TypeParameterList . Parameters . Select ( p => p . Identifier . ValueText ) ) ;
110- return $ "{ firstTypeDeclaration . Identifier . ValueText } {{{typeParameterList}}}.cs";
111- }
126+ if ( firstTypeDeclaration . TypeParameterList == null )
127+ {
128+ return $ "{ firstTypeDeclaration . Identifier . ValueText } .cs";
129+ }
112130
113- private static string GetMetadataFileName ( TypeDeclarationSyntax firstTypeDeclaration )
114- {
115- if ( firstTypeDeclaration . TypeParameterList == null )
116- {
117- return $ "{ firstTypeDeclaration . Identifier . ValueText } .cs";
131+ return $ "{ firstTypeDeclaration . Identifier . ValueText } `{ firstTypeDeclaration . Arity } .cs";
118132 }
119-
120- return $ "{ firstTypeDeclaration . Identifier . ValueText } `{ firstTypeDeclaration . Arity } .cs";
121133 }
122134 }
123135}
0 commit comments