Skip to content

[XcodeGen] 'Byte' comparison and pattern matching #79000

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 2 commits into from
Jan 29, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ fileprivate extension ByteScanner {
// Consume the element, stopping at the first space.
return try consume(using: { consumer in
switch consumer.peek {
case let c where c.isSpaceOrTab:
case \.isSpaceOrTab:
return false
case "\"":
try consumer.consumeStringLiteral()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ extension NinjaBuildFile {

extension Byte {
fileprivate var isNinjaVarName: Bool {
switch self.scalar {
switch self {
case "0"..."9", "a"..."z", "A"..."Z", "_", "-":
return true
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,11 @@ fileprivate extension ByteScanner {
// Ninja uses '$' as the escape character.
if c == "$" {
switch consumer.peek(ahead: 1) {
case let c? where c.isSpaceOrTab:
fallthrough
case "$", ":":
case "$", ":", \.isSpaceOrTab:
// Skip the '$' and take the unescaped character.
consumer.skip()
return consumer.eat()
case let c? where c.isNewline:
case \.isNewline:
// This is a line continuation, skip the newline, and strip any
// following space.
consumer.skip(untilAfter: \.isNewline)
Expand Down Expand Up @@ -160,7 +158,7 @@ extension NinjaParser.Lexer {
private mutating func consumeElement() -> String? {
input.consumeUnescaped(while: { char in
switch char {
case let c where c.isNinjaOperator || c.isSpaceTabOrNewline:
case \.isNinjaOperator, \.isSpaceTabOrNewline:
false
default:
true
Expand Down
46 changes: 7 additions & 39 deletions utils/swift-xcodegen/Sources/SwiftXcodeGen/Scanner/Byte.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,37 +17,15 @@ struct Byte: Hashable {
}
}

// Please forgive me...
func == (lhs: UnicodeScalar, rhs: Byte?) -> Bool {
guard let rhs else { return false }
return lhs.value == rhs.rawValue
}
func == (lhs: Byte?, rhs: UnicodeScalar) -> Bool {
rhs == lhs
}
func != (lhs: UnicodeScalar, rhs: Byte?) -> Bool {
!(lhs == rhs)
}
func != (lhs: Byte?, rhs: UnicodeScalar) -> Bool {
rhs != lhs
}

func ~= (pattern: UnicodeScalar, match: Byte) -> Bool {
pattern == match
}
func ~= (pattern: UnicodeScalar, match: Byte?) -> Bool {
pattern == match
extension Byte: ExpressibleByUnicodeScalarLiteral {
init(unicodeScalarLiteral value: UnicodeScalar) {
self.init(UInt8(ascii: value))
}
}

extension Byte? {
var isSpaceOrTab: Bool {
self?.isSpaceOrTab == true
}
var isNewline: Bool {
self?.isNewline == true
}
var isSpaceTabOrNewline: Bool {
self?.isSpaceTabOrNewline == true
extension Byte: Comparable {
static func < (lhs: Self, rhs: Self) -> Bool {
lhs.rawValue < rhs.rawValue
}
}

Expand All @@ -61,14 +39,4 @@ extension Byte {
var isSpaceTabOrNewline: Bool {
isSpaceOrTab || isNewline
}
init(ascii scalar: UnicodeScalar) {
assert(scalar.isASCII)
self.rawValue = UInt8(scalar.value)
}
var scalar: UnicodeScalar {
UnicodeScalar(UInt32(rawValue))!
}
var char: Character {
.init(scalar)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,6 @@ struct ByteScanner {
tryEat(where: { $0 == byte })
}

mutating func tryEat(_ c: UnicodeScalar) -> Bool {
tryEat(where: { $0 == c })
}

mutating func tryEat<S: Sequence>(_ seq: S) -> Bool where S.Element == UInt8 {
let start = cursor
for byte in seq {
Expand Down
11 changes: 10 additions & 1 deletion utils/swift-xcodegen/Sources/SwiftXcodeGen/Utils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ extension String {
let result = scanner.consumeWhole { consumer in
switch consumer.peek {
case "\\", "\"":
consumer.append(Byte(ascii: "\\"))
consumer.append("\\")
case " ", "$": // $ is potentially a variable reference
needsQuotes = true
default:
Expand Down Expand Up @@ -132,3 +132,12 @@ extension String {
}
}
}

/// Pattern match by `is` property. E.g. `case \.isNewline: ...`
func ~= <T>(keyPath: KeyPath<T, Bool>, subject: T) -> Bool {
return subject[keyPath: keyPath]
}

func ~= <T>(keyPath: KeyPath<T, Bool>, subject: T?) -> Bool {
return subject?[keyPath: keyPath] == true
}