diff --git a/Sources/SwiftDocC/DocumentationService/Convert/Symbol Link Resolution/DocCSymbolRepresentable.swift b/Sources/SwiftDocC/DocumentationService/Convert/Symbol Link Resolution/DocCSymbolRepresentable.swift index 272f3c6ddc..7b80a822f2 100644 --- a/Sources/SwiftDocC/DocumentationService/Convert/Symbol Link Resolution/DocCSymbolRepresentable.swift +++ b/Sources/SwiftDocC/DocumentationService/Convert/Symbol Link Resolution/DocCSymbolRepresentable.swift @@ -154,12 +154,19 @@ public extension Collection where Element: DocCSymbolRepresentable { } else { // Disambiguate by kind return map { currentSymbol in - ( - shouldAddIdHash: filter { - $0.kindIdentifier == currentSymbol.kindIdentifier - }.count > 1, - shouldAddKind: true - ) + let kindCount = filter { $0.kindIdentifier == currentSymbol.kindIdentifier }.count + + if LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver { + return ( + shouldAddIdHash: kindCount > 1, + shouldAddKind: kindCount == 1 + ) + } else { + return ( + shouldAddIdHash: kindCount > 1, + shouldAddKind: true + ) + } } } } diff --git a/Sources/SwiftDocC/Infrastructure/DocumentationContext.swift b/Sources/SwiftDocC/Infrastructure/DocumentationContext.swift index 3f6d27b750..9e9b07c280 100644 --- a/Sources/SwiftDocC/Infrastructure/DocumentationContext.swift +++ b/Sources/SwiftDocC/Infrastructure/DocumentationContext.swift @@ -110,7 +110,17 @@ public class DocumentationContext: DocumentationContextDataProviderDelegate { } } + /// A link resolver that resolves references by finding them in the documentation cache. let documentationCacheBasedLinkResolver = DocumentationCacheBasedLinkResolver() + /// A link resolver that resolves references by finding them in path hierarchy. + var hierarchyBasedLinkResolver: PathHierarchyBasedLinkResolver? = nil + + /// Gathered differences between the two link resolution implementations. + /// + /// This is only if ``LinkResolutionMigrationConfiguration/shouldReportLinkResolutionPathMismatches`` or ``LinkResolutionMigrationConfiguration/shouldReportLinkResolutionResultMismatches`` is enabled. + /// + /// > Note: This is a temporary property that will go away along with the ``DocumentationCacheBasedLinkResolver`` at some point in the future. + var linkResolutionMismatches = LinkResolutionMismatches() /// The provider of documentation bundles for this context. var dataProvider: DocumentationContextDataProvider @@ -323,6 +333,9 @@ public class DocumentationContext: DocumentationContextDataProviderDelegate { /// - bundle: The bundle that was removed. public func dataProvider(_ dataProvider: DocumentationContextDataProvider, didRemoveBundle bundle: DocumentationBundle) throws { documentationCacheBasedLinkResolver.unregisterBundle(identifier: bundle.identifier) + if let hierarchyBasedLinkResolver = hierarchyBasedLinkResolver { + hierarchyBasedLinkResolver.unregisterBundle(identifier: bundle.identifier) + } // Purge the reference cache for this bundle and disable reference caching for // this bundle moving forward. @@ -1106,7 +1119,13 @@ public class DocumentationContext: DocumentationContextDataProviderDelegate { var moduleReferences = [String: ResolvedTopicReference]() // Build references for all symbols in all of this module's symbol graphs. - let symbolReferences = documentationCacheBasedLinkResolver.referencesForSymbols(in: symbolGraphLoader.unifiedGraphs, bundle: bundle, context: self) + let symbolReferences: [SymbolGraph.Symbol.Identifier : [ResolvedTopicReference]] + if LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver { + symbolReferences = hierarchyBasedLinkResolver!.referencesForSymbols(in:symbolGraphLoader.unifiedGraphs, bundle: bundle, context: self) + .mapValues({ [$0] }) // The documentation cache implementation uses an array of values to handle multi languages + } else { + symbolReferences = documentationCacheBasedLinkResolver.referencesForSymbols(in: symbolGraphLoader.unifiedGraphs, bundle: bundle, context: self) + } // Set the index and cache storage capacity to avoid ad-hoc storage resizing. symbolIndex.reserveCapacity(symbolReferences.count) @@ -1203,20 +1222,24 @@ public class DocumentationContext: DocumentationContextDataProviderDelegate { // Add this module to the dictionary of processed modules to keep track of repeat symbol graphs moduleReferences[moduleName] = moduleReference - // Add modules as root nodes in the URL tree - try symbolsURLHierarchy.add(moduleReference, parent: symbolsURLHierarchy.root) + if hierarchyBasedLinkResolver == nil || LinkResolutionMigrationConfiguration.shouldReportLinkResolutionMismatches { + // Add modules as root nodes in the URL tree + try symbolsURLHierarchy.add(moduleReference, parent: symbolsURLHierarchy.root) + } } - // Map the symbol graph hierarchy into a URL tree to use as default curation - // for symbols that aren't manually curated via documentation extension. - - // Curate all root framework symbols under the module in the URL tree - for symbol in unifiedSymbolGraph.symbols.values where symbol.defaultSymbol!.pathComponents.count == 1 { - try symbolIndex[symbol.uniqueIdentifier].map({ - // If merging symbol graph extension there can be repeat symbols, don't add them again. - guard (try? symbolsURLHierarchy.parent(of: $0.reference)) == nil else { return } - try symbolsURLHierarchy.add($0.reference, parent: moduleReference) - }) + if hierarchyBasedLinkResolver == nil || LinkResolutionMigrationConfiguration.shouldReportLinkResolutionMismatches { + // Map the symbol graph hierarchy into a URL tree to use as default curation + // for symbols that aren't manually curated via documentation extension. + + // Curate all root framework symbols under the module in the URL tree + for symbol in unifiedSymbolGraph.symbols.values where symbol.defaultSymbol!.pathComponents.count == 1 { + try symbolIndex[symbol.uniqueIdentifier].map({ + // If merging symbol graph extension there can be repeat symbols, don't add them again. + guard (try? symbolsURLHierarchy.parent(of: $0.reference)) == nil else { return } + try symbolsURLHierarchy.add($0.reference, parent: moduleReference) + }) + } } // Collect symbols and relationships @@ -1236,35 +1259,117 @@ public class DocumentationContext: DocumentationContextDataProviderDelegate { try shouldContinueRegistration() - for (_, relationships) in combinedRelationships { - // Add parent <-> child edges to the URL tree - try relationships - .compactMap(parentChildRelationship(from:)) - .sorted(by: Self.sortRelationshipsPreOrder) - .forEach({ pair in - // Add the relationship to the URL hierarchy - let (parentRef, childRef) = pair - // If the unique reference already exists, it's been added by another symbol graph - // likely built for a different target platform, ignore it as it's the exact same symbol. - if (try? symbolsURLHierarchy.parent(of: childRef)) == nil { - do { - try symbolsURLHierarchy.add(childRef, parent: parentRef) - } catch let error as BidirectionalTree.Error { - switch error { - // Some parents might not exist if they are types from other frameworks and - // those are not pulled into and available in the current symbol graph. - case .nodeNotFound: break - default: throw error + if let hierarchyBasedLinkResolver = hierarchyBasedLinkResolver { + // Map the resolved references with their identifiers + hierarchyBasedLinkResolver.addMappingForSymbols(symbolIndex: symbolIndex) + } + + if hierarchyBasedLinkResolver == nil || LinkResolutionMigrationConfiguration.shouldReportLinkResolutionMismatches { + // The `symbolsURLHierarchy` is only used in the cache-based link resolver to traverse the documentation and + // update child references to also include their parent's disambiguation. + // + // It is also used to compute the would-be symbol paths when gathering symbol path mismatches between the two + // link resolution implementations. + for (_, relationships) in combinedRelationships { + // Add parent <-> child edges to the URL tree + try relationships + .compactMap(parentChildRelationship(from:)) + .sorted(by: Self.sortRelationshipsPreOrder) + .forEach({ pair in + // Add the relationship to the URL hierarchy + let (parentRef, childRef) = pair + // If the unique reference already exists, it's been added by another symbol graph + // likely built for a different target platform, ignore it as it's the exact same symbol. + if (try? symbolsURLHierarchy.parent(of: childRef)) == nil { + do { + try symbolsURLHierarchy.add(childRef, parent: parentRef) + } catch let error as BidirectionalTree.Error { + switch error { + // Some parents might not exist if they are types from other frameworks and + // those are not pulled into and available in the current symbol graph. + case .nodeNotFound: break + default: throw error + } } } + }) + } + + + // Only update the nodes and symbol index when using the documentation cache-based link resolver otherwise the context will end up in an inconsistent state. + if hierarchyBasedLinkResolver == nil { + // Update the children of collision URLs. Walk the tree and update any dependents of updated URLs + for moduleReference in moduleReferences.values { + try symbolsURLHierarchy.traversePreOrder(from: moduleReference) { reference in + try self.documentationCacheBasedLinkResolver.updateNodeWithReferenceIfCollisionChild(reference, symbolsURLHierarchy: &symbolsURLHierarchy, symbolIndex: &symbolIndex, context: self) } - }) - } - - // Update the children of collision URLs. Walk the tree and update any dependents of updated URLs - for moduleReference in moduleReferences.values { - try symbolsURLHierarchy.traversePreOrder(from: moduleReference) { reference in - try self.documentationCacheBasedLinkResolver.updateNodeWithReferenceIfCollisionChild(reference, symbolsURLHierarchy: &symbolsURLHierarchy, symbolIndex: &symbolIndex, context: self) + } + } + + if LinkResolutionMigrationConfiguration.shouldReportLinkResolutionPathMismatches { + // The way that symbol path mismatches are gathered depend on which link resolution implementation is used to resolve links. + if let hierarchyBasedLinkResolver = hierarchyBasedLinkResolver { + // Attempting to use the The documentation cache based link resolver to compute the disambiguated symbol paths when it is not in full control of the symbol index, + // topic graph, and documentation cache will result in the wrong behavior. The issues range from incorrectly computed paths to precondition failures. + // + // To compute what the disambiguated symbol paths would be for the documentation cache based link resolver, one needs to first compute the initial disambiguated + // paths and then traverse them to update the child paths to match their parents disambiguation prefix. + var cacheBasedReferences = documentationCacheBasedLinkResolver.referencesForSymbols(in: symbolGraphLoader.unifiedGraphs, bundle: bundle, context: self).mapValues({ $0.first! }) + // Normally the second step would be done by traversing the `symbolsURLHierarchy` but since that is constructed using disambiguated references that didn't originate + // from the documentation cache based link resolver the `symbolsURLHierarchy` can't accurately map to the references that are computed by the documentation cache based link resolver. + // + // Luckily the path hierarchy describe the hierarchical relationships between the symbols in a way where it's possible to get the `Symbol.Identifier` for each symbol. + // By sorting the pairs of `(symbol, parent symbol)` by the symbol's number of path components it's possible to traverse the hierarchy breath first and update the initial disambiguated + // paths from the documentation cache based link resolver so that each child path matches the disambiguation from the parent path. + let sortedSymbolAndParentPairs = hierarchyBasedLinkResolver.pathHierarchy.lookup.values.lazy + .filter { $0.symbol != nil && $0.parent?.symbol != nil } + .sorted(by: \.symbol!.pathComponents.count) + .map { ($0.symbol!.identifier, $0.parent!.symbol!.identifier) } + + for (symbolID, parentID) in sortedSymbolAndParentPairs { + if let symbolCacheReference = cacheBasedReferences[symbolID], + symbolCacheReference.pathComponents.count > 3, + let parentCacheReference = cacheBasedReferences[parentID], + parentCacheReference.pathComponents != symbolCacheReference.pathComponents.dropLast() + { + cacheBasedReferences[symbolID] = parentCacheReference.appendingPath(symbolCacheReference.lastPathComponent) + } + } + + let hierarchyBasedReferences = symbolReferences.mapValues({ $0.first! }) + for (id, hierarchyBasedReference) in hierarchyBasedReferences { + guard let cacheBasedMainReference = cacheBasedReferences[id] else { + linkResolutionMismatches.missingPathsInCacheBasedLinkResolver.append(hierarchyBasedReference.path) + continue + } + if hierarchyBasedReference.path != cacheBasedMainReference.path { + linkResolutionMismatches.pathsWithMismatchedDisambiguation[hierarchyBasedReference.path] = cacheBasedMainReference.path + } + } + for (id, cacheBasedReference) in cacheBasedReferences where !hierarchyBasedReferences.keys.contains(id) { + linkResolutionMismatches.missingPathsInHierarchyBasedLinkResolver.append(cacheBasedReference.path) + } + } else { + // If the documentation cache based implementation is used then it has already fully updated the symbol index and the documentation cache by this point. + let hierarchyBasedReferences = hierarchyBasedLinkResolver!.referencesForSymbols(in: symbolGraphLoader.unifiedGraphs, bundle: bundle, context: self) + + for (usr, hierarchyBasedReference) in hierarchyBasedReferences { + guard let cacheBasedMainReference = symbolIndex[usr.precise]?.reference.path else { + linkResolutionMismatches.missingPathsInCacheBasedLinkResolver.append(hierarchyBasedReference.path) + continue + } + + if hierarchyBasedReference.path != cacheBasedMainReference { + linkResolutionMismatches.pathsWithMismatchedDisambiguation[hierarchyBasedReference.path] = cacheBasedMainReference + } + } + for (usr, node) in symbolIndex { + guard let kind = node.symbol?.kind.identifier, kind != .module, + !hierarchyBasedReferences.keys.contains(where: { $0.precise == usr }) + else { continue } + linkResolutionMismatches.missingPathsInHierarchyBasedLinkResolver.append(node.reference.path) + } + } } } @@ -1321,10 +1426,12 @@ public class DocumentationContext: DocumentationContextDataProviderDelegate { } // Index references - documentationCacheBasedLinkResolver.referencesIndex.removeAll() - documentationCacheBasedLinkResolver.referencesIndex.reserveCapacity(knownIdentifiers.count) - for reference in knownIdentifiers { - documentationCacheBasedLinkResolver.registerReference(reference) + if !LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver { + documentationCacheBasedLinkResolver.referencesIndex.removeAll() + documentationCacheBasedLinkResolver.referencesIndex.reserveCapacity(knownIdentifiers.count) + for reference in knownIdentifiers { + documentationCacheBasedLinkResolver.registerReference(reference) + } } return (moduleReferences: Set(moduleReferences.values), urlHierarchy: symbolsURLHierarchy) @@ -1612,6 +1719,9 @@ public class DocumentationContext: DocumentationContextDataProviderDelegate { topicGraph.addNode(graphNode) documentationCache[reference] = documentation + if let hierarchyBasedLinkResolver = hierarchyBasedLinkResolver { + hierarchyBasedLinkResolver.addRootArticle(article, anchorSections: documentation.anchorSections) + } for anchor in documentation.anchorSections { nodeAnchorSections[anchor.reference] = anchor } @@ -1668,6 +1778,9 @@ public class DocumentationContext: DocumentationContextDataProviderDelegate { let graphNode = TopicGraph.Node(reference: reference, kind: .article, source: .file(url: article.source), title: title) topicGraph.addNode(graphNode) + if let hierarchyBasedLinkResolver = hierarchyBasedLinkResolver { + hierarchyBasedLinkResolver.addArticle(article, anchorSections: documentation.anchorSections) + } for anchor in documentation.anchorSections { nodeAnchorSections[anchor.reference] = anchor } @@ -1802,11 +1915,16 @@ public class DocumentationContext: DocumentationContextDataProviderDelegate { // Load all bundle symbol graphs into the loader. var symbolGraphLoader: SymbolGraphLoader! + var hierarchyBasedResolver: PathHierarchyBasedLinkResolver! discoveryGroup.async(queue: discoveryQueue) { [unowned self] in symbolGraphLoader = SymbolGraphLoader(bundle: bundle, dataProvider: self.dataProvider) do { try symbolGraphLoader.loadAll() + if LinkResolutionMigrationConfiguration.shouldSetUpHierarchyBasedLinkResolver { + let pathHierarchy = PathHierarchy(symbolGraphLoader: symbolGraphLoader, bundleName: urlReadablePath(bundle.displayName), knownDisambiguatedPathComponents: knownDisambiguatedSymbolPathComponents) + hierarchyBasedResolver = PathHierarchyBasedLinkResolver(pathHierarchy: pathHierarchy) + } } catch { // Pipe the error out of the dispatch queue. discoveryError.sync({ @@ -1862,7 +1980,21 @@ public class DocumentationContext: DocumentationContextDataProviderDelegate { // All discovery went well, process the inputs. let (technologies, tutorials, tutorialArticles, allArticles) = result var (otherArticles, rootPageArticles) = splitArticles(allArticles) - + + if LinkResolutionMigrationConfiguration.shouldSetUpHierarchyBasedLinkResolver { + hierarchyBasedLinkResolver = hierarchyBasedResolver + hierarchyBasedResolver.addMappingForRoots(bundle: bundle) + for tutorial in tutorials { + hierarchyBasedResolver.addTutorial(tutorial) + } + for article in tutorialArticles { + hierarchyBasedResolver.addTutorialArticle(article) + } + for technology in technologies { + hierarchyBasedResolver.addTechnology(technology) + } + } + let rootPages = registerRootPages(from: rootPageArticles, in: bundle) let (moduleReferences, symbolsURLHierarchy) = try registerSymbols(from: bundle, symbolGraphLoader: symbolGraphLoader) // We don't need to keep the loader in memory after we've registered all symbols. @@ -1901,7 +2033,13 @@ public class DocumentationContext: DocumentationContextDataProviderDelegate { ) try shouldContinueRegistration() - var allCuratedReferences = try crawlSymbolCuration(rootModules: moduleReferences, rootPages: rootPages, symbolsURLHierarchy: symbolsURLHierarchy, bundle: bundle) + var allCuratedReferences: Set + if LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver { + let topLevelModuleReferences = hierarchyBasedLinkResolver!.topLevelSymbols() + allCuratedReferences = try crawlSymbolCuration(in: topLevelModuleReferences, bundle: bundle) + } else { + allCuratedReferences = try crawlSymbolCuration(rootModules: moduleReferences, rootPages: rootPages, symbolsURLHierarchy: symbolsURLHierarchy, bundle: bundle) + } // Store the list of manually curated references if doc coverage is on. if shouldStoreManuallyCuratedReferences { @@ -1931,6 +2069,10 @@ public class DocumentationContext: DocumentationContextDataProviderDelegate { // Emit warnings for any remaining uncurated files. emitWarningsForUncuratedTopics() + if let hierarchyBasedLinkResolver = hierarchyBasedLinkResolver { + hierarchyBasedLinkResolver.addAnchorForSymbols(symbolIndex: symbolIndex) + } + // Fifth, resolve links in nodes that are added solely via curation try preResolveExternalLinks(references: Array(allCuratedReferences), bundle: bundle) resolveLinks(curatedReferences: allCuratedReferences, bundle: bundle) @@ -1994,13 +2136,23 @@ public class DocumentationContext: DocumentationContextDataProviderDelegate { /// /// This will include all symbols that were not manually curated by the documentation author. /// - Returns: An ordered list of symbol references that have been added to the topic graph automatically. - private func autoCurateSymbolsInTopicGraph(symbolsURLHierarchy: BidirectionalTree, engine: DiagnosticEngine) - -> [(child: ResolvedTopicReference, parent: ResolvedTopicReference)] { - - // We'll collect references in an array to keep them pre-order in respect to their position in the symbol hierarchy + private func autoCurateSymbolsInTopicGraph(symbolsURLHierarchy: BidirectionalTree, engine: DiagnosticEngine) -> [(child: ResolvedTopicReference, parent: ResolvedTopicReference)] { var automaticallyCuratedSymbols = [(ResolvedTopicReference, ResolvedTopicReference)]() + if LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver { + hierarchyBasedLinkResolver!.traverseSymbolAndParentPairs { reference, parentReference in + guard let topicGraphNode = topicGraph.nodeWithReference(reference), + let topicGraphParentNode = topicGraph.nodeWithReference(parentReference), + // Check that the node hasn't got any parents from manual curation + topicGraph.reverseEdges[reference] == nil + else { return } + topicGraph.addEdge(from: topicGraphParentNode, to: topicGraphNode) + automaticallyCuratedSymbols.append((child: reference, parent: parentReference)) + } + return automaticallyCuratedSymbols + } do { + // We'll collect references in an array to keep them pre-order in respect to their position in the symbol hierarchy // Walk all symbols and find their nodes in the topic graph try symbolsURLHierarchy.traversePreOrder { reference in @@ -2008,7 +2160,7 @@ public class DocumentationContext: DocumentationContextDataProviderDelegate { guard symbolsURLHierarchy.root != reference, // Fetch the matching topic graph node let topicGraphNode = topicGraph.nodeWithReference(reference), - // Check that the node hasn't got any parents + // Check that the node hasn't got any parents from manual curation topicGraph.reverseEdges[reference] == nil, // Check that the symbol does have a parent in the symbol graph let symbolGraphParentReference = try symbolsURLHierarchy.parent(of: reference), @@ -2059,7 +2211,6 @@ public class DocumentationContext: DocumentationContextDataProviderDelegate { // Crawl hierarchy under a root page for custom curations let rootPageReferences = rootPages.map(\.topicGraphNode.reference) - return try crawlSymbolCuration(in: topLevelModuleReferences + rootPageReferences, bundle: bundle) } @@ -2336,25 +2487,42 @@ public class DocumentationContext: DocumentationContextDataProviderDelegate { > Note: If the reference is already resolved, the original reference is returned. - Parameters: - - reference: An unresolved (or resolved) identifer. - - parentIdentifier: The *resolved* identifier that serves as an enclosing search context, especially the parent identifier's bundle identifier. + - reference: An unresolved (or resolved) reference. + - parent: The *resolved* reference that serves as an enclosing search context, especially the parent reference's bundle identifier. - fromSymbolLink: If `true` will try to resolve relative links *only* in documentation symbol locations in the hierarchy. If `false` it will try to resolve relative links as tutorials, articles, symbols, etc. - - Returns: The resolved identifier for the topic if the parent provided the correct context and the topic exists. - - We have four approaches to trying to resolve a reference: - - 1. we check if the link is already resolved, i.e. the path is fully formed and there is a matching documentation node - 2. we check if the link is resolvable in the local context (e.g. the parent), i.e. "MyClass" ~> "MyClass/myFunction()" - 3. we check if the link is resolvable as a sibling to the parent, i.e. "MyClass/myFunction()" ~> "MyClass/path" - 4. we check if the link is resolvable in the root context (e.g. the module) of its parent, i.e. we will try resolving 'MyClass' as 'MyKit/MyClass' - 5. we check if there is a registered external resolver for the link's bundle id and if so, use that resolver - - If none of these succeeds we will return the original unresolved reference. + - Returns: Either the successfully resolved reference for the topic or error information about why the reference couldn't resolve. */ public func resolve(_ reference: TopicReference, in parent: ResolvedTopicReference, fromSymbolLink isCurrentlyResolvingSymbolLink: Bool = false) -> TopicReferenceResolutionResult { switch reference { case .unresolved(let unresolvedReference): - return documentationCacheBasedLinkResolver.resolve(unresolvedReference, in: parent, fromSymbolLink: isCurrentlyResolvingSymbolLink, context: self) + if LinkResolutionMigrationConfiguration.shouldReportLinkResolutionResultMismatches { + let hierarchyBasedResult = hierarchyBasedLinkResolver!.resolve(unresolvedReference, in: parent, fromSymbolLink: isCurrentlyResolvingSymbolLink, context: self) + let cacheBasedResult = documentationCacheBasedLinkResolver.resolve(unresolvedReference, in: parent, fromSymbolLink: isCurrentlyResolvingSymbolLink, context: self) + + let inputInfo = LinkResolutionMismatches.FailedLinkInfo( + path: unresolvedReference.topicURL.url.withoutHostAndPortAndScheme().absoluteString, + parent: parent.url.withoutHostAndPortAndScheme().absoluteString, + asSymbolLink: isCurrentlyResolvingSymbolLink + ) + switch (hierarchyBasedResult, cacheBasedResult) { + case (.success, .failure): + linkResolutionMismatches.mismatchedLinksThatCacheBasedLinkResolverFailedToResolve.insert(inputInfo) + case (.failure, .success): + linkResolutionMismatches.mismatchedLinksThatHierarchyBasedLinkResolverFailedToResolve.insert(inputInfo) + default: + break // No difference to report + } + + return LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver + ? hierarchyBasedResult + : cacheBasedResult + } + + if LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver { + return hierarchyBasedLinkResolver!.resolve(unresolvedReference, in: parent, fromSymbolLink: isCurrentlyResolvingSymbolLink, context: self) + } else { + return documentationCacheBasedLinkResolver.resolve(unresolvedReference, in: parent, fromSymbolLink: isCurrentlyResolvingSymbolLink, context: self) + } case .resolved(let resolved): // This reference is already resolved (either as a success or a failure), so don't change anything. return resolved diff --git a/Sources/SwiftDocC/Infrastructure/DocumentationConverter.swift b/Sources/SwiftDocC/Infrastructure/DocumentationConverter.swift index 802e1c4620..8c348a30de 100644 --- a/Sources/SwiftDocC/Infrastructure/DocumentationConverter.swift +++ b/Sources/SwiftDocC/Infrastructure/DocumentationConverter.swift @@ -103,7 +103,7 @@ public struct DocumentationConverter: DocumentationConverterProtocol { /// - currentPlatforms: The current version and beta information for platforms that may be encountered while processing symbol graph files. /// that may be encountered while processing symbol graph files. /// - workspace: A provided documentation workspace. Creates a new empty workspace if value is `nil`. - /// - context: A provided documentation context. Creates a new empty context in the workspace if value is `nil`. + /// - context: A provided documentation context. /// - dataProvider: A data provider to use when registering bundles. /// - Parameter fileManager: A file persistence manager /// - Parameter externalIDsToConvert: The external IDs of the documentation nodes to convert. @@ -377,6 +377,8 @@ public struct DocumentationConverter: DocumentationConverterProtocol { // Log the peak memory. benchmark(add: Benchmark.PeakMemory()) + context.linkResolutionMismatches.reportGatheredMismatchesIfEnabled() + return (analysisProblems: context.problems, conversionProblems: conversionProblems) } diff --git a/Sources/SwiftDocC/Infrastructure/DocumentationCurator.swift b/Sources/SwiftDocC/Infrastructure/DocumentationCurator.swift index fc505354cb..9aaae8ba2a 100644 --- a/Sources/SwiftDocC/Infrastructure/DocumentationCurator.swift +++ b/Sources/SwiftDocC/Infrastructure/DocumentationCurator.swift @@ -42,10 +42,9 @@ struct DocumentationCurator { return cached } - let unresolved = UnresolvedTopicReference(topicURL: ValidatedURL(symbolPath: destination)) - let maybeResolved = context.resolve(.unresolved(unresolved), in: resolved, fromSymbolLink: true) - - if case let .success(resolved) = maybeResolved { + // The symbol link may be written with a scheme and bundle identifier. + let url = ValidatedURL(parsingExact: destination)?.requiring(scheme: ResolvedTopicReference.urlScheme) ?? ValidatedURL(symbolPath: destination) + if case let .success(resolved) = context.resolve(.unresolved(.init(topicURL: url)), in: resolved, fromSymbolLink: true) { return resolved } return nil @@ -116,6 +115,11 @@ struct DocumentationCurator { context.topicGraph.addNode(curatedNode) // Move the article from the article cache to the documentation + + if let hierarchyBasedLinkResolver = context.hierarchyBasedLinkResolver { + hierarchyBasedLinkResolver.addArticle(filename: articleFilename, reference: reference, anchorSections: documentationNode.anchorSections) + } + context.documentationCache[reference] = documentationNode for anchor in documentationNode.anchorSections { context.nodeAnchorSections[anchor.reference] = anchor diff --git a/Sources/SwiftDocC/Infrastructure/Link Resolution/LinkResolutionMigration.swift b/Sources/SwiftDocC/Infrastructure/Link Resolution/LinkResolutionMigration.swift new file mode 100644 index 0000000000..96b713d508 --- /dev/null +++ b/Sources/SwiftDocC/Infrastructure/Link Resolution/LinkResolutionMigration.swift @@ -0,0 +1,150 @@ +/* + 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 Swift project authors +*/ + +import Foundation + +/// A scope of configurations for how the documentation context should resolve links while migrating from one implementation to another. +/// +/// If any reporting is enabled, the documentation context will setup both link resolver to compare them. +/// +///> Note: This is a temporary configuration that will go away along with the ``DocumentationCacheBasedLinkResolver`` at some point in the future. +enum LinkResolutionMigrationConfiguration { + + // MARK: Configuration + + /// Whether or not the context should the a ``PathHierarchyBasedLinkResolver`` to resolve links. + static var shouldUseHierarchyBasedLinkResolver: Bool = { + return UserDefaults.standard.bool(forKey: "DocCUseHierarchyBasedLinkResolver") + || ProcessInfo.processInfo.environment["DOCC_USE_HIERARCHY_BASED_LINK_RESOLVER"] == "YES" + }() + + /// Whether or not the context should report differences between the disambiguated paths created by ``PathHierarchyBasedLinkResolver`` and ``DocumentationCacheBasedLinkResolver``. + /// + /// What mismatches can be reported depend on the value of ``shouldUseHierarchyBasedLinkResolver``: + /// - When the cache based resolved is used to resolve links both mismatched symbol paths and mismatched link resolution reports will be reported. + /// - When the path hierarchy based resolved is used to resolve links only mismatched symbol paths will be reported. + static var shouldReportLinkResolutionMismatches: Bool = { + return UserDefaults.standard.bool(forKey: "DocCReportLinkResolutionMismatches") + || ProcessInfo.processInfo.environment["DOCC_REPORT_LINK_RESOLUTION_MISMATCHES"] == "YES" + }() + + // MARK: Derived conditions + + /// Whether or not the context should set up a ``PathHierarchyBasedLinkResolver``. + /// + /// > Node: Check ``shouldUseHierarchyBasedLinkResolver`` to determine which implementation to use to resolve links. + static var shouldSetUpHierarchyBasedLinkResolver: Bool { + return shouldUseHierarchyBasedLinkResolver || shouldReportLinkResolutionMismatches + } + + /// Whether or not to report mismatches in link resolution results between the two implementations. + static var shouldReportLinkResolutionResultMismatches: Bool { + return shouldReportLinkResolutionMismatches && !shouldUseHierarchyBasedLinkResolver + } + + /// Whether or not to report mismatches in symbol path disambiguation between the two implementations. + static var shouldReportLinkResolutionPathMismatches: Bool { + return shouldReportLinkResolutionMismatches + } +} + +// MARK: Gathering mismatches + +/// A type that gathers differences between the two link resolution implementations. +/// +/// > Note: This is a temporary report that will go away along with the ``DocumentationCacheBasedLinkResolver`` at some point in the future. +final class LinkResolutionMismatches { + /// Gathered resolved reference paths that have different disambiguation in the two implementations. + var pathsWithMismatchedDisambiguation: [String: String] = [:] + + /// Gathered resolved reference paths that are missing from the path hierarchy-based implementation. + var missingPathsInHierarchyBasedLinkResolver: [String] = [] + /// Gathered resolved reference paths that are missing from the documentation cache-based implementation. + var missingPathsInCacheBasedLinkResolver: [String] = [] + + /// Information about the inputs for a link that resolved in one implementation but not the other. + struct FailedLinkInfo: Hashable { + /// The path, and optional fragment, of the unresolved reference. + let path: String + /// The path, and optional fragment, of the parent reference that the link was resolved relative to. + let parent: String + /// Whether or not the link was resolved as a symbol link. + let asSymbolLink: Bool + } + + /// Links that resolved in the cache-based implementation but not the path hierarchy-based implementation + var mismatchedLinksThatHierarchyBasedLinkResolverFailedToResolve = Set() + + /// Links that resolved in the path hierarchy-based implementation but not the cache-based implementation. + var mismatchedLinksThatCacheBasedLinkResolverFailedToResolve = Set() +} + +// MARK: Reporting mismatches + +extension LinkResolutionMismatches { + /// Prints the gathered mismatches + /// + /// > Note: If ``LinkResolutionMigrationConfiguration/shouldReportLinkResolutionPathMismatches`` is ``false`` this won't print anything. + func reportGatheredMismatchesIfEnabled() { + guard LinkResolutionMigrationConfiguration.shouldReportLinkResolutionPathMismatches else { return } + let prefix = "[HierarchyBasedLinkResolutionDiff]" + + if pathsWithMismatchedDisambiguation.isEmpty { + print("\(prefix) All symbol paths have the same disambiguation suffixes in both link resolver implementations.") + } else { + print("\(prefix) The following symbol paths have the different disambiguation across the two link resolver implementations:") + let columnWidth = max(40, (pathsWithMismatchedDisambiguation.keys.map { $0.count } + ["path hierarchy implementation".count]).max()!) + print("\("Path hierarchy implementation".padding(toLength: columnWidth, withPad: " ", startingAt: 0)) | Documentation cache implementation") + print("\(String(repeating: "-", count: columnWidth))-+-\(String(repeating: "-", count: columnWidth))") + for (hierarchyBasedPath, mainCacheBasedPath) in pathsWithMismatchedDisambiguation.sorted(by: \.key) { + print("\(hierarchyBasedPath.padding(toLength: columnWidth, withPad: " ", startingAt: 0)) | \(mainCacheBasedPath)") + } + } + + if !missingPathsInHierarchyBasedLinkResolver.isEmpty { + let missingPaths = missingPathsInHierarchyBasedLinkResolver.sorted() + print("\(prefix) The following symbol paths exist in the cache-based link resolver but is missing in the path hierarchy-based link resolver:\n\(missingPaths.joined(separator: "\n"))") + } + if !missingPathsInCacheBasedLinkResolver.isEmpty { + let missingPaths = missingPathsInCacheBasedLinkResolver.sorted() + print("\(prefix) The following symbol paths exist in the path hierarchy-based link resolver but is missing in the cache-based link resolver:\n\(missingPaths.joined(separator: "\n"))") + } + + guard !LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver else { + // Results can only be reported when the documentation cache based implementation is used to resolve links + return + } + + let mismatchedFailedCacheResults = mismatchedLinksThatCacheBasedLinkResolverFailedToResolve + let mismatchedFailedHierarchyResults = mismatchedLinksThatHierarchyBasedLinkResolverFailedToResolve + + if mismatchedFailedCacheResults.isEmpty && mismatchedFailedHierarchyResults.isEmpty { + print("\(prefix) Both link resolver implementations succeeded and failed to resolve the same links.") + } else { + if !mismatchedFailedCacheResults.isEmpty { + print("\(prefix) The following links failed to resolve in the documentation cache implementation but succeeded in the path hierarchy implementation:") + + let firstColumnWidth = mismatchedFailedCacheResults.map { $0.path.count }.max()! + 2 // 2 extra for the quotes + for result in mismatchedFailedCacheResults { + print("\(result.path.singleQuoted.padding(toLength: firstColumnWidth, withPad: " ", startingAt: 0)) relative to \(result.parent.singleQuoted) \(result.asSymbolLink ? "(symbol link)" : "")") + } + } + + if !mismatchedFailedHierarchyResults.isEmpty { + print("\(prefix) The following links failed to resolve in the path hierarchy implementation but succeeded in the documentation cache implementation:") + + let firstColumnWidth = mismatchedFailedHierarchyResults.map { $0.path.count }.max()! + 2 // 2 extra for the quotes + for result in mismatchedFailedHierarchyResults { + print("\(result.path.singleQuoted.padding(toLength: firstColumnWidth, withPad: " ", startingAt: 0)) relative to \(result.parent.singleQuoted) \(result.asSymbolLink ? "(symbol link)" : "")") + } + } + } + } +} diff --git a/Sources/SwiftDocC/Infrastructure/Link Resolution/PathHierarchy.swift b/Sources/SwiftDocC/Infrastructure/Link Resolution/PathHierarchy.swift new file mode 100644 index 0000000000..754d8e592b --- /dev/null +++ b/Sources/SwiftDocC/Infrastructure/Link Resolution/PathHierarchy.swift @@ -0,0 +1,1169 @@ +/* + 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 Swift project authors +*/ + +import Foundation +import SymbolKit + +/// An opaque identifier that uniquely identifies a resolved entry in the path hierarchy, +/// +/// Resolved identifiers cannot be inspected and can only be created by the path hierarchy. +struct ResolvedIdentifier: Equatable, Hashable { + // This is currently implemented with a UUID. That detail should remain hidden and may change at any time. + private let storage = UUID() +} + +/// A hierarchy of path components corresponding to the documentation hierarchy with disambiguation information at every level. +/// +/// The main purpose of the path hierarchy is finding documentation entities based on relative paths from other documentation entities with good handling of link disambiguation. +/// This disambiguation aware hierarchy also makes it suitable for determining the least disambiguated paths for each documentation page. +/// +/// The documentation hierarchy exist both in the path hierarchy and in the topic graph but for different purposes and in formats with different specialization. Neither is a replacement for the other. +/// +/// ### Creation +/// +/// Due to the rich relationships between symbols, a path hierarchy is created in two steps. First, the path hierarchy is initialized with all the symbols for all modules. +/// Next, non-symbols are added to the path hierarchy and on-page landmarks for both symbols and non-symbols are added where applicable. +/// It is not possible to add symbols to a path hierarchy after it has been initialized. +/// +/// ### Usage +/// +/// After a path hierarchy has been fully created — with both symbols and non-symbols — it can be used to find elements in the hierarchy and to determine the least disambiguated paths for all elements. +struct PathHierarchy { + + /// A map of module names to module nodes. + private(set) var modules: [String: Node] + /// The container of top-level articles in the documentation hierarchy. + let articlesContainer: Node + /// The container of tutorials in the documentation hierarchy. + let tutorialContainer: Node + /// The container of tutorial overview pages in the documentation hierarchy. + let tutorialOverviewContainer: Node + + /// A map of known documentation nodes based on their unique identifiers. + private(set) var lookup: [ResolvedIdentifier: Node] + + // MARK: Creating a path hierarchy + + /// Initializes a path hierarchy with the all the symbols from all modules that a the given symbol graph loader provides. + /// + /// - Parameters: + /// - loader: The symbol graph loader that provides all symbols. + /// - bundleName: The name of the documentation bundle, used as a container for articles and tutorials. + /// - moduleKindDisplayName: The display name for the "module" kind of symbol. + /// - knownDisambiguatedPathComponents: A list of path components with known required disambiguations. + init( + symbolGraphLoader loader: SymbolGraphLoader, + bundleName: String, + moduleKindDisplayName: String = "Framework", + knownDisambiguatedPathComponents: [String: [String]]? = nil + ) { + var roots: [String: Node] = [:] + var allNodes: [String: [Node]] = [:] + + let symbolGraphs = loader.symbolGraphs + .sorted(by: { lhs, _ in + return !lhs.key.lastPathComponent.contains("@") + }) + + for (url, graph) in symbolGraphs { + let moduleName = graph.module.name + let moduleNode: Node + + if !loader.hasPrimaryURL(moduleName: moduleName) { + guard let moduleName = SymbolGraphLoader.moduleNameFor(url), + let existingModuleNode = roots[moduleName] + else { continue } + moduleNode = existingModuleNode + } else if let existingModuleNode = roots[moduleName] { + moduleNode = existingModuleNode + } else { + let moduleIdentifierLanguage = graph.symbols.values.first?.identifier.interfaceLanguage ?? SourceLanguage.swift.id + let moduleSymbol = SymbolGraph.Symbol( + identifier: .init(precise: moduleName, interfaceLanguage: moduleIdentifierLanguage), + names: SymbolGraph.Symbol.Names(title: moduleName, navigator: nil, subHeading: nil, prose: nil), + pathComponents: [moduleName], + docComment: nil, + accessLevel: SymbolGraph.Symbol.AccessControl(rawValue: "public"), + kind: SymbolGraph.Symbol.Kind(parsedIdentifier: .module, displayName: moduleKindDisplayName), + mixins: [:]) + let newModuleNode = Node(symbol: moduleSymbol) + roots[moduleName] = newModuleNode + moduleNode = newModuleNode + allNodes[moduleName] = [moduleNode] + } + + var nodes: [String: Node] = [:] + nodes.reserveCapacity(graph.symbols.count) + for (id, symbol) in graph.symbols { + let node = Node(symbol: symbol) + nodes[id] = node + allNodes[id, default: []].append(node) + } + + var topLevelCandidates = nodes + for relationship in graph.relationships where [.memberOf, .requirementOf, .optionalRequirementOf].contains(relationship.kind) { + guard let sourceNode = nodes[relationship.source] else { + continue + } + if let targetNode = nodes[relationship.target] { + if targetNode.add(symbolChild: sourceNode) { + nodes[relationship.source] = nil + } + topLevelCandidates.removeValue(forKey: relationship.source) + } else if let targetNodes = allNodes[relationship.target] { + for targetNode in targetNodes { + if targetNode.add(symbolChild: sourceNode) { + nodes[relationship.source] = nil + } + } + topLevelCandidates.removeValue(forKey: relationship.source) + } else { + // Symbols that are not added to the path hierarchy based on relationships will be added to the path hierarchy based on the symbol's path components. + // Using relationships over path components is preferred because it provides information needed to disambiguate path collisions. + // + // In full symbol graphs this is expected to be rare. In partial symbol graphs from the ConvertService it is expected that parent symbols and relationships + // will be missing. The ConvertService is expected to provide the necessary `knownDisambiguatedPathComponents` to disambiguate any collisions. + continue + } + } + for relationship in graph.relationships where [.defaultImplementationOf].contains(relationship.kind) { + guard let sourceNode = nodes[relationship.source], sourceNode.parent == nil else { + continue + } + topLevelCandidates.removeValue(forKey: relationship.source) + guard let targetParent = nodes[relationship.target]?.parent else { + continue + } + if targetParent.add(symbolChild: sourceNode) { + nodes[relationship.source] = nil + } + } + + // The hierarchy doesn't contain any non-symbol nodes yet. It's OK to unwrap the `symbol` property. + for topLevelNode in topLevelCandidates.values where topLevelNode.symbol!.pathComponents.count == 1 { + _ = moduleNode.add(symbolChild: topLevelNode) + } + + for node in topLevelCandidates.values where node.symbol!.pathComponents.count > 1 { + var parent = moduleNode + var components = { (symbol: SymbolGraph.Symbol) -> [String] in + let original = symbol.pathComponents + if let disambiguated = knownDisambiguatedPathComponents?[node.symbol!.identifier.precise], disambiguated.count == original.count { + return disambiguated + } else { + return original + } + }(node.symbol!)[...].dropLast() + while !components.isEmpty, let child = try? parent.children[components.first!]?.find(nil, nil) { + parent = child + components = components.dropFirst() + } + for component in components { + let component = Self.parse(pathComponent: component[...]) + let nodeWithoutSymbol = Node(name: component.name) + _ = parent.add(child: nodeWithoutSymbol, kind: component.kind, hash: component.hash) + parent = nodeWithoutSymbol + } + _ = parent.add(symbolChild: node) + } + } + + allNodes.removeAll() + + // build the lookup list by traversing the hierarchy and adding identifiers to each node + + var lookup = [ResolvedIdentifier: Node]() + func descend(_ node: Node) { + assert(node.identifier == nil) + if node.symbol != nil { + node.identifier = ResolvedIdentifier() + lookup[node.identifier] = node + } + for tree in node.children.values { + for (_, subtree) in tree.storage { + for (_, node) in subtree { + descend(node) + } + } + } + } + + for module in roots.values { + descend(module) + } + + func newNode(_ name: String) -> Node { + let id = ResolvedIdentifier() + let node = Node(name: name) + node.identifier = id + lookup[id] = node + return node + } + self.articlesContainer = roots[bundleName] ?? newNode(bundleName) + self.tutorialContainer = newNode(bundleName) + self.tutorialOverviewContainer = newNode("tutorials") + + assert(lookup.allSatisfy({ $0.key == $0.value.identifier})) + + self.modules = roots + self.lookup = lookup + + assert(topLevelSymbols().allSatisfy({ lookup[$0] != nil})) + } + + /// Adds an article to the path hierarchy. + /// - Parameter name: The path component name of the article (the file name without the file extension). + /// - Returns: The new unique identifier that represent this article. + mutating func addArticle(name: String) -> ResolvedIdentifier { + return addNonSymbolChild(parent: articlesContainer.identifier, name: name, kind: "article") + } + + /// Adds a tutorial to the path hierarchy. + /// - Parameter name: The path component name of the tutorial (the file name without the file extension). + /// - Returns: The new unique identifier that represent this tutorial. + mutating func addTutorial(name: String) -> ResolvedIdentifier { + return addNonSymbolChild(parent: tutorialContainer.identifier, name: name, kind: "tutorial") + } + + /// Adds a tutorial overview page to the path hierarchy. + /// - Parameter name: The path component name of the tutorial overview (the file name without the file extension). + /// - Returns: The new unique identifier that represent this tutorial overview. + mutating func addTutorialOverview(name: String) -> ResolvedIdentifier { + return addNonSymbolChild(parent: tutorialOverviewContainer.identifier, name: name, kind: "technology") + } + + /// Adds a non-symbol child element to an existing element in the path hierarchy. + /// - Parameters: + /// - parent: The unique identifier of the existing element to add the new child element to. + /// - name: The path component name of the new element. + /// - kind: The kind of the new element + /// - Returns: The new unique identifier that represent this element. + mutating func addNonSymbolChild(parent: ResolvedIdentifier, name: String, kind: String) -> ResolvedIdentifier { + let parent = lookup[parent]! + + let newReference = ResolvedIdentifier() + let newNode = Node(name: name) + newNode.identifier = newReference + self.lookup[newReference] = newNode + _ = parent.add(child: newNode, kind: kind, hash: nil) + + return newReference + } + + /// Adds a non-symbol technology root. + /// - Parameters: + /// - name: The path component name of the technology root. + /// - Returns: The new unique identifier that represent the root. + mutating func addTechnologyRoot(name: String) -> ResolvedIdentifier { + let newReference = ResolvedIdentifier() + let newNode = Node(name: name) + newNode.identifier = newReference + self.lookup[newReference] = newNode + + modules[name] = newNode + + return newReference + } + + // MARK: Finding elements in the hierarchy + + /// Attempts to find an element in the path hierarchy for a given path relative to another element. + /// + /// - Parameters: + /// - rawPath: The documentation link path string. + /// - parent: An optional identifier for the node in the hierarchy to search relative to. + /// - onlyFindSymbols: Whether or not only symbol matches should be found. + /// - Returns: Returns the unique identifier for the found match or raises an error if no match can be found. + /// - Throws: Raises a ``PathHierarchy/Error`` if no match can be found. + func find(path rawPath: String, parent: ResolvedIdentifier? = nil, onlyFindSymbols: Bool) throws -> ResolvedIdentifier { + let node = try findNode(path: rawPath, parent: parent, onlyFindSymbols: onlyFindSymbols) + if node.identifier == nil { + throw Error.unfindableMatch + } + if onlyFindSymbols, node.symbol == nil { + throw Error.nonSymbolMatchForSymbolLink + } + return node.identifier + } + + private func findNode(path rawPath: String, parent: ResolvedIdentifier?, onlyFindSymbols: Bool) throws -> Node { + // The search for a documentation element can be though of as 3 steps: + // First, parse the path into structured path components. + let (path, isAbsolute) = Self.parse(path: rawPath) + guard !path.isEmpty else { + throw Error.notFound(availableChildren: []) + } + + // Second, find the node to start the search relative to. + // This may consume or or more path components. See implementation for details. + var remaining = path[...] + var node = try findRoot(parentID: parent, remaining: &remaining, isAbsolute: isAbsolute, onlyFindSymbols: onlyFindSymbols) + + // Third, search for the match relative to the start node. + if remaining.isEmpty { + // If all path components were consumed, then the start of the search is the match. + return node + } + + // Search for the remaining components from the node + while true { + let (children, pathComponent) = try findChildTree(node: &node, remaining: remaining) + + do { + guard let child = try children.find(pathComponent.kind, pathComponent.hash) else { + // The search has ended with a node that doesn't have a child matching the next path component. + throw Error.partialResult( + partialResult: node, + remainingSubpath: remaining.map(\.full).joined(separator: "/"), + availableChildren: node.children.keys.sorted(by: availableChildNameIsBefore) + ) + } + node = child + remaining = remaining.dropFirst() + if remaining.isEmpty { + // If all path components are consumed, then the match is found. + return child + } + } catch DisambiguationTree.Error.lookupCollision(let collisions) { + func wrappedCollisionError() -> Error { + Error.lookupCollision(partialResult: node, collisions: collisions) + } + + // See if the collision can be resolved by looking ahead on level deeper. + guard let nextPathComponent = remaining.dropFirst().first else { + // This was the last path component so there's nothing to look ahead. + // + // It's possible for a symbol that exist on multiple languages to collide with itself. + // Check if the collision can be resolved by finding a unique symbol or an otherwise preferred match. + var uniqueCollisions: [String: Node] = [:] + for (node, _) in collisions { + guard let symbol = node.symbol else { + // Non-symbol collisions should have already been resolved + throw wrappedCollisionError() + } + + let id = symbol.identifier.precise + if symbol.identifier.interfaceLanguage == "swift" || !uniqueCollisions.keys.contains(id) { + uniqueCollisions[id] = node + } + + guard uniqueCollisions.count < 2 else { + // Encountered more than one unique symbol + throw wrappedCollisionError() + } + } + // A wrapped error would have been raised while iterating over the collection. + return uniqueCollisions.first!.value + } + // Try resolving the rest of the path for each collision ... + let possibleMatches = collisions.compactMap { + return try? $0.node.children[nextPathComponent.name]?.find(nextPathComponent.kind, nextPathComponent.hash) + } + // If only one collision matches, return that match. + if possibleMatches.count == 1 { + return possibleMatches.first! + } + // If all matches are the same symbol, return the Swift version of that symbol + if !possibleMatches.isEmpty, possibleMatches.dropFirst().allSatisfy({ $0.symbol?.identifier.precise == possibleMatches.first!.symbol?.identifier.precise }) { + return possibleMatches.first(where: { $0.symbol?.identifier.interfaceLanguage == "swift" }) ?? possibleMatches.first! + } + // Couldn't resolve the collision by look ahead. + throw Error.lookupCollision( + partialResult: node, + collisions: collisions.map { ($0.node, $0.disambiguation) } + ) + } + } + } + + /// Finds the child disambiguation tree for a given node that match the remaining path components. + /// - Parameters: + /// - node: The current node. + /// - remaining: The remaining path components. + /// - Returns: The child disambiguation tree and path component. + private func findChildTree(node: inout Node, remaining: ArraySlice) throws -> (DisambiguationTree, PathComponent) { + var pathComponent = remaining.first! + if let match = node.children[pathComponent.name] { + return (match, pathComponent) + } else if let match = node.children[pathComponent.full] { + // The path component parsing may treat dash separated words as disambiguation information. + // If the parsed name didn't match, also try the original. + pathComponent.kind = nil + pathComponent.hash = nil + return (match, pathComponent) + } else { + if node.name == pathComponent.name || node.name == pathComponent.full, let parent = node.parent { + // When multiple path components in a row have the same name it's possible that the search started at a node that's + // too deep in the hierarchy that won't find the final result. + // Check if a match would be found in the parent before raising an error. + if let match = parent.children[pathComponent.name] { + node = parent + return (match, pathComponent) + } else if let match = parent.children[pathComponent.full] { + node = parent + // The path component parsing may treat dash separated words as disambiguation information. + // If the parsed name didn't match, also try the original. + pathComponent.kind = nil + pathComponent.hash = nil + return (match, pathComponent) + } + } + } + // The search has ended with a node that doesn't have a child matching the next path component. + throw Error.partialResult( + partialResult: node, + remainingSubpath: remaining.map(\.full).joined(separator: "/"), + availableChildren: node.children.keys.sorted(by: availableChildNameIsBefore) + ) + } + + /// Attempt to find the node to start the relative search relative to. + /// + /// - Parameters: + /// - parentID: An optional ID of the node to start the search relative to. + /// - remaining: The parsed path components. + /// - isAbsolute: If the parsed path represent an absolute documentation link. + /// - onlyFindSymbols: If symbol results are required. + /// - Returns: The node to start the relative search relative to. + private func findRoot(parentID: ResolvedIdentifier?, remaining: inout ArraySlice, isAbsolute: Bool, onlyFindSymbols: Bool) throws -> Node { + // If the first path component is "tutorials" or "documentation" then that + let isKnownTutorialPath = remaining.first!.full == "tutorials" + let isKnownDocumentationPath = remaining.first!.full == "documentation" + if isKnownDocumentationPath || isKnownTutorialPath { + // Drop that component since it isn't represented in the path hierarchy. + remaining.removeFirst() + } + guard let component = remaining.first else { + throw Error.notFound(availableChildren: []) + } + + if !onlyFindSymbols { + // If non-symbol matches are possible there is a fixed order to try resolving the link: + // Articles match before tutorials which match before the tutorial overview page which match before symbols. + lookForArticleRoot: if !isKnownTutorialPath { + if articlesContainer.name == component.name || articlesContainer.name == component.full { + if let next = remaining.dropFirst().first { + if !articlesContainer.children.keys.contains(next.name) && !articlesContainer.children.keys.contains(next.full) { + break lookForArticleRoot + } + } + remaining = remaining.dropFirst() + return articlesContainer + } else if articlesContainer.children.keys.contains(component.name) || articlesContainer.children.keys.contains(component.full) { + return articlesContainer + } + } + if !isKnownDocumentationPath { + if tutorialContainer.name == component.name || tutorialContainer.name == component.full { + remaining = remaining.dropFirst() + return tutorialContainer + } else if tutorialContainer.children.keys.contains(component.name) || tutorialContainer.children.keys.contains(component.full) { + return tutorialContainer + } + // The parent for tutorial overviews / technologies is "tutorials" which has already been removed above, so no need to check against that name. + else if tutorialOverviewContainer.children.keys.contains(component.name) || tutorialOverviewContainer.children.keys.contains(component.full) { + return tutorialOverviewContainer + } + } + if !isKnownTutorialPath && isAbsolute { + // If this is an absolute non-tutorial link, then the first component will be a module name. + if let matched = modules[component.name] ?? modules[component.full] { + remaining = remaining.dropFirst() + return matched + } + } + } + + func matches(node: Node, component: PathComponent) -> Bool { + if let symbol = node.symbol { + return node.name == component.name + && (component.kind == nil || component.kind == symbol.kind.identifier.identifier) + && (component.hash == nil || component.hash == symbol.identifier.precise.stableHashString) + } else { + return node.name == component.full + } + } + + if let parentID = parentID { + // If a parent ID was provided, start at that node and continue up the hierarchy until that node has a child that matches the first path components name. + var parentNode = lookup[parentID]! + let firstComponent = remaining.first! + if matches(node: parentNode, component: firstComponent) { + remaining = remaining.dropFirst() + return parentNode + } + while !parentNode.children.keys.contains(firstComponent.name) && !parentNode.children.keys.contains(firstComponent.full) { + guard let parent = parentNode.parent else { + if matches(node: parentNode, component: firstComponent){ + remaining = remaining.dropFirst() + return parentNode + } + if let matched = modules[component.name] ?? modules[component.full] { + remaining = remaining.dropFirst() + return matched + } + // No node up the hierarchy from the provided parent has a child that matches the first path component. + // Go back to the provided parent node for diagnostic information about its available children. + parentNode = lookup[parentID]! + throw Error.partialResult(partialResult: parentNode, remainingSubpath: remaining.map({ $0.full }).joined(separator: "/"), availableChildren: parentNode.children.keys.sorted(by: availableChildNameIsBefore)) + } + parentNode = parent + } + return parentNode + } + + // If no parent ID was provided, check if the first path component is a module name. + if let matched = modules[component.name] ?? modules[component.full] { + remaining = remaining.dropFirst() + return matched + } + + // No place to start the search from could be found. + // It would be a nice future improvement to allow skipping the module and find top level symbols directly. + let topLevelNames = Set(modules.keys + [articlesContainer.name, tutorialContainer.name]).sorted(by: availableChildNameIsBefore) + throw Error.notFound(availableChildren: topLevelNames) + } +} + +extension PathHierarchy { + /// A node in the path hierarchy. + final class Node { + /// The unique identifier for this node. + fileprivate(set) var identifier: ResolvedIdentifier! + + // Everything else is file-private or private. + + /// The name of this path component in the hierarchy. + private(set) var name: String + + /// The descendants of this node in the hierarchy. + /// Each name maps to a disambiguation tree that handles + fileprivate private(set) var children: [String: DisambiguationTree] + + private(set) unowned var parent: Node? + /// The symbol, if a node has one. + private(set) var symbol: SymbolGraph.Symbol? + + /// Initializes a symbol node. + fileprivate init(symbol: SymbolGraph.Symbol!) { + self.symbol = symbol + self.name = symbol.pathComponents.last! + self.children = [:] + } + + /// Initializes a non-symbol node with a given name. + fileprivate init(name: String) { + self.symbol = nil + self.name = name + self.children = [:] + } + + /// Adds a descendant to this node, providing disambiguation information from the node's symbol. + fileprivate func add(symbolChild: Node) -> Bool { + precondition(symbolChild.symbol != nil) + return add( + child: symbolChild, + kind: symbolChild.symbol!.kind.identifier.identifier, + hash: symbolChild.symbol!.identifier.precise.stableHashString + ) + } + + /// Adds a descendant of this node. + fileprivate func add(child: Node, kind: String?, hash: String?) -> Bool { + child.parent = self + return children[child.name, default: .init()].add(kind ?? "_", hash ?? "_", child) + } + + /// Combines this node with another node. + fileprivate func merge(with other: Node) { + assert(self.parent?.symbol?.identifier.precise == other.parent?.symbol?.identifier.precise) + self.children = self.children.merging(other.children, uniquingKeysWith: { $0.merge(with: $1) }) + + for (_, tree) in self.children { + for subtree in tree.storage.values { + for node in subtree.values { + node.parent = self + } + } + } + } + } +} +// MARK: Parsing documentation links + +/// All known symbol kind identifiers. +/// +/// This is used to identify parsed path components as kind information. +private let knownSymbolKinds = Set(SymbolGraph.Symbol.KindIdentifier.allCases.map { $0.identifier }) +/// All known source language identifiers. +/// +/// This is used to skip language prefixes from kind disambiguation information. +private let knownLanguagePrefixes = SourceLanguage.knownLanguages.flatMap { [$0.id] + $0.idAliases }.map { $0 + "." } + +extension PathHierarchy { + /// The parsed information for a documentation URI path component. + struct PathComponent { + /// The full original path component + let full: String + /// The parsed entity name + let name: String + /// The parsed entity kind, if any. + var kind: String? + /// The parsed entity hash, if any. + var hash: String? + } + + /// Parsed a documentation link path (and optional fragment) string into structured path component values. + /// - Parameter path: The documentation link string, containing a path and an optional fragment. + /// - Returns: A pair of the parsed path components and a flag that indicate if the documentation link is absolute or not. + static func parse(path: String) -> (components: [PathComponent], isAbsolute: Bool) { + guard !path.isEmpty else { return ([], true) } + var components = path.split(separator: "/", omittingEmptySubsequences: true) + let isAbsolute = path.first == "/" || components.first == "documentation" || components.first == "tutorials" + + if let hashIndex = components.last?.firstIndex(of: "#") { + let last = components.removeLast() + components.append(last[.. PathComponent { + let full = String(original) + guard let dashIndex = original.lastIndex(of: "-") else { + return PathComponent(full: full, name: full, kind: nil, hash: nil) + } + + let hash = String(original[dashIndex...].dropFirst()) + let name = String(original[.. Bool { + var index: UInt8 = 0 + for char in hash.utf8 { + guard index <= 5, (48...57).contains(char) || (97...122).contains(char) else { return false } + index += 1 + } + return true + } + + if knownSymbolKinds.contains(hash) { + // The parsed hash value is a symbol kind + return PathComponent(full: full, name: name, kind: hash, hash: nil) + } + if let languagePrefix = knownLanguagePrefixes.first(where: { hash.starts(with: $0) }) { + // The hash is actually a symbol kind with a language prefix + return PathComponent(full: full, name: name, kind: String(hash.dropFirst(languagePrefix.count)), hash: nil) + } + if !isValidHash(hash) { + // The parsed hash is neither a symbol not a valid hash. It's probably a hyphen-separated name. + return PathComponent(full: full, name: full, kind: nil, hash: nil) + } + + if let dashIndex = name.lastIndex(of: "-") { + let kind = String(name[dashIndex...].dropFirst()) + let name = String(name[.. [String: String] { + func descend(_ node: Node, accumulatedPath: String) -> [(String, (String, Bool))] { + var results: [(String, (String, Bool))] = [] + let caseInsensitiveChildren = [String: DisambiguationTree](node.children.map { ($0.key.lowercased(), $0.value) }, uniquingKeysWith: { $0.merge(with: $1) }) + + for (_, tree) in caseInsensitiveChildren { + let disambiguatedChildren = tree.disambiguatedValuesWithCollapsedUniqueSymbols(includeLanguage: includeLanguage) + let uniqueNodesWithChildren = Set(disambiguatedChildren.filter { $0.disambiguation.value() != nil && !$0.value.children.isEmpty }.map { $0.value.symbol?.identifier.precise }) + for (node, disambiguation) in disambiguatedChildren { + var path: String + if node.identifier == nil && disambiguatedChildren.count == 1 { + // When descending through placeholder nodes, we trust that the known disambiguation + // that they were created with is necessary. + var knownDisambiguation = "" + let (kind, subtree) = tree.storage.first! + if kind != "_" { + knownDisambiguation += "-\(kind)" + } + let hash = subtree.keys.first! + if hash != "_" { + knownDisambiguation += "-\(hash)" + } + path = accumulatedPath + "/" + node.name + knownDisambiguation + } else { + path = accumulatedPath + "/" + node.name + } + if let symbol = node.symbol { + results.append( + (symbol.identifier.precise, (path + disambiguation.makeSuffix(), symbol.identifier.interfaceLanguage == "swift")) + ) + } + if includeDisambiguationForUnambiguousChildren || uniqueNodesWithChildren.count > 1 { + path += disambiguation.makeSuffix() + } + results += descend(node, accumulatedPath: path) + } + } + return results + } + + var gathered: [(String, (String, Bool))] = [] + + for (moduleName, node) in modules { + let path = "/" + moduleName + gathered.append( + (moduleName, (path, node.symbol == nil || node.symbol!.identifier.interfaceLanguage == "swift")) + ) + gathered += descend(node, accumulatedPath: path) + } + + // If a symbol node exist in multiple languages, prioritize the Swift variant. + return [String: (String, Bool)](gathered, uniquingKeysWith: { lhs, rhs in lhs.1 ? lhs : rhs }).mapValues({ $0.0 }) + } +} + +// MARK: Traversing + +extension PathHierarchy { + /// Returns the list of top level symbols + func topLevelSymbols() -> [ResolvedIdentifier] { + var result: Set = [] + // Roots represent modules and only have direct symbol descendants. + for root in modules.values { + for (_, tree) in root.children { + for subtree in tree.storage.values { + for node in subtree.values where node.symbol != nil { + result.insert(node.identifier) + } + } + } + } + return Array(result) + modules.values.map { $0.identifier } + } +} + +// MARK: Error messages + +extension PathHierarchy { + /// An error finding an entry in the path hierarchy. + enum Error: Swift.Error { + /// No element was found at the beginning of the path. + /// + /// Includes information about: + /// - A list of the names for the top level elements. + case notFound(availableChildren: [String]) + + /// Matched node does not correspond to a documentation page. + /// + /// For partial symbol graph files, sometimes sparse nodes that don't correspond to known documentation need to be created to form a hierarchy. These nodes are not findable. + case unfindableMatch + + /// A symbol link found a non-symbol match. + case nonSymbolMatchForSymbolLink + + /// No child element is found partway through the path. + /// + /// Includes information about: + /// - The partial result for as much of the path that could be found. + /// - The remaining portion of the path. + /// - A list of the names for the children of the partial result. + case partialResult(partialResult: Node, remainingSubpath: String, availableChildren: [String]) + + /// Multiple matches are found partway through the path. + /// + /// Includes information about: + /// - The partial result for as much of the path that could be found unambiguously. + /// - A list of possible matches paired with the disambiguation suffixes needed to distinguish them. + case lookupCollision(partialResult: Node, collisions: [(node: Node, disambiguation: String)]) + } +} + +/// A comparison/sort function for the list of names for the children of the partial result in a diagnostic. +private func availableChildNameIsBefore(_ lhs: String, _ rhs: String) -> Bool { + return lhs.localizedCaseInsensitiveCompare(rhs) == .orderedAscending +} + +extension PathHierarchy.Error { + /// Formats the error into an error message suitable for presentation + func errorMessage(context: DocumentationContext) -> String { + switch self { + case .partialResult(let partialResult, let remaining, let available): + return "Reference at \(partialResult.pathWithoutDisambiguation().singleQuoted) can't resolve \(remaining.singleQuoted). Available children: \(available.joined(separator: ", "))." + + case .notFound, .unfindableMatch: + return "No local documentation matches this reference." + + case .nonSymbolMatchForSymbolLink: + return "Symbol links can only resolve symbols." + + case .lookupCollision(let partialResult, let collisions): + let collisionDescription = collisions.map { "Add \($0.disambiguation.singleQuoted) to refer to \($0.node.fullNameOfValue(context: context).singleQuoted)"}.sorted() + return "Reference is ambiguous after \(partialResult.pathWithoutDisambiguation().singleQuoted): \(collisionDescription.joined(separator: ". "))." + } + } +} + +private extension PathHierarchy.Node { + /// Creates a path string without any disambiguation. + /// + /// > Note: This value is only intended for error messages and other presentation. + func pathWithoutDisambiguation() -> String { + var components = [name] + var node = self + while let parent = node.parent { + components.insert(parent.name, at: 0) + node = parent + } + return "/" + components.joined(separator: "/") + } + + /// Determines the full name of a node's value using information from the documentation context. + /// + /// > Note: This value is only intended for error messages and other presentation. + func fullNameOfValue(context: DocumentationContext) -> String { + guard let identifier = identifier else { return name } + if let symbol = symbol { + return context.symbolIndex[symbol.identifier.precise]!.name.description + } + // This only gets called for PathHierarchy error messages, so hierarchyBasedLinkResolver is never nil. + let reference = context.hierarchyBasedLinkResolver!.resolvedReferenceMap[identifier]! + if reference.fragment != nil { + return context.nodeAnchorSections[reference]!.title + } else { + return context.documentationCache[reference]!.name.description + } + } +} + +// MARK: Dump + +/// A node in a tree structure that can be printed into a visual representation for debugging. +private struct DumpableNode { + var name: String + var children: [DumpableNode] +} + +private extension PathHierarchy.Node { + /// Maps the path hierarchy subtree into a representation that can be printed into a visual form for debugging. + func dumpableNode() -> DumpableNode { + // Each node is printed as 3-layer hierarchy with the child names, their kind disambiguation, and their hash disambiguation. + return DumpableNode( + name: symbol.map { "{ \($0.identifier.precise) : \($0.identifier.interfaceLanguage).\($0.kind.identifier.identifier) }" } ?? "[ \(name) ]", + children: children.sorted(by: \.key).map { (key, disambiguationTree) -> DumpableNode in + DumpableNode( + name: key, + children: disambiguationTree.storage.sorted(by: \.key).map { (kind, kindTree) -> DumpableNode in + DumpableNode( + name: kind, + children: kindTree.sorted(by: \.key).map { (usr, node) -> DumpableNode in + DumpableNode( + name: usr, + children: [node.dumpableNode()] + ) + } + ) + } + ) + } + ) + } +} + +extension PathHierarchy { + /// Creates a visual representation or the path hierarchy for debugging. + func dump() -> String { + var children = modules.sorted(by: \.key).map { $0.value.dumpableNode() } + if articlesContainer.symbol == nil { + children.append(articlesContainer.dumpableNode()) // The article parent can be the same node as the module + } + children.append(contentsOf: [tutorialContainer.dumpableNode(), tutorialOverviewContainer.dumpableNode()]) + + let root = DumpableNode(name: ".", children: children) + return Self.dump(root) + } + + fileprivate static func dump(_ node: DumpableNode, decorator: String = "") -> String { + var result = "" + result.append("\(decorator) \(node.name)\n") + + let children = node.children + for (index, child) in children.enumerated() { + var decorator = decorator + if decorator.hasSuffix("├") { + decorator = decorator.dropLast() + "│" + } + if decorator.hasSuffix("╰") { + decorator = decorator.dropLast() + " " + } + let newDecorator = decorator + " " + (index == children.count-1 ? "╰" : "├") + result.append(dump(child, decorator: newDecorator)) + } + return result + } +} + +// MARK: Removing nodes + +extension PathHierarchy { + // When unregistering a documentation bundle from a context, entries for that bundle should no longer be findable. + // The below implementation marks nodes as "not findable" while leaving them in the hierarchy so that they can be + // traversed. + // This would be problematic if it happened repeatedly but in practice the path hierarchy will only be in this state + // after unregistering a data provider until a new data provider is registered. + + /// Removes a node from the path hierarchy so that it can no longer be found. + /// - Parameter id: The unique identifier for the node. + mutating func removeNodeWithID(_ id: ResolvedIdentifier) { + // Remove the node from the lookup and unset its identifier + lookup.removeValue(forKey: id)!.identifier = nil + } +} + +// MARK: Disambiguation tree + +/// A fixed-depth tree that stores disambiguation information and finds values based on partial disambiguation. +private struct DisambiguationTree { + // Each disambiguation tree is fixed at two levels and stores a limited number of values. + // In practice, almost all trees store either 1, 2, or 3 elements with 1 being the most common. + // It's very rare to have more than 10 values and 20+ values is extremely rare. + // + // Given this expected amount of data, a nested dictionary implementation performs well. + private(set) var storage: [String: [String: PathHierarchy.Node]] = [:] + + /// Add a new value to the tree for a given pair of kind and hash disambiguations. + /// - Parameters: + /// - kind: The kind disambiguation for this value. + /// - hash: The hash disambiguation for this value. + /// - value: The new value + /// - Returns: If a value already exist with the same pair of kind and hash disambiguations. + @discardableResult + mutating func add(_ kind: String, _ hash: String, _ value: PathHierarchy.Node) -> Bool { + if let existing = storage[kind]?[hash] { + existing.merge(with: value) + return true + } else if storage.count == 1, let existing = storage["_"]?["_"] { + // It is possible for articles and other non-symbols to collide with unfindable symbol placeholder nodes. + // When this happens, remove the placeholder node and move its children to the real (non-symbol) node. + value.merge(with: existing) + storage = [kind: [hash: value]] + return true + } else { + storage[kind, default: [:]][hash] = value + return false + } + } + + /// Combines the data from this tree with another tree to form a new, merged disambiguation tree. + func merge(with other: DisambiguationTree) -> DisambiguationTree { + return DisambiguationTree(storage: self.storage.merging(other.storage, uniquingKeysWith: { lhs, rhs in + lhs.merging(rhs, uniquingKeysWith: { + lhsValue, rhsValue in + assert(lhsValue.symbol!.identifier.precise == rhsValue.symbol!.identifier.precise) + return lhsValue + }) + })) + } + + /// Errors finding values in the disambiguation tree + enum Error: Swift.Error { + /// Multiple matches found. + /// + /// Includes a list of values paired with their missing disambiguation suffixes. + case lookupCollision([(node: PathHierarchy.Node, disambiguation: String)]) + } + + /// Attempts to find a value in the disambiguation tree based on partial disambiguation information. + /// + /// There are 3 possible results: + /// - No match is found; indicated by a `nil` return value. + /// - Exactly one match is found; indicated by a non-nil return value. + /// - More than one match is found; indicated by a raised error listing the matches and their missing disambiguation. + func find(_ kind: String?, _ hash: String?) throws -> PathHierarchy.Node? { + if let kind = kind { + // Need to match the provided kind + guard let subtree = storage[kind] else { return nil } + if let hash = hash { + return subtree[hash] + } else if subtree.count == 1 { + return subtree.values.first + } else { + // Subtree contains more than one match. + throw Error.lookupCollision(subtree.map { ($0.value, $0.key) }) + } + } else if storage.count == 1, let subtree = storage.values.first { + // Tree only contains one kind subtree + if let hash = hash { + return subtree[hash] + } else if subtree.count == 1 { + return subtree.values.first + } else { + // Subtree contains more than one match. + throw Error.lookupCollision(subtree.map { ($0.value, $0.key) }) + } + } else if let hash = hash { + // Need to match the provided hash + let kinds = storage.filter { $0.value.keys.contains(hash) } + if kinds.isEmpty { + return nil + } else if kinds.count == 1 { + return kinds.first!.value[hash] + } else { + // Subtree contains more than one match + throw Error.lookupCollision(kinds.map { ($0.value[hash]!, $0.key) }) + } + } + // Disambiguate by a mix of kinds and USRs + throw Error.lookupCollision(self.disambiguatedValues().map { ($0.value, $0.disambiguation.value()) }) + } + + /// Returns all values paired with their disambiguation suffixes. + /// + /// - Parameter includeLanguage: Whether or not the kind disambiguation information should include the language, for example: "swift". + func disambiguatedValues(includeLanguage: Bool = false) -> [(value: PathHierarchy.Node, disambiguation: Disambiguation)] { + if storage.count == 1 { + let tree = storage.values.first! + if tree.count == 1 { + return [(tree.values.first!, .none)] + } + } + + var collisions: [(value: PathHierarchy.Node, disambiguation: Disambiguation)] = [] + for (kind, kindTree) in storage { + if kindTree.count == 1 { + // No other match has this kind + if includeLanguage, let symbol = kindTree.first!.value.symbol { + collisions.append((value: kindTree.first!.value, disambiguation: .kind("\(SourceLanguage(id: symbol.identifier.interfaceLanguage).linkDisambiguationID).\(kind)"))) + } else { + collisions.append((value: kindTree.first!.value, disambiguation: .kind(kind))) + } + continue + } + for (usr, value) in kindTree { + collisions.append((value: value, disambiguation: .hash(usr))) + } + } + return collisions + } + + /// Returns all values paired with their disambiguation suffixes without needing to disambiguate between two different versions of the same symbol. + /// + /// - Parameter includeLanguage: Whether or not the kind disambiguation information should include the language, for example: "swift". + func disambiguatedValuesWithCollapsedUniqueSymbols(includeLanguage: Bool) -> [(value: PathHierarchy.Node, disambiguation: Disambiguation)] { + typealias DisambiguationPair = (String, String) + + var uniqueSymbolIDs = [String: [DisambiguationPair]]() + var nonSymbols = [DisambiguationPair]() + for (kind, kindTree) in storage { + for (hash, value) in kindTree { + guard let symbol = value.symbol else { + nonSymbols.append((kind, hash)) + continue + } + if symbol.identifier.interfaceLanguage == "swift" { + uniqueSymbolIDs[symbol.identifier.precise, default: []].insert((kind, hash), at: 0) + } else { + uniqueSymbolIDs[symbol.identifier.precise, default: []].append((kind, hash)) + } + } + } + + var duplicateSymbols = [String: ArraySlice]() + + var new = DisambiguationTree() + for (kind, hash) in nonSymbols { + new.add(kind, hash, storage[kind]![hash]!) + } + for (id, symbolDisambiguations) in uniqueSymbolIDs { + let (kind, hash) = symbolDisambiguations[0] + new.add(kind, hash, storage[kind]![hash]!) + + if symbolDisambiguations.count > 1 { + duplicateSymbols[id] = symbolDisambiguations.dropFirst() + } + } + + var disambiguated = new.disambiguatedValues(includeLanguage: includeLanguage) + guard !duplicateSymbols.isEmpty else { + return disambiguated + } + + for (id, disambiguations) in duplicateSymbols { + let primaryDisambiguation = disambiguated.first(where: { $0.value.symbol?.identifier.precise == id })!.disambiguation + for (kind, hash) in disambiguations { + disambiguated.append((storage[kind]![hash]!, primaryDisambiguation.updated(kind: kind, hash: hash))) + } + } + + return disambiguated + } + + /// The computed disambiguation for a given path hierarchy node. + enum Disambiguation { + /// No disambiguation is needed. + case none + /// This node is disambiguated by its kind. + case kind(String) + /// This node is disambiguated by its hash. + case hash(String) + + /// Returns the kind or hash value that disambiguates this node. + func value() -> String! { + switch self { + case .none: + return nil + case .kind(let value), .hash(let value): + return value + } + } + /// Makes a new disambiguation suffix string. + func makeSuffix() -> String { + switch self { + case .none: + return "" + case .kind(let value), .hash(let value): + return "-"+value + } + } + + /// Creates a new disambiguation with a new kind or hash value. + func updated(kind: String, hash: String) -> Self { + switch self { + case .none: + return .none + case .kind: + return .kind(kind) + case .hash: + return .hash(hash) + } + } + } +} diff --git a/Sources/SwiftDocC/Infrastructure/Link Resolution/PathHierarchyBasedLinkResolver.swift b/Sources/SwiftDocC/Infrastructure/Link Resolution/PathHierarchyBasedLinkResolver.swift new file mode 100644 index 0000000000..6f45d4b60c --- /dev/null +++ b/Sources/SwiftDocC/Infrastructure/Link Resolution/PathHierarchyBasedLinkResolver.swift @@ -0,0 +1,354 @@ +/* + 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 Swift project authors +*/ + +import Foundation +import SymbolKit + +/// A type that encapsulates resolving links by searching a hierarchy of path components. +final class PathHierarchyBasedLinkResolver { + /// A hierarchy of path components used to resolve links in the documentation. + private(set) var pathHierarchy: PathHierarchy! + + /// Map between resolved identifiers and resolved topic references. + private(set) var resolvedReferenceMap = BidirectionalMap() + + /// Initializes a link resolver with a given path hierarchy. + init(pathHierarchy: PathHierarchy) { + self.pathHierarchy = pathHierarchy + } + + /// Remove all matches from a given documentation bundle from the link resolver. + func unregisterBundle(identifier: BundleIdentifier) { + var newMap = BidirectionalMap() + for (id, reference) in resolvedReferenceMap { + if reference.bundleIdentifier == identifier { + pathHierarchy.removeNodeWithID(id) + } else { + newMap[id] = reference + } + } + resolvedReferenceMap = newMap + } + + /// Creates a path string—that can be used to find documentation in the path hierarchy—from an unresolved topic reference, + private static func path(for unresolved: UnresolvedTopicReference) -> String { + guard let fragment = unresolved.fragment else { + return unresolved.path + } + return "\(unresolved.path)#\(urlReadableFragment(fragment))" + } + + /// Traverse all the pairs of symbols and their parents. + func traverseSymbolAndParentPairs(_ observe: (_ symbol: ResolvedTopicReference, _ parent: ResolvedTopicReference) -> Void) { + for (id, node) in pathHierarchy.lookup { + guard node.symbol != nil else { continue } + + guard let parentID = node.parent?.identifier else { continue } + observe(resolvedReferenceMap[id]!, resolvedReferenceMap[parentID]!) + } + } + + /// Returns a list of all the top level symbols. + func topLevelSymbols() -> [ResolvedTopicReference] { + return pathHierarchy.topLevelSymbols().map { resolvedReferenceMap[$0]! } + } + + // MARK: - Adding non-symbols + + /// Map the resolved identifiers to resolved topic references for a given bundle's article, tutorial, and technology root pages. + func addMappingForRoots(bundle: DocumentationBundle) { + resolvedReferenceMap[pathHierarchy.tutorialContainer.identifier] = bundle.tutorialsRootReference + resolvedReferenceMap[pathHierarchy.articlesContainer.identifier] = bundle.articlesDocumentationRootReference + resolvedReferenceMap[pathHierarchy.tutorialOverviewContainer.identifier] = bundle.technologyTutorialsRootReference + } + + /// Map the resolved identifiers to resolved topic references for all symbols in the given symbol index. + func addMappingForSymbols(symbolIndex: [String: DocumentationNode]) { + for (id, node) in pathHierarchy.lookup { + guard let symbol = node.symbol, let node = symbolIndex[symbol.identifier.precise] else { + continue + } + resolvedReferenceMap[id] = node.reference + } + } + + /// Adds a tutorial and its landmarks to the path hierarchy. + func addTutorial(_ tutorial: DocumentationContext.SemanticResult) { + addTutorial( + reference: tutorial.topicGraphNode.reference, + source: tutorial.source, + landmarks: tutorial.value.landmarks + ) + } + + /// Adds a tutorial article and its landmarks to the path hierarchy. + func addTutorialArticle(_ tutorial: DocumentationContext.SemanticResult) { + addTutorial( + reference: tutorial.topicGraphNode.reference, + source: tutorial.source, + landmarks: tutorial.value.landmarks + ) + } + + private func addTutorial(reference: ResolvedTopicReference, source: URL, landmarks: [Landmark]) { + let tutorialID = pathHierarchy.addTutorial(name: urlReadablePath(source.deletingPathExtension().lastPathComponent)) + resolvedReferenceMap[tutorialID] = reference + + for landmark in landmarks { + let landmarkID = pathHierarchy.addNonSymbolChild(parent: tutorialID, name: urlReadableFragment(landmark.title), kind: "landmark") + resolvedReferenceMap[landmarkID] = reference.withFragment(landmark.title) + } + } + + /// Adds a technology and its volumes and chapters to the path hierarchy. + func addTechnology(_ technology: DocumentationContext.SemanticResult) { + let reference = technology.topicGraphNode.reference + + let technologyID = pathHierarchy.addTutorialOverview(name: urlReadablePath(technology.source.deletingPathExtension().lastPathComponent)) + resolvedReferenceMap[technologyID] = reference + + var anonymousVolumeID: ResolvedIdentifier? + for volume in technology.value.volumes { + if anonymousVolumeID == nil, volume.name == nil { + anonymousVolumeID = pathHierarchy.addNonSymbolChild(parent: technologyID, name: "$volume", kind: "volume") + resolvedReferenceMap[anonymousVolumeID!] = reference.appendingPath("$volume") + } + + let chapterParentID: ResolvedIdentifier + let chapterParentReference: ResolvedTopicReference + if let name = volume.name { + chapterParentID = pathHierarchy.addNonSymbolChild(parent: technologyID, name: name, kind: "volume") + chapterParentReference = reference.appendingPath(name) + resolvedReferenceMap[chapterParentID] = chapterParentReference + } else { + chapterParentID = technologyID + chapterParentReference = reference + } + + for chapter in volume.chapters { + let chapterID = pathHierarchy.addNonSymbolChild(parent: technologyID, name: chapter.name, kind: "volume") + resolvedReferenceMap[chapterID] = chapterParentReference.appendingPath(chapter.name) + } + } + } + + /// Adds a technology root article and its headings to the path hierarchy. + func addRootArticle(_ article: DocumentationContext.SemanticResult
, anchorSections: [AnchorSection]) { + let articleID = pathHierarchy.addTechnologyRoot(name: article.source.deletingPathExtension().lastPathComponent) + resolvedReferenceMap[articleID] = article.topicGraphNode.reference + addAnchors(anchorSections, to: articleID) + } + + /// Adds an article and its headings to the path hierarchy. + func addArticle(_ article: DocumentationContext.SemanticResult
, anchorSections: [AnchorSection]) { + let articleID = pathHierarchy.addArticle(name: article.source.deletingPathExtension().lastPathComponent) + resolvedReferenceMap[articleID] = article.topicGraphNode.reference + addAnchors(anchorSections, to: articleID) + } + + /// Adds a article and its headings to the path hierarchy. + func addArticle(filename: String, reference: ResolvedTopicReference, anchorSections: [AnchorSection]) { + let articleID = pathHierarchy.addArticle(name: filename) + resolvedReferenceMap[articleID] = reference + addAnchors(anchorSections, to: articleID) + } + + /// Adds the headings for all symbols in the symbol index to the path hierarchy. + func addAnchorForSymbols(symbolIndex: [String: DocumentationNode]) { + for (id, node) in pathHierarchy.lookup { + guard let symbol = node.symbol, let node = symbolIndex[symbol.identifier.precise] else { continue } + addAnchors(node.anchorSections, to: id) + } + } + + private func addAnchors(_ anchorSections: [AnchorSection], to parent: ResolvedIdentifier) { + for anchor in anchorSections { + let identifier = pathHierarchy.addNonSymbolChild(parent: parent, name: anchor.reference.fragment!, kind: "anchor") + resolvedReferenceMap[identifier] = anchor.reference + } + } + + /// Adds a task group on a given page to the documentation hierarchy. + func addTaskGroup(named name: String, reference: ResolvedTopicReference, to parent: ResolvedTopicReference) { + let parentID = resolvedReferenceMap[parent]! + let taskGroupID = pathHierarchy.addNonSymbolChild(parent: parentID, name: urlReadablePath(name), kind: "taskGroup") + resolvedReferenceMap[taskGroupID] = reference + } + + // MARK: Reference resolving + + /// Attempts to resolve an unresolved reference. + /// + /// - Parameters: + /// - unresolvedReference: The unresolved reference to resolve. + /// - parent: The parent reference to resolve the unresolved reference relative to. + /// - isCurrentlyResolvingSymbolLink: Whether or not the documentation link is a symbol link. + /// - context: The documentation context to resolve the link in. + /// - Returns: The result of resolving the reference. + public func resolve(_ unresolvedReference: UnresolvedTopicReference, in parent: ResolvedTopicReference, fromSymbolLink isCurrentlyResolvingSymbolLink: Bool, context: DocumentationContext) -> TopicReferenceResolutionResult { + // Check if the unresolved reference is external + if let bundleID = unresolvedReference.bundleIdentifier, + !context.registeredBundles.contains(where: { bundle in + bundle.identifier == bundleID || urlReadablePath(bundle.displayName) == bundleID + }) { + + if context.externalReferenceResolvers[bundleID] != nil, + let resolvedExternalReference = context.externallyResolvedLinks[unresolvedReference.topicURL] { + // Return the successful or failed externally resolved reference. + return resolvedExternalReference + } else if !context.registeredBundles.contains(where: { $0.identifier == bundleID }) { + return .failure(unresolvedReference, errorMessage: "No external resolver registered for \(bundleID.singleQuoted).") + } + } + + do { + let parentID = resolvedReferenceMap[parent] + let found = try pathHierarchy.find(path: Self.path(for: unresolvedReference), parent: parentID, onlyFindSymbols: isCurrentlyResolvingSymbolLink) + let foundReference = resolvedReferenceMap[found]! + + return .success(foundReference) + } catch let error as PathHierarchy.Error { + // If the reference didn't resolve in the path hierarchy, see if it can be resolved in the fallback resolver. + if let resolvedFallbackReference = fallbackResolver.resolve(unresolvedReference, in: parent, fromSymbolLink: isCurrentlyResolvingSymbolLink, context: context) { + return .success(resolvedFallbackReference) + } else { + return .failure(unresolvedReference, errorMessage: error.errorMessage(context: context)) + } + } catch { + fatalError("Only SymbolPathTree.Error errors are raised from the symbol link resolution code above.") + } + } + + private let fallbackResolver = FallbackResolverBasedLinkResolver() + + // MARK: Symbol reference creation + + /// Returns a map between symbol identifiers and topic references. + /// + /// - Parameters: + /// - symbolGraph: The complete symbol graph to walk through. + /// - bundle: The bundle to use when creating symbol references. + func referencesForSymbols(in unifiedGraphs: [String: UnifiedSymbolGraph], bundle: DocumentationBundle, context: DocumentationContext) -> [SymbolGraph.Symbol.Identifier: ResolvedTopicReference] { + let disambiguatedPaths = pathHierarchy.caseInsensitiveDisambiguatedPaths(includeDisambiguationForUnambiguousChildren: true, includeLanguage: true) + + var result: [SymbolGraph.Symbol.Identifier: ResolvedTopicReference] = [:] + + for (moduleName, symbolGraph) in unifiedGraphs { + let paths: [ResolvedTopicReference?] = Array(symbolGraph.symbols.values).concurrentMap { unifiedSymbol -> ResolvedTopicReference? in + let symbol = unifiedSymbol + let uniqueIdentifier = unifiedSymbol.uniqueIdentifier + + if let pathComponents = context.knownDisambiguatedSymbolPathComponents?[uniqueIdentifier], + let componentsCount = symbol.defaultSymbol?.pathComponents.count, + pathComponents.count == componentsCount + { + let symbolReference = SymbolReference(pathComponents: pathComponents, interfaceLanguages: symbol.sourceLanguages) + return ResolvedTopicReference(symbolReference: symbolReference, moduleName: moduleName, bundle: bundle) + } + + guard let path = disambiguatedPaths[uniqueIdentifier] else { + return nil + } + + return ResolvedTopicReference( + bundleIdentifier: bundle.documentationRootReference.bundleIdentifier, + path: NodeURLGenerator.Path.documentationFolder + path, + sourceLanguages: symbol.sourceLanguages + ) + } + for (symbol, reference) in zip(symbolGraph.symbols.values, paths) { + guard let reference = reference else { continue } + result[symbol.defaultIdentifier] = reference + } + } + return result + } +} + +/// A fallback resolver that replicates the exact order of resolved topic references that are attempted to resolve via a fallback resolver when the path hierarchy doesn't have a match. +private final class FallbackResolverBasedLinkResolver { + var cachedResolvedFallbackReferences = Synchronized<[String: ResolvedTopicReference]>([:]) + + func resolve(_ unresolvedReference: UnresolvedTopicReference, in parent: ResolvedTopicReference, fromSymbolLink isCurrentlyResolvingSymbolLink: Bool, context: DocumentationContext) -> ResolvedTopicReference? { + // Check if a fallback reference resolver should resolve this + let referenceBundleIdentifier = unresolvedReference.bundleIdentifier ?? parent.bundleIdentifier + guard !context.fallbackReferenceResolvers.isEmpty, + let knownBundleIdentifier = context.registeredBundles.first(where: { $0.identifier == referenceBundleIdentifier || urlReadablePath($0.displayName) == referenceBundleIdentifier })?.identifier, + let fallbackResolver = context.fallbackReferenceResolvers[knownBundleIdentifier] + else { + return nil + } + + if let cached = cachedResolvedFallbackReferences.sync({ $0[unresolvedReference.topicURL.absoluteString] }) { + return cached + } + var allCandidateURLs = [URL]() + + let alreadyResolved = ResolvedTopicReference( + bundleIdentifier: referenceBundleIdentifier, + path: unresolvedReference.path.prependingLeadingSlash, + fragment: unresolvedReference.topicURL.components.fragment, + sourceLanguages: parent.sourceLanguages + ) + allCandidateURLs.append(alreadyResolved.url) + + let currentBundle = context.bundle(identifier: knownBundleIdentifier)! + if !isCurrentlyResolvingSymbolLink { + // First look up articles path + allCandidateURLs.append(contentsOf: [ + // First look up articles path + currentBundle.articlesDocumentationRootReference.url.appendingPathComponent(unresolvedReference.path), + // Then technology tutorials root path (for individual tutorial pages) + currentBundle.technologyTutorialsRootReference.url.appendingPathComponent(unresolvedReference.path), + // Then tutorials root path (for tutorial table of contents pages) + currentBundle.tutorialsRootReference.url.appendingPathComponent(unresolvedReference.path), + ]) + } + // Try resolving in the local context (as child) + allCandidateURLs.append(parent.appendingPathOfReference(unresolvedReference).url) + + // To look for siblings we require at least a module (first) + // and a symbol (second) path components. + let parentPath = parent.path.components(separatedBy: "/").dropLast() + if parentPath.count >= 2 { + allCandidateURLs.append(parent.url.deletingLastPathComponent().appendingPathComponent(unresolvedReference.path)) + } + + // Check that the parent is not an article (ignoring if absolute or relative link) + // because we cannot resolve in the parent context if it's not a symbol. + if parent.path.hasPrefix(currentBundle.documentationRootReference.path) && parentPath.count > 2 { + let rootPath = currentBundle.documentationRootReference.appendingPath(parentPath[2]) + let resolvedInRoot = rootPath.url.appendingPathComponent(unresolvedReference.path) + + // Confirm here that we we're not already considering this link. We only need to specifically + // consider the parent reference when looking for deeper links. + if resolvedInRoot.path != allCandidateURLs.last?.path { + allCandidateURLs.append(resolvedInRoot) + } + } + + allCandidateURLs.append(currentBundle.documentationRootReference.url.appendingPathComponent(unresolvedReference.path)) + + for candidateURL in allCandidateURLs { + if let cached = cachedResolvedFallbackReferences.sync({ $0[candidateURL.absoluteString] }) { + return cached + } + let unresolvedReference = UnresolvedTopicReference(topicURL: ValidatedURL(candidateURL)!) + let reference = fallbackResolver.resolve(.unresolved(unresolvedReference), sourceLanguage: parent.sourceLanguage) + + if case .success(let resolvedReference) = reference { + cachedResolvedFallbackReferences.sync({ $0[resolvedReference.absoluteString] = resolvedReference }) + return resolvedReference + } + } + // Give up: there is no local or external document for this reference. + return nil + } +} diff --git a/Sources/SwiftDocC/Infrastructure/Symbol Graph/GeneratedDocumentationTopics.swift b/Sources/SwiftDocC/Infrastructure/Symbol Graph/GeneratedDocumentationTopics.swift index fa50ae4a0a..9f7ac282f1 100644 --- a/Sources/SwiftDocC/Infrastructure/Symbol Graph/GeneratedDocumentationTopics.swift +++ b/Sources/SwiftDocC/Infrastructure/Symbol Graph/GeneratedDocumentationTopics.swift @@ -141,6 +141,9 @@ enum GeneratedDocumentationTopics { let inheritedSection = AutomaticTaskGroupSection(title: defaultImplementationGroupTitle, references: [collectionReference], renderPositionPreference: .bottom) symbol.automaticTaskGroupsVariants[trait]?.append(inheritedSection) } + if let hierarchyBasedLinkResolver = context.hierarchyBasedLinkResolver { + hierarchyBasedLinkResolver.addTaskGroup(named: title, reference: collectionReference, to: parent) + } } } else { fatalError("createCollectionNode() should be used only to add nodes under symbols.") diff --git a/Sources/SwiftDocC/Model/Rendering/RenderContentCompiler.swift b/Sources/SwiftDocC/Model/Rendering/RenderContentCompiler.swift index 9730a04e9b..6c4a2b91a2 100644 --- a/Sources/SwiftDocC/Model/Rendering/RenderContentCompiler.swift +++ b/Sources/SwiftDocC/Model/Rendering/RenderContentCompiler.swift @@ -138,8 +138,9 @@ struct RenderContentCompiler: MarkupVisitor { return cached } - let unresolved = UnresolvedTopicReference(topicURL: .init(symbolPath: destination)) - if case let .success(resolved) = context.resolve(.unresolved(unresolved), in: identifier, fromSymbolLink: true) { + // The symbol link may be written with a scheme and bundle identifier. + let url = ValidatedURL(parsingExact: destination)?.requiring(scheme: ResolvedTopicReference.urlScheme) ?? ValidatedURL(symbolPath: destination) + if case let .success(resolved) = context.resolve(.unresolved(.init(topicURL: url)), in: identifier, fromSymbolLink: true) { return resolved } diff --git a/Sources/SwiftDocC/Semantics/MarkupReferenceResolver.swift b/Sources/SwiftDocC/Semantics/MarkupReferenceResolver.swift index 73af512d87..31808c448f 100644 --- a/Sources/SwiftDocC/Semantics/MarkupReferenceResolver.swift +++ b/Sources/SwiftDocC/Semantics/MarkupReferenceResolver.swift @@ -129,8 +129,7 @@ struct MarkupReferenceResolver: MarkupRewriter { // We don't require a scheme here as the link can be a relative one, e.g. ``SwiftUI/View``. let url = ValidatedURL(parsingExact: unresolvedDestination)?.requiring(scheme: ResolvedTopicReference.urlScheme) ?? ValidatedURL(symbolPath: unresolvedDestination) - let unresolved = TopicReference.unresolved(.init(topicURL: url)) - return resolve(reference: unresolved, range: range, severity: .warning, fromSymbolLink: true) + return resolve(reference: .unresolved(.init(topicURL: url)), range: range, severity: .warning, fromSymbolLink: true) } mutating func visitSymbolLink(_ symbolLink: SymbolLink) -> Markup? { diff --git a/Sources/SwiftDocC/SwiftDocC.docc/SwiftDocC.md b/Sources/SwiftDocC/SwiftDocC.docc/SwiftDocC.md index 870bfa27ec..efe24ad101 100644 --- a/Sources/SwiftDocC/SwiftDocC.docc/SwiftDocC.md +++ b/Sources/SwiftDocC/SwiftDocC.docc/SwiftDocC.md @@ -25,6 +25,10 @@ SwiftDocC provides the APIs you use to load a bundle, parse the symbol-graph met - - +### Resolving documentation links + +- + ### Rendering Converting in-memory documentation into rendering nodes and persisting them on disk as JSON. diff --git a/Sources/SwiftDocC/SwiftDocC.docc/SwiftDocC/Benchmarking.md b/Sources/SwiftDocC/SwiftDocC.docc/SwiftDocC/Benchmarking.md index b7458a9cb1..5d4b0873ed 100644 --- a/Sources/SwiftDocC/SwiftDocC.docc/SwiftDocC/Benchmarking.md +++ b/Sources/SwiftDocC/SwiftDocC.docc/SwiftDocC/Benchmarking.md @@ -67,7 +67,8 @@ benchmark(add: BundlesCount(context: context)) ### Default Metrics - ``Benchmark/Duration`` -- ``Benchmark/OutputSize`` +- ``Benchmark/DataDirectoryOutputSize`` +- ``Benchmark/IndexDirectoryOutputSize`` - ``Benchmark/PeakMemory`` - ``Benchmark/TopicGraphHash`` - ``Benchmark/ExternalTopicsHash`` diff --git a/Sources/SwiftDocC/SwiftDocC.docc/SwiftDocC/LinkResolution.md b/Sources/SwiftDocC/SwiftDocC.docc/SwiftDocC/LinkResolution.md new file mode 100644 index 0000000000..51f717a0ae --- /dev/null +++ b/Sources/SwiftDocC/SwiftDocC.docc/SwiftDocC/LinkResolution.md @@ -0,0 +1,59 @@ +# Linking between documentation + +Connect documentation pages with documentation links. + +## Overview + +DocC uses links to connect documentation pages to each other. + +Some links are automatic or created by tools. For example symbol declarations in symbol graph files use `typeIdentifier` tokens with `preciseIdentifier` values to link to other types that are referenced in the declaration and symbol graph relationships are used to construct a default documentation hierarchy. These links use unique and exact identifiers to reference other symbols. + +All other documentation links are written in the documentation content; in symbol documentation comments or in markdown or tutorial files. These "authored" documentation links are used to associate documentation extension files with symbols, form links in the documentation content itself, customize the documentation hierarchy, and organize tutorials. + +Developers can write two types of documentation links: + - Symbol links; a symbol path surrounded by two grave accents on each side: ` ``MyClass/myProperty`` ` + - General documentation links; markdown links with a "doc" scheme: `` or ``. + +As the name suggest, symbol links can only link to symbols. General documentation links can link to all types of documentation content: symbols, articles, and tutorials. General documentation links can use the documentation catalogs identifier as the "hostname" of the documentation URI but links within the same catalog only need the path component of the URI. Optionally URI fragments can be used to reference specific headings/sections on a documentation page. + +``` +doc://com.example/path/to/documentation/page#optional-heading + ╰─────┬─────╯╰────────────┬────────────╯╰───────┬───────╯ + bundle ID path in docs hierarchy heading name +``` + +## Resolving a documentation link + +To make authored documentation links easier to write and easier to read in plain text format all authored documentation links are relative links. The symbol links in documentation extension headers are written relative to the scope of modules. All other authored documentation links are written relative to the page where the link is written. + +These relative documentation links can specify path components from higher up in the documentation hierarchy to reference container symbols or container pages. + +### Handling ambiguous links + +It's possible for collisions to occur in documentation links (symbol links or otherwise) where more than one page are represented by the same path. A common cause for documentation link collisions are function overloads (functions with the same name but different arguments or different return values). It's also possible to have documentation link collisions in conceptual content if an article file name is the same as a tutorial file name (excluding the file extension in both cases). + +If DocC encounters an ambiguous documentation link that could either resolve to an article (using its file name), a tutorial (using its file name), or a symbol (using the symbol's name in a lone path component) then DocC will prefer the article result over other two results and the tutorial result over the symbol result. + +If DocC encounters an ambiguous link to a symbol (either written as a symbol link or as a general documentation link) then DocC will require that additional information is added to the link to disambiguate between the different symbol results. If the symbols are different kinds (for example a class, an enum, and a property) then DocC will disambiguate the links by appending the kind ID to the ambiguous path component. + +``` +/path/to/Something-class +/path/to/Something-enum +/path/to/Something-property +``` + + +If two or more symbol results have the same kind, then that information doesn't distinguish the results. In this case DocC will use a hashed version of each symbols's unique and exact identifiers to disambiguate the results. + +``` +/path/to/someFunction-abc123 +/path/to/someFunction-def456 +``` + +Links with added disambiguation information is both harder read and harder write so DocC aims to require as little disambiguation as possible. + +## Resolving links outside the documentation catalog + +If a ``DocumentationContext`` is configured with one or more ``DocumentationContext/externalReferenceResolvers`` it is capable of resolving links general documentation links via that ``ExternalReferenceResolver``. External documentation links need to be written with a bundle ID in the URI to identify which external resolver should handle the request. + + diff --git a/Sources/SwiftDocC/Utility/DataStructures/BidirectionalMap.swift b/Sources/SwiftDocC/Utility/DataStructures/BidirectionalMap.swift index 611f62e076..704a840fab 100644 --- a/Sources/SwiftDocC/Utility/DataStructures/BidirectionalMap.swift +++ b/Sources/SwiftDocC/Utility/DataStructures/BidirectionalMap.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 @@ -16,7 +16,7 @@ import Foundation /// This type is basically a wrapper around two dictionaries not allowing the relationships in /// the two dictionaries to get out of sync. /// - warning: Do not use optional types for `Value1` and `Value2`. Do not use the same type for `Value1` and `Value2`. -struct BidirectionalMap { +struct BidirectionalMap: Sequence { private var forward = [Value1: Value2]() private var reverse = [Value2: Value1]() @@ -63,4 +63,8 @@ struct BidirectionalMap { forward.reserveCapacity(count) reverse.reserveCapacity(count) } + + func makeIterator() -> Dictionary.Iterator { + return forward.makeIterator() + } } diff --git a/Tests/SwiftDocCTests/DocumentationService/ConvertService/ConvertServiceTests.swift b/Tests/SwiftDocCTests/DocumentationService/ConvertService/ConvertServiceTests.swift index af680a915d..004aaffbb3 100644 --- a/Tests/SwiftDocCTests/DocumentationService/ConvertService/ConvertServiceTests.swift +++ b/Tests/SwiftDocCTests/DocumentationService/ConvertService/ConvertServiceTests.swift @@ -355,10 +355,25 @@ class ConvertServiceTests: XCTestCase { "/documentation/MyKit/MyClass-swift.class/myFunction()-swift.method" ) - XCTAssertEqual( - renderNode.abstract?.first, - .codeVoice(code: "myFunction()") - ) + if LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver { + XCTAssertEqual( + renderNode.abstract?.first, + .reference( + identifier: .init(""" + doc://identifier/documentation/MyKit/MyClass-swift.class/myFunction()-swift.method + """ + ), + isActive: true, + overridingTitle: nil, + overridingTitleInlineContent: nil + ) + ) + } else { + XCTAssertEqual( + renderNode.abstract?.first, + .codeVoice(code: "myFunction()") + ) + } } let symbolGraphWithAdjustedLink = Data( diff --git a/Tests/SwiftDocCTests/Indexing/NavigatorIndexTests.swift b/Tests/SwiftDocCTests/Indexing/NavigatorIndexTests.swift index 2438fbeb1d..f04f5d2ddc 100644 --- a/Tests/SwiftDocCTests/Indexing/NavigatorIndexTests.swift +++ b/Tests/SwiftDocCTests/Indexing/NavigatorIndexTests.swift @@ -267,6 +267,7 @@ Root func testNavigationTreeLargeDumpAndRead() throws { + try XCTSkipIf(true, "These performance measurements aren't compared to previous results.") #if os(OSX) let targetURL = try createTemporaryDirectory() let indexURL = targetURL.appendingPathComponent("nav.index") diff --git a/Tests/SwiftDocCTests/Infrastructure/DocumentationContext/DocumentationContext+MixedLanguageLinkResolutionTests.swift b/Tests/SwiftDocCTests/Infrastructure/DocumentationContext/DocumentationContext+MixedLanguageLinkResolutionTests.swift index a4d95a81aa..adc775d0de 100644 --- a/Tests/SwiftDocCTests/Infrastructure/DocumentationContext/DocumentationContext+MixedLanguageLinkResolutionTests.swift +++ b/Tests/SwiftDocCTests/Infrastructure/DocumentationContext/DocumentationContext+MixedLanguageLinkResolutionTests.swift @@ -13,8 +13,13 @@ import XCTest class DocumentationContext_MixedLanguageLinkResolutionTests: XCTestCase { - func testResolvesLinksUsingParentReferenceAlias() throws { - let (_, _, context) = try testBundleAndContext(copying: "MixedLanguageFrameworkComplexLinks") + func testResolvingLinksWhenSymbolHasSameNameInBothLanguages() throws { + let (_, _, context) = try testBundleAndContext(copying: "MixedLanguageFrameworkComplexLinks") { url in + let swiftSymbolGraph = url.appendingPathComponent("symbol-graph/swift/ObjCLinks.symbols.json") + try String(contentsOf: swiftSymbolGraph) + .replacingOccurrences(of: "FooSwift", with: "FooObjC") + .write(to: swiftSymbolGraph, atomically: true, encoding: .utf8) + } func assertCanResolveSymbolLinks( symbolPaths: String..., @@ -53,17 +58,17 @@ class DocumentationContext_MixedLanguageLinkResolutionTests: XCTestCase { assertCanResolveSymbolLinks( symbolPaths: "first(_:one:)", "first:one:", "second:two:", "second(_:two:)", - parentPath: "FooSwift" + parentPath: "FooObjC" ) assertCanResolveSymbolLinks( - symbolPaths: "FooSwift", "FooObjC", "second:two:", "second(_:two:)", - parentPath: "FooSwift/first(_:one:)" + symbolPaths: "FooObjC", "second:two:", "second(_:two:)", + parentPath: "FooObjC/first(_:one:)" ) assertCanResolveSymbolLinks( - symbolPaths: "FooSwift", "FooObjC", "first:one:", "first(_:one:)", - parentPath: "FooSwift/second(_:two:)" + symbolPaths: "FooObjC", "first:one:", "first(_:one:)", + parentPath: "FooObjC/second(_:two:)" ) } } diff --git a/Tests/SwiftDocCTests/Infrastructure/DocumentationContext/DocumentationContextTests.swift b/Tests/SwiftDocCTests/Infrastructure/DocumentationContext/DocumentationContextTests.swift index 02769921f7..46c305feab 100644 --- a/Tests/SwiftDocCTests/Infrastructure/DocumentationContext/DocumentationContextTests.swift +++ b/Tests/SwiftDocCTests/Infrastructure/DocumentationContext/DocumentationContextTests.swift @@ -1634,8 +1634,13 @@ let expected = """ // Verify the non-overload collisions were resolved XCTAssertNoThrow(try context.entity(with: ResolvedTopicReference(bundleIdentifier: "org.swift.docc.example", path: "/documentation/SideKit/SideClass/Test-swift.enum", sourceLanguage: .swift))) - XCTAssertNoThrow(try context.entity(with: ResolvedTopicReference(bundleIdentifier: "org.swift.docc.example", path: "/documentation/SideKit/SideClass/tEst-swift.var-9053a", sourceLanguage: .swift))) - XCTAssertNoThrow(try context.entity(with: ResolvedTopicReference(bundleIdentifier: "org.swift.docc.example", path: "/documentation/SideKit/SideClass/test-swift.var-959hd", sourceLanguage: .swift))) + if LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver { + XCTAssertNoThrow(try context.entity(with: ResolvedTopicReference(bundleIdentifier: "org.swift.docc.example", path: "/documentation/SideKit/SideClass/tEst-9053a", sourceLanguage: .swift))) + XCTAssertNoThrow(try context.entity(with: ResolvedTopicReference(bundleIdentifier: "org.swift.docc.example", path: "/documentation/SideKit/SideClass/test-959hd", sourceLanguage: .swift))) + } else { + XCTAssertNoThrow(try context.entity(with: ResolvedTopicReference(bundleIdentifier: "org.swift.docc.example", path: "/documentation/SideKit/SideClass/tEst-swift.var-9053a", sourceLanguage: .swift))) + XCTAssertNoThrow(try context.entity(with: ResolvedTopicReference(bundleIdentifier: "org.swift.docc.example", path: "/documentation/SideKit/SideClass/test-swift.var-959hd", sourceLanguage: .swift))) + } } func testUnknownSymbolKind() throws { @@ -2559,6 +2564,13 @@ let expected = """ /// matched with their documentation extension files. Besides verifying the correct content /// it verifies also that the curation in these doc extensions is reflected in the topic graph. func testMatchesCorrectlyDocExtensionToChildOfCollisionTopic() throws { + let fifthTestMemberPath: String + if LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver { + fifthTestMemberPath = "ShapeKit/OverloadedParentStruct-1jr3p/fifthTestMember" + } else { + fifthTestMemberPath = "ShapeKit/OverloadedParentStruct-1jr3p/fifthTestMember-swift.type.property" + } + let (_, bundle, context) = try testBundleAndContext(copying: "OverloadedSymbols") { url in // Add an article to be curated from collided nodes' doc extensions. try """ @@ -2583,6 +2595,15 @@ let expected = """ ### Basics - """.write(to: url.appendingPathComponent("fifthTestMember.md"), atomically: true, encoding: .utf8) + + // Add doc extension file for a child of a collision symbol + try """ + # ``\(fifthTestMemberPath)`` + fifthTestMember abstract. + ## Topics + ### Basics + - + """.write(to: url.appendingPathComponent("fifthTestMember.md"), atomically: true, encoding: .utf8) } let articleReference = ResolvedTopicReference(bundleIdentifier: bundle.identifier, path: "/documentation/ShapeKit/NewArticle", sourceLanguage: .swift) @@ -2601,7 +2622,8 @@ let expected = """ XCTAssertTrue(tgNode1.contains(articleReference)) // Fetch the "fifthTestMember" node - let reference2 = ResolvedTopicReference(bundleIdentifier: bundle.identifier, path: "/documentation/ShapeKit/OverloadedParentStruct-1jr3p/fifthTestMember-swift.type.property", sourceLanguage: .swift) + let reference2 = ResolvedTopicReference(bundleIdentifier: bundle.identifier, path: "/documentation/\(fifthTestMemberPath)", sourceLanguage: .swift) + let node2 = try context.entity(with: reference2) let symbol2 = try XCTUnwrap(node2.semantic as? Symbol) @@ -2756,23 +2778,22 @@ let expected = """ // Verifies if the context resolves linkable nodes. func testLinkableNodes() throws { - let (bundle, context) = try testBundleAndContext(named: "TestBundle") + let (_, bundle, context) = try testBundleAndContext(copying: "TestBundle") { url in + try "# Article1".write(to: url.appendingPathComponent("resolvable-article.md"), atomically: true, encoding: .utf8) + let myKitURL = url.appendingPathComponent("documentation").appendingPathComponent("mykit.md") + try String(contentsOf: myKitURL) + .replacingOccurrences(of: " - ", with: " - ") + .write(to: myKitURL, atomically: true, encoding: .utf8) + } let moduleReference = ResolvedTopicReference(bundleIdentifier: bundle.identifier, path: "/documentation/MyKit", sourceLanguage: .swift) - let moduleTopicGraphNode = try XCTUnwrap(context.topicGraph.nodeWithReference(moduleReference)) - // Add a new resolvable node - let resolvableReference = ResolvedTopicReference(bundleIdentifier: bundle.identifier, path: "/documentation/Test-Bundle/resolvable-article", sourceLanguage: .swift) - let resolvableNode = try DocumentationNode(reference: resolvableReference, article: Article(markup: Document(parsing: "# Article1"), metadata: nil, redirects: nil)) - context.documentationCache[resolvableReference] = resolvableNode - - let resolvableTopicGraphNode = TopicGraph.Node(reference: resolvableReference, kind: .article, source: .external, title: "Article1", isResolvable: true) - context.topicGraph.addEdge(from: moduleTopicGraphNode, to: resolvableTopicGraphNode) - // Try resolving the new resolvable node - XCTAssertNoThrow(try context.entity(with: resolvableReference)) switch context.resolve(.unresolved(UnresolvedTopicReference(topicURL: ValidatedURL(parsingExact: "doc:resolvable-article")!)), in: moduleReference) { - case .success: break - case .failure(_, let errorMessage): XCTFail("Did not resolve resolvable link. Error: \(errorMessage)") + case .success(let resolvedReference): + XCTAssertEqual(resolvedReference.absoluteString, "doc://\(bundle.identifier)/documentation/Test-Bundle/resolvable-article") + XCTAssertNoThrow(try context.entity(with: resolvedReference)) + case .failure(_, let errorMessage): + XCTFail("Did not resolve resolvable link. Error: \(errorMessage)") } } diff --git a/Tests/SwiftDocCTests/Infrastructure/DocumentationCuratorTests.swift b/Tests/SwiftDocCTests/Infrastructure/DocumentationCuratorTests.swift index e07cb214d0..623e7c3700 100644 --- a/Tests/SwiftDocCTests/Infrastructure/DocumentationCuratorTests.swift +++ b/Tests/SwiftDocCTests/Infrastructure/DocumentationCuratorTests.swift @@ -99,7 +99,7 @@ class DocumentationCuratorTests: XCTestCase { ### Invalid curation - A few different curationos that should each reasult in warnigns. + A few different curations that should each result in warnings. The first is a reference to the parent, the second is a reference to self, and the last is an unresolved reference. - ``MyKit`` diff --git a/Tests/SwiftDocCTests/Infrastructure/PathHierarchyTests.swift b/Tests/SwiftDocCTests/Infrastructure/PathHierarchyTests.swift new file mode 100644 index 0000000000..c46042ee35 --- /dev/null +++ b/Tests/SwiftDocCTests/Infrastructure/PathHierarchyTests.swift @@ -0,0 +1,1191 @@ +/* + 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 Swift project authors +*/ + +import XCTest +import SymbolKit +@testable import SwiftDocC +import SwiftDocCTestUtilities + +class PathHierarchyTests: XCTestCase { + + func testFindingUnambiguousAbsolutePaths() throws { + try XCTSkipUnless(LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver) + let (_, context) = try testBundleAndContext(named: "MixedLanguageFrameworkWithLanguageRefinements") + let tree = try XCTUnwrap(context.hierarchyBasedLinkResolver?.pathHierarchy) + + try assertFindsPath("/MixedFramework", in: tree, asSymbolID: "MixedFramework") + + // @objc public enum MyEnum: Int { + // case firstCase + // case secondCase + // public func myEnumFunction() { } + // public typealias MyEnumTypeAlias = Int + // public var myEnumProperty: MyEnumTypeAlias { 0 } + // } + try assertFindsPath("/MixedFramework/MyEnum", in: tree, asSymbolID: "c:@M@MixedFramework@E@MyEnum") + try assertFindsPath("/MixedFramework/MyEnum/firstCase", in: tree, asSymbolID: "c:@M@MixedFramework@E@MyEnum@MyEnumFirstCase") + try assertFindsPath("/MixedFramework/MyEnum/secondCase", in: tree, asSymbolID: "c:@M@MixedFramework@E@MyEnum@MyEnumSecondCase") + try assertFindsPath("/MixedFramework/MyEnum/myEnumFunction()", in: tree, asSymbolID: "s:14MixedFramework6MyEnumO02myD8FunctionyyF") + try assertFindsPath("/MixedFramework/MyEnum/MyEnumTypeAlias", in: tree, asSymbolID: "s:14MixedFramework6MyEnumO0cD9TypeAliasa") + try assertFindsPath("/MixedFramework/MyEnum/myEnumProperty", in: tree, asSymbolID: "s:14MixedFramework6MyEnumO02myD8PropertySivp") + + // public struct MyStruct { + // public func myStructFunction() { } + // public typealias MyStructTypeAlias = Int + // public var myStructProperty: MyStructTypeAlias { 0 } + // public static var myStructTypeProperty: MyStructTypeAlias { 0 } + // } + try assertFindsPath("/MixedFramework/MyStruct", in: tree, asSymbolID: "s:14MixedFramework8MyStructV") + try assertFindsPath("/MixedFramework/MyStruct/myStructFunction()", in: tree, asSymbolID: "s:14MixedFramework8MyStructV02myD8FunctionyyF") + try assertFindsPath("/MixedFramework/MyStruct/MyStructTypeAlias", in: tree, asSymbolID: "s:14MixedFramework8MyStructV0cD9TypeAliasa") + try assertFindsPath("/MixedFramework/MyStruct/myStructProperty", in: tree, asSymbolID: "s:14MixedFramework8MyStructV02myD8PropertySivp") + try assertFindsPath("/MixedFramework/MyStruct/myStructTypeProperty", in: tree, asSymbolID: "s:14MixedFramework8MyStructV02myD12TypePropertySivpZ") + + // @objc public class MyClass: NSObject { + // @objc public func myInstanceMethod() { } + // @nonobjc public func mySwiftOnlyInstanceMethod() { } + // public typealias MyClassTypeAlias = Int + // public var myInstanceProperty: MyClassTypeAlias { 0 } + // public static var myClassTypeProperty: MyClassTypeAlias { 0 } + // } + try assertFindsPath("/MixedFramework/MyClass", in: tree, asSymbolID: "c:@M@MixedFramework@objc(cs)MyClass") + try assertFindsPath("/MixedFramework/MyClass/myInstanceMethod", in: tree, asSymbolID: "c:@M@MixedFramework@objc(cs)MyClass(im)myInstanceMethod") + try assertFindsPath("/MixedFramework/MyClass/myInstanceMethod()", in: tree, asSymbolID: "c:@M@MixedFramework@objc(cs)MyClass(im)myInstanceMethod") + try assertFindsPath("/MixedFramework/MyClass/mySwiftOnlyInstanceMethod()", in: tree, asSymbolID: "s:14MixedFramework7MyClassC25mySwiftOnlyInstanceMethodyyF") + try assertPathNotFound("/MixedFramework/MyClass/mySwiftOnlyInstanceMethod", in: tree) + try assertFindsPath("/MixedFramework/MyClass/MyClassTypeAlias", in: tree, asSymbolID: "s:14MixedFramework7MyClassC0cD9TypeAliasa") + try assertFindsPath("/MixedFramework/MyClass/myInstanceProperty", in: tree, asSymbolID: "s:14MixedFramework7MyClassC18myInstancePropertySivp") + try assertFindsPath("/MixedFramework/MyClass/myClassTypeProperty", in: tree, asSymbolID: "s:14MixedFramework7MyClassC02myD12TypePropertySivpZ") + + // @objc public protocol MyObjectiveCCompatibleProtocol { + // func myProtocolMethod() + // typealias MyProtocolTypeAlias = MyClass + // var myProtocolProperty: MyProtocolTypeAlias { get } + // static var myProtocolTypeProperty: MyProtocolTypeAlias { get } + // @objc optional func myPropertyOptionalMethod() + // } + try assertFindsPath("/MixedFramework/MyObjectiveCCompatibleProtocol", in: tree, asSymbolID: "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol") + try assertFindsPath("/MixedFramework/MyObjectiveCCompatibleProtocol/myProtocolMethod", in: tree, asSymbolID: "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(im)myProtocolMethod") + try assertFindsPath("/MixedFramework/MyObjectiveCCompatibleProtocol/myProtocolMethod()", in: tree, asSymbolID: "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(im)myProtocolMethod") + try assertFindsPath("/MixedFramework/MyObjectiveCCompatibleProtocol/myProtocolProperty", in: tree, asSymbolID: "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(py)myProtocolProperty") + // Objective-C class properties have a "property" kind instead of a "type.property" kind (rdar://92927788) + try assertFindsPath("/MixedFramework/MyObjectiveCCompatibleProtocol/myProtocolTypeProperty-type.property", in: tree, asSymbolID: "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(cpy)myProtocolTypeProperty") + try assertFindsPath("/MixedFramework/MyObjectiveCCompatibleProtocol/myPropertyOptionalMethod", in: tree, asSymbolID: "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(im)myPropertyOptionalMethod") + try assertFindsPath("/MixedFramework/MyObjectiveCCompatibleProtocol/myPropertyOptionalMethod()", in: tree, asSymbolID: "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(im)myPropertyOptionalMethod") + + // public protocol MySwiftProtocol { + // func myProtocolMethod() + // associatedtype MyProtocolAssociatedType + // typealias MyProtocolTypeAlias = MyStruct + // var myProtocolProperty: MyProtocolAssociatedType { get } + // static var myProtocolTypeProperty: MyProtocolAssociatedType { get } + // } + try assertFindsPath("/MixedFramework/MySwiftProtocol", in: tree, asSymbolID: "s:14MixedFramework15MySwiftProtocolP") + try assertFindsPath("/MixedFramework/MySwiftProtocol/myProtocolMethod()", in: tree, asSymbolID: "s:14MixedFramework15MySwiftProtocolP02myE6MethodyyF") + try assertFindsPath("/MixedFramework/MySwiftProtocol/MyProtocolAssociatedType", in: tree, asSymbolID: "s:14MixedFramework15MySwiftProtocolP0cE14AssociatedTypeQa") + try assertFindsPath("/MixedFramework/MySwiftProtocol/MyProtocolTypeAlias", in: tree, asSymbolID: "s:14MixedFramework15MySwiftProtocolP0cE9TypeAliasa") + try assertFindsPath("/MixedFramework/MySwiftProtocol/myProtocolProperty", in: tree, asSymbolID: "s:14MixedFramework15MySwiftProtocolP02myE8Property0cE14AssociatedTypeQzvp") + try assertFindsPath("/MixedFramework/MySwiftProtocol/myProtocolTypeProperty", in: tree, asSymbolID: "s:14MixedFramework15MySwiftProtocolP02myE12TypeProperty0ce10AssociatedG0QzvpZ") + + // public typealias MyTypeAlias = MyStruct + try assertFindsPath("/MixedFramework/MyTypeAlias", in: tree, asSymbolID: "s:14MixedFramework11MyTypeAliasa") + + // public func myTopLevelFunction() { } + // public var myTopLevelVariable = true + try assertFindsPath("/MixedFramework/myTopLevelFunction()", in: tree, asSymbolID: "s:14MixedFramework18myTopLevelFunctionyyF") + try assertFindsPath("/MixedFramework/myTopLevelVariable", in: tree, asSymbolID: "s:14MixedFramework18myTopLevelVariableSbvp") + + // public protocol MyOtherProtocolThatConformToMySwiftProtocol: MySwiftProtocol { + // func myOtherProtocolMethod() + // } + try assertFindsPath("/MixedFramework/MyOtherProtocolThatConformToMySwiftProtocol", in: tree, asSymbolID: "s:14MixedFramework028MyOtherProtocolThatConformToc5SwiftE0P") + try assertFindsPath("/MixedFramework/MyOtherProtocolThatConformToMySwiftProtocol/myOtherProtocolMethod()", in: tree, asSymbolID: "s:14MixedFramework028MyOtherProtocolThatConformToc5SwiftE0P02mydE6MethodyyF") + + // @objcMembers public class MyClassThatConformToMyOtherProtocol: NSObject, MyOtherProtocolThatConformToMySwiftProtocol { + // public func myOtherProtocolMethod() { } + // public func myProtocolMethod() { } + // public typealias MyProtocolAssociatedType = MyStruct + // public var myProtocolProperty: MyStruct { .init() } + // public class var myProtocolTypeProperty: MyStruct { .init() } + // } + try assertFindsPath("/MixedFramework/MyClassThatConformToMyOtherProtocol", in: tree, asSymbolID: "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol") + try assertFindsPath("/MixedFramework/MyClassThatConformToMyOtherProtocol/myOtherProtocolMethod()", in: tree, asSymbolID: "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol(im)myOtherProtocolMethod") + try assertFindsPath("/MixedFramework/MyClassThatConformToMyOtherProtocol/myOtherProtocolMethod", in: tree, asSymbolID: "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol(im)myOtherProtocolMethod") + try assertFindsPath("/MixedFramework/MyClassThatConformToMyOtherProtocol/myProtocolMethod()", in: tree, asSymbolID: "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol(im)myProtocolMethod") + try assertFindsPath("/MixedFramework/MyClassThatConformToMyOtherProtocol/myProtocolMethod", in: tree, asSymbolID: "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol(im)myProtocolMethod") + try assertFindsPath("/MixedFramework/MyClassThatConformToMyOtherProtocol/MyProtocolAssociatedType", in: tree, asSymbolID: "s:14MixedFramework020MyClassThatConformToC13OtherProtocolC0cI14AssociatedTypea") + try assertFindsPath("/MixedFramework/MyClassThatConformToMyOtherProtocol/myProtocolProperty", in: tree, asSymbolID: "s:14MixedFramework020MyClassThatConformToC13OtherProtocolC02myI8PropertyAA0C6StructVvp") + try assertFindsPath("/MixedFramework/MyClassThatConformToMyOtherProtocol/myProtocolTypeProperty", in: tree, asSymbolID: "s:14MixedFramework020MyClassThatConformToC13OtherProtocolC02myI12TypePropertyAA0C6StructVvpZ") + + // public final class CollisionsWithDifferentCapitalization { + // public var something: Int = 0 + // public var someThing: Int = 0 + // } + try assertFindsPath("/MixedFramework/CollisionsWithDifferentCapitalization", in: tree, asSymbolID: "s:14MixedFramework37CollisionsWithDifferentCapitalizationC") + try assertFindsPath("/MixedFramework/CollisionsWithDifferentCapitalization/something", in: tree, asSymbolID: "s:14MixedFramework37CollisionsWithDifferentCapitalizationC9somethingSivp") + try assertFindsPath("/MixedFramework/CollisionsWithDifferentCapitalization/someThing", in: tree, asSymbolID: "s:14MixedFramework37CollisionsWithDifferentCapitalizationC9someThingSivp") + + // public enum CollisionsWithDifferentKinds { + // case something + // public var something: String { "" } + // public typealias Something = Int + // } + try assertFindsPath("/MixedFramework/CollisionsWithDifferentKinds", in: tree, asSymbolID: "s:14MixedFramework28CollisionsWithDifferentKindsO") + try assertFindsPath("/MixedFramework/CollisionsWithDifferentKinds/something-enum.case", in: tree, asSymbolID: "s:14MixedFramework28CollisionsWithDifferentKindsO9somethingyA2CmF") + try assertFindsPath("/MixedFramework/CollisionsWithDifferentKinds/something-property", in: tree, asSymbolID: "s:14MixedFramework28CollisionsWithDifferentKindsO9somethingSSvp") + try assertFindsPath("/MixedFramework/CollisionsWithDifferentKinds/Something", in: tree, asSymbolID: "s:14MixedFramework28CollisionsWithDifferentKindsO9Somethinga") + + // public final class CollisionsWithEscapedKeywords { + // public subscript() -> Int { 0 } + // public func `subscript`() { } + // public static func `subscript`() { } + // + // public init() { } + // public func `init`() { } + // public static func `init`() { } + // } + try assertFindsPath("/MixedFramework/CollisionsWithEscapedKeywords", in: tree, asSymbolID: "s:14MixedFramework29CollisionsWithEscapedKeywordsC") + try assertFindsPath("/MixedFramework/CollisionsWithEscapedKeywords/init()-init", in: tree, asSymbolID: "s:14MixedFramework29CollisionsWithEscapedKeywordsCACycfc") + try assertFindsPath("/MixedFramework/CollisionsWithEscapedKeywords/init()-method", in: tree, asSymbolID: "s:14MixedFramework29CollisionsWithEscapedKeywordsC4inityyF") + try assertFindsPath("/MixedFramework/CollisionsWithEscapedKeywords/init()-type.method", in: tree, asSymbolID: "s:14MixedFramework29CollisionsWithEscapedKeywordsC4inityyFZ") + try assertFindsPath("/MixedFramework/CollisionsWithEscapedKeywords/subscript()-subscript", in: tree, asSymbolID: "s:14MixedFramework29CollisionsWithEscapedKeywordsCSiycip") + try assertFindsPath("/MixedFramework/CollisionsWithEscapedKeywords/subscript()-method", in: tree, asSymbolID: "s:14MixedFramework29CollisionsWithEscapedKeywordsC9subscriptyyF") + try assertFindsPath("/MixedFramework/CollisionsWithEscapedKeywords/subscript()-type.method", in: tree, asSymbolID: "s:14MixedFramework29CollisionsWithEscapedKeywordsC9subscriptyyFZ") + + // public enum CollisionsWithDifferentFunctionArguments { + // public func something(argument: Int) -> Int { 0 } + // public func something(argument: String) -> Int { 0 } + // } + try assertFindsPath("/MixedFramework/CollisionsWithDifferentFunctionArguments", in: tree, asSymbolID: "s:14MixedFramework40CollisionsWithDifferentFunctionArgumentsO") + try assertFindsPath("/MixedFramework/CollisionsWithDifferentFunctionArguments/something(argument:)-1cyvp", in: tree, asSymbolID: "s:14MixedFramework40CollisionsWithDifferentFunctionArgumentsO9something8argumentS2i_tF") + try assertFindsPath("/MixedFramework/CollisionsWithDifferentFunctionArguments/something(argument:)-2vke2", in: tree, asSymbolID: "s:14MixedFramework40CollisionsWithDifferentFunctionArgumentsO9something8argumentSiSS_tF") + + // public enum CollisionsWithDifferentSubscriptArguments { + // public subscript(something: Int) -> Int { 0 } + // public subscript(somethingElse: String) -> Int { 0 } + // } + try assertFindsPath("/MixedFramework/CollisionsWithDifferentSubscriptArguments", in: tree, asSymbolID: "s:14MixedFramework41CollisionsWithDifferentSubscriptArgumentsO") + try assertFindsPath("/MixedFramework/CollisionsWithDifferentSubscriptArguments/subscript(_:)-4fd0l", in: tree, asSymbolID: "s:14MixedFramework41CollisionsWithDifferentSubscriptArgumentsOyS2icip") + try assertFindsPath("/MixedFramework/CollisionsWithDifferentSubscriptArguments/subscript(_:)-757cj", in: tree, asSymbolID: "s:14MixedFramework41CollisionsWithDifferentSubscriptArgumentsOySiSScip") + + // @objc(MySwiftClassObjectiveCName) + // public class MySwiftClassSwiftName: NSObject { + // @objc(myPropertyObjectiveCName) + // public var myPropertySwiftName: Int { 0 } + // + // @objc(myMethodObjectiveCName) + // public func myMethodSwiftName() -> Int { 0 } + // } + try assertFindsPath("/MixedFramework/MySwiftClassSwiftName", in: tree, asSymbolID: "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName") + try assertFindsPath("/MixedFramework/MySwiftClassSwiftName/myPropertySwiftName", in: tree, asSymbolID: "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName(py)myPropertyObjectiveCName") + try assertFindsPath("/MixedFramework/MySwiftClassSwiftName/myMethodSwiftName()", in: tree, asSymbolID: "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName(im)myMethodObjectiveCName") + try assertPathNotFound("/MixedFramework/MySwiftClassObjectiveCName/myPropertySwiftName", in: tree) + try assertPathNotFound("/MixedFramework/MySwiftClassObjectiveCName/myMethodSwiftName()", in: tree) + + try assertFindsPath("/MixedFramework/MySwiftClassObjectiveCName", in: tree, asSymbolID: "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName") + try assertFindsPath("/MixedFramework/MySwiftClassObjectiveCName/myPropertyObjectiveCName", in: tree, asSymbolID: "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName(py)myPropertyObjectiveCName") + try assertFindsPath("/MixedFramework/MySwiftClassObjectiveCName/myMethodObjectiveCName", in: tree, asSymbolID: "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName(im)myMethodObjectiveCName") + try assertPathNotFound("/MixedFramework/MySwiftClassSwiftName/myPropertyObjectiveCName", in: tree) + try assertPathNotFound("/MixedFramework/MySwiftClassSwiftName/myMethoObjectiveCName", in: tree) + + // NS_SWIFT_NAME(MyObjectiveCClassSwiftName) + // @interface MyObjectiveCClassObjectiveCName : NSObject + // + // @property (copy, readonly) NSString * myPropertyObjectiveCName NS_SWIFT_NAME(myPropertySwiftName); + // + // - (void)myMethodObjectiveCName NS_SWIFT_NAME(myMethodSwiftName()); + // - (void)myMethodWithArgument:(NSString *)argument NS_SWIFT_NAME(myMethod(argument:)); + // + // @end + try assertFindsPath("/MixedFramework/MyObjectiveCClassSwiftName", in: tree, asSymbolID: "c:objc(cs)MyObjectiveCClassObjectiveCName") + try assertFindsPath("/MixedFramework/MyObjectiveCClassSwiftName/myPropertySwiftName", in: tree, asSymbolID: "c:objc(cs)MyObjectiveCClassObjectiveCName(py)myPropertyObjectiveCName") + try assertFindsPath("/MixedFramework/MyObjectiveCClassSwiftName/myMethodSwiftName()", in: tree, asSymbolID: "c:objc(cs)MyObjectiveCClassObjectiveCName(im)myMethodObjectiveCName") + try assertFindsPath("/MixedFramework/MyObjectiveCClassSwiftName/myMethod(argument:)", in: tree, asSymbolID: "c:objc(cs)MyObjectiveCClassObjectiveCName(im)myMethodWithArgument:") + + try assertFindsPath("/MixedFramework/MyObjectiveCClassObjectiveCName", in: tree, asSymbolID: "c:objc(cs)MyObjectiveCClassObjectiveCName") + try assertFindsPath("/MixedFramework/MyObjectiveCClassObjectiveCName/myPropertyObjectiveCName", in: tree, asSymbolID: "c:objc(cs)MyObjectiveCClassObjectiveCName(py)myPropertyObjectiveCName") + try assertFindsPath("/MixedFramework/MyObjectiveCClassObjectiveCName/myMethodObjectiveCName", in: tree, asSymbolID: "c:objc(cs)MyObjectiveCClassObjectiveCName(im)myMethodObjectiveCName") + try assertFindsPath("/MixedFramework/MyObjectiveCClassObjectiveCName/myMethodWithArgument:", in: tree, asSymbolID: "c:objc(cs)MyObjectiveCClassObjectiveCName(im)myMethodWithArgument:") + + // typedef NS_ENUM(NSInteger, MyObjectiveCEnum) { + // MyObjectiveCEnumFirst, + // MyObjectiveCEnumSecond NS_SWIFT_NAME(secondCaseSwiftName) + // }; + try assertFindsPath("/MixedFramework/MyObjectiveCEnum", in: tree, asSymbolID: "c:@E@MyObjectiveCEnum") + try assertFindsPath("/MixedFramework/MyObjectiveCEnum/MyObjectiveCEnumFirst", in: tree, asSymbolID: "c:@E@MyObjectiveCEnum@MyObjectiveCEnumFirst") + try assertFindsPath("/MixedFramework/MyObjectiveCEnum/first", in: tree, asSymbolID: "c:@E@MyObjectiveCEnum@MyObjectiveCEnumFirst") + try assertFindsPath("/MixedFramework/MyObjectiveCEnum/MyObjectiveCEnumSecond", in: tree, asSymbolID: "c:@E@MyObjectiveCEnum@MyObjectiveCEnumSecond") + try assertFindsPath("/MixedFramework/MyObjectiveCEnum/secondCaseSwiftName", in: tree, asSymbolID: "c:@E@MyObjectiveCEnum@MyObjectiveCEnumSecond") + + // typedef NS_ENUM(NSInteger, MyObjectiveCEnumObjectiveCName) { + // MyObjectiveCEnumObjectiveCNameFirst, + // MyObjectiveCEnumObjectiveCNameSecond NS_SWIFT_NAME(secondCaseSwiftName) + // } NS_SWIFT_NAME(MyObjectiveCEnumSwiftName); + try assertFindsPath("/MixedFramework/MyObjectiveCEnumObjectiveCName", in: tree, asSymbolID: "c:@E@MyObjectiveCEnumObjectiveCName") + try assertFindsPath("/MixedFramework/MyObjectiveCEnumObjectiveCName/MyObjectiveCEnumObjectiveCNameFirst", in: tree, asSymbolID: "c:@E@MyObjectiveCEnumObjectiveCName@MyObjectiveCEnumObjectiveCNameFirst") + try assertFindsPath("/MixedFramework/MyObjectiveCEnumObjectiveCName/MyObjectiveCEnumObjectiveCNameSecond", in: tree, asSymbolID: "c:@E@MyObjectiveCEnumObjectiveCName@MyObjectiveCEnumObjectiveCNameSecond") + try assertPathNotFound("/MixedFramework/MyObjectiveCEnumObjectiveCName/first", in: tree) + try assertPathNotFound("/MixedFramework/MyObjectiveCEnumObjectiveCName/secondCaseSwiftName", in: tree) + + try assertFindsPath("/MixedFramework/MyObjectiveCEnumSwiftName", in: tree, asSymbolID: "c:@E@MyObjectiveCEnumObjectiveCName") + try assertFindsPath("/MixedFramework/MyObjectiveCEnumSwiftName/first", in: tree, asSymbolID: "c:@E@MyObjectiveCEnumObjectiveCName@MyObjectiveCEnumObjectiveCNameFirst") + try assertFindsPath("/MixedFramework/MyObjectiveCEnumSwiftName/secondCaseSwiftName", in: tree, asSymbolID: "c:@E@MyObjectiveCEnumObjectiveCName@MyObjectiveCEnumObjectiveCNameSecond") + try assertPathNotFound("/MixedFramework/MyObjectiveCEnumSwiftName/MyObjectiveCEnumObjectiveCNameFirst", in: tree) + try assertPathNotFound("/MixedFramework/MyObjectiveCEnumSwiftName/MyObjectiveCEnumObjectiveCNameSecond", in: tree) + + // typedef NS_OPTIONS(NSInteger, MyObjectiveCOption) { + // MyObjectiveCOptionNone = 0, + // MyObjectiveCOptionFirst = 1 << 0, + // MyObjectiveCOptionSecond NS_SWIFT_NAME(secondCaseSwiftName) = 1 << 1 + // }; + try assertFindsPath("/MixedFramework/MyObjectiveCOption-enum", in: tree, asSymbolID: "c:@E@MyObjectiveCOption") + try assertFindsPath("/MixedFramework/MyObjectiveCOption-enum/MyObjectiveCOptionNone", in: tree, asSymbolID: "c:@E@MyObjectiveCOption@MyObjectiveCOptionNone") + try assertFindsPath("/MixedFramework/MyObjectiveCOption-enum/MyObjectiveCOptionFirst", in: tree, asSymbolID: "c:@E@MyObjectiveCOption@MyObjectiveCOptionFirst") + try assertFindsPath("/MixedFramework/MyObjectiveCOption-enum/MyObjectiveCOptionSecond", in: tree, asSymbolID: "c:@E@MyObjectiveCOption@MyObjectiveCOptionSecond") + + try assertFindsPath("/MixedFramework/MyObjectiveCOption-struct", in: tree, asSymbolID: "c:@E@MyObjectiveCOption") + try assertPathNotFound("/MixedFramework/MyObjectiveCOption-struct/MyObjectiveCOptionNone", in: tree) + try assertPathNotFound("/MixedFramework/MyObjectiveCOption-struct/none", in: tree) + try assertFindsPath("/MixedFramework/MyObjectiveCOption-struct/first", in: tree, asSymbolID: "c:@E@MyObjectiveCOption@MyObjectiveCOptionFirst") + try assertFindsPath("/MixedFramework/MyObjectiveCOption-struct/secondCaseSwiftName", in: tree, asSymbolID: "c:@E@MyObjectiveCOption@MyObjectiveCOptionSecond") + + // typedef NSInteger MyTypedObjectiveCEnum NS_TYPED_ENUM; + // + // MyTypedObjectiveCEnum const MyTypedObjectiveCEnumFirst; + // MyTypedObjectiveCEnum const MyTypedObjectiveCEnumSecond; + try assertFindsPath("/MixedFramework/MyTypedObjectiveCEnum-struct", in: tree, asSymbolID: "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum") + try assertFindsPath("/MixedFramework/MyTypedObjectiveCEnum-struct/first", in: tree, asSymbolID: "c:@MyTypedObjectiveCEnumFirst") + try assertFindsPath("/MixedFramework/MyTypedObjectiveCEnum-struct/second", in: tree, asSymbolID: "c:@MyTypedObjectiveCEnumSecond") + + try assertFindsPath("/MixedFramework/MyTypedObjectiveCEnum-typealias", in: tree, asSymbolID: "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum") + try assertFindsPath("/MixedFramework/MyTypedObjectiveCEnumFirst", in: tree, asSymbolID: "c:@MyTypedObjectiveCEnumFirst") + try assertFindsPath("/MixedFramework/MyTypedObjectiveCEnumSecond", in: tree, asSymbolID: "c:@MyTypedObjectiveCEnumSecond") + + // typedef NSInteger MyTypedObjectiveCExtensibleEnum NS_TYPED_EXTENSIBLE_ENUM; + // + // MyTypedObjectiveCExtensibleEnum const MyTypedObjectiveCExtensibleEnumFirst; + // MyTypedObjectiveCExtensibleEnum const MyTypedObjectiveCExtensibleEnumSecond; + try assertFindsPath("/MixedFramework/MyTypedObjectiveCExtensibleEnum-struct", in: tree, asSymbolID: "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum") + try assertFindsPath("/MixedFramework/MyTypedObjectiveCExtensibleEnum-struct/first", in: tree, asSymbolID: "c:@MyTypedObjectiveCExtensibleEnumFirst") + try assertFindsPath("/MixedFramework/MyTypedObjectiveCExtensibleEnum-struct/second", in: tree, asSymbolID: "c:@MyTypedObjectiveCExtensibleEnumSecond") + + try assertFindsPath("/MixedFramework/MyTypedObjectiveCExtensibleEnum-typealias", in: tree, asSymbolID: "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum") + try assertFindsPath("/MixedFramework/MyTypedObjectiveCExtensibleEnumFirst", in: tree, asSymbolID: "c:@MyTypedObjectiveCExtensibleEnumFirst") + try assertFindsPath("/MixedFramework/MyTypedObjectiveCExtensibleEnumSecond", in: tree, asSymbolID: "c:@MyTypedObjectiveCExtensibleEnumSecond") + } + + func testAmbiguousPaths() throws { + try XCTSkipUnless(LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver) + let (_, context) = try testBundleAndContext(named: "MixedLanguageFrameworkWithLanguageRefinements") + let tree = try XCTUnwrap(context.hierarchyBasedLinkResolver?.pathHierarchy) + + // public enum CollisionsWithDifferentKinds { + // case something + // public var something: String { "" } + // public typealias Something = Int + // } + try assertPathCollision("/MixedFramework/CollisionsWithDifferentKinds/something", in: tree, collisions: [ + (symbolID: "s:14MixedFramework28CollisionsWithDifferentKindsO9somethingyA2CmF", disambiguation: "enum.case"), + (symbolID: "s:14MixedFramework28CollisionsWithDifferentKindsO9somethingSSvp", disambiguation: "property"), + ]) + + // public final class CollisionsWithEscapedKeywords { + // public subscript() -> Int { 0 } + // public func `subscript`() { } + // public static func `subscript`() { } + // + // public init() { } + // public func `init`() { } + // public static func `init`() { } + // } + try assertPathCollision("/MixedFramework/CollisionsWithEscapedKeywords/init()", in: tree, collisions: [ + (symbolID: "s:14MixedFramework29CollisionsWithEscapedKeywordsCACycfc", disambiguation: "init"), + (symbolID: "s:14MixedFramework29CollisionsWithEscapedKeywordsC4inityyF", disambiguation: "method"), + (symbolID: "s:14MixedFramework29CollisionsWithEscapedKeywordsC4inityyFZ", disambiguation: "type.method"), + ]) + + try assertPathCollision("/MixedFramework/CollisionsWithEscapedKeywords/subscript()", in: tree, collisions: [ + (symbolID: "s:14MixedFramework29CollisionsWithEscapedKeywordsC9subscriptyyF", disambiguation: "method"), + (symbolID: "s:14MixedFramework29CollisionsWithEscapedKeywordsCSiycip", disambiguation: "subscript"), + (symbolID: "s:14MixedFramework29CollisionsWithEscapedKeywordsC9subscriptyyFZ", disambiguation: "type.method"), + ]) + + // public enum CollisionsWithDifferentFunctionArguments { + // public func something(argument: Int) -> Int { 0 } + // public func something(argument: String) -> Int { 0 } + // } + try assertPathCollision("/MixedFramework/CollisionsWithDifferentFunctionArguments/something(argument:)", in: tree, collisions: [ + (symbolID: "s:14MixedFramework40CollisionsWithDifferentFunctionArgumentsO9something8argumentS2i_tF", disambiguation: "1cyvp"), + (symbolID: "s:14MixedFramework40CollisionsWithDifferentFunctionArgumentsO9something8argumentSiSS_tF", disambiguation: "2vke2"), + ]) + + // public enum CollisionsWithDifferentSubscriptArguments { + // public subscript(something: Int) -> Int { 0 } + // public subscript(somethingElse: String) -> Int { 0 } + // } + try assertPathCollision("/MixedFramework/CollisionsWithDifferentSubscriptArguments/subscript(_:)", in: tree, collisions: [ + (symbolID: "s:14MixedFramework41CollisionsWithDifferentSubscriptArgumentsOyS2icip", disambiguation: "4fd0l"), + (symbolID: "s:14MixedFramework41CollisionsWithDifferentSubscriptArgumentsOySiSScip", disambiguation: "757cj"), + ]) + + // typedef NS_OPTIONS(NSInteger, MyObjectiveCOption) { + // MyObjectiveCOptionNone = 0, + // MyObjectiveCOptionFirst = 1 << 0, + // MyObjectiveCOptionSecond NS_SWIFT_NAME(secondCaseSwiftName) = 1 << 1 + // }; + try assertFindsPath("/MixedFramework/MyObjectiveCOption", in: tree, asSymbolID: "c:@E@MyObjectiveCOption") + try assertFindsPath("/MixedFramework/MyObjectiveCOption-enum", in: tree, asSymbolID: "c:@E@MyObjectiveCOption") + try assertFindsPath("/MixedFramework/MyObjectiveCOption-struct", in: tree, asSymbolID: "c:@E@MyObjectiveCOption") + // Since both collisions are the same symbol (in different languages) it can be disambiguated as one of the values. + // + // Resolving subpaths will pick to the version of the symbol that has those descendants. + try assertFindsPath("/MixedFramework/MyObjectiveCOption/MyObjectiveCOptionNone", in: tree, asSymbolID: "c:@E@MyObjectiveCOption@MyObjectiveCOptionNone") + try assertFindsPath("/MixedFramework/MyObjectiveCOption/MyObjectiveCOptionFirst", in: tree, asSymbolID: "c:@E@MyObjectiveCOption@MyObjectiveCOptionFirst") + try assertFindsPath("/MixedFramework/MyObjectiveCOption/MyObjectiveCOptionSecond", in: tree, asSymbolID: "c:@E@MyObjectiveCOption@MyObjectiveCOptionSecond") + + try assertFindsPath("/MixedFramework/MyObjectiveCOption/first", in: tree, asSymbolID: "c:@E@MyObjectiveCOption@MyObjectiveCOptionFirst") + try assertFindsPath("/MixedFramework/MyObjectiveCOption/secondCaseSwiftName", in: tree, asSymbolID: "c:@E@MyObjectiveCOption@MyObjectiveCOptionSecond") + // Using a disambiguation suffix to pick a specific version of the symbol can only find the descendants in that language ... + try assertFindsPath("/MixedFramework/MyObjectiveCOption-enum/MyObjectiveCOptionNone", in: tree, asSymbolID: "c:@E@MyObjectiveCOption@MyObjectiveCOptionNone") + try assertFindsPath("/MixedFramework/MyObjectiveCOption-enum/MyObjectiveCOptionFirst", in: tree, asSymbolID: "c:@E@MyObjectiveCOption@MyObjectiveCOptionFirst") + try assertFindsPath("/MixedFramework/MyObjectiveCOption-enum/MyObjectiveCOptionSecond", in: tree, asSymbolID: "c:@E@MyObjectiveCOption@MyObjectiveCOptionSecond") + + try assertFindsPath("/MixedFramework/MyObjectiveCOption-struct/first", in: tree, asSymbolID: "c:@E@MyObjectiveCOption@MyObjectiveCOptionFirst") + try assertFindsPath("/MixedFramework/MyObjectiveCOption-struct/secondCaseSwiftName", in: tree, asSymbolID: "c:@E@MyObjectiveCOption@MyObjectiveCOptionSecond") + // ... but not the descendants in the other language. + try assertPathNotFound("/MixedFramework/MyObjectiveCOption-struct/MyObjectiveCOptionNone", in: tree) + try assertPathNotFound("/MixedFramework/MyObjectiveCOption-struct/MyObjectiveCOptionFirst", in: tree) + try assertPathNotFound("/MixedFramework/MyObjectiveCOption-struct/MyObjectiveCOptionSecond", in: tree) + + try assertPathNotFound("/MixedFramework/MyObjectiveCOption-enum/first", in: tree) + try assertPathNotFound("/MixedFramework/MyObjectiveCOption-enum/secondCaseSwiftName", in: tree) + + // typedef NSInteger MyTypedObjectiveCEnum NS_TYPED_ENUM; + // + // MyTypedObjectiveCEnum const MyTypedObjectiveCEnumFirst; + // MyTypedObjectiveCEnum const MyTypedObjectiveCEnumSecond; + try assertFindsPath("/MixedFramework/MyTypedObjectiveCEnum", in: tree, asSymbolID: "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum") + try assertFindsPath("/MixedFramework/MyTypedObjectiveCEnum-struct", in: tree, asSymbolID: "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum") + try assertFindsPath("/MixedFramework/MyTypedObjectiveCEnum-typealias", in: tree, asSymbolID: "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum") + // Since both collisions are the same symbol (in different languages) it can be disambiguated as one of the values. + // + // Resolving subpaths will pick to the version of the symbol that has those descendants. + try assertFindsPath("/MixedFramework/MyTypedObjectiveCEnum/first", in: tree, asSymbolID: "c:@MyTypedObjectiveCEnumFirst") + try assertFindsPath("/MixedFramework/MyTypedObjectiveCEnum/second", in: tree, asSymbolID: "c:@MyTypedObjectiveCEnumSecond") + + try assertFindsPath("/MixedFramework/MyTypedObjectiveCEnumFirst", in: tree, asSymbolID: "c:@MyTypedObjectiveCEnumFirst") + try assertFindsPath("/MixedFramework/MyTypedObjectiveCEnumSecond", in: tree, asSymbolID: "c:@MyTypedObjectiveCEnumSecond") + // Using a disambiguation suffix to pick a specific version of the symbol can only find the descendants in that language ... + try assertFindsPath("/MixedFramework/MyTypedObjectiveCEnum-struct/first", in: tree, asSymbolID: "c:@MyTypedObjectiveCEnumFirst") + try assertFindsPath("/MixedFramework/MyTypedObjectiveCEnum-struct/second", in: tree, asSymbolID: "c:@MyTypedObjectiveCEnumSecond") + // ... but not the descendants in the other language. + try assertPathNotFound("MixedFramework/MyTypedObjectiveCEnum-typealias/first", in: tree) + try assertPathNotFound("MixedFramework/MyTypedObjectiveCEnum-typealias/second", in: tree) + + // typedef NSInteger MyTypedObjectiveCExtensibleEnum NS_TYPED_EXTENSIBLE_ENUM; + // + // MyTypedObjectiveCExtensibleEnum const MyTypedObjectiveCExtensibleEnumFirst; + // MyTypedObjectiveCExtensibleEnum const MyTypedObjectiveCExtensibleEnumSecond; + try assertFindsPath("/MixedFramework/MyTypedObjectiveCExtensibleEnum", in: tree, asSymbolID: "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum") + try assertFindsPath("/MixedFramework/MyTypedObjectiveCExtensibleEnum-struct", in: tree, asSymbolID: "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum") + try assertFindsPath("/MixedFramework/MyTypedObjectiveCExtensibleEnum-typealias", in: tree, asSymbolID: "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum") + // Since both collisions are the same symbol (in different languages) it can be disambiguated as one of the values. + // + // Resolving subpaths will pick to the version of the symbol that has those descendants. + try assertFindsPath("/MixedFramework/MyTypedObjectiveCExtensibleEnum/first", in: tree, asSymbolID: "c:@MyTypedObjectiveCExtensibleEnumFirst") + try assertFindsPath("/MixedFramework/MyTypedObjectiveCExtensibleEnum/second", in: tree, asSymbolID: "c:@MyTypedObjectiveCExtensibleEnumSecond") + + try assertFindsPath("/MixedFramework/MyTypedObjectiveCExtensibleEnumFirst", in: tree, asSymbolID: "c:@MyTypedObjectiveCExtensibleEnumFirst") + try assertFindsPath("/MixedFramework/MyTypedObjectiveCExtensibleEnumSecond", in: tree, asSymbolID: "c:@MyTypedObjectiveCExtensibleEnumSecond") + // Using a disambiguation suffix to pick a specific version of the symbol can only find the descendants in that language ... + try assertFindsPath("/MixedFramework/MyTypedObjectiveCExtensibleEnum-struct/first", in: tree, asSymbolID: "c:@MyTypedObjectiveCExtensibleEnumFirst") + try assertFindsPath("/MixedFramework/MyTypedObjectiveCExtensibleEnum-struct/second", in: tree, asSymbolID: "c:@MyTypedObjectiveCExtensibleEnumSecond") + // ... but not the descendants in the other language. + try assertPathNotFound("MixedFramework/MyTypedObjectiveCExtensibleEnum-typealias/first", in: tree) + try assertPathNotFound("MixedFramework/MyTypedObjectiveCExtensibleEnum-typealias/second", in: tree) + } + + func testRedundantKindDisambiguation() throws { + try XCTSkipUnless(LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver) + let (_, context) = try testBundleAndContext(named: "MixedLanguageFrameworkWithLanguageRefinements") + let tree = try XCTUnwrap(context.hierarchyBasedLinkResolver?.pathHierarchy) + + try assertFindsPath("/MixedFramework-module", in: tree, asSymbolID: "MixedFramework") + + // @objc public enum MyEnum: Int { + // case firstCase + // case secondCase + // public func myEnumFunction() { } + // public typealias MyEnumTypeAlias = Int + // public var myEnumProperty: MyEnumTypeAlias { 0 } + // } + try assertFindsPath("/MixedFramework-module/MyEnum-enum", in: tree, asSymbolID: "c:@M@MixedFramework@E@MyEnum") + try assertFindsPath("/MixedFramework-module/MyEnum-enum/firstCase-enum.case", in: tree, asSymbolID: "c:@M@MixedFramework@E@MyEnum@MyEnumFirstCase") + try assertFindsPath("/MixedFramework-module/MyEnum-enum/secondCase-enum.case", in: tree, asSymbolID: "c:@M@MixedFramework@E@MyEnum@MyEnumSecondCase") + try assertFindsPath("/MixedFramework-module/MyEnum-enum/myEnumFunction()-method", in: tree, asSymbolID: "s:14MixedFramework6MyEnumO02myD8FunctionyyF") + try assertFindsPath("/MixedFramework-module/MyEnum-enum/MyEnumTypeAlias-typealias", in: tree, asSymbolID: "s:14MixedFramework6MyEnumO0cD9TypeAliasa") + try assertFindsPath("/MixedFramework-module/MyEnum-enum/myEnumProperty-property", in: tree, asSymbolID: "s:14MixedFramework6MyEnumO02myD8PropertySivp") + + // public struct MyStruct { + // public func myStructFunction() { } + // public typealias MyStructTypeAlias = Int + // public var myStructProperty: MyStructTypeAlias { 0 } + // public static var myStructTypeProperty: MyStructTypeAlias { 0 } + // } + try assertFindsPath("/MixedFramework-module/MyStruct-struct", in: tree, asSymbolID: "s:14MixedFramework8MyStructV") + try assertFindsPath("/MixedFramework-module/MyStruct-struct/myStructFunction()-method", in: tree, asSymbolID: "s:14MixedFramework8MyStructV02myD8FunctionyyF") + try assertFindsPath("/MixedFramework-module/MyStruct-struct/MyStructTypeAlias-typealias", in: tree, asSymbolID: "s:14MixedFramework8MyStructV0cD9TypeAliasa") + try assertFindsPath("/MixedFramework-module/MyStruct-struct/myStructProperty-property", in: tree, asSymbolID: "s:14MixedFramework8MyStructV02myD8PropertySivp") + try assertFindsPath("/MixedFramework-module/MyStruct-struct/myStructTypeProperty-type.property", in: tree, asSymbolID: "s:14MixedFramework8MyStructV02myD12TypePropertySivpZ") + + // public protocol MySwiftProtocol { + // func myProtocolMethod() + // associatedtype MyProtocolAssociatedType + // typealias MyProtocolTypeAlias = MyStruct + // var myProtocolProperty: MyProtocolAssociatedType { get } + // static var myProtocolTypeProperty: MyProtocolAssociatedType { get } + // } + try assertFindsPath("/MixedFramework-module/MySwiftProtocol-protocol", in: tree, asSymbolID: "s:14MixedFramework15MySwiftProtocolP") + try assertFindsPath("/MixedFramework-module/MySwiftProtocol-protocol/myProtocolMethod()-method", in: tree, asSymbolID: "s:14MixedFramework15MySwiftProtocolP02myE6MethodyyF") + try assertFindsPath("/MixedFramework-module/MySwiftProtocol-protocol/MyProtocolAssociatedType-associatedtype", in: tree, asSymbolID: "s:14MixedFramework15MySwiftProtocolP0cE14AssociatedTypeQa") + try assertFindsPath("/MixedFramework-module/MySwiftProtocol-protocol/MyProtocolTypeAlias-typealias", in: tree, asSymbolID: "s:14MixedFramework15MySwiftProtocolP0cE9TypeAliasa") + try assertFindsPath("/MixedFramework-module/MySwiftProtocol-protocol/myProtocolProperty-property", in: tree, asSymbolID: "s:14MixedFramework15MySwiftProtocolP02myE8Property0cE14AssociatedTypeQzvp") + try assertFindsPath("/MixedFramework-module/MySwiftProtocol-protocol/myProtocolTypeProperty-type.property", in: tree, asSymbolID: "s:14MixedFramework15MySwiftProtocolP02myE12TypeProperty0ce10AssociatedG0QzvpZ") + + // public func myTopLevelFunction() { } + // public var myTopLevelVariable = true + try assertFindsPath("/MixedFramework/myTopLevelFunction()-func", in: tree, asSymbolID: "s:14MixedFramework18myTopLevelFunctionyyF") + try assertFindsPath("/MixedFramework/myTopLevelVariable-var", in: tree, asSymbolID: "s:14MixedFramework18myTopLevelVariableSbvp") + } + + func testBothRedundantDisambiguations() throws { + try XCTSkipUnless(LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver) + let (_, context) = try testBundleAndContext(named: "MixedLanguageFrameworkWithLanguageRefinements") + let tree = try XCTUnwrap(context.hierarchyBasedLinkResolver?.pathHierarchy) + + try assertFindsPath("/MixedFramework-module-9r7pl", in: tree, asSymbolID: "MixedFramework") + + // @objc public enum MyEnum: Int { + // case firstCase + // case secondCase + // public func myEnumFunction() { } + // public typealias MyEnumTypeAlias = Int + // public var myEnumProperty: MyEnumTypeAlias { 0 } + // } + try assertFindsPath("/MixedFramework-module-9r7pl/MyEnum-enum-1m96o", in: tree, asSymbolID: "c:@M@MixedFramework@E@MyEnum") + try assertFindsPath("/MixedFramework-module-9r7pl/MyEnum-enum-1m96o/firstCase-enum.case-5ocr4", in: tree, asSymbolID: "c:@M@MixedFramework@E@MyEnum@MyEnumFirstCase") + try assertFindsPath("/MixedFramework-module-9r7pl/MyEnum-enum-1m96o/secondCase-enum.case-ihyt", in: tree, asSymbolID: "c:@M@MixedFramework@E@MyEnum@MyEnumSecondCase") + try assertFindsPath("/MixedFramework-module-9r7pl/MyEnum-enum-1m96o/myEnumFunction()-method-2pa9q", in: tree, asSymbolID: "s:14MixedFramework6MyEnumO02myD8FunctionyyF") + try assertFindsPath("/MixedFramework-module-9r7pl/MyEnum-enum-1m96o/MyEnumTypeAlias-typealias-5ejt4", in: tree, asSymbolID: "s:14MixedFramework6MyEnumO0cD9TypeAliasa") + try assertFindsPath("/MixedFramework-module-9r7pl/MyEnum-enum-1m96o/myEnumProperty-property-6cz2q", in: tree, asSymbolID: "s:14MixedFramework6MyEnumO02myD8PropertySivp") + + // public struct MyStruct { + // public func myStructFunction() { } + // public typealias MyStructTypeAlias = Int + // public var myStructProperty: MyStructTypeAlias { 0 } + // public static var myStructTypeProperty: MyStructTypeAlias { 0 } + // } + try assertFindsPath("/MixedFramework-module-9r7pl/MyStruct-struct-23xcd", in: tree, asSymbolID: "s:14MixedFramework8MyStructV") + try assertFindsPath("/MixedFramework-module-9r7pl/MyStruct-struct-23xcd/myStructFunction()-method-9p92r", in: tree, asSymbolID: "s:14MixedFramework8MyStructV02myD8FunctionyyF") + try assertFindsPath("/MixedFramework-module-9r7pl/MyStruct-struct-23xcd/MyStructTypeAlias-typealias-630hf", in: tree, asSymbolID: "s:14MixedFramework8MyStructV0cD9TypeAliasa") + try assertFindsPath("/MixedFramework-module-9r7pl/MyStruct-struct-23xcd/myStructProperty-property-5ywbx", in: tree, asSymbolID: "s:14MixedFramework8MyStructV02myD8PropertySivp") + try assertFindsPath("/MixedFramework-module-9r7pl/MyStruct-struct-23xcd/myStructTypeProperty-type.property-8ti6m", in: tree, asSymbolID: "s:14MixedFramework8MyStructV02myD12TypePropertySivpZ") + + // public protocol MySwiftProtocol { + // func myProtocolMethod() + // associatedtype MyProtocolAssociatedType + // typealias MyProtocolTypeAlias = MyStruct + // var myProtocolProperty: MyProtocolAssociatedType { get } + // static var myProtocolTypeProperty: MyProtocolAssociatedType { get } + // } + try assertFindsPath("/MixedFramework-module-9r7pl/MySwiftProtocol-protocol-xmee", in: tree, asSymbolID: "s:14MixedFramework15MySwiftProtocolP") + try assertFindsPath("/MixedFramework-module-9r7pl/MySwiftProtocol-protocol-xmee/myProtocolMethod()-method-6srz6", in: tree, asSymbolID: "s:14MixedFramework15MySwiftProtocolP02myE6MethodyyF") + try assertFindsPath("/MixedFramework-module-9r7pl/MySwiftProtocol-protocol-xmee/MyProtocolAssociatedType-associatedtype-33siz", in: tree, asSymbolID: "s:14MixedFramework15MySwiftProtocolP0cE14AssociatedTypeQa") + try assertFindsPath("/MixedFramework-module-9r7pl/MySwiftProtocol-protocol-xmee/MyProtocolTypeAlias-typealias-9rpv6", in: tree, asSymbolID: "s:14MixedFramework15MySwiftProtocolP0cE9TypeAliasa") + try assertFindsPath("/MixedFramework-module-9r7pl/MySwiftProtocol-protocol-xmee/myProtocolProperty-property-qer2", in: tree, asSymbolID: "s:14MixedFramework15MySwiftProtocolP02myE8Property0cE14AssociatedTypeQzvp") + try assertFindsPath("/MixedFramework-module-9r7pl/MySwiftProtocol-protocol-xmee/myProtocolTypeProperty-type.property-8h7hm", in: tree, asSymbolID: "s:14MixedFramework15MySwiftProtocolP02myE12TypeProperty0ce10AssociatedG0QzvpZ") + + // public func myTopLevelFunction() { } + // public var myTopLevelVariable = true + try assertFindsPath("/MixedFramework-module-9r7pl/myTopLevelFunction()-func-55lhl", in: tree, asSymbolID: "s:14MixedFramework18myTopLevelFunctionyyF") + try assertFindsPath("/MixedFramework-module-9r7pl/myTopLevelVariable-var-520ez", in: tree, asSymbolID: "s:14MixedFramework18myTopLevelVariableSbvp") + } + + func testDisambiguatedPaths() throws { + try XCTSkipUnless(LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver) + let (_, context) = try testBundleAndContext(named: "MixedLanguageFrameworkWithLanguageRefinements") + let tree = try XCTUnwrap(context.hierarchyBasedLinkResolver?.pathHierarchy) + + let paths = tree.caseInsensitiveDisambiguatedPaths() + // @objc public enum MyEnum: Int { + // case firstCase + // case secondCase + // public func myEnumFunction() { } + // public typealias MyEnumTypeAlias = Int + // public var myEnumProperty: MyEnumTypeAlias { 0 } + // } + XCTAssertEqual( + paths["c:@M@MixedFramework@E@MyEnum"], + "/MixedFramework/MyEnum") + XCTAssertEqual( + paths["s:SQsE2neoiySbx_xtFZ::SYNTHESIZED::c:@M@MixedFramework@E@MyEnum"], + "/MixedFramework/MyEnum/!=(_:_:)") + XCTAssertEqual( + paths["c:@M@MixedFramework@E@MyEnum@MyEnumFirstCase"], + "/MixedFramework/MyEnum/firstCase") + XCTAssertEqual( + paths["s:SYsSHRzSH8RawValueSYRpzrlE4hash4intoys6HasherVz_tF::SYNTHESIZED::c:@M@MixedFramework@E@MyEnum"], + "/MixedFramework/MyEnum/hash(into:)") + XCTAssertEqual( + paths["s:SYsSHRzSH8RawValueSYRpzrlE04hashB0Sivp::SYNTHESIZED::c:@M@MixedFramework@E@MyEnum"], + "/MixedFramework/MyEnum/hashValue") + XCTAssertEqual( + paths["s:14MixedFramework6MyEnumO8rawValueACSgSi_tcfc"], + "/MixedFramework/MyEnum/init(rawValue:)") + XCTAssertEqual( + paths["s:14MixedFramework6MyEnumO02myD8FunctionyyF"], + "/MixedFramework/MyEnum/myEnumFunction()") + XCTAssertEqual( + paths["s:14MixedFramework6MyEnumO02myD8PropertySivp"], + "/MixedFramework/MyEnum/myEnumProperty") + XCTAssertEqual( + paths["c:@M@MixedFramework@E@MyEnum@MyEnumSecondCase"], + "/MixedFramework/MyEnum/secondCase") + XCTAssertEqual( + paths["s:14MixedFramework6MyEnumO0cD9TypeAliasa"], + "/MixedFramework/MyEnum/MyEnumTypeAlias") + + // public final class CollisionsWithDifferentCapitalization { + // public var something: Int = 0 + // public var someThing: Int = 0 + // } + XCTAssertEqual( + paths["s:14MixedFramework37CollisionsWithDifferentCapitalizationC9somethingSivp"], + "/MixedFramework/CollisionsWithDifferentCapitalization/something-2c4k6") + XCTAssertEqual( + paths["s:14MixedFramework37CollisionsWithDifferentCapitalizationC9someThingSivp"], + "/MixedFramework/CollisionsWithDifferentCapitalization/someThing-90i4h") + + // public enum CollisionsWithDifferentKinds { + // case something + // public var something: String { "" } + // public typealias Something = Int + // } + XCTAssertEqual( + paths["s:14MixedFramework28CollisionsWithDifferentKindsO9somethingyA2CmF"], + "/MixedFramework/CollisionsWithDifferentKinds/something-enum.case") + XCTAssertEqual( + paths["s:14MixedFramework28CollisionsWithDifferentKindsO9somethingSSvp"], + "/MixedFramework/CollisionsWithDifferentKinds/something-property") + XCTAssertEqual( + paths["s:14MixedFramework28CollisionsWithDifferentKindsO9Somethinga"], + "/MixedFramework/CollisionsWithDifferentKinds/Something-typealias") + + // public final class CollisionsWithEscapedKeywords { + // public subscript() -> Int { 0 } + // public func `subscript`() { } + // public static func `subscript`() { } + // + // public init() { } + // public func `init`() { } + // public static func `init`() { } + // } + XCTAssertEqual( + paths["s:14MixedFramework29CollisionsWithEscapedKeywordsC9subscriptyyF"], + "/MixedFramework/CollisionsWithEscapedKeywords/subscript()-method") + XCTAssertEqual( + paths["s:14MixedFramework29CollisionsWithEscapedKeywordsCSiycip"], + "/MixedFramework/CollisionsWithEscapedKeywords/subscript()-subscript") + XCTAssertEqual( + paths["s:14MixedFramework29CollisionsWithEscapedKeywordsC9subscriptyyFZ"], + "/MixedFramework/CollisionsWithEscapedKeywords/subscript()-type.method") + + XCTAssertEqual( + paths["s:14MixedFramework29CollisionsWithEscapedKeywordsCACycfc"], + "/MixedFramework/CollisionsWithEscapedKeywords/init()-init") + XCTAssertEqual( + paths["s:14MixedFramework29CollisionsWithEscapedKeywordsC4inityyF"], + "/MixedFramework/CollisionsWithEscapedKeywords/init()-method") + XCTAssertEqual( + paths["s:14MixedFramework29CollisionsWithEscapedKeywordsC4inityyFZ"], + "/MixedFramework/CollisionsWithEscapedKeywords/init()-type.method") + + // public enum CollisionsWithDifferentFunctionArguments { + // public func something(argument: Int) -> Int { 0 } + // public func something(argument: String) -> Int { 0 } + // } + XCTAssertEqual( + paths["s:14MixedFramework40CollisionsWithDifferentFunctionArgumentsO9something8argumentS2i_tF"], + "/MixedFramework/CollisionsWithDifferentFunctionArguments/something(argument:)-1cyvp") + XCTAssertEqual( + paths["s:14MixedFramework40CollisionsWithDifferentFunctionArgumentsO9something8argumentSiSS_tF"], + "/MixedFramework/CollisionsWithDifferentFunctionArguments/something(argument:)-2vke2") + + // public enum CollisionsWithDifferentSubscriptArguments { + // public subscript(something: Int) -> Int { 0 } + // public subscript(somethingElse: String) -> Int { 0 } + // } + XCTAssertEqual( + paths["s:14MixedFramework41CollisionsWithDifferentSubscriptArgumentsOyS2icip"], + "/MixedFramework/CollisionsWithDifferentSubscriptArguments/subscript(_:)-4fd0l") + XCTAssertEqual( + paths["s:14MixedFramework41CollisionsWithDifferentSubscriptArgumentsOySiSScip"], + "/MixedFramework/CollisionsWithDifferentSubscriptArguments/subscript(_:)-757cj") + } + + func testFindingRelativePaths() throws { + try XCTSkipUnless(LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver) + let (_, context) = try testBundleAndContext(named: "MixedLanguageFrameworkWithLanguageRefinements") + let tree = try XCTUnwrap(context.hierarchyBasedLinkResolver?.pathHierarchy) + + let moduleID = try tree.find(path: "/MixedFramework", onlyFindSymbols: true) + + // @objc public enum MyEnum: Int { + // case firstCase + // case secondCase + // public func myEnumFunction() { } + // public typealias MyEnumTypeAlias = Int + // public var myEnumProperty: MyEnumTypeAlias { 0 } + // } + // + // public struct MyStruct { + // public func myStructFunction() { } + // public typealias MyStructTypeAlias = Int + // public var myStructProperty: MyStructTypeAlias { 0 } + // public static var myStructTypeProperty: MyStructTypeAlias { 0 } + // } + let myEnumID = try tree.find(path: "MyEnum", parent: moduleID, onlyFindSymbols: true) + XCTAssertEqual(try tree.findSymbol(path: "firstCase", parent: myEnumID).identifier.precise, "c:@M@MixedFramework@E@MyEnum@MyEnumFirstCase") + XCTAssertEqual(try tree.findSymbol(path: "secondCase", parent: myEnumID).identifier.precise, "c:@M@MixedFramework@E@MyEnum@MyEnumSecondCase") + XCTAssertEqual(try tree.findSymbol(path: "myEnumFunction()", parent: myEnumID).identifier.precise, "s:14MixedFramework6MyEnumO02myD8FunctionyyF") + XCTAssertEqual(try tree.findSymbol(path: "MyEnumTypeAlias", parent: myEnumID).identifier.precise, "s:14MixedFramework6MyEnumO0cD9TypeAliasa") + XCTAssertEqual(try tree.findSymbol(path: "myEnumProperty", parent: myEnumID).identifier.precise, "s:14MixedFramework6MyEnumO02myD8PropertySivp") + + let myStructID = try tree.find(path: "MyStruct", parent: moduleID, onlyFindSymbols: true) + XCTAssertEqual(try tree.findSymbol(path: "myStructFunction()", parent: myStructID).identifier.precise, "s:14MixedFramework8MyStructV02myD8FunctionyyF") + XCTAssertEqual(try tree.findSymbol(path: "MyStructTypeAlias", parent: myStructID).identifier.precise, "s:14MixedFramework8MyStructV0cD9TypeAliasa") + XCTAssertEqual(try tree.findSymbol(path: "myStructProperty", parent: myStructID).identifier.precise, "s:14MixedFramework8MyStructV02myD8PropertySivp") + XCTAssertEqual(try tree.findSymbol(path: "myStructTypeProperty", parent: myStructID).identifier.precise, "s:14MixedFramework8MyStructV02myD12TypePropertySivpZ") + + // Resolve symbols with the same parent + let myFirstCaseID = try tree.find(path: "firstCase", parent: myEnumID, onlyFindSymbols: true) + XCTAssertEqual(try tree.findSymbol(path: "firstCase", parent: myFirstCaseID).identifier.precise, "c:@M@MixedFramework@E@MyEnum@MyEnumFirstCase") + XCTAssertEqual(try tree.findSymbol(path: "secondCase", parent: myFirstCaseID).identifier.precise, "c:@M@MixedFramework@E@MyEnum@MyEnumSecondCase") + XCTAssertEqual(try tree.findSymbol(path: "myEnumFunction()", parent: myFirstCaseID).identifier.precise, "s:14MixedFramework6MyEnumO02myD8FunctionyyF") + XCTAssertEqual(try tree.findSymbol(path: "MyEnumTypeAlias", parent: myFirstCaseID).identifier.precise, "s:14MixedFramework6MyEnumO0cD9TypeAliasa") + XCTAssertEqual(try tree.findSymbol(path: "myEnumProperty", parent: myFirstCaseID).identifier.precise, "s:14MixedFramework6MyEnumO02myD8PropertySivp") + + let myStructFunctionID = try tree.find(path: "myStructFunction()", parent: myStructID, onlyFindSymbols: true) + XCTAssertEqual(try tree.findSymbol(path: "myStructFunction()", parent: myStructFunctionID).identifier.precise, "s:14MixedFramework8MyStructV02myD8FunctionyyF") + XCTAssertEqual(try tree.findSymbol(path: "MyStructTypeAlias", parent: myStructFunctionID).identifier.precise, "s:14MixedFramework8MyStructV0cD9TypeAliasa") + XCTAssertEqual(try tree.findSymbol(path: "myStructProperty", parent: myStructFunctionID).identifier.precise, "s:14MixedFramework8MyStructV02myD8PropertySivp") + XCTAssertEqual(try tree.findSymbol(path: "myStructTypeProperty", parent: myStructFunctionID).identifier.precise, "s:14MixedFramework8MyStructV02myD12TypePropertySivpZ") + + // Resolve symbols accessible from the parent's parent + XCTAssertEqual(try tree.findSymbol(path: "MyEnum", parent: myFirstCaseID).identifier.precise, "c:@M@MixedFramework@E@MyEnum") + XCTAssertEqual(try tree.findSymbol(path: "MyEnum/firstCase", parent: myFirstCaseID).identifier.precise, "c:@M@MixedFramework@E@MyEnum@MyEnumFirstCase") + XCTAssertEqual(try tree.findSymbol(path: "MyEnum/secondCase", parent: myFirstCaseID).identifier.precise, "c:@M@MixedFramework@E@MyEnum@MyEnumSecondCase") + XCTAssertEqual(try tree.findSymbol(path: "MyEnum/myEnumFunction()", parent: myFirstCaseID).identifier.precise, "s:14MixedFramework6MyEnumO02myD8FunctionyyF") + XCTAssertEqual(try tree.findSymbol(path: "MyEnum/MyEnumTypeAlias", parent: myFirstCaseID).identifier.precise, "s:14MixedFramework6MyEnumO0cD9TypeAliasa") + XCTAssertEqual(try tree.findSymbol(path: "MyEnum/myEnumProperty", parent: myFirstCaseID).identifier.precise, "s:14MixedFramework6MyEnumO02myD8PropertySivp") + + XCTAssertEqual(try tree.findSymbol(path: "MyStruct", parent: myFirstCaseID).identifier.precise, "s:14MixedFramework8MyStructV") + XCTAssertEqual(try tree.findSymbol(path: "MyStruct/myStructFunction()", parent: myFirstCaseID).identifier.precise, "s:14MixedFramework8MyStructV02myD8FunctionyyF") + XCTAssertEqual(try tree.findSymbol(path: "MyStruct/MyStructTypeAlias", parent: myFirstCaseID).identifier.precise, "s:14MixedFramework8MyStructV0cD9TypeAliasa") + XCTAssertEqual(try tree.findSymbol(path: "MyStruct/myStructProperty", parent: myFirstCaseID).identifier.precise, "s:14MixedFramework8MyStructV02myD8PropertySivp") + XCTAssertEqual(try tree.findSymbol(path: "MyStruct/myStructTypeProperty", parent: myFirstCaseID).identifier.precise, "s:14MixedFramework8MyStructV02myD12TypePropertySivpZ") + + XCTAssertEqual(try tree.findSymbol(path: "MyEnum", parent: myStructFunctionID).identifier.precise, "c:@M@MixedFramework@E@MyEnum") + XCTAssertEqual(try tree.findSymbol(path: "MyEnum/firstCase", parent: myStructFunctionID).identifier.precise, "c:@M@MixedFramework@E@MyEnum@MyEnumFirstCase") + XCTAssertEqual(try tree.findSymbol(path: "MyEnum/secondCase", parent: myStructFunctionID).identifier.precise, "c:@M@MixedFramework@E@MyEnum@MyEnumSecondCase") + XCTAssertEqual(try tree.findSymbol(path: "MyEnum/myEnumFunction()", parent: myStructFunctionID).identifier.precise, "s:14MixedFramework6MyEnumO02myD8FunctionyyF") + XCTAssertEqual(try tree.findSymbol(path: "MyEnum/MyEnumTypeAlias", parent: myStructFunctionID).identifier.precise, "s:14MixedFramework6MyEnumO0cD9TypeAliasa") + XCTAssertEqual(try tree.findSymbol(path: "MyEnum/myEnumProperty", parent: myStructFunctionID).identifier.precise, "s:14MixedFramework6MyEnumO02myD8PropertySivp") + + XCTAssertEqual(try tree.findSymbol(path: "MyStruct", parent: myStructFunctionID).identifier.precise, "s:14MixedFramework8MyStructV") + XCTAssertEqual(try tree.findSymbol(path: "MyStruct/myStructFunction()", parent: myStructFunctionID).identifier.precise, "s:14MixedFramework8MyStructV02myD8FunctionyyF") + XCTAssertEqual(try tree.findSymbol(path: "MyStruct/MyStructTypeAlias", parent: myStructFunctionID).identifier.precise, "s:14MixedFramework8MyStructV0cD9TypeAliasa") + XCTAssertEqual(try tree.findSymbol(path: "MyStruct/myStructProperty", parent: myStructFunctionID).identifier.precise, "s:14MixedFramework8MyStructV02myD8PropertySivp") + XCTAssertEqual(try tree.findSymbol(path: "MyStruct/myStructTypeProperty", parent: myStructFunctionID).identifier.precise, "s:14MixedFramework8MyStructV02myD12TypePropertySivpZ") + + XCTAssertEqual(try tree.findSymbol(path: "MixedFramework", parent: myFirstCaseID).identifier.precise, "MixedFramework") + XCTAssertEqual(try tree.findSymbol(path: "MixedFramework", parent: myStructFunctionID).identifier.precise, "MixedFramework") + + // All the way up and all the way down + XCTAssertEqual(try tree.findSymbol(path: "MixedFramework-module/MyEnum-enum/firstCase-enum.case", parent: myFirstCaseID).identifier.precise, "c:@M@MixedFramework@E@MyEnum@MyEnumFirstCase") + XCTAssertEqual(try tree.findSymbol(path: "MixedFramework-module/MyEnum-enum/secondCase-enum.case", parent: myFirstCaseID).identifier.precise, "c:@M@MixedFramework@E@MyEnum@MyEnumSecondCase") + XCTAssertEqual(try tree.findSymbol(path: "MixedFramework-module/MyEnum-enum/myEnumFunction()-method", parent: myFirstCaseID).identifier.precise, "s:14MixedFramework6MyEnumO02myD8FunctionyyF") + XCTAssertEqual(try tree.findSymbol(path: "MixedFramework-module/MyEnum-enum/MyEnumTypeAlias-typealias", parent: myFirstCaseID).identifier.precise, "s:14MixedFramework6MyEnumO0cD9TypeAliasa") + XCTAssertEqual(try tree.findSymbol(path: "MixedFramework-module/MyEnum-enum/myEnumProperty-property", parent: myFirstCaseID).identifier.precise, "s:14MixedFramework6MyEnumO02myD8PropertySivp") + + XCTAssertEqual(try tree.findSymbol(path: "MixedFramework-module/MyStruct-struct/myStructFunction()-method", parent: myStructFunctionID).identifier.precise, "s:14MixedFramework8MyStructV02myD8FunctionyyF") + XCTAssertEqual(try tree.findSymbol(path: "MixedFramework-module/MyStruct-struct/MyStructTypeAlias-typealias", parent: myStructFunctionID).identifier.precise, "s:14MixedFramework8MyStructV0cD9TypeAliasa") + XCTAssertEqual(try tree.findSymbol(path: "MixedFramework-module/MyStruct-struct/myStructProperty-property", parent: myStructFunctionID).identifier.precise, "s:14MixedFramework8MyStructV02myD8PropertySivp") + XCTAssertEqual(try tree.findSymbol(path: "MixedFramework-module/MyStruct-struct/myStructTypeProperty-type.property", parent: myStructFunctionID).identifier.precise, "s:14MixedFramework8MyStructV02myD12TypePropertySivpZ") + + // Absolute links + XCTAssertEqual(try tree.findSymbol(path: "/MixedFramework-module/MyEnum-enum/firstCase-enum.case", parent: myFirstCaseID).identifier.precise, "c:@M@MixedFramework@E@MyEnum@MyEnumFirstCase") + XCTAssertEqual(try tree.findSymbol(path: "/MixedFramework-module/MyEnum-enum/secondCase-enum.case", parent: myFirstCaseID).identifier.precise, "c:@M@MixedFramework@E@MyEnum@MyEnumSecondCase") + XCTAssertEqual(try tree.findSymbol(path: "/MixedFramework-module/MyEnum-enum/myEnumFunction()-method", parent: myFirstCaseID).identifier.precise, "s:14MixedFramework6MyEnumO02myD8FunctionyyF") + XCTAssertEqual(try tree.findSymbol(path: "/MixedFramework-module/MyEnum-enum/MyEnumTypeAlias-typealias", parent: myFirstCaseID).identifier.precise, "s:14MixedFramework6MyEnumO0cD9TypeAliasa") + XCTAssertEqual(try tree.findSymbol(path: "/MixedFramework-module/MyEnum-enum/myEnumProperty-property", parent: myFirstCaseID).identifier.precise, "s:14MixedFramework6MyEnumO02myD8PropertySivp") + + XCTAssertEqual(try tree.findSymbol(path: "/MixedFramework-module/MyStruct-struct/myStructFunction()-method", parent: myStructFunctionID).identifier.precise, "s:14MixedFramework8MyStructV02myD8FunctionyyF") + XCTAssertEqual(try tree.findSymbol(path: "/MixedFramework-module/MyStruct-struct/MyStructTypeAlias-typealias", parent: myStructFunctionID).identifier.precise, "s:14MixedFramework8MyStructV0cD9TypeAliasa") + XCTAssertEqual(try tree.findSymbol(path: "/MixedFramework-module/MyStruct-struct/myStructProperty-property", parent: myStructFunctionID).identifier.precise, "s:14MixedFramework8MyStructV02myD8PropertySivp") + XCTAssertEqual(try tree.findSymbol(path: "/MixedFramework-module/MyStruct-struct/myStructTypeProperty-type.property", parent: myStructFunctionID).identifier.precise, "s:14MixedFramework8MyStructV02myD12TypePropertySivpZ") + + // @objc(MySwiftClassObjectiveCName) + // public class MySwiftClassSwiftName: NSObject { + // @objc(myPropertyObjectiveCName) + // public var myPropertySwiftName: Int { 0 } + // + // @objc(myMethodObjectiveCName) + // public func myMethodSwiftName() -> Int { 0 } + // } + let mySwiftClassSwiftID = try tree.find(path: "MySwiftClassSwiftName", parent: moduleID, onlyFindSymbols: true) + XCTAssertEqual(try tree.findSymbol(path: "myPropertySwiftName", parent: mySwiftClassSwiftID).identifier.precise, "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName(py)myPropertyObjectiveCName") + XCTAssertEqual(try tree.findSymbol(path: "myMethodSwiftName()", parent: mySwiftClassSwiftID).identifier.precise, "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName(im)myMethodObjectiveCName") + XCTAssertThrowsError(try tree.findSymbol(path: "myPropertyObjectiveCName", parent: mySwiftClassSwiftID)) + XCTAssertThrowsError(try tree.findSymbol(path: "myMethodObjectiveCName", parent: mySwiftClassSwiftID)) + + let mySwiftClassObjCID = try tree.find(path: "MySwiftClassObjectiveCName", parent: moduleID, onlyFindSymbols: true) + XCTAssertEqual(try tree.findSymbol(path: "myPropertyObjectiveCName", parent: mySwiftClassObjCID).identifier.precise, "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName(py)myPropertyObjectiveCName") + XCTAssertEqual(try tree.findSymbol(path: "myMethodObjectiveCName", parent: mySwiftClassObjCID).identifier.precise, "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName(im)myMethodObjectiveCName") + XCTAssertThrowsError(try tree.findSymbol(path: "myPropertySwiftName", parent: mySwiftClassObjCID)) + XCTAssertThrowsError(try tree.findSymbol(path: "myMethodSwiftName()", parent: mySwiftClassObjCID)) + + // typedef NS_OPTIONS(NSInteger, MyObjectiveCOption) { + // MyObjectiveCOptionNone = 0, + // MyObjectiveCOptionFirst = 1 << 0, + // MyObjectiveCOptionSecond NS_SWIFT_NAME(secondCaseSwiftName) = 1 << 1 + // }; + let myOptionAsEnumID = try tree.find(path: "MyObjectiveCOption-enum", parent: moduleID, onlyFindSymbols: true) + XCTAssertEqual(try tree.findSymbol(path: "MyObjectiveCOptionNone", parent: myOptionAsEnumID).identifier.precise, "c:@E@MyObjectiveCOption@MyObjectiveCOptionNone") + XCTAssertEqual(try tree.findSymbol(path: "MyObjectiveCOptionFirst", parent: myOptionAsEnumID).identifier.precise, "c:@E@MyObjectiveCOption@MyObjectiveCOptionFirst") + XCTAssertEqual(try tree.findSymbol(path: "MyObjectiveCOptionSecond", parent: myOptionAsEnumID).identifier.precise, "c:@E@MyObjectiveCOption@MyObjectiveCOptionSecond") + XCTAssertThrowsError(try tree.findSymbol(path: "none", parent: myOptionAsEnumID)) + XCTAssertThrowsError(try tree.findSymbol(path: "first", parent: myOptionAsEnumID)) + XCTAssertThrowsError(try tree.findSymbol(path: "second", parent: myOptionAsEnumID)) + XCTAssertThrowsError(try tree.findSymbol(path: "secondCaseSwiftName", parent: myOptionAsEnumID)) + + let myOptionAsStructID = try tree.find(path: "MyObjectiveCOption-struct", parent: moduleID, onlyFindSymbols: true) + XCTAssertEqual(try tree.findSymbol(path: "first", parent: myOptionAsStructID).identifier.precise, "c:@E@MyObjectiveCOption@MyObjectiveCOptionFirst") + XCTAssertEqual(try tree.findSymbol(path: "secondCaseSwiftName", parent: myOptionAsStructID).identifier.precise, "c:@E@MyObjectiveCOption@MyObjectiveCOptionSecond") + XCTAssertThrowsError(try tree.findSymbol(path: "none", parent: myOptionAsStructID)) + XCTAssertThrowsError(try tree.findSymbol(path: "second", parent: myOptionAsStructID)) + XCTAssertThrowsError(try tree.findSymbol(path: "MyObjectiveCOptionNone", parent: myOptionAsStructID)) + XCTAssertThrowsError(try tree.findSymbol(path: "MyObjectiveCOptionFirst", parent: myOptionAsStructID)) + XCTAssertThrowsError(try tree.findSymbol(path: "MyObjectiveCOptionSecond", parent: myOptionAsStructID)) + + // typedef NSInteger MyTypedObjectiveCExtensibleEnum NS_TYPED_EXTENSIBLE_ENUM; + // + // MyTypedObjectiveCExtensibleEnum const MyTypedObjectiveCExtensibleEnumFirst; + // MyTypedObjectiveCExtensibleEnum const MyTypedObjectiveCExtensibleEnumSecond; + let myTypedExtensibleEnumID = try tree.find(path: "MyTypedObjectiveCExtensibleEnum-struct", parent: moduleID, onlyFindSymbols: true) + XCTAssertEqual(try tree.findSymbol(path: "first", parent: myTypedExtensibleEnumID).identifier.precise, "c:@MyTypedObjectiveCExtensibleEnumFirst") + XCTAssertEqual(try tree.findSymbol(path: "second", parent: myTypedExtensibleEnumID).identifier.precise, "c:@MyTypedObjectiveCExtensibleEnumSecond") + } + + func testPathWithDocumentationPrefix() throws { + try XCTSkipUnless(LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver) + let (_, context) = try testBundleAndContext(named: "MixedLanguageFrameworkWithLanguageRefinements") + let tree = try XCTUnwrap(context.hierarchyBasedLinkResolver?.pathHierarchy) + + let moduleID = try tree.find(path: "/MixedFramework", onlyFindSymbols: true) + + XCTAssertEqual(try tree.findSymbol(path: "MyEnum", parent: moduleID).identifier.precise, "c:@M@MixedFramework@E@MyEnum") + XCTAssertEqual(try tree.findSymbol(path: "MixedFramework/MyEnum", parent: moduleID).identifier.precise, "c:@M@MixedFramework@E@MyEnum") + XCTAssertEqual(try tree.findSymbol(path: "documentation/MixedFramework/MyEnum", parent: moduleID).identifier.precise, "c:@M@MixedFramework@E@MyEnum") + XCTAssertEqual(try tree.findSymbol(path: "/documentation/MixedFramework/MyEnum", parent: moduleID).identifier.precise, "c:@M@MixedFramework@E@MyEnum") + + assertParsedPathComponents("documentation/MixedFramework/MyEnum", [("documentation", nil, nil), ("MixedFramework", nil, nil), ("MyEnum", nil, nil)]) + assertParsedPathComponents("/documentation/MixedFramework/MyEnum", [("documentation", nil, nil), ("MixedFramework", nil, nil), ("MyEnum", nil, nil)]) + } + + func testTestBundle() throws { + try XCTSkipUnless(LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver) + let (bundle, context) = try testBundleAndContext(named: "TestBundle") + let linkResolver = try XCTUnwrap(context.hierarchyBasedLinkResolver) + let tree = try XCTUnwrap(linkResolver.pathHierarchy) + + // Test finding the parent via the `fromTopicReference` integration shim. + let parentID = linkResolver.resolvedReferenceMap[ResolvedTopicReference(bundleIdentifier: bundle.identifier, path: "/documentation/MyKit", sourceLanguage: .swift)]! + XCTAssertNotNil(parentID) + XCTAssertEqual(try tree.findSymbol(path: "globalFunction(_:considering:)", parent: parentID).identifier.precise, "s:5MyKit14globalFunction_11consideringy10Foundation4DataV_SitF") + XCTAssertEqual(try tree.findSymbol(path: "MyKit/globalFunction(_:considering:)", parent: parentID).identifier.precise, "s:5MyKit14globalFunction_11consideringy10Foundation4DataV_SitF") + XCTAssertEqual(try tree.findSymbol(path: "/MyKit/globalFunction(_:considering:)", parent: parentID).identifier.precise, "s:5MyKit14globalFunction_11consideringy10Foundation4DataV_SitF") + + let myKidModuleID = try tree.find(path: "/MyKit", onlyFindSymbols: true) + XCTAssertEqual(try tree.findSymbol(path: "globalFunction(_:considering:)", parent: myKidModuleID).identifier.precise, "s:5MyKit14globalFunction_11consideringy10Foundation4DataV_SitF") + XCTAssertEqual(try tree.findSymbol(path: "MyKit/globalFunction(_:considering:)", parent: myKidModuleID).identifier.precise, "s:5MyKit14globalFunction_11consideringy10Foundation4DataV_SitF") + XCTAssertEqual(try tree.findSymbol(path: "/MyKit/globalFunction(_:considering:)", parent: myKidModuleID).identifier.precise, "s:5MyKit14globalFunction_11consideringy10Foundation4DataV_SitF") + + XCTAssertEqual(try tree.findSymbol(path: "MyClass/init()-33vaw", parent: myKidModuleID).identifier.precise, "s:5MyKit0A5ClassCACycfcDUPLICATE") + + // Test finding symbol from an extension + let sideKidModuleID = try tree.find(path: "/SideKit", onlyFindSymbols: true) + XCTAssertEqual(try tree.findSymbol(path: "UncuratedClass/angle", parent: sideKidModuleID).identifier.precise, "s:So14UncuratedClassCV5MyKitE5angle12CoreGraphics7CGFloatVSgvp") + try assertFindsPath("/SideKit/SideClass/Element", in: tree, asSymbolID: "s:7SideKit0A5ClassC7Elementa") + try assertFindsPath("/SideKit/SideClass/Element/inherited()", in: tree, asSymbolID: "s:7SideKit0A5::SYNTESIZED::inheritedFF") + try assertPathCollision("/SideKit/SideProtocol/func()", in: tree, collisions: [ + ("s:5MyKit0A5MyProtocol0Afunc()DefaultImp", "2dxqn"), + ("s:5MyKit0A5MyProtocol0Afunc()", "6ijsi"), + ]) + + try assertFindsPath("/FillIntroduced/iOSOnlyDeprecated()", in: tree, asSymbolID: "s:14FillIntroduced17iOSOnlyDeprecatedyyF") + try assertFindsPath("/FillIntroduced/macCatalystOnlyIntroduced()", in: tree, asSymbolID: "s:14FillIntroduced015macCatalystOnlyB0yyF") + + let paths = tree.caseInsensitiveDisambiguatedPaths() + try assertFindsPath("/SideKit/UncuratedClass", in: tree, asSymbolID: "s:7SideKit14UncuratedClassC") + XCTAssertEqual(paths["s:7SideKit14UncuratedClassC"], + "/SideKit/UncuratedClass") + + // Test finding non-symbol children + let discussionID = try tree.find(path: "/SideKit#Discussion", onlyFindSymbols: false) + XCTAssertNil(tree.lookup[discussionID]!.symbol) + XCTAssertEqual(tree.lookup[discussionID]!.name, "Discussion") + + let protocolImplementationsID = try tree.find(path: "/SideKit/SideClass/Element/Protocol-Implementations", onlyFindSymbols: false) + XCTAssertNil(tree.lookup[protocolImplementationsID]!.symbol) + XCTAssertEqual(tree.lookup[protocolImplementationsID]!.name, "Protocol-Implementations") + + let landmarkID = try tree.find(path: "/Test-Bundle/TestTutorial#Create-a-New-AR-Project-💻", onlyFindSymbols: false) + XCTAssertNil(tree.lookup[landmarkID]!.symbol) + XCTAssertEqual(tree.lookup[landmarkID]!.name, "Create-a-New-AR-Project-💻") + + let articleID = try tree.find(path: "/Test-Bundle/Default-Code-Listing-Syntax", onlyFindSymbols: false) + XCTAssertNil(tree.lookup[articleID]!.symbol) + XCTAssertEqual(tree.lookup[articleID]!.name, "Default-Code-Listing-Syntax") + } + + func testMixedLanguageFramework() throws { + try XCTSkipUnless(LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver) + let (_, context) = try testBundleAndContext(named: "MixedLanguageFramework") + let tree = try XCTUnwrap(context.hierarchyBasedLinkResolver?.pathHierarchy) + + try assertFindsPath("MixedLanguageFramework/Bar/myStringFunction(_:)", in: tree, asSymbolID: "c:objc(cs)Bar(cm)myStringFunction:error:") + try assertFindsPath("MixedLanguageFramework/Bar/myStringFunction:error:", in: tree, asSymbolID: "c:objc(cs)Bar(cm)myStringFunction:error:") + + try assertPathCollision("MixedLanguageFramework/Foo", in: tree, collisions: [ + ("c:@E@Foo", "enum"), + ("c:@E@Foo", "struct"), + ("c:MixedLanguageFramework.h@T@Foo", "typealias"), + ]) + + try assertFindsPath("MixedLanguageFramework/Foo/first", in: tree, asSymbolID: "c:@E@Foo@first") + + try assertFindsPath("MixedLanguageFramework/Foo-enum/first", in: tree, asSymbolID: "c:@E@Foo@first") + try assertFindsPath("MixedLanguageFramework/Foo-struct/first", in: tree, asSymbolID: "c:@E@Foo@first") + try assertFindsPath("MixedLanguageFramework/Foo-c.enum/first", in: tree, asSymbolID: "c:@E@Foo@first") + try assertFindsPath("MixedLanguageFramework/Foo-swift.struct/first", in: tree, asSymbolID: "c:@E@Foo@first") + + try assertFindsPath("MixedLanguageFramework/Foo/first-enum.case", in: tree, asSymbolID: "c:@E@Foo@first") + try assertFindsPath("MixedLanguageFramework/Foo/first-c.enum.case", in: tree, asSymbolID: "c:@E@Foo@first") + try assertFindsPath("MixedLanguageFramework/Foo/first-type.property", in: tree, asSymbolID: "c:@E@Foo@first") + try assertFindsPath("MixedLanguageFramework/Foo/first-swift.type.property", in: tree, asSymbolID: "c:@E@Foo@first") + + try assertFindsPath("MixedLanguageFramework/MixedLanguageProtocol/mixedLanguageMethod()", in: tree, asSymbolID: "c:@M@TestFramework@objc(pl)MixedLanguageProtocol(im)mixedLanguageMethod") + try assertFindsPath("MixedLanguageFramework/MixedLanguageProtocol/mixedLanguageMethod", in: tree, asSymbolID: "c:@M@TestFramework@objc(pl)MixedLanguageProtocol(im)mixedLanguageMethod") + + let paths = tree.caseInsensitiveDisambiguatedPaths() + XCTAssertEqual(paths["c:@E@Foo"], + "/MixedLanguageFramework/Foo-struct") + XCTAssertEqual(paths["c:MixedLanguageFramework.h@T@Foo"], + "/MixedLanguageFramework/Foo-typealias") + XCTAssertEqual(paths["c:@E@Foo@first"], + "/MixedLanguageFramework/Foo/first") + XCTAssertEqual(paths["c:@E@Foo@second"], + "/MixedLanguageFramework/Foo/second") + XCTAssertEqual(paths["s:So3FooV8rawValueABSu_tcfc"], + "/MixedLanguageFramework/Foo/init(rawValue:)") + XCTAssertEqual(paths["c:objc(cs)Bar(cm)myStringFunction:error:"], + "/MixedLanguageFramework/Bar/myStringFunction(_:)") + XCTAssertEqual(paths["s:22MixedLanguageFramework15SwiftOnlyStructV4tadayyF"], + "/MixedLanguageFramework/SwiftOnlyStruct/tada()") + } + + func testOverloadedSymbols() throws { + try XCTSkipUnless(LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver) + let (_, context) = try testBundleAndContext(named: "OverloadedSymbols") + let tree = try XCTUnwrap(context.hierarchyBasedLinkResolver?.pathHierarchy) + + let paths = tree.caseInsensitiveDisambiguatedPaths() + + XCTAssertEqual(paths["s:8ShapeKit22OverloadedParentStructV"], + "/ShapeKit/OverloadedParentStruct-1jr3p") + XCTAssertEqual(paths["s:8ShapeKit22overloadedparentstructV"], + "/ShapeKit/overloadedparentstruct-6a7lx") + + // These need to be disambiguated in two path components + XCTAssertEqual(paths["s:8ShapeKit22OverloadedParentStructV15fifthTestMemberSivpZ"], + "/ShapeKit/OverloadedParentStruct-1jr3p/fifthTestMember") + XCTAssertEqual(paths["s:8ShapeKit22overloadedparentstructV15fifthTestMemberSivp"], + "/ShapeKit/overloadedparentstruct-6a7lx/fifthTestMember") + + // This is the only enum case and can be disambiguated as such + XCTAssertEqual(paths["s:8ShapeKit14OverloadedEnumO19firstTestMemberNameyACSScACmF"], + "/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-enum.case") + // These are all methods and can only be disambiguated with the USR hash + XCTAssertEqual(paths["s:8ShapeKit14OverloadedEnumO19firstTestMemberNameySdSiF"], + "/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-14g8s") + XCTAssertEqual(paths["s:8ShapeKit14OverloadedEnumO19firstTestMemberNameySdSfF"], + "/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-14ife") + XCTAssertEqual(paths["s:8ShapeKit14OverloadedEnumO19firstTestMemberNameySdSSF"], + "/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-14ob0") + XCTAssertEqual(paths["s:8ShapeKit14OverloadedEnumO19firstTestMemberNameyS2dF"], + "/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-4ja8m") + XCTAssertEqual(paths["s:8ShapeKit14OverloadedEnumO19firstTestMemberNameySdSaySdGF"], + "/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-88rbf") + } + + func testSnippets() throws { + try XCTSkipUnless(LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver) + let (_, context) = try testBundleAndContext(named: "Snippets") + let tree = try XCTUnwrap(context.hierarchyBasedLinkResolver?.pathHierarchy) + + try assertFindsPath("/Snippets/Snippets/MySnippet", in: tree, asSymbolID: "$snippet__Test.Snippets.MySnippet") + + let paths = tree.caseInsensitiveDisambiguatedPaths() + XCTAssertEqual(paths["$snippet__Test.Snippets.MySnippet"], + "/Snippets/Snippets/MySnippet") + + // Test relative links from the article that overlap with the snippet's path + let snippetsArticleID = try tree.find(path: "/Snippets/Snippets", onlyFindSymbols: false) + XCTAssertEqual(try tree.findSymbol(path: "MySnippet", parent: snippetsArticleID).identifier.precise, "$snippet__Test.Snippets.MySnippet") + XCTAssertEqual(try tree.findSymbol(path: "Snippets/MySnippet", parent: snippetsArticleID).identifier.precise, "$snippet__Test.Snippets.MySnippet") + XCTAssertEqual(try tree.findSymbol(path: "Snippets/Snippets/MySnippet", parent: snippetsArticleID).identifier.precise, "$snippet__Test.Snippets.MySnippet") + XCTAssertEqual(try tree.findSymbol(path: "/Snippets/Snippets/MySnippet", parent: snippetsArticleID).identifier.precise, "$snippet__Test.Snippets.MySnippet") + + // Test relative links from another article (which doesn't overlap with the snippet's path) + let sliceArticleID = try tree.find(path: "/Snippets/SliceIndentation", onlyFindSymbols: false) + XCTAssertThrowsError(try tree.findSymbol(path: "MySnippet", parent: sliceArticleID)) + XCTAssertEqual(try tree.findSymbol(path: "Snippets/MySnippet", parent: sliceArticleID).identifier.precise, "$snippet__Test.Snippets.MySnippet") + XCTAssertEqual(try tree.findSymbol(path: "Snippets/Snippets/MySnippet", parent: sliceArticleID).identifier.precise, "$snippet__Test.Snippets.MySnippet") + XCTAssertEqual(try tree.findSymbol(path: "/Snippets/Snippets/MySnippet", parent: sliceArticleID).identifier.precise, "$snippet__Test.Snippets.MySnippet") + } + + func testOneSymbolPathsWithKnownDisambiguation() throws { + try XCTSkipUnless(LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver) + let exampleDocumentation = Folder(name: "MyKit.docc", content: [ + CopyOfFile(original: Bundle.module.url(forResource: "mykit-one-symbol.symbols", withExtension: "json", subdirectory: "Test Resources")!), + InfoPlist(displayName: "MyKit", identifier: "com.test.MyKit"), + ]) + let tempURL = try createTemporaryDirectory() + let bundleURL = try exampleDocumentation.write(inside: tempURL) + + do { + let (_, _, context) = try loadBundle(from: bundleURL) + let tree = try XCTUnwrap(context.hierarchyBasedLinkResolver?.pathHierarchy) + + try assertFindsPath("/MyKit/MyClass/myFunction()", in: tree, asSymbolID: "s:5MyKit0A5ClassC10myFunctionyyF") + try assertPathNotFound("/MyKit/MyClass-swift.class/myFunction()", in: tree) + try assertPathNotFound("/MyKit/MyClass", in: tree) + + XCTAssertEqual(tree.caseInsensitiveDisambiguatedPaths()["s:5MyKit0A5ClassC10myFunctionyyF"], + "/MyKit/MyClass/myFunction()") + + XCTAssertEqual(context.symbolIndex["s:5MyKit0A5ClassC10myFunctionyyF"]?.reference.path, + "/documentation/MyKit/MyClass/myFunction()") + } + + do { + let (_, _, context) = try loadBundle(from: bundleURL) { context in + context.knownDisambiguatedSymbolPathComponents = [ + "s:5MyKit0A5ClassC10myFunctionyyF": ["MyClass-swift.class", "myFunction()"] + ] + } + let tree = try XCTUnwrap(context.hierarchyBasedLinkResolver?.pathHierarchy) + + try assertFindsPath("/MyKit/MyClass-swift.class/myFunction()", in: tree, asSymbolID: "s:5MyKit0A5ClassC10myFunctionyyF") + try assertPathNotFound("/MyKit/MyClass", in: tree) + try assertPathNotFound("/MyKit/MyClass-swift.class", in: tree) + + XCTAssertEqual(tree.caseInsensitiveDisambiguatedPaths()["s:5MyKit0A5ClassC10myFunctionyyF"], + "/MyKit/MyClass-class/myFunction()") + + XCTAssertEqual(context.symbolIndex["s:5MyKit0A5ClassC10myFunctionyyF"]?.reference.path, + "/documentation/MyKit/MyClass-swift.class/myFunction()") + } + + do { + let (_, _, context) = try loadBundle(from: bundleURL) { context in + context.knownDisambiguatedSymbolPathComponents = [ + "s:5MyKit0A5ClassC10myFunctionyyF": ["MyClass-swift.class-hash", "myFunction()"] + ] + } + let tree = try XCTUnwrap(context.hierarchyBasedLinkResolver?.pathHierarchy) + + try assertFindsPath("/MyKit/MyClass-swift.class-hash/myFunction()", in: tree, asSymbolID: "s:5MyKit0A5ClassC10myFunctionyyF") + try assertPathNotFound("/MyKit/MyClass", in: tree) + try assertPathNotFound("/MyKit/MyClass-swift.class", in: tree) + try assertPathNotFound("/MyKit/MyClass-swift.class-hash", in: tree) + + + XCTAssertEqual(tree.caseInsensitiveDisambiguatedPaths()["s:5MyKit0A5ClassC10myFunctionyyF"], + "/MyKit/MyClass-class-hash/myFunction()") + + XCTAssertEqual(context.symbolIndex["s:5MyKit0A5ClassC10myFunctionyyF"]?.reference.path, + "/documentation/MyKit/MyClass-swift.class-hash/myFunction()") + } + } + + func testPartialSymbolGraphPaths() throws { + try XCTSkipUnless(LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver) + let symbolPaths = [ + ["A", "B", "C"], + ["A", "B", "C2"], + ["X", "Y"], + ["X", "Y2", "Z", "W"], + ] + let graph = SymbolGraph( + metadata: SymbolGraph.Metadata( + formatVersion: SymbolGraph.SemanticVersion(major: 1, minor: 1, patch: 1), + generator: "unit-test" + ), + module: SymbolGraph.Module( + name: "Module", + platform: SymbolGraph.Platform(architecture: nil, vendor: nil, operatingSystem: nil) + ), + symbols: symbolPaths.map { + SymbolGraph.Symbol( + identifier: SymbolGraph.Symbol.Identifier(precise: $0.joined(separator: "."), interfaceLanguage: "swift"), + names: SymbolGraph.Symbol.Names(title: "Title", navigator: nil, subHeading: nil, prose: nil), // names doesn't matter for path disambiguation + pathComponents: $0, + docComment: nil, + accessLevel: SymbolGraph.Symbol.AccessControl(rawValue: "public"), + kind: SymbolGraph.Symbol.Kind(parsedIdentifier: .class, displayName: "Kind Display Name"), // kind display names doesn't matter for path disambiguation + mixins: [:] + ) + }, + relationships: [] + ) + let exampleDocumentation = Folder(name: "MyKit.docc", content: [ + try TextFile(name: "mykit.symbols.json", utf8Content: XCTUnwrap(String(data: JSONEncoder().encode(graph), encoding: .utf8))), + InfoPlist(displayName: "MyKit", identifier: "com.test.MyKit"), + ]) + let tempURL = try createTemporaryDirectory() + let bundleURL = try exampleDocumentation.write(inside: tempURL) + + let (_, _, context) = try loadBundle(from: bundleURL) + let tree = try XCTUnwrap(context.hierarchyBasedLinkResolver?.pathHierarchy) + + try assertPathNotFound("/Module/A", in: tree) + try assertPathNotFound("/Module/A/B", in: tree) + try assertFindsPath("/Module/A/B/C", in: tree, asSymbolID: "A.B.C") + try assertFindsPath("/Module/A/B/C2", in: tree, asSymbolID: "A.B.C2") + + try assertPathNotFound("/Module/X", in: tree) + try assertFindsPath("/Module/X/Y", in: tree, asSymbolID: "X.Y") + try assertPathNotFound("/Module/X/Y2", in: tree) + try assertPathNotFound("/Module/X/Y2/Z", in: tree) + try assertFindsPath("/Module/X/Y2/Z/W", in: tree, asSymbolID: "X.Y2.Z.W") + + let paths = tree.caseInsensitiveDisambiguatedPaths() + XCTAssertEqual(paths.keys.sorted(), ["A.B.C", "A.B.C2", "Module", "X.Y", "X.Y2.Z.W"]) + XCTAssertEqual(paths["A.B.C"], "/Module/A/B/C") + XCTAssertEqual(paths["A.B.C2"], "/Module/A/B/C2") + XCTAssertEqual(paths["X.Y"], "/Module/X/Y") + XCTAssertEqual(paths["X.Y2.Z.W"], "/Module/X/Y2/Z/W") + } + + func testParsingPaths() { + // Check path components without disambiguation + assertParsedPathComponents("", []) + assertParsedPathComponents("/", []) + assertParsedPathComponents("/first", [("first", nil, nil)]) + assertParsedPathComponents("first", [("first", nil, nil)]) + assertParsedPathComponents("first/second/third", [("first", nil, nil), ("second", nil, nil), ("third", nil, nil)]) + assertParsedPathComponents("first/", [("first", nil, nil)]) + assertParsedPathComponents("first//second", [("first", nil, nil), ("second", nil, nil)]) + assertParsedPathComponents("first/second#third", [("first", nil, nil), ("second", nil, nil), ("third", nil, nil)]) + + // Check disambiguation + assertParsedPathComponents("path-hash", [("path", nil, "hash")]) + assertParsedPathComponents("path-struct", [("path", "struct", nil)]) + assertParsedPathComponents("path-struct-hash", [("path", "struct", "hash")]) + + assertParsedPathComponents("path-swift.something", [("path", "something", nil)]) + assertParsedPathComponents("path-c.something", [("path", "something", nil)]) + + assertParsedPathComponents("path-swift.something-hash", [("path", "something", "hash")]) + assertParsedPathComponents("path-c.something-hash", [("path", "something", "hash")]) + + assertParsedPathComponents("path-type.property-hash", [("path", "type.property", "hash")]) + assertParsedPathComponents("path-swift.type.property-hash", [("path", "type.property", "hash")]) + assertParsedPathComponents("path-type.property", [("path", "type.property", nil)]) + assertParsedPathComponents("path-swift.type.property", [("path", "type.property", nil)]) + } + + // MARK: Test helpers + + private func assertFindsPath(_ path: String, in tree: PathHierarchy, asSymbolID symbolID: String, file: StaticString = #file, line: UInt = #line) throws { + do { + let symbol = try tree.findSymbol(path: path) + XCTAssertEqual(symbol.identifier.precise, symbolID, file: file, line: line) + } catch PathHierarchy.Error.notFound { + XCTFail("Symbol for \(path.singleQuoted) not found in tree", file: file, line: line) + } catch PathHierarchy.Error.partialResult { + XCTFail("Symbol for \(path.singleQuoted) not found in tree. Only part of path is found.", file: file, line: line) + } catch PathHierarchy.Error.lookupCollision(_, let collisions) { + let symbols = collisions.map { $0.node.symbol! } + XCTFail("Unexpected collision for \(path.singleQuoted); \(symbols.map { return "\($0.names.title) - \($0.kind.identifier.identifier) - \($0.identifier.precise.stableHashString)"})", file: file, line: line) + } + } + + private func assertPathNotFound(_ path: String, in tree: PathHierarchy, file: StaticString = #file, line: UInt = #line) throws { + do { + let symbol = try tree.findSymbol(path: path) + XCTFail("Unexpectedly found symbol with ID \(symbol.identifier.precise) for path \(path.singleQuoted)", file: file, line: line) + } catch PathHierarchy.Error.notFound, PathHierarchy.Error.unfindableMatch, PathHierarchy.Error.nonSymbolMatchForSymbolLink { + // This specific error is expected. + } catch PathHierarchy.Error.partialResult { + // For the purpose of this assertion, this also counts as "not found". + } catch PathHierarchy.Error.lookupCollision(_, let collisions) { + let symbols = collisions.map { $0.node.symbol! } + XCTFail("Unexpected collision for \(path.singleQuoted); \(symbols.map { return "\($0.names.title) - \($0.kind.identifier.identifier) - \($0.identifier.precise.stableHashString)"})", file: file, line: line) + } + } + + private func assertPathCollision(_ path: String, in tree: PathHierarchy, collisions expectedCollisions: [(symbolID: String, disambiguation: String)], file: StaticString = #file, line: UInt = #line) throws { + do { + let symbol = try tree.findSymbol(path: path) + XCTFail("Unexpectedly found unambiguous symbol with ID \(symbol.identifier.precise) for path \(path.singleQuoted)", file: file, line: line) + } catch PathHierarchy.Error.notFound { + XCTFail("Symbol for \(path.singleQuoted) not found in tree", file: file, line: line) + } catch PathHierarchy.Error.partialResult { + XCTFail("Symbol for \(path.singleQuoted) not found in tree. Only part of path is found.", file: file, line: line) + } catch PathHierarchy.Error.lookupCollision(_, let collisions) { + let sortedCollisions = collisions.sorted(by: \.disambiguation) + XCTAssertEqual(sortedCollisions.count, expectedCollisions.count, file: file, line: line) + for (actual, expected) in zip(sortedCollisions, expectedCollisions) { + XCTAssertEqual(actual.node.symbol?.identifier.precise, expected.symbolID, file: file, line: line) + XCTAssertEqual(actual.disambiguation, expected.disambiguation, file: file, line: line) + } + } + } + + private func assertParsedPathComponents(_ path: String, _ expected: [(String, String?, String?)], file: StaticString = #file, line: UInt = #line) { + let (actual, _) = PathHierarchy.parse(path: path) + XCTAssertEqual(actual.count, expected.count, file: file, line: line) + for (actualComponents, expectedComponents) in zip(actual, expected) { + XCTAssertEqual(actualComponents.name, expectedComponents.0, "Incorrect path component", file: file, line: line) + XCTAssertEqual(actualComponents.kind, expectedComponents.1, "Incorrect kind disambiguation", file: file, line: line) + XCTAssertEqual(actualComponents.hash, expectedComponents.2, "Incorrect hash disambiguation", file: file, line: line) + } + } +} + +extension PathHierarchy { + func findSymbol(path rawPath: String, parent: ResolvedIdentifier? = nil) throws -> SymbolGraph.Symbol { + let id = try find(path: rawPath, parent: parent, onlyFindSymbols: true) + return lookup[id]!.symbol! + } +} diff --git a/Tests/SwiftDocCTests/Infrastructure/Symbol Link Resolution/AbsoluteSymbolLinkTests.swift b/Tests/SwiftDocCTests/Infrastructure/Symbol Link Resolution/AbsoluteSymbolLinkTests.swift index e00624e5e0..9aac9e45fa 100644 --- a/Tests/SwiftDocCTests/Infrastructure/Symbol Link Resolution/AbsoluteSymbolLinkTests.swift +++ b/Tests/SwiftDocCTests/Infrastructure/Symbol Link Resolution/AbsoluteSymbolLinkTests.swift @@ -541,7 +541,7 @@ class AbsoluteSymbolLinkTests: XCTestCase { codeListings: [:] ) - let expectedDescriptions = [ + var expectedDescriptions = [ // doc://com.shapes.ShapeKit/documentation/ShapeKit: """ { @@ -612,64 +612,64 @@ class AbsoluteSymbolLinkTests: XCTestCase { basePathComponents: [] } """, - // doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-swift.enum.case: + // doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-14g8s: """ { bundleID: 'com.shapes.ShapeKit', module: 'ShapeKit', topLevelSymbol: (name: 'OverloadedEnum', suffix: (none)), representsModule: false, - basePathComponents: [(name: 'firstTestMemberName(_:)', suffix: (kind: 'swift.enum.case'))] + basePathComponents: [(name: 'firstTestMemberName(_:)', suffix: (idHash: '14g8s'))] } """, - // doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-swift.method-14g8s: + // doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-14ife: """ { bundleID: 'com.shapes.ShapeKit', module: 'ShapeKit', topLevelSymbol: (name: 'OverloadedEnum', suffix: (none)), representsModule: false, - basePathComponents: [(name: 'firstTestMemberName(_:)', suffix: (kind: 'swift.method', idHash: '14g8s'))] + basePathComponents: [(name: 'firstTestMemberName(_:)', suffix: (idHash: '14ife'))] } """, - // doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-swift.method-14ife: + // doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-14ob0: """ { bundleID: 'com.shapes.ShapeKit', module: 'ShapeKit', topLevelSymbol: (name: 'OverloadedEnum', suffix: (none)), representsModule: false, - basePathComponents: [(name: 'firstTestMemberName(_:)', suffix: (kind: 'swift.method', idHash: '14ife'))] + basePathComponents: [(name: 'firstTestMemberName(_:)', suffix: (idHash: '14ob0'))] } """, - // doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-swift.method-14ob0: + // doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-4ja8m: """ { bundleID: 'com.shapes.ShapeKit', module: 'ShapeKit', topLevelSymbol: (name: 'OverloadedEnum', suffix: (none)), representsModule: false, - basePathComponents: [(name: 'firstTestMemberName(_:)', suffix: (kind: 'swift.method', idHash: '14ob0'))] + basePathComponents: [(name: 'firstTestMemberName(_:)', suffix: (idHash: '4ja8m'))] } """, - // doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-swift.method-4ja8m: + // doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-88rbf: """ { bundleID: 'com.shapes.ShapeKit', module: 'ShapeKit', topLevelSymbol: (name: 'OverloadedEnum', suffix: (none)), representsModule: false, - basePathComponents: [(name: 'firstTestMemberName(_:)', suffix: (kind: 'swift.method', idHash: '4ja8m'))] + basePathComponents: [(name: 'firstTestMemberName(_:)', suffix: (idHash: '88rbf'))] } """, - // doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-swift.method-88rbf: + // doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-swift.enum.case: """ { bundleID: 'com.shapes.ShapeKit', module: 'ShapeKit', topLevelSymbol: (name: 'OverloadedEnum', suffix: (none)), representsModule: false, - basePathComponents: [(name: 'firstTestMemberName(_:)', suffix: (kind: 'swift.method', idHash: '88rbf'))] + basePathComponents: [(name: 'firstTestMemberName(_:)', suffix: (kind: 'swift.enum.case'))] } """, // doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedParentStruct-1jr3p: @@ -682,14 +682,14 @@ class AbsoluteSymbolLinkTests: XCTestCase { basePathComponents: [] } """, - // doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedParentStruct-1jr3p/fifthTestMember-swift.type.property: + // doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedParentStruct-1jr3p/fifthTestMember: """ { bundleID: 'com.shapes.ShapeKit', module: 'ShapeKit', topLevelSymbol: (name: 'OverloadedParentStruct', suffix: (idHash: '1jr3p')), representsModule: false, - basePathComponents: [(name: 'fifthTestMember', suffix: (kind: 'swift.type.property'))] + basePathComponents: [(name: 'fifthTestMember', suffix: (none))] } """, // doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedProtocol: @@ -832,17 +832,42 @@ class AbsoluteSymbolLinkTests: XCTestCase { basePathComponents: [] } """, - // doc://com.shapes.ShapeKit/documentation/ShapeKit/overloadedparentstruct-6a7lx/fifthTestMember-swift.property: + // doc://com.shapes.ShapeKit/documentation/ShapeKit/overloadedparentstruct-6a7lx/fifthTestMember: """ { bundleID: 'com.shapes.ShapeKit', module: 'ShapeKit', topLevelSymbol: (name: 'overloadedparentstruct', suffix: (idHash: '6a7lx')), representsModule: false, - basePathComponents: [(name: 'fifthTestMember', suffix: (kind: 'swift.property'))] + basePathComponents: [(name: 'fifthTestMember', suffix: (none))] } """, ] + if !LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver { + // The cache-based resolver redundantly disambiguates these overloads with both kind and hash ... + for index in 7...11 { + expectedDescriptions[index] = expectedDescriptions[index].replacingOccurrences( + of: "basePathComponents: [(name: 'firstTestMemberName(_:)', suffix: (idHash: '", + with: "basePathComponents: [(name: 'firstTestMemberName(_:)', suffix: (kind: 'swift.method', idHash: '" + ) + } + // ... because of the above, the cache-based resolver sort the enum case before the methods + expectedDescriptions.insert( + expectedDescriptions.remove(at: 12), + at: 7 + ) + + // The cache-based resolver redundantly disambiguates these overloads which already have disambiguated parents. + expectedDescriptions[14] = expectedDescriptions[14].replacingOccurrences( + of: "basePathComponents: [(name: 'fifthTestMember', suffix: (none))]", + with: "basePathComponents: [(name: 'fifthTestMember', suffix: (kind: 'swift.type.property'))]" + ) + expectedDescriptions[29] = expectedDescriptions[29].replacingOccurrences( + of: "basePathComponents: [(name: 'fifthTestMember', suffix: (none))]", + with: "basePathComponents: [(name: 'fifthTestMember', suffix: (kind: 'swift.property'))]" + ) + } + XCTAssertEqual(expectedDescriptions.count, context.symbolIndex.count) let validatedSymbolLinkDescriptions = context.symbolIndex.values diff --git a/Tests/SwiftDocCTests/Infrastructure/Symbol Link Resolution/DocCSymbolRepresentableTests.swift b/Tests/SwiftDocCTests/Infrastructure/Symbol Link Resolution/DocCSymbolRepresentableTests.swift index c496295430..636457543d 100644 --- a/Tests/SwiftDocCTests/Infrastructure/Symbol Link Resolution/DocCSymbolRepresentableTests.swift +++ b/Tests/SwiftDocCTests/Infrastructure/Symbol Link Resolution/DocCSymbolRepresentableTests.swift @@ -46,6 +46,8 @@ class DocCSymbolRepresentableTests: XCTestCase { } func testOverloadedParentAndMember() throws { + try XCTSkipIf(LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver, "This is already unambiguous at the parent level. The `AbsoluteSymbolLink.LinkComponent` doesn't have the information to identify that.") + try performOverloadSymbolDisambiguationTest( correctLink: """ doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedParentStruct-1jr3p/fifthTestMember-swift.type.property @@ -74,18 +76,34 @@ class DocCSymbolRepresentableTests: XCTestCase { } func testFunctionWithKindIdentifierAndUSRHash() throws { - try performOverloadSymbolDisambiguationTest( - correctLink: """ - doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-swift.method-14g8s - """, - incorrectLinks: [ - "doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-swift.method", - "doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-14g8s", - "doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)", - ], - symbolTitle: "firstTestMemberName(_:)", - expectedNumberOfAmbiguousSymbols: 6 - ) + if LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver { + try performOverloadSymbolDisambiguationTest( + correctLink: """ + doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-14g8s + """, + incorrectLinks: [ + "doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-swift.method-14g8s", + "doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-swift.method", + "doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)", + ], + symbolTitle: "firstTestMemberName(_:)", + expectedNumberOfAmbiguousSymbols: 6 + ) + } else { + // The cache-based resolver redundantly disambiguates with both kind and usr when another overload has a different kind. + try performOverloadSymbolDisambiguationTest( + correctLink: """ + doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-swift.method-14g8s + """, + incorrectLinks: [ + "doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-swift.method", + "doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)-14g8s", + "doc://com.shapes.ShapeKit/documentation/ShapeKit/OverloadedEnum/firstTestMemberName(_:)", + ], + symbolTitle: "firstTestMemberName(_:)", + expectedNumberOfAmbiguousSymbols: 6 + ) + } } func testSymbolWithNoDisambiguation() throws { @@ -140,13 +158,13 @@ class DocCSymbolRepresentableTests: XCTestCase { XCTAssertEqual(ambiguousSymbols.count, expectedNumberOfAmbiguousSymbols) // Find the documentation node based on what we expect the correct link to be - let correctDocumentionNodeToSelect = try XCTUnwrap( + let correctDocumentationNodeToSelect = try XCTUnwrap( context.symbolIndex.values.first { $0.reference.absoluteString == correctLink } ) let correctSymbolToSelect = try XCTUnwrap( - correctDocumentionNodeToSelect.symbol + correctDocumentationNodeToSelect.symbol ) // First confirm the first link does resolve as expected @@ -222,8 +240,12 @@ class DocCSymbolRepresentableTests: XCTestCase { count += 1 } - // We expect this bundle to contain 5 symbols that need both type and usr - // disambiguation. - XCTAssertEqual(count, 5) + if LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver { + // With the hierarchy-based resolver it's never necessary to disambiguate with both kind and usr. + XCTAssertEqual(count, 0) + } else { + // With the cache-based resolver we expect this bundle to contain 5 symbols that need both kind and usr disambiguation. + XCTAssertEqual(count, 5) + } } } diff --git a/Tests/SwiftDocCTests/Infrastructure/SymbolDisambiguationTests.swift b/Tests/SwiftDocCTests/Infrastructure/SymbolDisambiguationTests.swift index 48d627d44a..78d00cfc5b 100644 --- a/Tests/SwiftDocCTests/Infrastructure/SymbolDisambiguationTests.swift +++ b/Tests/SwiftDocCTests/Infrastructure/SymbolDisambiguationTests.swift @@ -174,36 +174,47 @@ class SymbolDisambiguationTests: XCTestCase { "/documentation/SymbolDisambiguationTests/Something/first(_:_:)-swift.method", ]) - // Ideally these wouldn't include the kind information because information doesn't help disambiguate these two references. - XCTAssertEqual((references[SymbolGraph.Symbol.Identifier(precise: "second", interfaceLanguage: "swift")] ?? []).map { $0.path }, [ - "/documentation/SymbolDisambiguationTests/Something/first(_:_:)-swift.type.method-\("second".stableHashString)", - ]) - XCTAssertEqual((references[SymbolGraph.Symbol.Identifier(precise: "third", interfaceLanguage: "swift")] ?? []).map { $0.path }, [ - "/documentation/SymbolDisambiguationTests/Something/first(_:_:)-swift.type.method-\("third".stableHashString)", - ]) + if LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver { + XCTAssertEqual((references[SymbolGraph.Symbol.Identifier(precise: "second", interfaceLanguage: "swift")] ?? []).map { $0.path }, [ + "/documentation/SymbolDisambiguationTests/Something/first(_:_:)-\("second".stableHashString)", + ]) + XCTAssertEqual((references[SymbolGraph.Symbol.Identifier(precise: "third", interfaceLanguage: "swift")] ?? []).map { $0.path }, [ + "/documentation/SymbolDisambiguationTests/Something/first(_:_:)-\("third".stableHashString)", + ]) + } else { + // The cache-based resolver redundantly disambiguates with both kind and usr when another overload has a different kind. + XCTAssertEqual((references[SymbolGraph.Symbol.Identifier(precise: "second", interfaceLanguage: "swift")] ?? []).map { $0.path }, [ + "/documentation/SymbolDisambiguationTests/Something/first(_:_:)-swift.type.method-\("second".stableHashString)", + ]) + XCTAssertEqual((references[SymbolGraph.Symbol.Identifier(precise: "third", interfaceLanguage: "swift")] ?? []).map { $0.path }, [ + "/documentation/SymbolDisambiguationTests/Something/first(_:_:)-swift.type.method-\("third".stableHashString)", + ]) + } } func testMixedLanguageFramework() throws { let (bundle, context) = try testBundleAndContext(named: "MixedLanguageFramework") - let aliases = [String: [String]](uniqueKeysWithValues: context.documentationCacheBasedLinkResolver.referenceAliases.map({ ($0.key.path, $0.value.map(\.path).sorted()) })) - XCTAssertEqual(aliases, [ - "/documentation/MixedLanguageFramework/Bar/myStringFunction(_:)": [ - "/documentation/MixedLanguageFramework/Bar/myStringFunction:error:", - ], - "/documentation/MixedLanguageFramework/Foo-swift.struct": [ - "/documentation/MixedLanguageFramework/Foo-c.enum", - ], - "/documentation/MixedLanguageFramework/MixedLanguageClassConformingToProtocol/init()": [ - "/documentation/MixedLanguageFramework/MixedLanguageClassConformingToProtocol/init", - ], - "/documentation/MixedLanguageFramework/MixedLanguageClassConformingToProtocol/mixedLanguageMethod()": [ - "/documentation/MixedLanguageFramework/MixedLanguageClassConformingToProtocol/mixedLanguageMethod", - ], - "/documentation/MixedLanguageFramework/MixedLanguageProtocol/mixedLanguageMethod()": [ - "/documentation/MixedLanguageFramework/MixedLanguageProtocol/mixedLanguageMethod", - ], - ]) + if !LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver { + let aliases = [String: [String]](uniqueKeysWithValues: context.documentationCacheBasedLinkResolver.referenceAliases.map({ ($0.key.path, $0.value.map(\.path).sorted()) })) + XCTAssertEqual(aliases, [ + "/documentation/MixedLanguageFramework/Bar/myStringFunction(_:)": [ + "/documentation/MixedLanguageFramework/Bar/myStringFunction:error:", + ], + "/documentation/MixedLanguageFramework/Foo-swift.struct": [ + "/documentation/MixedLanguageFramework/Foo-c.enum", + ], + "/documentation/MixedLanguageFramework/MixedLanguageClassConformingToProtocol/init()": [ + "/documentation/MixedLanguageFramework/MixedLanguageClassConformingToProtocol/init", + ], + "/documentation/MixedLanguageFramework/MixedLanguageClassConformingToProtocol/mixedLanguageMethod()": [ + "/documentation/MixedLanguageFramework/MixedLanguageClassConformingToProtocol/mixedLanguageMethod", + ], + "/documentation/MixedLanguageFramework/MixedLanguageProtocol/mixedLanguageMethod()": [ + "/documentation/MixedLanguageFramework/MixedLanguageProtocol/mixedLanguageMethod", + ], + ]) + } var loader = SymbolGraphLoader(bundle: bundle, dataProvider: context.dataProvider) try loader.loadAll() diff --git a/Tests/SwiftDocCTests/Rendering/DefaultCodeListingSyntaxTests.swift b/Tests/SwiftDocCTests/Rendering/DefaultCodeListingSyntaxTests.swift index ce757804e4..81a619c666 100644 --- a/Tests/SwiftDocCTests/Rendering/DefaultCodeListingSyntaxTests.swift +++ b/Tests/SwiftDocCTests/Rendering/DefaultCodeListingSyntaxTests.swift @@ -23,23 +23,20 @@ class DefaultCodeBlockSyntaxTests: XCTestCase { var testBundleWithLanguageDefault: DocumentationBundle! var testBundleWithoutLanguageDefault: DocumentationBundle! - var bundleBaseURL: URL! - - override func setUp() { - func renderSection(for bundle: DocumentationBundle, in context: DocumentationContext) -> ContentRenderSection { + override func setUpWithError() throws { + func renderSection(for bundle: DocumentationBundle, in context: DocumentationContext) throws -> ContentRenderSection { let identifier = ResolvedTopicReference(bundleIdentifier: "org.swift.docc.example", path: "/documentation/Test-Bundle/Default-Code-Listing-Syntax", fragment: nil, sourceLanguage: .swift) let source = context.documentURL(for: identifier) - let node = try! context.entity(with: identifier) + let node = try context.entity(with: identifier) var translator = RenderNodeTranslator(context: context, bundle: bundle, identifier: node.reference, source: source) let renderNode = translator.visit(node.semantic) as! RenderNode return renderNode.primaryContentSections.first! as! ContentRenderSection } - let (url, bundleWithLanguageDefault, context) = try! testBundleAndContext(copying: "TestBundle") - bundleBaseURL = url + let (_, bundleWithLanguageDefault, context) = try testBundleAndContext(copying: "TestBundle") testBundleWithLanguageDefault = bundleWithLanguageDefault @@ -58,12 +55,8 @@ class DefaultCodeBlockSyntaxTests: XCTestCase { miscResourceURLs: testBundleWithLanguageDefault.miscResourceURLs ) - renderSectionWithLanguageDefault = renderSection(for: testBundleWithLanguageDefault, in: context) - renderSectionWithoutLanguageDefault = renderSection(for: testBundleWithoutLanguageDefault, in: context) - } - - override func tearDown() { - try? FileManager.default.removeItem(at: bundleBaseURL) + renderSectionWithLanguageDefault = try renderSection(for: testBundleWithLanguageDefault, in: context) + renderSectionWithoutLanguageDefault = try renderSection(for: testBundleWithoutLanguageDefault, in: context) } struct CodeListing { diff --git a/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorTests.swift b/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorTests.swift index c20d412a54..31b62f2a6f 100644 --- a/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorTests.swift +++ b/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorTests.swift @@ -944,13 +944,13 @@ class RenderNodeTranslatorTests: XCTestCase { let renderNode = try XCTUnwrap(translator.visitArticle(article) as? RenderNode) let discussion = try XCTUnwrap(renderNode.primaryContentSections.first(where: { $0.kind == .content }) as? ContentRenderSection) - if case let .paragraph(elements) = discussion.content[2] { + if case let .paragraph(elements) = discussion.content.dropFirst(2).first { XCTAssertEqual(elements, [.text("Does a foo.")]) } else { XCTFail("Unexpected content where snippet explanation should be.") } - if case let .codeListing(syntax, code, _) = discussion.content[3] { + if case let .codeListing(syntax, code, _) = discussion.content.dropFirst(3).first { XCTAssertEqual(syntax, "swift") XCTAssertEqual(code.joined(separator: "\n"), """ func foo() {} diff --git a/Tests/SwiftDocCTests/Semantics/SymbolTests.swift b/Tests/SwiftDocCTests/Semantics/SymbolTests.swift index d2be003f1a..1feabe8cbe 100644 --- a/Tests/SwiftDocCTests/Semantics/SymbolTests.swift +++ b/Tests/SwiftDocCTests/Semantics/SymbolTests.swift @@ -538,6 +538,11 @@ class SymbolTests: XCTestCase { - ``UnresolvableClassInMyClassTopicCuration`` - ``MyClass/unresolvablePropertyInMyClassTopicCuration`` - + + ### Ambiguous curation + + - ``init()`` + - ``MyClass/init()-swift.init`` """ let documentationExtensionURL = url.appendingPathComponent("documentation/myclass.md") @@ -547,10 +552,21 @@ class SymbolTests: XCTestCase { let unresolvedTopicProblems = context.problems.filter { $0.diagnostic.identifier == "org.swift.docc.unresolvedTopicReference" } - XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'UnresolvableSymbolLinkInMyClassOverview' couldn't be resolved. No local documentation matches this reference." })) - XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'UnresolvableClassInMyClassTopicCuration' couldn't be resolved. No local documentation matches this reference." })) - XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'MyClass/unresolvablePropertyInMyClassTopicCuration' couldn't be resolved. No local documentation matches this reference." })) XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'doc://com.test.external/ExternalPage' couldn't be resolved. No external resolver registered for 'com.test.external'." })) + if LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver { + XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'UnresolvableSymbolLinkInMyClassOverview' couldn't be resolved. Reference at '/MyKit/MyClass' can't resolve 'UnresolvableSymbolLinkInMyClassOverview'. Available children: init(), myFunction()." })) + XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'UnresolvableClassInMyClassTopicCuration' couldn't be resolved. Reference at '/MyKit/MyClass' can't resolve 'UnresolvableClassInMyClassTopicCuration'. Available children: init(), myFunction()." })) + + XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'MyClass/unresolvablePropertyInMyClassTopicCuration' couldn't be resolved. Reference at '/MyKit/MyClass' can't resolve 'unresolvablePropertyInMyClassTopicCuration'. Available children: init(), myFunction()." })) + XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'init()' couldn't be resolved. Reference is ambiguous after '/MyKit/MyClass': Add '33vaw' to refer to 'init()'. Add '3743d' to refer to 'init()'." })) + XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'MyClass/init()-swift.init' couldn't be resolved. Reference is ambiguous after '/MyKit/MyClass': Add '33vaw' to refer to 'init()'. Add '3743d' to refer to 'init()'." })) + } else { + XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'UnresolvableSymbolLinkInMyClassOverview' couldn't be resolved. No local documentation matches this reference." })) + XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'UnresolvableClassInMyClassTopicCuration' couldn't be resolved. No local documentation matches this reference." })) + XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'MyClass/unresolvablePropertyInMyClassTopicCuration' couldn't be resolved. No local documentation matches this reference." })) + XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'init()' couldn't be resolved. No local documentation matches this reference." })) + XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'MyClass/init()-swift.init' couldn't be resolved. No local documentation matches this reference." })) + } } func testUnresolvedReferenceWarningsInDocComment() throws { @@ -586,9 +602,15 @@ class SymbolTests: XCTestCase { let unresolvedTopicProblems = context.problems.filter { $0.diagnostic.identifier == "org.swift.docc.unresolvedTopicReference" } - XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'UnresolvableSymbolLinkInMyClassOverview' couldn't be resolved. No local documentation matches this reference." })) - XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'UnresolvableClassInMyClassTopicCuration' couldn't be resolved. No local documentation matches this reference." })) - XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'MyClass/unresolvablePropertyInMyClassTopicCuration' couldn't be resolved. No local documentation matches this reference." })) + if LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver { + XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'UnresolvableSymbolLinkInMyClassOverview' couldn't be resolved. Reference at '/MyKit/MyClass/myFunction()' can't resolve 'UnresolvableSymbolLinkInMyClassOverview'. Available children: Unresolvable-curation." })) + XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'UnresolvableClassInMyClassTopicCuration' couldn't be resolved. Reference at '/MyKit/MyClass/myFunction()' can't resolve 'UnresolvableClassInMyClassTopicCuration'. Available children: Unresolvable-curation." })) + XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'MyClass/unresolvablePropertyInMyClassTopicCuration' couldn't be resolved. Reference at '/MyKit/MyClass' can't resolve 'unresolvablePropertyInMyClassTopicCuration'. Available children: init(), myFunction()." })) + } else { + XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'UnresolvableSymbolLinkInMyClassOverview' couldn't be resolved. No local documentation matches this reference." })) + XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'UnresolvableClassInMyClassTopicCuration' couldn't be resolved. No local documentation matches this reference." })) + XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'MyClass/unresolvablePropertyInMyClassTopicCuration' couldn't be resolved. No local documentation matches this reference." })) + } XCTAssertTrue(unresolvedTopicProblems.contains(where: { $0.diagnostic.localizedSummary == "Topic reference 'doc://com.test.external/ExternalPage' couldn't be resolved. No external resolver registered for 'com.test.external'." })) } diff --git a/Tests/SwiftDocCTests/Test Bundles/MixedLanguageFrameworkWithLanguageRefinements.docc/Info.plist b/Tests/SwiftDocCTests/Test Bundles/MixedLanguageFrameworkWithLanguageRefinements.docc/Info.plist new file mode 100644 index 0000000000..de1cfe43f7 --- /dev/null +++ b/Tests/SwiftDocCTests/Test Bundles/MixedLanguageFrameworkWithLanguageRefinements.docc/Info.plist @@ -0,0 +1,14 @@ + + + + + CFBundleName + MixedFramework + CFBundleDisplayName + MixedFramework + CFBundleIdentifier + org.swift.MixedFramework + CFBundleVersion + 0.1.0 + + diff --git a/Tests/SwiftDocCTests/Test Bundles/MixedLanguageFrameworkWithLanguageRefinements.docc/symbol-graph/clang/x86_64-apple-macos12.3/MixedFramework.symbols.json b/Tests/SwiftDocCTests/Test Bundles/MixedLanguageFrameworkWithLanguageRefinements.docc/symbol-graph/clang/x86_64-apple-macos12.3/MixedFramework.symbols.json new file mode 100644 index 0000000000..d82492abf5 --- /dev/null +++ b/Tests/SwiftDocCTests/Test Bundles/MixedLanguageFrameworkWithLanguageRefinements.docc/symbol-graph/clang/x86_64-apple-macos12.3/MixedFramework.symbols.json @@ -0,0 +1,3352 @@ +{ + "metadata" : { + "formatVersion" : { + "major" : 0, + "minor" : 5, + "patch" : 0 + }, + "generator" : "SymbolKit" + }, + "module" : { + "name" : "MixedFramework", + "platform" : { + "architecture" : "x86_64", + "operatingSystem" : { + "minimumVersion" : { + "major" : 12, + "minor" : 3, + "patch" : 0 + }, + "name" : "macos" + }, + "vendor" : "apple" + } + }, + "relationships" : [ + { + "kind" : "memberOf", + "source" : "c:@E@MyObjectiveCEnum@MyObjectiveCEnumFirst", + "target" : "c:@E@MyObjectiveCEnum", + "targetFallback" : null + }, + { + "kind" : "memberOf", + "source" : "c:@E@MyObjectiveCEnum@MyObjectiveCEnumSecond", + "target" : "c:@E@MyObjectiveCEnum", + "targetFallback" : null + }, + { + "kind" : "memberOf", + "source" : "c:@E@MyObjectiveCEnumObjectiveCName@MyObjectiveCEnumObjectiveCNameFirst", + "target" : "c:@E@MyObjectiveCEnumObjectiveCName", + "targetFallback" : null + }, + { + "kind" : "memberOf", + "source" : "c:@E@MyObjectiveCEnumObjectiveCName@MyObjectiveCEnumObjectiveCNameSecond", + "target" : "c:@E@MyObjectiveCEnumObjectiveCName", + "targetFallback" : null + }, + { + "kind" : "memberOf", + "source" : "c:@E@MyObjectiveCOption@MyObjectiveCOptionFirst", + "target" : "c:@E@MyObjectiveCOption", + "targetFallback" : null + }, + { + "kind" : "memberOf", + "source" : "c:@E@MyObjectiveCOption@MyObjectiveCOptionNone", + "target" : "c:@E@MyObjectiveCOption", + "targetFallback" : null + }, + { + "kind" : "memberOf", + "source" : "c:@E@MyObjectiveCOption@MyObjectiveCOptionSecond", + "target" : "c:@E@MyObjectiveCOption", + "targetFallback" : null + }, + { + "kind" : "memberOf", + "source" : "c:@M@MixedFramework@E@MyEnum@MyEnumFirstCase", + "target" : "c:@M@MixedFramework@E@MyEnum", + "targetFallback" : null + }, + { + "kind" : "memberOf", + "source" : "c:@M@MixedFramework@E@MyEnum@MyEnumSecondCase", + "target" : "c:@M@MixedFramework@E@MyEnum", + "targetFallback" : null + }, + { + "kind" : "inheritsFrom", + "source" : "c:@M@MixedFramework@objc(cs)MyClass", + "target" : "c:objc(cs)NSObject", + "targetFallback" : "NSObject" + }, + { + "kind" : "memberOf", + "source" : "c:@M@MixedFramework@objc(cs)MyClass(im)init", + "target" : "c:@M@MixedFramework@objc(cs)MyClass", + "targetFallback" : null + }, + { + "kind" : "memberOf", + "source" : "c:@M@MixedFramework@objc(cs)MyClass(im)myInstanceMethod", + "target" : "c:@M@MixedFramework@objc(cs)MyClass", + "targetFallback" : null + }, + { + "kind" : "inheritsFrom", + "source" : "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol", + "target" : "c:objc(cs)NSObject", + "targetFallback" : "NSObject" + }, + { + "kind" : "memberOf", + "source" : "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol(im)init", + "target" : "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol", + "targetFallback" : null + }, + { + "kind" : "memberOf", + "source" : "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol(im)myOtherProtocolMethod", + "target" : "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol", + "targetFallback" : null + }, + { + "kind" : "memberOf", + "source" : "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol(im)myProtocolMethod", + "target" : "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol", + "targetFallback" : null + }, + { + "kind" : "inheritsFrom", + "source" : "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName", + "target" : "c:objc(cs)NSObject", + "targetFallback" : "NSObject" + }, + { + "kind" : "memberOf", + "source" : "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName(im)init", + "target" : "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName", + "targetFallback" : null + }, + { + "kind" : "memberOf", + "source" : "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName(im)myMethodObjectiveCName", + "target" : "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName", + "targetFallback" : null + }, + { + "kind" : "memberOf", + "source" : "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName(py)myPropertyObjectiveCName", + "target" : "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName", + "targetFallback" : null + }, + { + "kind" : "memberOf", + "source" : "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(cpy)myProtocolTypeProperty", + "target" : "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol", + "targetFallback" : null + }, + { + "kind" : "memberOf", + "source" : "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(im)myPropertyOptionalMethod", + "target" : "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol", + "targetFallback" : null + }, + { + "kind" : "memberOf", + "source" : "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(im)myProtocolMethod", + "target" : "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol", + "targetFallback" : null + }, + { + "kind" : "memberOf", + "source" : "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(py)myProtocolProperty", + "target" : "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol", + "targetFallback" : null + }, + { + "kind" : "inheritsFrom", + "source" : "c:objc(cs)MyObjectiveCClassObjectiveCName", + "target" : "c:objc(cs)NSObject", + "targetFallback" : "NSObject" + }, + { + "kind" : "memberOf", + "source" : "c:objc(cs)MyObjectiveCClassObjectiveCName(im)myMethodObjectiveCName", + "target" : "c:objc(cs)MyObjectiveCClassObjectiveCName", + "targetFallback" : null + }, + { + "kind" : "memberOf", + "source" : "c:objc(cs)MyObjectiveCClassObjectiveCName(im)myMethodWithArgument:", + "target" : "c:objc(cs)MyObjectiveCClassObjectiveCName", + "targetFallback" : null + }, + { + "kind" : "memberOf", + "source" : "c:objc(cs)MyObjectiveCClassObjectiveCName(py)myPropertyObjectiveCName", + "target" : "c:objc(cs)MyObjectiveCClassObjectiveCName", + "targetFallback" : null + } + ], + "symbols" : [ + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "keyword", + "spelling" : "extern" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:d", + "spelling" : "double" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "identifier", + "spelling" : "MixedFrameworkVersionNumber" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 46, + "line" : 9 + }, + "start" : { + "character" : 4, + "line" : 9 + } + }, + "text" : "Project version number for MixedFramework." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@MixedFrameworkVersionNumber" + }, + "kind" : { + "displayName" : "Global Variable", + "identifier" : "var" + }, + "location" : { + "position" : { + "character" : 25, + "line" : 10 + }, + "uri" : "MixedFramework.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MixedFrameworkVersionNumber" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MixedFrameworkVersionNumber" + } + ], + "title" : "MixedFrameworkVersionNumber" + }, + "pathComponents" : [ + "MixedFrameworkVersionNumber" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "keyword", + "spelling" : "extern" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "keyword", + "spelling" : "const" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:c", + "spelling" : "unsigned char" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "identifier", + "spelling" : "MixedFrameworkVersionString" + }, + { + "kind" : "text", + "spelling" : "[]" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 46, + "line" : 12 + }, + "start" : { + "character" : 4, + "line" : 12 + } + }, + "text" : "Project version string for MixedFramework." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@MixedFrameworkVersionString" + }, + "kind" : { + "displayName" : "Global Variable", + "identifier" : "var" + }, + "location" : { + "position" : { + "character" : 38, + "line" : 13 + }, + "uri" : "MixedFramework.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MixedFrameworkVersionString" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MixedFrameworkVersionString" + } + ], + "title" : "MixedFrameworkVersionString" + }, + "pathComponents" : [ + "MixedFrameworkVersionString" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "keyword", + "spelling" : "@interface" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "identifier", + "spelling" : "MyClass" + }, + { + "kind" : "text", + "spelling" : " : " + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:objc(cs)NSObject", + "spelling" : "NSObject" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 35, + "line" : 253 + }, + "start" : { + "character" : 4, + "line" : 253 + } + }, + "text" : "My Objective-C compatible class" + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@M@MixedFramework@objc(cs)MyClass" + }, + "kind" : { + "displayName" : "Class", + "identifier" : "class" + }, + "location" : { + "position" : { + "character" : 11, + "line" : 255 + }, + "uri" : "MixedFramework-Swift.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyClass" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyClass" + } + ], + "title" : "MyClass" + }, + "pathComponents" : [ + "MyClass" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "text", + "spelling" : "- (" + }, + { + "kind" : "keyword", + "spelling" : "id" + }, + { + "kind" : "text", + "spelling" : ") " + }, + { + "kind" : "identifier", + "spelling" : "init" + }, + { + "kind" : "text", + "spelling" : ";" + } + ], + "functionSignature" : { + "parameters" : [ + + ], + "returns" : [ + { + "kind" : "keyword", + "spelling" : "id" + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@M@MixedFramework@objc(cs)MyClass(im)init" + }, + "kind" : { + "displayName" : "Instance Method", + "identifier" : "method" + }, + "location" : { + "position" : { + "character" : 0, + "line" : 258 + }, + "uri" : "MixedFramework-Swift.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "init" + } + ], + "subHeading" : [ + { + "kind" : "text", + "spelling" : "- " + }, + { + "kind" : "identifier", + "spelling" : "init" + } + ], + "title" : "init" + }, + "pathComponents" : [ + "MyClass", + "init" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "text", + "spelling" : "- (" + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:v", + "spelling" : "void" + }, + { + "kind" : "text", + "spelling" : ") " + }, + { + "kind" : "identifier", + "spelling" : "myInstanceMethod" + }, + { + "kind" : "text", + "spelling" : ";" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 35, + "line" : 256 + }, + "start" : { + "character" : 4, + "line" : 256 + } + }, + "text" : "An instance method on my class." + } + ] + }, + "functionSignature" : { + "parameters" : [ + + ], + "returns" : [ + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:v", + "spelling" : "void" + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@M@MixedFramework@objc(cs)MyClass(im)myInstanceMethod" + }, + "kind" : { + "displayName" : "Instance Method", + "identifier" : "method" + }, + "location" : { + "position" : { + "character" : 0, + "line" : 257 + }, + "uri" : "MixedFramework-Swift.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "myInstanceMethod" + } + ], + "subHeading" : [ + { + "kind" : "text", + "spelling" : "- " + }, + { + "kind" : "identifier", + "spelling" : "myInstanceMethod" + } + ], + "title" : "myInstanceMethod" + }, + "pathComponents" : [ + "MyClass", + "myInstanceMethod" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "keyword", + "spelling" : "@interface" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "identifier", + "spelling" : "MyClassThatConformToMyOtherProtocol" + }, + { + "kind" : "text", + "spelling" : " : " + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:objc(cs)NSObject", + "spelling" : "NSObject" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 76, + "line" : 262 + }, + "start" : { + "character" : 4, + "line" : 262 + } + }, + "text" : "My Objective-C compatible class that conform to “my other protocol”." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol" + }, + "kind" : { + "displayName" : "Class", + "identifier" : "class" + }, + "location" : { + "position" : { + "character" : 11, + "line" : 264 + }, + "uri" : "MixedFramework-Swift.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyClassThatConformToMyOtherProtocol" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyClassThatConformToMyOtherProtocol" + } + ], + "title" : "MyClassThatConformToMyOtherProtocol" + }, + "pathComponents" : [ + "MyClassThatConformToMyOtherProtocol" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "text", + "spelling" : "- (" + }, + { + "kind" : "keyword", + "spelling" : "id" + }, + { + "kind" : "text", + "spelling" : ") " + }, + { + "kind" : "identifier", + "spelling" : "init" + }, + { + "kind" : "text", + "spelling" : ";" + } + ], + "functionSignature" : { + "parameters" : [ + + ], + "returns" : [ + { + "kind" : "keyword", + "spelling" : "id" + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol(im)init" + }, + "kind" : { + "displayName" : "Instance Method", + "identifier" : "method" + }, + "location" : { + "position" : { + "character" : 0, + "line" : 267 + }, + "uri" : "MixedFramework-Swift.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "init" + } + ], + "subHeading" : [ + { + "kind" : "text", + "spelling" : "- " + }, + { + "kind" : "identifier", + "spelling" : "init" + } + ], + "title" : "init" + }, + "pathComponents" : [ + "MyClassThatConformToMyOtherProtocol", + "init" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "text", + "spelling" : "- (" + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:v", + "spelling" : "void" + }, + { + "kind" : "text", + "spelling" : ") " + }, + { + "kind" : "identifier", + "spelling" : "myOtherProtocolMethod" + }, + { + "kind" : "text", + "spelling" : ";" + } + ], + "functionSignature" : { + "parameters" : [ + + ], + "returns" : [ + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:v", + "spelling" : "void" + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol(im)myOtherProtocolMethod" + }, + "kind" : { + "displayName" : "Instance Method", + "identifier" : "method" + }, + "location" : { + "position" : { + "character" : 0, + "line" : 265 + }, + "uri" : "MixedFramework-Swift.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "myOtherProtocolMethod" + } + ], + "subHeading" : [ + { + "kind" : "text", + "spelling" : "- " + }, + { + "kind" : "identifier", + "spelling" : "myOtherProtocolMethod" + } + ], + "title" : "myOtherProtocolMethod" + }, + "pathComponents" : [ + "MyClassThatConformToMyOtherProtocol", + "myOtherProtocolMethod" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "text", + "spelling" : "- (" + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:v", + "spelling" : "void" + }, + { + "kind" : "text", + "spelling" : ") " + }, + { + "kind" : "identifier", + "spelling" : "myProtocolMethod" + }, + { + "kind" : "text", + "spelling" : ";" + } + ], + "functionSignature" : { + "parameters" : [ + + ], + "returns" : [ + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:v", + "spelling" : "void" + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol(im)myProtocolMethod" + }, + "kind" : { + "displayName" : "Instance Method", + "identifier" : "method" + }, + "location" : { + "position" : { + "character" : 0, + "line" : 266 + }, + "uri" : "MixedFramework-Swift.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "myProtocolMethod" + } + ], + "subHeading" : [ + { + "kind" : "text", + "spelling" : "- " + }, + { + "kind" : "identifier", + "spelling" : "myProtocolMethod" + } + ], + "title" : "myProtocolMethod" + }, + "pathComponents" : [ + "MyClassThatConformToMyOtherProtocol", + "myProtocolMethod" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "keyword", + "spelling" : "enum" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "identifier", + "spelling" : "MyEnum" + }, + { + "kind" : "text", + "spelling" : ": " + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:@T@NSInteger", + "spelling" : "NSInteger" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 35, + "line" : 270 + }, + "start" : { + "character" : 4, + "line" : 270 + } + }, + "text" : "My Objective-C compatible enum." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@M@MixedFramework@E@MyEnum" + }, + "kind" : { + "displayName" : "Enumeration", + "identifier" : "enum" + }, + "location" : { + "position" : { + "character" : 8, + "line" : 271 + }, + "uri" : "MixedFramework-Swift.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyEnum" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyEnum" + } + ], + "title" : "MyEnum" + }, + "pathComponents" : [ + "MyEnum" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "identifier", + "spelling" : "MyEnumFirstCase" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 24, + "line" : 272 + }, + "start" : { + "character" : 4, + "line" : 272 + } + }, + "text" : "The first enum case." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@M@MixedFramework@E@MyEnum@MyEnumFirstCase" + }, + "kind" : { + "displayName" : "Enumeration Case", + "identifier" : "enum.case" + }, + "location" : { + "position" : { + "character" : 2, + "line" : 273 + }, + "uri" : "MixedFramework-Swift.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyEnumFirstCase" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyEnumFirstCase" + } + ], + "title" : "MyEnumFirstCase" + }, + "pathComponents" : [ + "MyEnum", + "MyEnumFirstCase" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "identifier", + "spelling" : "MyEnumSecondCase" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 25, + "line" : 274 + }, + "start" : { + "character" : 4, + "line" : 274 + } + }, + "text" : "The second enum case." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@M@MixedFramework@E@MyEnum@MyEnumSecondCase" + }, + "kind" : { + "displayName" : "Enumeration Case", + "identifier" : "enum.case" + }, + "location" : { + "position" : { + "character" : 2, + "line" : 275 + }, + "uri" : "MixedFramework-Swift.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyEnumSecondCase" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyEnumSecondCase" + } + ], + "title" : "MyEnumSecondCase" + }, + "pathComponents" : [ + "MyEnum", + "MyEnumSecondCase" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "keyword", + "spelling" : "@interface" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "identifier", + "spelling" : "MyObjectiveCClassObjectiveCName" + }, + { + "kind" : "text", + "spelling" : " : " + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:objc(cs)NSObject", + "spelling" : "NSObject" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 68, + "line" : 11 + }, + "start" : { + "character" : 4, + "line" : 11 + } + }, + "text" : "An Objective-C class with different Swift and Objective-C names." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:objc(cs)MyObjectiveCClassObjectiveCName" + }, + "kind" : { + "displayName" : "Class", + "identifier" : "class" + }, + "location" : { + "position" : { + "character" : 11, + "line" : 13 + }, + "uri" : "ObjectiveCDeclarations.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCClassObjectiveCName" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCClassObjectiveCName" + } + ], + "title" : "MyObjectiveCClassObjectiveCName" + }, + "pathComponents" : [ + "MyObjectiveCClassObjectiveCName" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "text", + "spelling" : "- (" + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:v", + "spelling" : "void" + }, + { + "kind" : "text", + "spelling" : ") " + }, + { + "kind" : "identifier", + "spelling" : "myMethodObjectiveCName" + }, + { + "kind" : "text", + "spelling" : ";" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 56, + "line" : 18 + }, + "start" : { + "character" : 4, + "line" : 18 + } + }, + "text" : "A method with different Swift and Objective-C names." + } + ] + }, + "functionSignature" : { + "parameters" : [ + + ], + "returns" : [ + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:v", + "spelling" : "void" + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:objc(cs)MyObjectiveCClassObjectiveCName(im)myMethodObjectiveCName" + }, + "kind" : { + "displayName" : "Instance Method", + "identifier" : "method" + }, + "location" : { + "position" : { + "character" : 0, + "line" : 19 + }, + "uri" : "ObjectiveCDeclarations.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "myMethodObjectiveCName" + } + ], + "subHeading" : [ + { + "kind" : "text", + "spelling" : "- " + }, + { + "kind" : "identifier", + "spelling" : "myMethodObjectiveCName" + } + ], + "title" : "myMethodObjectiveCName" + }, + "pathComponents" : [ + "MyObjectiveCClassObjectiveCName", + "myMethodObjectiveCName" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "text", + "spelling" : "- (" + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:v", + "spelling" : "void" + }, + { + "kind" : "text", + "spelling" : ") " + }, + { + "kind" : "identifier", + "spelling" : "myMethodWithArgument:" + }, + { + "kind" : "text", + "spelling" : "(" + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:objc(cs)NSString", + "spelling" : "NSString" + }, + { + "kind" : "text", + "spelling" : " *)" + }, + { + "kind" : "internalParam", + "spelling" : "argument" + }, + { + "kind" : "text", + "spelling" : ";" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 56, + "line" : 22 + }, + "start" : { + "character" : 4, + "line" : 22 + } + }, + "text" : "A method with different Swift and Objective-C names." + }, + { + "range" : { + "end" : { + "character" : 17, + "line" : 23 + }, + "start" : { + "character" : 4, + "line" : 23 + } + }, + "text" : "- Parameters:" + }, + { + "range" : { + "end" : { + "character" : 29, + "line" : 24 + }, + "start" : { + "character" : 4, + "line" : 24 + } + }, + "text" : " - argument: An argument" + } + ] + }, + "functionSignature" : { + "parameters" : [ + { + "children" : [ + + ], + "declarationFragments" : [ + { + "kind" : "text", + "spelling" : "(" + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:objc(cs)NSString", + "spelling" : "NSString" + }, + { + "kind" : "text", + "spelling" : " *)" + }, + { + "kind" : "internalParam", + "spelling" : "argument" + } + ], + "name" : "argument" + } + ], + "returns" : [ + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:v", + "spelling" : "void" + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:objc(cs)MyObjectiveCClassObjectiveCName(im)myMethodWithArgument:" + }, + "kind" : { + "displayName" : "Instance Method", + "identifier" : "method" + }, + "location" : { + "position" : { + "character" : 0, + "line" : 25 + }, + "uri" : "ObjectiveCDeclarations.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "myMethodWithArgument:" + } + ], + "subHeading" : [ + { + "kind" : "text", + "spelling" : "- " + }, + { + "kind" : "identifier", + "spelling" : "myMethodWithArgument:" + } + ], + "title" : "myMethodWithArgument:" + }, + "pathComponents" : [ + "MyObjectiveCClassObjectiveCName", + "myMethodWithArgument:" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "keyword", + "spelling" : "@property" + }, + { + "kind" : "text", + "spelling" : " (" + }, + { + "kind" : "keyword", + "spelling" : "atomic" + }, + { + "kind" : "text", + "spelling" : ", " + }, + { + "kind" : "keyword", + "spelling" : "copy" + }, + { + "kind" : "text", + "spelling" : ", " + }, + { + "kind" : "keyword", + "spelling" : "readonly" + }, + { + "kind" : "text", + "spelling" : ") " + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:objc(cs)NSString", + "spelling" : "NSString" + }, + { + "kind" : "text", + "spelling" : " *" + }, + { + "kind" : "identifier", + "spelling" : "myPropertyObjectiveCName" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 58, + "line" : 15 + }, + "start" : { + "character" : 4, + "line" : 15 + } + }, + "text" : "A property with different Swift and Objective-C names." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:objc(cs)MyObjectiveCClassObjectiveCName(py)myPropertyObjectiveCName" + }, + "isReadOnly" : true, + "kind" : { + "displayName" : "Instance Property", + "identifier" : "property" + }, + "location" : { + "position" : { + "character" : 38, + "line" : 16 + }, + "uri" : "ObjectiveCDeclarations.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "myPropertyObjectiveCName" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "myPropertyObjectiveCName" + } + ], + "title" : "myPropertyObjectiveCName" + }, + "pathComponents" : [ + "MyObjectiveCClassObjectiveCName", + "myPropertyObjectiveCName" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "keyword", + "spelling" : "@protocol" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "identifier", + "spelling" : "MyObjectiveCCompatibleProtocol" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 38, + "line" : 279 + }, + "start" : { + "character" : 4, + "line" : 279 + } + }, + "text" : "My Objective-C compatible protocol" + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol" + }, + "kind" : { + "displayName" : "Protocol", + "identifier" : "protocol" + }, + "location" : { + "position" : { + "character" : 10, + "line" : 281 + }, + "uri" : "MixedFramework-Swift.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCCompatibleProtocol" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCCompatibleProtocol" + } + ], + "title" : "MyObjectiveCCompatibleProtocol" + }, + "pathComponents" : [ + "MyObjectiveCCompatibleProtocol" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "text", + "spelling" : "- (" + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:v", + "spelling" : "void" + }, + { + "kind" : "text", + "spelling" : ") " + }, + { + "kind" : "identifier", + "spelling" : "myPropertyOptionalMethod" + }, + { + "kind" : "text", + "spelling" : ";" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 47, + "line" : 290 + }, + "start" : { + "character" : 4, + "line" : 290 + } + }, + "text" : "An optional method\/function of my protocol." + } + ] + }, + "functionSignature" : { + "parameters" : [ + + ], + "returns" : [ + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:v", + "spelling" : "void" + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(im)myPropertyOptionalMethod" + }, + "kind" : { + "displayName" : "Instance Method", + "identifier" : "method" + }, + "location" : { + "position" : { + "character" : 0, + "line" : 291 + }, + "uri" : "MixedFramework-Swift.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "myPropertyOptionalMethod" + } + ], + "subHeading" : [ + { + "kind" : "text", + "spelling" : "- " + }, + { + "kind" : "identifier", + "spelling" : "myPropertyOptionalMethod" + } + ], + "title" : "myPropertyOptionalMethod" + }, + "pathComponents" : [ + "MyObjectiveCCompatibleProtocol", + "myPropertyOptionalMethod" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "text", + "spelling" : "- (" + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:v", + "spelling" : "void" + }, + { + "kind" : "text", + "spelling" : ") " + }, + { + "kind" : "identifier", + "spelling" : "myProtocolMethod" + }, + { + "kind" : "text", + "spelling" : ";" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 37, + "line" : 282 + }, + "start" : { + "character" : 4, + "line" : 282 + } + }, + "text" : "A method\/function on my protocol." + } + ] + }, + "functionSignature" : { + "parameters" : [ + + ], + "returns" : [ + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:v", + "spelling" : "void" + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(im)myProtocolMethod" + }, + "kind" : { + "displayName" : "Instance Method", + "identifier" : "method" + }, + "location" : { + "position" : { + "character" : 0, + "line" : 283 + }, + "uri" : "MixedFramework-Swift.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "myProtocolMethod" + } + ], + "subHeading" : [ + { + "kind" : "text", + "spelling" : "- " + }, + { + "kind" : "identifier", + "spelling" : "myProtocolMethod" + } + ], + "title" : "myProtocolMethod" + }, + "pathComponents" : [ + "MyObjectiveCCompatibleProtocol", + "myProtocolMethod" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "keyword", + "spelling" : "@property" + }, + { + "kind" : "text", + "spelling" : " (" + }, + { + "kind" : "keyword", + "spelling" : "nonatomic" + }, + { + "kind" : "text", + "spelling" : ", " + }, + { + "kind" : "keyword", + "spelling" : "strong" + }, + { + "kind" : "text", + "spelling" : ", " + }, + { + "kind" : "keyword", + "spelling" : "readonly" + }, + { + "kind" : "text", + "spelling" : ") " + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:@M@MixedFramework@objc(cs)MyClass", + "spelling" : "MyClass" + }, + { + "kind" : "text", + "spelling" : " *" + }, + { + "kind" : "identifier", + "spelling" : "myProtocolProperty" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 30, + "line" : 284 + }, + "start" : { + "character" : 4, + "line" : 284 + } + }, + "text" : "A property on my protocol." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(py)myProtocolProperty" + }, + "isReadOnly" : true, + "kind" : { + "displayName" : "Instance Property", + "identifier" : "property" + }, + "location" : { + "position" : { + "character" : 59, + "line" : 285 + }, + "uri" : "MixedFramework-Swift.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "myProtocolProperty" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "myProtocolProperty" + } + ], + "title" : "myProtocolProperty" + }, + "pathComponents" : [ + "MyObjectiveCCompatibleProtocol", + "myProtocolProperty" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "keyword", + "spelling" : "@property" + }, + { + "kind" : "text", + "spelling" : " (" + }, + { + "kind" : "keyword", + "spelling" : "class" + }, + { + "kind" : "text", + "spelling" : ", " + }, + { + "kind" : "keyword", + "spelling" : "nonatomic" + }, + { + "kind" : "text", + "spelling" : ", " + }, + { + "kind" : "keyword", + "spelling" : "strong" + }, + { + "kind" : "text", + "spelling" : ", " + }, + { + "kind" : "keyword", + "spelling" : "readonly" + }, + { + "kind" : "text", + "spelling" : ") " + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:@M@MixedFramework@objc(cs)MyClass", + "spelling" : "MyClass" + }, + { + "kind" : "text", + "spelling" : " *" + }, + { + "kind" : "identifier", + "spelling" : "myProtocolTypeProperty" + } + ], + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(cpy)myProtocolTypeProperty" + }, + "isReadOnly" : true, + "kind" : { + "displayName" : "Type Property", + "identifier" : "type.property" + }, + "location" : { + "position" : { + "character" : 0, + "line" : 287 + }, + "uri" : "MixedFramework-Swift.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "myProtocolTypeProperty" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "myProtocolTypeProperty" + } + ], + "title" : "myProtocolTypeProperty" + }, + "pathComponents" : [ + "MyObjectiveCCompatibleProtocol", + "myProtocolTypeProperty" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "keyword", + "spelling" : "enum" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "identifier", + "spelling" : "MyObjectiveCEnum" + }, + { + "kind" : "text", + "spelling" : ": " + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:@T@NSInteger", + "spelling" : "NSInteger" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 21, + "line" : 29 + }, + "start" : { + "character" : 4, + "line" : 29 + } + }, + "text" : "A `NS_ENUM` type." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@E@MyObjectiveCEnum" + }, + "kind" : { + "displayName" : "Enumeration", + "identifier" : "enum" + }, + "location" : { + "position" : { + "character" : 8, + "line" : 30 + }, + "uri" : "ObjectiveCDeclarations.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCEnum" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCEnum" + } + ], + "title" : "MyObjectiveCEnum" + }, + "pathComponents" : [ + "MyObjectiveCEnum" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCEnumFirst" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 35, + "line" : 31 + }, + "start" : { + "character" : 8, + "line" : 31 + } + }, + "text" : "The first enumeration case." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@E@MyObjectiveCEnum@MyObjectiveCEnumFirst" + }, + "kind" : { + "displayName" : "Enumeration Case", + "identifier" : "enum.case" + }, + "location" : { + "position" : { + "character" : 4, + "line" : 32 + }, + "uri" : "ObjectiveCDeclarations.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCEnumFirst" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCEnumFirst" + } + ], + "title" : "MyObjectiveCEnumFirst" + }, + "pathComponents" : [ + "MyObjectiveCEnum", + "MyObjectiveCEnumFirst" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCEnumSecond" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 81, + "line" : 33 + }, + "start" : { + "character" : 8, + "line" : 33 + } + }, + "text" : "The second enumeration case (with different Swift and Objective-C names)." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@E@MyObjectiveCEnum@MyObjectiveCEnumSecond" + }, + "kind" : { + "displayName" : "Enumeration Case", + "identifier" : "enum.case" + }, + "location" : { + "position" : { + "character" : 4, + "line" : 34 + }, + "uri" : "ObjectiveCDeclarations.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCEnumSecond" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCEnumSecond" + } + ], + "title" : "MyObjectiveCEnumSecond" + }, + "pathComponents" : [ + "MyObjectiveCEnum", + "MyObjectiveCEnumSecond" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "keyword", + "spelling" : "enum" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "identifier", + "spelling" : "MyObjectiveCEnumObjectiveCName" + }, + { + "kind" : "text", + "spelling" : ": " + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:@T@NSInteger", + "spelling" : "NSInteger" + } + ], + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@E@MyObjectiveCEnumObjectiveCName" + }, + "kind" : { + "displayName" : "Enumeration", + "identifier" : "enum" + }, + "location" : { + "position" : { + "character" : 8, + "line" : 37 + }, + "uri" : "ObjectiveCDeclarations.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCEnumObjectiveCName" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCEnumObjectiveCName" + } + ], + "title" : "MyObjectiveCEnumObjectiveCName" + }, + "pathComponents" : [ + "MyObjectiveCEnumObjectiveCName" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCEnumObjectiveCNameFirst" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 35, + "line" : 38 + }, + "start" : { + "character" : 8, + "line" : 38 + } + }, + "text" : "The first enumeration case." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@E@MyObjectiveCEnumObjectiveCName@MyObjectiveCEnumObjectiveCNameFirst" + }, + "kind" : { + "displayName" : "Enumeration Case", + "identifier" : "enum.case" + }, + "location" : { + "position" : { + "character" : 4, + "line" : 39 + }, + "uri" : "ObjectiveCDeclarations.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCEnumObjectiveCNameFirst" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCEnumObjectiveCNameFirst" + } + ], + "title" : "MyObjectiveCEnumObjectiveCNameFirst" + }, + "pathComponents" : [ + "MyObjectiveCEnumObjectiveCName", + "MyObjectiveCEnumObjectiveCNameFirst" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCEnumObjectiveCNameSecond" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 81, + "line" : 40 + }, + "start" : { + "character" : 8, + "line" : 40 + } + }, + "text" : "The second enumeration case (with different Swift and Objective-C names)." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@E@MyObjectiveCEnumObjectiveCName@MyObjectiveCEnumObjectiveCNameSecond" + }, + "kind" : { + "displayName" : "Enumeration Case", + "identifier" : "enum.case" + }, + "location" : { + "position" : { + "character" : 4, + "line" : 41 + }, + "uri" : "ObjectiveCDeclarations.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCEnumObjectiveCNameSecond" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCEnumObjectiveCNameSecond" + } + ], + "title" : "MyObjectiveCEnumObjectiveCNameSecond" + }, + "pathComponents" : [ + "MyObjectiveCEnumObjectiveCName", + "MyObjectiveCEnumObjectiveCNameSecond" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "keyword", + "spelling" : "enum" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "identifier", + "spelling" : "MyObjectiveCOption" + }, + { + "kind" : "text", + "spelling" : ": " + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:@T@NSInteger", + "spelling" : "NSInteger" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 23, + "line" : 44 + }, + "start" : { + "character" : 4, + "line" : 44 + } + }, + "text" : "A `NS_OPTION` type." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@E@MyObjectiveCOption" + }, + "kind" : { + "displayName" : "Enumeration", + "identifier" : "enum" + }, + "location" : { + "position" : { + "character" : 8, + "line" : 45 + }, + "uri" : "ObjectiveCDeclarations.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCOption" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCOption" + } + ], + "title" : "MyObjectiveCOption" + }, + "pathComponents" : [ + "MyObjectiveCOption" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCOptionFirst" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 30, + "line" : 48 + }, + "start" : { + "character" : 8, + "line" : 48 + } + }, + "text" : "The first option case." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@E@MyObjectiveCOption@MyObjectiveCOptionFirst" + }, + "kind" : { + "displayName" : "Enumeration Case", + "identifier" : "enum.case" + }, + "location" : { + "position" : { + "character" : 4, + "line" : 49 + }, + "uri" : "ObjectiveCDeclarations.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCOptionFirst" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCOptionFirst" + } + ], + "title" : "MyObjectiveCOptionFirst" + }, + "pathComponents" : [ + "MyObjectiveCOption", + "MyObjectiveCOptionFirst" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCOptionNone" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 31, + "line" : 46 + }, + "start" : { + "character" : 8, + "line" : 46 + } + }, + "text" : "The \"none\" option case." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@E@MyObjectiveCOption@MyObjectiveCOptionNone" + }, + "kind" : { + "displayName" : "Enumeration Case", + "identifier" : "enum.case" + }, + "location" : { + "position" : { + "character" : 4, + "line" : 47 + }, + "uri" : "ObjectiveCDeclarations.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCOptionNone" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCOptionNone" + } + ], + "title" : "MyObjectiveCOptionNone" + }, + "pathComponents" : [ + "MyObjectiveCOption", + "MyObjectiveCOptionNone" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCOptionSecond" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 31, + "line" : 50 + }, + "start" : { + "character" : 8, + "line" : 50 + } + }, + "text" : "The second option case." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@E@MyObjectiveCOption@MyObjectiveCOptionSecond" + }, + "kind" : { + "displayName" : "Enumeration Case", + "identifier" : "enum.case" + }, + "location" : { + "position" : { + "character" : 4, + "line" : 51 + }, + "uri" : "ObjectiveCDeclarations.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCOptionSecond" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyObjectiveCOptionSecond" + } + ], + "title" : "MyObjectiveCOptionSecond" + }, + "pathComponents" : [ + "MyObjectiveCOption", + "MyObjectiveCOptionSecond" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "keyword", + "spelling" : "@interface" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "identifier", + "spelling" : "MySwiftClassObjectiveCName" + }, + { + "kind" : "text", + "spelling" : " : " + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:objc(cs)NSObject", + "spelling" : "NSObject" + } + ], + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName" + }, + "kind" : { + "displayName" : "Class", + "identifier" : "class" + }, + "location" : { + "position" : { + "character" : 11, + "line" : 296 + }, + "uri" : "MixedFramework-Swift.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MySwiftClassObjectiveCName" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MySwiftClassObjectiveCName" + } + ], + "title" : "MySwiftClassObjectiveCName" + }, + "pathComponents" : [ + "MySwiftClassObjectiveCName" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "text", + "spelling" : "- (" + }, + { + "kind" : "keyword", + "spelling" : "id" + }, + { + "kind" : "text", + "spelling" : ") " + }, + { + "kind" : "identifier", + "spelling" : "init" + }, + { + "kind" : "text", + "spelling" : ";" + } + ], + "functionSignature" : { + "parameters" : [ + + ], + "returns" : [ + { + "kind" : "keyword", + "spelling" : "id" + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName(im)init" + }, + "kind" : { + "displayName" : "Instance Method", + "identifier" : "method" + }, + "location" : { + "position" : { + "character" : 0, + "line" : 299 + }, + "uri" : "MixedFramework-Swift.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "init" + } + ], + "subHeading" : [ + { + "kind" : "text", + "spelling" : "- " + }, + { + "kind" : "identifier", + "spelling" : "init" + } + ], + "title" : "init" + }, + "pathComponents" : [ + "MySwiftClassObjectiveCName", + "init" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "text", + "spelling" : "- (" + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:@T@NSInteger", + "spelling" : "NSInteger" + }, + { + "kind" : "text", + "spelling" : ") " + }, + { + "kind" : "identifier", + "spelling" : "myMethodObjectiveCName" + }, + { + "kind" : "text", + "spelling" : ";" + } + ], + "functionSignature" : { + "parameters" : [ + + ], + "returns" : [ + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:@T@NSInteger", + "spelling" : "NSInteger" + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName(im)myMethodObjectiveCName" + }, + "kind" : { + "displayName" : "Instance Method", + "identifier" : "method" + }, + "location" : { + "position" : { + "character" : 0, + "line" : 298 + }, + "uri" : "MixedFramework-Swift.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "myMethodObjectiveCName" + } + ], + "subHeading" : [ + { + "kind" : "text", + "spelling" : "- " + }, + { + "kind" : "identifier", + "spelling" : "myMethodObjectiveCName" + } + ], + "title" : "myMethodObjectiveCName" + }, + "pathComponents" : [ + "MySwiftClassObjectiveCName", + "myMethodObjectiveCName" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "keyword", + "spelling" : "@property" + }, + { + "kind" : "text", + "spelling" : " (" + }, + { + "kind" : "keyword", + "spelling" : "nonatomic" + }, + { + "kind" : "text", + "spelling" : ", " + }, + { + "kind" : "keyword", + "spelling" : "readonly" + }, + { + "kind" : "text", + "spelling" : ") " + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:@T@NSInteger", + "spelling" : "NSInteger" + }, + { + "kind" : "identifier", + "spelling" : "myPropertyObjectiveCName" + } + ], + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName(py)myPropertyObjectiveCName" + }, + "isReadOnly" : true, + "kind" : { + "displayName" : "Instance Property", + "identifier" : "property" + }, + "location" : { + "position" : { + "character" : 42, + "line" : 297 + }, + "uri" : "MixedFramework-Swift.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "myPropertyObjectiveCName" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "myPropertyObjectiveCName" + } + ], + "title" : "myPropertyObjectiveCName" + }, + "pathComponents" : [ + "MySwiftClassObjectiveCName", + "myPropertyObjectiveCName" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "keyword", + "spelling" : "typedef" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:@T@NSInteger", + "spelling" : "NSInteger" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "identifier", + "spelling" : "MyTypedObjectiveCEnum" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 27, + "line" : 54 + }, + "start" : { + "character" : 4, + "line" : 54 + } + }, + "text" : "A `NS_TYPED_ENUM` type." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum" + }, + "kind" : { + "displayName" : "Type Alias", + "identifier" : "typealias" + }, + "location" : { + "position" : { + "character" : 18, + "line" : 55 + }, + "uri" : "ObjectiveCDeclarations.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyTypedObjectiveCEnum" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyTypedObjectiveCEnum" + } + ], + "title" : "MyTypedObjectiveCEnum" + }, + "pathComponents" : [ + "MyTypedObjectiveCEnum" + ], + "type" : "c:@T@NSInteger" + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "keyword", + "spelling" : "const" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum", + "spelling" : "MyTypedObjectiveCEnum" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "identifier", + "spelling" : "MyTypedObjectiveCEnumFirst" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 31, + "line" : 57 + }, + "start" : { + "character" : 4, + "line" : 57 + } + }, + "text" : "The first typed enum value." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@MyTypedObjectiveCEnumFirst" + }, + "kind" : { + "displayName" : "Global Variable", + "identifier" : "var" + }, + "location" : { + "position" : { + "character" : 28, + "line" : 58 + }, + "uri" : "ObjectiveCDeclarations.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyTypedObjectiveCEnumFirst" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyTypedObjectiveCEnumFirst" + } + ], + "title" : "MyTypedObjectiveCEnumFirst" + }, + "pathComponents" : [ + "MyTypedObjectiveCEnumFirst" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "keyword", + "spelling" : "const" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum", + "spelling" : "MyTypedObjectiveCEnum" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "identifier", + "spelling" : "MyTypedObjectiveCEnumSecond" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 32, + "line" : 59 + }, + "start" : { + "character" : 4, + "line" : 59 + } + }, + "text" : "The second typed enum value." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@MyTypedObjectiveCEnumSecond" + }, + "kind" : { + "displayName" : "Global Variable", + "identifier" : "var" + }, + "location" : { + "position" : { + "character" : 28, + "line" : 60 + }, + "uri" : "ObjectiveCDeclarations.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyTypedObjectiveCEnumSecond" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyTypedObjectiveCEnumSecond" + } + ], + "title" : "MyTypedObjectiveCEnumSecond" + }, + "pathComponents" : [ + "MyTypedObjectiveCEnumSecond" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "keyword", + "spelling" : "typedef" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:@T@NSInteger", + "spelling" : "NSInteger" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "identifier", + "spelling" : "MyTypedObjectiveCExtensibleEnum" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 38, + "line" : 62 + }, + "start" : { + "character" : 4, + "line" : 62 + } + }, + "text" : "A `NS_TYPED_EXTENSIBLE_ENUM` type." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum" + }, + "kind" : { + "displayName" : "Type Alias", + "identifier" : "typealias" + }, + "location" : { + "position" : { + "character" : 18, + "line" : 63 + }, + "uri" : "ObjectiveCDeclarations.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyTypedObjectiveCExtensibleEnum" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyTypedObjectiveCExtensibleEnum" + } + ], + "title" : "MyTypedObjectiveCExtensibleEnum" + }, + "pathComponents" : [ + "MyTypedObjectiveCExtensibleEnum" + ], + "type" : "c:@T@NSInteger" + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "keyword", + "spelling" : "const" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum", + "spelling" : "MyTypedObjectiveCExtensibleEnum" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "identifier", + "spelling" : "MyTypedObjectiveCExtensibleEnumFirst" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 36, + "line" : 65 + }, + "start" : { + "character" : 4, + "line" : 65 + } + }, + "text" : "The first extensible enum value." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@MyTypedObjectiveCExtensibleEnumFirst" + }, + "kind" : { + "displayName" : "Global Variable", + "identifier" : "var" + }, + "location" : { + "position" : { + "character" : 38, + "line" : 66 + }, + "uri" : "ObjectiveCDeclarations.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyTypedObjectiveCExtensibleEnumFirst" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyTypedObjectiveCExtensibleEnumFirst" + } + ], + "title" : "MyTypedObjectiveCExtensibleEnumFirst" + }, + "pathComponents" : [ + "MyTypedObjectiveCExtensibleEnumFirst" + ] + }, + { + "accessLevel" : "public", + "declarationFragments" : [ + { + "kind" : "keyword", + "spelling" : "const" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "typeIdentifier", + "preciseIdentifier" : "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum", + "spelling" : "MyTypedObjectiveCExtensibleEnum" + }, + { + "kind" : "text", + "spelling" : " " + }, + { + "kind" : "identifier", + "spelling" : "MyTypedObjectiveCExtensibleEnumSecond" + } + ], + "docComment" : { + "lines" : [ + { + "range" : { + "end" : { + "character" : 37, + "line" : 67 + }, + "start" : { + "character" : 4, + "line" : 67 + } + }, + "text" : "The second extensible enum value." + } + ] + }, + "identifier" : { + "interfaceLanguage" : "occ", + "precise" : "c:@MyTypedObjectiveCExtensibleEnumSecond" + }, + "kind" : { + "displayName" : "Global Variable", + "identifier" : "var" + }, + "location" : { + "position" : { + "character" : 38, + "line" : 68 + }, + "uri" : "ObjectiveCDeclarations.h" + }, + "names" : { + "navigator" : [ + { + "kind" : "identifier", + "spelling" : "MyTypedObjectiveCExtensibleEnumSecond" + } + ], + "subHeading" : [ + { + "kind" : "identifier", + "spelling" : "MyTypedObjectiveCExtensibleEnumSecond" + } + ], + "title" : "MyTypedObjectiveCExtensibleEnumSecond" + }, + "pathComponents" : [ + "MyTypedObjectiveCExtensibleEnumSecond" + ] + } + ] +} \ No newline at end of file diff --git a/Tests/SwiftDocCTests/Test Bundles/MixedLanguageFrameworkWithLanguageRefinements.docc/symbol-graph/swift/x86_64-apple-macos/MixedFramework.symbols.json b/Tests/SwiftDocCTests/Test Bundles/MixedLanguageFrameworkWithLanguageRefinements.docc/symbol-graph/swift/x86_64-apple-macos/MixedFramework.symbols.json new file mode 100644 index 0000000000..f603c35f4e --- /dev/null +++ b/Tests/SwiftDocCTests/Test Bundles/MixedLanguageFrameworkWithLanguageRefinements.docc/symbol-graph/swift/x86_64-apple-macos/MixedFramework.symbols.json @@ -0,0 +1,15399 @@ +{ + "metadata": { + "formatVersion": { + "major": 0, + "minor": 5, + "patch": 3 + }, + "generator": "Apple Swift version 5.7 (swiftlang-5.7.0.113.201 clang-1400.0.16.2)" + }, + "module": { + "name": "MixedFramework", + "platform": { + "architecture": "x86_64", + "vendor": "apple", + "operatingSystem": { + "name": "macosx", + "minimumVersion": { + "major": 12, + "minor": 3, + "patch": 0 + } + } + } + }, + "symbols": [ + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:s20_SwiftNewtypeWrapperPsSHRzSH8RawValueSYRpzrlE4hash4intoys6HasherVz_tF::SYNTHESIZED::c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyTypedObjectiveCEnum", + "hash(into:)" + ], + "names": { + "title": "hash(into:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hash" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "into" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "keyword", + "spelling": "inout" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "typeIdentifier", + "spelling": "Hasher", + "preciseIdentifier": "s:s6HasherV" + }, + { + "kind": "text", + "spelling": ")" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Hashes the essential components of this value by feeding them into the" + }, + { + "text": "given hasher." + }, + { + "text": "" + }, + { + "text": "- Parameter hasher: The hasher to use when combining the components" + }, + { + "text": " of this instance." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "into", + "internalName": "hasher", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "hasher" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Hasher", + "preciseIdentifier": "s:s6HasherV" + } + ] + } + ], + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "swiftGenerics": { + "constraints": [ + { + "kind": "conformance", + "lhs": "Self", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + }, + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift", + "constraints": [ + { + "kind": "conformance", + "lhs": "Self", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + }, + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hash" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "into" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "hasher" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "keyword", + "spelling": "inout" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "typeIdentifier", + "spelling": "Hasher", + "preciseIdentifier": "s:s6HasherV" + }, + { + "kind": "text", + "spelling": ")" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:s9OptionSetPss17FixedWidthInteger8RawValueRpzrlE16formIntersectionyyxF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "formIntersection(_:)" + ], + "names": { + "title": "formIntersection(_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "formIntersection" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ")" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Removes all elements of this option set that are not " + }, + { + "text": "also present in the given set." + }, + { + "text": "" + }, + { + "text": "This method is implemented as a `&` (bitwise AND) operation on the" + }, + { + "text": "two sets' raw values." + }, + { + "text": "" + }, + { + "text": "- Parameter other: An option set." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "other", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "swiftGenerics": { + "constraints": [ + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "FixedWidthInteger", + "rhsPrecise": "s:s17FixedWidthIntegerP" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift", + "constraints": [ + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "FixedWidthInteger", + "rhsPrecise": "s:s17FixedWidthIntegerP" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "mutating" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "formIntersection" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "_" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ")" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.struct", + "displayName": "Structure" + }, + "identifier": { + "precise": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyTypedObjectiveCExtensibleEnum" + ], + "names": { + "title": "MyTypedObjectiveCExtensibleEnum", + "navigator": [ + { + "kind": "identifier", + "spelling": "MyTypedObjectiveCExtensibleEnum" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "struct" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyTypedObjectiveCExtensibleEnum" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "struct" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyTypedObjectiveCExtensibleEnum" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.enum", + "displayName": "Enumeration" + }, + "identifier": { + "precise": "s:14MixedFramework28CollisionsWithDifferentKindsO", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "CollisionsWithDifferentKinds" + ], + "names": { + "title": "CollisionsWithDifferentKinds", + "navigator": [ + { + "kind": "identifier", + "spelling": "CollisionsWithDifferentKinds" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "enum" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "CollisionsWithDifferentKinds" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 19, + "character": 4 + }, + "end": { + "line": 19, + "character": 66 + } + }, + "text": "A container for colliding symbols with different symbol kinds." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "enum" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "CollisionsWithDifferentKinds" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithVariousCollisions.swift", + "position": { + "line": 20, + "character": 12 + } + } + }, + { + "kind": { + "identifier": "swift.init", + "displayName": "Initializer" + }, + "identifier": { + "precise": "s:So016MyObjectiveCEnumB5CNameV8rawValueABSgSi_tcfc", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCEnumSwiftName", + "init(rawValue:)" + ], + "names": { + "title": "init(rawValue:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "init" + }, + { + "kind": "text", + "spelling": "?(" + }, + { + "kind": "externalParam", + "spelling": "rawValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": ")" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "init" + }, + { + "kind": "text", + "spelling": "?(" + }, + { + "kind": "externalParam", + "spelling": "rawValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": ")" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.func.op", + "displayName": "Operator" + }, + "identifier": { + "precise": "s:SQsE2neoiySbx_xtFZ::SYNTHESIZED::c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyTypedObjectiveCEnum", + "!=(_:_:)" + ], + "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.typealias", + "displayName": "Type Alias" + }, + "identifier": { + "precise": "s:14MixedFramework30MyObjectiveCCompatibleProtocolP0cF9TypeAliasa", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCCompatibleProtocol", + "MyProtocolTypeAlias" + ], + "names": { + "title": "MyObjectiveCCompatibleProtocol.MyProtocolTypeAlias", + "navigator": [ + { + "kind": "identifier", + "spelling": "MyProtocolTypeAlias" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "typealias" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyProtocolTypeAlias" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 56, + "character": 8 + }, + "end": { + "line": 56, + "character": 36 + } + }, + "text": "A type alias on my protocol." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "typealias" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyProtocolTypeAlias" + }, + { + "kind": "text", + "spelling": " = " + }, + { + "kind": "typeIdentifier", + "spelling": "MyClass", + "preciseIdentifier": "c:@M@MixedFramework@objc(cs)MyClass" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 57, + "character": 14 + } + } + }, + { + "kind": { + "identifier": "swift.var", + "displayName": "Global Variable" + }, + "identifier": { + "precise": "s:14MixedFramework18myTopLevelVariableSbvp", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "myTopLevelVariable" + ], + "names": { + "title": "myTopLevelVariable", + "subHeading": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myTopLevelVariable" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 86, + "character": 4 + }, + "end": { + "line": 86, + "character": 25 + } + }, + "text": "My top-level variable" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myTopLevelVariable" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 87, + "character": 11 + } + } + }, + { + "kind": { + "identifier": "swift.property", + "displayName": "Instance Property" + }, + "identifier": { + "precise": "s:14MixedFramework28CollisionsWithDifferentKindsO9somethingSSvp", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "CollisionsWithDifferentKinds", + "something" + ], + "names": { + "title": "something", + "subHeading": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "something" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "String", + "preciseIdentifier": "s:SS" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 23, + "character": 8 + }, + "end": { + "line": 23, + "character": 35 + } + }, + "text": "A \"something\" enum property" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "something" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "String", + "preciseIdentifier": "s:SS" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithVariousCollisions.swift", + "position": { + "line": 24, + "character": 15 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:14MixedFramework40CollisionsWithDifferentFunctionArgumentsO9something8argumentS2i_tF", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "CollisionsWithDifferentFunctionArguments", + "something(argument:)" + ], + "names": { + "title": "something(argument:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "something" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "argument" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 48, + "character": 8 + }, + "end": { + "line": 48, + "character": 52 + } + }, + "text": "A subscript with a \"something\" Int argument." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "argument", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "argument" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "something" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "argument" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithVariousCollisions.swift", + "position": { + "line": 49, + "character": 16 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:s10SetAlgebraPsE8isSubset2ofSbx_tF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "isSubset(of:)" + ], + "names": { + "title": "isSubset(of:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "isSubset" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "of" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Returns a Boolean value that indicates whether the set is a subset of" + }, + { + "text": "another set." + }, + { + "text": "" + }, + { + "text": "Set *A* is a subset of another set *B* if every member of *A* is also a" + }, + { + "text": "member of *B*." + }, + { + "text": "" + }, + { + "text": " let employees: Set = [\"Alicia\", \"Bethany\", \"Chris\", \"Diana\", \"Eric\"]" + }, + { + "text": " let attendees: Set = [\"Alicia\", \"Bethany\", \"Diana\"]" + }, + { + "text": " print(attendees.isSubset(of: employees))" + }, + { + "text": " // Prints \"true\"" + }, + { + "text": "" + }, + { + "text": "- Parameter other: A set of the same type as the current set." + }, + { + "text": "- Returns: `true` if the set is a subset of `other`; otherwise, `false`." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "of", + "internalName": "other", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "isSubset" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "of" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.class", + "displayName": "Class" + }, + "identifier": { + "precise": "s:14MixedFramework29CollisionsWithEscapedKeywordsC", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "CollisionsWithEscapedKeywords" + ], + "names": { + "title": "CollisionsWithEscapedKeywords", + "navigator": [ + { + "kind": "identifier", + "spelling": "CollisionsWithEscapedKeywords" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "class" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "CollisionsWithEscapedKeywords" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 29, + "character": 4 + }, + "end": { + "line": 29, + "character": 66 + } + }, + "text": "A container for colliding symbols with different symbol kinds." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "final" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "class" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "CollisionsWithEscapedKeywords" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithVariousCollisions.swift", + "position": { + "line": 30, + "character": 19 + } + } + }, + { + "kind": { + "identifier": "swift.property", + "displayName": "Instance Property" + }, + "identifier": { + "precise": "s:s20_SwiftNewtypeWrapperPsSHRzSH8RawValueSYRpzrlE04hashE0Sivp::SYNTHESIZED::c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyTypedObjectiveCExtensibleEnum", + "hashValue" + ], + "names": { + "title": "hashValue", + "subHeading": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hashValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "The hash value." + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift", + "constraints": [ + { + "kind": "conformance", + "lhs": "Self", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + }, + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hashValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.type.property", + "displayName": "Type Property" + }, + "identifier": { + "precise": "c:@MyTypedObjectiveCEnumSecond", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyTypedObjectiveCEnum", + "second" + ], + "names": { + "title": "second", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "let" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "second" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyTypedObjectiveCEnum", + "preciseIdentifier": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum" + } + ] + }, + "swiftExtension": { + "extendedModule": "MixedFramework" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "let" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "second" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyTypedObjectiveCEnum", + "preciseIdentifier": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.func", + "displayName": "Function" + }, + "identifier": { + "precise": "s:14MixedFramework18myTopLevelFunctionyyF", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "myTopLevelFunction()" + ], + "names": { + "title": "myTopLevelFunction()", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myTopLevelFunction" + }, + { + "kind": "text", + "spelling": "()" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 83, + "character": 4 + }, + "end": { + "line": 83, + "character": 25 + } + }, + "text": "My top-level function" + } + ] + }, + "functionSignature": { + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myTopLevelFunction" + }, + { + "kind": "text", + "spelling": "()" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 84, + "character": 12 + } + } + }, + { + "kind": { + "identifier": "swift.property", + "displayName": "Instance Property" + }, + "identifier": { + "precise": "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(py)myProtocolProperty", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCCompatibleProtocol", + "myProtocolProperty" + ], + "names": { + "title": "myProtocolProperty", + "subHeading": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myProtocolProperty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyProtocolTypeAlias", + "preciseIdentifier": "s:14MixedFramework30MyObjectiveCCompatibleProtocolP0cF9TypeAliasa" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 58, + "character": 8 + }, + "end": { + "line": 58, + "character": 34 + } + }, + "text": "A property on my protocol." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myProtocolProperty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyProtocolTypeAlias", + "preciseIdentifier": "s:14MixedFramework30MyObjectiveCCompatibleProtocolP0cF9TypeAliasa" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 59, + "character": 8 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:s9OptionSetPsE5unionyxxF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "union(_:)" + ], + "names": { + "title": "union(_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "union" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Returns a new option set of the elements contained in this set, in the" + }, + { + "text": "given set, or in both." + }, + { + "text": "" + }, + { + "text": "This example uses the `union(_:)` method to add two more shipping options" + }, + { + "text": "to the default set." + }, + { + "text": "" + }, + { + "text": " let defaultShipping = ShippingOptions.standard" + }, + { + "text": " let memberShipping = defaultShipping.union([.secondDay, .priority])" + }, + { + "text": " print(memberShipping.contains(.priority))" + }, + { + "text": " // Prints \"true\"" + }, + { + "text": "" + }, + { + "text": "- Parameter other: An option set." + }, + { + "text": "- Returns: A new option set made up of the elements contained in this" + }, + { + "text": " set, in `other`, or in both." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "other", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "union" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "_" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.property", + "displayName": "Instance Property" + }, + "identifier": { + "precise": "s:SYsSHRzSH8RawValueSYRpzrlE04hashB0Sivp::SYNTHESIZED::c:@M@MixedFramework@E@MyEnum", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyEnum", + "hashValue" + ], + "names": { + "title": "hashValue", + "subHeading": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hashValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift", + "constraints": [ + { + "kind": "conformance", + "lhs": "Self", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + }, + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hashValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.struct", + "displayName": "Structure" + }, + "identifier": { + "precise": "c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption" + ], + "names": { + "title": "MyObjectiveCOption", + "navigator": [ + { + "kind": "identifier", + "spelling": "MyObjectiveCOption" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "struct" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyObjectiveCOption" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "struct" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyObjectiveCOption" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.typealias", + "displayName": "Type Alias" + }, + "identifier": { + "precise": "s:14MixedFramework11MyTypeAliasa", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyTypeAlias" + ], + "names": { + "title": "MyTypeAlias", + "navigator": [ + { + "kind": "identifier", + "spelling": "MyTypeAlias" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "typealias" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyTypeAlias" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 80, + "character": 4 + }, + "end": { + "line": 80, + "character": 18 + } + }, + "text": "My type alias." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "typealias" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyTypeAlias" + }, + { + "kind": "text", + "spelling": " = " + }, + { + "kind": "typeIdentifier", + "spelling": "MyStruct", + "preciseIdentifier": "s:14MixedFramework8MyStructV" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 81, + "character": 17 + } + } + }, + { + "kind": { + "identifier": "swift.typealias", + "displayName": "Type Alias" + }, + "identifier": { + "precise": "s:14MixedFramework28CollisionsWithDifferentKindsO9Somethinga", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "CollisionsWithDifferentKinds", + "Something" + ], + "names": { + "title": "CollisionsWithDifferentKinds.Something", + "navigator": [ + { + "kind": "identifier", + "spelling": "Something" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "typealias" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "Something" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 25, + "character": 8 + }, + "end": { + "line": 25, + "character": 32 + } + }, + "text": "A \"something\" type alias" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "typealias" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "Something" + }, + { + "kind": "text", + "spelling": " = " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithVariousCollisions.swift", + "position": { + "line": 26, + "character": 21 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:SYsSHRzSH8RawValueSYRpzrlE4hash4intoys6HasherVz_tF::SYNTHESIZED::c:@E@MyObjectiveCEnum", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCEnum", + "hash(into:)" + ], + "names": { + "title": "hash(into:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hash" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "into" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "keyword", + "spelling": "inout" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "typeIdentifier", + "spelling": "Hasher", + "preciseIdentifier": "s:s6HasherV" + }, + { + "kind": "text", + "spelling": ")" + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "into", + "internalName": "hasher", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "hasher" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Hasher", + "preciseIdentifier": "s:s6HasherV" + } + ] + } + ], + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "swiftGenerics": { + "constraints": [ + { + "kind": "conformance", + "lhs": "Self", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + }, + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift", + "constraints": [ + { + "kind": "conformance", + "lhs": "Self", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + }, + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hash" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "into" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "hasher" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "keyword", + "spelling": "inout" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "typeIdentifier", + "spelling": "Hasher", + "preciseIdentifier": "s:s6HasherV" + }, + { + "kind": "text", + "spelling": ")" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.property", + "displayName": "Instance Property" + }, + "identifier": { + "precise": "s:14MixedFramework8MyStructV02myD8PropertySivp", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyStruct", + "myStructProperty" + ], + "names": { + "title": "myStructProperty", + "subHeading": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myStructProperty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyStructTypeAlias", + "preciseIdentifier": "s:14MixedFramework8MyStructV0cD9TypeAliasa" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 30, + "character": 8 + }, + "end": { + "line": 30, + "character": 32 + } + }, + "text": "A property on my struct." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myStructProperty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyStructTypeAlias", + "preciseIdentifier": "s:14MixedFramework8MyStructV0cD9TypeAliasa" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 31, + "character": 15 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:14MixedFramework028MyOtherProtocolThatConformToc5SwiftE0P02mydE6MethodyyF", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyOtherProtocolThatConformToMySwiftProtocol", + "myOtherProtocolMethod()" + ], + "names": { + "title": "myOtherProtocolMethod()", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myOtherProtocolMethod" + }, + { + "kind": "text", + "spelling": "()" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 91, + "character": 8 + }, + "end": { + "line": 91, + "character": 38 + } + }, + "text": "A method on my other protocol." + } + ] + }, + "functionSignature": { + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myOtherProtocolMethod" + }, + { + "kind": "text", + "spelling": "()" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 92, + "character": 9 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:SYsSHRzSH8RawValueSYRpzrlE4hash4intoys6HasherVz_tF::SYNTHESIZED::c:@E@MyObjectiveCEnumObjectiveCName", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCEnumSwiftName", + "hash(into:)" + ], + "names": { + "title": "hash(into:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hash" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "into" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "keyword", + "spelling": "inout" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "typeIdentifier", + "spelling": "Hasher", + "preciseIdentifier": "s:s6HasherV" + }, + { + "kind": "text", + "spelling": ")" + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "into", + "internalName": "hasher", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "hasher" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Hasher", + "preciseIdentifier": "s:s6HasherV" + } + ] + } + ], + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "swiftGenerics": { + "constraints": [ + { + "kind": "conformance", + "lhs": "Self", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + }, + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift", + "constraints": [ + { + "kind": "conformance", + "lhs": "Self", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + }, + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hash" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "into" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "hasher" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "keyword", + "spelling": "inout" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "typeIdentifier", + "spelling": "Hasher", + "preciseIdentifier": "s:s6HasherV" + }, + { + "kind": "text", + "spelling": ")" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.init", + "displayName": "Initializer" + }, + "identifier": { + "precise": "s:s9OptionSetPss17FixedWidthInteger8RawValueRpzrlExycfc::SYNTHESIZED::c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "init()" + ], + "names": { + "title": "init()", + "subHeading": [ + { + "kind": "keyword", + "spelling": "init" + }, + { + "kind": "text", + "spelling": "()" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Creates an empty option set." + }, + { + "text": "" + }, + { + "text": "This initializer creates an option set with a raw value of zero." + } + ] + }, + "swiftGenerics": { + "constraints": [ + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "FixedWidthInteger", + "rhsPrecise": "s:s17FixedWidthIntegerP" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift", + "constraints": [ + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "FixedWidthInteger", + "rhsPrecise": "s:s17FixedWidthIntegerP" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "init" + }, + { + "kind": "text", + "spelling": "()" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:s9OptionSetPss17FixedWidthInteger8RawValueRpzrlE9formUnionyyxF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "formUnion(_:)" + ], + "names": { + "title": "formUnion(_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "formUnion" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ")" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Inserts the elements of another set into this option set." + }, + { + "text": "" + }, + { + "text": "This method is implemented as a `|` (bitwise OR) operation on the" + }, + { + "text": "two sets' raw values." + }, + { + "text": "" + }, + { + "text": "- Parameter other: An option set." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "other", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "swiftGenerics": { + "constraints": [ + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "FixedWidthInteger", + "rhsPrecise": "s:s17FixedWidthIntegerP" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift", + "constraints": [ + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "FixedWidthInteger", + "rhsPrecise": "s:s17FixedWidthIntegerP" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "mutating" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "formUnion" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "_" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ")" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:s10SetAlgebraPsE10isSuperset2ofSbx_tF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "isSuperset(of:)" + ], + "names": { + "title": "isSuperset(of:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "isSuperset" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "of" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Returns a Boolean value that indicates whether the set is a superset of" + }, + { + "text": "the given set." + }, + { + "text": "" + }, + { + "text": "Set *A* is a superset of another set *B* if every member of *B* is also a" + }, + { + "text": "member of *A*." + }, + { + "text": "" + }, + { + "text": " let employees: Set = [\"Alicia\", \"Bethany\", \"Chris\", \"Diana\", \"Eric\"]" + }, + { + "text": " let attendees: Set = [\"Alicia\", \"Bethany\", \"Diana\"]" + }, + { + "text": " print(employees.isSuperset(of: attendees))" + }, + { + "text": " // Prints \"true\"" + }, + { + "text": "" + }, + { + "text": "- Parameter other: A set of the same type as the current set." + }, + { + "text": "- Returns: `true` if the set is a superset of `other`; otherwise," + }, + { + "text": " `false`." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "of", + "internalName": "other", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "isSuperset" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "of" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.protocol", + "displayName": "Protocol" + }, + "identifier": { + "precise": "s:14MixedFramework028MyOtherProtocolThatConformToc5SwiftE0P", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyOtherProtocolThatConformToMySwiftProtocol" + ], + "names": { + "title": "MyOtherProtocolThatConformToMySwiftProtocol", + "navigator": [ + { + "kind": "identifier", + "spelling": "MyOtherProtocolThatConformToMySwiftProtocol" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "protocol" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyOtherProtocolThatConformToMySwiftProtocol" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 89, + "character": 4 + }, + "end": { + "line": 89, + "character": 54 + } + }, + "text": "My other protocol. This one extends \"my protocol\"." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "protocol" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyOtherProtocolThatConformToMySwiftProtocol" + }, + { + "kind": "text", + "spelling": " : " + }, + { + "kind": "typeIdentifier", + "spelling": "MySwiftProtocol", + "preciseIdentifier": "s:14MixedFramework15MySwiftProtocolP" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 90, + "character": 16 + } + } + }, + { + "kind": { + "identifier": "swift.property", + "displayName": "Instance Property" + }, + "identifier": { + "precise": "s:SYsSHRzSH8RawValueSYRpzrlE04hashB0Sivp::SYNTHESIZED::c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyTypedObjectiveCExtensibleEnum", + "hashValue" + ], + "names": { + "title": "hashValue", + "subHeading": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hashValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift", + "constraints": [ + { + "kind": "conformance", + "lhs": "Self", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + }, + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hashValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.typealias", + "displayName": "Type Alias" + }, + "identifier": { + "precise": "s:14MixedFramework8MyStructV0cD9TypeAliasa", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyStruct", + "MyStructTypeAlias" + ], + "names": { + "title": "MyStruct.MyStructTypeAlias", + "navigator": [ + { + "kind": "identifier", + "spelling": "MyStructTypeAlias" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "typealias" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyStructTypeAlias" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 28, + "character": 8 + }, + "end": { + "line": 28, + "character": 34 + } + }, + "text": "A type alias on my struct." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "typealias" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyStructTypeAlias" + }, + { + "kind": "text", + "spelling": " = " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 29, + "character": 21 + } + } + }, + { + "kind": { + "identifier": "swift.type.property", + "displayName": "Type Property" + }, + "identifier": { + "precise": "c:@MyTypedObjectiveCEnumFirst", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyTypedObjectiveCEnum", + "first" + ], + "names": { + "title": "first", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "let" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "first" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyTypedObjectiveCEnum", + "preciseIdentifier": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum" + } + ] + }, + "swiftExtension": { + "extendedModule": "MixedFramework" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "let" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "first" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyTypedObjectiveCEnum", + "preciseIdentifier": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.enum", + "displayName": "Enumeration" + }, + "identifier": { + "precise": "s:14MixedFramework40CollisionsWithDifferentFunctionArgumentsO", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "CollisionsWithDifferentFunctionArguments" + ], + "names": { + "title": "CollisionsWithDifferentFunctionArguments", + "navigator": [ + { + "kind": "identifier", + "spelling": "CollisionsWithDifferentFunctionArguments" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "enum" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "CollisionsWithDifferentFunctionArguments" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 46, + "character": 4 + }, + "end": { + "line": 46, + "character": 66 + } + }, + "text": "A container for colliding symbols with different symbol kinds." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "enum" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "CollisionsWithDifferentFunctionArguments" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithVariousCollisions.swift", + "position": { + "line": 47, + "character": 12 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:14MixedFramework40CollisionsWithDifferentFunctionArgumentsO9something8argumentSiSS_tF", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "CollisionsWithDifferentFunctionArguments", + "something(argument:)" + ], + "names": { + "title": "something(argument:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "something" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "argument" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "String", + "preciseIdentifier": "s:SS" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 50, + "character": 8 + }, + "end": { + "line": 50, + "character": 60 + } + }, + "text": "A subscript with a \"something else\" String argument." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "argument", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "argument" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "String", + "preciseIdentifier": "s:SS" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "something" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "argument" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "String", + "preciseIdentifier": "s:SS" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithVariousCollisions.swift", + "position": { + "line": 51, + "character": 16 + } + } + }, + { + "kind": { + "identifier": "swift.init", + "displayName": "Initializer" + }, + "identifier": { + "precise": "s:s10SetAlgebraPs7ElementQz012ArrayLiteralC0RtzrlE05arrayE0xAFd_tcfc::SYNTHESIZED::c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "init(arrayLiteral:)" + ], + "names": { + "title": "init(arrayLiteral:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "init" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "arrayLiteral" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": "." + }, + { + "kind": "typeIdentifier", + "spelling": "Element" + }, + { + "kind": "text", + "spelling": "...)" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Creates a set containing the elements of the given array literal." + }, + { + "text": "" + }, + { + "text": "Do not call this initializer directly. It is used by the compiler when" + }, + { + "text": "you use an array literal. Instead, create a new set using an array" + }, + { + "text": "literal as its value by enclosing a comma-separated list of values in" + }, + { + "text": "square brackets. You can use an array literal anywhere a set is expected" + }, + { + "text": "by the type context." + }, + { + "text": "" + }, + { + "text": "Here, a set of strings is created from an array literal holding only" + }, + { + "text": "strings:" + }, + { + "text": "" + }, + { + "text": " let ingredients: Set = [\"cocoa beans\", \"sugar\", \"cocoa butter\", \"salt\"]" + }, + { + "text": " if ingredients.isSuperset(of: [\"sugar\", \"salt\"]) {" + }, + { + "text": " print(\"Whatever it is, it's bound to be delicious!\")" + }, + { + "text": " }" + }, + { + "text": " // Prints \"Whatever it is, it's bound to be delicious!\"" + }, + { + "text": "" + }, + { + "text": "- Parameter arrayLiteral: A list of elements of the new set." + } + ] + }, + "swiftGenerics": { + "constraints": [ + { + "kind": "sameType", + "lhs": "Self.ArrayLiteralElement", + "rhs": "Self.Element" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift", + "constraints": [ + { + "kind": "sameType", + "lhs": "Self.ArrayLiteralElement", + "rhs": "Self.Element" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "init" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "arrayLiteral" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": "." + }, + { + "kind": "typeIdentifier", + "spelling": "Element" + }, + { + "kind": "text", + "spelling": "...)" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:s9OptionSetPsE12intersectionyxxF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "intersection(_:)" + ], + "names": { + "title": "intersection(_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "intersection" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Returns a new option set with only the elements contained in both this" + }, + { + "text": "set and the given set." + }, + { + "text": "" + }, + { + "text": "This example uses the `intersection(_:)` method to limit the available" + }, + { + "text": "shipping options to what can be used with a PO Box destination." + }, + { + "text": "" + }, + { + "text": " // Can only ship standard or priority to PO Boxes" + }, + { + "text": " let poboxShipping: ShippingOptions = [.standard, .priority]" + }, + { + "text": " let memberShipping: ShippingOptions =" + }, + { + "text": " [.standard, .priority, .secondDay]" + }, + { + "text": "" + }, + { + "text": " let availableOptions = memberShipping.intersection(poboxShipping)" + }, + { + "text": " print(availableOptions.contains(.priority))" + }, + { + "text": " // Prints \"true\"" + }, + { + "text": " print(availableOptions.contains(.secondDay))" + }, + { + "text": " // Prints \"false\"" + }, + { + "text": "" + }, + { + "text": "- Parameter other: An option set." + }, + { + "text": "- Returns: A new option set with only the elements contained in both this" + }, + { + "text": " set and `other`." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "other", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "intersection" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "_" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.init", + "displayName": "Initializer" + }, + "identifier": { + "precise": "s:So16MyObjectiveCEnumV8rawValueABSgSi_tcfc", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCEnum", + "init(rawValue:)" + ], + "names": { + "title": "init(rawValue:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "init" + }, + { + "kind": "text", + "spelling": "?(" + }, + { + "kind": "externalParam", + "spelling": "rawValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": ")" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "init" + }, + { + "kind": "text", + "spelling": "?(" + }, + { + "kind": "externalParam", + "spelling": "rawValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": ")" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol(im)myOtherProtocolMethod", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyClassThatConformToMyOtherProtocol", + "myOtherProtocolMethod()" + ], + "names": { + "title": "myOtherProtocolMethod()", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myOtherProtocolMethod" + }, + { + "kind": "text", + "spelling": "()" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 91, + "character": 8 + }, + "end": { + "line": 91, + "character": 38 + } + }, + "text": "A method on my other protocol." + } + ] + }, + "functionSignature": { + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myOtherProtocolMethod" + }, + { + "kind": "text", + "spelling": "()" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 98, + "character": 16 + } + } + }, + { + "kind": { + "identifier": "swift.subscript", + "displayName": "Instance Subscript" + }, + "identifier": { + "precise": "s:14MixedFramework29CollisionsWithEscapedKeywordsCSiycip", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "CollisionsWithEscapedKeywords", + "subscript()" + ], + "names": { + "title": "subscript()", + "subHeading": [ + { + "kind": "keyword", + "spelling": "subscript" + }, + { + "kind": "text", + "spelling": "() -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 31, + "character": 8 + }, + "end": { + "line": 31, + "character": 38 + } + }, + "text": "A subscript without arguments." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "subscript" + }, + { + "kind": "text", + "spelling": "() -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithVariousCollisions.swift", + "position": { + "line": 32, + "character": 11 + } + } + }, + { + "kind": { + "identifier": "swift.enum", + "displayName": "Enumeration" + }, + "identifier": { + "precise": "s:14MixedFramework41CollisionsWithDifferentSubscriptArgumentsO", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "CollisionsWithDifferentSubscriptArguments" + ], + "names": { + "title": "CollisionsWithDifferentSubscriptArguments", + "navigator": [ + { + "kind": "identifier", + "spelling": "CollisionsWithDifferentSubscriptArguments" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "enum" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "CollisionsWithDifferentSubscriptArguments" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 54, + "character": 4 + }, + "end": { + "line": 54, + "character": 66 + } + }, + "text": "A container for colliding symbols with different symbol kinds." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "enum" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "CollisionsWithDifferentSubscriptArguments" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithVariousCollisions.swift", + "position": { + "line": 55, + "character": 12 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:s20_SwiftNewtypeWrapperPsSHRzSH8RawValueSYRpzrlE4hash4intoys6HasherVz_tF::SYNTHESIZED::c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyTypedObjectiveCExtensibleEnum", + "hash(into:)" + ], + "names": { + "title": "hash(into:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hash" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "into" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "keyword", + "spelling": "inout" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "typeIdentifier", + "spelling": "Hasher", + "preciseIdentifier": "s:s6HasherV" + }, + { + "kind": "text", + "spelling": ")" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Hashes the essential components of this value by feeding them into the" + }, + { + "text": "given hasher." + }, + { + "text": "" + }, + { + "text": "- Parameter hasher: The hasher to use when combining the components" + }, + { + "text": " of this instance." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "into", + "internalName": "hasher", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "hasher" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Hasher", + "preciseIdentifier": "s:s6HasherV" + } + ] + } + ], + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "swiftGenerics": { + "constraints": [ + { + "kind": "conformance", + "lhs": "Self", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + }, + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift", + "constraints": [ + { + "kind": "conformance", + "lhs": "Self", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + }, + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hash" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "into" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "hasher" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "keyword", + "spelling": "inout" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "typeIdentifier", + "spelling": "Hasher", + "preciseIdentifier": "s:s6HasherV" + }, + { + "kind": "text", + "spelling": ")" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.protocol", + "displayName": "Protocol" + }, + "identifier": { + "precise": "s:14MixedFramework15MySwiftProtocolP", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MySwiftProtocol" + ], + "names": { + "title": "MySwiftProtocol", + "navigator": [ + { + "kind": "identifier", + "spelling": "MySwiftProtocol" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "protocol" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MySwiftProtocol" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 66, + "character": 4 + }, + "end": { + "line": 66, + "character": 15 + } + }, + "text": "My protocol" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "protocol" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MySwiftProtocol" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 67, + "character": 16 + } + } + }, + { + "kind": { + "identifier": "swift.init", + "displayName": "Initializer" + }, + "identifier": { + "precise": "s:s10SetAlgebraPsEyxqd__ncSTRd__7ElementQyd__ACRtzlufc::SYNTHESIZED::c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "init(_:)" + ], + "names": { + "title": "init(_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "init" + }, + { + "kind": "text", + "spelling": "<" + }, + { + "kind": "genericParameter", + "spelling": "S" + }, + { + "kind": "text", + "spelling": ">(" + }, + { + "kind": "typeIdentifier", + "spelling": "S" + }, + { + "kind": "text", + "spelling": ")" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Creates a new set from a finite sequence of items." + }, + { + "text": "" + }, + { + "text": "Use this initializer to create a new set from an existing sequence, like" + }, + { + "text": "an array or a range:" + }, + { + "text": "" + }, + { + "text": " let validIndices = Set(0..<7).subtracting([2, 4, 5])" + }, + { + "text": " print(validIndices)" + }, + { + "text": " // Prints \"[6, 0, 1, 3]\"" + }, + { + "text": "" + }, + { + "text": "- Parameter sequence: The elements to use as members of the new set." + } + ] + }, + "swiftGenerics": { + "parameters": [ + { + "name": "S", + "index": 0, + "depth": 1 + } + ], + "constraints": [ + { + "kind": "conformance", + "lhs": "S", + "rhs": "Sequence", + "rhsPrecise": "s:ST" + }, + { + "kind": "sameType", + "lhs": "Self.Element", + "rhs": "S.Element" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "init" + }, + { + "kind": "text", + "spelling": "<" + }, + { + "kind": "genericParameter", + "spelling": "S" + }, + { + "kind": "text", + "spelling": ">(" + }, + { + "kind": "externalParam", + "spelling": "_" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "sequence" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "S" + }, + { + "kind": "text", + "spelling": ") " + }, + { + "kind": "keyword", + "spelling": "where" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "typeIdentifier", + "spelling": "S" + }, + { + "kind": "text", + "spelling": " : " + }, + { + "kind": "typeIdentifier", + "spelling": "Sequence", + "preciseIdentifier": "s:ST" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": "." + }, + { + "kind": "typeIdentifier", + "spelling": "Element" + }, + { + "kind": "text", + "spelling": " == " + }, + { + "kind": "typeIdentifier", + "spelling": "S" + }, + { + "kind": "text", + "spelling": "." + }, + { + "kind": "typeIdentifier", + "spelling": "Element" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.class", + "displayName": "Class" + }, + "identifier": { + "precise": "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyClassThatConformToMyOtherProtocol" + ], + "names": { + "title": "MyClassThatConformToMyOtherProtocol", + "navigator": [ + { + "kind": "identifier", + "spelling": "MyClassThatConformToMyOtherProtocol" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "class" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyClassThatConformToMyOtherProtocol" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 95, + "character": 4 + }, + "end": { + "line": 95, + "character": 72 + } + }, + "text": "My Objective-C compatible class that conform to \"my other protocol\"." + } + ] + }, + "declarationFragments": [ + { + "kind": "attribute", + "spelling": "@objcMembers" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "class" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyClassThatConformToMyOtherProtocol" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 97, + "character": 13 + } + } + }, + { + "kind": { + "identifier": "swift.type.property", + "displayName": "Type Property" + }, + "identifier": { + "precise": "c:@E@MyObjectiveCOption@MyObjectiveCOptionFirst", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "first" + ], + "names": { + "title": "first", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "first" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyObjectiveCOption", + "preciseIdentifier": "c:@E@MyObjectiveCOption" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "first" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyObjectiveCOption", + "preciseIdentifier": "c:@E@MyObjectiveCOption" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.func.op", + "displayName": "Operator" + }, + "identifier": { + "precise": "s:SQsE2neoiySbx_xtFZ::SYNTHESIZED::s:14MixedFramework28CollisionsWithDifferentKindsO", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "CollisionsWithDifferentKinds", + "!=(_:_:)" + ], + "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.type.property", + "displayName": "Type Property" + }, + "identifier": { + "precise": "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(cpy)myProtocolTypeProperty", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCCompatibleProtocol", + "myProtocolTypeProperty" + ], + "names": { + "title": "myProtocolTypeProperty", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myProtocolTypeProperty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyProtocolTypeAlias", + "preciseIdentifier": "s:14MixedFramework30MyObjectiveCCompatibleProtocolP0cF9TypeAliasa" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 60, + "character": 8 + }, + "end": { + "line": 60, + "character": 39 + } + }, + "text": "A type property on my protocol." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myProtocolTypeProperty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyProtocolTypeAlias", + "preciseIdentifier": "s:14MixedFramework30MyObjectiveCCompatibleProtocolP0cF9TypeAliasa" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 61, + "character": 15 + } + } + }, + { + "kind": { + "identifier": "swift.func.op", + "displayName": "Operator" + }, + "identifier": { + "precise": "s:SQsE2neoiySbx_xtFZ::SYNTHESIZED::c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyTypedObjectiveCExtensibleEnum", + "!=(_:_:)" + ], + "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.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol(im)myProtocolMethod", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyClassThatConformToMyOtherProtocol", + "myProtocolMethod()" + ], + "names": { + "title": "myProtocolMethod()", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myProtocolMethod" + }, + { + "kind": "text", + "spelling": "()" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 68, + "character": 8 + }, + "end": { + "line": 68, + "character": 41 + } + }, + "text": "A method/function on my protocol." + } + ] + }, + "functionSignature": { + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myProtocolMethod" + }, + { + "kind": "text", + "spelling": "()" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 100, + "character": 16 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:s9OptionSetPs7ElementQzRszrlE6removeyxSgxF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "remove(_:)" + ], + "names": { + "title": "remove(_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "remove" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": "." + }, + { + "kind": "typeIdentifier", + "spelling": "Element" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": "." + }, + { + "kind": "typeIdentifier", + "spelling": "Element" + }, + { + "kind": "text", + "spelling": "?" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Removes the given element and all elements subsumed by it." + }, + { + "text": "" + }, + { + "text": "In the following example, the `.priority` shipping option is removed from" + }, + { + "text": "the `options` option set. Attempting to remove the same shipping option" + }, + { + "text": "a second time results in `nil`, because `options` no longer contains" + }, + { + "text": "`.priority` as a member." + }, + { + "text": "" + }, + { + "text": " var options: ShippingOptions = [.secondDay, .priority]" + }, + { + "text": " let priorityOption = options.remove(.priority)" + }, + { + "text": " print(priorityOption == .priority)" + }, + { + "text": " // Prints \"true\"" + }, + { + "text": "" + }, + { + "text": " print(options.remove(.priority))" + }, + { + "text": " // Prints \"nil\"" + }, + { + "text": "" + }, + { + "text": "In the next example, the `.express` element is passed to `remove(_:)`." + }, + { + "text": "Although `.express` is not a member of `options`, `.express` subsumes" + }, + { + "text": "the remaining `.secondDay` element of the option set. Therefore," + }, + { + "text": "`options` is emptied and the intersection between `.express` and" + }, + { + "text": "`options` is returned." + }, + { + "text": "" + }, + { + "text": " let expressOption = options.remove(.express)" + }, + { + "text": " print(expressOption == .express)" + }, + { + "text": " // Prints \"false\"" + }, + { + "text": " print(expressOption == .secondDay)" + }, + { + "text": " // Prints \"true\"" + }, + { + "text": "" + }, + { + "text": "- Parameter member: The element of the set to remove." + }, + { + "text": "- Returns: The intersection of `[member]` and the set, if the" + }, + { + "text": " intersection was nonempty; otherwise, `nil`." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "member", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "member" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": "." + }, + { + "kind": "typeIdentifier", + "spelling": "Element" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": "." + }, + { + "kind": "typeIdentifier", + "spelling": "Element" + }, + { + "kind": "text", + "spelling": "?" + } + ] + }, + "swiftGenerics": { + "constraints": [ + { + "kind": "sameType", + "lhs": "Self", + "rhs": "Self.Element" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift", + "constraints": [ + { + "kind": "sameType", + "lhs": "Self", + "rhs": "Self.Element" + } + ] + }, + "declarationFragments": [ + { + "kind": "attribute", + "spelling": "@discardableResult" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "mutating" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "remove" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "_" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "member" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": "." + }, + { + "kind": "typeIdentifier", + "spelling": "Element" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": "." + }, + { + "kind": "typeIdentifier", + "spelling": "Element" + }, + { + "kind": "text", + "spelling": "?" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.subscript", + "displayName": "Instance Subscript" + }, + "identifier": { + "precise": "s:14MixedFramework41CollisionsWithDifferentSubscriptArgumentsOyS2icip", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "CollisionsWithDifferentSubscriptArguments", + "subscript(_:)" + ], + "names": { + "title": "subscript(_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "subscript" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 56, + "character": 8 + }, + "end": { + "line": 56, + "character": 52 + } + }, + "text": "A subscript with a \"something\" Int argument." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "subscript" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "internalParam", + "spelling": "something" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithVariousCollisions.swift", + "position": { + "line": 57, + "character": 11 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:14MixedFramework8MyStructV02myD8FunctionyyF", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyStruct", + "myStructFunction()" + ], + "names": { + "title": "myStructFunction()", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myStructFunction" + }, + { + "kind": "text", + "spelling": "()" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 26, + "character": 8 + }, + "end": { + "line": 26, + "character": 32 + } + }, + "text": "A function on my struct." + } + ] + }, + "functionSignature": { + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myStructFunction" + }, + { + "kind": "text", + "spelling": "()" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 27, + "character": 16 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:s10SetAlgebraPsE14isStrictSubset2ofSbx_tF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "isStrictSubset(of:)" + ], + "names": { + "title": "isStrictSubset(of:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "isStrictSubset" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "of" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Returns a Boolean value that indicates whether this set is a strict" + }, + { + "text": "subset of the given set." + }, + { + "text": "" + }, + { + "text": "Set *A* is a strict subset of another set *B* if every member of *A* is" + }, + { + "text": "also a member of *B* and *B* contains at least one element that is not a" + }, + { + "text": "member of *A*." + }, + { + "text": "" + }, + { + "text": " let employees: Set = [\"Alicia\", \"Bethany\", \"Chris\", \"Diana\", \"Eric\"]" + }, + { + "text": " let attendees: Set = [\"Alicia\", \"Bethany\", \"Diana\"]" + }, + { + "text": " print(attendees.isStrictSubset(of: employees))" + }, + { + "text": " // Prints \"true\"" + }, + { + "text": "" + }, + { + "text": " // A set is never a strict subset of itself:" + }, + { + "text": " print(attendees.isStrictSubset(of: attendees))" + }, + { + "text": " // Prints \"false\"" + }, + { + "text": "" + }, + { + "text": "- Parameter other: A set of the same type as the current set." + }, + { + "text": "- Returns: `true` if the set is a strict subset of `other`; otherwise," + }, + { + "text": " `false`." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "of", + "internalName": "other", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "isStrictSubset" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "of" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.property", + "displayName": "Instance Property" + }, + "identifier": { + "precise": "s:s20_SwiftNewtypeWrapperPsSHRzSH8RawValueSYRpzrlE04hashE0Sivp::SYNTHESIZED::c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyTypedObjectiveCEnum", + "hashValue" + ], + "names": { + "title": "hashValue", + "subHeading": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hashValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "The hash value." + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift", + "constraints": [ + { + "kind": "conformance", + "lhs": "Self", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + }, + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hashValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.type.property", + "displayName": "Type Property" + }, + "identifier": { + "precise": "c:@MyTypedObjectiveCExtensibleEnumSecond", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyTypedObjectiveCExtensibleEnum", + "second" + ], + "names": { + "title": "second", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "let" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "second" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyTypedObjectiveCExtensibleEnum", + "preciseIdentifier": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum" + } + ] + }, + "swiftExtension": { + "extendedModule": "MixedFramework" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "let" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "second" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyTypedObjectiveCExtensibleEnum", + "preciseIdentifier": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.enum", + "displayName": "Enumeration" + }, + "identifier": { + "precise": "c:@E@MyObjectiveCEnumObjectiveCName", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCEnumSwiftName" + ], + "names": { + "title": "MyObjectiveCEnumSwiftName", + "navigator": [ + { + "kind": "identifier", + "spelling": "MyObjectiveCEnumSwiftName" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "enum" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyObjectiveCEnumSwiftName" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "enum" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyObjectiveCEnumSwiftName" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.typealias", + "displayName": "Type Alias" + }, + "identifier": { + "precise": "s:14MixedFramework020MyClassThatConformToC13OtherProtocolC0cI14AssociatedTypea", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyClassThatConformToMyOtherProtocol", + "MyProtocolAssociatedType" + ], + "names": { + "title": "MyClassThatConformToMyOtherProtocol.MyProtocolAssociatedType", + "navigator": [ + { + "kind": "identifier", + "spelling": "MyProtocolAssociatedType" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "typealias" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyProtocolAssociatedType" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 70, + "character": 8 + }, + "end": { + "line": 70, + "character": 42 + } + }, + "text": "An associated type on my protocol." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "typealias" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyProtocolAssociatedType" + }, + { + "kind": "text", + "spelling": " = " + }, + { + "kind": "typeIdentifier", + "spelling": "MyStruct", + "preciseIdentifier": "s:14MixedFramework8MyStructV" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 102, + "character": 21 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:s9OptionSetPss17FixedWidthInteger8RawValueRpzrlE23formSymmetricDifferenceyyxF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "formSymmetricDifference(_:)" + ], + "names": { + "title": "formSymmetricDifference(_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "formSymmetricDifference" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ")" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Replaces this set with a new set containing all elements " + }, + { + "text": "contained in either this set or the given set, but not in both." + }, + { + "text": "" + }, + { + "text": "This method is implemented as a `^` (bitwise XOR) operation on the two" + }, + { + "text": "sets' raw values." + }, + { + "text": "" + }, + { + "text": "- Parameter other: An option set." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "other", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "swiftGenerics": { + "constraints": [ + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "FixedWidthInteger", + "rhsPrecise": "s:s17FixedWidthIntegerP" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift", + "constraints": [ + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "FixedWidthInteger", + "rhsPrecise": "s:s17FixedWidthIntegerP" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "mutating" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "formSymmetricDifference" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "_" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ")" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.protocol", + "displayName": "Protocol" + }, + "identifier": { + "precise": "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCCompatibleProtocol" + ], + "names": { + "title": "MyObjectiveCCompatibleProtocol", + "navigator": [ + { + "kind": "identifier", + "spelling": "MyObjectiveCCompatibleProtocol" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "protocol" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyObjectiveCCompatibleProtocol" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 51, + "character": 4 + }, + "end": { + "line": 51, + "character": 38 + } + }, + "text": "My Objective-C compatible protocol" + } + ] + }, + "declarationFragments": [ + { + "kind": "attribute", + "spelling": "@objc" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "protocol" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyObjectiveCCompatibleProtocol" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 53, + "character": 16 + } + } + }, + { + "kind": { + "identifier": "swift.enum", + "displayName": "Enumeration" + }, + "identifier": { + "precise": "c:@E@MyObjectiveCEnum", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCEnum" + ], + "names": { + "title": "MyObjectiveCEnum", + "navigator": [ + { + "kind": "identifier", + "spelling": "MyObjectiveCEnum" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "enum" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyObjectiveCEnum" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "enum" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyObjectiveCEnum" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.init", + "displayName": "Initializer" + }, + "identifier": { + "precise": "s:So21MyTypedObjectiveCEnuma8rawValueABSi_tcfc", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyTypedObjectiveCEnum", + "init(rawValue:)" + ], + "names": { + "title": "init(rawValue:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "init" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "rawValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": ")" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "init" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "rawValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": ")" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.property", + "displayName": "Instance Property" + }, + "identifier": { + "precise": "s:SYsSHRzSH8RawValueSYRpzrlE04hashB0Sivp::SYNTHESIZED::c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyTypedObjectiveCEnum", + "hashValue" + ], + "names": { + "title": "hashValue", + "subHeading": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hashValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift", + "constraints": [ + { + "kind": "conformance", + "lhs": "Self", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + }, + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hashValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.init", + "displayName": "Initializer" + }, + "identifier": { + "precise": "s:14MixedFramework6MyEnumO8rawValueACSgSi_tcfc", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyEnum", + "init(rawValue:)" + ], + "names": { + "title": "init(rawValue:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "init" + }, + { + "kind": "text", + "spelling": "?(" + }, + { + "kind": "externalParam", + "spelling": "rawValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": ")" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Creates a new instance with the specified raw value." + }, + { + "text": "" + }, + { + "text": "If there is no value of the type that corresponds with the specified raw" + }, + { + "text": "value, this initializer returns `nil`. For example:" + }, + { + "text": "" + }, + { + "text": " enum PaperSize: String {" + }, + { + "text": " case A4, A5, Letter, Legal" + }, + { + "text": " }" + }, + { + "text": "" + }, + { + "text": " print(PaperSize(rawValue: \"Legal\"))" + }, + { + "text": " // Prints \"Optional(\"PaperSize.Legal\")\"" + }, + { + "text": "" + }, + { + "text": " print(PaperSize(rawValue: \"Tabloid\"))" + }, + { + "text": " // Prints \"nil\"" + }, + { + "text": "" + }, + { + "text": "- Parameter rawValue: The raw value to use for the new instance." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "init" + }, + { + "kind": "text", + "spelling": "?(" + }, + { + "kind": "externalParam", + "spelling": "rawValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": ")" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.property", + "displayName": "Instance Property" + }, + "identifier": { + "precise": "s:14MixedFramework020MyClassThatConformToC13OtherProtocolC02myI8PropertyAA0C6StructVvp", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyClassThatConformToMyOtherProtocol", + "myProtocolProperty" + ], + "names": { + "title": "myProtocolProperty", + "subHeading": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myProtocolProperty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyStruct", + "preciseIdentifier": "s:14MixedFramework8MyStructV" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 74, + "character": 8 + }, + "end": { + "line": 74, + "character": 34 + } + }, + "text": "A property on my protocol." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myProtocolProperty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyStruct", + "preciseIdentifier": "s:14MixedFramework8MyStructV" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 104, + "character": 15 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:s9OptionSetPs7ElementQzRszrlE6update4withxSgx_tF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "update(with:)" + ], + "names": { + "title": "update(with:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "update" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "with" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": "." + }, + { + "kind": "typeIdentifier", + "spelling": "Element" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": "." + }, + { + "kind": "typeIdentifier", + "spelling": "Element" + }, + { + "kind": "text", + "spelling": "?" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Inserts the given element into the set." + }, + { + "text": "" + }, + { + "text": "If `newMember` is not contained in the set but subsumes current members" + }, + { + "text": "of the set, the subsumed members are returned." + }, + { + "text": "" + }, + { + "text": " var options: ShippingOptions = [.secondDay, .priority]" + }, + { + "text": " let replaced = options.update(with: .express)" + }, + { + "text": " print(replaced == .secondDay)" + }, + { + "text": " // Prints \"true\"" + }, + { + "text": "" + }, + { + "text": "- Returns: The intersection of `[newMember]` and the set if the" + }, + { + "text": " intersection was nonempty; otherwise, `nil`." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "with", + "internalName": "newMember", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "newMember" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": "." + }, + { + "kind": "typeIdentifier", + "spelling": "Element" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": "." + }, + { + "kind": "typeIdentifier", + "spelling": "Element" + }, + { + "kind": "text", + "spelling": "?" + } + ] + }, + "swiftGenerics": { + "constraints": [ + { + "kind": "sameType", + "lhs": "Self", + "rhs": "Self.Element" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift", + "constraints": [ + { + "kind": "sameType", + "lhs": "Self", + "rhs": "Self.Element" + } + ] + }, + "declarationFragments": [ + { + "kind": "attribute", + "spelling": "@discardableResult" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "mutating" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "update" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "with" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "newMember" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": "." + }, + { + "kind": "typeIdentifier", + "spelling": "Element" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": "." + }, + { + "kind": "typeIdentifier", + "spelling": "Element" + }, + { + "kind": "text", + "spelling": "?" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:s10SetAlgebraPsE8subtractyyxF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "subtract(_:)" + ], + "names": { + "title": "subtract(_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "subtract" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ")" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Removes the elements of the given set from this set." + }, + { + "text": "" + }, + { + "text": "In the following example, the elements of the `employees` set that are" + }, + { + "text": "also members of the `neighbors` set are removed. In particular, the" + }, + { + "text": "names `\"Bethany\"` and `\"Eric\"` are removed from `employees`." + }, + { + "text": "" + }, + { + "text": " var employees: Set = [\"Alicia\", \"Bethany\", \"Chris\", \"Diana\", \"Eric\"]" + }, + { + "text": " let neighbors: Set = [\"Bethany\", \"Eric\", \"Forlani\", \"Greta\"]" + }, + { + "text": " employees.subtract(neighbors)" + }, + { + "text": " print(employees)" + }, + { + "text": " // Prints \"[\"Diana\", \"Chris\", \"Alicia\"]\"" + }, + { + "text": "" + }, + { + "text": "- Parameter other: A set of the same type as the current set." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "other", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "mutating" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "subtract" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "_" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ")" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.property", + "displayName": "Instance Property" + }, + "identifier": { + "precise": "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName(py)myPropertyObjectiveCName", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MySwiftClassSwiftName", + "myPropertySwiftName" + ], + "names": { + "title": "myPropertySwiftName", + "subHeading": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myPropertySwiftName" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ] + }, + "declarationFragments": [ + { + "kind": "attribute", + "spelling": "@objc" + }, + { + "kind": "text", + "spelling": "(myPropertyObjectiveCName) " + }, + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myPropertySwiftName" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithDifferentObjectiveCNames.swift", + "position": { + "line": 14, + "character": 15 + } + } + }, + { + "kind": { + "identifier": "swift.func.op", + "displayName": "Operator" + }, + "identifier": { + "precise": "s:SQsE2neoiySbx_xtFZ::SYNTHESIZED::c:@M@MixedFramework@E@MyEnum", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyEnum", + "!=(_:_:)" + ], + "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.type.property", + "displayName": "Type Property" + }, + "identifier": { + "precise": "c:@MyTypedObjectiveCExtensibleEnumFirst", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyTypedObjectiveCExtensibleEnum", + "first" + ], + "names": { + "title": "first", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "let" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "first" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyTypedObjectiveCExtensibleEnum", + "preciseIdentifier": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum" + } + ] + }, + "swiftExtension": { + "extendedModule": "MixedFramework" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "let" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "first" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyTypedObjectiveCExtensibleEnum", + "preciseIdentifier": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.type.method", + "displayName": "Type Method" + }, + "identifier": { + "precise": "s:14MixedFramework29CollisionsWithEscapedKeywordsC9subscriptyyFZ", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "CollisionsWithEscapedKeywords", + "subscript()" + ], + "names": { + "title": "subscript()", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "`subscript`" + }, + { + "kind": "text", + "spelling": "()" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 35, + "character": 8 + }, + "end": { + "line": 35, + "character": 48 + } + }, + "text": "A class (type) method named \"subscript\"." + } + ] + }, + "functionSignature": { + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "`subscript`" + }, + { + "kind": "text", + "spelling": "()" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithVariousCollisions.swift", + "position": { + "line": 36, + "character": 23 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "c:objc(cs)MyObjectiveCClassObjectiveCName(im)myMethodWithArgument:", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCClassSwiftName", + "myMethod(argument:)" + ], + "names": { + "title": "myMethod(argument:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myMethod" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "argument" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "String", + "preciseIdentifier": "s:SS" + }, + { + "kind": "text", + "spelling": ")" + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "argument", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "argument" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "String", + "preciseIdentifier": "s:SS" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Void", + "preciseIdentifier": "s:s4Voida" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myMethod" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "argument" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "String", + "preciseIdentifier": "s:SS" + }, + { + "kind": "text", + "spelling": ")" + } + ], + "accessLevel": "open" + }, + { + "kind": { + "identifier": "swift.class", + "displayName": "Class" + }, + "identifier": { + "precise": "c:@M@MixedFramework@objc(cs)MyClass", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyClass" + ], + "names": { + "title": "MyClass", + "navigator": [ + { + "kind": "identifier", + "spelling": "MyClass" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "class" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyClass" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 36, + "character": 4 + }, + "end": { + "line": 36, + "character": 35 + } + }, + "text": "My Objective-C compatible class" + } + ] + }, + "declarationFragments": [ + { + "kind": "attribute", + "spelling": "@objc" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "class" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyClass" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 38, + "character": 13 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:SYsSHRzSH8RawValueSYRpzrlE4hash4intoys6HasherVz_tF::SYNTHESIZED::c:@M@MixedFramework@E@MyEnum", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyEnum", + "hash(into:)" + ], + "names": { + "title": "hash(into:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hash" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "into" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "keyword", + "spelling": "inout" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "typeIdentifier", + "spelling": "Hasher", + "preciseIdentifier": "s:s6HasherV" + }, + { + "kind": "text", + "spelling": ")" + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "into", + "internalName": "hasher", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "hasher" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Hasher", + "preciseIdentifier": "s:s6HasherV" + } + ] + } + ], + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "swiftGenerics": { + "constraints": [ + { + "kind": "conformance", + "lhs": "Self", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + }, + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift", + "constraints": [ + { + "kind": "conformance", + "lhs": "Self", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + }, + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hash" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "into" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "hasher" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "keyword", + "spelling": "inout" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "typeIdentifier", + "spelling": "Hasher", + "preciseIdentifier": "s:s6HasherV" + }, + { + "kind": "text", + "spelling": ")" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.property", + "displayName": "Instance Property" + }, + "identifier": { + "precise": "s:14MixedFramework7MyClassC18myInstancePropertySivp", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyClass", + "myInstanceProperty" + ], + "names": { + "title": "myInstanceProperty", + "subHeading": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myInstanceProperty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyClassTypeAlias", + "preciseIdentifier": "s:14MixedFramework7MyClassC0cD9TypeAliasa" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 45, + "character": 8 + }, + "end": { + "line": 45, + "character": 41 + } + }, + "text": "An instance property on my class." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myInstanceProperty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyClassTypeAlias", + "preciseIdentifier": "s:14MixedFramework7MyClassC0cD9TypeAliasa" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 46, + "character": 15 + } + } + }, + { + "kind": { + "identifier": "swift.typealias", + "displayName": "Type Alias" + }, + "identifier": { + "precise": "s:14MixedFramework7MyClassC0cD9TypeAliasa", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyClass", + "MyClassTypeAlias" + ], + "names": { + "title": "MyClass.MyClassTypeAlias", + "navigator": [ + { + "kind": "identifier", + "spelling": "MyClassTypeAlias" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "typealias" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyClassTypeAlias" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 43, + "character": 8 + }, + "end": { + "line": 43, + "character": 33 + } + }, + "text": "A type alias on my class." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "typealias" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyClassTypeAlias" + }, + { + "kind": "text", + "spelling": " = " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 44, + "character": 21 + } + } + }, + { + "kind": { + "identifier": "swift.property", + "displayName": "Instance Property" + }, + "identifier": { + "precise": "s:s10SetAlgebraPsE7isEmptySbvp::SYNTHESIZED::c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "isEmpty" + ], + "names": { + "title": "isEmpty", + "subHeading": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "isEmpty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "A Boolean value that indicates whether the set has no elements." + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "isEmpty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.type.property", + "displayName": "Type Property" + }, + "identifier": { + "precise": "s:14MixedFramework020MyClassThatConformToC13OtherProtocolC02myI12TypePropertyAA0C6StructVvpZ", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyClassThatConformToMyOtherProtocol", + "myProtocolTypeProperty" + ], + "names": { + "title": "myProtocolTypeProperty", + "subHeading": [ + { + "kind": "keyword", + "spelling": "class" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myProtocolTypeProperty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyStruct", + "preciseIdentifier": "s:14MixedFramework8MyStructV" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 76, + "character": 8 + }, + "end": { + "line": 76, + "character": 39 + } + }, + "text": "A type property on my protocol." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "class" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myProtocolTypeProperty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyStruct", + "preciseIdentifier": "s:14MixedFramework8MyStructV" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 105, + "character": 21 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(im)myPropertyOptionalMethod", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCCompatibleProtocol", + "myPropertyOptionalMethod()" + ], + "names": { + "title": "myPropertyOptionalMethod()", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myPropertyOptionalMethod" + }, + { + "kind": "text", + "spelling": "()" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 62, + "character": 8 + }, + "end": { + "line": 62, + "character": 51 + } + }, + "text": "An optional method/function of my protocol." + } + ] + }, + "functionSignature": { + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "declarationFragments": [ + { + "kind": "attribute", + "spelling": "@objc" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "optional" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myPropertyOptionalMethod" + }, + { + "kind": "text", + "spelling": "()" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 63, + "character": 24 + } + } + }, + { + "kind": { + "identifier": "swift.func.op", + "displayName": "Operator" + }, + "identifier": { + "precise": "s:SQsE2neoiySbx_xtFZ::SYNTHESIZED::c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "!=(_:_:)" + ], + "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.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:14MixedFramework15MySwiftProtocolP02myE6MethodyyF", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MySwiftProtocol", + "myProtocolMethod()" + ], + "names": { + "title": "myProtocolMethod()", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myProtocolMethod" + }, + { + "kind": "text", + "spelling": "()" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 68, + "character": 8 + }, + "end": { + "line": 68, + "character": 41 + } + }, + "text": "A method/function on my protocol." + } + ] + }, + "functionSignature": { + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myProtocolMethod" + }, + { + "kind": "text", + "spelling": "()" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 69, + "character": 9 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:14MixedFramework29CollisionsWithEscapedKeywordsC9subscriptyyF", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "CollisionsWithEscapedKeywords", + "subscript()" + ], + "names": { + "title": "subscript()", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "`subscript`" + }, + { + "kind": "text", + "spelling": "()" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 33, + "character": 8 + }, + "end": { + "line": 33, + "character": 45 + } + }, + "text": "An instance method named \"subscript\"." + } + ] + }, + "functionSignature": { + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "`subscript`" + }, + { + "kind": "text", + "spelling": "()" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithVariousCollisions.swift", + "position": { + "line": 34, + "character": 16 + } + } + }, + { + "kind": { + "identifier": "swift.property", + "displayName": "Instance Property" + }, + "identifier": { + "precise": "s:14MixedFramework6MyEnumO02myD8PropertySivp", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyEnum", + "myEnumProperty" + ], + "names": { + "title": "myEnumProperty", + "subHeading": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myEnumProperty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyEnumTypeAlias", + "preciseIdentifier": "s:14MixedFramework6MyEnumO0cD9TypeAliasa" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 20, + "character": 8 + }, + "end": { + "line": 20, + "character": 30 + } + }, + "text": "A property on my enum." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myEnumProperty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyEnumTypeAlias", + "preciseIdentifier": "s:14MixedFramework6MyEnumO0cD9TypeAliasa" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 21, + "character": 15 + } + } + }, + { + "kind": { + "identifier": "swift.init", + "displayName": "Initializer" + }, + "identifier": { + "precise": "s:So31MyTypedObjectiveCExtensibleEnuma8rawValueABSi_tcfc", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyTypedObjectiveCExtensibleEnum", + "init(rawValue:)" + ], + "names": { + "title": "init(rawValue:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "init" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "rawValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": ")" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "init" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "rawValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": ")" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.class", + "displayName": "Class" + }, + "identifier": { + "precise": "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MySwiftClassSwiftName" + ], + "names": { + "title": "MySwiftClassSwiftName", + "navigator": [ + { + "kind": "identifier", + "spelling": "MySwiftClassSwiftName" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "class" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MySwiftClassSwiftName" + } + ] + }, + "declarationFragments": [ + { + "kind": "attribute", + "spelling": "@objc" + }, + { + "kind": "text", + "spelling": "(MySwiftClassObjectiveCName) " + }, + { + "kind": "keyword", + "spelling": "class" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MySwiftClassSwiftName" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithDifferentObjectiveCNames.swift", + "position": { + "line": 12, + "character": 13 + } + } + }, + { + "kind": { + "identifier": "swift.subscript", + "displayName": "Instance Subscript" + }, + "identifier": { + "precise": "s:14MixedFramework41CollisionsWithDifferentSubscriptArgumentsOySiSScip", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "CollisionsWithDifferentSubscriptArguments", + "subscript(_:)" + ], + "names": { + "title": "subscript(_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "subscript" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "String", + "preciseIdentifier": "s:SS" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 58, + "character": 8 + }, + "end": { + "line": 58, + "character": 60 + } + }, + "text": "A subscript with a \"something else\" String argument." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "subscript" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "internalParam", + "spelling": "somethingElse" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "String", + "preciseIdentifier": "s:SS" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithVariousCollisions.swift", + "position": { + "line": 59, + "character": 11 + } + } + }, + { + "kind": { + "identifier": "swift.typealias", + "displayName": "Type Alias" + }, + "identifier": { + "precise": "s:14MixedFramework6MyEnumO0cD9TypeAliasa", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyEnum", + "MyEnumTypeAlias" + ], + "names": { + "title": "MyEnum.MyEnumTypeAlias", + "navigator": [ + { + "kind": "identifier", + "spelling": "MyEnumTypeAlias" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "typealias" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyEnumTypeAlias" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 18, + "character": 8 + }, + "end": { + "line": 18, + "character": 32 + } + }, + "text": "A type alias on my enum." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "typealias" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyEnumTypeAlias" + }, + { + "kind": "text", + "spelling": " = " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 19, + "character": 21 + } + } + }, + { + "kind": { + "identifier": "swift.class", + "displayName": "Class" + }, + "identifier": { + "precise": "c:objc(cs)MyObjectiveCClassObjectiveCName", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCClassSwiftName" + ], + "names": { + "title": "MyObjectiveCClassSwiftName", + "navigator": [ + { + "kind": "identifier", + "spelling": "MyObjectiveCClassSwiftName" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "class" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyObjectiveCClassSwiftName" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "class" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyObjectiveCClassSwiftName" + } + ], + "accessLevel": "open" + }, + { + "kind": { + "identifier": "swift.struct", + "displayName": "Structure" + }, + "identifier": { + "precise": "s:14MixedFramework8MyStructV", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyStruct" + ], + "names": { + "title": "MyStruct", + "navigator": [ + { + "kind": "identifier", + "spelling": "MyStruct" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "struct" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyStruct" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 24, + "character": 4 + }, + "end": { + "line": 24, + "character": 14 + } + }, + "text": "My struct." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "struct" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyStruct" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 25, + "character": 14 + } + } + }, + { + "kind": { + "identifier": "swift.property", + "displayName": "Instance Property" + }, + "identifier": { + "precise": "s:14MixedFramework37CollisionsWithDifferentCapitalizationC9somethingSivp", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "CollisionsWithDifferentCapitalization", + "something" + ], + "names": { + "title": "something", + "subHeading": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "something" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 13, + "character": 8 + }, + "end": { + "line": 13, + "character": 31 + } + }, + "text": "A \"something\" property." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "something" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithVariousCollisions.swift", + "position": { + "line": 14, + "character": 15 + } + } + }, + { + "kind": { + "identifier": "swift.enum.case", + "displayName": "Case" + }, + "identifier": { + "precise": "c:@E@MyObjectiveCEnum@MyObjectiveCEnumSecond", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCEnum", + "secondCaseSwiftName" + ], + "names": { + "title": "MyObjectiveCEnum.secondCaseSwiftName", + "subHeading": [ + { + "kind": "keyword", + "spelling": "case" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "secondCaseSwiftName" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "case" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "secondCaseSwiftName" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.associatedtype", + "displayName": "Associated Type" + }, + "identifier": { + "precise": "s:14MixedFramework15MySwiftProtocolP0cE14AssociatedTypeQa", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MySwiftProtocol", + "MyProtocolAssociatedType" + ], + "names": { + "title": "MyProtocolAssociatedType", + "subHeading": [ + { + "kind": "keyword", + "spelling": "associatedtype" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyProtocolAssociatedType" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 70, + "character": 8 + }, + "end": { + "line": 70, + "character": 42 + } + }, + "text": "An associated type on my protocol." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "associatedtype" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyProtocolAssociatedType" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 71, + "character": 19 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName(im)myMethodObjectiveCName", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MySwiftClassSwiftName", + "myMethodSwiftName()" + ], + "names": { + "title": "myMethodSwiftName()", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myMethodSwiftName" + }, + { + "kind": "text", + "spelling": "() -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ] + }, + "functionSignature": { + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ] + }, + "declarationFragments": [ + { + "kind": "attribute", + "spelling": "@objc" + }, + { + "kind": "text", + "spelling": "(myMethodObjectiveCName) " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myMethodSwiftName" + }, + { + "kind": "text", + "spelling": "() -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithDifferentObjectiveCNames.swift", + "position": { + "line": 17, + "character": 16 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:14MixedFramework7MyClassC25mySwiftOnlyInstanceMethodyyF", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyClass", + "mySwiftOnlyInstanceMethod()" + ], + "names": { + "title": "mySwiftOnlyInstanceMethod()", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "mySwiftOnlyInstanceMethod" + }, + { + "kind": "text", + "spelling": "()" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 41, + "character": 8 + }, + "end": { + "line": 41, + "character": 39 + } + }, + "text": "An instance method on my class." + } + ] + }, + "functionSignature": { + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "declarationFragments": [ + { + "kind": "attribute", + "spelling": "@nonobjc" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "mySwiftOnlyInstanceMethod" + }, + { + "kind": "text", + "spelling": "()" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 42, + "character": 25 + } + } + }, + { + "kind": { + "identifier": "swift.typealias", + "displayName": "Type Alias" + }, + "identifier": { + "precise": "s:14MixedFramework15MySwiftProtocolP0cE9TypeAliasa", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MySwiftProtocol", + "MyProtocolTypeAlias" + ], + "names": { + "title": "MySwiftProtocol.MyProtocolTypeAlias", + "navigator": [ + { + "kind": "identifier", + "spelling": "MyProtocolTypeAlias" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "typealias" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyProtocolTypeAlias" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 72, + "character": 8 + }, + "end": { + "line": 72, + "character": 36 + } + }, + "text": "A type alias on my protocol." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "typealias" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyProtocolTypeAlias" + }, + { + "kind": "text", + "spelling": " = " + }, + { + "kind": "typeIdentifier", + "spelling": "MyStruct", + "preciseIdentifier": "s:14MixedFramework8MyStructV" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 73, + "character": 14 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "c:@M@MixedFramework@objc(cs)MyClass(im)myInstanceMethod", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyClass", + "myInstanceMethod()" + ], + "names": { + "title": "myInstanceMethod()", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myInstanceMethod" + }, + { + "kind": "text", + "spelling": "()" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 39, + "character": 8 + }, + "end": { + "line": 39, + "character": 39 + } + }, + "text": "An instance method on my class." + } + ] + }, + "functionSignature": { + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "declarationFragments": [ + { + "kind": "attribute", + "spelling": "@objc" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myInstanceMethod" + }, + { + "kind": "text", + "spelling": "()" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 40, + "character": 22 + } + } + }, + { + "kind": { + "identifier": "swift.type.property", + "displayName": "Type Property" + }, + "identifier": { + "precise": "s:14MixedFramework7MyClassC02myD12TypePropertySivpZ", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyClass", + "myClassTypeProperty" + ], + "names": { + "title": "myClassTypeProperty", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myClassTypeProperty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyClassTypeAlias", + "preciseIdentifier": "s:14MixedFramework7MyClassC0cD9TypeAliasa" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 47, + "character": 8 + }, + "end": { + "line": 47, + "character": 44 + } + }, + "text": "A class (type) property on my class." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myClassTypeProperty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyClassTypeAlias", + "preciseIdentifier": "s:14MixedFramework7MyClassC0cD9TypeAliasa" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 48, + "character": 22 + } + } + }, + { + "kind": { + "identifier": "swift.property", + "displayName": "Instance Property" + }, + "identifier": { + "precise": "s:SYsSHRzSH8RawValueSYRpzrlE04hashB0Sivp::SYNTHESIZED::c:@E@MyObjectiveCEnumObjectiveCName", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCEnumSwiftName", + "hashValue" + ], + "names": { + "title": "hashValue", + "subHeading": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hashValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift", + "constraints": [ + { + "kind": "conformance", + "lhs": "Self", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + }, + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hashValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:s10SetAlgebraPsE16isStrictSuperset2ofSbx_tF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "isStrictSuperset(of:)" + ], + "names": { + "title": "isStrictSuperset(of:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "isStrictSuperset" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "of" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Returns a Boolean value that indicates whether this set is a strict" + }, + { + "text": "superset of the given set." + }, + { + "text": "" + }, + { + "text": "Set *A* is a strict superset of another set *B* if every member of *B* is" + }, + { + "text": "also a member of *A* and *A* contains at least one element that is *not*" + }, + { + "text": "a member of *B*." + }, + { + "text": "" + }, + { + "text": " let employees: Set = [\"Alicia\", \"Bethany\", \"Chris\", \"Diana\", \"Eric\"]" + }, + { + "text": " let attendees: Set = [\"Alicia\", \"Bethany\", \"Diana\"]" + }, + { + "text": " print(employees.isStrictSuperset(of: attendees))" + }, + { + "text": " // Prints \"true\"" + }, + { + "text": "" + }, + { + "text": " // A set is never a strict superset of itself:" + }, + { + "text": " print(employees.isStrictSuperset(of: employees))" + }, + { + "text": " // Prints \"false\"" + }, + { + "text": "" + }, + { + "text": "- Parameter other: A set of the same type as the current set." + }, + { + "text": "- Returns: `true` if the set is a strict superset of `other`; otherwise," + }, + { + "text": " `false`." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "of", + "internalName": "other", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "isStrictSuperset" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "of" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.init", + "displayName": "Initializer" + }, + "identifier": { + "precise": "s:14MixedFramework29CollisionsWithEscapedKeywordsCACycfc", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "CollisionsWithEscapedKeywords", + "init()" + ], + "names": { + "title": "init()", + "subHeading": [ + { + "kind": "keyword", + "spelling": "init" + }, + { + "kind": "text", + "spelling": "()" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 38, + "character": 8 + }, + "end": { + "line": 38, + "character": 40 + } + }, + "text": "An initializer without arguments" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "init" + }, + { + "kind": "text", + "spelling": "()" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithVariousCollisions.swift", + "position": { + "line": 39, + "character": 11 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:s9OptionSetPs7ElementQzRszrlE6insertySb8inserted_x17memberAfterInserttxF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "insert(_:)" + ], + "names": { + "title": "insert(_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "insert" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": "." + }, + { + "kind": "typeIdentifier", + "spelling": "Element" + }, + { + "kind": "text", + "spelling": ") -> (inserted" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + }, + { + "kind": "text", + "spelling": ", memberAfterInsert" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": "." + }, + { + "kind": "typeIdentifier", + "spelling": "Element" + }, + { + "kind": "text", + "spelling": ")" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Adds the given element to the option set if it is not already a member." + }, + { + "text": "" + }, + { + "text": "In the following example, the `.secondDay` shipping option is added to" + }, + { + "text": "the `freeOptions` option set if `purchasePrice` is greater than 50.0. For" + }, + { + "text": "the `ShippingOptions` declaration, see the `OptionSet` protocol" + }, + { + "text": "discussion." + }, + { + "text": "" + }, + { + "text": " let purchasePrice = 87.55" + }, + { + "text": "" + }, + { + "text": " var freeOptions: ShippingOptions = [.standard, .priority]" + }, + { + "text": " if purchasePrice > 50 {" + }, + { + "text": " freeOptions.insert(.secondDay)" + }, + { + "text": " }" + }, + { + "text": " print(freeOptions.contains(.secondDay))" + }, + { + "text": " // Prints \"true\"" + }, + { + "text": "" + }, + { + "text": "- Parameter newMember: The element to insert." + }, + { + "text": "- Returns: `(true, newMember)` if `newMember` was not contained in" + }, + { + "text": " `self`. Otherwise, returns `(false, oldMember)`, where `oldMember` is" + }, + { + "text": " the member of the set equal to `newMember`." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "newMember", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "newMember" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": "." + }, + { + "kind": "typeIdentifier", + "spelling": "Element" + } + ] + } + ], + "returns": [ + { + "kind": "text", + "spelling": "(inserted" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + }, + { + "kind": "text", + "spelling": ", memberAfterInsert" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": "." + }, + { + "kind": "typeIdentifier", + "spelling": "Element" + }, + { + "kind": "text", + "spelling": ")" + } + ] + }, + "swiftGenerics": { + "constraints": [ + { + "kind": "sameType", + "lhs": "Self", + "rhs": "Self.Element" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift", + "constraints": [ + { + "kind": "sameType", + "lhs": "Self", + "rhs": "Self.Element" + } + ] + }, + "declarationFragments": [ + { + "kind": "attribute", + "spelling": "@discardableResult" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "mutating" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "insert" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "_" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "newMember" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": "." + }, + { + "kind": "typeIdentifier", + "spelling": "Element" + }, + { + "kind": "text", + "spelling": ") -> (inserted" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + }, + { + "kind": "text", + "spelling": ", memberAfterInsert" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": "." + }, + { + "kind": "typeIdentifier", + "spelling": "Element" + }, + { + "kind": "text", + "spelling": ")" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "c:objc(cs)MyObjectiveCClassObjectiveCName(im)myMethodObjectiveCName", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCClassSwiftName", + "myMethodSwiftName()" + ], + "names": { + "title": "myMethodSwiftName()", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myMethodSwiftName" + }, + { + "kind": "text", + "spelling": "()" + } + ] + }, + "functionSignature": { + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Void", + "preciseIdentifier": "s:s4Voida" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myMethodSwiftName" + }, + { + "kind": "text", + "spelling": "()" + } + ], + "accessLevel": "open" + }, + { + "kind": { + "identifier": "swift.property", + "displayName": "Instance Property" + }, + "identifier": { + "precise": "s:SYsSHRzSH8RawValueSYRpzrlE04hashB0Sivp::SYNTHESIZED::c:@E@MyObjectiveCEnum", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCEnum", + "hashValue" + ], + "names": { + "title": "hashValue", + "subHeading": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hashValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift", + "constraints": [ + { + "kind": "conformance", + "lhs": "Self", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + }, + { + "kind": "conformance", + "lhs": "Self.RawValue", + "rhs": "Hashable", + "rhsPrecise": "s:SH" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "hashValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.enum.case", + "displayName": "Case" + }, + "identifier": { + "precise": "c:@E@MyObjectiveCEnumObjectiveCName@MyObjectiveCEnumObjectiveCNameSecond", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCEnumSwiftName", + "secondCaseSwiftName" + ], + "names": { + "title": "MyObjectiveCEnumSwiftName.secondCaseSwiftName", + "subHeading": [ + { + "kind": "keyword", + "spelling": "case" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "secondCaseSwiftName" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "case" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "secondCaseSwiftName" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.struct", + "displayName": "Structure" + }, + "identifier": { + "precise": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyTypedObjectiveCEnum" + ], + "names": { + "title": "MyTypedObjectiveCEnum", + "navigator": [ + { + "kind": "identifier", + "spelling": "MyTypedObjectiveCEnum" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "struct" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyTypedObjectiveCEnum" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "struct" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyTypedObjectiveCEnum" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:s10SetAlgebraPsE10isDisjoint4withSbx_tF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "isDisjoint(with:)" + ], + "names": { + "title": "isDisjoint(with:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "isDisjoint" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "with" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Returns a Boolean value that indicates whether the set has no members in" + }, + { + "text": "common with the given set." + }, + { + "text": "" + }, + { + "text": "In the following example, the `employees` set is disjoint with the" + }, + { + "text": "`visitors` set because no name appears in both sets." + }, + { + "text": "" + }, + { + "text": " let employees: Set = [\"Alicia\", \"Bethany\", \"Chris\", \"Diana\", \"Eric\"]" + }, + { + "text": " let visitors: Set = [\"Marcia\", \"Nathaniel\", \"Olivia\"]" + }, + { + "text": " print(employees.isDisjoint(with: visitors))" + }, + { + "text": " // Prints \"true\"" + }, + { + "text": "" + }, + { + "text": "- Parameter other: A set of the same type as the current set." + }, + { + "text": "- Returns: `true` if the set has no elements in common with `other`;" + }, + { + "text": " otherwise, `false`." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "with", + "internalName": "other", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "isDisjoint" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "with" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:14MixedFramework6MyEnumO02myD8FunctionyyF", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyEnum", + "myEnumFunction()" + ], + "names": { + "title": "myEnumFunction()", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myEnumFunction" + }, + { + "kind": "text", + "spelling": "()" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 16, + "character": 8 + }, + "end": { + "line": 16, + "character": 30 + } + }, + "text": "A function on my enum." + } + ] + }, + "functionSignature": { + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myEnumFunction" + }, + { + "kind": "text", + "spelling": "()" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 17, + "character": 16 + } + } + }, + { + "kind": { + "identifier": "swift.property", + "displayName": "Instance Property" + }, + "identifier": { + "precise": "s:14MixedFramework15MySwiftProtocolP02myE8Property0cE14AssociatedTypeQzvp", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MySwiftProtocol", + "myProtocolProperty" + ], + "names": { + "title": "myProtocolProperty", + "subHeading": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myProtocolProperty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyProtocolAssociatedType", + "preciseIdentifier": "s:14MixedFramework15MySwiftProtocolP0cE14AssociatedTypeQa" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 74, + "character": 8 + }, + "end": { + "line": 74, + "character": 34 + } + }, + "text": "A property on my protocol." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myProtocolProperty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyProtocolAssociatedType", + "preciseIdentifier": "s:14MixedFramework15MySwiftProtocolP0cE14AssociatedTypeQa" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 75, + "character": 8 + } + } + }, + { + "kind": { + "identifier": "swift.init", + "displayName": "Initializer" + }, + "identifier": { + "precise": "s:So31MyTypedObjectiveCExtensibleEnumayABSicfc", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyTypedObjectiveCExtensibleEnum", + "init(_:)" + ], + "names": { + "title": "init(_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "init" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": ")" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "init" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "_" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "rawValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": ")" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.property", + "displayName": "Instance Property" + }, + "identifier": { + "precise": "s:14MixedFramework37CollisionsWithDifferentCapitalizationC9someThingSivp", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "CollisionsWithDifferentCapitalization", + "someThing" + ], + "names": { + "title": "someThing", + "subHeading": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "someThing" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 15, + "character": 8 + }, + "end": { + "line": 15, + "character": 32 + } + }, + "text": "A \"some thing\" property." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "someThing" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithVariousCollisions.swift", + "position": { + "line": 16, + "character": 15 + } + } + }, + { + "kind": { + "identifier": "swift.enum", + "displayName": "Enumeration" + }, + "identifier": { + "precise": "c:@M@MixedFramework@E@MyEnum", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyEnum" + ], + "names": { + "title": "MyEnum", + "navigator": [ + { + "kind": "identifier", + "spelling": "MyEnum" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "enum" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyEnum" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 9, + "character": 4 + }, + "end": { + "line": 9, + "character": 35 + } + }, + "text": "My Objective-C compatible enum." + } + ] + }, + "declarationFragments": [ + { + "kind": "attribute", + "spelling": "@objc" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "enum" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "MyEnum" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 11, + "character": 12 + } + } + }, + { + "kind": { + "identifier": "swift.enum.case", + "displayName": "Case" + }, + "identifier": { + "precise": "c:@M@MixedFramework@E@MyEnum@MyEnumSecondCase", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyEnum", + "secondCase" + ], + "names": { + "title": "MyEnum.secondCase", + "subHeading": [ + { + "kind": "keyword", + "spelling": "case" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "secondCase" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 14, + "character": 8 + }, + "end": { + "line": 14, + "character": 29 + } + }, + "text": "The second enum case." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "case" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "secondCase" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 15, + "character": 9 + } + } + }, + { + "kind": { + "identifier": "swift.type.method", + "displayName": "Type Method" + }, + "identifier": { + "precise": "s:14MixedFramework29CollisionsWithEscapedKeywordsC4inityyFZ", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "CollisionsWithEscapedKeywords", + "init()" + ], + "names": { + "title": "init()", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "`init`" + }, + { + "kind": "text", + "spelling": "()" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 42, + "character": 8 + }, + "end": { + "line": 42, + "character": 43 + } + }, + "text": "A class (type) method named \"init\"." + } + ] + }, + "functionSignature": { + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "`init`" + }, + { + "kind": "text", + "spelling": "()" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithVariousCollisions.swift", + "position": { + "line": 43, + "character": 23 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:s9OptionSetPsE19symmetricDifferenceyxxF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "symmetricDifference(_:)" + ], + "names": { + "title": "symmetricDifference(_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "symmetricDifference" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Returns a new option set with the elements contained in this set or in" + }, + { + "text": "the given set, but not in both." + }, + { + "text": "" + }, + { + "text": "- Parameter other: An option set." + }, + { + "text": "- Returns: A new option set with only the elements contained in either" + }, + { + "text": " this set or `other`, but not in both." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "other", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "symmetricDifference" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "_" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "other" + }, + { + "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:SQsE2neoiySbx_xtFZ::SYNTHESIZED::c:@E@MyObjectiveCEnumObjectiveCName", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCEnumSwiftName", + "!=(_:_:)" + ], + "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.class", + "displayName": "Class" + }, + "identifier": { + "precise": "s:14MixedFramework37CollisionsWithDifferentCapitalizationC", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "CollisionsWithDifferentCapitalization" + ], + "names": { + "title": "CollisionsWithDifferentCapitalization", + "navigator": [ + { + "kind": "identifier", + "spelling": "CollisionsWithDifferentCapitalization" + } + ], + "subHeading": [ + { + "kind": "keyword", + "spelling": "class" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "CollisionsWithDifferentCapitalization" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 11, + "character": 4 + }, + "end": { + "line": 11, + "character": 79 + } + }, + "text": "A container for properties with the same name but different capitalization." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "final" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "class" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "CollisionsWithDifferentCapitalization" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithVariousCollisions.swift", + "position": { + "line": 12, + "character": 19 + } + } + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:14MixedFramework29CollisionsWithEscapedKeywordsC4inityyF", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "CollisionsWithEscapedKeywords", + "init()" + ], + "names": { + "title": "init()", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "`init`" + }, + { + "kind": "text", + "spelling": "()" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 40, + "character": 8 + }, + "end": { + "line": 40, + "character": 40 + } + }, + "text": "An instance method named \"init\"." + } + ] + }, + "functionSignature": { + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "`init`" + }, + { + "kind": "text", + "spelling": "()" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithVariousCollisions.swift", + "position": { + "line": 41, + "character": 16 + } + } + }, + { + "kind": { + "identifier": "swift.enum.case", + "displayName": "Case" + }, + "identifier": { + "precise": "c:@M@MixedFramework@E@MyEnum@MyEnumFirstCase", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyEnum", + "firstCase" + ], + "names": { + "title": "MyEnum.firstCase", + "subHeading": [ + { + "kind": "keyword", + "spelling": "case" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "firstCase" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 12, + "character": 8 + }, + "end": { + "line": 12, + "character": 28 + } + }, + "text": "The first enum case." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "case" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "firstCase" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 13, + "character": 9 + } + } + }, + { + "kind": { + "identifier": "swift.func.op", + "displayName": "Operator" + }, + "identifier": { + "precise": "s:SQsE2neoiySbx_xtFZ::SYNTHESIZED::c:@E@MyObjectiveCEnum", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCEnum", + "!=(_:_:)" + ], + "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.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:s9OptionSetPs7ElementQzRszrlE8containsySbxF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "contains(_:)" + ], + "names": { + "title": "contains(_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "contains" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Returns a Boolean value that indicates whether a given element is a" + }, + { + "text": "member of the option set." + }, + { + "text": "" + }, + { + "text": "This example uses the `contains(_:)` method to check whether next-day" + }, + { + "text": "shipping is in the `availableOptions` instance." + }, + { + "text": "" + }, + { + "text": " let availableOptions = ShippingOptions.express" + }, + { + "text": " if availableOptions.contains(.nextDay) {" + }, + { + "text": " print(\"Next day shipping available\")" + }, + { + "text": " }" + }, + { + "text": " // Prints \"Next day shipping available\"" + }, + { + "text": "" + }, + { + "text": "- Parameter member: The element to look for in the option set." + }, + { + "text": "- Returns: `true` if the option set contains `member`; otherwise," + }, + { + "text": " `false`." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "member", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "member" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ] + }, + "swiftGenerics": { + "constraints": [ + { + "kind": "sameType", + "lhs": "Self", + "rhs": "Self.Element" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift", + "constraints": [ + { + "kind": "sameType", + "lhs": "Self", + "rhs": "Self.Element" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "contains" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "_" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "member" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Bool", + "preciseIdentifier": "s:Sb" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.type.property", + "displayName": "Type Property" + }, + "identifier": { + "precise": "c:@E@MyObjectiveCOption@MyObjectiveCOptionSecond", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "secondCaseSwiftName" + ], + "names": { + "title": "secondCaseSwiftName", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "secondCaseSwiftName" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyObjectiveCOption", + "preciseIdentifier": "c:@E@MyObjectiveCOption" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "secondCaseSwiftName" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyObjectiveCOption", + "preciseIdentifier": "c:@E@MyObjectiveCOption" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "s:s10SetAlgebraPsE11subtractingyxxF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "subtracting(_:)" + ], + "names": { + "title": "subtracting(_:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "subtracting" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + "docComment": { + "lines": [ + { + "text": "Returns a new set containing the elements of this set that do not occur" + }, + { + "text": "in the given set." + }, + { + "text": "" + }, + { + "text": "In the following example, the `nonNeighbors` set is made up of the" + }, + { + "text": "elements of the `employees` set that are not elements of `neighbors`:" + }, + { + "text": "" + }, + { + "text": " let employees: Set = [\"Alicia\", \"Bethany\", \"Chris\", \"Diana\", \"Eric\"]" + }, + { + "text": " let neighbors: Set = [\"Bethany\", \"Eric\", \"Forlani\", \"Greta\"]" + }, + { + "text": " let nonNeighbors = employees.subtracting(neighbors)" + }, + { + "text": " print(nonNeighbors)" + }, + { + "text": " // Prints \"[\"Diana\", \"Chris\", \"Alicia\"]\"" + }, + { + "text": "" + }, + { + "text": "- Parameter other: A set of the same type as the current set." + }, + { + "text": "- Returns: A new set." + } + ] + }, + "functionSignature": { + "parameters": [ + { + "name": "other", + "declarationFragments": [ + { + "kind": "identifier", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ] + }, + "swiftExtension": { + "extendedModule": "Swift" + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "subtracting" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "_" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "other" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + }, + { + "kind": "text", + "spelling": ") -> " + }, + { + "kind": "typeIdentifier", + "spelling": "Self" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.enum.case", + "displayName": "Case" + }, + "identifier": { + "precise": "s:14MixedFramework28CollisionsWithDifferentKindsO9somethingyA2CmF", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "CollisionsWithDifferentKinds", + "something" + ], + "names": { + "title": "CollisionsWithDifferentKinds.something", + "subHeading": [ + { + "kind": "keyword", + "spelling": "case" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "something" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 21, + "character": 8 + }, + "end": { + "line": 21, + "character": 31 + } + }, + "text": "A \"something\" enum case" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "case" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "something" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithVariousCollisions.swift", + "position": { + "line": 22, + "character": 9 + } + } + }, + { + "kind": { + "identifier": "swift.init", + "displayName": "Initializer" + }, + "identifier": { + "precise": "s:So18MyObjectiveCOptionV8rawValueABSi_tcfc", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCOption", + "init(rawValue:)" + ], + "names": { + "title": "init(rawValue:)", + "subHeading": [ + { + "kind": "keyword", + "spelling": "init" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "rawValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": ")" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "init" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "externalParam", + "spelling": "rawValue" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "Int", + "preciseIdentifier": "s:Si" + }, + { + "kind": "text", + "spelling": ")" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.property", + "displayName": "Instance Property" + }, + "identifier": { + "precise": "c:objc(cs)MyObjectiveCClassObjectiveCName(py)myPropertyObjectiveCName", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCClassSwiftName", + "myPropertySwiftName" + ], + "names": { + "title": "myPropertySwiftName", + "subHeading": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myPropertySwiftName" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "String", + "preciseIdentifier": "s:SS" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myPropertySwiftName" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "String", + "preciseIdentifier": "s:SS" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "open" + }, + { + "kind": { + "identifier": "swift.enum.case", + "displayName": "Case" + }, + "identifier": { + "precise": "c:@E@MyObjectiveCEnumObjectiveCName@MyObjectiveCEnumObjectiveCNameFirst", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCEnumSwiftName", + "first" + ], + "names": { + "title": "MyObjectiveCEnumSwiftName.first", + "subHeading": [ + { + "kind": "keyword", + "spelling": "case" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "first" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "case" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "first" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.type.property", + "displayName": "Type Property" + }, + "identifier": { + "precise": "s:14MixedFramework8MyStructV02myD12TypePropertySivpZ", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyStruct", + "myStructTypeProperty" + ], + "names": { + "title": "myStructTypeProperty", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myStructTypeProperty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyStructTypeAlias", + "preciseIdentifier": "s:14MixedFramework8MyStructV0cD9TypeAliasa" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 32, + "character": 8 + }, + "end": { + "line": 32, + "character": 37 + } + }, + "text": "A type property on my struct." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myStructTypeProperty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyStructTypeAlias", + "preciseIdentifier": "s:14MixedFramework8MyStructV0cD9TypeAliasa" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 33, + "character": 22 + } + } + }, + { + "kind": { + "identifier": "swift.type.property", + "displayName": "Type Property" + }, + "identifier": { + "precise": "s:14MixedFramework15MySwiftProtocolP02myE12TypeProperty0ce10AssociatedG0QzvpZ", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MySwiftProtocol", + "myProtocolTypeProperty" + ], + "names": { + "title": "myProtocolTypeProperty", + "subHeading": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myProtocolTypeProperty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyProtocolAssociatedType", + "preciseIdentifier": "s:14MixedFramework15MySwiftProtocolP0cE14AssociatedTypeQa" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 76, + "character": 8 + }, + "end": { + "line": 76, + "character": 39 + } + }, + "text": "A type property on my protocol." + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "static" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "keyword", + "spelling": "var" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myProtocolTypeProperty" + }, + { + "kind": "text", + "spelling": ": " + }, + { + "kind": "typeIdentifier", + "spelling": "MyProtocolAssociatedType", + "preciseIdentifier": "s:14MixedFramework15MySwiftProtocolP0cE14AssociatedTypeQa" + }, + { + "kind": "text", + "spelling": " { " + }, + { + "kind": "keyword", + "spelling": "get" + }, + { + "kind": "text", + "spelling": " }" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 77, + "character": 15 + } + } + }, + { + "kind": { + "identifier": "swift.enum.case", + "displayName": "Case" + }, + "identifier": { + "precise": "c:@E@MyObjectiveCEnum@MyObjectiveCEnumFirst", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCEnum", + "first" + ], + "names": { + "title": "MyObjectiveCEnum.first", + "subHeading": [ + { + "kind": "keyword", + "spelling": "case" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "first" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "case" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "first" + } + ], + "accessLevel": "public" + }, + { + "kind": { + "identifier": "swift.method", + "displayName": "Instance Method" + }, + "identifier": { + "precise": "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(im)myProtocolMethod", + "interfaceLanguage": "swift" + }, + "pathComponents": [ + "MyObjectiveCCompatibleProtocol", + "myProtocolMethod()" + ], + "names": { + "title": "myProtocolMethod()", + "subHeading": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myProtocolMethod" + }, + { + "kind": "text", + "spelling": "()" + } + ] + }, + "docComment": { + "lines": [ + { + "range": { + "start": { + "line": 54, + "character": 8 + }, + "end": { + "line": 54, + "character": 41 + } + }, + "text": "A method/function on my protocol." + } + ] + }, + "functionSignature": { + "returns": [ + { + "kind": "text", + "spelling": "()" + } + ] + }, + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "func" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "myProtocolMethod" + }, + { + "kind": "text", + "spelling": "()" + } + ], + "accessLevel": "public", + "location": { + "uri": "file:///Users/username/path/to/MixedFramework/DeclarationsWithMinimalCollisions.swift", + "position": { + "line": 55, + "character": 9 + } + } + } + ], + "relationships": [ + { + "kind": "memberOf", + "source": "s:So016MyObjectiveCEnumB5CNameV8rawValueABSgSi_tcfc", + "target": "c:@E@MyObjectiveCEnumObjectiveCName" + }, + { + "kind": "memberOf", + "source": "c:@E@MyObjectiveCOption@MyObjectiveCOptionFirst", + "target": "c:@E@MyObjectiveCOption" + }, + { + "kind": "memberOf", + "source": "s:s10SetAlgebraPsEyxqd__ncSTRd__7ElementQyd__ACRtzlufc::SYNTHESIZED::c:@E@MyObjectiveCOption", + "target": "c:@E@MyObjectiveCOption", + "sourceOrigin": { + "identifier": "s:s10SetAlgebraPsEyxqd__ncSTRd__7ElementQyd__ACRtzlufc", + "displayName": "SetAlgebra.init(_:)" + } + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework30MyObjectiveCCompatibleProtocolP0cF9TypeAliasa", + "target": "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol" + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName", + "target": "s:s23CustomStringConvertibleP", + "targetFallback": "Swift.CustomStringConvertible" + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@E@MyEnum", + "target": "s:SQ", + "targetFallback": "Swift.Equatable" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework6MyEnumO0cD9TypeAliasa", + "target": "c:@M@MixedFramework@E@MyEnum" + }, + { + "kind": "conformsTo", + "source": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum", + "target": "s:SH", + "targetFallback": "Swift.Hashable" + }, + { + "kind": "conformsTo", + "source": "s:14MixedFramework28CollisionsWithDifferentKindsO", + "target": "s:SH", + "targetFallback": "Swift.Hashable" + }, + { + "kind": "memberOf", + "source": "s:So31MyTypedObjectiveCExtensibleEnuma8rawValueABSi_tcfc", + "target": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum" + }, + { + "kind": "conformsTo", + "source": "c:objc(cs)MyObjectiveCClassObjectiveCName", + "target": "s:s28CustomDebugStringConvertibleP", + "targetFallback": "Swift.CustomDebugStringConvertible" + }, + { + "kind": "memberOf", + "source": "s:s10SetAlgebraPsE14isStrictSubset2ofSbx_tF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "target": "c:@E@MyObjectiveCOption", + "sourceOrigin": { + "identifier": "s:s10SetAlgebraPsE14isStrictSubset2ofSbx_tF", + "displayName": "SetAlgebra.isStrictSubset(of:)" + } + }, + { + "kind": "inheritsFrom", + "source": "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol", + "target": "c:objc(cs)NSObject", + "targetFallback": "ObjectiveC.NSObject" + }, + { + "kind": "conformsTo", + "source": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum", + "target": "s:s8SendableP", + "targetFallback": "Swift.Sendable" + }, + { + "kind": "memberOf", + "source": "s:s9OptionSetPs7ElementQzRszrlE6removeyxSgxF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "target": "c:@E@MyObjectiveCOption", + "sourceOrigin": { + "identifier": "s:s9OptionSetPs7ElementQzRszrlE6removeyxSgxF", + "displayName": "OptionSet.remove(_:)" + } + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework37CollisionsWithDifferentCapitalizationC9somethingSivp", + "target": "s:14MixedFramework37CollisionsWithDifferentCapitalizationC" + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@objc(cs)MyClass", + "target": "s:s23CustomStringConvertibleP", + "targetFallback": "Swift.CustomStringConvertible" + }, + { + "kind": "requirementOf", + "source": "s:14MixedFramework15MySwiftProtocolP02myE6MethodyyF", + "target": "s:14MixedFramework15MySwiftProtocolP" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework6MyEnumO02myD8FunctionyyF", + "target": "c:@M@MixedFramework@E@MyEnum" + }, + { + "kind": "memberOf", + "source": "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol(im)myOtherProtocolMethod", + "target": "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol", + "sourceOrigin": { + "identifier": "s:14MixedFramework028MyOtherProtocolThatConformToc5SwiftE0P02mydE6MethodyyF", + "displayName": "MyOtherProtocolThatConformToMySwiftProtocol.myOtherProtocolMethod()" + } + }, + { + "kind": "conformsTo", + "source": "c:@E@MyObjectiveCEnum", + "target": "s:SY", + "targetFallback": "Swift.RawRepresentable" + }, + { + "kind": "conformsTo", + "source": "c:@E@MyObjectiveCEnumObjectiveCName", + "target": "s:SY", + "targetFallback": "Swift.RawRepresentable" + }, + { + "kind": "memberOf", + "source": "s:SYsSHRzSH8RawValueSYRpzrlE4hash4intoys6HasherVz_tF::SYNTHESIZED::c:@E@MyObjectiveCEnumObjectiveCName", + "target": "c:@E@MyObjectiveCEnumObjectiveCName", + "sourceOrigin": { + "identifier": "s:SYsSHRzSH8RawValueSYRpzrlE4hash4intoys6HasherVz_tF", + "displayName": "RawRepresentable.hash(into:)" + } + }, + { + "kind": "memberOf", + "source": "s:SYsSHRzSH8RawValueSYRpzrlE4hash4intoys6HasherVz_tF::SYNTHESIZED::c:@M@MixedFramework@E@MyEnum", + "target": "c:@M@MixedFramework@E@MyEnum", + "sourceOrigin": { + "identifier": "s:SYsSHRzSH8RawValueSYRpzrlE4hash4intoys6HasherVz_tF", + "displayName": "RawRepresentable.hash(into:)" + } + }, + { + "kind": "memberOf", + "source": "s:s9OptionSetPss17FixedWidthInteger8RawValueRpzrlE23formSymmetricDifferenceyyxF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "target": "c:@E@MyObjectiveCOption", + "sourceOrigin": { + "identifier": "s:s9OptionSetPss17FixedWidthInteger8RawValueRpzrlE23formSymmetricDifferenceyyxF", + "displayName": "OptionSet.formSymmetricDifference(_:)" + } + }, + { + "kind": "memberOf", + "source": "s:SYsSHRzSH8RawValueSYRpzrlE4hash4intoys6HasherVz_tF::SYNTHESIZED::c:@E@MyObjectiveCEnum", + "target": "c:@E@MyObjectiveCEnum", + "sourceOrigin": { + "identifier": "s:SYsSHRzSH8RawValueSYRpzrlE4hash4intoys6HasherVz_tF", + "displayName": "RawRepresentable.hash(into:)" + } + }, + { + "kind": "memberOf", + "source": "s:So31MyTypedObjectiveCExtensibleEnumayABSicfc", + "target": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum" + }, + { + "kind": "requirementOf", + "source": "s:14MixedFramework15MySwiftProtocolP0cE14AssociatedTypeQa", + "target": "s:14MixedFramework15MySwiftProtocolP" + }, + { + "kind": "requirementOf", + "source": "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(im)myPropertyOptionalMethod", + "target": "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol" + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName", + "target": "s:s28CustomDebugStringConvertibleP", + "targetFallback": "Swift.CustomDebugStringConvertible" + }, + { + "kind": "memberOf", + "source": "s:So16MyObjectiveCEnumV8rawValueABSgSi_tcfc", + "target": "c:@E@MyObjectiveCEnum" + }, + { + "kind": "conformsTo", + "source": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum", + "target": "s:SQ", + "targetFallback": "Swift.Equatable" + }, + { + "kind": "optionalRequirementOf", + "source": "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(im)myPropertyOptionalMethod", + "target": "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework8MyStructV02myD12TypePropertySivpZ", + "target": "s:14MixedFramework8MyStructV" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework6MyEnumO02myD8PropertySivp", + "target": "c:@M@MixedFramework@E@MyEnum" + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@objc(cs)MyClass", + "target": "s:s28CustomDebugStringConvertibleP", + "targetFallback": "Swift.CustomDebugStringConvertible" + }, + { + "kind": "memberOf", + "source": "s:s9OptionSetPs7ElementQzRszrlE6update4withxSgx_tF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "target": "c:@E@MyObjectiveCOption", + "sourceOrigin": { + "identifier": "s:s9OptionSetPs7ElementQzRszrlE6update4withxSgx_tF", + "displayName": "OptionSet.update(with:)" + } + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol", + "target": "s:s7CVarArgP", + "targetFallback": "Swift.CVarArg" + }, + { + "kind": "conformsTo", + "source": "s:14MixedFramework28CollisionsWithDifferentKindsO", + "target": "s:SQ", + "targetFallback": "Swift.Equatable" + }, + { + "kind": "memberOf", + "source": "c:objc(cs)MyObjectiveCClassObjectiveCName(py)myPropertyObjectiveCName", + "target": "c:objc(cs)MyObjectiveCClassObjectiveCName" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework29CollisionsWithEscapedKeywordsCSiycip", + "target": "s:14MixedFramework29CollisionsWithEscapedKeywordsC" + }, + { + "kind": "memberOf", + "source": "s:s10SetAlgebraPsE8subtractyyxF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "target": "c:@E@MyObjectiveCOption", + "sourceOrigin": { + "identifier": "s:s10SetAlgebraPsE8subtractyyxF", + "displayName": "SetAlgebra.subtract(_:)" + } + }, + { + "kind": "conformsTo", + "source": "c:objc(cs)MyObjectiveCClassObjectiveCName", + "target": "s:s23CustomStringConvertibleP", + "targetFallback": "Swift.CustomStringConvertible" + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@E@MyEnum", + "target": "s:SH", + "targetFallback": "Swift.Hashable" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework7MyClassC25mySwiftOnlyInstanceMethodyyF", + "target": "c:@M@MixedFramework@objc(cs)MyClass" + }, + { + "kind": "conformsTo", + "source": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum", + "target": "s:SH", + "targetFallback": "Swift.Hashable" + }, + { + "kind": "memberOf", + "source": "s:s9OptionSetPss17FixedWidthInteger8RawValueRpzrlE16formIntersectionyyxF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "target": "c:@E@MyObjectiveCOption", + "sourceOrigin": { + "identifier": "s:s9OptionSetPss17FixedWidthInteger8RawValueRpzrlE16formIntersectionyyxF", + "displayName": "OptionSet.formIntersection(_:)" + } + }, + { + "kind": "requirementOf", + "source": "s:14MixedFramework15MySwiftProtocolP02myE8Property0cE14AssociatedTypeQzvp", + "target": "s:14MixedFramework15MySwiftProtocolP" + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@objc(cs)MyClass", + "target": "s:SQ", + "targetFallback": "Swift.Equatable" + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName", + "target": "c:objc(pl)NSObject", + "targetFallback": "ObjectiveC.NSObjectProtocol" + }, + { + "kind": "memberOf", + "source": "c:objc(cs)MyObjectiveCClassObjectiveCName(im)myMethodWithArgument:", + "target": "c:objc(cs)MyObjectiveCClassObjectiveCName" + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@objc(cs)MyClass", + "target": "c:objc(pl)NSObject", + "targetFallback": "ObjectiveC.NSObjectProtocol" + }, + { + "kind": "conformsTo", + "source": "c:objc(cs)MyObjectiveCClassObjectiveCName", + "target": "s:SH", + "targetFallback": "Swift.Hashable" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework020MyClassThatConformToC13OtherProtocolC02myI8PropertyAA0C6StructVvp", + "target": "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol", + "sourceOrigin": { + "identifier": "s:14MixedFramework15MySwiftProtocolP02myE8Property0cE14AssociatedTypeQzvp", + "displayName": "MySwiftProtocol.myProtocolProperty" + } + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName", + "target": "s:SQ", + "targetFallback": "Swift.Equatable" + }, + { + "kind": "memberOf", + "source": "s:s9OptionSetPsE5unionyxxF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "target": "c:@E@MyObjectiveCOption", + "sourceOrigin": { + "identifier": "s:s9OptionSetPsE5unionyxxF", + "displayName": "OptionSet.union(_:)" + } + }, + { + "kind": "conformsTo", + "source": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum", + "target": "s:s8SendableP", + "targetFallback": "Swift.Sendable" + }, + { + "kind": "requirementOf", + "source": "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(im)myProtocolMethod", + "target": "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol" + }, + { + "kind": "memberOf", + "source": "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName(im)myMethodObjectiveCName", + "target": "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName" + }, + { + "kind": "memberOf", + "source": "s:s10SetAlgebraPsE8isSubset2ofSbx_tF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "target": "c:@E@MyObjectiveCOption", + "sourceOrigin": { + "identifier": "s:s10SetAlgebraPsE8isSubset2ofSbx_tF", + "displayName": "SetAlgebra.isSubset(of:)" + } + }, + { + "kind": "memberOf", + "source": "c:@M@MixedFramework@objc(cs)MyClass(im)myInstanceMethod", + "target": "c:@M@MixedFramework@objc(cs)MyClass" + }, + { + "kind": "conformsTo", + "source": "c:@E@MyObjectiveCOption", + "target": "s:s25ExpressibleByArrayLiteralP", + "targetFallback": "Swift.ExpressibleByArrayLiteral" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework7MyClassC02myD12TypePropertySivpZ", + "target": "c:@M@MixedFramework@objc(cs)MyClass" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework40CollisionsWithDifferentFunctionArgumentsO9something8argumentS2i_tF", + "target": "s:14MixedFramework40CollisionsWithDifferentFunctionArgumentsO" + }, + { + "kind": "memberOf", + "source": "s:s10SetAlgebraPsE10isSuperset2ofSbx_tF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "target": "c:@E@MyObjectiveCOption", + "sourceOrigin": { + "identifier": "s:s10SetAlgebraPsE10isSuperset2ofSbx_tF", + "displayName": "SetAlgebra.isSuperset(of:)" + } + }, + { + "kind": "memberOf", + "source": "s:s9OptionSetPss17FixedWidthInteger8RawValueRpzrlE9formUnionyyxF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "target": "c:@E@MyObjectiveCOption", + "sourceOrigin": { + "identifier": "s:s9OptionSetPss17FixedWidthInteger8RawValueRpzrlE9formUnionyyxF", + "displayName": "OptionSet.formUnion(_:)" + } + }, + { + "kind": "conformsTo", + "source": "c:@E@MyObjectiveCOption", + "target": "s:SY", + "targetFallback": "Swift.RawRepresentable" + }, + { + "kind": "memberOf", + "source": "s:s9OptionSetPss17FixedWidthInteger8RawValueRpzrlExycfc::SYNTHESIZED::c:@E@MyObjectiveCOption", + "target": "c:@E@MyObjectiveCOption", + "sourceOrigin": { + "identifier": "s:s9OptionSetPss17FixedWidthInteger8RawValueRpzrlExycfc", + "displayName": "OptionSet.init()" + } + }, + { + "kind": "memberOf", + "source": "c:@M@MixedFramework@E@MyEnum@MyEnumSecondCase", + "target": "c:@M@MixedFramework@E@MyEnum" + }, + { + "kind": "conformsTo", + "source": "c:objc(cs)MyObjectiveCClassObjectiveCName", + "target": "s:SQ", + "targetFallback": "Swift.Equatable" + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName", + "target": "s:SH", + "targetFallback": "Swift.Hashable" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework7MyClassC0cD9TypeAliasa", + "target": "c:@M@MixedFramework@objc(cs)MyClass" + }, + { + "kind": "memberOf", + "source": "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol(im)myProtocolMethod", + "target": "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol", + "sourceOrigin": { + "identifier": "s:14MixedFramework15MySwiftProtocolP02myE6MethodyyF", + "displayName": "MySwiftProtocol.myProtocolMethod()" + } + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework7MyClassC18myInstancePropertySivp", + "target": "c:@M@MixedFramework@objc(cs)MyClass" + }, + { + "kind": "memberOf", + "source": "c:objc(cs)MyObjectiveCClassObjectiveCName(im)myMethodObjectiveCName", + "target": "c:objc(cs)MyObjectiveCClassObjectiveCName" + }, + { + "kind": "memberOf", + "source": "s:s9OptionSetPsE12intersectionyxxF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "target": "c:@E@MyObjectiveCOption", + "sourceOrigin": { + "identifier": "s:s9OptionSetPsE12intersectionyxxF", + "displayName": "OptionSet.intersection(_:)" + } + }, + { + "kind": "memberOf", + "source": "s:s10SetAlgebraPs7ElementQz012ArrayLiteralC0RtzrlE05arrayE0xAFd_tcfc::SYNTHESIZED::c:@E@MyObjectiveCOption", + "target": "c:@E@MyObjectiveCOption", + "sourceOrigin": { + "identifier": "s:s10SetAlgebraPs7ElementQz012ArrayLiteralC0RtzrlE05arrayE0xAFd_tcfc", + "displayName": "SetAlgebra.init(arrayLiteral:)" + } + }, + { + "kind": "conformsTo", + "source": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum", + "target": "s:SQ", + "targetFallback": "Swift.Equatable" + }, + { + "kind": "conformsTo", + "source": "c:objc(cs)MyObjectiveCClassObjectiveCName", + "target": "c:objc(pl)NSObject", + "targetFallback": "ObjectiveC.NSObjectProtocol" + }, + { + "kind": "conformsTo", + "source": "c:@E@MyObjectiveCOption", + "target": "s:s9OptionSetP", + "targetFallback": "Swift.OptionSet" + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@objc(cs)MyClass", + "target": "s:SH", + "targetFallback": "Swift.Hashable" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework41CollisionsWithDifferentSubscriptArgumentsOyS2icip", + "target": "s:14MixedFramework41CollisionsWithDifferentSubscriptArgumentsO" + }, + { + "kind": "memberOf", + "source": "c:@M@MixedFramework@E@MyEnum@MyEnumFirstCase", + "target": "c:@M@MixedFramework@E@MyEnum" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework28CollisionsWithDifferentKindsO9somethingyA2CmF", + "target": "s:14MixedFramework28CollisionsWithDifferentKindsO" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework37CollisionsWithDifferentCapitalizationC9someThingSivp", + "target": "s:14MixedFramework37CollisionsWithDifferentCapitalizationC" + }, + { + "kind": "requirementOf", + "source": "s:14MixedFramework15MySwiftProtocolP02myE12TypeProperty0ce10AssociatedG0QzvpZ", + "target": "s:14MixedFramework15MySwiftProtocolP" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework020MyClassThatConformToC13OtherProtocolC0cI14AssociatedTypea", + "target": "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol", + "sourceOrigin": { + "identifier": "s:14MixedFramework15MySwiftProtocolP0cE14AssociatedTypeQa", + "displayName": "MySwiftProtocol.MyProtocolAssociatedType" + } + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework40CollisionsWithDifferentFunctionArgumentsO9something8argumentSiSS_tF", + "target": "s:14MixedFramework40CollisionsWithDifferentFunctionArgumentsO" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework28CollisionsWithDifferentKindsO9somethingSSvp", + "target": "s:14MixedFramework28CollisionsWithDifferentKindsO" + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol", + "target": "s:SQ", + "targetFallback": "Swift.Equatable" + }, + { + "kind": "conformsTo", + "source": "c:@E@MyObjectiveCEnumObjectiveCName", + "target": "s:s8SendableP", + "targetFallback": "Swift.Sendable" + }, + { + "kind": "memberOf", + "source": "s:s20_SwiftNewtypeWrapperPsSHRzSH8RawValueSYRpzrlE04hashE0Sivp::SYNTHESIZED::c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum", + "target": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum", + "sourceOrigin": { + "identifier": "s:s20_SwiftNewtypeWrapperPsSHRzSH8RawValueSYRpzrlE04hashE0Sivp", + "displayName": "_SwiftNewtypeWrapper.hashValue" + } + }, + { + "kind": "memberOf", + "source": "s:s10SetAlgebraPsE10isDisjoint4withSbx_tF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "target": "c:@E@MyObjectiveCOption", + "sourceOrigin": { + "identifier": "s:s10SetAlgebraPsE10isDisjoint4withSbx_tF", + "displayName": "SetAlgebra.isDisjoint(with:)" + } + }, + { + "kind": "memberOf", + "source": "s:So21MyTypedObjectiveCEnuma8rawValueABSi_tcfc", + "target": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum" + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@E@MyEnum", + "target": "s:SY", + "targetFallback": "Swift.RawRepresentable" + }, + { + "kind": "conformsTo", + "source": "c:@E@MyObjectiveCEnum", + "target": "s:s8SendableP", + "targetFallback": "Swift.Sendable" + }, + { + "kind": "memberOf", + "source": "s:s20_SwiftNewtypeWrapperPsSHRzSH8RawValueSYRpzrlE04hashE0Sivp::SYNTHESIZED::c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum", + "target": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum", + "sourceOrigin": { + "identifier": "s:s20_SwiftNewtypeWrapperPsSHRzSH8RawValueSYRpzrlE04hashE0Sivp", + "displayName": "_SwiftNewtypeWrapper.hashValue" + } + }, + { + "kind": "conformsTo", + "source": "c:@E@MyObjectiveCEnum", + "target": "s:SH", + "targetFallback": "Swift.Hashable" + }, + { + "kind": "conformsTo", + "source": "c:@E@MyObjectiveCOption", + "target": "s:s10SetAlgebraP", + "targetFallback": "Swift.SetAlgebra" + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol", + "target": "s:14MixedFramework15MySwiftProtocolP" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework41CollisionsWithDifferentSubscriptArgumentsOySiSScip", + "target": "s:14MixedFramework41CollisionsWithDifferentSubscriptArgumentsO" + }, + { + "kind": "conformsTo", + "source": "c:@E@MyObjectiveCEnumObjectiveCName", + "target": "s:SH", + "targetFallback": "Swift.Hashable" + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol", + "target": "c:objc(pl)NSObject", + "targetFallback": "ObjectiveC.NSObjectProtocol" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework15MySwiftProtocolP0cE9TypeAliasa", + "target": "s:14MixedFramework15MySwiftProtocolP" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework8MyStructV02myD8FunctionyyF", + "target": "s:14MixedFramework8MyStructV" + }, + { + "kind": "memberOf", + "source": "s:s9OptionSetPsE19symmetricDifferenceyxxF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "target": "c:@E@MyObjectiveCOption", + "sourceOrigin": { + "identifier": "s:s9OptionSetPsE19symmetricDifferenceyxxF", + "displayName": "OptionSet.symmetricDifference(_:)" + } + }, + { + "kind": "memberOf", + "source": "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName(py)myPropertyObjectiveCName", + "target": "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName" + }, + { + "kind": "memberOf", + "source": "s:So18MyObjectiveCOptionV8rawValueABSi_tcfc", + "target": "c:@E@MyObjectiveCOption" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework020MyClassThatConformToC13OtherProtocolC02myI12TypePropertyAA0C6StructVvpZ", + "target": "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol", + "sourceOrigin": { + "identifier": "s:14MixedFramework15MySwiftProtocolP02myE12TypeProperty0ce10AssociatedG0QzvpZ", + "displayName": "MySwiftProtocol.myProtocolTypeProperty" + } + }, + { + "kind": "memberOf", + "source": "c:@E@MyObjectiveCEnum@MyObjectiveCEnumSecond", + "target": "c:@E@MyObjectiveCEnum" + }, + { + "kind": "conformsTo", + "source": "c:@E@MyObjectiveCEnum", + "target": "s:SQ", + "targetFallback": "Swift.Equatable" + }, + { + "kind": "memberOf", + "source": "s:s9OptionSetPs7ElementQzRszrlE8containsySbxF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "target": "c:@E@MyObjectiveCOption", + "sourceOrigin": { + "identifier": "s:s9OptionSetPs7ElementQzRszrlE8containsySbxF", + "displayName": "OptionSet.contains(_:)" + } + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework29CollisionsWithEscapedKeywordsC4inityyF", + "target": "s:14MixedFramework29CollisionsWithEscapedKeywordsC" + }, + { + "kind": "memberOf", + "source": "s:s10SetAlgebraPsE11subtractingyxxF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "target": "c:@E@MyObjectiveCOption", + "sourceOrigin": { + "identifier": "s:s10SetAlgebraPsE11subtractingyxxF", + "displayName": "SetAlgebra.subtracting(_:)" + } + }, + { + "kind": "conformsTo", + "source": "c:@E@MyObjectiveCEnumObjectiveCName", + "target": "s:SQ", + "targetFallback": "Swift.Equatable" + }, + { + "kind": "memberOf", + "source": "s:SYsSHRzSH8RawValueSYRpzrlE04hashB0Sivp::SYNTHESIZED::c:@E@MyObjectiveCEnum", + "target": "c:@E@MyObjectiveCEnum", + "sourceOrigin": { + "identifier": "s:SYsSHRzSH8RawValueSYRpzrlE04hashB0Sivp", + "displayName": "RawRepresentable.hashValue" + } + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework29CollisionsWithEscapedKeywordsC4inityyFZ", + "target": "s:14MixedFramework29CollisionsWithEscapedKeywordsC" + }, + { + "kind": "memberOf", + "source": "c:@E@MyObjectiveCOption@MyObjectiveCOptionSecond", + "target": "c:@E@MyObjectiveCOption" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework28CollisionsWithDifferentKindsO9Somethinga", + "target": "s:14MixedFramework28CollisionsWithDifferentKindsO" + }, + { + "kind": "memberOf", + "source": "c:@E@MyObjectiveCEnumObjectiveCName@MyObjectiveCEnumObjectiveCNameSecond", + "target": "c:@E@MyObjectiveCEnumObjectiveCName" + }, + { + "kind": "requirementOf", + "source": "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(py)myProtocolProperty", + "target": "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol" + }, + { + "kind": "memberOf", + "source": "s:SYsSHRzSH8RawValueSYRpzrlE04hashB0Sivp::SYNTHESIZED::c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum", + "target": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum", + "sourceOrigin": { + "identifier": "s:SYsSHRzSH8RawValueSYRpzrlE04hashB0Sivp", + "displayName": "RawRepresentable.hashValue" + } + }, + { + "kind": "conformsTo", + "source": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum", + "target": "s:SY", + "targetFallback": "Swift.RawRepresentable" + }, + { + "kind": "memberOf", + "source": "s:SYsSHRzSH8RawValueSYRpzrlE04hashB0Sivp::SYNTHESIZED::c:@E@MyObjectiveCEnumObjectiveCName", + "target": "c:@E@MyObjectiveCEnumObjectiveCName", + "sourceOrigin": { + "identifier": "s:SYsSHRzSH8RawValueSYRpzrlE04hashB0Sivp", + "displayName": "RawRepresentable.hashValue" + } + }, + { + "kind": "memberOf", + "source": "s:SYsSHRzSH8RawValueSYRpzrlE04hashB0Sivp::SYNTHESIZED::c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum", + "target": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum", + "sourceOrigin": { + "identifier": "s:SYsSHRzSH8RawValueSYRpzrlE04hashB0Sivp", + "displayName": "RawRepresentable.hashValue" + } + }, + { + "kind": "memberOf", + "source": "s:SYsSHRzSH8RawValueSYRpzrlE04hashB0Sivp::SYNTHESIZED::c:@M@MixedFramework@E@MyEnum", + "target": "c:@M@MixedFramework@E@MyEnum", + "sourceOrigin": { + "identifier": "s:SYsSHRzSH8RawValueSYRpzrlE04hashB0Sivp", + "displayName": "RawRepresentable.hashValue" + } + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol", + "target": "s:SH", + "targetFallback": "Swift.Hashable" + }, + { + "kind": "inheritsFrom", + "source": "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName", + "target": "c:objc(cs)NSObject", + "targetFallback": "ObjectiveC.NSObject" + }, + { + "kind": "memberOf", + "source": "s:s10SetAlgebraPsE7isEmptySbvp::SYNTHESIZED::c:@E@MyObjectiveCOption", + "target": "c:@E@MyObjectiveCOption", + "sourceOrigin": { + "identifier": "s:s10SetAlgebraPsE7isEmptySbvp", + "displayName": "SetAlgebra.isEmpty" + } + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework29CollisionsWithEscapedKeywordsCACycfc", + "target": "s:14MixedFramework29CollisionsWithEscapedKeywordsC" + }, + { + "kind": "conformsTo", + "source": "c:@E@MyObjectiveCOption", + "target": "s:s8SendableP", + "targetFallback": "Swift.Sendable" + }, + { + "kind": "requirementOf", + "source": "s:14MixedFramework028MyOtherProtocolThatConformToc5SwiftE0P02mydE6MethodyyF", + "target": "s:14MixedFramework028MyOtherProtocolThatConformToc5SwiftE0P" + }, + { + "kind": "memberOf", + "source": "c:@MyTypedObjectiveCExtensibleEnumSecond", + "target": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum" + }, + { + "kind": "memberOf", + "source": "c:@MyTypedObjectiveCEnumSecond", + "target": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework6MyEnumO8rawValueACSgSi_tcfc", + "target": "c:@M@MixedFramework@E@MyEnum", + "sourceOrigin": { + "identifier": "s:SY8rawValuexSg03RawB0Qz_tcfc", + "displayName": "RawRepresentable.init(rawValue:)" + } + }, + { + "kind": "memberOf", + "source": "s:s20_SwiftNewtypeWrapperPsSHRzSH8RawValueSYRpzrlE4hash4intoys6HasherVz_tF::SYNTHESIZED::c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum", + "target": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum", + "sourceOrigin": { + "identifier": "s:s20_SwiftNewtypeWrapperPsSHRzSH8RawValueSYRpzrlE4hash4intoys6HasherVz_tF", + "displayName": "_SwiftNewtypeWrapper.hash(into:)" + } + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol", + "target": "s:s23CustomStringConvertibleP", + "targetFallback": "Swift.CustomStringConvertible" + }, + { + "kind": "memberOf", + "source": "s:SQsE2neoiySbx_xtFZ::SYNTHESIZED::c:@E@MyObjectiveCEnum", + "target": "c:@E@MyObjectiveCEnum", + "sourceOrigin": { + "identifier": "s:SQsE2neoiySbx_xtFZ", + "displayName": "Equatable.!=(_:_:)" + } + }, + { + "kind": "memberOf", + "source": "s:s20_SwiftNewtypeWrapperPsSHRzSH8RawValueSYRpzrlE4hash4intoys6HasherVz_tF::SYNTHESIZED::c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum", + "target": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum", + "sourceOrigin": { + "identifier": "s:s20_SwiftNewtypeWrapperPsSHRzSH8RawValueSYRpzrlE4hash4intoys6HasherVz_tF", + "displayName": "_SwiftNewtypeWrapper.hash(into:)" + } + }, + { + "kind": "conformsTo", + "source": "c:objc(cs)MyObjectiveCClassObjectiveCName", + "target": "s:s7CVarArgP", + "targetFallback": "Swift.CVarArg" + }, + { + "kind": "memberOf", + "source": "s:SQsE2neoiySbx_xtFZ::SYNTHESIZED::c:@E@MyObjectiveCOption", + "target": "c:@E@MyObjectiveCOption", + "sourceOrigin": { + "identifier": "s:SQsE2neoiySbx_xtFZ", + "displayName": "Equatable.!=(_:_:)" + } + }, + { + "kind": "memberOf", + "source": "s:SQsE2neoiySbx_xtFZ::SYNTHESIZED::c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum", + "target": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum", + "sourceOrigin": { + "identifier": "s:SQsE2neoiySbx_xtFZ", + "displayName": "Equatable.!=(_:_:)" + } + }, + { + "kind": "inheritsFrom", + "source": "c:@M@MixedFramework@objc(cs)MyClass", + "target": "c:objc(cs)NSObject", + "targetFallback": "ObjectiveC.NSObject" + }, + { + "kind": "memberOf", + "source": "s:SQsE2neoiySbx_xtFZ::SYNTHESIZED::c:@E@MyObjectiveCEnumObjectiveCName", + "target": "c:@E@MyObjectiveCEnumObjectiveCName", + "sourceOrigin": { + "identifier": "s:SQsE2neoiySbx_xtFZ", + "displayName": "Equatable.!=(_:_:)" + } + }, + { + "kind": "memberOf", + "source": "s:SQsE2neoiySbx_xtFZ::SYNTHESIZED::c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum", + "target": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum", + "sourceOrigin": { + "identifier": "s:SQsE2neoiySbx_xtFZ", + "displayName": "Equatable.!=(_:_:)" + } + }, + { + "kind": "memberOf", + "source": "c:@MyTypedObjectiveCEnumFirst", + "target": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum" + }, + { + "kind": "memberOf", + "source": "s:SQsE2neoiySbx_xtFZ::SYNTHESIZED::c:@M@MixedFramework@E@MyEnum", + "target": "c:@M@MixedFramework@E@MyEnum", + "sourceOrigin": { + "identifier": "s:SQsE2neoiySbx_xtFZ", + "displayName": "Equatable.!=(_:_:)" + } + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@objc(cs)MySwiftClassObjectiveCName", + "target": "s:s7CVarArgP", + "targetFallback": "Swift.CVarArg" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework8MyStructV02myD8PropertySivp", + "target": "s:14MixedFramework8MyStructV" + }, + { + "kind": "memberOf", + "source": "s:SQsE2neoiySbx_xtFZ::SYNTHESIZED::s:14MixedFramework28CollisionsWithDifferentKindsO", + "target": "s:14MixedFramework28CollisionsWithDifferentKindsO", + "sourceOrigin": { + "identifier": "s:SQsE2neoiySbx_xtFZ", + "displayName": "Equatable.!=(_:_:)" + } + }, + { + "kind": "requirementOf", + "source": "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol(cpy)myProtocolTypeProperty", + "target": "c:@M@MixedFramework@objc(pl)MyObjectiveCCompatibleProtocol" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework29CollisionsWithEscapedKeywordsC9subscriptyyF", + "target": "s:14MixedFramework29CollisionsWithEscapedKeywordsC" + }, + { + "kind": "memberOf", + "source": "c:@MyTypedObjectiveCExtensibleEnumFirst", + "target": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCExtensibleEnum" + }, + { + "kind": "conformsTo", + "source": "c:@E@MyObjectiveCOption", + "target": "s:SQ", + "targetFallback": "Swift.Equatable" + }, + { + "kind": "memberOf", + "source": "s:s9OptionSetPs7ElementQzRszrlE6insertySb8inserted_x17memberAfterInserttxF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "target": "c:@E@MyObjectiveCOption", + "sourceOrigin": { + "identifier": "s:s9OptionSetPs7ElementQzRszrlE6insertySb8inserted_x17memberAfterInserttxF", + "displayName": "OptionSet.insert(_:)" + } + }, + { + "kind": "memberOf", + "source": "s:s10SetAlgebraPsE16isStrictSuperset2ofSbx_tF::SYNTHESIZED::c:@E@MyObjectiveCOption", + "target": "c:@E@MyObjectiveCOption", + "sourceOrigin": { + "identifier": "s:s10SetAlgebraPsE16isStrictSuperset2ofSbx_tF", + "displayName": "SetAlgebra.isStrictSuperset(of:)" + } + }, + { + "kind": "memberOf", + "source": "c:@E@MyObjectiveCEnum@MyObjectiveCEnumFirst", + "target": "c:@E@MyObjectiveCEnum" + }, + { + "kind": "conformsTo", + "source": "s:14MixedFramework028MyOtherProtocolThatConformToc5SwiftE0P", + "target": "s:14MixedFramework15MySwiftProtocolP" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework8MyStructV0cD9TypeAliasa", + "target": "s:14MixedFramework8MyStructV" + }, + { + "kind": "inheritsFrom", + "source": "c:objc(cs)MyObjectiveCClassObjectiveCName", + "target": "c:objc(cs)NSObject", + "targetFallback": "ObjectiveC.NSObject" + }, + { + "kind": "memberOf", + "source": "c:@E@MyObjectiveCEnumObjectiveCName@MyObjectiveCEnumObjectiveCNameFirst", + "target": "c:@E@MyObjectiveCEnumObjectiveCName" + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol", + "target": "s:14MixedFramework028MyOtherProtocolThatConformToc5SwiftE0P" + }, + { + "kind": "conformsTo", + "source": "c:ObjectiveCDeclarations.h@T@MyTypedObjectiveCEnum", + "target": "s:SY", + "targetFallback": "Swift.RawRepresentable" + }, + { + "kind": "memberOf", + "source": "s:14MixedFramework29CollisionsWithEscapedKeywordsC9subscriptyyFZ", + "target": "s:14MixedFramework29CollisionsWithEscapedKeywordsC" + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@objc(cs)MyClass", + "target": "s:s7CVarArgP", + "targetFallback": "Swift.CVarArg" + }, + { + "kind": "conformsTo", + "source": "c:@M@MixedFramework@objc(cs)MyClassThatConformToMyOtherProtocol", + "target": "s:s28CustomDebugStringConvertibleP", + "targetFallback": "Swift.CustomDebugStringConvertible" + } + ] +} \ No newline at end of file diff --git a/bin/test b/bin/test index c890307978..700dcd9c5d 100755 --- a/bin/test +++ b/bin/test @@ -20,7 +20,8 @@ filepath() { DOCC_ROOT="$(dirname $(dirname $(filepath $0)))" # Build SwiftDocC. -swift test --parallel --package-path "$DOCC_ROOT" +DOCC_USE_HIERARCHY_BASED_LINK_RESOLVER=NO swift test --parallel --package-path "$DOCC_ROOT" +DOCC_USE_HIERARCHY_BASED_LINK_RESOLVER=YES swift test --parallel --package-path "$DOCC_ROOT" # Run source code checks for the codebase. LC_ALL=C "$DOCC_ROOT"/bin/check-source