3
3
using System . IO ;
4
4
using System . Linq ;
5
5
using System . Xml ;
6
- using Semmle . Util . Logging ;
6
+ using System . Xml . Serialization ;
7
7
8
8
namespace Semmle . Autobuild . Shared
9
9
{
@@ -26,6 +26,26 @@ public class Project<TAutobuildOptions> : ProjectOrSolution<TAutobuildOptions> w
26
26
private readonly Lazy < List < Project < TAutobuildOptions > > > includedProjectsLazy ;
27
27
public override IEnumerable < IProjectOrSolution > IncludedProjects => includedProjectsLazy . Value ;
28
28
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
+
29
49
public Project ( Autobuilder < TAutobuildOptions > builder , string path ) : base ( builder , path )
30
50
{
31
51
ToolsVersion = new Version ( ) ;
@@ -49,7 +69,7 @@ public Project(Autobuilder<TAutobuildOptions> builder, string path) : base(build
49
69
50
70
if ( root ? . Name == "Project" )
51
71
{
52
- if ( root . HasAttribute ( "Sdk" ) )
72
+ if ( UsesSdk ( root ) )
53
73
{
54
74
DotNetProject = true ;
55
75
return ;
0 commit comments