@@ -31,15 +31,15 @@ namespace SonarAnalyzer.Rules.CSharp
3131 [ DiagnosticAnalyzer ( LanguageNames . CSharp ) ]
3232 public sealed class ControlCharacterInString : SonarDiagnosticAnalyzer
3333 {
34- internal const string DiagnosticId = "S2479" ;
34+ private const string DiagnosticId = "S2479" ;
3535 private const string MessageFormat = "Replace the control character at position {0} by its escape sequence '{1}'." ;
3636
37- private static readonly DiagnosticDescriptor rule =
37+ private static readonly DiagnosticDescriptor Rule =
3838 DescriptorFactory . Create ( DiagnosticId , MessageFormat ) ;
3939
40- public override ImmutableArray < DiagnosticDescriptor > SupportedDiagnostics => ImmutableArray . Create ( rule ) ;
40+ public override ImmutableArray < DiagnosticDescriptor > SupportedDiagnostics => ImmutableArray . Create ( Rule ) ;
4141
42- private static readonly IDictionary < char , string > EscapedControlCharacters = new Dictionary < char , string > ( )
42+ private static readonly IDictionary < char , string > EscapedControlCharacters = new Dictionary < char , string >
4343 {
4444 { '\u0000 ' , "\\ 0" } ,
4545 { '\u0001 ' , "\\ u0001" } ,
@@ -102,7 +102,8 @@ protected override void Initialize(SonarAnalysisContext context)
102102 {
103103 context . RegisterSyntaxNodeActionInNonGenerated (
104104 c => CheckControlCharacter ( c , ( ( LiteralExpressionSyntax ) c . Node ) . Token . Text , 0 ) ,
105- SyntaxKind . StringLiteralExpression ) ;
105+ SyntaxKind . StringLiteralExpression ,
106+ SyntaxKindEx . Utf8StringLiteralExpression ) ;
106107
107108 context . RegisterSyntaxNodeActionInNonGenerated (
108109 c => CheckControlCharacter ( c , ( ( InterpolatedStringTextSyntax ) c . Node ) . TextToken . Text , 1 ) ,
@@ -111,7 +112,7 @@ protected override void Initialize(SonarAnalysisContext context)
111112
112113 private static void CheckControlCharacter ( SyntaxNodeAnalysisContext c , string text , int displayPosIncrement )
113114 {
114- if ( IsSimpleVerbatimString ( c . Node ) || IsInterpolatedVerbatimString ( c . Node . Parent ) )
115+ if ( IsInescapableString ( c . Node ) || IsInescepableInterpolatedString ( c . Node . Parent ) || IsInescapableUtf8String ( c . Node ) )
115116 {
116117 return ;
117118 }
@@ -120,17 +121,24 @@ private static void CheckControlCharacter(SyntaxNodeAnalysisContext c, string te
120121 {
121122 if ( EscapedControlCharacters . TryGetValue ( text [ charPos ] , out var escapeSequence ) )
122123 {
123- c . ReportIssue ( Diagnostic . Create ( rule , c . Node . GetLocation ( ) , displayPosIncrement + charPos ,
124- escapeSequence ) ) ;
124+ c . ReportIssue ( Diagnostic . Create ( Rule , c . Node . GetLocation ( ) , displayPosIncrement + charPos , escapeSequence ) ) ;
125125 return ;
126126 }
127127 }
128128 }
129129
130- private static bool IsSimpleVerbatimString ( SyntaxNode syntaxNode ) =>
131- syntaxNode . GetFirstToken ( ) . IsVerbatimStringLiteral ( ) ;
130+ private static bool IsInescapableString ( SyntaxNode syntaxNode ) =>
131+ syntaxNode . GetFirstToken ( ) is var token
132+ && ( token . IsVerbatimStringLiteral ( )
133+ || token . IsAnyKind ( SyntaxKindEx . SingleLineRawStringLiteralToken , SyntaxKindEx . MultiLineRawStringLiteralToken ) ) ;
132134
133- private static bool IsInterpolatedVerbatimString ( SyntaxNode syntaxNode ) =>
134- syntaxNode . GetFirstToken ( ) . IsKind ( SyntaxKind . InterpolatedVerbatimStringStartToken ) ;
135+ private static bool IsInescepableInterpolatedString ( SyntaxNode syntaxNode ) =>
136+ syntaxNode . GetFirstToken ( ) . IsAnyKind (
137+ SyntaxKind . InterpolatedVerbatimStringStartToken ,
138+ SyntaxKindEx . InterpolatedSingleLineRawStringStartToken ,
139+ SyntaxKindEx . InterpolatedMultiLineRawStringStartToken ) ;
140+
141+ private static bool IsInescapableUtf8String ( SyntaxNode syntaxNode ) =>
142+ syntaxNode . GetFirstToken ( ) . IsAnyKind ( SyntaxKindEx . Utf8SingleLineRawStringLiteralToken , SyntaxKindEx . Utf8MultiLineRawStringLiteralToken ) ;
135143 }
136144}
0 commit comments