11using Microsoft . AspNetCore . Razor . Language ;
2+ using Microsoft . AspNetCore . Razor . Language . Intermediate ;
23using Microsoft . CodeAnalysis ;
34using Microsoft . CodeAnalysis . CSharp ;
45using Microsoft . CodeAnalysis . Text ;
@@ -140,15 +141,7 @@ static string toBase36(ReadOnlySpan<byte> hash)
140141
141142 public static RazorCSharpDocument GetCSharpDocumentSafe ( this RazorCodeDocument document )
142143 {
143- // GetCSharpDocument extension method has been turned into an instance method in https://github.com/dotnet/razor/pull/11939.
144- if ( document . GetType ( ) . GetMethod ( "GetCSharpDocument" , BindingFlags . Instance | BindingFlags . NonPublic ) is { } method )
145- {
146- return ( RazorCSharpDocument ) method . Invoke ( document , [ ] ) ! ;
147- }
148-
149- return ( RazorCSharpDocument ) typeof ( RazorCodeDocument ) . Assembly . GetType ( "Microsoft.AspNetCore.Razor.Language.RazorCodeDocumentExtensions" ) !
150- . GetMethod ( "GetCSharpDocument" , BindingFlags . Static | BindingFlags . Public ) !
151- . Invoke ( null , [ document ] ) ! ;
144+ return document . GetDocumentDataSafe < RazorCSharpDocument > ( "GetCSharpDocument" ) ;
152145 }
153146
154147 public static IReadOnlyList < RazorDiagnostic > GetDiagnostics ( this RazorCSharpDocument document )
@@ -160,6 +153,24 @@ public static IReadOnlyList<RazorDiagnostic> GetDiagnostics(this RazorCSharpDocu
160153 . GetValue ( document ) ! ;
161154 }
162155
156+ private static T GetDocumentDataSafe < T > ( this RazorCodeDocument document , string methodName , string ? instanceMethodName = null )
157+ {
158+ // GetCSharpDocument and similar extension methods have been turned into instance methods in https://github.com/dotnet/razor/pull/11939.
159+ if ( document . GetType ( ) . GetMethod ( instanceMethodName ?? methodName , BindingFlags . Instance | BindingFlags . NonPublic ) is { } method )
160+ {
161+ return ( T ) method . Invoke ( document , [ ] ) ! ;
162+ }
163+
164+ return ( T ) typeof ( RazorCodeDocument ) . Assembly . GetType ( "Microsoft.AspNetCore.Razor.Language.RazorCodeDocumentExtensions" ) !
165+ . GetMethod ( methodName , BindingFlags . Static | BindingFlags . Public ) !
166+ . Invoke ( null , [ document ] ) ! ;
167+ }
168+
169+ public static DocumentIntermediateNode GetDocumentIntermediateNodeSafe ( this RazorCodeDocument document )
170+ {
171+ return document . GetDocumentDataSafe < DocumentIntermediateNode > ( "GetDocumentIntermediateNode" , "GetDocumentNode" ) ;
172+ }
173+
163174 public static string GetGeneratedCode ( this RazorCSharpDocument document )
164175 {
165176 // There can be either `string GeneratedCode` or `SourceText Text` property.
@@ -177,15 +188,7 @@ public static string GetGeneratedCode(this RazorCSharpDocument document)
177188
178189 public static RazorSyntaxTree GetSyntaxTreeSafe ( this RazorCodeDocument document )
179190 {
180- // GetSyntaxTree extension method has been turned into an instance method in https://github.com/dotnet/razor/pull/11939.
181- if ( document . GetType ( ) . GetMethod ( "GetSyntaxTree" , BindingFlags . Instance | BindingFlags . NonPublic ) is { } method )
182- {
183- return ( RazorSyntaxTree ) method . Invoke ( document , [ ] ) ! ;
184- }
185-
186- return ( RazorSyntaxTree ) typeof ( RazorCodeDocument ) . Assembly . GetType ( "Microsoft.AspNetCore.Razor.Language.RazorCodeDocumentExtensions" ) !
187- . GetMethod ( "GetSyntaxTree" , BindingFlags . Static | BindingFlags . Public ) !
188- . Invoke ( null , [ document ] ) ! ;
191+ return document . GetDocumentDataSafe < RazorSyntaxTree > ( "GetSyntaxTree" ) ;
189192 }
190193
191194 public static IEnumerable < RazorProjectItem > EnumerateItemsSafe ( this RazorProjectFileSystem fileSystem , string basePath )
@@ -241,6 +244,29 @@ .. var rest
241244 . Invoke ( engine , [ projectItem , .. Enumerable . Repeat < object ? > ( null , method . GetParameters ( ) . Length - 1 ) ] ) ! ;
242245 }
243246
247+ public static string Serialize ( this IntermediateNode node )
248+ {
249+ // DebuggerDisplayFormatter merged to IntermediateNodeFormatter in https://github.com/dotnet/razor/pull/11931.
250+
251+ var assembly = typeof ( IntermediateNode ) . Assembly ;
252+ if ( assembly . GetType ( "Microsoft.AspNetCore.Razor.Language.Intermediate.DebuggerDisplayFormatter" ) is { } debuggerDisplayFormatter )
253+ {
254+ var formatter = Activator . CreateInstance ( debuggerDisplayFormatter ) ! ;
255+ debuggerDisplayFormatter . GetMethod ( "FormatTree" , BindingFlags . Instance | BindingFlags . Public ) !
256+ . Invoke ( formatter , [ node ] ) ;
257+ return formatter . ToString ( ) ! ;
258+ }
259+ else
260+ {
261+ var type = assembly . GetType ( "Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeFormatter" ) ! ;
262+ var sb = new StringBuilder ( ) ;
263+ var formatter = type . GetConstructors ( ) . Single ( ) . Invoke ( [ sb , 0 , false ] ) ! ;
264+ type . GetMethod ( "FormatTree" , BindingFlags . Instance | BindingFlags . Public ) !
265+ . Invoke ( formatter , [ node ] ) ;
266+ return sb . ToString ( ) ;
267+ }
268+ }
269+
244270 public static void SetCSharpLanguageVersionSafe ( this RazorProjectEngineBuilder builder , LanguageVersion languageVersion )
245271 {
246272 // Changed in https://github.com/dotnet/razor/commit/40384334fd4c20180c25b3c88a82d3ca5da07487.
0 commit comments