22using System . Collections . Generic ;
33using System . IO ;
44using System . Linq ;
5- using System . Text ;
5+ using System . Text . RegularExpressions ;
66using Semmle . Util . Logging ;
77
88namespace Semmle . Extraction . CSharp . DependencyFetching
99{
10- internal sealed class Resx : DotnetSourceGeneratorWrapper
10+ internal sealed partial class Resx : DotnetSourceGeneratorWrapper
1111 {
1212 protected override string FileType => "Resx" ;
1313
@@ -28,6 +28,24 @@ protected override void GenerateAnalyzerConfig(IEnumerable<string> resources, st
2828 sw . WriteLine ( "is_global = true" ) ;
2929
3030 var rootNamespace = Path . GetFileNameWithoutExtension ( csprojFile ) ;
31+
32+ var matches = File . ReadAllLines ( csprojFile )
33+ . Select ( line => RootNamespace ( ) . Match ( line ) )
34+ . Where ( match => match . Success )
35+ . Select ( match => match . Groups [ 1 ] . Value )
36+ . ToArray ( ) ;
37+
38+ if ( matches . Length == 1 )
39+ {
40+ logger . LogDebug ( $ "RootNamespace found in { csprojFile } : { matches [ 0 ] } ") ;
41+ rootNamespace = matches [ 0 ] ;
42+ }
43+ else if ( matches . Length > 1 )
44+ {
45+ logger . LogDebug ( $ "Multiple RootNamespace elements found in { csprojFile } . Using the first one.") ;
46+ rootNamespace = matches [ 0 ] ;
47+ }
48+
3149 sw . WriteLine ( $ "build_property.RootNamespace = { rootNamespace } ") ;
3250
3351 foreach ( var f in resources . Select ( f => f . Replace ( '\\ ' , '/' ) ) )
@@ -36,5 +54,8 @@ protected override void GenerateAnalyzerConfig(IEnumerable<string> resources, st
3654 sw . WriteLine ( $ "build_metadata.AdditionalFiles.EmitFormatMethods = true") ;
3755 }
3856 }
57+
58+ [ GeneratedRegex ( @"<RootNamespace>(.*)</RootNamespace>" , RegexOptions . Compiled | RegexOptions . Singleline ) ]
59+ private static partial Regex RootNamespace ( ) ;
3960 }
4061}
0 commit comments