@@ -6,6 +6,13 @@ namespace ChartTools.Generator;
66
77internal class CodeBuilder ( StringBuilder ? builder = default )
88{
9+ public CodeBuilder ( CodeBuilder ? builder = default )
10+ : this ( new StringBuilder ( builder ? . ToString ( ) ?? null ) )
11+ {
12+ m_contextStack = builder ? . m_contextStack ?? [ ] ;
13+ m_indent = builder ? . m_indent ?? string . Empty ;
14+ }
15+
916 public CodeBuilder ( string value )
1017 : this ( new StringBuilder ( value ) ) { }
1118
@@ -23,15 +30,16 @@ public CodeBuilder(int indent, StringBuilder? builder = default)
2330 { '(' , ')' } ,
2431 { '{' , '}' } ,
2532 { '[' , ']' } ,
33+ { '<' , '>' } ,
2634 { '"' , '"' }
2735 } ;
2836
2937 public CodeBuilder StartContext ( char openChar , bool newLine = true )
3038 {
39+ StringBuilder . Append ( m_indent + openChar ) ;
40+
3141 if ( newLine )
32- StringBuilder . AppendLine ( m_indent + openChar ) ;
33- else
34- StringBuilder . Append ( m_indent + openChar ) ;
42+ StringBuilder . AppendLine ( ) ;
3543
3644 m_contextStack . Push ( openChar ) ;
3745 m_indent += '\t ' ;
@@ -49,19 +57,27 @@ public CodeBuilder EndContext(bool newLine = true)
4957 if ( ! m_contextClosers . TryGetValue ( openChar , out char closeChar ) )
5058 throw new InvalidOperationException ( $ "No closing character defined for '{ openChar } '.") ;
5159
52- m_indent = m_indent . Substring ( 0 , m_indent . Length - 2 ) ;
60+ m_indent = m_indent [ ..^ 1 ] ;
61+
62+ StringBuilder . Append ( m_indent + closeChar ) ;
5363
5464 if ( newLine )
55- StringBuilder . AppendLine ( m_indent + closeChar ) ;
56- else
57- StringBuilder . Append ( m_indent + closeChar ) ;
65+ StringBuilder . AppendLine ( ) ;
5866
5967 return this ;
6068 }
6169
62- public CodeBuilder AppendLine ( string line )
70+ public CodeBuilder EndAllContexts ( bool newLine = true )
6371 {
64- StringBuilder . AppendLine ( m_indent + line ) ;
72+ while ( m_contextStack . Count > 0 )
73+ EndContext ( newLine ) ;
74+
75+ return this ;
76+ }
77+
78+ public CodeBuilder AppendLine ( in ReadOnlySpan < char > line )
79+ {
80+ StringBuilder . AppendLine ( m_indent + line . ToString ( ) ) ;
6581 return this ;
6682 }
6783
@@ -71,14 +87,43 @@ public CodeBuilder AppendLine()
7187 return this ;
7288 }
7389
74- public CodeBuilder Append ( string text )
90+ public CodeBuilder AppendLines ( ReadOnlySpan < char > lines )
7591 {
76- StringBuilder . Append ( m_indent + text ) ;
92+ int breakIndex ;
93+
94+ while ( ( breakIndex = lines . IndexOf ( '\n ' ) ) != - 1 )
95+ {
96+ ReadOnlySpan < char > line = lines [ ..breakIndex ] ;
97+
98+ Append ( line ) ;
99+ lines = lines [ ( breakIndex + 1 ) ..] ;
100+ }
101+
102+ if ( lines . Length > 0 )
103+ AppendLine ( lines ) ;
104+
105+ return this ;
106+ }
107+
108+ public CodeBuilder Append ( in ReadOnlySpan < char > text )
109+ {
110+ StringBuilder . Append ( m_indent + text . ToString ( ) ) ;
111+ return this ;
112+ }
113+
114+ public CodeBuilder AppendInstruction ( in ReadOnlySpan < char > instruction )
115+ {
116+ StringBuilder . AppendLine ( m_indent + instruction . ToString ( ) + ';' ) ;
77117 return this ;
78118 }
79119
80120 public override string ToString ( )
81- => StringBuilder . ToString ( ) ;
121+ {
122+ if ( m_contextStack . Count > 0 )
123+ throw new InvalidOperationException ( "Buidler has unclosed contexts." ) ;
124+
125+ return StringBuilder . ToString ( ) ;
126+ }
82127
83128 public static implicit operator StringBuilder ( CodeBuilder builder )
84129 => builder . StringBuilder ;
0 commit comments