public UnityProjectDataCache BuildData(FileSystemPath projectFileLocation, XmlDocument document) { var documentElement = document.DocumentElement; if (documentElement == null || documentElement.Name != "Project") { return(UnityProjectDataCache.Empty); } var explicitLangVersion = false; var unityVersion = new Version(0, 0); var appPath = UnityInstallationFinder.GetAppPathByDll(documentElement); var versionFromDll = UnityVersion.GetVersionByAppPath(appPath); foreach (XmlNode propertyGroup in documentElement.GetElementsByTagName("PropertyGroup")) { var xmlElement = propertyGroup as XmlElement; if (xmlElement == null) { continue; } // We can't just grab the value here because there may be multiple values set, one per configuration. // I haven't seen Unity or Rider do this, so it must be VSTU, but I don't have proof... if (xmlElement.GetElementsByTagName("LangVersion").Count > 0) { explicitLangVersion = true; } if (versionFromDll != null) { continue; } // Ideally, we could get the defines through the project model (see IManagedProjectConfiguration), but // that only seems to give us the currently active project settings, and Unity's own .csproj creator // only sets the version for the Debug build, not the Release build. VSTU sets the defines in both // configurations. foreach (XmlNode defines in xmlElement.GetElementsByTagName("DefineConstants")) { unityVersion = GetVersionFromDefines(defines.InnerText, unityVersion); } } return(new UnityProjectDataCache(versionFromDll ?? unityVersion, explicitLangVersion, appPath)); }