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