Skip to content

Add 'Add Explicit Raw Values' code action#2668

Open
ayush-that wants to merge 1 commit into
swiftlang:mainfrom
ayush-that:feature/add-explicit-enum-raw-values
Open

Add 'Add Explicit Raw Values' code action#2668
ayush-that wants to merge 1 commit into
swiftlang:mainfrom
ayush-that:feature/add-explicit-enum-raw-values

Conversation

@ayush-that
Copy link
Copy Markdown

resolves #2516.

adds a syntactic refactoring action that converts implicit raw values to explicit ones for enums whose first inherited type is an integer (any width up to Int128/UInt128) or String.

before:

enum Status: Int {
    case active
    case inactive
    case pending = 10
    case archived
}

after:

enum Status: Int {
    case active = 0
    case inactive = 1
    case pending = 10
    case archived = 11
}

design follows the feedback @ahoppen left on #2536: implemented as SyntaxRefactoringCodeActionProvider, only the first inherited type is consulted for the raw value type, raw value expressions are validated as integer literals and the action is suppressed when they cannot be parsed, Int128 and UInt128 are accepted in the type list, and the action is suppressed when there is nothing to transform.

beyond #2536, the action also handles:

  • negative integer raw values (case low = -5 followed by implicit cases continues at -4)
  • alternate-base integer literals with underscore separators (case bit0 = 0x10 continues at 17)
  • backticked case identifiers in String enums (case `default becomes = "default", not = "default")
  • integer overflow during continuation (suppresses the action rather than trapping)
  • enums containing #if directives (rintaro flagged this on the original issue)
  • enums containing freestanding macro expansions
  • cases with associated values (suppresses rather than producing case payload = 0(String))

motivation

making implicit raw values explicit is a common refactor before serialising values or relying on their numeric identity. doing it by hand is error-prone once any cases already have explicit values, because the continuation rule must be reapplied for every gap.

modifications

  • new Sources/SwiftSyntaxCodeActions/AddExplicitEnumRawValues.swift
  • registered in Sources/SwiftSyntaxCodeActions/SyntaxCodeActions.swift and Sources/SwiftSyntaxCodeActions/CMakeLists.txt
  • 12 LSP-level tests in Tests/SourceKitLSPTests/CodeActionTests.swift covering positive cases (Int, String, negative continuation, hex continuation, backtick stripping) and negative cases (no raw value type, raw value type not first, all cases explicit, unsupported raw value expression, #if directives, freestanding macros, associated value cases)

result

when the cursor is on an enum declaration with a supported raw value type and at least one case missing an explicit raw value, sourcekit-lsp offers "Add Explicit Raw Values" and inserts the missing values in place. existing positive and negative cases continue to behave as before.

all 12 new tests pass locally.

Copilot AI review requested due to automatic review settings May 26, 2026 05:26
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR introduces a new SwiftSyntax-based refactoring code action to add explicit raw values to enum cases, along with targeted test coverage and build/registration wiring.

Changes:

  • Add AddExplicitEnumRawValues code action provider and register it with the code action registry.
  • Add a suite of LSP tests covering Int/String raw value insertion and “not offered” scenarios.
  • Introduce a test helper to assert that a code action is not offered at a marker.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
Tests/SourceKitLSPTests/CodeActionTests.swift Adds tests for the new refactor and a helper to assert non-offering.
Sources/SwiftSyntaxCodeActions/SyntaxCodeActions.swift Registers the new provider in the global provider list.
Sources/SwiftSyntaxCodeActions/CMakeLists.txt Adds the new Swift source file to the CMake target.
Sources/SwiftSyntaxCodeActions/AddExplicitEnumRawValues.swift Implements the refactor logic for adding explicit enum raw values.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Tests/SourceKitLSPTests/CodeActionTests.swift Outdated
Comment thread Sources/SwiftSyntaxCodeActions/AddExplicitEnumRawValues.swift Outdated
Comment thread Sources/SwiftSyntaxCodeActions/AddExplicitEnumRawValues.swift Outdated
Copy link
Copy Markdown
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

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

This looks great. Thank you @ayush-that. I just have two

Comment thread Sources/SwiftSyntaxCodeActions/AddExplicitEnumRawValues.swift
Comment thread Sources/SwiftSyntaxCodeActions/AddExplicitEnumRawValues.swift Outdated
@ayush-that ayush-that force-pushed the feature/add-explicit-enum-raw-values branch from 3236b69 to a8765a4 Compare May 26, 2026 14:15
Adds a syntactic refactoring action that converts implicit raw values to
explicit ones for enums whose first inherited type is an integer type
(any width up to Int128/UInt128) or String.

Resolves swiftlang#2516.

Before:

    enum Status: Int {
        case active
        case inactive
        case pending = 10
        case archived
    }

After:

    enum Status: Int {
        case active = 0
        case inactive = 1
        case pending = 10
        case archived = 11
    }

The action is exposed through `SyntaxRefactoringCodeActionProvider` and
performs all transformations as a list of `SourceEdit`s, leaving the
rest of the enum (including trailing trivia and member ordering)
untouched.

### Motivation:

For enums with implicit raw values, making the values explicit is a
common refactoring step before serialising the values or relying on
their numeric identity. Doing the renumbering by hand is error-prone
once any cases already have explicit values, because the implicit
continuation rule has to be reapplied for every gap.

### Modifications:

- New `Sources/SwiftSyntaxCodeActions/AddExplicitEnumRawValues.swift`
  conforming to `EditRefactoringProvider` and
  `SyntaxRefactoringCodeActionProvider`. Handles negative integer
  literals, hex/binary/octal literals with underscore separators, and
  backticked case identifiers in String enums.
- Registered in `Sources/SwiftSyntaxCodeActions/SyntaxCodeActions.swift`
  and `Sources/SwiftSyntaxCodeActions/CMakeLists.txt`.
- Twelve LSP-level tests in `Tests/SourceKitLSPTests/CodeActionTests.swift`
  covering positive cases (Int, String, negative continuation, hex
  continuation, backtick stripping) and negative cases (no raw value
  type, raw value type not first in inheritance clause, all cases
  already explicit, unsupported raw value expression, #if directives,
  freestanding macro expansions, associated value cases).

### Result:

When the cursor is on an enum declaration whose raw value type is
supported and at least one case is missing an explicit raw value,
SourceKit-LSP offers the "Add Explicit Raw Values" code action and
inserts the missing raw values in place. The action is suppressed in
situations where the implicit numbering cannot be computed safely
(unsupported raw value expression, #if blocks, freestanding macros,
associated value cases).
@ayush-that ayush-that force-pushed the feature/add-explicit-enum-raw-values branch from a8765a4 to 28e69b6 Compare May 26, 2026 14:37
Copy link
Copy Markdown
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

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

This looks great. Thank you 🙏🏽

@ahoppen
Copy link
Copy Markdown
Member

ahoppen commented May 27, 2026

@swift-ci Please test

@ahoppen
Copy link
Copy Markdown
Member

ahoppen commented May 28, 2026

@swift-ci Please test Windows

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add explicit enum case raw values code action

3 participants