@@ -248,7 +248,7 @@ private struct PathComponentScanner {
248
248
249
249
mutating func _scanOperatorName( ) -> Substring ? {
250
250
// If the next component is a Swift operator, parse the full operator before splitting on "/" ("/" may appear in the operator name)
251
- if remaining. unicodeScalars. prefix ( 3 ) . allSatisfy ( \ . isValidSwiftOperatorHead ) {
251
+ if remaining. unicodeScalars. prefix ( 3 ) . isValidSwiftOperator ( ) {
252
252
return scanUntil ( index: remaining. firstIndex ( of: Self . swiftOperatorEnd) ) + scan( length: 1 )
253
253
}
254
254
@@ -354,6 +354,20 @@ private extension StringProtocol {
354
354
}
355
355
}
356
356
357
+ private extension Collection < Unicode . Scalar > {
358
+ /// Determines if this sequence of unicode scalars represent a valid Swift operator name
359
+ /// - Complexity: O(_n_), where _n_ is the length of the collection.
360
+ func isValidSwiftOperator( ) -> Bool {
361
+ // See https://docs.swift.org/swift-book/documentation/the-swift-programming-language/lexicalstructure#Operators
362
+
363
+ // The first character of an operator supports fewer characters than the rest of the operator name
364
+ guard let first, first. isValidSwiftOperatorHead else {
365
+ return false
366
+ }
367
+ return dropFirst ( ) . allSatisfy { $0. isValidSwiftOperatorCharacter }
368
+ }
369
+ }
370
+
357
371
private extension Unicode . Scalar {
358
372
/// Checks if this unicode scalar is a valid C99 Extended Identifier.
359
373
var isValidC99ExtendedIdentifier : Bool {
@@ -547,10 +561,11 @@ private extension Unicode.Scalar {
547
561
}
548
562
}
549
563
564
+ /// A Boolean value that indicates if this scalar is a valid Swift operator head.
550
565
var isValidSwiftOperatorHead : Bool {
551
566
// See https://docs.swift.org/swift-book/documentation/the-swift-programming-language/lexicalstructure#Operators
552
567
switch value {
553
- case
568
+ case
554
569
// ! % & * + - . / < = > ? ^| ~
555
570
0x21 , 0x25 , 0x26 , 0x2A , 0x2B , 0x2D ... 0x2F , 0x3C , 0x3D ... 0x3F , 0x5E , 0x7C , 0x7E ,
556
571
// ¡ ¢ £ ¤ ¥ ¦ §
@@ -573,6 +588,12 @@ private extension Unicode.Scalar {
573
588
0x2041 ... 0x2053 ,
574
589
// ⁕ ⁖ ⁗ ⁘ ⁙ ⁚ ⁛ ⁜ ⁝ ⁞
575
590
0x2055 ... 0x205E ,
591
+ // Arrows
592
+ 0x2190 ... 0x21FF ,
593
+ // Mathematical Operators
594
+ 0x2200 ... 0x22FF ,
595
+ // Miscellaneous Technical
596
+ 0x2300 ... 0x23FF ,
576
597
// Box Drawing
577
598
0x2500 ... 0x257F ,
578
599
// Block Elements
@@ -610,4 +631,31 @@ private extension Unicode.Scalar {
610
631
return false
611
632
}
612
633
}
634
+
635
+ /// A Boolean value that indicates if this scalar is a valid Swift operator character (after the first character).
636
+ var isValidSwiftOperatorCharacter : Bool {
637
+ // See https://docs.swift.org/swift-book/documentation/the-swift-programming-language/lexicalstructure#Operators
638
+ if isValidSwiftOperatorHead {
639
+ return true
640
+ }
641
+
642
+ switch value {
643
+ case
644
+ // Combining Diacritical Marks
645
+ 0x0300 ... 0x036F ,
646
+ // Combining Diacritical Marks Supplement
647
+ 0x1DC0 ... 0x1DFF ,
648
+ // Combining Diacritical Marks for Symbols
649
+ 0x20D0 ... 0x20FF ,
650
+ // Variation Selectors
651
+ 0xFE00 ... 0xFE0F ,
652
+ // Combining Half Marks
653
+ 0xFE20 ... 0xFE2F ,
654
+ // Variation Selectors Supplement
655
+ 0xE0100 ... 0xE01EF :
656
+ return true
657
+ default :
658
+ return false
659
+ }
660
+ }
613
661
}
0 commit comments