Does the Swift Package Manager support regex literals?
Asked Answered
J

3

9

I am using the Swift Package Manager, with Swift 5.7.1. I would like to compile code with a regex literal. For example, main.swift could be as follows:

let message = "Hello, world"
print(message.replacing(/[aeiou]/, with: "[vowel]"))

I am not at present interested in the output, but with the compilation.

If I create a project in XCode, it works just fine. However, if I try it in the Swift Package Manager (using swift build) it obviously does not recognize that /[aeiou]/ is a regex literal. Instead, I get messages like '/' is not a prefix unary operator.

Is there any way to get this to work with the Swift Package Manager, or is it simply not yet supported?

Jitterbug answered 26/2, 2023 at 17:7 Comment(0)
I
24

Swift 5.7's regex literals can work when using the Swift Package Manager, but they must be explicitly enabled in your Package.swift. By default, the new syntax is disabled since it's a source-breaking language change (due to the existing use of "/" in comment syntax and operators the / operator).

Here's an illustrative Package.swift that sets "-enable-bare-slash-regex" for all the package targets. I've also included a couple of additional settings that you may want if you're working towards fully adopting Swift 5.7:

// swift-tools-version: 5.7

import PackageDescription

let package = Package(
  name: "your-package-name",
  platforms: [...],
  dependencies: [...],
  targets: [
    .target(
      name: "FooBar",
      dependencies: []
    ),
    .testTarget(
      name: "FooBarTests",
      dependencies: [
        "FooBar",
      ]
    ),
  ]
)

for target in package.targets {
  target.swiftSettings = target.swiftSettings ?? []
  target.swiftSettings?.append(
    .unsafeFlags([
      "-Xfrontend", "-warn-concurrency",
      "-Xfrontend", "-enable-actor-data-race-checks",
      "-enable-bare-slash-regex",
    ])
  )
}

In a future Swift version and once there’s been time for existing code to transition to Swift 5.7, regex literals will likely be enabled by default.


Swift 5.8 Update

The Swift 5.8 release supports the piecemeal adoption of upcoming language improvements. The enableUpcomingFeature helps avoid the situation where "use of unsafe flags make the products containing this target ineligible for use by other packages".

let swiftSettings: [SwiftSetting] = [
    // -enable-bare-slash-regex becomes
    .enableUpcomingFeature("BareSlashRegexLiterals"), 
    // -warn-concurrency becomes
    .enableUpcomingFeature("StrictConcurrency"), 
    .unsafeFlags(["-enable-actor-data-race-checks"], 
        .when(configuration: .debug)),
]

for target in package.targets {
    target.swiftSettings = target.swiftSettings ?? []
    target.swiftSettings?.append(contentsOf: swiftSettings)
}
Intricate answered 1/3, 2023 at 19:38 Comment(0)
B
2

All you need is to add swiftSettings: [.unsafeFlags(["-enable-bare-slash-regex"])] to .target(…) in your package description.

Berbera answered 21/4 at 7:24 Comment(1)
However, this is now built in: in version 5.8+, you can add .enableUpcomingFeature("BareSlashRegexLiterals") to swiftSettings to avoid the problems with unsafe flags.Jitterbug
S
0

If you specify Swift 6, this will work without having to mess with swiftSettings:

let package = Package(
    name: "Foo",
    targets: [],
    swiftLanguageVersions: [.v6]
)
Seagrave answered 25/9 at 22:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.