33using System . IO ;
44using System . Linq ;
55using System . Xml ;
6- using Semmle . Util . Logging ;
6+ using System . Xml . Serialization ;
77
88namespace Semmle . Autobuild . Shared
99{
@@ -26,6 +26,26 @@ public class Project<TAutobuildOptions> : ProjectOrSolution<TAutobuildOptions> w
2626 private readonly Lazy < List < Project < TAutobuildOptions > > > includedProjectsLazy ;
2727 public override IEnumerable < IProjectOrSolution > IncludedProjects => includedProjectsLazy . Value ;
2828
29+ private static bool HasSdkAttribute ( XmlElement xml ) =>
30+ xml . HasAttribute ( "Sdk" ) ;
31+
32+ private static bool AnyElement ( XmlNodeList l , Func < XmlElement , bool > f ) =>
33+ l . OfType < XmlElement > ( ) . Any ( f ) ;
34+
35+ /// <summary>
36+ /// According to https://learn.microsoft.com/en-us/visualstudio/msbuild/how-to-use-project-sdk?view=vs-2022#reference-a-project-sdk
37+ /// there are three ways to reference a project SDK:
38+ /// 1. As an attribute on the <Project/>.
39+ /// 2. As a top level element of <Project>.
40+ /// 3. As an attribute on an <Import> element.
41+ ///
42+ /// Returns true, if the Sdk attribute is used, otherwise false.
43+ /// </summary>
44+ private static bool UsesSdk ( XmlElement xml ) =>
45+ HasSdkAttribute ( xml ) || // Case 1
46+ AnyElement ( xml . ChildNodes , e => e . Name == "Sdk" ) || // Case 2
47+ AnyElement ( xml . GetElementsByTagName ( "Import" ) , HasSdkAttribute ) ; // Case 3
48+
2949 public Project ( Autobuilder < TAutobuildOptions > builder , string path ) : base ( builder , path )
3050 {
3151 ToolsVersion = new Version ( ) ;
@@ -49,7 +69,7 @@ public Project(Autobuilder<TAutobuildOptions> builder, string path) : base(build
4969
5070 if ( root ? . Name == "Project" )
5171 {
52- if ( root . HasAttribute ( "Sdk" ) )
72+ if ( UsesSdk ( root ) )
5373 {
5474 DotNetProject = true ;
5575 return ;
0 commit comments