[SourceKit] Annotate class method dynamic Self return types

Pass through the original Type in addition to the TypeDecl so that we
can distinguish DynamicSelfType with underlying ClassType from just any
old ClassType.

rdar://problem/25158493
This commit is contained in:
Ben Langmuir
2016-03-14 19:43:54 -07:00
parent ca198b0320
commit 1b08d83b6f
11 changed files with 41 additions and 26 deletions

View File

@@ -118,7 +118,11 @@ public:
/// Called when printing the referenced name of a type declaration, possibly
/// from deep inside another type.
virtual void printTypeRef(const TypeDecl *TD, Identifier Name);
///
/// \param T the original \c Type being referenced. May be null.
/// \param RefTo the \c TypeDecl this is considered a reference to.
/// \param Name the name to be printed.
virtual void printTypeRef(Type T, const TypeDecl *RefTo, Identifier Name);
/// Called when printing the referenced name of a module.
virtual void printModuleRef(ModuleEntity Mod, Identifier Name);
@@ -147,7 +151,7 @@ public:
// Helper functions.
void printTypeRef(const DynamicSelfType *T, Identifier Name);
void printTypeRef(DynamicSelfType *T, Identifier Name);
void printSeparator(bool &first, StringRef separator) {
if (first) {

View File

@@ -657,17 +657,21 @@ void ASTPrinter::printTextImpl(StringRef Text) {
printText(Text);
}
void ASTPrinter::printTypeRef(const TypeDecl *TD, Identifier Name) {
void ASTPrinter::printTypeRef(Type T, const TypeDecl *RefTo, Identifier Name) {
PrintNameContext Context = PrintNameContext::Normal;
if (auto GP = dyn_cast<GenericTypeParamDecl>(TD)) {
if (auto GP = dyn_cast<GenericTypeParamDecl>(RefTo)) {
if (GP->isProtocolSelf())
Context = PrintNameContext::GenericParameter;
} else if (T && T->is<DynamicSelfType>()) {
assert(T->getAs<DynamicSelfType>()->getSelfType()->getAnyNominal() &&
"protocol Self handled as GenericTypeParamDecl");
Context = PrintNameContext::ClassDynamicSelf;
}
printName(Name, Context);
}
void ASTPrinter::printTypeRef(const DynamicSelfType *T, Identifier Name) {
void ASTPrinter::printTypeRef(DynamicSelfType *T, Identifier Name) {
// Try to print as a reference to the static type so that we will get a USR,
// in cursor info.
if (auto staticSelfT = T->getSelfType()) {
@@ -675,9 +679,14 @@ void ASTPrinter::printTypeRef(const DynamicSelfType *T, Identifier Name) {
if (auto AT = staticSelfT->getAs<ArchetypeType>()) {
if (auto GTD = AT->getSelfProtocol()->getProtocolSelf()) {
assert(GTD->isProtocolSelf());
printTypeRef(GTD, Name);
printTypeRef(T, GTD, Name);
return;
}
// Handle class 'Self', which is just a class type.
} else if (auto *NTD = staticSelfT->getAnyNominal()) {
printTypeRef(T, NTD, Name);
return;
}
}
@@ -1918,7 +1927,7 @@ static void printExtendedTypeName(Type ExtendedType, ASTPrinter &Printer,
return;
}
Printer.printTypeRef(Nominal, Nominal->getName());
Printer.printTypeRef(ExtendedType, Nominal, Nominal->getName());
}
void PrintAST::
@@ -3148,7 +3157,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
template <typename T>
void printTypeDeclName(T *Ty) {
TypeDecl *TD = Ty->getDecl();
Printer.printTypeRef(TD, TD->getName());
Printer.printTypeRef(Ty, TD, TD->getName());
}
// FIXME: we should have a callback that would tell us

View File

@@ -317,7 +317,7 @@ void ComponentIdentTypeRepr::printImpl(ASTPrinter &Printer,
if (auto MD = dyn_cast<ModuleDecl>(TD))
Printer.printModuleRef(MD, getIdentifier());
else
Printer.printTypeRef(TD, getIdentifier());
Printer.printTypeRef(Type(), TD, getIdentifier());
} else {
Printer.printName(getIdentifier());
}

View File

@@ -69,8 +69,8 @@ private:
void printTypePost(const TypeLoc &TL) override {
return OtherPrinter.printTypePost(TL);
}
void printTypeRef(const TypeDecl *TD, Identifier Name) override {
return OtherPrinter.printTypeRef(TD, Name);
void printTypeRef(Type T, const TypeDecl *TD, Identifier Name) override {
return OtherPrinter.printTypeRef(T, TD, Name);
}
void printModuleRef(ModuleEntity Mod, Identifier Name) override {
return OtherPrinter.printModuleRef(Mod, Name);

View File

@@ -227,7 +227,7 @@ class <loc>FooClassDerived</loc> : <ref:Class>FooClassBase</ref>, <ref:Protocol>
<decl:Class>class <loc>FooUnavailableMembers</loc> : <ref:Class>FooClassBase</ref> {
<decl:Constructor>convenience <loc>init!(<decl:Param>int i: <ref:Struct>Int32</ref></decl>)</loc></decl>
<decl:Func>@available(*, unavailable, message: "use object construction 'FooUnavailableMembers(int:)'")
class func <loc>withInt(<decl:Param>i: <ref:Struct>Int32</ref></decl>)</loc> -> Self!</decl>
class func <loc>withInt(<decl:Param>i: <ref:Struct>Int32</ref></decl>)</loc> -> <ref:Class>Self</ref>!</decl>
<decl:Func>@available(*, unavailable, message: "x")
func <loc>unavailable()</loc></decl>
<decl:Func>@available(*, unavailable, message: "Not available in Swift")

View File

@@ -2676,7 +2676,9 @@ var FooSubUnnamedEnumeratorA1: Int { get }
key.length: 5
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.kind: source.lang.swift.ref.class,
key.name: "FooUnavailableMembers",
key.usr: "c:objc(cs)FooUnavailableMembers",
key.offset: 3973,
key.length: 4
},
@@ -4406,7 +4408,7 @@ var FooSubUnnamedEnumeratorA1: Int { get }
key.usr: "c:objc(cs)FooUnavailableMembers(cm)unavailableMembersWithInt:",
key.offset: 3939,
key.length: 39,
key.fully_annotated_decl: "<decl.function.method.class><syntaxtype.keyword>class</syntaxtype.keyword> <syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>withInt</decl.name>(<decl.var.parameter><decl.var.parameter.name>i</decl.var.parameter.name>: <decl.var.parameter.type><ref.struct usr=\"s:Vs5Int32\">Int32</ref.struct></decl.var.parameter.type></decl.var.parameter>) -&gt; <decl.function.returntype>Self!</decl.function.returntype></decl.function.method.class>",
key.fully_annotated_decl: "<decl.function.method.class><syntaxtype.keyword>class</syntaxtype.keyword> <syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>withInt</decl.name>(<decl.var.parameter><decl.var.parameter.name>i</decl.var.parameter.name>: <decl.var.parameter.type><ref.struct usr=\"s:Vs5Int32\">Int32</ref.struct></decl.var.parameter.type></decl.var.parameter>) -&gt; <decl.function.returntype><ref.class usr=\"c:objc(cs)FooUnavailableMembers\">Self</ref.class>!</decl.function.returntype></decl.function.method.class>",
key.entities: [
{
key.kind: source.lang.swift.decl.var.local,

View File

@@ -613,5 +613,5 @@ class C7 {
// CHECK76: source.lang.swift.decl.function.method.instance (169:8-169:11)
// CHECK76: (Self) -> () -> Self
// FIXME: should have tags and a USR
// CHECK76: <Declaration>func f() -&gt; Self</Declaration>
// CHECK76: <decl.function.returntype>Self</decl.function.returntype>
// CHECK76: <Declaration>func f() -&gt; <Type usr="s:C11cursor_info2C7">Self</Type></Declaration>
// CHECK76: <decl.function.returntype><ref.class usr="s:C11cursor_info2C7">Self</ref.class></decl.function.returntype>

View File

@@ -120,10 +120,10 @@ public:
EntitiesStack.back().SubEntities.push_back(std::move(Entity));
}
void printTypeRef(const TypeDecl *TD, Identifier Name) override {
void printTypeRef(Type T, const TypeDecl *TD, Identifier Name) override {
unsigned StartOffset = OS.tell();
References.emplace_back(TD, StartOffset, Name.str().size());
StreamPrinter::printTypeRef(TD, Name);
StreamPrinter::printTypeRef(T, TD, Name);
}
};

View File

@@ -183,10 +183,10 @@ public:
}
}
void printTypeRef(const TypeDecl *TD, Identifier Name) override {
void printTypeRef(Type T, const TypeDecl *TD, Identifier Name) override {
unsigned StartOffset = OS.tell();
Info.References.emplace_back(TD, StartOffset, Name.str().size());
StreamPrinter::printTypeRef(TD, Name);
StreamPrinter::printTypeRef(T, TD, Name);
}
void printModuleRef(ModuleEntity Mod, Identifier Name) override {

View File

@@ -48,11 +48,11 @@ public:
:XMLEscapingPrinter(OS) { }
private:
void printTypeRef(const TypeDecl *TD, Identifier Name) override {
void printTypeRef(Type T, const TypeDecl *TD, Identifier Name) override {
printXML("<Type usr=\"");
SwiftLangSupport::printUSR(TD, OS);
printXML("\">");
StreamPrinter::printTypeRef(TD, Name);
StreamPrinter::printTypeRef(T, TD, Name);
printXML("</Type>");
}
};
@@ -259,11 +259,11 @@ private:
closeTag(tag);
}
void printTypeRef(const TypeDecl *TD, Identifier name) override {
void printTypeRef(Type T, const TypeDecl *TD, Identifier name) override {
auto tag = getTagForDecl(TD, /*isRef=*/true);
openTagWithUSRForDecl(tag, TD);
insideRef = true;
XMLEscapingPrinter::printTypeRef(TD, name);
XMLEscapingPrinter::printTypeRef(T, TD, name);
insideRef = false;
closeTag(tag);
}

View File

@@ -1612,9 +1612,9 @@ public:
OS << "</synthesized>";
}
void printTypeRef(const TypeDecl *TD, Identifier Name) override {
void printTypeRef(Type T, const TypeDecl *TD, Identifier Name) override {
OS << "<ref:" << Decl::getKindName(TD->getKind()) << '>';
StreamPrinter::printTypeRef(TD, Name);
StreamPrinter::printTypeRef(T, TD, Name);
OS << "</ref>";
}
void printModuleRef(ModuleEntity Mod, Identifier Name) override {