Skip to content

Commit baa4123

Browse files
use getConformingProtocols when printing opaque generic types (#58991)
* use getConformingProtocols when printing opaque generic types rdar://93610106
1 parent 8506f71 commit baa4123

File tree

2 files changed

+141
-3
lines changed

2 files changed

+141
-3
lines changed

lib/AST/ASTPrinter.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
#include "clang/AST/DeclObjC.h"
5858
#include "clang/Basic/Module.h"
5959
#include "clang/Basic/SourceManager.h"
60+
#include "llvm/ADT/STLExtras.h"
6061
#include "llvm/ADT/StringSwitch.h"
6162
#include "llvm/Support/Compiler.h"
6263
#include "llvm/Support/ConvertUTF.h"
@@ -6397,10 +6398,16 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
63976398

63986399
// Print based on the type.
63996400
Printer << "some ";
6400-
if (auto inheritedType = decl->getInherited().front().getType())
6401-
inheritedType->print(Printer, Options);
6402-
else
6401+
if (!decl->getConformingProtocols().empty()) {
6402+
llvm::interleave(decl->getConformingProtocols(), Printer, [&](ProtocolDecl *proto){
6403+
if (auto printType = proto->getDeclaredType())
6404+
printType->print(Printer, Options);
6405+
else
6406+
Printer << proto->getNameStr();
6407+
}, " & ");
6408+
} else {
64036409
Printer << "Any";
6410+
}
64046411
return;
64056412
}
64066413

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift %s -module-name SomeProtocol -emit-module -emit-module-path %t/
3+
// RUN: %target-swift-symbolgraph-extract -module-name SomeProtocol -I %t -pretty-print -output-dir %t
4+
// RUN: %FileCheck %s --input-file %t/SomeProtocol.symbols.json
5+
// RUN: %FileCheck %s --input-file %t/SomeProtocol.symbols.json --check-prefix MULTI
6+
7+
// RUN: %empty-directory(%t)
8+
// RUN: %target-build-swift %s -module-name SomeProtocol -emit-module -emit-module-path %t/SomeProtocol.swiftmodule -emit-symbol-graph -emit-symbol-graph-dir %t/
9+
// RUN: %{python} -m json.tool %t/SomeProtocol.symbols.json %t/SomeProtocol.formatted.symbols.json
10+
// RUN: %FileCheck %s --input-file %t/SomeProtocol.formatted.symbols.json
11+
// RUN: %FileCheck %s --input-file %t/SomeProtocol.formatted.symbols.json --check-prefix MULTI
12+
13+
// Make sure that `some MyProtocol` parameters don't crash swift-symbolgraph-extract, and that it
14+
// properly renders `some MyProtocol & OtherProtocol` parameters with multiple protocols listed.
15+
16+
public protocol SomeProtocol {}
17+
18+
public func doSomething(with param: some SomeProtocol) {}
19+
20+
public protocol OtherProtocol {}
21+
22+
public func doSomethingElse(with param: some SomeProtocol & OtherProtocol) {}
23+
24+
// CHECK-LABEL: "precise": "s:12SomeProtocol11doSomething4withyx_tA2ARzlF",
25+
26+
// the functionSignature fragments come before the full fragments, so skip those
27+
// CHECK: "functionSignature": {
28+
// CHECK: "declarationFragments": [
29+
30+
// CHECK: "declarationFragments": [
31+
// CHECK-NEXT: {
32+
// CHECK-NEXT: "kind": "keyword",
33+
// CHECK-NEXT: "spelling": "func"
34+
// CHECK-NEXT: },
35+
// CHECK-NEXT: {
36+
// CHECK-NEXT: "kind": "text",
37+
// CHECK-NEXT: "spelling": " "
38+
// CHECK-NEXT: },
39+
// CHECK-NEXT: {
40+
// CHECK-NEXT: "kind": "identifier",
41+
// CHECK-NEXT: "spelling": "doSomething"
42+
// CHECK-NEXT: },
43+
// CHECK-NEXT: {
44+
// CHECK-NEXT: "kind": "text",
45+
// CHECK-NEXT: "spelling": "("
46+
// CHECK-NEXT: },
47+
// CHECK-NEXT: {
48+
// CHECK-NEXT: "kind": "externalParam",
49+
// CHECK-NEXT: "spelling": "with"
50+
// CHECK-NEXT: },
51+
// CHECK-NEXT: {
52+
// CHECK-NEXT: "kind": "text",
53+
// CHECK-NEXT: "spelling": " "
54+
// CHECK-NEXT: },
55+
// CHECK-NEXT: {
56+
// CHECK-NEXT: "kind": "internalParam",
57+
// CHECK-NEXT: "spelling": "param"
58+
// CHECK-NEXT: },
59+
// CHECK-NEXT: {
60+
// CHECK-NEXT: "kind": "text",
61+
// CHECK-NEXT: "spelling": ": some "
62+
// CHECK-NEXT: },
63+
// CHECK-NEXT: {
64+
// CHECK-NEXT: "kind": "typeIdentifier",
65+
// CHECK-NEXT: "spelling": "SomeProtocol",
66+
// CHECK-NEXT: "preciseIdentifier": "s:12SomeProtocolAAP"
67+
// CHECK-NEXT: },
68+
// CHECK-NEXT: {
69+
// CHECK-NEXT: "kind": "text",
70+
// CHECK-NEXT: "spelling": ")"
71+
// CHECK-NEXT: }
72+
// CHECK-NEXT: ],
73+
74+
// MULTI-LABEL: "precise": "s:12SomeProtocol15doSomethingElse4withyx_tAA05OtherB0RzA2ARzlF",
75+
76+
// the functionSignature fragments come before the full fragments, so skip those
77+
// MULTI: "functionSignature": {
78+
// MULTI: "declarationFragments": [
79+
80+
// MULTI: "declarationFragments": [
81+
// MULTI-NEXT: {
82+
// MULTI-NEXT: "kind": "keyword",
83+
// MULTI-NEXT: "spelling": "func"
84+
// MULTI-NEXT: },
85+
// MULTI-NEXT: {
86+
// MULTI-NEXT: "kind": "text",
87+
// MULTI-NEXT: "spelling": " "
88+
// MULTI-NEXT: },
89+
// MULTI-NEXT: {
90+
// MULTI-NEXT: "kind": "identifier",
91+
// MULTI-NEXT: "spelling": "doSomethingElse"
92+
// MULTI-NEXT: },
93+
// MULTI-NEXT: {
94+
// MULTI-NEXT: "kind": "text",
95+
// MULTI-NEXT: "spelling": "("
96+
// MULTI-NEXT: },
97+
// MULTI-NEXT: {
98+
// MULTI-NEXT: "kind": "externalParam",
99+
// MULTI-NEXT: "spelling": "with"
100+
// MULTI-NEXT: },
101+
// MULTI-NEXT: {
102+
// MULTI-NEXT: "kind": "text",
103+
// MULTI-NEXT: "spelling": " "
104+
// MULTI-NEXT: },
105+
// MULTI-NEXT: {
106+
// MULTI-NEXT: "kind": "internalParam",
107+
// MULTI-NEXT: "spelling": "param"
108+
// MULTI-NEXT: },
109+
// MULTI-NEXT: {
110+
// MULTI-NEXT: "kind": "text",
111+
// MULTI-NEXT: "spelling": ": some "
112+
// MULTI-NEXT: },
113+
// MULTI-NEXT: {
114+
// MULTI-NEXT: "kind": "typeIdentifier",
115+
// MULTI-NEXT: "spelling": "OtherProtocol",
116+
// MULTI-NEXT: "preciseIdentifier": "s:12SomeProtocol05OtherB0P"
117+
// MULTI-NEXT: },
118+
// MULTI-NEXT: {
119+
// MULTI-NEXT: "kind": "text",
120+
// MULTI-NEXT: "spelling": " & "
121+
// MULTI-NEXT: },
122+
// MULTI-NEXT: {
123+
// MULTI-NEXT: "kind": "typeIdentifier",
124+
// MULTI-NEXT: "spelling": "SomeProtocol",
125+
// MULTI-NEXT: "preciseIdentifier": "s:12SomeProtocolAAP"
126+
// MULTI-NEXT: },
127+
// MULTI-NEXT: {
128+
// MULTI-NEXT: "kind": "text",
129+
// MULTI-NEXT: "spelling": ")"
130+
// MULTI-NEXT: }
131+
// MULTI-NEXT: ],

0 commit comments

Comments
 (0)