Skip to content

Commit 7d3b096

Browse files
add support for the Doxygen \returns command
1 parent 9ddf78b commit 7d3b096

File tree

6 files changed

+111
-0
lines changed

6 files changed

+111
-0
lines changed

Sources/Markdown/Base/Markup.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ func makeMarkup(_ data: _MarkupData) -> Markup {
7373
return InlineAttributes(data)
7474
case .doxygenParam:
7575
return DoxygenParam(data)
76+
case .doxygenReturns:
77+
return DoxygenReturns(data)
7678
}
7779
}
7880

Sources/Markdown/Base/RawMarkup.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ enum RawMarkupData: Equatable {
5353
case tableCell(colspan: UInt, rowspan: UInt)
5454

5555
case doxygenParam(name: String)
56+
case doxygenReturns
5657
}
5758

5859
extension RawMarkupData {
@@ -336,6 +337,10 @@ final class RawMarkup: ManagedBuffer<RawMarkupHeader, RawMarkup> {
336337
static func doxygenParam(name: String, parsedRange: SourceRange?, _ children: [RawMarkup]) -> RawMarkup {
337338
return .create(data: .doxygenParam(name: name), parsedRange: parsedRange, children: children)
338339
}
340+
341+
static func doxygenReturns(parsedRange: SourceRange?, _ children: [RawMarkup]) -> RawMarkup {
342+
return .create(data: .doxygenReturns, parsedRange: parsedRange, children: children)
343+
}
339344
}
340345

341346
fileprivate extension Sequence where Element == RawMarkup {
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright (c) 2023 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See https://swift.org/LICENSE.txt for license information
8+
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import Foundation
12+
13+
/// A parsed Doxygen `\returns` command.
14+
///
15+
/// The Doxygen support in Swift-Markdown parses `\returns` commands of the form
16+
/// `\returns description`, where `description` continues until the next blank line or parsed
17+
/// command. The commands `\return` and `\result` are also accepted, with the same format.
18+
///
19+
/// ```markdown
20+
/// \returns A freshly-created object.
21+
/// ```
22+
public struct DoxygenReturns: BlockContainer {
23+
public var _data: _MarkupData
24+
25+
init(_ raw: RawMarkup) throws {
26+
guard case .doxygenParam = raw.data else {
27+
throw RawMarkup.Error.concreteConversionError(from: raw, to: BlockDirective.self)
28+
}
29+
let absoluteRaw = AbsoluteRawMarkup(markup: raw, metadata: MarkupMetadata(id: .newRoot(), indexInParent: 0))
30+
self.init(_MarkupData(absoluteRaw))
31+
}
32+
33+
init(_ data: _MarkupData) {
34+
self._data = data
35+
}
36+
37+
public func accept<V: MarkupVisitor>(_ visitor: inout V) -> V.Result {
38+
return visitor.visitDoxygenReturns(self)
39+
}
40+
}
41+
42+
public extension DoxygenReturns {
43+
/// Create a new Doxygen parameter definition.
44+
///
45+
/// - Parameter name: The name of the parameter being described.
46+
/// - Parameter children: Block child elements.
47+
init<Children: Sequence>(children: Children) where Children.Element == BlockMarkup {
48+
try! self.init(.doxygenReturns(parsedRange: nil, children.map({ $0.raw.markup })))
49+
}
50+
51+
/// Create a new Doxygen parameter definition.
52+
///
53+
/// - Parameter name: The name of the parameter being described.
54+
/// - Parameter children: Block child elements.
55+
init(children: BlockMarkup...) {
56+
self.init(children: children)
57+
}
58+
}

Sources/Markdown/Parser/BlockDirectiveParser.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,11 +226,14 @@ struct PendingBlockDirective {
226226
struct PendingDoxygenCommand {
227227
enum CommandKind {
228228
case param(name: Substring)
229+
case returns
229230

230231
var debugDescription: String {
231232
switch self {
232233
case .param(name: let name):
233234
return "'param' Argument: '\(name)'"
235+
case .returns:
236+
return "'returns'"
234237
}
235238
}
236239
}
@@ -730,6 +733,8 @@ private enum ParseContainer: CustomStringConvertible {
730733
switch pendingDoxygenCommand.kind {
731734
case .param(let name):
732735
return [.doxygenParam(name: String(name), parsedRange: range, children)]
736+
case .returns:
737+
return [.doxygenReturns(parsedRange: range, children)]
733738
}
734739
}
735740
}
@@ -870,6 +875,14 @@ struct ParseContainerStack {
870875
endLocation: name.range!.upperBound)
871876
pendingCommand.addLine(remainder)
872877
return (pendingCommand, remainder)
878+
case "return", "returns", "result":
879+
var pendingCommand = PendingDoxygenCommand(
880+
atLocation: at.range!.lowerBound,
881+
nameLocation: name.range!.lowerBound,
882+
kind: .returns,
883+
endLocation: name.range!.upperBound)
884+
pendingCommand.addLine(remainder)
885+
return (pendingCommand, remainder)
873886
default:
874887
return nil
875888
}

Sources/Markdown/Visitor/MarkupVisitor.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,14 @@ public protocol MarkupVisitor {
282282
- returns: The result of the visit.
283283
*/
284284
mutating func visitDoxygenParam(_ doxygenParam: DoxygenParam) -> Result
285+
286+
/**
287+
Visit a `DoxygenReturns` element and return the result.
288+
289+
- parameter doxygenReturns: A `DoxygenReturns` element.
290+
- returns: The result of the visit.
291+
*/
292+
mutating func visitDoxygenReturns(_ doxygenReturns: DoxygenReturns) -> Result
285293
}
286294

287295
extension MarkupVisitor {
@@ -384,4 +392,7 @@ extension MarkupVisitor {
384392
public mutating func visitDoxygenParam(_ doxygenParam: DoxygenParam) -> Result {
385393
return defaultVisit(doxygenParam)
386394
}
395+
public mutating func visitDoxygenReturns(_ doxygenReturns: DoxygenReturns) -> Result {
396+
return defaultVisit(doxygenReturns)
397+
}
387398
}

Tests/MarkdownTests/Parsing/DoxygenCommandParserTests.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,28 @@ class DoxygenCommandParserTests: XCTestCase {
3232
XCTAssertEqual(document.debugDescription(), expectedDump)
3333
}
3434

35+
func testParseReturns() {
36+
func assertValidParse(source: String) {
37+
let document = Document(parsing: source, options: parseOptions)
38+
XCTAssert(document.child(at: 0) is DoxygenReturns)
39+
40+
let expectedDump = """
41+
Document
42+
└─ DoxygenReturns
43+
└─ Paragraph
44+
└─ Text "The thing."
45+
"""
46+
XCTAssertEqual(document.debugDescription(), expectedDump)
47+
}
48+
49+
assertValidParse(source: "@returns The thing.")
50+
assertValidParse(source: "@return The thing.")
51+
assertValidParse(source: "@result The thing.")
52+
assertValidParse(source: #"\returns The thing."#)
53+
assertValidParse(source: #"\return The thing."#)
54+
assertValidParse(source: #"\result The thing."#)
55+
}
56+
3557
func testParseParamWithSlash() throws {
3658
let source = #"""
3759
\param thing The thing.

0 commit comments

Comments
 (0)