You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Improve parsing of links with type disambiguation that include generics (#1338)
* Improve parsing of links with type disambiguation that include generics
rdar://160232871
* Add documentation for the private type signature string scanner API
/// A file-private, low-level string scanner type that's only designed for parsing type signature based disambiguation suffixes in authored links.
526
+
///
527
+
/// ## Correct usage
528
+
///
529
+
/// The higher level methods like ``scanReturnTypes()``, ``scanArguments()``, ``scanTuple()``, or ``scanValue()`` makes assumptions about the scanners content and current state.
530
+
/// For example:
531
+
/// - ``scanReturnTypes()`` knows that return types are specified after any parameter types and requires that the caller has already scanned the parameter types and advanced past the `"->"` separator.
532
+
/// It's the caller's (`parseTypeSignatureDisambiguation(pathComponent:)` above) responsibility to do these things correctly.
533
+
/// Similarly, it's the caller's responsibility to advance past the `"-"` prefix verify that the scanner points to an open parenthesis character (`(`) that before calling ``scanArguments()`` to scan the parameter types.
534
+
/// Failing to do either of these things will result in unexpected parsed disambiguation that DocC will fail to find a match for.
535
+
/// - Both ``scanArguments()``, or ``scanTuple()`` expects that the disambiguation portion of the authored link has a balanced number of open and closer parenthesis (`(` and `)`).
536
+
/// If the authored link contains unbalanced parenthesis then disambiguation isn't valid and the scanner will return a parsed value that DocC will fail to find a match for.
537
+
/// - ``scanValue()`` expects that the disambiguation portion of the authored link has a balanced number of open and closer angle brackets (`<` and `>`).
538
+
/// If the authored link contains unbalanced angle brackets then disambiguation isn't valid and the scanner will return a parsed value that DocC will fail to find a match for.
525
539
privatestructStringScanner:~Copyable {
526
540
privatevarremaining:Substring
527
541
528
542
init(_ original:Substring){
529
543
remaining = original
530
544
}
531
545
532
-
func peek()->Character?{
546
+
/// Returns the next character _without_ advancing the scanner
547
+
privatefunc peek()->Character?{
533
548
remaining.first
534
549
}
535
550
536
-
mutatingfunc take()->Character{
551
+
/// Advances the scanner and returns the scanned character.
552
+
privatemutatingfunc take()->Character{
537
553
remaining.removeFirst()
538
554
}
539
555
556
+
/// Advances the scanner by `count` elements and returns the scanned substring.
540
557
mutatingfunc take(_ count:Int)->Substring{
541
558
defer{ remaining = remaining.dropFirst(count)}
542
559
return remaining.prefix(count)
543
560
}
544
561
545
-
mutatingfunc takeAll()->Substring{
562
+
/// Advances the scanner to the end and returns the scanned substring.
/// A Boolean value indicating whether the scanner has reached the end.
558
618
varisAtEnd:Bool{
559
619
remaining.isEmpty
560
620
}
561
621
622
+
/// Returns a Boolean value indicating whether the substring at the scanners current position begins with the specified prefix.
562
623
func hasPrefix(_ prefix:String)->Bool{
563
624
remaining.hasPrefix(prefix)
564
625
}
565
626
566
627
// MARK: Parsing argument types by scanning
567
628
629
+
/// Scans the remainder of the scanner's contents as the individual elements of a tuple return type,
630
+
/// or as a single return type if the scanners current position isn't an open parenthesis (`(`)
631
+
///
632
+
/// For example, consider a scanner that has already advanced 8 characters into the string `"-(One)->(Two,Three)"`
633
+
/// ```
634
+
/// -(One)->(Two, Three)
635
+
/// ^
636
+
/// ```
637
+
/// Because the scanner's current position is an open parenthesis (`(`), the scanner advances all the way to the end and returns `["Two", "Three"]` representing two elements in the tuple return value.
638
+
///
639
+
/// - Note: The scanner expects that the caller has already scanned any parameter types and advanced past the `"->"` separator.
/// Scans the list of individual parameter type names as if the scanner's current position was 1 past the open parenthesis (`(`) or a tuple.
650
+
///
651
+
/// For example, consider a scanner that has already advanced 2 characters into the string `"-(One,(A,B))->(Two)"`
652
+
/// ```
653
+
/// -(One,(A,B))->(Two)
654
+
/// ^
655
+
/// ```
656
+
/// The scanner parses two parameter return types---`"One"` and `"(A,B)"`---before the parenthesis balance out, advancing its position to one after the arguments list's closing parenthesis (`)`).
657
+
/// ```
658
+
/// -(One,(A,B))->(Two)
659
+
/// ^
660
+
/// ```
661
+
/// - Note: The scanner expects that the caller has already advanced past the open parenthesis (`(`) that begins the list of parameter types.
0 commit comments