From f461a50ba24e27a89449f349787356309d205a4a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 26 Apr 2026 01:20:12 +0000 Subject: [PATCH] improve: remove System.Linq from SystemCapability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace three LINQ chains with explicit loops to match the no-LINQ pattern already established throughout the codebase (ExecShellWrapperParser, NodeCapabilities, OpenClawGatewayClient, etc.): - ResolveExecutable: AddRange+Select → foreach+Add when building the PATHEXT extensions list; eliminates the lazy IEnumerable allocation from Enumerable.Select. - HandleExecApprovalsGet: Rules.Select(...).ToArray() → indexed for-loop into pre-allocated object[rules.Count]; removes the intermediate IEnumerable<> iterator allocation. - HandleExecApprovalsSet shells parsing: .Where(...).Select(...).ToArray() → foreach with explicit ValueKind guard; pre-sizes the List from GetArrayLength() to avoid re-allocation on resize. Also removes the now-unused 'using System.Linq;' import. No behaviour change; 652 Shared tests pass, 20 skipped. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Capabilities/SystemCapability.cs | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/OpenClaw.Shared/Capabilities/SystemCapability.cs b/src/OpenClaw.Shared/Capabilities/SystemCapability.cs index bbfca5f..53d0565 100644 --- a/src/OpenClaw.Shared/Capabilities/SystemCapability.cs +++ b/src/OpenClaw.Shared/Capabilities/SystemCapability.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Threading.Tasks; namespace OpenClaw.Shared.Capabilities; @@ -122,8 +121,8 @@ private NodeInvokeResponse HandleWhich(NodeInvokeRequest request) if (OperatingSystem.IsWindows()) { var pathext = Environment.GetEnvironmentVariable("PATHEXT") ?? ".EXE;.CMD;.BAT;.COM"; - extensions.AddRange(pathext.Split(';', StringSplitOptions.RemoveEmptyEntries) - .Select(e => e.ToLowerInvariant())); + foreach (var e in pathext.Split(';', StringSplitOptions.RemoveEmptyEntries)) + extensions.Add(e.ToLowerInvariant()); } else { @@ -346,18 +345,25 @@ private NodeInvokeResponse HandleExecApprovalsGet() } var data = _approvalPolicy.GetPolicyData(); - return Success(new + var rules = data.Rules; + var rulesSummary = new object[rules.Count]; + for (var i = 0; i < rules.Count; i++) { - enabled = true, - defaultAction = data.DefaultAction.ToString().ToLowerInvariant(), - rules = data.Rules.Select(r => new + var r = rules[i]; + rulesSummary[i] = new { pattern = r.Pattern, action = r.Action.ToString().ToLowerInvariant(), shells = r.Shells, description = r.Description, enabled = r.Enabled - }).ToArray() + }; + } + return Success(new + { + enabled = true, + defaultAction = data.DefaultAction.ToString().ToLowerInvariant(), + rules = rulesSummary }); } @@ -403,10 +409,13 @@ private NodeInvokeResponse HandleExecApprovalsSet(NodeInvokeRequest request) if (ruleEl.TryGetProperty("shells", out var shellsEl) && shellsEl.ValueKind == System.Text.Json.JsonValueKind.Array) { - rule.Shells = shellsEl.EnumerateArray() - .Where(s => s.ValueKind == System.Text.Json.JsonValueKind.String) - .Select(s => s.GetString() ?? "") - .ToArray(); + var shellsList = new List(shellsEl.GetArrayLength()); + foreach (var s in shellsEl.EnumerateArray()) + { + if (s.ValueKind == System.Text.Json.JsonValueKind.String) + shellsList.Add(s.GetString() ?? ""); + } + rule.Shells = shellsList.Count > 0 ? shellsList.ToArray() : null; } rules.Add(rule);