Skip to content

Commit 72020de

Browse files
add experimental Doxygen support (#497)
rdar://105848459
1 parent c66e840 commit 72020de

File tree

11 files changed

+144
-6
lines changed

11 files changed

+144
-6
lines changed

Package.resolved

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Sources/SwiftDocC/Model/DocumentationNode.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,12 @@ public struct DocumentationNode {
422422
]
423423
} else if let symbol = documentedSymbol, let docComment = symbol.docComment {
424424
let docCommentString = docComment.lines.map { $0.text }.joined(separator: "\n")
425-
let docCommentMarkup = Document(parsing: docCommentString, options: [.parseBlockDirectives, .parseSymbolLinks])
425+
426+
var documentOptions: ParseOptions = [.parseBlockDirectives, .parseSymbolLinks]
427+
if FeatureFlags.current.isExperimentalDoxygenSupportEnabled {
428+
documentOptions.insert(.parseMinimalDoxygen)
429+
}
430+
let docCommentMarkup = Document(parsing: docCommentString, options: documentOptions)
426431

427432
let docCommentDirectives = docCommentMarkup.children.compactMap({ $0 as? BlockDirective })
428433
if !docCommentDirectives.isEmpty {

Sources/SwiftDocC/Model/Semantics/Parameter.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,12 @@ public struct Parameter {
2525
self.name = name
2626
self.contents = contents
2727
}
28+
29+
/// Initialize a value to describe documentation about a symbol's parameter via a Doxygen `\param` command.
30+
///
31+
/// - Parameter doxygenParameter: A parsed Doxygen `\param` command.
32+
public init(_ doxygenParameter: DoxygenParameter) {
33+
self.name = doxygenParameter.name
34+
self.contents = Array(doxygenParameter.children)
35+
}
2836
}

Sources/SwiftDocC/Model/Semantics/Return.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,11 @@ public struct Return {
2020
public init(contents: [Markup]) {
2121
self.contents = contents
2222
}
23+
24+
/// Initialize a value to describe documentation about a symbol's return value.
25+
///
26+
/// - Parameter doxygenReturns: A parsed Doxygen `\returns` command.
27+
public init(_ doxygenReturns: DoxygenReturns) {
28+
self.contents = Array(doxygenReturns.children)
29+
}
2330
}

Sources/SwiftDocC/Utility/FeatureFlags.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ public struct FeatureFlags: Codable {
3030

3131
/// Whether or not experimental support for device frames on images and video is enabled.
3232
public var isExperimentalDeviceFrameSupportEnabled = false
33+
34+
/// Whether or not experimental support for parsing Doxygen commands is enabled.
35+
public var isExperimentalDoxygenSupportEnabled = false
3336

3437
/// Creates a set of feature flags with the given values.
3538
///

Sources/SwiftDocC/Utility/MarkupExtensions/ListItemExtractor.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,4 +407,14 @@ struct TaggedListItemExtractor: MarkupRewriter {
407407
// No match; leave this list item alone.
408408
return listItem
409409
}
410+
411+
mutating func visitDoxygenParameter(_ doxygenParam: DoxygenParameter) -> Markup? {
412+
parameters.append(Parameter(doxygenParam))
413+
return nil
414+
}
415+
416+
mutating func visitDoxygenReturns(_ doxygenReturns: DoxygenReturns) -> Markup? {
417+
returns.append(Return(doxygenReturns))
418+
return nil
419+
}
410420
}

Sources/SwiftDocCUtilities/ArgumentParsing/ActionExtensions/ConvertAction+CommandInitialization.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ extension ConvertAction {
2121
let outOfProcessResolver: OutOfProcessReferenceResolver?
2222

2323
FeatureFlags.current.isExperimentalDeviceFrameSupportEnabled = convert.enableExperimentalDeviceFrameSupport
24+
FeatureFlags.current.isExperimentalDoxygenSupportEnabled = convert.experimentalParseDoxygenCommands
2425

2526
// If the user-provided a URL for an external link resolver, attempt to
2627
// initialize an `OutOfProcessReferenceResolver` with the provided URL.

Sources/SwiftDocCUtilities/ArgumentParsing/Subcommands/Convert.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,12 @@ extension Docc {
167167
@OptionGroup()
168168
public var sourceRepositoryArguments: SourceRepositoryArguments
169169

170+
/// A user-provided value that is true if experimental Doxygen support should be enabled.
171+
///
172+
/// Defaults to false.
173+
@Flag(help: .hidden)
174+
public var experimentalParseDoxygenCommands = false
175+
170176
// MARK: - Info.plist fallbacks
171177

172178
/// A user-provided fallback display name for the documentation bundle.

Tests/SwiftDocCTests/Semantics/SymbolTests.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,31 @@ class SymbolTests: XCTestCase {
514514
XCTAssertEqual(problems.count, 0)
515515
}
516516

517+
func testParseDoxygenWithFeatureFlag() throws {
518+
enableFeatureFlag(\.isExperimentalDoxygenSupportEnabled)
519+
520+
let deckKitSymbolGraph = Bundle.module.url(
521+
forResource: "DeckKit-Objective-C",
522+
withExtension: "symbols.json",
523+
subdirectory: "Test Resources"
524+
)!
525+
let (_, _, context) = try testBundleAndContext(copying: "TestBundle") { url in
526+
try? FileManager.default.copyItem(at: deckKitSymbolGraph, to: url.appendingPathComponent("DeckKit.symbols.json"))
527+
}
528+
let symbol = try XCTUnwrap(context.symbolIndex["c:objc(cs)PlayingCard(cm)newWithRank:ofSuit:"]?.semantic as? Symbol)
529+
530+
XCTAssertEqual(symbol.abstract?.format(), "Allocate and initialize a new card with the given rank and suit.")
531+
532+
XCTAssertEqual(symbol.parametersSection?.parameters.count, 2)
533+
534+
let rankParameter = try XCTUnwrap(symbol.parametersSection?.parameters.first(where:{$0.name == "rank"}))
535+
XCTAssertEqual(rankParameter.contents.map({$0.format()}), ["The rank of the card."])
536+
let suitParameter = try XCTUnwrap(symbol.parametersSection?.parameters.first(where:{$0.name == "suit"}))
537+
XCTAssertEqual(suitParameter.contents.map({$0.format()}), ["The suit of the card."])
538+
539+
XCTAssertEqual(symbol.returnsSection?.content.map({ $0.format() }), ["A new card with the given configuration."])
540+
}
541+
517542
func testUnresolvedReferenceWarningsInDocumentationExtension() throws {
518543
let (url, _, context) = try testBundleAndContext(copying: "TestBundle") { url in
519544
let myKitDocumentationExtensionComment = """

Tests/SwiftDocCTests/Test Resources/DeckKit-Objective-C.symbols.json

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1591,14 +1591,66 @@
15911591
"range" : {
15921592
"end" : {
15931593
"character" : 68,
1594-
"line" : 56
1594+
"line" : 46
15951595
},
15961596
"start" : {
15971597
"character" : 4,
1598-
"line" : 56
1598+
"line" : 46
15991599
}
16001600
},
16011601
"text" : "Allocate and initialize a new card with the given rank and suit."
1602+
},
1603+
{
1604+
"range" : {
1605+
"end" : {
1606+
"character" : 3,
1607+
"line" : 47
1608+
},
1609+
"start" : {
1610+
"character" : 3,
1611+
"line" : 47
1612+
}
1613+
},
1614+
"text" : ""
1615+
},
1616+
{
1617+
"range" : {
1618+
"end" : {
1619+
"character" : 37,
1620+
"line" : 48
1621+
},
1622+
"start" : {
1623+
"character" : 4,
1624+
"line" : 48
1625+
}
1626+
},
1627+
"text" : "\\param rank The rank of the card."
1628+
},
1629+
{
1630+
"range" : {
1631+
"end" : {
1632+
"character" : 37,
1633+
"line" : 49
1634+
},
1635+
"start" : {
1636+
"character" : 4,
1637+
"line" : 49
1638+
}
1639+
},
1640+
"text" : "@param suit The suit of the card."
1641+
},
1642+
{
1643+
"range" : {
1644+
"end" : {
1645+
"character" : 54,
1646+
"line" : 50
1647+
},
1648+
"start" : {
1649+
"character" : 4,
1650+
"line" : 50
1651+
}
1652+
},
1653+
"text" : "\\returns A new card with the given configuration. "
16021654
}
16031655
]
16041656
},

Tests/SwiftDocCUtilitiesTests/ArgumentParsing/ConvertSubcommandTests.swift

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ class ConvertSubcommandTests: XCTestCase {
165165
]), "Did not refuse target folder path '\(path)'")
166166
}
167167
}
168-
168+
169169
func testAnalyzerIsTurnedOffByDefault() throws {
170170
setenv(TemplateOption.environmentVariableKey, testTemplateURL.path, 1)
171171
let convertOptions = try Docc.Convert.parse([
@@ -206,7 +206,7 @@ class ConvertSubcommandTests: XCTestCase {
206206
XCTAssertEqual(convertOptions.defaultCodeListingLanguage, "swift")
207207
}
208208

209-
// Are set when passed
209+
// Are set when passed
210210
do {
211211
let convertOptions = try Docc.Convert.parse([
212212
testBundleURL.path,
@@ -390,6 +390,27 @@ class ConvertSubcommandTests: XCTestCase {
390390
XCTAssertTrue(commandWithFlag.enableExperimentalDeviceFrameSupport)
391391
XCTAssertTrue(FeatureFlags.current.isExperimentalDeviceFrameSupportEnabled)
392392
}
393+
394+
func testExperimentalParseDoxygenFlag() throws {
395+
let originalFeatureFlagsState = FeatureFlags.current
396+
397+
defer {
398+
FeatureFlags.current = originalFeatureFlagsState
399+
}
400+
401+
let commandWithoutFlag = try Docc.Convert.parse([testBundleURL.path])
402+
let _ = try ConvertAction(fromConvertCommand: commandWithoutFlag)
403+
XCTAssertFalse(commandWithoutFlag.experimentalParseDoxygenCommands)
404+
XCTAssertFalse(FeatureFlags.current.isExperimentalDoxygenSupportEnabled)
405+
406+
let commandWithFlag = try Docc.Convert.parse([
407+
"--experimental-parse-doxygen-commands",
408+
testBundleURL.path,
409+
])
410+
let _ = try ConvertAction(fromConvertCommand: commandWithFlag)
411+
XCTAssertTrue(commandWithFlag.experimentalParseDoxygenCommands)
412+
XCTAssertTrue(FeatureFlags.current.isExperimentalDoxygenSupportEnabled)
413+
}
393414

394415
func testTransformForStaticHostingFlagWithoutHTMLTemplate() throws {
395416
unsetenv(TemplateOption.environmentVariableKey)

0 commit comments

Comments
 (0)