2
2
using System . Globalization ;
3
3
using System . IO ;
4
4
using System . Linq ;
5
+ using System . Runtime . InteropServices ;
5
6
using System . Text ;
6
7
using System . Xml . Linq ;
7
8
using Devlooped . Sponsors ;
@@ -94,12 +95,12 @@ void GenerateConstant(SourceProductionContext spc,
94
95
}
95
96
96
97
if ( comment != null )
97
- comment = "/// " + string . Join ( Environment . NewLine + "/// " , new XText ( comment ) . ToString ( ) . Trim ( ) . Replace ( "\\ n" , Environment . NewLine ) . Trim ( [ '\r ' , '\n ' ] ) . Split ( [ Environment . NewLine ] , StringSplitOptions . None ) ) ;
98
+ comment = "/// " + string . Join ( Environment . NewLine + "/// " , new XText ( comment ) . ToString ( ) . Trim ( ) . Replace ( "` n" , Environment . NewLine ) . Trim ( [ '\r ' , '\n ' ] ) . Split ( [ Environment . NewLine ] , StringSplitOptions . None ) ) ;
98
99
else
99
- comment = "/// " + string . Join ( Environment . NewLine + "/// " , new XText ( value ) . ToString ( ) . Replace ( "\\ n" , Environment . NewLine ) . Trim ( [ '\r ' , '\n ' ] ) . Split ( [ Environment . NewLine ] , StringSplitOptions . None ) ) ;
100
+ comment = "/// " + string . Join ( Environment . NewLine + "/// " , new XText ( value ) . ToString ( ) . Replace ( "` n" , Environment . NewLine ) . Trim ( [ '\r ' , '\n ' ] ) . Split ( [ Environment . NewLine ] , StringSplitOptions . None ) ) ;
100
101
101
102
// Revert normalization of newlines performed in MSBuild to workaround the limitation in editorconfig.
102
- var rootArea = Area . Load ( [ new ( name , value . Replace ( "\\ n" , Environment . NewLine ) . Trim ( [ '\r ' , '\n ' ] ) , comment , type ?? "string" ) , ] , root , rootComment ) ;
103
+ var rootArea = Area . Load ( [ new ( name , value . Replace ( "` n" , Environment . NewLine ) . Trim ( [ '\r ' , '\n ' ] ) , comment , type ?? "string" ) , ] , root , rootComment ) ;
103
104
// For now, we only support C# though
104
105
var file = parse . Language . Replace ( "#" , "Sharp" ) + ".sbntxt" ;
105
106
var template = Template . Parse ( EmbeddedResource . GetContent ( file ) , file ) ;
@@ -123,17 +124,35 @@ void GenerateConstant(SourceProductionContext spc,
123
124
124
125
var output = template . Render ( model , member => member . Name ) ;
125
126
126
- // Apply formatting since indenting isn't that nice in Scriban when rendering nested
127
- // structures via functions.
128
127
if ( parse . Language == LanguageNames . CSharp )
129
128
{
130
- output = SyntaxFactory
131
- . ParseCompilationUnit ( output , options : cs )
132
- . NormalizeWhitespace ( )
133
- . GetText ( )
134
- . ToString ( ) ;
129
+ // Apply formatting since indenting isn't that nice in Scriban when rendering nested
130
+ // structures via functions.
131
+ // We alos rewrite to prepend a newline leading trivia before the raw string literals if any
132
+ var node = new RawStringLiteralRewriter ( ) . Visit (
133
+ SyntaxFactory . ParseCompilationUnit ( output , options : cs ) . NormalizeWhitespace ( eol : Environment . NewLine ) ) ;
134
+
135
+ output = node . GetText ( ) . ToString ( ) ;
135
136
}
136
137
137
138
spc . AddSource ( $ "{ root } .{ name } .g.cs", SourceText . From ( output , Encoding . UTF8 ) ) ;
138
139
}
139
- }
140
+
141
+ class RawStringLiteralRewriter : CSharpSyntaxRewriter
142
+ {
143
+ public override SyntaxToken VisitToken ( SyntaxToken token )
144
+ {
145
+ // See https://learn.microsoft.com/en-us/dotnet/api/microsoft.codeanalysis.csharp.syntaxkind?view=roslyn-dotnet-4.13.0
146
+ // MultiLineRawStringLiteralToken = 8519
147
+ // Utf8MultiLineRawStringLiteralToken = 8522
148
+ if ( token . RawKind == 8519 || token . RawKind == 8522 )
149
+ return token . WithLeadingTrivia (
150
+ token . LeadingTrivia . Add (
151
+ RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) ?
152
+ SyntaxFactory . CarriageReturnLineFeed :
153
+ SyntaxFactory . LineFeed ) ) ;
154
+
155
+ return base . VisitToken ( token ) ;
156
+ }
157
+ }
158
+ }
0 commit comments