88using BenchmarkDotNet . Extensions ;
99using BenchmarkDotNet . Jobs ;
1010
11+ #nullable enable
12+
1113namespace BenchmarkDotNet . Toolchains
1214{
1315 internal static class AppConfigGenerator
@@ -26,42 +28,56 @@ internal static class AppConfigGenerator
2628
2729 internal static void Generate ( Job job , TextReader source , TextWriter destination , IResolver resolver )
2830 {
29- using ( var xmlReader = XmlReader . Create ( source ) )
30- {
31- var xmlDocument = new XmlDocument ( ) ;
31+ var xmlDocument = new XmlDocument ( ) ;
32+
33+ XmlNode configurationElement ;
3234
33- var configurationElement = GetOrCreateConfigurationElement ( xmlDocument , xmlReader ) ;
35+ if ( source == TextReader . Null )
36+ {
37+ // Create a new configuration node.
38+ configurationElement = xmlDocument . CreateNode ( XmlNodeType . Element , "configuration" , string . Empty ) ;
39+ xmlDocument . AppendChild ( configurationElement ) ;
40+ }
41+ else
42+ {
43+ // Try to get configuration node from specified TextReader.
44+ using var xmlReader = XmlReader . Create ( source ) ;
45+ configurationElement = GetOrCreateConfigurationElement ( xmlDocument , xmlReader ) ;
46+ }
3447
35- var runtimeElement = GetOrCreateRuntimeElement ( xmlDocument , configurationElement ) ;
48+ var runtimeElement = GetOrCreateRuntimeElement ( xmlDocument , configurationElement ) ;
3649
37- ClearStartupSettingsForCustomClr ( configurationElement , job . Environment . Runtime ) ;
38- ClearAllRuntimeSettingsThatCanBeSetOnlyByJobConfiguration ( runtimeElement ) ;
50+ ClearStartupSettingsForCustomClr ( configurationElement , job . Environment . Runtime ) ;
51+ ClearAllRuntimeSettingsThatCanBeSetOnlyByJobConfiguration ( runtimeElement ) ;
3952
40- GenerateJitSettings ( xmlDocument , runtimeElement , job . Environment ) ;
41- GenerateGCSettings ( xmlDocument , runtimeElement , job . Environment . Gc , resolver ) ;
53+ GenerateJitSettings ( xmlDocument , runtimeElement , job . Environment ) ;
54+ GenerateGCSettings ( xmlDocument , runtimeElement , job . Environment . Gc , resolver ) ;
4255
43- xmlDocument . Save ( destination ) ;
44- }
56+ xmlDocument . Save ( destination ) ;
4557 }
4658
4759 private static XmlNode GetOrCreateConfigurationElement ( XmlDocument xmlDocument , XmlReader xmlReader )
4860 {
4961 try
5062 {
5163 xmlDocument . Load ( xmlReader ) ;
52-
53- return xmlDocument . SelectSingleNode ( "/configuration" ) ;
64+ var configurationNode = xmlDocument . SelectSingleNode ( "/configuration" ) ;
65+ if ( configurationNode != null )
66+ return configurationNode ;
5467 }
55- catch // empty document
68+ catch ( XmlException )
5669 {
57- return xmlDocument . AppendChild ( xmlDocument . CreateNode ( XmlNodeType . Element , "configuration" , string . Empty ) ) ;
70+ // Failed to load XML content.
5871 }
72+
73+ // If the XML is invalid or configuration node is not exists. Create a new configuration element
74+ return xmlDocument . AppendChild ( xmlDocument . CreateNode ( XmlNodeType . Element , "configuration" , string . Empty ) ) ! ;
5975 }
6076
6177 private static XmlNode GetOrCreateRuntimeElement ( XmlDocument xmlDocument , XmlNode configurationElement )
6278 {
6379 return configurationElement . SelectSingleNode ( "runtime" )
64- ?? configurationElement . AppendChild ( xmlDocument . CreateNode ( XmlNodeType . Element , "runtime" , string . Empty ) ) ;
80+ ?? configurationElement . AppendChild ( xmlDocument . CreateNode ( XmlNodeType . Element , "runtime" , string . Empty ) ) ! ;
6581 }
6682
6783 private static void ClearAllRuntimeSettingsThatCanBeSetOnlyByJobConfiguration ( XmlNode runtimeElement )
@@ -75,7 +91,7 @@ private static void ClearAllRuntimeSettingsThatCanBeSetOnlyByJobConfiguration(Xm
7591 }
7692 }
7793
78- private static void ClearStartupSettingsForCustomClr ( XmlNode configurationElement , Runtime runtime )
94+ private static void ClearStartupSettingsForCustomClr ( XmlNode configurationElement , Runtime ? runtime )
7995 {
8096 if ( ! ( runtime is ClrRuntime clrRuntime ) || string . IsNullOrEmpty ( clrRuntime . Version ) )
8197 return ;
0 commit comments