diff --git a/bindings/xml/comment-xml-schema.rng b/bindings/xml/comment-xml-schema.rng
index 468efa04253..43300c7c3c3 100644
--- a/bindings/xml/comment-xml-schema.rng
+++ b/bindings/xml/comment-xml-schema.rng
@@ -650,9 +650,28 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/include/swift/AST/Comment.h b/include/swift/AST/Comment.h
index 6317ddea361..35c42e6aa02 100644
--- a/include/swift/AST/Comment.h
+++ b/include/swift/AST/Comment.h
@@ -22,34 +22,20 @@ class DocComment;
struct RawComment;
class DocComment {
-public:
- struct CommentParts {
- OptionalBrief;
- ArrayRef BodyNodes;
- ArrayRef ParamFields;
- Optional ReturnsField;
- Optional ThrowsField;
-
- bool isEmpty() const {
- return !Brief.hasValue() && !ReturnsField.hasValue() && !ThrowsField.hasValue() && BodyNodes.empty() && ParamFields.empty();
- }
- };
-
-private:
const Decl *D;
const swift::markup::Document *Doc = nullptr;
- const CommentParts Parts;
+ const swift::markup::CommentParts Parts;
public:
DocComment(const Decl *D, swift::markup::Document *Doc,
- CommentParts Parts)
+ swift::markup::CommentParts Parts)
: D(D), Doc(Doc), Parts(Parts) {}
const Decl *getDecl() const { return D; }
const swift::markup::Document *getDocument() const { return Doc; }
- CommentParts getParts() const {
+ swift::markup::CommentParts getParts() const {
return Parts;
}
diff --git a/include/swift/Markup/AST.h b/include/swift/Markup/AST.h
index fe60ddc2b4e..e8d0ae75640 100644
--- a/include/swift/Markup/AST.h
+++ b/include/swift/Markup/AST.h
@@ -22,6 +22,35 @@ namespace swift {
namespace markup {
class MarkupContext;
+class MarkupASTNode;
+class Paragraph;
+class ParamField;
+class ReturnsField;
+class ThrowsField;
+
+/// The basic structure of a doc comment attached to a Swift
+/// declaration.
+struct CommentParts {
+ Optional Brief;
+ ArrayRef BodyNodes;
+ ArrayRef ParamFields;
+ Optional ReturnsField;
+ Optional ThrowsField;
+
+ bool isEmpty() const {
+ return !Brief.hasValue() &&
+ !ReturnsField.hasValue() &&
+ !ThrowsField.hasValue() &&
+ BodyNodes.empty() &&
+ ParamFields.empty();
+ }
+
+ bool hasFunctionDocumentation() const {
+ return !ParamFields.empty() ||
+ ReturnsField.hasValue() ||
+ ThrowsField.hasValue();
+ }
+};
#define MARKUP_AST_NODE(Id, Parent) class Id;
#define ABSTRACT_MARKUP_AST_NODE(Id, Parent) class Id;
@@ -585,6 +614,10 @@ class ParamField final : public PrivateExtension,
StringRef Name;
+ // Parameter fields can contain a substructure describing a
+ // function or closure parameter.
+ llvm::Optional Parts;
+
ParamField(StringRef Name, ArrayRef Children);
public:
@@ -596,6 +629,21 @@ public:
return Name;
}
+ llvm::Optional getParts() const {
+ return Parts;
+ }
+
+ void setParts(CommentParts P) {
+ Parts = P;
+ }
+
+ bool isClosureParameter() const {
+ if (!Parts.hasValue())
+ return false;
+
+ return Parts.getValue().hasFunctionDocumentation();
+ }
+
ArrayRef getChildren() {
return {getTrailingObjects(), NumChildren};
}
diff --git a/lib/AST/DocComment.cpp b/lib/AST/DocComment.cpp
index d79c3c740a7..f3dc97f048a 100644
--- a/lib/AST/DocComment.cpp
+++ b/lib/AST/DocComment.cpp
@@ -70,7 +70,7 @@ Optional extractParamOutlineItem(
bool extractParameterOutline(
swift::markup::MarkupContext &MC, swift::markup::List *L,
- SmallVectorImpl &ParamFields) {
+ SmallVectorImpl &ParamFields) {
SmallVector NormalItems;
auto Children = L->getChildren();
if (Children.empty())
@@ -145,7 +145,7 @@ bool extractParameterOutline(
bool extractSeparatedParams(
swift::markup::MarkupContext &MC, swift::markup::List *L,
- SmallVectorImpl &ParamFields) {
+ SmallVectorImpl &ParamFields) {
SmallVector NormalItems;
auto Children = L->getChildren();
@@ -209,7 +209,7 @@ bool extractSeparatedParams(
bool extractSimpleField(
swift::markup::MarkupContext &MC, swift::markup::List *L,
- DocComment::CommentParts &Parts,
+ swift::markup::CommentParts &Parts,
SmallVectorImpl &BodyNodes) {
auto Children = L->getChildren();
SmallVector NormalItems;
@@ -274,11 +274,11 @@ bool extractSimpleField(
return NormalItems.size() == 0;
}
-static DocComment::CommentParts
+static swift::markup::CommentParts
extractCommentParts(swift::markup::MarkupContext &MC,
swift::markup::MarkupASTNode *Node) {
- DocComment::CommentParts Parts;
+ swift::markup::CommentParts Parts;
auto Children = Node->getChildren();
if (Children.empty())
return Parts;
@@ -289,7 +289,7 @@ extractCommentParts(swift::markup::MarkupContext &MC,
Parts.Brief = FirstParagraph;
SmallVector BodyNodes;
- SmallVector ParamFields;
+ SmallVector ParamFields;
// Look for special top-level lists
size_t StartOffset = FirstParagraph == nullptr ? 0 : 1;
@@ -317,6 +317,11 @@ extractCommentParts(swift::markup::MarkupContext &MC,
Parts.BodyNodes = MC.allocateCopy(llvm::makeArrayRef(BodyNodes));
Parts.ParamFields = MC.allocateCopy(llvm::makeArrayRef(ParamFields));
+ for (auto Param : Parts.ParamFields) {
+ auto ParamParts = extractCommentParts(MC, Param);
+ Param->setParts(ParamParts);
+ }
+
return Parts;
}
diff --git a/lib/IDE/CommentConversion.cpp b/lib/IDE/CommentConversion.cpp
index 6ff845f6425..36135666e20 100644
--- a/lib/IDE/CommentConversion.cpp
+++ b/lib/IDE/CommentConversion.cpp
@@ -211,13 +211,24 @@ struct CommentToXMLConverter {
}
void printParamField(const ParamField *PF) {
- OS << "";
+ OS << "";
+ OS << "";
OS << PF->getName();
- OS << "in";
- for (auto Child : PF->getChildren())
- printASTNode(Child);
+ OS << "";
+ OS << "in";
- OS << "";
+ if (PF->isClosureParameter()) {
+ OS << "";
+ visitCommentParts(PF->getParts().getValue());
+ OS << "";
+ } else {
+ OS << "";
+ for (auto Child : PF->getChildren()) {
+ printASTNode(Child);
+ }
+ OS << "";
+ }
+ OS << "";
}
void printResultDiscussion(const ReturnsField *RF) {
@@ -235,9 +246,40 @@ struct CommentToXMLConverter {
}
void visitDocComment(const DocComment *DC);
+ void visitCommentParts(const swift::markup::CommentParts &Parts);
};
} // unnamed namespace
+void CommentToXMLConverter::visitCommentParts(const swift::markup::CommentParts &Parts) {
+ if (Parts.Brief.hasValue()) {
+ OS << "";
+ printASTNode(Parts.Brief.getValue());
+ OS << "";
+ }
+
+ if (!Parts.ParamFields.empty()) {
+ OS << "";
+ for (const auto *PF : Parts.ParamFields)
+ printParamField(PF);
+
+ OS << "";
+ }
+
+ if (Parts.ReturnsField.hasValue())
+ printResultDiscussion(Parts.ReturnsField.getValue());
+
+ if (Parts.ThrowsField.hasValue())
+ printThrowsDiscussion(Parts.ThrowsField.getValue());
+
+ if (!Parts.BodyNodes.empty()) {
+ OS << "";
+ for (const auto *N : Parts.BodyNodes)
+ printASTNode(N);
+
+ OS << "";
+ }
+}
+
void CommentToXMLConverter::visitDocComment(const DocComment *DC) {
const Decl *D = DC->getDecl();
@@ -313,36 +355,7 @@ void CommentToXMLConverter::visitDocComment(const DocComment *DC) {
OS << "";
}
- auto Brief = DC->getBrief();
- if (Brief.hasValue()) {
- OS << "";
- printASTNode(Brief.getValue());
- OS << "";
- }
-
- if (!DC->getParamFields().empty()) {
- OS << "";
- for (const auto *PF : DC->getParamFields())
- printParamField(PF);
-
- OS << "";
- }
-
- auto RF = DC->getReturnsField();
- if (RF.hasValue())
- printResultDiscussion(RF.getValue());
-
- auto TF = DC->getThrowsField();
- if (TF.hasValue())
- printThrowsDiscussion(TF.getValue());
-
- if (!DC->getBodyNodes().empty()) {
- OS << "";
- for (const auto *N : DC->getBodyNodes())
- printASTNode(N);
-
- OS << "";
- }
+ visitCommentParts(DC->getParts());
OS << RootEndTag;
}
diff --git a/lib/Markup/AST.cpp b/lib/Markup/AST.cpp
index 406fa36bd00..72b78271b0b 100644
--- a/lib/Markup/AST.cpp
+++ b/lib/Markup/AST.cpp
@@ -205,7 +205,8 @@ Strong *Strong::create(MarkupContext &MC,
ParamField::ParamField(StringRef Name, ArrayRef Children)
: PrivateExtension(ASTNodeKind::ParamField), NumChildren(Children.size()),
- Name(Name) {
+ Name(Name),
+ Parts(None) {
std::uninitialized_copy(Children.begin(), Children.end(),
getTrailingObjects());
}
diff --git a/test/Inputs/comment_to_something_conversion.swift b/test/Inputs/comment_to_something_conversion.swift
index c93b3a03541..e5663b6da15 100644
--- a/test/Inputs/comment_to_something_conversion.swift
+++ b/test/Inputs/comment_to_something_conversion.swift
@@ -422,3 +422,39 @@ public func codeListingWithDefaultLanguage() {}
/// ```
public func codeListingWithOtherLanguage() {}
// CHECK: DocCommentAsXML=[codeListingWithOtherLanguage()s:F14swift_ide_test28codeListingWithOtherLanguageFT_T_public func codeListingWithOtherLanguage()Brief.]
+
+/// Partially applies a binary operator.
+///
+/// - Parameter a: The left-hand side to partially apply.
+/// - Parameter combine: A binary operator.
+/// - Parameter lhs: The left-hand side of the operator
+/// - Parameter rhs: The right-hand side of the operator
+/// - Returns: A result.
+/// - Throws: Nothing.
+public func closureParameterExplodedExploded(a: T, combine: (lhs: T, rhs: T) -> T) {}
+// CHECK: DocCommentAsXML=[closureParameterExplodedExploded(a:combine:)s:F14swift_ide_test32closureParameterExplodedExplodedurFT1ax7combineFT3lhsx3rhsx_x_T_public func closureParameterExplodedExploded<T>(a: T, combine: (lhs: T, rhs: T) -> T)Partially applies a binary operator.ainThe left-hand side to partially apply.combineinA binary operator.lhsinThe left-hand side of the operatorrhsinThe right-hand side of the operatorA result.Nothing.] CommentXMLValid
+
+/// Partially applies a binary operator.
+///
+/// - Parameters:
+/// - a: The left-hand side to partially apply.
+/// - combine: A binary operator.
+/// - Parameter lhs: The left-hand side of the operator
+/// - Parameter rhs: The right-hand side of the operator
+/// - Returns: A result.
+/// - Throws: Nothing.
+public func closureParameterOutlineExploded(a: T, combine: (lhs: T, rhs: T) -> T) {}
+// CHECK: DocCommentAsXML=[closureParameterOutlineExploded(a:combine:)s:F14swift_ide_test31closureParameterOutlineExplodedurFT1ax7combineFT3lhsx3rhsx_x_T_public func closureParameterOutlineExploded<T>(a: T, combine: (lhs: T, rhs: T) -> T)Partially applies a binary operator.ainThe left-hand side to partially apply.combineinA binary operator.lhsinThe left-hand side of the operatorrhsinThe right-hand side of the operatorA result.Nothing.] CommentXMLValid
+
+/// Partially applies a binary operator.
+///
+/// - Parameters:
+/// - a: The left-hand side to partially apply.
+/// - combine: A binary operator.
+/// - Parameters:
+/// - lhs: The left-hand side of the operator
+/// - rhs: The right-hand side of the operator
+/// - Returns: A result.
+/// - Throws: Nothing.
+public func closureParameterOutlineOutline(a: T, combine: (lhs: T, rhs: T) -> T) {}
+// CHECK: {{.*}}DocCommentAsXML=[closureParameterOutlineOutline(a:combine:)s:F14swift_ide_test30closureParameterOutlineOutlineurFT1ax7combineFT3lhsx3rhsx_x_T_public func closureParameterOutlineOutline<T>(a: T, combine: (lhs: T, rhs: T) -> T)Partially applies a binary operator.ainThe left-hand side to partially apply.combineinA binary operator.lhsinThe left-hand side of the operatorrhsinThe right-hand side of the operatorA result.Nothing.]