From e16db30316598b4d2f0a8c9661aa400b0302a5dd Mon Sep 17 00:00:00 2001
From: David Barbet <dabarbet@microsoft.com>
Date: Tue, 31 Jan 2023 13:33:55 -0800
Subject: [PATCH] Report to the client if the project being loaded is sdk style

---
 .../Eventing/IEventEmitterExtensions.cs          |  6 ++++--
 .../Models/Events/ProjectConfigurationMessage.cs |  1 +
 src/OmniSharp.MSBuild/ProjectLoadListener.cs     | 16 +++++++++++++++-
 3 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/src/OmniSharp.Abstractions/Eventing/IEventEmitterExtensions.cs b/src/OmniSharp.Abstractions/Eventing/IEventEmitterExtensions.cs
index adaaf96a9f..608787b405 100644
--- a/src/OmniSharp.Abstractions/Eventing/IEventEmitterExtensions.cs
+++ b/src/OmniSharp.Abstractions/Eventing/IEventEmitterExtensions.cs
@@ -54,7 +54,8 @@ public static void ProjectInformation(this IEventEmitter emitter,
                                               HashedString sdkVersion,
                                               IEnumerable<HashedString> references,
                                               IEnumerable<HashedString> fileExtensions,
-                                              IEnumerable<int> fileCounts)
+                                              IEnumerable<int> fileCounts,
+                                              bool sdkStyleProject)
         {
             var projectConfiguration = new ProjectConfigurationMessage()
             {
@@ -66,7 +67,8 @@ public static void ProjectInformation(this IEventEmitter emitter,
                 SessionId = sessionId.Value,
                 References = references.Select(hashed => hashed.Value),
                 FileExtensions = fileExtensions.Select(hashed => hashed.Value),
-                FileCounts = fileCounts
+                FileCounts = fileCounts,
+                SdkStyleProject = sdkStyleProject
             };
 
             emitter.Emit(
diff --git a/src/OmniSharp.Abstractions/Models/Events/ProjectConfigurationMessage.cs b/src/OmniSharp.Abstractions/Models/Events/ProjectConfigurationMessage.cs
index 02fe46c888..ed188ddf63 100644
--- a/src/OmniSharp.Abstractions/Models/Events/ProjectConfigurationMessage.cs
+++ b/src/OmniSharp.Abstractions/Models/Events/ProjectConfigurationMessage.cs
@@ -14,5 +14,6 @@ public class ProjectConfigurationMessage
         public IEnumerable<string> References { get; set; }
         public IEnumerable<string> FileExtensions { get; set; }
         public IEnumerable<int> FileCounts { get; set; }
+        public bool SdkStyleProject { get; set; }
     }
 }
diff --git a/src/OmniSharp.MSBuild/ProjectLoadListener.cs b/src/OmniSharp.MSBuild/ProjectLoadListener.cs
index fc4cfc9ff5..545567a1be 100644
--- a/src/OmniSharp.MSBuild/ProjectLoadListener.cs
+++ b/src/OmniSharp.MSBuild/ProjectLoadListener.cs
@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.Composition;
+using System.Diagnostics;
 using System.IO;
 using System.Linq;
 using Microsoft.Build.Execution;
@@ -51,7 +52,8 @@ public void ProjectLoaded(ProjectLoadedEventArgs args)
                 var hashedReferences = GetHashedReferences(args);
                 var (hashedFileExtensions, fileCounts) = GetUniqueHashedFileExtensionsAndCounts(args);
 
-                _eventEmitter.ProjectInformation(projectId, sessionId, (int)outputKind, projectCapabilities, targetFrameworks, sdkVersion, hashedReferences, hashedFileExtensions, fileCounts);
+                var sdkStyleProject = IsSdkStyleProject(args);
+                _eventEmitter.ProjectInformation(projectId, sessionId, (int)outputKind, projectCapabilities, targetFrameworks, sdkVersion, hashedReferences, hashedFileExtensions, fileCounts, sdkStyleProject);
             }
             catch (Exception ex)
             {
@@ -59,6 +61,18 @@ public void ProjectLoaded(ProjectLoadedEventArgs args)
             }
         }
 
+        private static bool IsSdkStyleProject(ProjectLoadedEventArgs args)
+        {
+            // To see if a project is an SDK style project we check for either of two things
+            //   1.  If it has a TargetFramework / TargetFrameworks property.  This isn't fully complete
+            //       as this property could come from a different props file
+            //   2.  If it imports an SDK.  This can be defined multiple ways in the project file, but
+            //       we can look at the resolved imports after evaluation to see if any are SDK based.
+            bool hasTargetFrameworkProperty = args.Project.Properties.Any(property => property.Name is "TargetFramework" or "TargetFrameworks");
+            bool importsSdk = args.Project.Imports.Any(import => import.SdkResult != null);
+            return hasTargetFrameworkProperty || importsSdk;
+        }
+
         private static (IEnumerable<HashedString> Extensions, IEnumerable<int> Counts) GetUniqueHashedFileExtensionsAndCounts(ProjectLoadedEventArgs args)
         {
             var contentFiles = args.ProjectInstance