[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

@@ -14,6 +14,7 @@
#define SWIFT_IDE_COMMENT_CONVERSION_H
#include "swift/Basic/LLVM.h"
#include "swift/AST/TypeOrExtensionDecl.h"
#include <memory>
#include <string>
@@ -27,7 +28,9 @@ namespace ide {
/// in Clang-like XML format.
///
/// \returns true if the declaration has a documentation comment.
bool getDocumentationCommentAsXML(const Decl *D, raw_ostream &OS);
bool getDocumentationCommentAsXML(
const Decl *D, raw_ostream &OS,
TypeOrExtensionDecl SynthesizedTarget = TypeOrExtensionDecl());
/// If the declaration has a documentation comment and a localization key,
/// print it into the given output stream and return true. Else, return false.

View File

@@ -813,6 +813,10 @@ public:
TypeArrayView<GenericTypeParamType> genericParams,
ArrayRef<Requirement> requirements, unsigned flags,
llvm::function_ref<bool(const Requirement &)> filter);
void printSingleDepthOfGenericSignature(
TypeArrayView<GenericTypeParamType> genericParams,
ArrayRef<Requirement> requirements, bool &isFirstReq, unsigned flags,
llvm::function_ref<bool(const Requirement &)> filter);
void printRequirement(const Requirement &req);
private:
@@ -872,7 +876,12 @@ public:
return false; // not needed for the parser library.
#endif
if (!shouldPrint(D, true))
bool Synthesize =
Options.TransformContext &&
Options.TransformContext->isPrintingSynthesizedExtension() &&
isa<ExtensionDecl>(D);
if (!shouldPrint(D, true) && !Synthesize)
return false;
Decl *Old = Current;
@@ -890,10 +899,6 @@ public:
SWIFT_DEFER { CurrentType = OldType; };
bool Synthesize =
Options.TransformContext &&
Options.TransformContext->isPrintingSynthesizedExtension() &&
isa<ExtensionDecl>(D);
if (Synthesize) {
Printer.setSynthesizedTarget(Options.TransformContext->getDecl());
}
@@ -1456,6 +1461,15 @@ void PrintAST::printSingleDepthOfGenericSignature(
TypeArrayView<GenericTypeParamType> genericParams,
ArrayRef<Requirement> requirements, unsigned flags,
llvm::function_ref<bool(const Requirement &)> filter) {
bool isFirstReq = true;
printSingleDepthOfGenericSignature(genericParams, requirements, isFirstReq,
flags, filter);
}
void PrintAST::printSingleDepthOfGenericSignature(
TypeArrayView<GenericTypeParamType> genericParams,
ArrayRef<Requirement> requirements, bool &isFirstReq, unsigned flags,
llvm::function_ref<bool(const Requirement &)> filter) {
bool printParams = (flags & PrintParams);
bool printRequirements = (flags & PrintRequirements);
printRequirements &= Options.PrintGenericRequirements;
@@ -1502,7 +1516,6 @@ void PrintAST::printSingleDepthOfGenericSignature(
}
if (printRequirements || printInherited) {
bool isFirstReq = true;
for (const auto &req : requirements) {
if (!filter(req))
continue;
@@ -1564,9 +1577,6 @@ void PrintAST::printSingleDepthOfGenericSignature(
}
} else {
Printer.callPrintStructurePre(PrintStructureKind::GenericRequirement);
// We don't substitute type for the printed requirement so that the
// printed requirement agrees with separately reported generic parameters.
printRequirement(req);
Printer.printStructurePost(PrintStructureKind::GenericRequirement);
}
@@ -1578,7 +1588,7 @@ void PrintAST::printSingleDepthOfGenericSignature(
}
void PrintAST::printRequirement(const Requirement &req) {
printType(req.getFirstType());
printTransformedType(req.getFirstType());
switch (req.getKind()) {
case RequirementKind::Layout:
Printer << " : ";
@@ -1592,7 +1602,7 @@ void PrintAST::printRequirement(const Requirement &req) {
Printer << " == ";
break;
}
printType(req.getSecondType());
printTransformedType(req.getSecondType());
}
bool PrintAST::shouldPrintPattern(const Pattern *P) {
@@ -2180,8 +2190,52 @@ static void printExtendedTypeName(Type ExtendedType, ASTPrinter &Printer,
Ty->print(Printer, Options);
}
void PrintAST::printSynthesizedExtension(Type ExtendedType,
ExtensionDecl *ExtDecl) {
auto printRequirementsFrom = [&](ExtensionDecl *ED, bool &IsFirst) {
auto Sig = ED->getGenericSignature();
printSingleDepthOfGenericSignature(Sig->getGenericParams(),
Sig->getRequirements(),
IsFirst, PrintRequirements,
[](const Requirement &Req){
return true;
});
};
auto printCombinedRequirementsIfNeeded = [&]() -> bool {
if (!Options.TransformContext ||
!Options.TransformContext->isPrintingSynthesizedExtension())
return false;
// Combined requirements only needed if the transform context is an enabling
// extension of the protocol rather than a nominal (which can't have
// constraints of its own).
ExtensionDecl *Target = dyn_cast<ExtensionDecl>(
Options.TransformContext->getDecl().getAsDecl());
if (!Target || Target == ExtDecl)
return false;
bool IsFirst = true;
if (ExtDecl->isConstrainedExtension()) {
printRequirementsFrom(ExtDecl, IsFirst);
}
if (Target->isConstrainedExtension()) {
if (auto *NTD = Target->getExtendedNominal()) {
// Update the current decl and type transform for Target rather than
// ExtDecl.
PrintOptions Adjusted = Options;
Adjusted.initForSynthesizedExtension(NTD);
llvm::SaveAndRestore<Decl*> TempCurrent(Current, NTD);
llvm::SaveAndRestore<PrintOptions> TempOptions(Options, Adjusted);
printRequirementsFrom(Target, IsFirst);
}
}
return true;
};
if (Options.BracketOptions.shouldOpenExtension(ExtDecl)) {
printDocumentationComment(ExtDecl);
printAttributes(ExtDecl);
@@ -2189,7 +2243,25 @@ void PrintAST::printSynthesizedExtension(Type ExtendedType,
printExtendedTypeName(ExtendedType, Printer, Options);
printInherited(ExtDecl);
// We may need to combine requirements from ExtDecl (which has the members
// to print) and the TransformContexts' decl if it is an enabling extension
// of the base NominalDecl (which can have its own requirements) rather than
// base NominalDecl itself (which can't). E.g:
//
// protocol Foo {}
// extension Foo where <requirments from ExtDecl> { ... }
// struct Bar {}
// extension Bar: Foo where <requirments from TransformContext> { ... }
//
// should produce a synthesized extension of Bar with both sets of
// requirments:
//
// extension Bar where <requirments from ExtDecl+TransformContext { ... }
//
if (!printCombinedRequirementsIfNeeded())
printDeclGenericRequirements(ExtDecl);
}
if (Options.TypeDefinitions) {
printMembersOfDecl(ExtDecl, false,

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;

View File

@@ -282,7 +282,10 @@ struct SynthesizedExtensionAnalyzer::Implementation {
auto handleRequirements = [&](SubstitutionMap subMap,
GenericSignature GenericSig,
ExtensionDecl *OwningExt,
ArrayRef<Requirement> Reqs) {
ProtocolDecl *BaseProto = OwningExt->getInnermostDeclContext()
->getSelfProtocolDecl();
for (auto Req : Reqs) {
auto Kind = Req.getKind();
@@ -290,8 +293,16 @@ struct SynthesizedExtensionAnalyzer::Implementation {
if (Kind == RequirementKind::Layout)
continue;
auto First = Req.getFirstType();
auto Second = Req.getSecondType();
Type First = Req.getFirstType();
Type Second = Req.getSecondType();
// Skip protocol's Self : <Protocol> requirement.
if (BaseProto &&
Req.getKind() == RequirementKind::Conformance &&
First->isEqual(BaseProto->getSelfInterfaceType()) &&
Second->getAnyNominal() == BaseProto)
continue;
if (!BaseType->isExistentialType()) {
First = First.subst(subMap);
Second = Second.subst(subMap);
@@ -346,19 +357,29 @@ struct SynthesizedExtensionAnalyzer::Implementation {
// the extension to the interface types of the base type's
// declaration.
SubstitutionMap subMap;
if (!BaseType->isExistentialType())
subMap = BaseType->getContextSubstitutionMap(M, Ext);
if (!BaseType->isExistentialType()) {
if (auto *NTD = Ext->getExtendedNominal())
subMap = BaseType->getContextSubstitutionMap(M, NTD);
}
assert(Ext->getGenericSignature() && "No generic signature.");
auto GenericSig = Ext->getGenericSignature();
if (handleRequirements(subMap, GenericSig, GenericSig->getRequirements()))
if (handleRequirements(subMap, GenericSig, Ext, GenericSig->getRequirements()))
return {Result, MergeInfo};
}
if (Conf && handleRequirements(Conf->getSubstitutions(M),
if (Conf) {
SubstitutionMap subMap;
if (!BaseType->isExistentialType()) {
if (auto *NTD = EnablingExt->getExtendedNominal())
subMap = BaseType->getContextSubstitutionMap(M, NTD);
}
if (handleRequirements(subMap,
Conf->getGenericSignature(),
EnablingExt,
Conf->getConditionalRequirements()))
return {Result, MergeInfo};
}
Result.Ext = Ext;
return {Result, MergeInfo};
@@ -431,7 +452,14 @@ struct SynthesizedExtensionAnalyzer::Implementation {
auto handleExtension = [&](ExtensionDecl *E, bool Synthesized,
ExtensionDecl *EnablingE,
NormalProtocolConformance *Conf) {
if (Options.shouldPrint(E)) {
PrintOptions AdjustedOpts = Options;
if (Synthesized) {
// Members from underscored system protocols should still appear as
// members of the target type, even if the protocols themselves are not
// printed.
AdjustedOpts.SkipUnderscoredStdlibProtocols = false;
}
if (AdjustedOpts.shouldPrint(E)) {
auto Pair = isApplicable(E, Synthesized, EnablingE, Conf);
if (Pair.first) {
InfoMap->insert({E, Pair.first});

View File

@@ -237,21 +237,21 @@ extension S13 : P5 {
public func foo1() {}
}
// CHECK1: <synthesized>extension <ref:Struct>S1</ref> where <ref:GenericTypeParam>Self</ref>.P2T1 : <ref:Protocol>P2</ref> {
// CHECK1: <synthesized>extension <ref:Struct>S1</ref> where T : <ref:Protocol>P2</ref> {
// CHECK1-NEXT: <decl:Func>public func <loc>p2member()</loc></decl>
// CHECK1-NEXT: <decl:Func>public func <loc>ef1(<decl:Param>t: T</decl>)</loc></decl>
// CHECK1-NEXT: <decl:Func>public func <loc>ef2(<decl:Param>t: <ref:Struct>S2</ref></decl>)</loc></decl>
// CHECK1-NEXT: }</synthesized>
// CHECK2: <synthesized>extension <ref:Struct>S1</ref> where <ref:GenericTypeParam>Self</ref>.T1 : <ref:Protocol>P3</ref> {
// CHECK2: <synthesized>extension <ref:Struct>S1</ref> where T : <ref:Protocol>P3</ref> {
// CHECK2-NEXT: <decl:Func>public func <loc>p3Func(<decl:Param>i: <ref:Struct>Int</ref></decl>)</loc> -> <ref:Struct>Int</ref></decl>
// CHECK2-NEXT: }</synthesized>
// CHECK3: <synthesized>extension <ref:Struct>S1</ref> where <ref:GenericTypeParam>Self</ref>.T1 == <ref:Struct>Int</ref> {
// CHECK3: <synthesized>extension <ref:Struct>S1</ref> where T == <ref:Struct>Int</ref> {
// CHECK3-NEXT: <decl:Func>public func <loc>p1IntFunc(<decl:Param>i: <ref:Struct>Int</ref></decl>)</loc> -> <ref:Struct>Int</ref></decl>
// CHECK3-NEXT: }</synthesized>
// CHECK4: <synthesized>extension <ref:Struct>S1</ref> where <ref:GenericTypeParam>Self</ref>.T1 == <ref:Struct>S9</ref><<ref:Struct>Int</ref>> {
// CHECK4: <synthesized>extension <ref:Struct>S1</ref> where T == <ref:Struct>S9</ref><<ref:Struct>Int</ref>> {
// CHECK4-NEXT: <decl:Func>public func <loc>S9IntFunc()</loc></decl>
// CHECK4-NEXT: }</synthesized>

File diff suppressed because it is too large Load Diff

View File

@@ -1960,6 +1960,7 @@
key.kind: source.lang.swift.decl.extension.class,
key.offset: 649,
key.length: 112,
key.fully_annotated_decl: "<decl.extension.class>extension <decl.name><ref.class usr=\"s:4main2CCC\">CC</ref.class></decl.name> : <ref.protocol usr=\"s:4main4ProtP\">Prot</ref.protocol></decl.extension.class>",
key.conforms: [
{
key.kind: source.lang.swift.ref.protocol,

View File

@@ -190,7 +190,7 @@ struct S3<Wrapped> : cake.P5 where Wrapped : cake.P5 {
typealias Element = Wrapped.Element
}
extension S3 {
extension S3 where Wrapped : P6 {
var null: Wrapped.Element? { get }
}
@@ -1792,158 +1792,175 @@ func shouldPrintAnyAsKeyword(x x: Any)
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 2280,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 2284,
key.length: 4
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 2290,
key.length: 7
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 2298,
key.length: 7
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 2309,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 2318,
key.length: 4
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 2323,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 2330,
key.length: 2
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 2334,
key.length: 2
},
{
key.kind: source.lang.swift.syntaxtype.argument,
key.offset: 2338,
key.length: 1
},
{
key.kind: source.lang.swift.syntaxtype.parameter,
key.offset: 2340,
key.length: 2
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 2344,
key.length: 2
},
{
key.kind: source.lang.swift.syntaxtype.argument,
key.offset: 2348,
key.length: 1
},
{
key.kind: source.lang.swift.syntaxtype.parameter,
key.offset: 2350,
key.length: 2
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 2354,
key.length: 2
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 2358,
key.offset: 2273,
key.length: 5
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 2364,
key.offset: 2279,
key.length: 7
},
{
key.kind: source.lang.swift.ref.protocol,
key.name: "P6",
key.usr: "s:4cake2P6P",
key.offset: 2289,
key.length: 2
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 2299,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 2303,
key.length: 4
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 2309,
key.length: 7
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 2317,
key.length: 7
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 2328,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 2337,
key.length: 4
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 2342,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 2349,
key.length: 2
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 2353,
key.length: 2
},
{
key.kind: source.lang.swift.syntaxtype.argument,
key.offset: 2357,
key.length: 1
},
{
key.kind: source.lang.swift.syntaxtype.parameter,
key.offset: 2359,
key.length: 2
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 2363,
key.length: 2
},
{
key.kind: source.lang.swift.syntaxtype.argument,
key.offset: 2367,
key.length: 1
},
{
key.kind: source.lang.swift.syntaxtype.parameter,
key.offset: 2369,
key.length: 2
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 2373,
key.length: 2
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 2377,
key.length: 5
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 2383,
key.length: 2
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 2388,
key.length: 4
},
{
key.kind: source.lang.swift.ref.protocol,
key.name: "Prot",
key.usr: "s:4cake4ProtP",
key.offset: 2374,
key.offset: 2393,
key.length: 4
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 2380,
key.offset: 2399,
key.length: 2
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 2385,
key.offset: 2404,
key.length: 4
},
{
key.kind: source.lang.swift.ref.class,
key.name: "C1",
key.usr: "s:4cake2C1C",
key.offset: 2390,
key.offset: 2409,
key.length: 2
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 2394,
key.offset: 2413,
key.length: 2
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 2397,
key.offset: 2416,
key.length: 7
},
{
key.kind: source.lang.swift.ref.struct,
key.name: "Int",
key.usr: "s:Si",
key.offset: 2408,
key.offset: 2427,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 2413,
key.offset: 2432,
key.length: 4
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 2418,
key.offset: 2437,
key.length: 23
},
{
key.kind: source.lang.swift.syntaxtype.argument,
key.offset: 2442,
key.offset: 2461,
key.length: 1
},
{
key.kind: source.lang.swift.syntaxtype.parameter,
key.offset: 2444,
key.offset: 2463,
key.length: 1
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 2447,
key.offset: 2466,
key.length: 3
}
]
@@ -2172,6 +2189,7 @@ func shouldPrintAnyAsKeyword(x x: Any)
key.doc.full_as_xml: "<Other><Name></Name><Declaration>@available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *)\nextension C1</Declaration><CommentParts><Abstract><Para>some comments</Para></Abstract></CommentParts></Other>",
key.offset: 473,
key.length: 37,
key.fully_annotated_decl: "<decl.extension.class>extension <decl.name><ref.class usr=\"s:4cake2C1C\">C1</ref.class></decl.name></decl.extension.class>",
key.extends: {
key.kind: source.lang.swift.ref.class,
key.name: "C1",
@@ -2214,6 +2232,7 @@ func shouldPrintAnyAsKeyword(x x: Any)
key.kind: source.lang.swift.decl.extension.class,
key.offset: 512,
key.length: 105,
key.fully_annotated_decl: "<decl.extension.class>extension <decl.name><ref.class usr=\"s:4cake2C1C\">C1</ref.class></decl.name> : <ref.protocol usr=\"s:4cake2P4P\">P4</ref.protocol></decl.extension.class>",
key.conforms: [
{
key.kind: source.lang.swift.ref.protocol,
@@ -2266,17 +2285,9 @@ func shouldPrintAnyAsKeyword(x x: Any)
},
{
key.kind: source.lang.swift.decl.extension.enum,
key.generic_requirements: [
{
key.description: "Self : Hashable"
},
{
key.description: "Self.RawValue : Hashable"
}
],
key.offset: 619,
key.length: 187,
key.fully_annotated_generic_signature: "&lt;<decl.generic_type_param usr=\"s:SYsSHRzSH8RawValueSYRpzrlE4Selfxmfp\"><decl.generic_type_param.name>Self</decl.generic_type_param.name></decl.generic_type_param> <syntaxtype.keyword>where</syntaxtype.keyword> <decl.generic_type_requirement><ref.generic_type_param usr=\"s:SYsSHRzSH8RawValueSYRpzrlE4Selfxmfp\">Self</ref.generic_type_param> : <ref.protocol usr=\"s:SH\">Hashable</ref.protocol></decl.generic_type_requirement>, <decl.generic_type_requirement><ref.generic_type_param usr=\"s:SYsSHRzSH8RawValueSYRpzrlE4Selfxmfp\">Self</ref.generic_type_param> : <ref.protocol usr=\"s:SY\">RawRepresentable</ref.protocol></decl.generic_type_requirement>, <decl.generic_type_requirement><ref.generic_type_param usr=\"s:SYsSHRzSH8RawValueSYRpzrlE4Selfxmfp\">Self</ref.generic_type_param>.RawValue : <ref.protocol usr=\"s:SH\">Hashable</ref.protocol></decl.generic_type_requirement>&gt;",
key.fully_annotated_decl: "<syntaxtype.keyword>extension</syntaxtype.keyword> <ref.class usr=\"s:4cake2C1C\">C1</ref.class>.<ref.enum usr=\"s:4cake2C1C0B5CasesO\">C1Cases</ref.enum>",
key.extends: {
key.kind: source.lang.swift.ref.enum,
key.name: "C1Cases",
@@ -2429,6 +2440,7 @@ func shouldPrintAnyAsKeyword(x x: Any)
key.doc.full_as_xml: "<Other><Name></Name><Declaration>@available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *)\nextension C2</Declaration><CommentParts><Abstract><Para>some comments</Para></Abstract></CommentParts></Other>",
key.offset: 982,
key.length: 37,
key.fully_annotated_decl: "<syntaxtype.keyword>extension</syntaxtype.keyword> <ref.class usr=\"s:4cake2C2C\">C2</ref.class>",
key.extends: {
key.kind: source.lang.swift.ref.class,
key.name: "C2",
@@ -2472,6 +2484,7 @@ func shouldPrintAnyAsKeyword(x x: Any)
key.kind: source.lang.swift.decl.extension.class,
key.offset: 1021,
key.length: 95,
key.fully_annotated_decl: "<syntaxtype.keyword>extension</syntaxtype.keyword> <ref.class usr=\"s:4cake2C2C\">C2</ref.class> : <ref.protocol usr=\"s:4cake2P4P\">P4</ref.protocol>",
key.conforms: [
{
key.kind: source.lang.swift.ref.protocol,
@@ -2623,7 +2636,7 @@ func shouldPrintAnyAsKeyword(x x: Any)
key.kind: source.lang.swift.decl.extension.protocol,
key.offset: 1343,
key.length: 54,
key.fully_annotated_generic_signature: "&lt;<decl.generic_type_param usr=\"s:4cake1PP4Selfxmfp\"><decl.generic_type_param.name>Self</decl.generic_type_param.name></decl.generic_type_param> <syntaxtype.keyword>where</syntaxtype.keyword> <decl.generic_type_requirement><ref.generic_type_param usr=\"s:4cake1PP4Selfxmfp\">Self</ref.generic_type_param> : <ref.protocol usr=\"s:4cake1PP\">P</ref.protocol></decl.generic_type_requirement>&gt;",
key.fully_annotated_decl: "<decl.extension.protocol>extension <decl.name><ref.protocol usr=\"s:4cake1PP\">P</ref.protocol></decl.name></decl.extension.protocol>",
key.extends: {
key.kind: source.lang.swift.ref.protocol,
key.name: "P",
@@ -2727,7 +2740,7 @@ func shouldPrintAnyAsKeyword(x x: Any)
key.kind: source.lang.swift.decl.extension.protocol,
key.offset: 1582,
key.length: 53,
key.fully_annotated_generic_signature: "&lt;<decl.generic_type_param usr=\"s:4cake2P6P4Selfxmfp\"><decl.generic_type_param.name>Self</decl.generic_type_param.name></decl.generic_type_param> <syntaxtype.keyword>where</syntaxtype.keyword> <decl.generic_type_requirement><ref.generic_type_param usr=\"s:4cake2P6P4Selfxmfp\">Self</ref.generic_type_param> : <ref.protocol usr=\"s:4cake2P6P\">P6</ref.protocol></decl.generic_type_requirement>&gt;",
key.fully_annotated_decl: "<decl.extension.protocol>extension <decl.name><ref.protocol usr=\"s:4cake2P6P\">P6</ref.protocol></decl.name></decl.extension.protocol>",
key.extends: {
key.kind: source.lang.swift.ref.protocol,
key.name: "P6",
@@ -2790,7 +2803,7 @@ func shouldPrintAnyAsKeyword(x x: Any)
key.kind: source.lang.swift.decl.extension.protocol,
key.offset: 1741,
key.length: 79,
key.fully_annotated_generic_signature: "&lt;<decl.generic_type_param usr=\"s:4cake4ProtP4Selfxmfp\"><decl.generic_type_param.name>Self</decl.generic_type_param.name></decl.generic_type_param> <syntaxtype.keyword>where</syntaxtype.keyword> <decl.generic_type_requirement><ref.generic_type_param usr=\"s:4cake4ProtP4Selfxmfp\">Self</ref.generic_type_param> : <ref.protocol usr=\"s:4cake4ProtP\">Prot</ref.protocol></decl.generic_type_requirement>&gt;",
key.fully_annotated_decl: "<decl.extension.protocol>extension <decl.name><ref.protocol usr=\"s:4cake4ProtP\">Prot</ref.protocol></decl.name></decl.extension.protocol>",
key.extends: {
key.kind: source.lang.swift.ref.protocol,
key.name: "Prot",
@@ -2834,7 +2847,7 @@ func shouldPrintAnyAsKeyword(x x: Any)
],
key.offset: 1822,
key.length: 63,
key.fully_annotated_generic_signature: "&lt;<decl.generic_type_param usr=\"s:4cake4ProtPAASi7ElementRtzrlE4Selfxmfp\"><decl.generic_type_param.name>Self</decl.generic_type_param.name></decl.generic_type_param> <syntaxtype.keyword>where</syntaxtype.keyword> <decl.generic_type_requirement><ref.generic_type_param usr=\"s:4cake4ProtPAASi7ElementRtzrlE4Selfxmfp\">Self</ref.generic_type_param> : <ref.protocol usr=\"s:4cake4ProtP\">Prot</ref.protocol></decl.generic_type_requirement>, <decl.generic_type_requirement><ref.generic_type_param usr=\"s:4cake4ProtPAASi7ElementRtzrlE4Selfxmfp\">Self</ref.generic_type_param>.Element == <ref.struct usr=\"s:Si\">Int</ref.struct></decl.generic_type_requirement>&gt;",
key.fully_annotated_decl: "<decl.extension.protocol>extension <decl.name><ref.protocol usr=\"s:4cake4ProtP\">Prot</ref.protocol></decl.name> <syntaxtype.keyword>where</syntaxtype.keyword> <decl.generic_type_requirement><ref.generic_type_param usr=\"s:4cake4ProtPAASi7ElementRtzrlE4Selfxmfp\">Self</ref.generic_type_param>.Element == <ref.struct usr=\"s:Si\">Int</ref.struct></decl.generic_type_requirement></decl.extension.protocol>",
key.extends: {
key.kind: source.lang.swift.ref.protocol,
key.name: "Prot",
@@ -2925,7 +2938,7 @@ func shouldPrintAnyAsKeyword(x x: Any)
key.kind: source.lang.swift.decl.extension.enum,
key.offset: 2031,
key.length: 76,
key.fully_annotated_generic_signature: "&lt;<decl.generic_type_param usr=\"s:SQ4Selfxmfp\"><decl.generic_type_param.name>Self</decl.generic_type_param.name></decl.generic_type_param> <syntaxtype.keyword>where</syntaxtype.keyword> <decl.generic_type_requirement><ref.generic_type_param usr=\"s:SQ4Selfxmfp\">Self</ref.generic_type_param> : <ref.protocol usr=\"s:SQ\">Equatable</ref.protocol></decl.generic_type_requirement>&gt;",
key.fully_annotated_decl: "<syntaxtype.keyword>extension</syntaxtype.keyword> <ref.struct usr=\"s:4cake2S1V\">S1</ref.struct>.<ref.enum usr=\"s:4cake2S1V2SEO\">SE</ref.enum>",
key.extends: {
key.kind: source.lang.swift.ref.enum,
key.name: "SE",
@@ -3035,9 +3048,14 @@ func shouldPrintAnyAsKeyword(x x: Any)
},
{
key.kind: source.lang.swift.decl.extension.struct,
key.generic_requirements: [
{
key.description: "Wrapped : P6"
}
],
key.offset: 2260,
key.length: 56,
key.fully_annotated_generic_signature: "&lt;<decl.generic_type_param usr=\"s:4cake2P6P4Selfxmfp\"><decl.generic_type_param.name>Self</decl.generic_type_param.name></decl.generic_type_param> <syntaxtype.keyword>where</syntaxtype.keyword> <decl.generic_type_requirement><ref.generic_type_param usr=\"s:4cake2P6P4Selfxmfp\">Self</ref.generic_type_param> : <ref.protocol usr=\"s:4cake2P6P\">P6</ref.protocol></decl.generic_type_requirement>&gt;",
key.length: 75,
key.fully_annotated_decl: "<syntaxtype.keyword>extension</syntaxtype.keyword> <ref.struct usr=\"s:4cake2S3V\">S3</ref.struct> <syntaxtype.keyword>where</syntaxtype.keyword> <decl.generic_type_requirement>Wrapped : <ref.protocol usr=\"s:4cake2P6P\">P6</ref.protocol></decl.generic_type_requirement>",
key.extends: {
key.kind: source.lang.swift.ref.struct,
key.name: "S3",
@@ -3049,7 +3067,7 @@ func shouldPrintAnyAsKeyword(x x: Any)
key.name: "null",
key.usr: "s:4cake2P6PAAE4null7ElementQzSgvp::SYNTHESIZED::s:4cake2S3V",
key.original_usr: "s:4cake2P6PAAE4null7ElementQzSgvp",
key.offset: 2280,
key.offset: 2299,
key.length: 34,
key.fully_annotated_decl: "<decl.var.instance><syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>null</decl.name>: <decl.var.type>Wrapped.Element?</decl.var.type> { <syntaxtype.keyword>get</syntaxtype.keyword> }</decl.var.instance>"
}
@@ -3078,7 +3096,7 @@ func shouldPrintAnyAsKeyword(x x: Any)
key.description: "T1.Element == Int"
}
],
key.offset: 2318,
key.offset: 2337,
key.length: 93,
key.fully_annotated_decl: "<decl.function.free><syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>genfoo</decl.name>&lt;<decl.generic_type_param usr=\"s:4cake6genfoo1x1yyx_q_tAA4ProtRzAA2C1CRb_Si7ElementRtzr0_lF2T1L_xmfp\"><decl.generic_type_param.name>T1</decl.generic_type_param.name></decl.generic_type_param>, <decl.generic_type_param usr=\"s:4cake6genfoo1x1yyx_q_tAA4ProtRzAA2C1CRb_Si7ElementRtzr0_lF2T2L_q_mfp\"><decl.generic_type_param.name>T2</decl.generic_type_param.name></decl.generic_type_param>&gt;(<decl.var.parameter><decl.var.parameter.argument_label>x</decl.var.parameter.argument_label> <decl.var.parameter.name>ix</decl.var.parameter.name>: <decl.var.parameter.type>T1</decl.var.parameter.type></decl.var.parameter>, <decl.var.parameter><decl.var.parameter.argument_label>y</decl.var.parameter.argument_label> <decl.var.parameter.name>iy</decl.var.parameter.name>: <decl.var.parameter.type>T2</decl.var.parameter.type></decl.var.parameter>) <syntaxtype.keyword>where</syntaxtype.keyword> <decl.generic_type_requirement>T1 : <ref.protocol usr=\"s:4cake4ProtP\">Prot</ref.protocol></decl.generic_type_requirement>, <decl.generic_type_requirement>T2 : <ref.class usr=\"s:4cake2C1C\">C1</ref.class></decl.generic_type_requirement>, <decl.generic_type_requirement>T1.Element == <ref.struct usr=\"s:Si\">Int</ref.struct></decl.generic_type_requirement></decl.function.free>",
key.entities: [
@@ -3086,14 +3104,14 @@ func shouldPrintAnyAsKeyword(x x: Any)
key.kind: source.lang.swift.decl.var.local,
key.keyword: "x",
key.name: "ix",
key.offset: 2344,
key.offset: 2363,
key.length: 2
},
{
key.kind: source.lang.swift.decl.var.local,
key.keyword: "y",
key.name: "iy",
key.offset: 2354,
key.offset: 2373,
key.length: 2
}
]
@@ -3102,7 +3120,7 @@ func shouldPrintAnyAsKeyword(x x: Any)
key.kind: source.lang.swift.decl.function.free,
key.name: "shouldPrintAnyAsKeyword(x:)",
key.usr: "s:4cake23shouldPrintAnyAsKeyword1xyyp_tF",
key.offset: 2413,
key.offset: 2432,
key.length: 38,
key.fully_annotated_decl: "<decl.function.free><syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>shouldPrintAnyAsKeyword</decl.name>(<decl.var.parameter><decl.var.parameter.argument_label>x</decl.var.parameter.argument_label>: <decl.var.parameter.type><syntaxtype.keyword>Any</syntaxtype.keyword></decl.var.parameter.type></decl.var.parameter>)</decl.function.free>",
key.entities: [
@@ -3110,7 +3128,7 @@ func shouldPrintAnyAsKeyword(x x: Any)
key.kind: source.lang.swift.decl.var.local,
key.keyword: "x",
key.name: "x",
key.offset: 2447,
key.offset: 2466,
key.length: 3
}
]

View File

@@ -767,7 +767,7 @@ extension Dictionary.Keys where Key : cake1.P1 {
key.kind: source.lang.swift.decl.extension.protocol,
key.offset: 166,
key.length: 35,
key.fully_annotated_generic_signature: "&lt;<decl.generic_type_param usr=\"s:5cake19InitProtoP4Selfxmfp\"><decl.generic_type_param.name>Self</decl.generic_type_param.name></decl.generic_type_param> <syntaxtype.keyword>where</syntaxtype.keyword> <decl.generic_type_requirement><ref.generic_type_param usr=\"s:5cake19InitProtoP4Selfxmfp\">Self</ref.generic_type_param> : <ref.protocol usr=\"s:5cake19InitProtoP\">InitProto</ref.protocol></decl.generic_type_requirement>&gt;",
key.fully_annotated_decl: "<decl.extension.protocol>extension <decl.name><ref.protocol usr=\"s:5cake19InitProtoP\">InitProto</ref.protocol></decl.name></decl.extension.protocol>",
key.extends: {
key.kind: source.lang.swift.ref.protocol,
key.name: "InitProto",
@@ -946,7 +946,7 @@ extension Dictionary.Keys where Key : cake1.P1 {
key.kind: source.lang.swift.decl.extension.protocol,
key.offset: 511,
key.length: 118,
key.fully_annotated_generic_signature: "&lt;<decl.generic_type_param usr=\"s:5cake12P2P4Selfxmfp\"><decl.generic_type_param.name>Self</decl.generic_type_param.name></decl.generic_type_param> <syntaxtype.keyword>where</syntaxtype.keyword> <decl.generic_type_requirement><ref.generic_type_param usr=\"s:5cake12P2P4Selfxmfp\">Self</ref.generic_type_param> : <ref.protocol usr=\"s:5cake12P2P\">P2</ref.protocol></decl.generic_type_requirement>&gt;",
key.fully_annotated_decl: "<decl.extension.protocol>extension <decl.name><ref.protocol usr=\"s:5cake12P2P\">P2</ref.protocol></decl.name></decl.extension.protocol>",
key.extends: {
key.kind: source.lang.swift.ref.protocol,
key.name: "P2",
@@ -1025,7 +1025,7 @@ extension Dictionary.Keys where Key : cake1.P1 {
],
key.offset: 631,
key.length: 64,
key.fully_annotated_generic_signature: "&lt;<decl.generic_type_param usr=\"s:5cake12P2PA2A2P3RzrlE4Selfxmfp\"><decl.generic_type_param.name>Self</decl.generic_type_param.name></decl.generic_type_param> <syntaxtype.keyword>where</syntaxtype.keyword> <decl.generic_type_requirement><ref.generic_type_param usr=\"s:5cake12P2PA2A2P3RzrlE4Selfxmfp\">Self</ref.generic_type_param> : <ref.protocol usr=\"s:5cake12P2P\">P2</ref.protocol></decl.generic_type_requirement>, <decl.generic_type_requirement><ref.generic_type_param usr=\"s:5cake12P2PA2A2P3RzrlE4Selfxmfp\">Self</ref.generic_type_param> : <ref.protocol usr=\"s:5cake12P3P\">P3</ref.protocol></decl.generic_type_requirement>&gt;",
key.fully_annotated_decl: "<decl.extension.protocol>extension <decl.name><ref.protocol usr=\"s:5cake12P2P\">P2</ref.protocol></decl.name> <syntaxtype.keyword>where</syntaxtype.keyword> <decl.generic_type_requirement><ref.generic_type_param usr=\"s:5cake12P2PA2A2P3RzrlE4Selfxmfp\">Self</ref.generic_type_param> : <ref.protocol usr=\"s:5cake12P3P\">P3</ref.protocol></decl.generic_type_requirement></decl.extension.protocol>",
key.extends: {
key.kind: source.lang.swift.ref.protocol,
key.name: "P2",
@@ -1078,7 +1078,7 @@ extension Dictionary.Keys where Key : cake1.P1 {
],
key.offset: 737,
key.length: 45,
key.fully_annotated_generic_signature: "&lt;<decl.generic_type_param usr=\"s:SD3Keyxmfp\"><decl.generic_type_param.name>Key</decl.generic_type_param.name></decl.generic_type_param>, <decl.generic_type_param usr=\"s:SD5Valueq_mfp\"><decl.generic_type_param.name>Value</decl.generic_type_param.name></decl.generic_type_param> <syntaxtype.keyword>where</syntaxtype.keyword> <decl.generic_type_requirement>Key : <ref.protocol usr=\"s:SH\">Hashable</ref.protocol></decl.generic_type_requirement>&gt;",
key.fully_annotated_decl: "<decl.extension.struct>extension <decl.name><ref.struct usr=\"s:SD\">Dictionary</ref.struct>.<ref.struct usr=\"s:SD4KeysV\">Keys</ref.struct></decl.name></decl.extension.struct>",
key.extends: {
key.kind: source.lang.swift.ref.struct,
key.name: "Keys",
@@ -1107,7 +1107,7 @@ extension Dictionary.Keys where Key : cake1.P1 {
],
key.offset: 784,
key.length: 66,
key.fully_annotated_generic_signature: "&lt;<decl.generic_type_param usr=\"s:SD4KeysV5cake1AC2P1RzrlE3Keyxmfp\"><decl.generic_type_param.name>Key</decl.generic_type_param.name></decl.generic_type_param>, <decl.generic_type_param usr=\"s:SD4KeysV5cake1AC2P1RzrlE5Valueq_mfp\"><decl.generic_type_param.name>Value</decl.generic_type_param.name></decl.generic_type_param> <syntaxtype.keyword>where</syntaxtype.keyword> <decl.generic_type_requirement>Key : <ref.protocol usr=\"s:SH\">Hashable</ref.protocol></decl.generic_type_requirement>, <decl.generic_type_requirement>Key : <ref.protocol usr=\"s:5cake12P1P\">P1</ref.protocol></decl.generic_type_requirement>&gt;",
key.fully_annotated_decl: "<decl.extension.struct>extension <decl.name><ref.struct usr=\"s:SD\">Dictionary</ref.struct>.<ref.struct usr=\"s:SD4KeysV\">Keys</ref.struct></decl.name> <syntaxtype.keyword>where</syntaxtype.keyword> <decl.generic_type_requirement>Key : <ref.protocol usr=\"s:5cake12P1P\">P1</ref.protocol></decl.generic_type_requirement></decl.extension.struct>",
key.extends: {
key.kind: source.lang.swift.ref.struct,
key.name: "Keys",

View File

@@ -0,0 +1,8 @@
// RUN: %empty-directory(%t)
// RUN: %empty-directory(%t/mcp)
// RUN: %empty-directory(%t/UnderscoredProto.framework/Modules/UnderscoredProto.swiftmodule)
// RUN: cp %S/../Inputs/UnderscoredProto.swiftinterface %t/UnderscoredProto.framework/Modules/UnderscoredProto.swiftmodule/%module-target-triple.swiftinterface
// RUN: %sourcekitd-test -req=doc-info -synthesized-extension -module UnderscoredProto -- -target %target-triple -Fsystem %t -module-cache-path %t/mcp > %t.response
// RUN: %diff -u %s.response %t.response

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,101 @@
// swift-interface-format-version: 1.0
// swift-module-flags: -swift-version 5 -enable-library-evolution -module-name UnderscoredProto
public protocol _UnderscoredProto {}
public protocol _UnderscoredProto2 {
associatedtype Elem
}
public extension _UnderscoredProto {
func fromProtoExtension()
}
public extension _UnderscoredProto2 {
func fromProto2Extension(takesElem: Elem)
}
@available(*, deprecated, message: "")
public extension _UnderscoredProto {
func fromDeprecatedProtoExtension(){}
}
public extension _UnderscoredProto2 where Elem == String {
func fromConditionalProto2Extension(takesElemIfString: Elem)
}
@available(*, deprecated, message: "")
public extension _UnderscoredProto2 where Elem == Int {
func fromDeprecatedConditionalProto2Extension(takesElemInt: Elem)
}
public struct A<T> {
public func fromA(takesT: T)
}
extension A {
public func fromAExtension(takesT: T)
}
extension A : _UnderscoredProto {}
extension A : _UnderscoredProto2 where T == String {
public typealias Elem = Int
public func fromAConditionalExtension(takesTIfString: T)
}
public class B<T>: _UnderscoredProto {
public func fromB(takesT: T)
}
extension B: _UnderscoredProto2 {
public typealias Elem = String
}
public class C<U,V>: B<String> where U: Equatable {
public func fromC(takesUIfEquatable: U)
}
public protocol _UnderscoredProto3 {
associatedtype Elem1
associatedtype Elem2
}
extension _UnderscoredProto3 {
public func fromProto3Extension(takesElem1: Elem1)
public func fromProto3Extension(takesElem2: Elem2)
}
public protocol _UnderscoredProto4: _UnderscoredProto3 where Elem2: Equatable {}
extension _UnderscoredProto4 {
public func fromProto4Extension(takesElem2IfEquatable: Elem2)
}
extension _UnderscoredProto4 where Elem2: Hashable {
public func fromProto4Extension(takesElem2IfHashable: Elem2)
}
extension C: _UnderscoredProto4 {
public typealias Elem1 = V
public typealias Elem2 = U
public func fromCConditionlExtension(takesU: U)
}
public struct D<T, U> {
public func fromD(takesT: T, takesU: U)
}
public protocol Other1 {}
public protocol _SomeProto {
associatedtype Item
}
extension _SomeProto where Item: Other1 {
public func fromSomeProtoExtensionSplitConditions(takesItemIfOther1: Item)
}
extension D: _SomeProto where T: Equatable {
public typealias Item = T
}

View File

@@ -260,7 +260,9 @@ struct SourceTextInfo {
} // end anonymous namespace
static void initDocGenericParams(const Decl *D, DocEntityInfo &Info) {
static void initDocGenericParams(const Decl *D, DocEntityInfo &Info,
TypeOrExtensionDecl SynthesizedTarget,
bool IsSynthesizedExt) {
auto *GC = D->getAsGenericContext();
if (!GC)
return;
@@ -276,36 +278,107 @@ static void initDocGenericParams(const Decl *D, DocEntityInfo &Info) {
if (ParentSig && ParentSig->isEqual(GenericSig))
return;
// If we have a synthesized target, map from its base type into the this
// declaration's innermost type context, or if we're dealing with the
// synthesized extention itself rather than a member, into its extended
// nominal (the extension's own requirements shouldn't be considered in the
// substitution).
SubstitutionMap SubMap;
Type BaseType;
if (SynthesizedTarget) {
BaseType = SynthesizedTarget.getBaseNominal()->getDeclaredInterfaceType();
if (!BaseType->isExistentialType()) {
DeclContext *DC;
if (IsSynthesizedExt)
DC = cast<ExtensionDecl>(D)->getExtendedNominal();
else
DC = D->getInnermostDeclContext()->getInnermostTypeContext();
auto *M = DC->getParentModule();
SubMap = BaseType->getContextSubstitutionMap(M, DC);
}
}
auto SubstTypes = [&](Type Ty) {
return Ty.subst(SubMap, SubstFlags::DesugarMemberTypes);
};
// FIXME: Not right for extensions of nested generic types
if (GC->isGeneric()) {
for (auto *GP : GenericSig->getInnermostGenericParams()) {
if (GP->getDecl()->isImplicit())
continue;
Type TypeToPrint = GP;
if (!SubMap.empty()) {
if (auto ArgTy = SubstTypes(GP)) {
if (!ArgTy->hasError()) {
// Ignore parameter that aren't generic after substitution
if (!ArgTy->is<ArchetypeType>() && !ArgTy->isTypeParameter())
continue;
TypeToPrint = ArgTy;
}
}
}
DocGenericParam Param;
Param.Name = std::string(GP->getName());
Param.Name = TypeToPrint->getString();
Info.GenericParams.push_back(Param);
}
}
ProtocolDecl *proto = nullptr;
ProtocolDecl *Proto = nullptr;
if (auto *typeDC = GC->getInnermostTypeContext())
proto = typeDC->getSelfProtocolDecl();
Proto = typeDC->getSelfProtocolDecl();
for (auto &Req : GenericSig->getRequirements()) {
// Skip protocol Self requirement.
if (proto &&
for (auto Req: GenericSig->getRequirements()) {
if (Proto &&
Req.getKind() == RequirementKind::Conformance &&
Req.getFirstType()->isEqual(proto->getSelfInterfaceType()) &&
Req.getSecondType()->getAnyNominal() == proto)
Req.getFirstType()->isEqual(Proto->getSelfInterfaceType()) &&
Req.getSecondType()->getAnyNominal() == Proto)
continue;
auto First = Req.getFirstType();
Type Second;
if (Req.getKind() != RequirementKind::Layout)
Second = Req.getSecondType();
if (!SubMap.empty()) {
Type SubFirst = SubstTypes(First);
if (!SubFirst->hasError())
First = SubFirst;
if (Second) {
Type SubSecond = SubstTypes(Second);
if (!SubSecond->hasError())
Second = SubSecond;
// Ignore requirements that don't involve a generic after substitution.
if (!(First->is<ArchetypeType>() || First->isTypeParameter()) &&
!(Second->is<ArchetypeType>() || Second->isTypeParameter()))
continue;
}
}
std::string ReqStr;
PrintOptions Opts;
llvm::raw_string_ostream OS(ReqStr);
Req.print(OS, Opts);
PrintOptions Opts;
if (Req.getKind() != RequirementKind::Layout) {
Requirement(Req.getKind(), First, Second).print(OS, Opts);
} else {
Requirement(Req.getKind(), First, Req.getLayoutConstraint()).print(OS, Opts);
}
OS.flush();
Info.GenericRequirements.push_back(std::move(ReqStr));
}
if (IsSynthesizedExt) {
// If there's a conditional conformance on the base type that 'enabled' this
// extension, we need to print its requirements too.
if (auto *EnablingExt = dyn_cast<ExtensionDecl>(SynthesizedTarget.getAsDecl())) {
if (EnablingExt->isConstrainedExtension()) {
initDocGenericParams(EnablingExt, Info,
/*Target=*/EnablingExt->getExtendedNominal(),
/*IsSynthesizedExtension*/false);
}
}
}
}
static bool initDocEntityInfo(const Decl *D,
@@ -376,29 +449,12 @@ static bool initDocEntityInfo(const Decl *D,
llvm::SmallString<128> DocBuffer;
{
llvm::raw_svector_ostream OSS(DocBuffer);
ide::getDocumentationCommentAsXML(D, OSS);
ide::getDocumentationCommentAsXML(D, OSS, SynthesizedTarget);
}
StringRef DocRef = (StringRef)DocBuffer;
if (IsSynthesizedExtension &&
DocRef.find("<Declaration>") != StringRef::npos) {
StringRef Open = "extension ";
assert(DocRef.find(Open) != StringRef::npos);
auto FirstPart = DocRef.substr(0, DocRef.find(Open) + (Open).size());
auto SecondPart = DocRef.substr(FirstPart.size());
auto ExtendedName = ((const ExtensionDecl*)D)->getExtendedNominal()
->getName().str();
assert(SecondPart.startswith(ExtendedName));
SecondPart = SecondPart.substr(ExtendedName.size());
llvm::SmallString<128> UpdatedDocBuffer;
UpdatedDocBuffer.append(FirstPart);
UpdatedDocBuffer.append(SynthesizedTargetNTD->getName().str());
UpdatedDocBuffer.append(SecondPart);
OS << UpdatedDocBuffer;
} else
OS << DocBuffer;
}
initDocGenericParams(D, Info);
initDocGenericParams(D, Info, SynthesizedTarget, IsSynthesizedExtension);
llvm::raw_svector_ostream LocalizationKeyOS(Info.LocalizationKey);
ide::getLocalizationKey(D, LocalizationKeyOS);
@@ -410,14 +466,13 @@ static bool initDocEntityInfo(const Decl *D,
VD, SynthesizedTarget, OS);
else
SwiftLangSupport::printFullyAnnotatedDeclaration(VD, Type(), OS);
} else if (auto *E = dyn_cast<ExtensionDecl>(D)) {
if (auto Sig = E->getGenericSignature()) {
// The extension under printing is potentially part of a synthesized
// extension. Thus it's hard to print the fully annotated decl. We
// need to at least print the generic signature here.
llvm::raw_svector_ostream OS(Info.FullyAnnotatedGenericSig);
SwiftLangSupport::printFullyAnnotatedGenericReq(Sig, OS);
}
} else if (auto *ED = dyn_cast<ExtensionDecl>(D)) {
llvm::raw_svector_ostream OS(Info.FullyAnnotatedDecl);
if (SynthesizedTarget)
SwiftLangSupport::printFullyAnnotatedSynthesizedDeclaration(
ED, SynthesizedTarget, OS);
else
SwiftLangSupport::printFullyAnnotatedDeclaration(ED, OS);
}
if (DeclaringModForCrossImport) {

View File

@@ -420,13 +420,17 @@ public:
swift::Type BaseTy,
llvm::raw_ostream &OS);
static void printFullyAnnotatedDeclaration(const swift::ExtensionDecl *VD,
llvm::raw_ostream &OS);
static void
printFullyAnnotatedSynthesizedDeclaration(const swift::ValueDecl *VD,
swift::TypeOrExtensionDecl Target,
llvm::raw_ostream &OS);
static void
printFullyAnnotatedGenericReq(const swift::GenericSignature Sig,
printFullyAnnotatedSynthesizedDeclaration(const swift::ExtensionDecl *ED,
swift::TypeOrExtensionDecl Target,
llvm::raw_ostream &OS);
/// Print 'description' or 'sourcetext' the given \p VD to \p OS. If

View File

@@ -457,12 +457,11 @@ void SwiftLangSupport::printFullyAnnotatedDeclaration(const ValueDecl *VD,
VD->print(Printer, PO);
}
void SwiftLangSupport::printFullyAnnotatedGenericReq(
const swift::GenericSignature Sig, llvm::raw_ostream &OS) {
assert(Sig);
void SwiftLangSupport::printFullyAnnotatedDeclaration(const ExtensionDecl *ED,
raw_ostream &OS) {
FullyAnnotatedDeclarationPrinter Printer(OS);
PrintOptions PO = PrintOptions::printQuickHelpDeclaration();
Sig->print(Printer, PO);
ED->print(Printer, PO);
}
void SwiftLangSupport::printFullyAnnotatedSynthesizedDeclaration(
@@ -475,6 +474,15 @@ void SwiftLangSupport::printFullyAnnotatedSynthesizedDeclaration(
VD->print(Printer, PO);
}
void SwiftLangSupport::printFullyAnnotatedSynthesizedDeclaration(
const swift::ExtensionDecl *ED, TypeOrExtensionDecl Target,
llvm::raw_ostream &OS) {
FullyAnnotatedDeclarationPrinter Printer(OS);
PrintOptions PO = PrintOptions::printQuickHelpDeclaration();
PO.initForSynthesizedExtension(Target);
ED->print(Printer, PO);
}
template <typename FnTy>
void walkRelatedDecls(const ValueDecl *VD, const FnTy &Fn) {
llvm::SmallDenseMap<DeclName, unsigned, 16> NamesSeen;