[IDE][SourceKit/DocSupport] Add members of underscored protocol extensions in extensions of conforming types.

We would previously hide the protocol, its extensions and members, but the '_'
prefix really just means the protocol itself isn't intended for clients, rather
than its members.

This also adds support for 'fully_annotated_decl' entries in doc-info for
extensions to be consistent with every other decl, and removes the
'fully_annotated_generic_signature' entry we supplied as a fallback.

Also fixes several bugs with the synthesized extensions mechanism:
- The type sustitutions applied to the extension's requirements were computed
  using the extension itself as the decl context rather than the extension's
  nominal. The meant the extension's requirements themselves were assumed to
  hold when determining the substitutions, so equality constraints were always
  met. Because of this extension members were incorrectly merged with the base
  nominal or its extensions despite having additional constraints.
- Types within the requirements weren't being transformed when printed (e.g.
  'Self.Element' was printed rather than 'T') both in the interface output and
  in the requirements list. We were also incorrectly printing requirements
  that were already satisfied once the base type was subsituted in.
- If both the protocol extension and 'enabling' extension of the base nominal
  that added the protocol conformance had conditional requirements, we were
  only printing the protocol extension's requirements in the synthesized
  extension.
- The USR and annotated decl output embedded in the 'key.doc.full_as_xml'
  string for synthesized members were printed to match their original context, rather than
  the synthesized one.

Resolves rdar://problem/57121937
This commit is contained in:
Nathan Hawes
2020-05-15 10:17:23 -07:00
parent 67d8be7d23
commit 51bace649b
15 changed files with 3407 additions and 1345 deletions

View File

@@ -258,7 +258,7 @@ struct CommentToXMLConverter {
OS << "</Tags>";
}
void visitDocComment(const DocComment *DC);
void visitDocComment(const DocComment *DC, TypeOrExtensionDecl SynthesizedTarget);
void visitCommentParts(const swift::markup::CommentParts &Parts);
};
} // unnamed namespace
@@ -297,7 +297,8 @@ void CommentToXMLConverter::visitCommentParts(const swift::markup::CommentParts
}
}
void CommentToXMLConverter::visitDocComment(const DocComment *DC) {
void CommentToXMLConverter::
visitDocComment(const DocComment *DC, TypeOrExtensionDecl SynthesizedTarget) {
const Decl *D = DC->getDecl();
StringRef RootEndTag;
@@ -347,6 +348,10 @@ void CommentToXMLConverter::visitDocComment(const DocComment *DC) {
{
llvm::raw_svector_ostream OS(SS);
Failed = ide::printValueDeclUSR(VD, OS);
if (!Failed && SynthesizedTarget) {
OS << "::SYNTHESIZED::";
Failed = ide::printValueDeclUSR(SynthesizedTarget.getBaseNominal(), OS);
}
}
if (!Failed && !SS.empty()) {
OS << "<USR>" << SS << "</USR>";
@@ -362,6 +367,9 @@ void CommentToXMLConverter::visitDocComment(const DocComment *DC) {
PO.VarInitializers = false;
PO.ShouldQualifyNestedDeclarations =
PrintOptions::QualifyNestedDeclarations::TypesOnly;
PO.SkipUnderscoredStdlibProtocols = false;
if (SynthesizedTarget)
PO.initForSynthesizedExtension(SynthesizedTarget);
OS << "<Declaration>";
llvm::SmallString<32> DeclSS;
@@ -398,12 +406,15 @@ static bool getClangDocumentationCommentAsXML(const clang::Decl *D,
return true;
}
static void replaceObjcDeclarationsWithSwiftOnes(const Decl *D,
StringRef Doc,
raw_ostream &OS) {
static void
replaceObjcDeclarationsWithSwiftOnes(const Decl *D, StringRef Doc,
raw_ostream &OS,
TypeOrExtensionDecl SynthesizedTarget) {
StringRef Open = "<Declaration>";
StringRef Close = "</Declaration>";
PrintOptions Options = PrintOptions::printQuickHelpDeclaration();
if (SynthesizedTarget)
Options.initForSynthesizedExtension(SynthesizedTarget);
std::string S;
llvm::raw_string_ostream SS(S);
D->print(SS, Options);
@@ -444,14 +455,16 @@ std::string ide::extractPlainTextFromComment(const StringRef Text) {
return getLineListFromComment(SourceMgr, MC, Text).str();
}
bool ide::getDocumentationCommentAsXML(const Decl *D, raw_ostream &OS) {
bool ide::getDocumentationCommentAsXML(const Decl *D, raw_ostream &OS,
TypeOrExtensionDecl SynthesizedTarget) {
auto MaybeClangNode = D->getClangNode();
if (MaybeClangNode) {
if (auto *CD = MaybeClangNode.getAsDecl()) {
std::string S;
llvm::raw_string_ostream SS(S);
if (getClangDocumentationCommentAsXML(CD, SS)) {
replaceObjcDeclarationsWithSwiftOnes(D, SS.str(), OS);
replaceObjcDeclarationsWithSwiftOnes(D, SS.str(), OS,
SynthesizedTarget);
return true;
}
}
@@ -464,7 +477,7 @@ bool ide::getDocumentationCommentAsXML(const Decl *D, raw_ostream &OS) {
return false;
CommentToXMLConverter Converter(OS);
Converter.visitDocComment(DC);
Converter.visitDocComment(DC, SynthesizedTarget);
OS.flush();
return true;