@@ -15,24 +15,18 @@ namespace StyleCop.Analyzers.DocumentationRules
1515 /// <c><inheritdoc></c> has been used on an element that doesn't inherit from a base class or implement an
1616 /// interface.
1717 /// </summary>
18- /// <remarks>
19- /// <para>Verifies that an <c>inheritdoc</c> tag is not used when the class or interface does not inherit from a
20- /// base class or interface.</para>
21- ///
22- /// <para>A violation of this rule occurs when the element having the <c>inheritdoc</c> tag doesn't inherit from a
23- /// base case or implement an interface.</para>
24- /// </remarks>
18+ /// <seealso href="https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1648.md">SA1648</seealso>
2519 [ DiagnosticAnalyzer ( LanguageNames . CSharp ) ]
2620 internal class SA1648InheritDocMustBeUsedWithInheritingClass : DiagnosticAnalyzer
2721 {
2822 /// <summary>
2923 /// The ID for diagnostics produced by the <see cref="SA1648InheritDocMustBeUsedWithInheritingClass"/> analyzer.
3024 /// </summary>
3125 public const string DiagnosticId = "SA1648" ;
32- private const string Title = "inheritdoc must be used with inheriting class" ;
33- private const string MessageFormat = "inheritdoc must be used with inheriting class" ;
34- private const string Description = "<inheritdoc> has been used on an element that doesn't inherit from a base class or implement an interface." ;
35- private const string HelpLink = "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1648.md" ;
26+ private static readonly LocalizableString Title = new LocalizableResourceString ( nameof ( DocumentationResources . SA1648Title ) , DocumentationResources . ResourceManager , typeof ( DocumentationResources ) ) ;
27+ private static readonly LocalizableString MessageFormat = new LocalizableResourceString ( nameof ( DocumentationResources . SA1648MessageFormat ) , DocumentationResources . ResourceManager , typeof ( DocumentationResources ) ) ;
28+ private static readonly LocalizableString Description = new LocalizableResourceString ( nameof ( DocumentationResources . SA1648Description ) , DocumentationResources . ResourceManager , typeof ( DocumentationResources ) ) ;
29+ private static readonly string HelpLink = "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1648.md" ;
3630
3731 private static readonly DiagnosticDescriptor Descriptor =
3832 new DiagnosticDescriptor ( DiagnosticId , Title , MessageFormat , AnalyzerCategory . DocumentationRules , DiagnosticSeverity . Warning , AnalyzerConstants . EnabledByDefault , Description , HelpLink ) ;
@@ -86,11 +80,17 @@ private static void HandleBaseTypeLikeDeclaration(SyntaxNodeAnalysisContext cont
8680 DocumentationCommentTriviaSyntax documentation = context . Node . GetDocumentationCommentTriviaSyntax ( ) ;
8781
8882 XmlNodeSyntax inheritDocElement = documentation ? . Content . GetFirstXmlElement ( XmlCommentHelper . InheritdocXmlTag ) ;
83+ if ( inheritDocElement == null )
84+ {
85+ return ;
86+ }
8987
90- if ( inheritDocElement != null )
88+ if ( HasXmlCrefAttribute ( inheritDocElement ) )
9189 {
92- context . ReportDiagnostic ( Diagnostic . Create ( Descriptor , inheritDocElement . GetLocation ( ) ) ) ;
90+ return ;
9391 }
92+
93+ context . ReportDiagnostic ( Diagnostic . Create ( Descriptor , inheritDocElement . GetLocation ( ) ) ) ;
9494 }
9595
9696 private static void HandleMemberDeclaration ( SyntaxNodeAnalysisContext context )
@@ -107,27 +107,50 @@ private static void HandleMemberDeclaration(SyntaxNodeAnalysisContext context)
107107 DocumentationCommentTriviaSyntax documentation = memberSyntax . GetDocumentationCommentTriviaSyntax ( ) ;
108108
109109 XmlNodeSyntax inheritDocElement = documentation ? . Content . GetFirstXmlElement ( XmlCommentHelper . InheritdocXmlTag ) ;
110+ if ( inheritDocElement == null )
111+ {
112+ return ;
113+ }
110114
111- if ( inheritDocElement != null )
115+ if ( HasXmlCrefAttribute ( inheritDocElement ) )
112116 {
113- ISymbol declaredSymbol = context . SemanticModel . GetDeclaredSymbol ( memberSyntax , context . CancellationToken ) ;
114- if ( declaredSymbol == null && memberSyntax . IsKind ( SyntaxKind . EventFieldDeclaration ) )
115- {
116- var eventFieldDeclarationSyntax = ( EventFieldDeclarationSyntax ) memberSyntax ;
117- VariableDeclaratorSyntax firstVariable = eventFieldDeclarationSyntax . Declaration ? . Variables . FirstOrDefault ( ) ;
118- if ( firstVariable != null )
119- {
120- declaredSymbol = context . SemanticModel . GetDeclaredSymbol ( firstVariable , context . CancellationToken ) ;
121- }
122- }
117+ return ;
118+ }
123119
124- // If we don't have a declared symbol we have some kind of field declaration. A field can not override or
125- // implement anything so we want to report a diagnostic.
126- if ( declaredSymbol == null || ! NamedTypeHelpers . IsImplementingAnInterfaceMember ( declaredSymbol ) )
120+ ISymbol declaredSymbol = context . SemanticModel . GetDeclaredSymbol ( memberSyntax , context . CancellationToken ) ;
121+ if ( declaredSymbol == null && memberSyntax . IsKind ( SyntaxKind . EventFieldDeclaration ) )
122+ {
123+ var eventFieldDeclarationSyntax = ( EventFieldDeclarationSyntax ) memberSyntax ;
124+ VariableDeclaratorSyntax firstVariable = eventFieldDeclarationSyntax . Declaration ? . Variables . FirstOrDefault ( ) ;
125+ if ( firstVariable != null )
127126 {
128- context . ReportDiagnostic ( Diagnostic . Create ( Descriptor , inheritDocElement . GetLocation ( ) ) ) ;
127+ declaredSymbol = context . SemanticModel . GetDeclaredSymbol ( firstVariable , context . CancellationToken ) ;
129128 }
130129 }
130+
131+ // If we don't have a declared symbol we have some kind of field declaration. A field can not override or
132+ // implement anything so we want to report a diagnostic.
133+ if ( declaredSymbol == null || ! NamedTypeHelpers . IsImplementingAnInterfaceMember ( declaredSymbol ) )
134+ {
135+ context . ReportDiagnostic ( Diagnostic . Create ( Descriptor , inheritDocElement . GetLocation ( ) ) ) ;
136+ }
137+ }
138+
139+ private static bool HasXmlCrefAttribute ( XmlNodeSyntax inheritDocElement )
140+ {
141+ XmlElementSyntax xmlElementSyntax = inheritDocElement as XmlElementSyntax ;
142+ if ( xmlElementSyntax ? . StartTag ? . Attributes . Any ( SyntaxKind . XmlCrefAttribute ) ?? false )
143+ {
144+ return true ;
145+ }
146+
147+ XmlEmptyElementSyntax xmlEmptyElementSyntax = inheritDocElement as XmlEmptyElementSyntax ;
148+ if ( xmlEmptyElementSyntax ? . Attributes . Any ( SyntaxKind . XmlCrefAttribute ) ?? false )
149+ {
150+ return true ;
151+ }
152+
153+ return false ;
131154 }
132155 }
133156}
0 commit comments