Skip to content

[stdlib] Mark NFD and NFC as SPI #42124

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions stdlib/public/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ set(SWIFTLIB_ESSENTIAL
UnicodeParser.swift
UnicodeScalarProperties.swift
CharacterProperties.swift # ORDER DEPENDENCY: UnicodeScalarProperties.swift
UnicodeSPI.swift
Unmanaged.swift
UnmanagedOpaqueString.swift
UnmanagedString.swift
Expand Down
1 change: 1 addition & 0 deletions stdlib/public/core/GroupInfo.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"UnicodeParser.swift",
"UnicodeScalar.swift",
"UnicodeScalarProperties.swift",
"UnicodeSPI.swift",
"UnavailableStringAPIs.swift",
"UnmanagedOpaqueString.swift",
"UnmanagedString.swift",
Expand Down
16 changes: 8 additions & 8 deletions stdlib/public/core/NFC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
import SwiftShims

extension Unicode {
internal struct _NFC<S: StringProtocol> {
internal struct _InternalNFC<S: StringProtocol> {
let base: S
}
}

extension Unicode._NFC {
extension Unicode._InternalNFC {
internal struct Iterator {
var buffer = Unicode._NormDataBuffer()

Expand All @@ -30,11 +30,11 @@ extension Unicode._NFC {
// we continue to try and compose following scalars with this composee.
var composee: Unicode.Scalar? = nil

var iterator: Unicode._NFD<S>.Iterator
var iterator: Unicode._InternalNFD<S>.Iterator
}
}

extension Unicode._NFC.Iterator: IteratorProtocol {
extension Unicode._InternalNFC.Iterator: IteratorProtocol {
internal func compose(
_ x: Unicode.Scalar,
and y: Unicode.Scalar
Expand Down Expand Up @@ -210,14 +210,14 @@ extension Unicode._NFC.Iterator: IteratorProtocol {
}
}

extension Unicode._NFC: Sequence {
extension Unicode._InternalNFC: Sequence {
internal func makeIterator() -> Iterator {
Iterator(iterator: base._nfd.makeIterator())
Iterator(iterator: base._internalNFD.makeIterator())
}
}

extension StringProtocol {
internal var _nfc: Unicode._NFC<Self> {
Unicode._NFC(base: self)
internal var _internalNFC: Unicode._InternalNFC<Self> {
Unicode._InternalNFC(base: self)
}
}
18 changes: 9 additions & 9 deletions stdlib/public/core/NFD.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
//===----------------------------------------------------------------------===//

extension Unicode {
internal struct _NFD<S: StringProtocol> {
let base: S
internal struct _InternalNFD<S: StringProtocol> {
let base: S.UnicodeScalarView
}
}

extension Unicode._NFD {
extension Unicode._InternalNFD {
internal struct Iterator {
var buffer = Unicode._NormDataBuffer()

Expand All @@ -28,7 +28,7 @@ extension Unicode._NFD {
}
}

extension Unicode._NFD.Iterator: IteratorProtocol {
extension Unicode._InternalNFD.Iterator: IteratorProtocol {
internal mutating func decompose(
_ scalar: Unicode.Scalar,
with normData: Unicode._NormData
Expand Down Expand Up @@ -165,17 +165,17 @@ extension Unicode._NFD.Iterator: IteratorProtocol {
}
}

extension Unicode._NFD: Sequence {
extension Unicode._InternalNFD: Sequence {
internal func makeIterator() -> Iterator {
Iterator(
index: base.unicodeScalars.startIndex,
unicodeScalars: base.unicodeScalars
index: base.startIndex,
unicodeScalars: base
)
}
}

extension StringProtocol {
internal var _nfd: Unicode._NFD<Self> {
Unicode._NFD(base: self)
internal var _internalNFD: Unicode._InternalNFD<Self> {
Unicode._InternalNFD(base: unicodeScalars)
}
}
2 changes: 1 addition & 1 deletion stdlib/public/core/String.swift
Original file line number Diff line number Diff line change
Expand Up @@ -987,7 +987,7 @@ extension _StringGutsSlice {
}
}

for scalar in String(_guts)._nfc {
for scalar in String(_guts)._internalNFC {
try scalar.withUTF8CodeUnits {
for byte in $0 {
try f(byte)
Expand Down
4 changes: 2 additions & 2 deletions stdlib/public/core/StringComparison.swift
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,8 @@ extension _StringGutsSlice {
with other: _StringGutsSlice,
expecting: _StringComparisonResult
) -> Bool {
var iter1 = Substring(self)._nfc.makeIterator()
var iter2 = Substring(other)._nfc.makeIterator()
var iter1 = Substring(self)._internalNFC.makeIterator()
var iter2 = Substring(other)._internalNFC.makeIterator()

var scalar1: Unicode.Scalar? = nil
var scalar2: Unicode.Scalar? = nil
Expand Down
125 changes: 125 additions & 0 deletions stdlib/public/core/UnicodeSPI.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2022 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// Unicode.NFD
//===----------------------------------------------------------------------===//

extension Unicode {
@_spi(_Unicode)
@available(SwiftStdlib 5.7, *)
public struct _NFD {
let base: Substring.UnicodeScalarView
Copy link
Member

Choose a reason for hiding this comment

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

To avoid surprises, I recommend spelling out the memberwise initializer here. The compiler-provided one probably works fine, but it usually is a good idea to be explicit about things that might get exposed.

(E.g. I don't know for sure if the implicit initializer will be declared public or internal. internal would make more sense, but ¯\_(ツ)_/¯)

}
}

@available(SwiftStdlib 5.7, *)
extension Unicode._NFD {
@_spi(_Unicode)
@available(SwiftStdlib 5.7, *)
public struct Iterator {
var base: Unicode._InternalNFD<Substring>.Iterator
Copy link
Member

Choose a reason for hiding this comment

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

Same here

}
}

@available(SwiftStdlib 5.7, *)
extension Unicode._NFD.Iterator: IteratorProtocol {
@_spi(_Unicode)
@available(SwiftStdlib 5.7, *)
public mutating func next() -> Unicode.Scalar? {
base.next()?.scalar
}
}

@available(SwiftStdlib 5.7, *)
extension Unicode._NFD: Sequence {
@_spi(_Unicode)
@available(SwiftStdlib 5.7, *)
public func makeIterator() -> Iterator {
Iterator(base: Unicode._InternalNFD(base: base).makeIterator())
}
}

extension String {
@_spi(_Unicode)
@available(SwiftStdlib 5.7, *)
public var _nfd: Unicode._NFD {
Unicode._NFD(base: self[...].unicodeScalars)
}
}

extension Substring {
@_spi(_Unicode)
@available(SwiftStdlib 5.7, *)
public var _nfd: Unicode._NFD {
Unicode._NFD(base: unicodeScalars)
}
}

//===----------------------------------------------------------------------===//
// Unicode.NFC
//===----------------------------------------------------------------------===//

extension Unicode {
@_spi(_Unicode)
@available(SwiftStdlib 5.7, *)
public struct _NFC {
let base: Substring.UnicodeScalarView
Copy link
Member

Choose a reason for hiding this comment

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

Same here

}
}

@available(SwiftStdlib 5.7, *)
extension Unicode._NFC {
@_spi(_Unicode)
@available(SwiftStdlib 5.7, *)
public struct Iterator {
var base: Unicode._InternalNFC<Substring>.Iterator
Copy link
Member

Choose a reason for hiding this comment

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

Ditto

}
}

@available(SwiftStdlib 5.7, *)
extension Unicode._NFC.Iterator: IteratorProtocol {
@_spi(_Unicode)
@available(SwiftStdlib 5.7, *)
public mutating func next() -> Unicode.Scalar? {
base.next()
}
}

@available(SwiftStdlib 5.7, *)
extension Unicode._NFC: Sequence {
@_spi(_Unicode)
@available(SwiftStdlib 5.7, *)
public func makeIterator() -> Iterator {
Iterator(
base: Unicode._InternalNFC<Substring>.Iterator(
iterator: Unicode._InternalNFD<Substring>(base: base).makeIterator()
)
)
}
}

extension String {
@_spi(_Unicode)
@available(SwiftStdlib 5.7, *)
public var _nfc: Unicode._NFC {
Unicode._NFC(base: self[...].unicodeScalars)
}
}

extension Substring {
@_spi(_Unicode)
@available(SwiftStdlib 5.7, *)
public var _nfc: Unicode._NFC {
Unicode._NFC(base: unicodeScalars)
}
}