From dd3a6a10d4e835f4d2d442623b1d93123a4ae9bb Mon Sep 17 00:00:00 2001 From: Ilya Date: Tue, 11 Oct 2022 23:50:16 +0500 Subject: [PATCH] Use source generator for `PSVersionInfo` to improve startup time (#15603) --- PowerShell.Common.props | 3 + .../PSVersionInfoGenerator.cs | 130 ++++++++++++++++++ .../PSVersionInfoGenerator.csproj | 18 +++ .../System.Management.Automation.csproj | 23 +++- .../engine/PSVersionInfo.cs | 58 +++----- 5 files changed, 190 insertions(+), 42 deletions(-) create mode 100644 src/System.Management.Automation/SourceGenerators/PSVersionInfoGenerator/PSVersionInfoGenerator.cs create mode 100644 src/System.Management.Automation/SourceGenerators/PSVersionInfoGenerator/PSVersionInfoGenerator.csproj diff --git a/PowerShell.Common.props b/PowerShell.Common.props index 5e7e41f147..8f784ede51 100644 --- a/PowerShell.Common.props +++ b/PowerShell.Common.props @@ -104,6 +104,9 @@ + + + + netstandard2.0 + 10.0 + true + + + + + + + diff --git a/src/System.Management.Automation/System.Management.Automation.csproj b/src/System.Management.Automation/System.Management.Automation.csproj index 75deb301ba..17938e9294 100644 --- a/src/System.Management.Automation/System.Management.Automation.csproj +++ b/src/System.Management.Automation/System.Management.Automation.csproj @@ -1,4 +1,4 @@ - + PowerShell's System.Management.Automation project @@ -6,6 +6,24 @@ System.Management.Automation + + + true + gen\SourceGenerated + + + + + + + + + + + + @@ -38,6 +56,9 @@ + + + diff --git a/src/System.Management.Automation/engine/PSVersionInfo.cs b/src/System.Management.Automation/engine/PSVersionInfo.cs index 169024508e..620577d8d4 100644 --- a/src/System.Management.Automation/engine/PSVersionInfo.cs +++ b/src/System.Management.Automation/engine/PSVersionInfo.cs @@ -3,7 +3,6 @@ using System.Collections; using System.Globalization; -using System.Reflection; using System.Text; using System.Text.RegularExpressions; @@ -27,7 +26,7 @@ namespace System.Management.Automation /// The above statement retrieves the PowerShell edition. /// /// - public static class PSVersionInfo + public static partial class PSVersionInfo { internal const string PSVersionTableName = "PSVersionTable"; internal const string PSRemotingProtocolVersionName = "PSRemotingProtocolVersion"; @@ -42,6 +41,18 @@ namespace System.Management.Automation private static readonly PSVersionHashTable s_psVersionTable; + /* + The following constants are generated by the source generator 'PSVersionInfoGenerator': + + internal const string ProductVersion; + internal const string GitCommitId; + + private const int Version_Major + private const int Version_Minor; + private const int Version_Patch; + private const string Version_Label; + */ + /// /// A constant to track current PowerShell Version. /// @@ -78,39 +89,14 @@ namespace System.Management.Automation { s_psVersionTable = new PSVersionHashTable(StringComparer.OrdinalIgnoreCase); - Assembly currentAssembly = typeof(PSVersionInfo).Assembly; - ProductVersion = currentAssembly.GetCustomAttribute().InformationalVersion; - - // Get 'GitCommitId' and 'PSVersion' from the 'productVersion' assembly attribute. - // - // The strings can be one of the following format examples: - // when powershell is built from a commit: - // productVersion = '6.0.0-beta.7 Commits: 29 SHA: 52c6b...' convert to GitCommitId = 'v6.0.0-beta.7-29-g52c6b...' - // PSVersion = '6.0.0-beta.7' - // when powershell is built from a release tag: - // productVersion = '6.0.0-beta.7 SHA: f1ec9...' convert to GitCommitId = 'v6.0.0-beta.7' - // PSVersion = '6.0.0-beta.7' - // when powershell is built from a release tag for RTM: - // productVersion = '6.0.0 SHA: f1ec9...' convert to GitCommitId = 'v6.0.0' - // PSVersion = '6.0.0' - string rawGitCommitId; - string mainVersion = ProductVersion.Substring(0, ProductVersion.IndexOf(' ')); - - if (ProductVersion.Contains(" Commits: ")) - { - rawGitCommitId = ProductVersion.Replace(" Commits: ", "-").Replace(" SHA: ", "-g"); - } - else - { - rawGitCommitId = mainVersion; - } - - s_psSemVersion = new SemanticVersion(mainVersion); + s_psSemVersion = Version_Label == string.Empty + ? new SemanticVersion(Version_Major, Version_Minor, Version_Patch) + : new SemanticVersion(Version_Major, Version_Minor, Version_Patch, Version_Label, buildLabel: null); s_psVersion = (Version)s_psSemVersion; s_psVersionTable[PSVersionName] = s_psSemVersion; s_psVersionTable[PSEditionName] = PSEditionValue; - s_psVersionTable[PSGitCommitIdName] = rawGitCommitId; + s_psVersionTable[PSGitCommitIdName] = GitCommitId; s_psVersionTable[PSCompatibleVersionsName] = new Version[] { s_psV1Version, s_psV2Version, s_psV3Version, s_psV4Version, s_psV5Version, s_psV51Version, s_psV6Version, s_psV61Version, s_psV62Version, s_psV7Version, s_psV71Version, s_psV72Version, s_psVersion }; s_psVersionTable[SerializationVersionName] = new Version(InternalSerializer.DefaultVersion); s_psVersionTable[PSRemotingProtocolVersionName] = RemotingConstants.ProtocolVersion; @@ -183,16 +169,6 @@ namespace System.Management.Automation } } - internal static string ProductVersion { get; } - - internal static string GitCommitId - { - get - { - return (string)s_psVersionTable[PSGitCommitIdName]; - } - } - /// /// Gets the edition of PowerShell. ///