55using Microsoft . CodeAnalysis ;
66using Microsoft . CodeAnalysis . CSharp ;
77using Microsoft . CodeAnalysis . CSharp . Syntax ;
8+ using Microsoft . CodeAnalysis . Diagnostics ;
89
910namespace Roslynator . CSharp ;
1011
1112[ DebuggerDisplay ( "{DebuggerDisplay,nq}" ) ]
12- internal readonly struct IndentationAnalysis
13+ internal sealed class IndentationAnalysis
1314{
1415 private readonly int ? _indentSize ;
15- private readonly SyntaxTrivia ? _singleIndentation ;
16+ private readonly SyntaxTrivia ? _indentStep ;
1617
17- private IndentationAnalysis ( SyntaxTrivia indentation , int ? indentSize , SyntaxTrivia ? singleIndentation )
18+ private IndentationAnalysis ( SyntaxTrivia indentation , IndentStyle ? indentStyle , int ? indentSize , SyntaxTrivia ? indentStep )
1819 {
1920 Indentation = indentation ;
21+ IndentStyle = indentStyle ;
2022 _indentSize = indentSize ;
21- _singleIndentation = singleIndentation ;
23+ _indentStep = indentStep ;
2224 }
2325
2426 public SyntaxTrivia Indentation { get ; }
2527
26- public int IndentSize => _indentSize ?? _singleIndentation ? . Span . Length ?? 0 ;
28+ public IndentStyle ? IndentStyle { get ; }
2729
28- public int IndentationLength => Indentation . Span . Length ;
30+ public int IndentSize => _indentSize ?? _indentStep ? . Span . Length ?? 0 ;
2931
30- public int IncreasedIndentationLength => ( IndentSize > 0 ) ? Indentation . Span . Length + IndentSize : 0 ;
32+ public int IndentationLength => Indentation . Span . Length ;
3133
32- public bool IsDefault
34+ public int IncreasedIndentationLength
3335 {
3436 get
3537 {
36- return Indentation . IsKind ( SyntaxKind . None )
37- && _indentSize is null
38- && _singleIndentation is null ;
38+ if ( IndentSize > 0 )
39+ {
40+ if ( IndentStyle == Roslynator . IndentStyle . Tab )
41+ return IndentationLength + 1 ;
42+
43+ return IndentationLength + IndentSize ;
44+ }
45+
46+ if ( _indentStep is not null )
47+ return IndentationLength + 4 ;
48+
49+ return IndentationLength ;
3950 }
4051 }
4152
4253 [ DebuggerBrowsable ( DebuggerBrowsableState . Never ) ]
43- private string DebuggerDisplay => $ "Length = { Indentation . Span . Length } { nameof ( IndentSize ) } = { IndentSize } ";
54+ private string DebuggerDisplay => $ "Length = { IndentationLength } { nameof ( IndentSize ) } = { IndentSize } ";
4455
45- public static IndentationAnalysis Create ( SyntaxNode node , CancellationToken cancellationToken = default )
56+ public static IndentationAnalysis Create ( SyntaxNode node , AnalyzerConfigOptions configOptions , CancellationToken cancellationToken = default )
4657 {
4758 SyntaxTrivia indentation = SyntaxTriviaAnalysis . DetermineIndentation ( node , cancellationToken ) ;
4859
60+ if ( configOptions . TryGetIndentStyle ( out IndentStyle indentStyle )
61+ && indentStyle == Roslynator . IndentStyle . Tab )
62+ {
63+ if ( ! configOptions . TryGetTabLength ( out int tabLength ) )
64+ tabLength = 4 ;
65+
66+ return new IndentationAnalysis ( indentation , indentStyle , tabLength , null ) ;
67+ }
68+ else if ( configOptions . TryGetIndentSize ( out int indentSize ) )
69+ {
70+ return new IndentationAnalysis ( indentation , Roslynator . IndentStyle . Space , indentSize , null ) ;
71+ }
72+
4973 ( SyntaxTrivia trivia1 , SyntaxTrivia trivia2 , bool isFromCompilationUnit ) = DetermineSingleIndentation ( node , cancellationToken ) ;
5074
5175 if ( isFromCompilationUnit )
5276 {
53- return new IndentationAnalysis ( indentation , trivia1 . Span . Length - trivia2 . Span . Length , null ) ;
77+ return new IndentationAnalysis ( indentation , null , trivia1 . Span . Length - trivia2 . Span . Length , null ) ;
5478 }
5579 else if ( indentation . Span . Length > 0 )
5680 {
5781 return ( trivia1 . Span . Length > 0 )
58- ? new IndentationAnalysis ( indentation , null , trivia1 )
59- : new IndentationAnalysis ( indentation , null , null ) ;
82+ ? new IndentationAnalysis ( indentation , null , null , trivia1 )
83+ : new IndentationAnalysis ( indentation , null , null , null ) ;
6084 }
6185 else if ( trivia1 . Span . Length > 0 )
6286 {
63- return new IndentationAnalysis ( indentation , null , trivia1 ) ;
87+ return new IndentationAnalysis ( indentation , null , null , trivia1 ) ;
6488 }
6589 else
6690 {
@@ -87,11 +111,14 @@ public SyntaxTriviaList GetIncreasedIndentationTriviaList()
87111
88112 public string GetSingleIndentation ( )
89113 {
90- if ( _singleIndentation is not null )
91- return _singleIndentation . ToString ( ) ;
114+ if ( _indentStep is not null )
115+ return _indentStep . ToString ( ) ;
116+
117+ if ( IndentStyle == Roslynator . IndentStyle . Tab )
118+ return "\t " ;
92119
93- if ( _indentSize == - 1 )
94- return Indentation . ToString ( ) ;
120+ if ( IndentStyle == Roslynator . IndentStyle . Space )
121+ return GetSpaces ( ) ;
95122
96123 if ( Indentation . Span . Length == 0 )
97124 return "" ;
@@ -101,7 +128,18 @@ public string GetSingleIndentation()
101128 if ( indentation [ indentation . Length - 1 ] == '\t ' )
102129 return "\t " ;
103130
104- return new string ( indentation [ 0 ] , IndentSize ) ;
131+ return GetSpaces ( ) ;
132+
133+ string GetSpaces ( )
134+ {
135+ return IndentSize switch
136+ {
137+ 2 => " " ,
138+ 4 => " " ,
139+ 8 => " " ,
140+ _ => new string ( ' ' , IndentSize ) ,
141+ } ;
142+ }
105143 }
106144
107145 private static ( SyntaxTrivia , SyntaxTrivia , bool isFromCompilationUnit ) DetermineSingleIndentation ( SyntaxNode node , CancellationToken cancellationToken = default )
0 commit comments