diff --git a/src/System.Management.Automation/cimSupport/cmdletization/ScriptWriter.cs b/src/System.Management.Automation/cimSupport/cmdletization/ScriptWriter.cs index 5aa1b201fc..46484a35d0 100644 --- a/src/System.Management.Automation/cimSupport/cmdletization/ScriptWriter.cs +++ b/src/System.Management.Automation/cimSupport/cmdletization/ScriptWriter.cs @@ -517,13 +517,53 @@ function __cmdletization_BindCommonParameters Dbg.Assert(typeMetadata != null, "Caller should verify typeMetadata != null"); string psTypeText; - List matchingEnums = (_cmdletizationMetadata.Enums ?? Enumerable.Empty()) - .Where(e => Regex.IsMatch( - typeMetadata.PSType, - string.Format(CultureInfo.InvariantCulture, @"\b{0}\b", Regex.Escape(e.EnumName)), - RegexOptions.CultureInvariant)) - .ToList(); - EnumMetadataEnum matchingEnum = matchingEnums.Count == 1 ? matchingEnums[0] : null; + EnumMetadataEnum matchingEnum = null; + + if (_cmdletizationMetadata.Enums is not null) + { + string psType = typeMetadata.PSType; + foreach (EnumMetadataEnum e in _cmdletizationMetadata.Enums) + { + int index = psType.IndexOf(e.EnumName, StringComparison.Ordinal); + if (index == -1) + { + // Fast return if 'PSType' doesn't contain the enum name at all. + continue; + } + + bool matchFound = false; + if (index == 0) + { + // Handle 2 common cases here (cover over 99% of how enum name is used in 'PSType'): + // - 'PSType' is exactly the enum name. + // - 'PSType' is the array format of the enum. + ReadOnlySpan remains = psType.AsSpan(e.EnumName.Length); + matchFound = remains.Length is 0 || remains.Equals("[]", StringComparison.Ordinal); + } + + if (!matchFound) + { + // Now we have to fall back to the expensive regular expression matching, because 'PSType' + // could be a composite type like 'Nullable' or 'Dictionary', + // but we don't want the case where the enum name is part of another type's name. + matchFound = Regex.IsMatch(psType, $@"\b{Regex.Escape(e.EnumName)}\b"); + } + + if (matchFound) + { + if (matchingEnum is null) + { + matchingEnum = e; + continue; + } + + // If more than one matching enum names were found, we treat it as no match found. + matchingEnum = null; + break; + } + } + } + if (matchingEnum != null) { psTypeText = typeMetadata.PSType.Replace(matchingEnum.EnumName, EnumWriter.GetEnumFullName(matchingEnum));