| File: NodeMode.cs | Web Access |
| Project: src\msbuild\src\Framework\Microsoft.Build.Framework.csproj (Microsoft.Build.Framework) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Diagnostics.CodeAnalysis; using System.Globalization; namespace Microsoft.Build.Framework { /// <summary> /// Enumeration of the various node modes that MSBuild.exe can run in. /// </summary> internal enum NodeMode { /// <summary> /// Normal out-of-process node. /// </summary> OutOfProcNode = 1, /// <summary> /// Out-of-process task host node. /// </summary> OutOfProcTaskHostNode = 2, /// <summary> /// Out-of-process RAR (ResolveAssemblyReference) service node. /// </summary> OutOfProcRarNode = 3, /// <summary> /// Out-of-process server node. /// </summary> OutOfProcServerNode = 8, } /// <summary> /// Helper methods for the NodeMode enum. /// </summary> internal static partial class NodeModeHelper { /// <summary> /// Converts a NodeMode value to a command line argument string. /// </summary> /// <param name="nodeMode">The node mode to convert</param> /// <returns>The command line argument string (e.g., "/nodemode:1")</returns> public static string ToCommandLineArgument(NodeMode nodeMode) => $"/nodemode:{(int)nodeMode}"; /// <summary> /// Tries to parse a node mode value from a string, supporting both integer values and enum names (case-insensitive). /// </summary> /// <param name="value">The value to parse (can be an integer or enum name)</param> /// <param name="nodeMode">The parsed NodeMode value if successful</param> /// <returns>True if parsing succeeded, false otherwise</returns> public static bool TryParse(string value, [NotNullWhen(true)] out NodeMode? nodeMode) { #if NET return TryParseImpl(value.AsSpan(), out nodeMode); #else return TryParseImpl(value, out nodeMode); #endif } #if NET /// <summary> /// Tries to parse a node mode value from a span, supporting both integer values and enum names (case-insensitive). /// </summary> /// <param name="value">The value to parse (can be an integer or enum name)</param> /// <param name="nodeMode">The parsed NodeMode value if successful</param> /// <returns>True if parsing succeeded, false otherwise</returns> public static bool TryParse(ReadOnlySpan<char> value, [NotNullWhen(true)] out NodeMode? nodeMode) { return TryParseImpl(value, out nodeMode); } #endif #if NET private static bool TryParseImpl(ReadOnlySpan<char> value, [NotNullWhen(true)] out NodeMode? nodeMode) #else private static bool TryParseImpl(string value, [NotNullWhen(true)] out NodeMode? nodeMode) #endif { nodeMode = null; #if NET if (value.IsEmpty || value.IsWhiteSpace()) { return false; } #else if (string.IsNullOrWhiteSpace(value)) { return false; } #endif // First try to parse as an integer for backward compatibility if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out int intValue)) { // Validate that the integer corresponds to a valid enum value if (Enum.IsDefined(typeof(NodeMode), intValue)) { nodeMode = (NodeMode)intValue; return true; } return false; } // Try to parse as an enum name (case-insensitive) if (Enum.TryParse(value, ignoreCase: true, out NodeMode enumValue) && Enum.IsDefined(typeof(NodeMode), enumValue)) { nodeMode = enumValue; return true; } return false; } /// <summary> /// Extracts the NodeMode from a command line string using regex pattern matching. /// </summary> /// <param name="commandLine">The command line to parse. Note that this can't be a span because generated regex don't have a Span Match overload</param> /// <returns>The NodeMode if found, otherwise null</returns> public static NodeMode? ExtractFromCommandLine(string commandLine) { if (string.IsNullOrWhiteSpace(commandLine)) { return null; } var match = CommandLineNodeModeRegex.Match(commandLine); if (!match.Success) { return null; } #if NET if (TryParse(match.Groups["nodemode"].ValueSpan, out NodeMode? nodeMode)) #else if (TryParse(match.Groups["nodemode"].Value, out NodeMode? nodeMode)) #endif { return nodeMode; } return null; } private const string CommandLineNodeModePattern = @"/nodemode:(?<nodemode>[a-zA-Z0-9]+)(?:\s|$)"; #if NET [System.Text.RegularExpressions.GeneratedRegex(CommandLineNodeModePattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase)] private static partial System.Text.RegularExpressions.Regex CommandLineNodeModeRegex { get; } #else private static System.Text.RegularExpressions.Regex CommandLineNodeModeRegex { get; } = new( CommandLineNodeModePattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase | System.Text.RegularExpressions.RegexOptions.Compiled); #endif } }