diff --git a/src/Microsoft.Management.UI.Internal/ShowCommand/ViewModel/CommandViewModel.cs b/src/Microsoft.Management.UI.Internal/ShowCommand/ViewModel/CommandViewModel.cs index c5e2502882..d6bb68bbc2 100644 --- a/src/Microsoft.Management.UI.Internal/ShowCommand/ViewModel/CommandViewModel.cs +++ b/src/Microsoft.Management.UI.Internal/ShowCommand/ViewModel/CommandViewModel.cs @@ -429,7 +429,7 @@ namespace Microsoft.PowerShell.Commands.ShowCommandInternal commandName = this.ModuleName + "\\" + commandName; } - if (commandName.IndexOf(' ') != -1) + if (commandName.Contains(' ')) { builder.AppendFormat("& \"{0}\"", commandName); } diff --git a/src/Microsoft.Management.UI.Internal/ShowCommand/ViewModel/ModuleViewModel.cs b/src/Microsoft.Management.UI.Internal/ShowCommand/ViewModel/ModuleViewModel.cs index 66a768940c..dd37c7c09d 100644 --- a/src/Microsoft.Management.UI.Internal/ShowCommand/ViewModel/ModuleViewModel.cs +++ b/src/Microsoft.Management.UI.Internal/ShowCommand/ViewModel/ModuleViewModel.cs @@ -435,21 +435,21 @@ namespace Microsoft.PowerShell.Commands.ShowCommandInternal /// Return match result. private static bool MatchesEvenIfInPlural(string commandName, string filter) { - if (commandName.IndexOf(filter, StringComparison.OrdinalIgnoreCase) != -1) + if (commandName.Contains(filter, StringComparison.OrdinalIgnoreCase)) { return true; } if (filter.Length > 5 && filter.EndsWith("es", StringComparison.OrdinalIgnoreCase)) { - filter = filter.Substring(0, filter.Length - 2); - return commandName.IndexOf(filter, StringComparison.OrdinalIgnoreCase) != -1; + ReadOnlySpan filterSpan = filter.AsSpan(0, filter.Length - 2); + return commandName.AsSpan().Contains(filterSpan, StringComparison.OrdinalIgnoreCase); } if (filter.Length > 4 && filter.EndsWith("s", StringComparison.OrdinalIgnoreCase)) { - filter = filter.Substring(0, filter.Length - 1); - return commandName.IndexOf(filter, StringComparison.OrdinalIgnoreCase) != -1; + ReadOnlySpan filterSpan = filter.AsSpan(0, filter.Length - 1); + return commandName.AsSpan().Contains(filterSpan, StringComparison.OrdinalIgnoreCase); } return false; diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimConverter.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimConverter.cs index abcb5d33f6..8fdb0fda75 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimConverter.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimConverter.cs @@ -459,8 +459,8 @@ namespace Microsoft.PowerShell.Cim return exceptionSafeReturn(delegate { int indexOfLastColon = cimIntrinsicValue.LastIndexOf(':'); - int port = int.Parse(cimIntrinsicValue.Substring(indexOfLastColon + 1), NumberStyles.Integer, CultureInfo.InvariantCulture); - IPAddress address = IPAddress.Parse(cimIntrinsicValue.Substring(0, indexOfLastColon)); + int port = int.Parse(cimIntrinsicValue.AsSpan(indexOfLastColon + 1), NumberStyles.Integer, CultureInfo.InvariantCulture); + IPAddress address = IPAddress.Parse(cimIntrinsicValue.AsSpan(0, indexOfLastColon)); return new IPEndPoint(address, port); }); } diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/OrderObjectBase.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/OrderObjectBase.cs index a7258cb1bb..8254f98a7e 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/OrderObjectBase.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/OrderObjectBase.cs @@ -72,7 +72,7 @@ namespace Microsoft.PowerShell.Commands if (trimmedValue.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) { if ((trimmedValue.Length > 2) && - int.TryParse(trimmedValue.Substring(2), NumberStyles.AllowHexSpecifier, + int.TryParse(trimmedValue.AsSpan(2), NumberStyles.AllowHexSpecifier, CultureInfo.CurrentCulture, out cultureNumber)) { _cultureInfo = new CultureInfo(cultureNumber); diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommand.cs index 2e260c5953..8b9213c6fd 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommand.cs @@ -377,7 +377,7 @@ namespace Microsoft.PowerShell.Commands try { - _commandViewModelObj = _showCommandProxy.GetCommandViewModel(new ShowCommandCommandInfo(commandInfo), _noCommonParameter.ToBool(), _importedModules, this.Name.IndexOf('\\') != -1); + _commandViewModelObj = _showCommandProxy.GetCommandViewModel(new ShowCommandCommandInfo(commandInfo), _noCommonParameter.ToBool(), _importedModules, this.Name.Contains('\\')); _showCommandProxy.ShowCommandWindow(_commandViewModelObj, _passThrough); } catch (TargetInvocationException ti) diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs index 1addb3dc5b..7cf189fb98 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs @@ -1865,8 +1865,11 @@ namespace Microsoft.PowerShell /// The string with any \0 characters removed... private string RemoveNulls(string input) { - if (input.IndexOf('\0') == -1) + if (input.Contains('\0')) + { return input; + } + StringBuilder sb = new StringBuilder(); foreach (char c in input) { diff --git a/src/Microsoft.WSMan.Management/ConfigProvider.cs b/src/Microsoft.WSMan.Management/ConfigProvider.cs index ccb03bc954..5a6c4d75cb 100644 --- a/src/Microsoft.WSMan.Management/ConfigProvider.cs +++ b/src/Microsoft.WSMan.Management/ConfigProvider.cs @@ -4105,7 +4105,7 @@ namespace Microsoft.WSMan.Management PSObject obj = (PSObject)objcache[CurrentNode]; CurrentNode = RemainingPath.Substring(pos + 1); - if (CurrentNode.IndexOf(WSManStringLiterals.DefaultPathSeparator) != -1) + if (CurrentNode.Contains(WSManStringLiterals.DefaultPathSeparator)) { // No more directories allowed after listeners objects return false; diff --git a/src/System.Management.Automation/FormatAndOutput/common/TableWriter.cs b/src/System.Management.Automation/FormatAndOutput/common/TableWriter.cs index f01cc9b849..c9974a6483 100644 --- a/src/System.Management.Automation/FormatAndOutput/common/TableWriter.cs +++ b/src/System.Management.Automation/FormatAndOutput/common/TableWriter.cs @@ -436,7 +436,7 @@ namespace Microsoft.PowerShell.Commands.Internal.Format } sb.Append(GenerateRowField(values[k], _si.columnInfo[k].width, alignment[k], dc, addPadding)); - if (values[k].IndexOf(ESC) != -1) + if (values[k].Contains(ESC)) { // Reset the console output if the content of this column contains ESC sb.Append(ResetConsoleVt100Code); diff --git a/src/System.Management.Automation/FormatAndOutput/common/Utilities/MshParameter.cs b/src/System.Management.Automation/FormatAndOutput/common/Utilities/MshParameter.cs index c037fa29df..53f379a59e 100644 --- a/src/System.Management.Automation/FormatAndOutput/common/Utilities/MshParameter.cs +++ b/src/System.Management.Automation/FormatAndOutput/common/Utilities/MshParameter.cs @@ -177,7 +177,7 @@ namespace Microsoft.PowerShell.Commands.Internal.Format if (key.Length < normalizedKey.Length) { // shorter, could be an abbreviation - if (string.Equals(key, normalizedKey.Substring(0, key.Length), StringComparison.OrdinalIgnoreCase)) + if (key.AsSpan().Equals(normalizedKey.AsSpan(0, key.Length), StringComparison.OrdinalIgnoreCase)) { // found abbreviation return true; diff --git a/src/System.Management.Automation/engine/CmdletParameterBinderController.cs b/src/System.Management.Automation/engine/CmdletParameterBinderController.cs index 4991d2623b..5914c900e4 100644 --- a/src/System.Management.Automation/engine/CmdletParameterBinderController.cs +++ b/src/System.Management.Automation/engine/CmdletParameterBinderController.cs @@ -3173,7 +3173,7 @@ namespace System.Management.Automation for (int i = 0; i < parameterName.Length; i++) { // try Upper case - if (char.IsUpper(parameterName[i]) && (usedHotKeysStr.IndexOf(parameterName[i]) == -1)) + if (char.IsUpper(parameterName[i]) && usedHotKeysStr.Contains(parameterName[i])) { label.Insert(i, hotKeyPrefix); usedHotKeys.Append(parameterName[i]); @@ -3187,7 +3187,7 @@ namespace System.Management.Automation // try Lower case for (int i = 0; i < parameterName.Length; i++) { - if (char.IsLower(parameterName[i]) && (usedHotKeysStr.IndexOf(parameterName[i]) == -1)) + if (char.IsLower(parameterName[i]) && usedHotKeysStr.Contains(parameterName[i])) { label.Insert(i, hotKeyPrefix); usedHotKeys.Append(parameterName[i]); @@ -3202,7 +3202,7 @@ namespace System.Management.Automation // try non-letters for (int i = 0; i < parameterName.Length; i++) { - if (!char.IsLetter(parameterName[i]) && (usedHotKeysStr.IndexOf(parameterName[i]) == -1)) + if (!char.IsLetter(parameterName[i]) && usedHotKeysStr.Contains(parameterName[i])) { label.Insert(i, hotKeyPrefix); usedHotKeys.Append(parameterName[i]); diff --git a/src/System.Management.Automation/engine/ComInterop/VariantArray.cs b/src/System.Management.Automation/engine/ComInterop/VariantArray.cs index d8c0a90384..77f4c6b377 100644 --- a/src/System.Management.Automation/engine/ComInterop/VariantArray.cs +++ b/src/System.Management.Automation/engine/ComInterop/VariantArray.cs @@ -77,7 +77,7 @@ namespace System.Management.Automation.ComInterop // See if we can find an existing type foreach (Type t in s_generatedTypes) { - int arity = int.Parse(t.Name.Substring("VariantArray".Length), CultureInfo.InvariantCulture); + int arity = int.Parse(t.Name.AsSpan("VariantArray".Length), NumberStyles.Integer, CultureInfo.InvariantCulture); if (size == arity) { return t; diff --git a/src/System.Management.Automation/engine/CommandCompletion/CompletionAnalysis.cs b/src/System.Management.Automation/engine/CommandCompletion/CompletionAnalysis.cs index 8d533edc3e..e96914f96b 100644 --- a/src/System.Management.Automation/engine/CommandCompletion/CompletionAnalysis.cs +++ b/src/System.Management.Automation/engine/CommandCompletion/CompletionAnalysis.cs @@ -1514,19 +1514,18 @@ namespace System.Management.Automation var analysis = new CompletionAnalysis(_ast, _tokens, _cursorPosition, _options); var subContext = analysis.CreateCompletionContext(completionContext.TypeInferenceContext); - int subReplaceIndex, subReplaceLength; - var subResult = analysis.GetResultHelper(subContext, out subReplaceIndex, out subReplaceLength, true); + var subResult = analysis.GetResultHelper(subContext, out int subReplaceIndex, out _, true); if (subResult != null && subResult.Count > 0) { result = new List(); replacementIndex = stringStartIndex + 1 + (cursorIndexInString - subInput.Length); replacementLength = subInput.Length; - string prefix = subInput.Substring(0, subReplaceIndex); + ReadOnlySpan prefix = subInput.AsSpan(0, subReplaceIndex); foreach (CompletionResult entry in subResult) { - string completionText = prefix + entry.CompletionText; + string completionText = string.Concat(prefix, entry.CompletionText.AsSpan()); if (entry.ResultType == CompletionResultType.Property) { completionText = TokenKind.DollarParen.Text() + completionText + TokenKind.RParen.Text(); @@ -1565,7 +1564,7 @@ namespace System.Management.Automation result = new List(CompletionCompleters.CompleteFilename(completionContext)); // Try command name completion only if the text contains '-' - if (wordToComplete.IndexOf('-') != -1) + if (wordToComplete.Contains('-')) { var commandNameResult = CompletionCompleters.CompleteCommand(completionContext); if (commandNameResult != null && commandNameResult.Count > 0) diff --git a/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs b/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs index c63ef8f05f..86657f92f3 100644 --- a/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs +++ b/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs @@ -1164,7 +1164,7 @@ namespace System.Management.Automation var tryCmdletCompletion = false; var clearLiteralPathsKey = TurnOnLiteralPathOption(context); - if (context.WordToComplete.IndexOf('-') != -1) + if (context.WordToComplete.Contains('-')) { tryCmdletCompletion = true; } @@ -1224,7 +1224,7 @@ namespace System.Management.Automation } // Handle member completion with wildcard: echo $a.* - if (pathAst.Value.IndexOf('*') != -1 && secondToLastMemberAst != null && + if (pathAst.Value.Contains('*') && secondToLastMemberAst != null && secondToLastMemberAst.Extent.EndLineNumber == pathAst.Extent.StartLineNumber && secondToLastMemberAst.Extent.EndColumnNumber == pathAst.Extent.StartColumnNumber) { @@ -1328,7 +1328,7 @@ namespace System.Management.Automation context.Options.Remove("LiteralPaths"); } - if (context.WordToComplete != string.Empty && context.WordToComplete.IndexOf('-') != -1) + if (context.WordToComplete != string.Empty && context.WordToComplete.Contains('-')) { var commandResults = CompleteCommand(context); if (commandResults != null) @@ -3844,7 +3844,7 @@ namespace System.Management.Automation wordToComplete = wordToComplete.Substring(1, wordToComplete.Length - (endQuoted ? 2 : 1)); } - if (wordToComplete.IndexOf('[') != -1) + if (wordToComplete.Contains('[')) { var cursor = (InternalScriptPosition)context.CursorPosition; cursor = cursor.CloneWithNewOffset(cursor.Offset - context.TokenAtCursor.Extent.StartOffset - (isQuoted ? 1 : 0)); @@ -5632,7 +5632,7 @@ namespace System.Management.Automation // If the completion included a namespace and ToStringCodeMethods.Type found // an accelerator, then just use the type's FullName instead because the user // probably didn't want the accelerator. - if (keyMatched.IndexOf('.') != -1 && completion.IndexOf('.') == -1) + if (keyMatched.Contains('.') && !completion.Contains('.')) { completion = Type.FullName; } @@ -6624,7 +6624,7 @@ namespace System.Management.Automation } string tooltip = memberInfo.ToString(); - if (tooltip.IndexOf("),", StringComparison.Ordinal) != -1) + if (tooltip.Contains("),", StringComparison.Ordinal)) { var overloads = tooltip.Split("),", StringSplitOptions.RemoveEmptyEntries); var newTooltip = new StringBuilder(); diff --git a/src/System.Management.Automation/engine/ExperimentalFeature/ExperimentalFeature.cs b/src/System.Management.Automation/engine/ExperimentalFeature/ExperimentalFeature.cs index dad066f2bf..452e7bcd7f 100644 --- a/src/System.Management.Automation/engine/ExperimentalFeature/ExperimentalFeature.cs +++ b/src/System.Management.Automation/engine/ExperimentalFeature/ExperimentalFeature.cs @@ -208,7 +208,7 @@ namespace System.Management.Automation /// internal static bool IsEngineFeatureName(string featureName) { - return featureName.Length > 2 && featureName.IndexOf('.') == -1 && featureName.StartsWith("PS", StringComparison.Ordinal); + return featureName.Length > 2 && !featureName.Contains('.') && featureName.StartsWith("PS", StringComparison.Ordinal); } /// diff --git a/src/System.Management.Automation/engine/Modules/GetModuleCommand.cs b/src/System.Management.Automation/engine/Modules/GetModuleCommand.cs index 2104142987..08b936a785 100644 --- a/src/System.Management.Automation/engine/Modules/GetModuleCommand.cs +++ b/src/System.Management.Automation/engine/Modules/GetModuleCommand.cs @@ -440,7 +440,7 @@ namespace Microsoft.PowerShell.Commands { foreach (var n in names) { - if (n.IndexOf(StringLiterals.DefaultPathSeparator) != -1 || n.IndexOf(StringLiterals.AlternatePathSeparator) != -1) + if (n.Contains(StringLiterals.DefaultPathSeparator) || n.Contains(StringLiterals.AlternatePathSeparator)) { string errorMessage = StringUtil.Format(stringFormat, n); var argumentException = new ArgumentException(errorMessage); diff --git a/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs b/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs index 986e1deff5..7506262ac1 100644 --- a/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs +++ b/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs @@ -925,7 +925,7 @@ namespace Microsoft.PowerShell.Commands { foreach (var n in names) { - if (n.IndexOf(StringLiterals.DefaultPathSeparator) != -1 || n.IndexOf(StringLiterals.AlternatePathSeparator) != -1) + if (n.Contains(StringLiterals.DefaultPathSeparator) || n.Contains(StringLiterals.AlternatePathSeparator)) { modulePaths.Add(n); } diff --git a/src/System.Management.Automation/engine/NativeCommandParameterBinder.cs b/src/System.Management.Automation/engine/NativeCommandParameterBinder.cs index 68d1fd2f19..580c1580b5 100644 --- a/src/System.Management.Automation/engine/NativeCommandParameterBinder.cs +++ b/src/System.Management.Automation/engine/NativeCommandParameterBinder.cs @@ -81,7 +81,7 @@ namespace System.Management.Automation if (parameter.ParameterNameSpecified) { - Diagnostics.Assert(parameter.ParameterText.IndexOf(' ') == -1, "Parameters cannot have whitespace"); + Diagnostics.Assert(!parameter.ParameterText.Contains(' '), "Parameters cannot have whitespace"); PossiblyGlobArg(parameter.ParameterText, usedQuotes: false); if (parameter.SpaceAfterParameter) diff --git a/src/System.Management.Automation/engine/ParameterBinderController.cs b/src/System.Management.Automation/engine/ParameterBinderController.cs index 6bad34823b..8524462c81 100644 --- a/src/System.Management.Automation/engine/ParameterBinderController.cs +++ b/src/System.Management.Automation/engine/ParameterBinderController.cs @@ -345,7 +345,7 @@ namespace System.Management.Automation { param = CommandParameterInternal.CreateParameterWithArgument( /*parameterAst*/null, paramText.Substring(1, colonIndex - 1), paramText, - /*argumentAst*/null, paramText.Substring(colonIndex + 1).Trim(), + /*argumentAst*/null, paramText.AsSpan(colonIndex + 1).Trim().ToString(), false); } else if (argIndex == arguments.Length - 1 || paramText[paramText.Length - 1] != ':') diff --git a/src/System.Management.Automation/engine/ParameterSetInfo.cs b/src/System.Management.Automation/engine/ParameterSetInfo.cs index 240a242fcd..f31d2f7241 100644 --- a/src/System.Management.Automation/engine/ParameterSetInfo.cs +++ b/src/System.Management.Automation/engine/ParameterSetInfo.cs @@ -292,7 +292,7 @@ namespace System.Management.Automation } // If the type is really an array, but the typename didn't include [], then add it. - if (type.IsArray && (parameterTypeString.IndexOf("[]", StringComparison.Ordinal) == -1)) + if (type.IsArray && !parameterTypeString.Contains("[]", StringComparison.Ordinal)) { var t = type; while (t.IsArray) diff --git a/src/System.Management.Automation/engine/debugger/Breakpoint.cs b/src/System.Management.Automation/engine/debugger/Breakpoint.cs index 30d83e5769..ade266e6c5 100644 --- a/src/System.Management.Automation/engine/debugger/Breakpoint.cs +++ b/src/System.Management.Automation/engine/debugger/Breakpoint.cs @@ -220,7 +220,7 @@ namespace System.Management.Automation // If the breakpoint looks like it might have specified a module name and the command // we're checking is in a module, try matching the module\command against the pattern // in the breakpoint. - if (!string.IsNullOrEmpty(commandInfo.ModuleName) && Command.IndexOf('\\') != -1) + if (!string.IsNullOrEmpty(commandInfo.ModuleName) && Command.Contains('\\')) { if (CommandPattern.IsMatch(commandInfo.ModuleName + "\\" + commandInfo.Name)) return true; diff --git a/src/System.Management.Automation/engine/hostifaces/MshHostUserInterface.cs b/src/System.Management.Automation/engine/hostifaces/MshHostUserInterface.cs index 38166d0b8e..45c0b44df7 100644 --- a/src/System.Management.Automation/engine/hostifaces/MshHostUserInterface.cs +++ b/src/System.Management.Automation/engine/hostifaces/MshHostUserInterface.cs @@ -1247,7 +1247,7 @@ namespace System.Management.Automation.Host if (andPos + 1 < choices[i].Label.Length) { splitLabel.Append(choices[i].Label.Substring(andPos + 1)); - hotkeysAndPlainLabels[0, i] = CultureInfo.CurrentCulture.TextInfo.ToUpper(choices[i].Label.Substring(andPos + 1, 1).Trim()); + hotkeysAndPlainLabels[0, i] = CultureInfo.CurrentCulture.TextInfo.ToUpper(choices[i].Label.AsSpan(andPos + 1, 1).Trim().ToString()); } hotkeysAndPlainLabels[1, i] = splitLabel.ToString().Trim(); diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index 314680c932..94b4e84295 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -68,7 +68,7 @@ namespace System.Management.Automation.Language var parser = new Parser(); if (!string.IsNullOrEmpty(fileName) && fileName.Length > scriptSchemaExtension.Length && fileName.EndsWith(scriptSchemaExtension, StringComparison.OrdinalIgnoreCase)) { - parser._keywordModuleName = Path.GetFileName(fileName.Substring(0, fileName.Length - scriptSchemaExtension.Length)); + parser._keywordModuleName = Path.GetFileName(fileName.AsSpan(0, fileName.Length - scriptSchemaExtension.Length)).ToString(); parseDscResource = true; } @@ -8107,7 +8107,7 @@ namespace System.Management.Automation.Language internal static string GetFileOrScript(string fileName, string input) { - return fileName ?? input.Substring(0, Math.Min(256, input.Length)).Trim(); + return fileName ?? input.AsSpan(0, Math.Min(256, input.Length)).Trim().ToString(); } } } diff --git a/src/System.Management.Automation/engine/parser/Position.cs b/src/System.Management.Automation/engine/parser/Position.cs index f26054174e..b7e63532cc 100644 --- a/src/System.Management.Automation/engine/parser/Position.cs +++ b/src/System.Management.Automation/engine/parser/Position.cs @@ -150,7 +150,7 @@ namespace System.Management.Automation.Language : sourceLine.Length - position.StartColumnNumber + 1; // Expand tabs before figuring out if we need to truncate the line - if (sourceLine.IndexOf('\t') != -1) + if (sourceLine.Contains('\t')) { var copyLine = new StringBuilder(sourceLine.Length * 2); diff --git a/src/System.Management.Automation/engine/parser/ast.cs b/src/System.Management.Automation/engine/parser/ast.cs index 460ef64f8b..b1dd14464f 100644 --- a/src/System.Management.Automation/engine/parser/ast.cs +++ b/src/System.Management.Automation/engine/parser/ast.cs @@ -1238,7 +1238,7 @@ namespace System.Management.Automation.Language string varSign = varAst.Splatted ? "@" : "$"; string newVarName = varSign + UsingExpressionAst.UsingPrefix + varName; - newScript.Append(script.Substring(startOffset, astStartOffset - startOffset)); + newScript.Append(script.AsSpan(startOffset, astStartOffset - startOffset)); newScript.Append(newVarName); startOffset = astEndOffset; } @@ -1259,13 +1259,13 @@ namespace System.Management.Automation.Language newParams += ",\n"; } - newScript.Append(script.Substring(startOffset, currentOffset - startOffset)); + newScript.Append(script.AsSpan(startOffset, currentOffset - startOffset)); newScript.Append(newParams); startOffset = currentOffset; } } - newScript.Append(script.Substring(startOffset, endOffset - startOffset)); + newScript.Append(script.AsSpan(startOffset, endOffset - startOffset)); string result = newScript.ToString(); if (Parent != null && initialStartOffset == this.Extent.StartOffset && initialEndOffset == this.Extent.EndOffset) @@ -2304,7 +2304,7 @@ namespace System.Management.Automation.Language string varSign = varAst.Splatted ? "@" : "$"; string newVarName = varSign + UsingExpressionAst.UsingPrefix + varName; - newParamText.Append(paramText.Substring(startOffset, astStartOffset - startOffset)); + newParamText.Append(paramText.AsSpan(startOffset, astStartOffset - startOffset)); newParamText.Append(newVarName); startOffset = astEndOffset; } while (orderedUsingVar.MoveNext()); @@ -2315,7 +2315,7 @@ namespace System.Management.Automation.Language return paramText; } - newParamText.Append(paramText.Substring(startOffset, endOffset - startOffset)); + newParamText.Append(paramText.AsSpan(startOffset, endOffset - startOffset)); return newParamText.ToString(); } @@ -6643,17 +6643,17 @@ namespace System.Management.Automation.Language string paramName = entry.Key; var paramValue = entry.Value; - if ((paramName.Length <= nameParam.Length) && (paramName.Equals(nameParam.Substring(0, paramName.Length), StringComparison.OrdinalIgnoreCase))) + if ((paramName.Length <= nameParam.Length) && (paramName.AsSpan().Equals(nameParam.AsSpan(0, paramName.Length), StringComparison.OrdinalIgnoreCase))) { resourceNames = paramValue; } // Since both parameters -ModuleName and -ModuleVersion has same start string i.e. Module so we will try to resolve it to -ModuleName // if user specifies like -Module - if ((paramName.Length <= moduleNameParam.Length) && (paramName.Equals(moduleNameParam.Substring(0, paramName.Length), StringComparison.OrdinalIgnoreCase))) + if ((paramName.Length <= moduleNameParam.Length) && (paramName.AsSpan().Equals(moduleNameParam.AsSpan(0, paramName.Length), StringComparison.OrdinalIgnoreCase))) { moduleNames = paramValue; } - else if ((paramName.Length <= moduleVersionParam.Length) && (paramName.Equals(moduleVersionParam.Substring(0, paramName.Length), StringComparison.OrdinalIgnoreCase))) + else if ((paramName.Length <= moduleVersionParam.Length) && (paramName.AsSpan().Equals(moduleVersionParam.AsSpan(0, paramName.Length), StringComparison.OrdinalIgnoreCase))) { moduleVersion = paramValue; } @@ -8401,7 +8401,7 @@ namespace System.Management.Automation.Language int lastDotIndex = fullTypeName.LastIndexOf('.'); if (lastDotIndex >= 0) { - return fullTypeName.Substring(lastDotIndex + 1).Equals(Name, StringComparison.OrdinalIgnoreCase); + return fullTypeName.AsSpan(lastDotIndex + 1).Equals(Name, StringComparison.OrdinalIgnoreCase); } return false; diff --git a/src/System.Management.Automation/engine/remoting/client/Job.cs b/src/System.Management.Automation/engine/remoting/client/Job.cs index 0cf3977f40..63847c3f69 100644 --- a/src/System.Management.Automation/engine/remoting/client/Job.cs +++ b/src/System.Management.Automation/engine/remoting/client/Job.cs @@ -510,7 +510,7 @@ namespace System.Management.Automation { Dbg.Assert(scriptExtent.StartScriptPosition.ColumnNumber > 0, "Column numbers start at 1"); Dbg.Assert(scriptExtent.StartScriptPosition.ColumnNumber <= scriptExtent.StartScriptPosition.Line.Length, "Column numbers are not greater than the length of a line"); - return scriptExtent.StartScriptPosition.Line.Substring(scriptExtent.StartScriptPosition.ColumnNumber - 1).Trim(); + return scriptExtent.StartScriptPosition.Line.AsSpan(scriptExtent.StartScriptPosition.ColumnNumber - 1).Trim().ToString(); } return invocationInfo.InvocationName; diff --git a/src/System.Management.Automation/engine/remoting/client/RemoteRunspacePoolInternal.cs b/src/System.Management.Automation/engine/remoting/client/RemoteRunspacePoolInternal.cs index 811baef9dc..b401f0f96b 100644 --- a/src/System.Management.Automation/engine/remoting/client/RemoteRunspacePoolInternal.cs +++ b/src/System.Management.Automation/engine/remoting/client/RemoteRunspacePoolInternal.cs @@ -2151,7 +2151,7 @@ namespace System.Management.Automation.Runspaces.Internal private static bool CheckForSSL(WSManConnectionInfo wsmanConnectionInfo) { return (!string.IsNullOrEmpty(wsmanConnectionInfo.Scheme) && - wsmanConnectionInfo.Scheme.IndexOf(WSManConnectionInfo.HttpsScheme, StringComparison.OrdinalIgnoreCase) != -1); + wsmanConnectionInfo.Scheme.Contains(WSManConnectionInfo.HttpsScheme, StringComparison.OrdinalIgnoreCase)); } private static int ConvertPSAuthToWSManAuth(AuthenticationMechanism psAuth) diff --git a/src/System.Management.Automation/engine/remoting/commands/EnterPSHostProcessCommand.cs b/src/System.Management.Automation/engine/remoting/commands/EnterPSHostProcessCommand.cs index cf06c4cda1..21614338af 100644 --- a/src/System.Management.Automation/engine/remoting/commands/EnterPSHostProcessCommand.cs +++ b/src/System.Management.Automation/engine/remoting/commands/EnterPSHostProcessCommand.cs @@ -648,7 +648,7 @@ namespace Microsoft.PowerShell.Commands int pAppDomainIndex = namedPipe.IndexOf('.', pIdIndex + 1); if (pAppDomainIndex > -1) { - string idString = namedPipe.Substring(pIdIndex + 1, (pAppDomainIndex - pIdIndex - 1)); + ReadOnlySpan idString = namedPipe.AsSpan(pIdIndex + 1, (pAppDomainIndex - pIdIndex - 1)); int id = -1; if (int.TryParse(idString, out id)) { diff --git a/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs b/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs index 937fa7dfab..1b28947623 100644 --- a/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs +++ b/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs @@ -1439,7 +1439,7 @@ namespace System.Management.Automation.Runspaces return (EnableNetworkAccess && // Interactive token requested (Credential == null && // No credential provided (ComputerName.Equals(DefaultComputerName, StringComparison.OrdinalIgnoreCase) || // Localhost computer name - ComputerName.IndexOf('.') == -1))); // Not FQDN computer name + !ComputerName.Contains('.')))); // Not FQDN computer name } } diff --git a/src/System.Management.Automation/engine/remoting/fanin/InitialSessionStateProvider.cs b/src/System.Management.Automation/engine/remoting/fanin/InitialSessionStateProvider.cs index 0d25baf5f8..dfcd8b4496 100644 --- a/src/System.Management.Automation/engine/remoting/fanin/InitialSessionStateProvider.cs +++ b/src/System.Management.Automation/engine/remoting/fanin/InitialSessionStateProvider.cs @@ -1896,7 +1896,7 @@ namespace System.Management.Automation.Remoting private string GetRoleCapabilityPath(string roleCapability) { string moduleName = "*"; - if (roleCapability.IndexOf('\\') != -1) + if (roleCapability.Contains('\\')) { string[] components = roleCapability.Split(Utils.Separators.Backslash, 2); moduleName = components[0]; diff --git a/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs b/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs index 35913a1f7b..c4f9f9d0d7 100644 --- a/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs +++ b/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs @@ -760,7 +760,7 @@ namespace System.Management.Automation.Remoting.Client try { // Route protocol message based on whether it is a session or command message. - if (data.IndexOf(SESSIONDMESSAGETAG, StringComparison.OrdinalIgnoreCase) > -1) + if (data.Contains(SESSIONDMESSAGETAG, StringComparison.OrdinalIgnoreCase)) { // Session message _sessionMessageQueue.Add(data); @@ -1708,7 +1708,7 @@ namespace System.Management.Automation.Remoting.Client } if ((error.Length == 0) || - error.IndexOf("WARNING:", StringComparison.OrdinalIgnoreCase) > -1) + error.Contains("WARNING:", StringComparison.OrdinalIgnoreCase)) { // Handle as interactive warning message Console.WriteLine(error); diff --git a/src/System.Management.Automation/engine/remoting/server/ServerRunspacePoolDriver.cs b/src/System.Management.Automation/engine/remoting/server/ServerRunspacePoolDriver.cs index d2aa643079..b3335cb7d0 100644 --- a/src/System.Management.Automation/engine/remoting/server/ServerRunspacePoolDriver.cs +++ b/src/System.Management.Automation/engine/remoting/server/ServerRunspacePoolDriver.cs @@ -890,8 +890,8 @@ namespace System.Management.Automation } else if (powershell.Commands.Commands.Count == 1 && !powershell.Commands.Commands[0].IsScript && - ((powershell.Commands.Commands[0].CommandText.IndexOf("Get-PSDebuggerStopArgs", StringComparison.OrdinalIgnoreCase) != -1) || - (powershell.Commands.Commands[0].CommandText.IndexOf("Set-PSDebuggerAction", StringComparison.OrdinalIgnoreCase) != -1))) + (powershell.Commands.Commands[0].CommandText.Contains("Get-PSDebuggerStopArgs", StringComparison.OrdinalIgnoreCase) || + powershell.Commands.Commands[0].CommandText.Contains("Set-PSDebuggerAction", StringComparison.OrdinalIgnoreCase))) { // We do not want to invoke debugger commands in the steppable pipeline. // Consider adding IsSteppable message to PSRP to handle this. diff --git a/src/System.Management.Automation/engine/runtime/Operations/MiscOps.cs b/src/System.Management.Automation/engine/runtime/Operations/MiscOps.cs index 940ac0dcbf..bfa573ee92 100644 --- a/src/System.Management.Automation/engine/runtime/Operations/MiscOps.cs +++ b/src/System.Management.Automation/engine/runtime/Operations/MiscOps.cs @@ -551,7 +551,7 @@ namespace System.Management.Automation "^(global:){0,1}(PID|PSVersionTable|PSEdition|PSHOME|HOST|TRUE|FALSE|NULL)$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant).Success == false) { - updatedScriptblock.Append(scriptblockBodyString.Substring(position, v.Extent.StartOffset - pipelineOffset - position)); + updatedScriptblock.Append(scriptblockBodyString.AsSpan(position, v.Extent.StartOffset - pipelineOffset - position)); updatedScriptblock.Append("${using:"); updatedScriptblock.Append(CodeGeneration.EscapeVariableName(variableName)); updatedScriptblock.Append('}'); @@ -559,7 +559,7 @@ namespace System.Management.Automation } } - updatedScriptblock.Append(scriptblockBodyString.Substring(position)); + updatedScriptblock.Append(scriptblockBodyString.AsSpan(position)); var sb = ScriptBlock.Create(updatedScriptblock.ToString()); var commandInfo = new CmdletInfo("Start-Job", typeof(StartJobCommand)); commandProcessor = context.CommandDiscovery.LookupCommandProcessor(commandInfo, CommandOrigin.Internal, false, context.EngineSessionState); diff --git a/src/System.Management.Automation/engine/runtime/Operations/StringOps.cs b/src/System.Management.Automation/engine/runtime/Operations/StringOps.cs index eeb71366be..2bf68796b4 100644 --- a/src/System.Management.Automation/engine/runtime/Operations/StringOps.cs +++ b/src/System.Management.Automation/engine/runtime/Operations/StringOps.cs @@ -53,12 +53,16 @@ namespace System.Management.Automation return new string(s[0], times); } - // Convert the string to a char array, use the array multiplication code, - // then construct a new string from the resulting char array. This uses - // extra memory compared to the naive algorithm, but is faster (measured - // against a V2 CLR, should be measured against V4 as the StringBuilder - // implementation changed.) - return new string(ArrayOps.Multiply(s.ToCharArray(), (uint)times)); + return string.Create(s.Length * times, (s, times), (dst, args) => + { + ReadOnlySpan src = args.s.AsSpan(); + int length = src.Length; + for (int i = 0; i < args.times; i++) + { + src.CopyTo(dst); + dst = dst.Slice(length); + } + }); } internal static string FormatOperator(string formatString, object formatArgs) diff --git a/src/System.Management.Automation/engine/scriptparameterbindercontroller.cs b/src/System.Management.Automation/engine/scriptparameterbindercontroller.cs index d1f8ba6ff2..601fc78667 100644 --- a/src/System.Management.Automation/engine/scriptparameterbindercontroller.cs +++ b/src/System.Management.Automation/engine/scriptparameterbindercontroller.cs @@ -274,7 +274,7 @@ namespace System.Management.Automation // foo "-abc" // This is important when splatting, we reconstruct the parameter if the // value is splatted. - var parameterText = new PSObject(new string(parameter.ParameterText.ToCharArray())); + var parameterText = new PSObject(new string(parameter.ParameterText)); if (parameterText.Properties[NotePropertyNameForSplattingParametersInArgs] == null) { var noteProperty = new PSNoteProperty(NotePropertyNameForSplattingParametersInArgs, diff --git a/src/System.Management.Automation/namespaces/LocationGlobber.cs b/src/System.Management.Automation/namespaces/LocationGlobber.cs index 217d3787e1..f03ff7038d 100644 --- a/src/System.Management.Automation/namespaces/LocationGlobber.cs +++ b/src/System.Management.Automation/namespaces/LocationGlobber.cs @@ -1869,9 +1869,7 @@ namespace System.Management.Automation if (normalizedPath.StartsWith(normalizedRoot, StringComparison.OrdinalIgnoreCase)) { isPathForCurrentDrive = true; - path = path.Substring(normalizedRoot.Length); - path = path.TrimStart(StringLiterals.DefaultPathSeparator); - path = StringLiterals.DefaultPathSeparator + path; + path = string.Concat(StringLiterals.DefaultPathSeparatorString, path.AsSpan(normalizedRoot.Length).TrimStart(StringLiterals.DefaultPathSeparator)); workingDriveForPath = _sessionState.Drive.Current; } } @@ -3087,8 +3085,7 @@ namespace System.Management.Automation } else { - string possibleDriveName = path.Substring(0, index); - if (string.Equals(possibleDriveName, drive.Name, StringComparison.OrdinalIgnoreCase)) + if (path.AsSpan(0, index).Equals(drive.Name, StringComparison.OrdinalIgnoreCase)) { treatAsRelative = false; } @@ -4438,17 +4435,17 @@ namespace System.Management.Automation const char mshEscapeChar = '`'; const char regexEscapeChar = '\\'; - char[] workerArray = path.ToCharArray(); + ReadOnlySpan workerArray = path; StringBuilder result = new StringBuilder(); - for (int index = 0; index < workerArray.GetLength(0); ++index) + for (int index = 0; index < workerArray.Length; ++index) { // look for an escape character if (workerArray[index] == mshEscapeChar) { - if (index + 1 < workerArray.GetLength(0)) + if (index + 1 < workerArray.Length) { if (workerArray[index + 1] == mshEscapeChar) { diff --git a/src/System.Management.Automation/namespaces/NavigationProviderBase.cs b/src/System.Management.Automation/namespaces/NavigationProviderBase.cs index 94f60deaac..654574c8de 100644 --- a/src/System.Management.Automation/namespaces/NavigationProviderBase.cs +++ b/src/System.Management.Automation/namespaces/NavigationProviderBase.cs @@ -873,12 +873,12 @@ namespace System.Management.Automation.Provider // normalize it, then we will get a wrong path. // // Fast return if nothing to normalize. - if (path.IndexOf(StringLiterals.AlternatePathSeparator) == -1) + if (!path.Contains(StringLiterals.AlternatePathSeparator)) { return path; } - bool pathHasBackSlash = path.IndexOf(StringLiterals.DefaultPathSeparator) != -1; + bool pathHasBackSlash = path.Contains(StringLiterals.DefaultPathSeparator); string normalizedPath; // There is a mix of slashes & the path is rooted & the path exists without normalization. diff --git a/src/System.Management.Automation/namespaces/TransactedRegistryKey.cs b/src/System.Management.Automation/namespaces/TransactedRegistryKey.cs index 145d72f061..67fec931cc 100644 --- a/src/System.Management.Automation/namespaces/TransactedRegistryKey.cs +++ b/src/System.Management.Automation/namespaces/TransactedRegistryKey.cs @@ -1723,7 +1723,7 @@ namespace Microsoft.PowerShell.Commands.Internal internal static string FixupName(string name) { BCLDebug.Assert(name != null, "[FixupName]name!=null"); - if (name.IndexOf('\\') == -1) + if (name.Contains('\\')) return name; StringBuilder sb = new StringBuilder(name); diff --git a/src/System.Management.Automation/security/CatalogHelper.cs b/src/System.Management.Automation/security/CatalogHelper.cs index acd0711d23..018720f391 100644 --- a/src/System.Management.Automation/security/CatalogHelper.cs +++ b/src/System.Management.Automation/security/CatalogHelper.cs @@ -218,7 +218,7 @@ namespace System.Management.Automation if (dirInfo != null) { // Relative path of the file is the path inside the containing folder excluding folder Name - relativePath = fileToHash.FullName.Substring(dirInfo.FullName.Length).TrimStart('\\'); + relativePath = fileToHash.FullName.AsSpan(dirInfo.FullName.Length).TrimStart('\\').ToString(); } else { @@ -613,7 +613,7 @@ namespace System.Management.Automation if (dirInfo != null) { // Relative path of the file is the path inside the containing folder excluding folder Name - relativePath = fileToHash.FullName.Substring(dirInfo.FullName.Length).TrimStart('\\'); + relativePath = fileToHash.FullName.AsSpan(dirInfo.FullName.Length).TrimStart('\\').ToString(); exclude = fileToHash.Name; } else diff --git a/src/System.Management.Automation/security/SecureStringHelper.cs b/src/System.Management.Automation/security/SecureStringHelper.cs index e0992f12f6..6f7bb1180b 100644 --- a/src/System.Management.Automation/security/SecureStringHelper.cs +++ b/src/System.Management.Automation/security/SecureStringHelper.cs @@ -131,7 +131,7 @@ namespace Microsoft.PowerShell { for (int i = 0; i < dataLen; i++) { - data[i] = byte.Parse(s.Substring(2 * i, 2), + data[i] = byte.Parse(s.AsSpan(2 * i, 2), NumberStyles.AllowHexSpecifier, System.Globalization.CultureInfo.InvariantCulture); } diff --git a/src/System.Management.Automation/utils/ClrFacade.cs b/src/System.Management.Automation/utils/ClrFacade.cs index db0f8f9f1b..dd1b806fdc 100644 --- a/src/System.Management.Automation/utils/ClrFacade.cs +++ b/src/System.Management.Automation/utils/ClrFacade.cs @@ -204,7 +204,7 @@ namespace System.Management.Automation // has 'dot' in it, the file will be treated as in Internet security zone. Otherwise, it's // in Intranet security zone. string hostName = uri.Host; - return hostName.IndexOf('.') == -1 ? SecurityZone.Intranet : SecurityZone.Internet; + return hostName.Contains('.') ? SecurityZone.Intranet : SecurityZone.Internet; } string root = Path.GetPathRoot(filePath);