Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accept more Objective-C symbol graph identifiers #110

Merged
merged 1 commit into from
Mar 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 24 additions & 7 deletions Sources/SwiftDocC/Model/SourceLanguage.swift
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -14,14 +14,18 @@ public struct SourceLanguage: Hashable, Codable {
public var name: String
/// A globally unique identifier for the language.
public var id: String
/// Aliases for the language's identifier.
public var idAliases: [String] = []

/// Creates a new language with a given name and identifier.
/// - Parameters:
/// - name: The display name of the programming language.
/// - id: A globally unique identifier for the language.
public init(name: String, id: String) {
/// - idAliases: Aliases for the language's identifier.
public init(name: String, id: String, idAliases: [String] = []) {
self.name = name
self.id = id
self.idAliases = idAliases
}

/// Finds the programming language that matches a given query identifier.
Expand All @@ -34,7 +38,7 @@ public struct SourceLanguage: Hashable, Codable {
switch queryID {
case "swift":
self = .swift
case "occ":
case "occ", "objective-c", "c":
self = .objectiveC
case "javascript":
self = .javaScript
Expand All @@ -52,7 +56,7 @@ public struct SourceLanguage: Hashable, Codable {
public init(id: String) {
switch id {
case "swift": self = .swift
case "occ": self = .objectiveC
case "occ", "objective-c", "c": self = .objectiveC
case "javascript": self = .javaScript
case "data": self = .data
case "metal": self = .metal
Expand Down Expand Up @@ -101,17 +105,30 @@ public struct SourceLanguage: Hashable, Codable {
}

private static func firstKnownLanguage(withName name: String) -> SourceLanguage? {
return SourceLanguage.knownLanguages.first { $0.name.lowercased() == name.lowercased() }
SourceLanguage.knownLanguages.first { $0.name.lowercased() == name.lowercased() }
}

private static func firstKnownLanguage(withIdentifier id: String) -> SourceLanguage? {
return SourceLanguage.knownLanguages.first { $0.id.lowercased() == id.lowercased() }
SourceLanguage.knownLanguages.first { knownLanguage in
([knownLanguage.id] + knownLanguage.idAliases)
.map { $0.lowercased() }
.contains(id)
}
}

/// The Swift programming language.
public static let swift = SourceLanguage(name: "Swift", id: "swift")

/// The Objective-C programming language.
public static let objectiveC = SourceLanguage(name: "Objective-C", id: "occ")
public static let objectiveC = SourceLanguage(
name: "Objective-C",
id: "occ",
idAliases: [
"objective-c",
"c", // FIXME: DocC should display C as its own language (SR-16050).
]
)

/// The JavaScript programming language or another language that conforms to the ECMAScript specification.
public static let javaScript = SourceLanguage(name: "JavaScript", id: "javascript")
/// Miscellaneous data, that's not a programming language.
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -23,7 +23,7 @@ extension DocumentationDataVariants {
guard selector.platform == platformName else { return nil }

return (
DocumentationDataVariantsTrait(interfaceLanguage: selector.interfaceLanguage),
DocumentationDataVariantsTrait(for: selector),
transform(value)
)
}
Expand All @@ -44,7 +44,7 @@ extension DocumentationDataVariants {
else { return nil }

return (
DocumentationDataVariantsTrait(interfaceLanguage: selector.interfaceLanguage),
DocumentationDataVariantsTrait(for: selector),
value
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
/*
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
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

import Foundation
import SymbolKit

/// A model type that encapsulates variants of documentation node data.
///
Expand Down Expand Up @@ -141,4 +142,14 @@ public struct DocumentationDataVariantsTrait: Hashable {
public init(interfaceLanguage: String? = nil) {
self.interfaceLanguage = interfaceLanguage
}

/// Creates a new trait given a symbol graph selector.
///
/// - Parameter selector: The symbol graph selector to use when creating the trait.
public init(for selector: UnifiedSymbolGraph.Selector) {
self.init(
interfaceLanguage: SourceLanguage(knownLanguageIdentifier: selector.interfaceLanguage)?.id
?? selector.interfaceLanguage
)
}
}
2 changes: 1 addition & 1 deletion Sources/SwiftDocC/Semantics/Symbol/Symbol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ extension Symbol {
/// depending on variances in their implementation across platforms (e.g. use `NSPoint` vs `CGPoint` parameter in a method).
/// This method finds matching symbols between graphs and merges their declarations in case there are differences.
func mergeDeclaration(mergingDeclaration: SymbolGraph.Symbol.DeclarationFragments, identifier: String, symbolAvailability: SymbolGraph.Symbol.Availability?, selector: UnifiedSymbolGraph.Selector) throws {
let trait = DocumentationDataVariantsTrait(interfaceLanguage: selector.interfaceLanguage)
let trait = DocumentationDataVariantsTrait(for: selector)
let platformName = selector.platform

if let platformName = platformName,
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -76,9 +76,26 @@ class SemaToRenderNodeMixedLanguageTests: XCTestCase {
)
}
}

func testOutputsMultiLanguageRenderNodes() throws {
let outputConsumer = try mixedLanguageFrameworkConsumer()

func assertOutputsMultiLanguageRenderNodes(variantInterfaceLanguage: String) throws {
let outputConsumer = try mixedLanguageFrameworkConsumer { bundleURL in
// Update the clang symbol graph with the Objective-C identifier given in variantInterfaceLanguage.

let clangSymbolGraphLocation = bundleURL
.appendingPathComponent("symbol-graphs")
.appendingPathComponent("clang")
.appendingPathComponent("MixedLanguageFramework.symbols.json")

var clangSymbolGraph = try JSONDecoder().decode(SymbolGraph.self, from: Data(contentsOf: clangSymbolGraphLocation))

clangSymbolGraph.symbols = clangSymbolGraph.symbols.mapValues { symbol in
var symbol = symbol
symbol.identifier.interfaceLanguage = variantInterfaceLanguage
return symbol
}

try JSONEncoder().encode(clangSymbolGraph).write(to: clangSymbolGraphLocation)
}

XCTAssertEqual(
Set(
Expand Down Expand Up @@ -136,7 +153,7 @@ class SemaToRenderNodeMixedLanguageTests: XCTestCase {
"c:@M@TestFramework@objc(pl)MixedLanguageProtocol(im)mixedLanguageMethod",
"c:@M@TestFramework@objc(cs)MixedLanguageClassConformingToProtocol(im)init",
"c:@CM@TestFramework@objc(cs)MixedLanguageClassConformingToProtocol(im)mixedLanguageMethod",

"MixedLanguageProtocol Implementations",
"Article",
"APICollection",
Expand All @@ -146,7 +163,19 @@ class SemaToRenderNodeMixedLanguageTests: XCTestCase {
]
)
}


func testOutputsMultiLanguageRenderNodesWithOccIdentifier() throws {
try assertOutputsMultiLanguageRenderNodes(variantInterfaceLanguage: "occ")
}

func testOutputsMultiLanguageRenderNodesWithObjectiveCIdentifier() throws {
try assertOutputsMultiLanguageRenderNodes(variantInterfaceLanguage: "objective-c")
}

func testOutputsMultiLanguageRenderNodesWithCIdentifier() throws {
try assertOutputsMultiLanguageRenderNodes(variantInterfaceLanguage: "c")
}

func testFrameworkRenderNodeHasExpectedContentAcrossLanguages() throws {
let outputConsumer = try mixedLanguageFrameworkConsumer()
let mixedLanguageFrameworkRenderNode = try outputConsumer.renderNode(
Expand Down
19 changes: 19 additions & 0 deletions Tests/SwiftDocCTests/Model/SourceLanguageTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
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
*/

@testable import SwiftDocC
import XCTest

class SourceLanguageTests: XCTestCase {
func testUsesIDAliasesWhenQueryingFirstKnownLanguage() {
XCTAssertEqual(SourceLanguage(knownLanguageIdentifier: "objective-c"), .objectiveC)
XCTAssertEqual(SourceLanguage(knownLanguageIdentifier: "c"), .objectiveC)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import Foundation
import XCTest
import SymbolKit
@testable import SwiftDocC

class DocumentationDataVariantsTests: XCTestCase {
Expand Down Expand Up @@ -84,4 +85,16 @@ class DocumentationDataVariantsTests: XCTestCase {
variants[objectiveCTrait] = "Objective-C"
XCTAssertEqual(variants.firstValue, "Swift") // Swift is still treated as the default value.
}

func testInitializesUsingSelectorLanguage() {
XCTAssertEqual(
DocumentationDataVariantsTrait(
for: UnifiedSymbolGraph.Selector(
interfaceLanguage: "MyLanguage",
platform: nil
)
).interfaceLanguage,
"MyLanguage"
)
}
}