From 381a9d07d238a9da5b0360f46ac7ba63c58d4813 Mon Sep 17 00:00:00 2001 From: Victoria Mitchell Date: Mon, 16 May 2022 13:27:55 -0600 Subject: [PATCH 1/4] improve detection for inherited symbol references rdar://93203894 Symbols for operator functions that include multiple dots (e.g. the ClosedRange `...` operator) are currently curated into an unnamed "Implementations" section due to improper string splitting behavior. This enhances the detection two ways: 1. For symbols where the "source origin" is available in our given symbol graphs, it loads the name information from the parent symbol. 2. For symbols where the "source origin" is not available, it improved the string splitting behavior by dropping empty-string components before reading names from it. This allows Comparable and Equatable implementations to curate their inherited operators properly. --- .../GeneratedDocumentationTopics.swift | 42 +- .../Rendering/RenderNodeTranslatorTests.swift | 29 +- .../Test Resources/FancyProtocol.symbols.json | 3524 +++++++++++++++++ 3 files changed, 3580 insertions(+), 15 deletions(-) create mode 100644 Tests/SwiftDocCTests/Test Resources/FancyProtocol.symbols.json diff --git a/Sources/SwiftDocC/Infrastructure/Symbol Graph/GeneratedDocumentationTopics.swift b/Sources/SwiftDocC/Infrastructure/Symbol Graph/GeneratedDocumentationTopics.swift index d5498565e8..b23ca6d42f 100644 --- a/Sources/SwiftDocC/Infrastructure/Symbol Graph/GeneratedDocumentationTopics.swift +++ b/Sources/SwiftDocC/Infrastructure/Symbol Graph/GeneratedDocumentationTopics.swift @@ -1,7 +1,7 @@ /* This source file is part of the Swift.org open source project - Copyright (c) 2021 Apple Inc. and the Swift project authors + Copyright (c) 2021-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 @@ -40,25 +40,35 @@ enum GeneratedDocumentationTopics { /// - reference: The parent type reference. /// - originDisplayName: The origin display name as provided by the symbol graph. /// - extendedModuleName: Extended module name. - mutating func add(_ childReference: ResolvedTopicReference, to reference: ResolvedTopicReference, originDisplayName: String, extendedModuleName: String) throws { - // Detect the path components of the providing the default implementation. - let typeComponents = originDisplayName.components(separatedBy: ".") - - // Verify that the fully qualified name contains at least a type name and default implementation name. - guard typeComponents.count >= 2 else { return } - + mutating func add(_ childReference: ResolvedTopicReference, to reference: ResolvedTopicReference, originDisplayName: String, originParentSymbol: ResolvedTopicReference?, extendedModuleName: String) throws { + let fromType: String + let typeSimpleName: String + if let originParentSymbol = originParentSymbol, !originParentSymbol.pathComponents.isEmpty { + // If we have a resolved symbol for the parent of `sourceOrigin`, use that for the names + fromType = originParentSymbol.pathComponents.joined(separator: ".") + typeSimpleName = originParentSymbol.pathComponents.last! + } else { + // If we don't have a resolved `sourceOrigin` parent, fall back to parsing its display name + + // Detect the path components of the providing the default implementation. + let typeComponents = originDisplayName.components(separatedBy: ".").filter({ !$0.isEmpty }) + + // Verify that the fully qualified name contains at least a type name and default implementation name. + guard typeComponents.count >= 2 else { return } + + // Get the fully qualified type. + fromType = typeComponents.dropLast().joined(separator: ".") + // The name of the type is second to last. + typeSimpleName = typeComponents[typeComponents.count-2] + } + // Create a type with inherited symbols, if needed. if !implementingTypes.keys.contains(reference) { implementingTypes[reference] = Collections() } - // Get the fully qualified type. - let fromType = typeComponents.dropLast().joined(separator: ".") - // Create a new default implementations provider, if needed. if !implementingTypes[reference]!.inheritedFromTypeName.keys.contains(fromType) { - // The name of the type is second to last. - let typeSimpleName = typeComponents[typeComponents.count-2] implementingTypes[reference]!.inheritedFromTypeName[fromType] = Collections.APICollection(title: "\(typeSimpleName) Implementations", parentReference: reference) } @@ -215,8 +225,12 @@ enum GeneratedDocumentationTopics { let child = context.symbolIndex[relationship.source], // Get the swift extension data let extends = child.symbol?.mixins[SymbolGraph.Symbol.Swift.Extension.mixinKey] as? SymbolGraph.Symbol.Swift.Extension { + var originParentSymbol: ResolvedTopicReference? = nil + if let originSymbol = context.symbolIndex[origin.identifier] { + originParentSymbol = try? symbolsURLHierarchy.parent(of: originSymbol.reference) + } // Add the inherited symbol to the index. - try inheritanceIndex.add(child.reference, to: parent.reference, originDisplayName: origin.displayName, extendedModuleName: extends.extendedModule) + try inheritanceIndex.add(child.reference, to: parent.reference, originDisplayName: origin.displayName, originParentSymbol: originParentSymbol, extendedModuleName: extends.extendedModule) } } diff --git a/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorTests.swift b/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorTests.swift index b413e03d77..7ebc681bed 100644 --- a/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorTests.swift +++ b/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorTests.swift @@ -1,7 +1,7 @@ /* This source file is part of the Swift.org open source project - Copyright (c) 2021 Apple Inc. and the Swift project authors + Copyright (c) 2021-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 @@ -623,6 +623,33 @@ class RenderNodeTranslatorTests: XCTestCase { } } + + /// Verify that symbols with ellipsis operators don't get curated into an unnamed protocol implementation section. + func testAutomaticImplementationsWithExtraDots() throws { + let fancyProtocolSGFURL = Bundle.module.url( + forResource: "FancyProtocol.symbols", withExtension: "json", subdirectory: "Test Resources")! + + // Create a test bundle copy with the symbol graph from above + let (bundleURL, bundle, context) = try testBundleAndContext(copying: "TestBundle", excludingPaths: [], codeListings: [:]) { url in + try? FileManager.default.copyItem(at: fancyProtocolSGFURL, to: url.appendingPathComponent("FancyProtocol.symbols.json")) + } + defer { + try? FileManager.default.removeItem(at: bundleURL) + } + + let reference = ResolvedTopicReference(bundleIdentifier: bundle.identifier, path: "/documentation/FancyProtocol/SomeClass", sourceLanguage: .swift) + var translator = RenderNodeTranslator(context: context, bundle: bundle, identifier: reference, source: nil) + let node = try context.entity(with: reference) + let symbol = try XCTUnwrap(node.semantic as? Symbol) + let renderNode = try XCTUnwrap(translator.visitSymbol(symbol) as? RenderNode) + + let defaultImplementationSection = try XCTUnwrap(renderNode.topicSections.first(where: { $0.title == "Default Implementations" })) + XCTAssertEqual(defaultImplementationSection.identifiers, [ + "doc://org.swift.docc.example/documentation/FancyProtocol/SomeClass/Comparable-Implementations", + "doc://org.swift.docc.example/documentation/FancyProtocol/SomeClass/Equatable-Implementations", + "doc://org.swift.docc.example/documentation/FancyProtocol/SomeClass/FancyProtocol-Implementations", + ]) + } func testAutomaticTaskGroupTopicsAreSorted() throws { let (bundle, context) = try testBundleAndContext(named: "DefaultImplementations") diff --git a/Tests/SwiftDocCTests/Test Resources/FancyProtocol.symbols.json b/Tests/SwiftDocCTests/Test Resources/FancyProtocol.symbols.json new file mode 100644 index 0000000000..8aea52a385 --- /dev/null +++ b/Tests/SwiftDocCTests/Test Resources/FancyProtocol.symbols.json @@ -0,0 +1,3524 @@ +{ + "metadata": { + "formatVersion": { + "major": 0, + "minor": 5, + "patch": 3 + }, + "generator": "Apple Swift version 5.7 (swiftlang-5.7.0.111.54 clang-1400.0.16.2)" + }, + "module": { + "name": "FancyProtocol", + "platform": { + "architecture": "x86_64", + "vendor": "apple", + "operatingSystem": { + "name": "macosx", + "minimumVersion": { + "major": 12, + "minor": 4, + "patch": 0 + } + } + } + }, + "symbols": [ + { + "kind": { + "identifier": "swift.protocol", + "displayName": "Protocol" + }, + "identifier": { + "precise": "s:12FancyProtocol13FancyProtocolP", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "FancyProtocol" + ], + "names": { + "title": "FancyProtocol", + "navigator": [ + { + "kind": "identifier", + "spelling": "FancyProtocol" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "protocol" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "FancyProtocol" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 23, + "character": 4 + }, + "end": { + "line": 23, + "character": 34 + } + }, + "text": "woah, fancy protocol over here" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "protocol" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "FancyProtocol" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.func.op", + "displayName": "Operator" + }, + "identifier": { + "precise": "s:12FancyProtocol13FancyProtocolPAAE4zzzzoiyxx_xtFZ", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "FancyProtocol", + "....(_:_:)" + ], + "names": { + "title": "....(_:_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "...." + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 25, + "character": 8 + }, + "end": { + "line": 25, + "character": 43 + } + }, + "text": "this right here is a fancy operator" + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "left", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "left" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + { + "name": "right", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "right" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + "swiftExtension": { + "extendedModule": "FancyProtocol" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "...." + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "internalParam", + "spelling": "left" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "internalParam", + "spelling": "right" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.func.op", + "displayName": "Operator" + }, + "identifier": { + "precise": "s:12FancyProtocol9SomeClassC1loiySbAC_ACtFZ", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "SomeClass", + "<(_:_:)" + ], + "names": { + "title": "<(_:_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "<" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "SomeClass", + "preciseIdentifier": "s:12FancyProtocol9SomeClassC" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "typeIdentifier", + "spelling": "SomeClass", + "preciseIdentifier": "s:12FancyProtocol9SomeClassC" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Returns a Boolean value indicating whether the value of the first" + }, + { + "text": "argument is less than that of the second argument." + }, + { + "text": "" + }, + { + "text": "This function is the only requirement of the `Comparable` protocol. The" + }, + { + "text": "remainder of the relational operator functions are implemented by the" + }, + { + "text": "standard library for any type that conforms to `Comparable`." + }, + { + "text": "" + }, + { + "text": "- Parameters:" + }, + { + "text": " - lhs: A value to compare." + }, + { + "text": " - rhs: Another value to compare." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "lhs", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "lhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "SomeClass", + "preciseIdentifier": "s:12FancyProtocol9SomeClassC" + } + ] + }, + { + "name": "rhs", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "rhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "SomeClass", + "preciseIdentifier": "s:12FancyProtocol9SomeClassC" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "<" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "internalParam", + "spelling": "lhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "SomeClass", + "preciseIdentifier": "s:12FancyProtocol9SomeClassC" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "internalParam", + "spelling": "rhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "SomeClass", + "preciseIdentifier": "s:12FancyProtocol9SomeClassC" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.func.op", + "displayName": "Operator" + }, + "identifier": { + "precise": "s:12FancyProtocol9SomeClassC2eeoiySbAC_ACtFZ", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "SomeClass", + "==(_:_:)" + ], + "names": { + "title": "==(_:_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "==" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "SomeClass", + "preciseIdentifier": "s:12FancyProtocol9SomeClassC" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "typeIdentifier", + "spelling": "SomeClass", + "preciseIdentifier": "s:12FancyProtocol9SomeClassC" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Returns a Boolean value indicating whether two values are equal." + }, + { + "text": "" + }, + { + "text": "Equality is the inverse of inequality. For any values `a` and `b`," + }, + { + "text": "`a == b` implies that `a != b` is `false`." + }, + { + "text": "" + }, + { + "text": "- Parameters:" + }, + { + "text": " - lhs: A value to compare." + }, + { + "text": " - rhs: Another value to compare." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "lhs", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "lhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "SomeClass", + "preciseIdentifier": "s:12FancyProtocol9SomeClassC" + } + ] + }, + { + "name": "rhs", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "rhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "SomeClass", + "preciseIdentifier": "s:12FancyProtocol9SomeClassC" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "==" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "internalParam", + "spelling": "lhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "SomeClass", + "preciseIdentifier": "s:12FancyProtocol9SomeClassC" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "internalParam", + "spelling": "rhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "SomeClass", + "preciseIdentifier": "s:12FancyProtocol9SomeClassC" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.func.op", + "displayName": "Operator" + }, + "identifier": { + "precise": "s:SQsE2neoiySbx_xtFZ::SYNTHESIZED::s:12FancyProtocol9SomeClassC", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "SomeClass", + "!=(_:_:)" + ], + "names": { + "title": "!=(_:_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "!=" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "lhs", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "lhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + { + "name": "rhs", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "rhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "!=" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "internalParam", + "spelling": "lhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "internalParam", + "spelling": "rhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.func.op", + "displayName": "Operator" + }, + "identifier": { + "precise": "s:SLsE3zzlopys16PartialRangeUpToVyxGxFZ::SYNTHESIZED::s:12FancyProtocol9SomeClassC", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "SomeClass", + "..<(_:)" + ], + "names": { + "title": "..<(_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "..<" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "PartialRangeUpTo", + "preciseIdentifier": "s:s16PartialRangeUpToV" + }, + { + "kind": "text", + "spelling": "<" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ">" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Returns a partial range up to, but not including, its upper bound." + }, + { + "text": "" + }, + { + "text": "Use the prefix half-open range operator (prefix `..<`) to create a" + }, + { + "text": "partial range of any type that conforms to the `Comparable` protocol." + }, + { + "text": "This example creates a `PartialRangeUpTo` instance that includes" + }, + { + "text": "any value less than `5.0`." + }, + { + "text": "" + }, + { + "text": " let upToFive = ..<5.0" + }, + { + "text": "" + }, + { + "text": " upToFive.contains(3.14) // true" + }, + { + "text": " upToFive.contains(6.28) // false" + }, + { + "text": " upToFive.contains(5.0) // false" + }, + { + "text": "" + }, + { + "text": "You can use this type of partial range of a collection's indices to" + }, + { + "text": "represent the range from the start of the collection up to, but not" + }, + { + "text": "including, the partial range's upper bound." + }, + { + "text": "" + }, + { + "text": " let numbers = [10, 20, 30, 40, 50, 60, 70]" + }, + { + "text": " print(numbers[..<3])" + }, + { + "text": " // Prints \"[10, 20, 30]\"" + }, + { + "text": "" + }, + { + "text": "- Parameter maximum: The upper bound for the range." + }, + { + "text": "" + }, + { + "text": "- Precondition: `maximum` must compare equal to itself (i.e. cannot be NaN)." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "maximum", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "maximum" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "PartialRangeUpTo", + "preciseIdentifier": "s:s16PartialRangeUpToV" + }, + { + "kind": "text", + "spelling": "<" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ">" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "..<" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "internalParam", + "spelling": "maximum" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "PartialRangeUpTo", + "preciseIdentifier": "s:s16PartialRangeUpToV" + }, + { + "kind": "text", + "spelling": "<" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ">" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.func.op", + "displayName": "Operator" + }, + "identifier": { + "precise": "s:12FancyProtocol13FancyProtocolPAAE4zzzzoiyxx_xtFZ::SYNTHESIZED::s:12FancyProtocol9SomeClassC", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "SomeClass", + "....(_:_:)" + ], + "names": { + "title": "....(_:_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "...." + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 25, + "character": 8 + }, + "end": { + "line": 25, + "character": 43 + } + }, + "text": "this right here is a fancy operator" + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "left", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "left" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + { + "name": "right", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "right" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + "swiftExtension": { + "extendedModule": "FancyProtocol" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "...." + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "internalParam", + "spelling": "left" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "internalParam", + "spelling": "right" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.func.op", + "displayName": "Operator" + }, + "identifier": { + "precise": "s:SLsE2leoiySbx_xtFZ::SYNTHESIZED::s:12FancyProtocol9SomeClassC", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "SomeClass", + "<=(_:_:)" + ], + "names": { + "title": "<=(_:_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "<=" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Returns a Boolean value indicating whether the value of the first argument" + }, + { + "text": "is less than or equal to that of the second argument." + }, + { + "text": "" + }, + { + "text": "This is the default implementation of the less-than-or-equal-to" + }, + { + "text": "operator (`<=`) for any type that conforms to `Comparable`." + }, + { + "text": "" + }, + { + "text": "- Parameters:" + }, + { + "text": " - lhs: A value to compare." + }, + { + "text": " - rhs: Another value to compare." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "lhs", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "lhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + { + "name": "rhs", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "rhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "<=" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "internalParam", + "spelling": "lhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "internalParam", + "spelling": "rhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.func.op", + "displayName": "Operator" + }, + "identifier": { + "precise": "s:SLsE3zzzoPys16PartialRangeFromVyxGxFZ::SYNTHESIZED::s:12FancyProtocol9SomeClassC", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "SomeClass", + "...(_:)" + ], + "names": { + "title": "...(_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "..." + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "PartialRangeFrom", + "preciseIdentifier": "s:s16PartialRangeFromV" + }, + { + "kind": "text", + "spelling": "<" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ">" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Returns a partial range extending upward from a lower bound." + }, + { + "text": "" + }, + { + "text": "Use the postfix range operator (postfix `...`) to create a partial range" + }, + { + "text": "of any type that conforms to the `Comparable` protocol. This example" + }, + { + "text": "creates a `PartialRangeFrom` instance that includes any value" + }, + { + "text": "greater than or equal to `5.0`." + }, + { + "text": "" + }, + { + "text": " let atLeastFive = 5.0..." + }, + { + "text": "" + }, + { + "text": " atLeastFive.contains(4.0) // false" + }, + { + "text": " atLeastFive.contains(5.0) // true" + }, + { + "text": " atLeastFive.contains(6.0) // true" + }, + { + "text": "" + }, + { + "text": "You can use this type of partial range of a collection's indices to" + }, + { + "text": "represent the range from the partial range's lower bound up to the end" + }, + { + "text": "of the collection." + }, + { + "text": "" + }, + { + "text": " let numbers = [10, 20, 30, 40, 50, 60, 70]" + }, + { + "text": " print(numbers[3...])" + }, + { + "text": " // Prints \"[40, 50, 60, 70]\"" + }, + { + "text": "" + }, + { + "text": "- Parameter minimum: The lower bound for the range." + }, + { + "text": "" + }, + { + "text": "- Precondition: `minimum` must compare equal to itself (i.e. cannot be NaN)." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "minimum", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "minimum" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "PartialRangeFrom", + "preciseIdentifier": "s:s16PartialRangeFromV" + }, + { + "kind": "text", + "spelling": "<" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ">" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "..." + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "internalParam", + "spelling": "minimum" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "PartialRangeFrom", + "preciseIdentifier": "s:s16PartialRangeFromV" + }, + { + "kind": "text", + "spelling": "<" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ">" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.func.op", + "displayName": "Operator" + }, + "identifier": { + "precise": "s:12FancyProtocol13FancyProtocolP4zzzzoiyxx_xtFZ", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "FancyProtocol", + "....(_:_:)" + ], + "names": { + "title": "....(_:_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "...." + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 25, + "character": 8 + }, + "end": { + "line": 25, + "character": 43 + } + }, + "text": "this right here is a fancy operator" + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "left", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "left" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + { + "name": "right", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "right" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "...." + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "internalParam", + "spelling": "left" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "internalParam", + "spelling": "right" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.class", + "displayName": "Class" + }, + "identifier": { + "precise": "s:12FancyProtocol9SomeClassC", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "SomeClass" + ], + "names": { + "title": "SomeClass", + "navigator": [ + { + "kind": "identifier", + "spelling": "SomeClass" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "class" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "SomeClass" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "class" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "SomeClass" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.func.op", + "displayName": "Operator" + }, + "identifier": { + "precise": "s:SLsE3zzzoiySNyxGx_xtFZ::SYNTHESIZED::s:12FancyProtocol9SomeClassC", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "SomeClass", + "...(_:_:)" + ], + "names": { + "title": "...(_:_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "..." + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "ClosedRange", + "preciseIdentifier": "s:SN" + }, + { + "kind": "text", + "spelling": "<" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ">" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Returns a closed range that contains both of its bounds." + }, + { + "text": "" + }, + { + "text": "Use the closed range operator (`...`) to create a closed range of any type" + }, + { + "text": "that conforms to the `Comparable` protocol. This example creates a" + }, + { + "text": "`ClosedRange` from \"a\" up to, and including, \"z\"." + }, + { + "text": "" + }, + { + "text": " let lowercase = \"a\"...\"z\"" + }, + { + "text": " print(lowercase.contains(\"z\"))" + }, + { + "text": " // Prints \"true\"" + }, + { + "text": "" + }, + { + "text": "- Parameters:" + }, + { + "text": " - minimum: The lower bound for the range." + }, + { + "text": " - maximum: The upper bound for the range." + }, + { + "text": "" + }, + { + "text": "- Precondition: `minimum <= maximum`." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "minimum", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "minimum" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + { + "name": "maximum", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "maximum" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "ClosedRange", + "preciseIdentifier": "s:SN" + }, + { + "kind": "text", + "spelling": "<" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ">" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "..." + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "internalParam", + "spelling": "minimum" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "internalParam", + "spelling": "maximum" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "ClosedRange", + "preciseIdentifier": "s:SN" + }, + { + "kind": "text", + "spelling": "<" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ">" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.func.op", + "displayName": "Operator" + }, + "identifier": { + "precise": "s:SLsE3zzloiySnyxGx_xtFZ::SYNTHESIZED::s:12FancyProtocol9SomeClassC", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "SomeClass", + "..<(_:_:)" + ], + "names": { + "title": "..<(_:_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "..<" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Range", + "preciseIdentifier": "s:Sn" + }, + { + "kind": "text", + "spelling": "<" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ">" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Returns a half-open range that contains its lower bound but not its upper" + }, + { + "text": "bound." + }, + { + "text": "" + }, + { + "text": "Use the half-open range operator (`..<`) to create a range of any type" + }, + { + "text": "that conforms to the `Comparable` protocol. This example creates a" + }, + { + "text": "`Range` from zero up to, but not including, 5.0." + }, + { + "text": "" + }, + { + "text": " let lessThanFive = 0.0..<5.0" + }, + { + "text": " print(lessThanFive.contains(3.14)) // Prints \"true\"" + }, + { + "text": " print(lessThanFive.contains(5.0)) // Prints \"false\"" + }, + { + "text": "" + }, + { + "text": "- Parameters:" + }, + { + "text": " - minimum: The lower bound for the range." + }, + { + "text": " - maximum: The upper bound for the range." + }, + { + "text": "" + }, + { + "text": "- Precondition: `minimum <= maximum`." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "minimum", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "minimum" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + { + "name": "maximum", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "maximum" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Range", + "preciseIdentifier": "s:Sn" + }, + { + "kind": "text", + "spelling": "<" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ">" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "..<" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "internalParam", + "spelling": "minimum" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "internalParam", + "spelling": "maximum" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Range", + "preciseIdentifier": "s:Sn" + }, + { + "kind": "text", + "spelling": "<" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ">" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.property", + "displayName": "Instance Property" + }, + "identifier": { + "precise": "s:12FancyProtocol9SomeClassC8somePropSSvp", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "SomeClass", + "someProp" + ], + "names": { + "title": "someProp", + "subHeading": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "someProp" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "String", + "preciseIdentifier": "s:SS" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "someProp" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "String", + "preciseIdentifier": "s:SS" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.func.op", + "displayName": "Operator" + }, + "identifier": { + "precise": "s:SLsE3zzzopys19PartialRangeThroughVyxGxFZ::SYNTHESIZED::s:12FancyProtocol9SomeClassC", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "SomeClass", + "...(_:)" + ], + "names": { + "title": "...(_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "..." + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "PartialRangeThrough", + "preciseIdentifier": "s:s19PartialRangeThroughV" + }, + { + "kind": "text", + "spelling": "<" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ">" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Returns a partial range up to, and including, its upper bound." + }, + { + "text": "" + }, + { + "text": "Use the prefix closed range operator (prefix `...`) to create a partial" + }, + { + "text": "range of any type that conforms to the `Comparable` protocol. This" + }, + { + "text": "example creates a `PartialRangeThrough` instance that includes" + }, + { + "text": "any value less than or equal to `5.0`." + }, + { + "text": "" + }, + { + "text": " let throughFive = ...5.0" + }, + { + "text": "" + }, + { + "text": " throughFive.contains(4.0) // true" + }, + { + "text": " throughFive.contains(5.0) // true" + }, + { + "text": " throughFive.contains(6.0) // false" + }, + { + "text": "" + }, + { + "text": "You can use this type of partial range of a collection's indices to" + }, + { + "text": "represent the range from the start of the collection up to, and" + }, + { + "text": "including, the partial range's upper bound." + }, + { + "text": "" + }, + { + "text": " let numbers = [10, 20, 30, 40, 50, 60, 70]" + }, + { + "text": " print(numbers[...3])" + }, + { + "text": " // Prints \"[10, 20, 30, 40]\"" + }, + { + "text": "" + }, + { + "text": "- Parameter maximum: The upper bound for the range." + }, + { + "text": "" + }, + { + "text": "- Precondition: `maximum` must compare equal to itself (i.e. cannot be NaN)." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "maximum", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "maximum" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "PartialRangeThrough", + "preciseIdentifier": "s:s19PartialRangeThroughV" + }, + { + "kind": "text", + "spelling": "<" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ">" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "..." + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "internalParam", + "spelling": "maximum" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "PartialRangeThrough", + "preciseIdentifier": "s:s19PartialRangeThroughV" + }, + { + "kind": "text", + "spelling": "<" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ">" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.func.op", + "displayName": "Operator" + }, + "identifier": { + "precise": "s:SLsE1goiySbx_xtFZ::SYNTHESIZED::s:12FancyProtocol9SomeClassC", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "SomeClass", + ">(_:_:)" + ], + "names": { + "title": ">(_:_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": ">" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Returns a Boolean value indicating whether the value of the first argument" + }, + { + "text": "is greater than that of the second argument." + }, + { + "text": "" + }, + { + "text": "This is the default implementation of the greater-than operator (`>`) for" + }, + { + "text": "any type that conforms to `Comparable`." + }, + { + "text": "" + }, + { + "text": "- Parameters:" + }, + { + "text": " - lhs: A value to compare." + }, + { + "text": " - rhs: Another value to compare." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "lhs", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "lhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + { + "name": "rhs", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "rhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": ">" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "internalParam", + "spelling": "lhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "internalParam", + "spelling": "rhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.func.op", + "displayName": "Operator" + }, + "identifier": { + "precise": "s:SLsE2geoiySbx_xtFZ::SYNTHESIZED::s:12FancyProtocol9SomeClassC", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "SomeClass", + ">=(_:_:)" + ], + "names": { + "title": ">=(_:_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": ">=" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Returns a Boolean value indicating whether the value of the first argument" + }, + { + "text": "is greater than or equal to that of the second argument." + }, + { + "text": "" + }, + { + "text": "This is the default implementation of the greater-than-or-equal-to operator" + }, + { + "text": "(`>=`) for any type that conforms to `Comparable`." + }, + { + "text": "" + }, + { + "text": "- Parameters:" + }, + { + "text": " - lhs: A value to compare." + }, + { + "text": " - rhs: Another value to compare." + }, + { + "text": "- Returns: `true` if `lhs` is greater than or equal to `rhs`; otherwise," + }, + { + "text": " `false`." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "lhs", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "lhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + { + "name": "rhs", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "rhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": ">=" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "internalParam", + "spelling": "lhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "internalParam", + "spelling": "rhs" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ], + "accessLevel": "public" + } + ], + "relationships": [ + { + "kind": "memberOf", + "source": "s:12FancyProtocol9SomeClassC1loiySbAC_ACtFZ", + "target": "s:12FancyProtocol9SomeClassC", + "sourceOrigin": { + "identifier": "s:SL1loiySbx_xtFZ", + "displayName": "Comparable.<(_:_:)" + } + }, + { + "kind": "memberOf", + "source": "s:12FancyProtocol9SomeClassC2eeoiySbAC_ACtFZ", + "target": "s:12FancyProtocol9SomeClassC", + "sourceOrigin": { + "identifier": "s:SQ2eeoiySbx_xtFZ", + "displayName": "Equatable.==(_:_:)" + } + }, + { + "kind": "defaultImplementationOf", + "source": "s:12FancyProtocol13FancyProtocolPAAE4zzzzoiyxx_xtFZ", + "target": "s:12FancyProtocol13FancyProtocolP4zzzzoiyxx_xtFZ", + "sourceOrigin": { + "identifier": "s:12FancyProtocol13FancyProtocolP4zzzzoiyxx_xtFZ", + "displayName": "FancyProtocol.....(_:_:)" + } + }, + { + "kind": "memberOf", + "source": "s:SLsE2leoiySbx_xtFZ::SYNTHESIZED::s:12FancyProtocol9SomeClassC", + "target": "s:12FancyProtocol9SomeClassC", + "sourceOrigin": { + "identifier": "s:SLsE2leoiySbx_xtFZ", + "displayName": "Comparable.<=(_:_:)" + } + }, + { + "kind": "memberOf", + "source": "s:12FancyProtocol13FancyProtocolPAAE4zzzzoiyxx_xtFZ::SYNTHESIZED::s:12FancyProtocol9SomeClassC", + "target": "s:12FancyProtocol9SomeClassC", + "sourceOrigin": { + "identifier": "s:12FancyProtocol13FancyProtocolP4zzzzoiyxx_xtFZ", + "displayName": "FancyProtocol.....(_:_:)" + } + }, + { + "kind": "memberOf", + "source": "s:SLsE3zzlopys16PartialRangeUpToVyxGxFZ::SYNTHESIZED::s:12FancyProtocol9SomeClassC", + "target": "s:12FancyProtocol9SomeClassC", + "sourceOrigin": { + "identifier": "s:SLsE3zzlopys16PartialRangeUpToVyxGxFZ", + "displayName": "Comparable...<(_:)" + } + }, + { + "kind": "memberOf", + "source": "s:SQsE2neoiySbx_xtFZ::SYNTHESIZED::s:12FancyProtocol9SomeClassC", + "target": "s:12FancyProtocol9SomeClassC", + "sourceOrigin": { + "identifier": "s:SQsE2neoiySbx_xtFZ", + "displayName": "Equatable.!=(_:_:)" + } + }, + { + "kind": "memberOf", + "source": "s:SLsE3zzzoPys16PartialRangeFromVyxGxFZ::SYNTHESIZED::s:12FancyProtocol9SomeClassC", + "target": "s:12FancyProtocol9SomeClassC", + "sourceOrigin": { + "identifier": "s:SLsE3zzzoPys16PartialRangeFromVyxGxFZ", + "displayName": "Comparable....(_:)" + } + }, + { + "kind": "requirementOf", + "source": "s:12FancyProtocol13FancyProtocolP4zzzzoiyxx_xtFZ", + "target": "s:12FancyProtocol13FancyProtocolP" + }, + { + "kind": "conformsTo", + "source": "s:12FancyProtocol9SomeClassC", + "target": "s:SQ", + "targetFallback": "Swift.Equatable" + }, + { + "kind": "memberOf", + "source": "s:SLsE3zzloiySnyxGx_xtFZ::SYNTHESIZED::s:12FancyProtocol9SomeClassC", + "target": "s:12FancyProtocol9SomeClassC", + "sourceOrigin": { + "identifier": "s:SLsE3zzloiySnyxGx_xtFZ", + "displayName": "Comparable...<(_:_:)" + } + }, + { + "kind": "memberOf", + "source": "s:SLsE3zzzoiySNyxGx_xtFZ::SYNTHESIZED::s:12FancyProtocol9SomeClassC", + "target": "s:12FancyProtocol9SomeClassC", + "sourceOrigin": { + "identifier": "s:SLsE3zzzoiySNyxGx_xtFZ", + "displayName": "Comparable....(_:_:)" + } + }, + { + "kind": "memberOf", + "source": "s:12FancyProtocol9SomeClassC8somePropSSvp", + "target": "s:12FancyProtocol9SomeClassC" + }, + { + "kind": "conformsTo", + "source": "s:12FancyProtocol9SomeClassC", + "target": "s:SL", + "targetFallback": "Swift.Comparable" + }, + { + "kind": "memberOf", + "source": "s:SLsE2geoiySbx_xtFZ::SYNTHESIZED::s:12FancyProtocol9SomeClassC", + "target": "s:12FancyProtocol9SomeClassC", + "sourceOrigin": { + "identifier": "s:SLsE2geoiySbx_xtFZ", + "displayName": "Comparable.>=(_:_:)" + } + }, + { + "kind": "memberOf", + "source": "s:SLsE1goiySbx_xtFZ::SYNTHESIZED::s:12FancyProtocol9SomeClassC", + "target": "s:12FancyProtocol9SomeClassC", + "sourceOrigin": { + "identifier": "s:SLsE1goiySbx_xtFZ", + "displayName": "Comparable.>(_:_:)" + } + }, + { + "kind": "conformsTo", + "source": "s:12FancyProtocol9SomeClassC", + "target": "s:12FancyProtocol13FancyProtocolP" + }, + { + "kind": "memberOf", + "source": "s:SLsE3zzzopys19PartialRangeThroughVyxGxFZ::SYNTHESIZED::s:12FancyProtocol9SomeClassC", + "target": "s:12FancyProtocol9SomeClassC", + "sourceOrigin": { + "identifier": "s:SLsE3zzzopys19PartialRangeThroughVyxGxFZ", + "displayName": "Comparable....(_:)" + } + } + ] +} From dd06f44710563a0808afe70e56e28c5667ba8a50 Mon Sep 17 00:00:00 2001 From: Victoria Mitchell Date: Fri, 10 Jun 2022 10:07:29 -0600 Subject: [PATCH 2/4] review: use String.split instead of .components.filter --- .../Symbol Graph/GeneratedDocumentationTopics.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/SwiftDocC/Infrastructure/Symbol Graph/GeneratedDocumentationTopics.swift b/Sources/SwiftDocC/Infrastructure/Symbol Graph/GeneratedDocumentationTopics.swift index b23ca6d42f..93ac9f3ff7 100644 --- a/Sources/SwiftDocC/Infrastructure/Symbol Graph/GeneratedDocumentationTopics.swift +++ b/Sources/SwiftDocC/Infrastructure/Symbol Graph/GeneratedDocumentationTopics.swift @@ -51,7 +51,7 @@ enum GeneratedDocumentationTopics { // If we don't have a resolved `sourceOrigin` parent, fall back to parsing its display name // Detect the path components of the providing the default implementation. - let typeComponents = originDisplayName.components(separatedBy: ".").filter({ !$0.isEmpty }) + let typeComponents = originDisplayName.split(separator: ".") // Verify that the fully qualified name contains at least a type name and default implementation name. guard typeComponents.count >= 2 else { return } @@ -59,7 +59,7 @@ enum GeneratedDocumentationTopics { // Get the fully qualified type. fromType = typeComponents.dropLast().joined(separator: ".") // The name of the type is second to last. - typeSimpleName = typeComponents[typeComponents.count-2] + typeSimpleName = String(typeComponents[typeComponents.count-2]) } // Create a type with inherited symbols, if needed. From 02ad0cbbabe2c7142872da25d4a11558019780fa Mon Sep 17 00:00:00 2001 From: Victoria Mitchell Date: Fri, 10 Jun 2022 10:23:17 -0600 Subject: [PATCH 3/4] review: remove unneeded cleanup block --- .../SwiftDocCTests/Rendering/RenderNodeTranslatorTests.swift | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorTests.swift b/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorTests.swift index 7ebc681bed..97da4c3c8d 100644 --- a/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorTests.swift +++ b/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorTests.swift @@ -630,12 +630,9 @@ class RenderNodeTranslatorTests: XCTestCase { forResource: "FancyProtocol.symbols", withExtension: "json", subdirectory: "Test Resources")! // Create a test bundle copy with the symbol graph from above - let (bundleURL, bundle, context) = try testBundleAndContext(copying: "TestBundle", excludingPaths: [], codeListings: [:]) { url in + let (_, bundle, context) = try testBundleAndContext(copying: "TestBundle", excludingPaths: [], codeListings: [:]) { url in try? FileManager.default.copyItem(at: fancyProtocolSGFURL, to: url.appendingPathComponent("FancyProtocol.symbols.json")) } - defer { - try? FileManager.default.removeItem(at: bundleURL) - } let reference = ResolvedTopicReference(bundleIdentifier: bundle.identifier, path: "/documentation/FancyProtocol/SomeClass", sourceLanguage: .swift) var translator = RenderNodeTranslator(context: context, bundle: bundle, identifier: reference, source: nil) From f2d37daef1dee183fe623b3416c72accbf6a6d47 Mon Sep 17 00:00:00 2001 From: Victoria Mitchell Date: Fri, 10 Jun 2022 11:16:25 -0600 Subject: [PATCH 4/4] review: add test for default implementation page titles --- .../Rendering/RenderNodeTranslatorTests.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorTests.swift b/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorTests.swift index 97da4c3c8d..400a1fcb37 100644 --- a/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorTests.swift +++ b/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorTests.swift @@ -646,6 +646,13 @@ class RenderNodeTranslatorTests: XCTestCase { "doc://org.swift.docc.example/documentation/FancyProtocol/SomeClass/Equatable-Implementations", "doc://org.swift.docc.example/documentation/FancyProtocol/SomeClass/FancyProtocol-Implementations", ]) + let implReferences = defaultImplementationSection.identifiers.compactMap({ renderNode.references[$0] as? TopicRenderReference }) + XCTAssertEqual(implReferences.map({ $0.title }), [ + "Comparable Implementations", + "Equatable Implementations", + "FancyProtocol Implementations", + ]) + } func testAutomaticTaskGroupTopicsAreSorted() throws {