Skip to content

[code-simplifier] Simplify ExecutableConditionAttribute code#9375

Merged
Evangelink merged 2 commits into
mainfrom
code-simplification/executable-condition-attribute-128f7e2cbf1ac23e
Jun 23, 2026
Merged

[code-simplifier] Simplify ExecutableConditionAttribute code#9375
Evangelink merged 2 commits into
mainfrom
code-simplification/executable-condition-attribute-128f7e2cbf1ac23e

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Code Simplification — 2026-06-23

This PR simplifies ExecutableConditionAttribute, added in #9369, to improve clarity and consistency while preserving all functionality.

Files Simplified

  • src/TestFramework/TestFramework/Attributes/TestMethod/ExecutableConditionAttribute.cs — three targeted cleanups

Improvements Made

  1. Replaced ternary-throw with explicit null guard

    The original ternary-throw pattern is syntactically valid but reads in an unusual order (the "throw" branch precedes the normal path):

    // Before
    _arguments = arguments is null
        ? throw new ArgumentNullException(nameof(arguments))
        : (string[])arguments.Clone();
    
    // After
    if (arguments is null)
    {
        throw new ArgumentNullException(nameof(arguments));
    }
    
    _arguments = (string[])arguments.Clone();

    The explicit guard-then-assign form is more readable and consistent with patterns used elsewhere in the file (e.g. the if (process is null) return false; guard in TryRunWithExitCodeZero).

  2. Used string.IsNullOrEmpty for combined null+empty check

    // Before
    if (pathExt is null || pathExt.Length == 0)
    
    // After
    if (string.IsNullOrEmpty(pathExt))

    string.IsNullOrEmpty is the canonical idiom already used throughout the codebase (e.g. CollectionAssert.Subset.cs, StructuredAssertionMessage.cs, Ensure.cs).

  3. Replaced manual array construction with collection spread

    // Before
    string[] result = new string[parts.Length + 1];
    result[0] = string.Empty;
    Array.Copy(parts, 0, result, 1, parts.Length);
    return result;
    
    // After
    return [string.Empty, ..parts];

    The spread syntax is already used in the codebase (e.g. MSTestAdapter.PlatformServices) and generates identical IL. With LangVersion preview set project-wide, this is fully supported.

Changes Based On

Testing

  • ✅ No functional changes — all three edits are semantically equivalent to the original
  • ✅ Existing tests in ExecutableConditionAttributeTests cover all affected code paths
  • ⚠️ Full build requires .NET SDK 11.0.x (preview) which CI will supply

Review Focus

Please verify:

  • Functionality is preserved (all three changes are equivalent rewrites)
  • Changes align with project conventions

🤖 Automated content by GitHub Copilot. Posted via a maintainer's GitHub token, so it appears under their account — the account owner did not write or approve this content personally. Generated by the Code Simplifier workflow. · 164.9 AIC · ⌖ 18.1 AIC · ⊞ 9.3K · [◷]( · )

Add this agentic workflows to your repo

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/code-simplifier.md@main
  • expires on Jun 24, 2026, 2:10 PM UTC

- Replace ternary-throw pattern with explicit if-guard for arguments null check
- Use string.IsNullOrEmpty instead of manual null-or-length check for pathExt
- Use collection spread [string.Empty, ..parts] instead of Array.Copy pattern

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 23, 2026 14:10
@Evangelink Evangelink added type/automation Created or maintained by an agentic workflow. type/tech-debt Code health, refactoring, simplification. labels Jun 23, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR performs small readability-focused refactors in ExecutableConditionAttribute (MSTest TestFramework) while preserving behavior, primarily around argument cloning and Windows PATHEXT handling.

Changes:

  • Replaced a ternary-throw assignment with an explicit arguments is null guard and subsequent clone.
  • Simplified the PATHEXT null/empty check via string.IsNullOrEmpty.
  • Simplified the executable-extension array construction using a collection expression with spread.
Show a summary per file
File Description
src/TestFramework/TestFramework/Attributes/TestMethod/ExecutableConditionAttribute.cs Refactors constructor argument guarding/cloning and streamlines Windows PATHEXT parsing/extension list construction without changing behavior.

Copilot's findings

  • Files reviewed: 1/1 changed files
  • Comments generated: 0

@Evangelink

Copy link
Copy Markdown
Member Author

🔍 Build Failure Analysis

Summary — The build fails due to a single IDE0055 formatting violation in the newly-added return [string.Empty, ..parts] collection-expression spread: the repository style requires a space after .., but the PR omits it.

Root cause: Missing space in collection-expression spread element

IDE0055 ("Fix formatting") is triggered by the Roslyn formatter at line 340, column 33 of ExecutableConditionAttribute.cs. Column 33 is exactly the p in ..parts — the formatter wants to insert a space before parts, turning ..parts into .. parts.

This is consistent with:

The error fires four times (once per target framework compiled from TestFramework.csproj) and is promoted to an error by TreatWarningsAsErrors=true on CI.

Affected file / error

Proposed fix

-        return [string.Empty, ..parts];
+        return [string.Empty, .. parts];

You can also let the toolchain fix it automatically:

dotnet format analyzers src/TestFramework/TestFramework/TestFramework.csproj --diagnostics IDE0055

Build overview
Field Value
Result ❌ FAILED
Duration 177.1 s
MSBuild 18.7.0-preview (SDK 11.0.100-preview.5.26227.104)
Projects built 46
Errors 5 (4 × same IDE0055 + final "Build failed.")
Warnings 0
Failed projects Build.proj, NonWindowsTests.slnf, MSTest.TestAdapter.csproj, TestFramework.csproj
All MSBuild errors (4 unique + 1 summary)
Code Project File:Line Message
IDE0055 TestFramework.csproj ExecutableConditionAttribute.cs:340:33 Fix formatting
IDE0055 TestFramework.csproj ExecutableConditionAttribute.cs:340:33 Fix formatting (TFM 2)
IDE0055 TestFramework.csproj ExecutableConditionAttribute.cs:340:33 Fix formatting (TFM 3)
IDE0055 TestFramework.csproj ExecutableConditionAttribute.cs:340:33 Fix formatting (TFM 4)

The same diagnostic repeats for each target framework (net462, netstandard2.0, net6.0, net8.0 or similar) because Roslyn is invoked once per TFM.


🤖 Generated by the Build Failure Analysis workflow using (a href="(dev.azure.com/redacted) · commit 81e36e2

🤖 Automated content by GitHub Copilot. Posted via a maintainer's GitHub token, so it appears under their account — the account owner did not write or approve this content personally. Generated by the Build Failure Analysis workflow. · 775.1 AIC · ⌖ 21.7 AIC · ⊞ 46.9K · [◷]( · )

@Evangelink Evangelink left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Automated content by GitHub Copilot. Posted via a maintainer's GitHub token, so it appears under their account — the account owner did not write or approve this content personally. Generated by the Build Failure Analysis workflow. · 775.1 AIC · ⌖ 21.7 AIC · ⊞ 46.9K ·

Copilot AI review requested due to automatic review settings June 23, 2026 15:32
@Evangelink Evangelink marked this pull request as ready for review June 23, 2026 15:32
@Evangelink Evangelink added the state/needs-review Awaiting review from the team. label Jun 23, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 1/1 changed files
  • Comments generated: 0 new

@Evangelink Evangelink left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

🤖 Automated review by GitHub Copilot. Posted via a maintainer's GitHub token, so it appears under their account — the account owner did not write or approve this content personally. Generated by the Expert Code Review workflow. To request a follow-up action, reply by tagging @copilot directly.

Review: all three changes are semantically equivalent — LGTM

Dimensions checked: Correctness · API Compat · Cross-TFM · Null Safety · Thread Safety · Performance · Resource Safety · PublicAPI / XLF / resx (none changed) · Code Style


Change 1 — Null guard refactor (lines 123–133)

_arguments = arguments is null ? throw ... : ...if (arguments is null) { throw ... } _arguments = ...

Equivalent. Both branches throw ArgumentNullException when arguments is null; the assignment only runs when arguments is not null. No observable difference in semantics, exception type, or stack frame.


Change 2 — string.IsNullOrEmpty (line 331)

pathExt is null || pathExt.Length == 0string.IsNullOrEmpty(pathExt)

Equivalent. string.IsNullOrEmpty carries [return: NotNullWhen(false)], so the Roslyn null-flow analysis after the guard is identical to the explicit pattern — pathExt is known non-null in the remainder of the method in both forms.


Change 3 — Collection spread [string.Empty, .. parts] (lines 338–343)

Manual new string[parts.Length + 1] / result[0] / Array.Copyreturn [string.Empty, .. parts]

Equivalent and cross-TFM safe. Collection expressions are a compiler-lowering feature: Roslyn emits the exact same array-allocation + Array.Copy IL when targeting net462 or netstandard2.0. No BCL type unavailable on those targets is required. The project already uses [string.Empty, ".exe", ...] collection expressions in the early-return path of the same method, confirming the pattern compiles correctly across all TFMs. LangVersion preview is confirmed in Directory.Build.props (<LangVersion>preview</LangVersion>).

@Evangelink Evangelink enabled auto-merge (squash) June 23, 2026 16:09
@Evangelink Evangelink merged commit 8b25ce6 into main Jun 23, 2026
48 checks passed
@Evangelink Evangelink deleted the code-simplification/executable-condition-attribute-128f7e2cbf1ac23e branch June 23, 2026 17:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-review Awaiting review from the team. type/automation Created or maintained by an agentic workflow. type/tech-debt Code health, refactoring, simplification.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants