Skip to content

Commit 97e10e4

Browse files
authored
Merge pull request #2332 from swiftwasm/main
[pull] swiftwasm from main
2 parents 67d0ea5 + 632dfcf commit 97e10e4

30 files changed

+1844
-161
lines changed

include/swift/SymbolGraphGen/SymbolGraphGen.h

+12
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,26 @@
1414
#define SWIFT_SYMBOLGRAPHGEN_SYMBOLGRAPHGEN_H
1515

1616
#include "swift/AST/Module.h"
17+
#include "swift/AST/Type.h"
1718
#include "SymbolGraphOptions.h"
1819

1920
namespace swift {
21+
class ValueDecl;
22+
2023
namespace symbolgraphgen {
2124

2225
/// Emit a Symbol Graph JSON file for a module.
2326
int emitSymbolGraphForModule(ModuleDecl *M, const SymbolGraphOptions &Options);
2427

28+
/// Print a Symbol Graph containing a single node for the given decl.
29+
///
30+
/// \returns \c EXIT_SUCCESS if the kind of the provided node is supported and
31+
/// its Symbo lGraph was printed, or \c EXIT_FAILURE otherwise.
32+
int printSymbolGraphForDecl(const ValueDecl *D, Type BaseTy,
33+
bool InSynthesizedExtensions,
34+
const SymbolGraphOptions &Options,
35+
llvm::raw_ostream &OS);
36+
2537
} // end namespace symbolgraphgen
2638
} // end namespace swift
2739

lib/AST/ASTPrinter.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -750,8 +750,14 @@ class PrintAST : public ASTVisitor<PrintAST> {
750750
else if (auto *ED = dyn_cast<ExtensionDecl>(Current))
751751
subMap = CurrentType->getContextSubstitutionMap(M, ED);
752752
else {
753+
Decl *subTarget = Current;
754+
if (isa<ParamDecl>(Current)) {
755+
auto *DC = Current->getDeclContext();
756+
if (auto *FD = dyn_cast<AbstractFunctionDecl>(DC))
757+
subTarget = FD;
758+
}
753759
subMap = CurrentType->getMemberSubstitutionMap(
754-
M, cast<ValueDecl>(Current));
760+
M, cast<ValueDecl>(subTarget));
755761
}
756762

757763
T = T.subst(subMap, SubstFlags::DesugarMemberTypes);

lib/SymbolGraphGen/DeclarationFragmentPrinter.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,11 @@ void DeclarationFragmentPrinter::printTypeRef(Type T, const TypeDecl *RefTo,
140140
USR.clear();
141141

142142
auto ShouldLink = Name.str() != "Self";
143-
if (const auto *TD = T->getAnyNominal()) {
144-
if (SG->isImplicitlyPrivate(TD)) {
145-
ShouldLink = false;
143+
if (T) {
144+
if (const auto *TD = T->getAnyNominal()) {
145+
if (SG->isImplicitlyPrivate(TD)) {
146+
ShouldLink = false;
147+
}
146148
}
147149
}
148150

lib/SymbolGraphGen/Edge.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ void Edge::serialize(llvm::json::OStream &OS) const {
4747
ConformanceExtension->getGenericRequirements(),
4848
ConformanceExtension->getExtendedNominal()
4949
->getDeclContext()->getSelfNominalTypeDecl(),
50-
FilteredRequirements);
50+
FilteredRequirements);
5151
if (!FilteredRequirements.empty()) {
5252
OS.attributeArray("swiftConstraints", [&](){
5353
for (const auto &Req :

lib/SymbolGraphGen/JSON.cpp

+89-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
//===----------------------------------------------------------------------===//
1414

1515
#include "swift/AST/Decl.h"
16+
#include "swift/AST/GenericParamList.h"
1617
#include "swift/AST/Module.h"
18+
#include "swift/AST/Type.h"
1719
#include "JSON.h"
1820

1921
void swift::symbolgraphgen::serialize(const llvm::VersionTuple &VT,
@@ -115,10 +117,75 @@ void swift::symbolgraphgen::serialize(const swift::GenericTypeParamType *Param,
115117
});
116118
}
117119

120+
void
121+
swift::symbolgraphgen::filterGenericParams(
122+
TypeArrayView<GenericTypeParamType> GenericParams,
123+
SmallVectorImpl<const GenericTypeParamType*> &FilteredParams,
124+
SubstitutionMap SubMap) {
125+
126+
for (auto Param : GenericParams) {
127+
if (const auto *GPD = Param->getDecl()) {
128+
129+
// Ignore the implicit Self param
130+
if (GPD->isImplicit()) {
131+
if (!isa<ExtensionDecl>(GPD->getDeclContext()))
132+
continue;
133+
134+
// Extension decls (and their children) refer to implicit copies of the
135+
// explicit params of the nominal they extend. Don't filter those out.
136+
auto *ED = cast<ExtensionDecl>(GPD->getDeclContext());
137+
if (auto *NTD = ED->getExtendedNominal()) {
138+
if (auto *GPL = NTD->getGenericParams()) {
139+
auto ImplicitAndSameName = [&](GenericTypeParamDecl *NominalGPD) {
140+
return NominalGPD->isImplicit() &&
141+
GPD->getName() == NominalGPD->getName();
142+
};
143+
if (llvm::any_of(GPL->getParams(), ImplicitAndSameName))
144+
continue;
145+
}
146+
}
147+
}
148+
149+
// Ignore parameters that have been substituted.
150+
if (!SubMap.empty()) {
151+
Type SubTy = Type(Param).subst(SubMap);
152+
if (!SubTy->hasError() && SubTy.getPointer() != Param) {
153+
if (!SubTy->is<ArchetypeType>()) {
154+
continue;
155+
}
156+
auto AT = SubTy->castTo<ArchetypeType>();
157+
if (!AT->getInterfaceType()->isEqual(Param)) {
158+
continue;
159+
}
160+
}
161+
}
162+
163+
FilteredParams.push_back(Param);
164+
}
165+
}
166+
}
167+
168+
static bool containsParams(swift::Type Ty, llvm::ArrayRef<const swift::GenericTypeParamType*> Others) {
169+
return Ty.findIf([&](swift::Type T) -> bool {
170+
if (auto AT = T->getAs<swift::ArchetypeType>()) {
171+
T = AT->getInterfaceType();
172+
}
173+
174+
for (auto *Param: Others) {
175+
if (T->isEqual(const_cast<swift::GenericTypeParamType*>(Param)))
176+
return true;
177+
}
178+
return false;
179+
});
180+
}
181+
118182
void swift::symbolgraphgen::filterGenericRequirements(
119183
ArrayRef<Requirement> Requirements,
120184
const NominalTypeDecl *Self,
121-
SmallVectorImpl<Requirement> &FilteredRequirements) {
185+
SmallVectorImpl<Requirement> &FilteredRequirements,
186+
SubstitutionMap SubMap,
187+
ArrayRef<const GenericTypeParamType *> FilteredParams) {
188+
122189
for (const auto &Req : Requirements) {
123190
if (Req.getKind() == RequirementKind::Layout) {
124191
continue;
@@ -130,10 +197,29 @@ void swift::symbolgraphgen::filterGenericRequirements(
130197
if (Req.getSecondType()->getAnyNominal() == Self) {
131198
continue;
132199
}
133-
FilteredRequirements.push_back(Req);
200+
201+
// Ignore requirements that don't involve the filtered set of generic
202+
// parameters after substitution.
203+
if (!SubMap.empty()) {
204+
Type SubFirst = Req.getFirstType().subst(SubMap);
205+
if (SubFirst->hasError())
206+
SubFirst = Req.getFirstType();
207+
Type SubSecond = Req.getSecondType().subst(SubMap);
208+
if (SubSecond->hasError())
209+
SubSecond = Req.getSecondType();
210+
211+
if (!containsParams(SubFirst, FilteredParams) &&
212+
!containsParams(SubSecond, FilteredParams))
213+
continue;
214+
215+
// Use the same requirement kind with the substituted types.
216+
FilteredRequirements.emplace_back(Req.getKind(), SubFirst, SubSecond);
217+
} else {
218+
// Use the original requirement.
219+
FilteredRequirements.push_back(Req);
220+
}
134221
}
135222
}
136-
137223
void
138224
swift::symbolgraphgen::filterGenericRequirements(const ExtensionDecl *Extension,
139225
SmallVectorImpl<Requirement> &FilteredRequirements) {

lib/SymbolGraphGen/JSON.h

+11-6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/Support/JSON.h"
2020
#include "llvm/Support/VersionTuple.h"
2121
#include "swift/AST/GenericSignature.h"
22+
#include "swift/AST/SubstitutionMap.h"
2223
#include "swift/AST/Type.h"
2324

2425
namespace swift {
@@ -41,16 +42,20 @@ void serialize(const llvm::VersionTuple &VT, llvm::json::OStream &OS);
4142
void serialize(const llvm::Triple &T, llvm::json::OStream &OS);
4243
void serialize(const ExtensionDecl *Extension, llvm::json::OStream &OS);
4344
void serialize(const Requirement &Req, llvm::json::OStream &OS);
44-
void serialize(const swift::GenericTypeParamType *Param,
45-
llvm::json::OStream &OS);
45+
void serialize(const swift::GenericTypeParamType *Param, llvm::json::OStream &OS);
4646

47+
void filterGenericParams(
48+
TypeArrayView<GenericTypeParamType> GenericParams,
49+
SmallVectorImpl<const GenericTypeParamType*> &FilteredParams,
50+
SubstitutionMap SubMap = {});
4751

4852
/// Filter generic requirements on an extension that aren't relevant
4953
/// for documentation.
50-
void
51-
filterGenericRequirements(ArrayRef<Requirement> Requirements,
52-
const NominalTypeDecl *Self,
53-
SmallVectorImpl<Requirement> &FilteredRequirements);
54+
void filterGenericRequirements(
55+
ArrayRef<Requirement> Requirements, const NominalTypeDecl *Self,
56+
SmallVectorImpl<Requirement> &FilteredRequirements,
57+
SubstitutionMap SubMap = {},
58+
ArrayRef<const GenericTypeParamType *> FilteredParams = {});
5459

5560
/// Filter generic requirements on an extension that aren't relevant
5661
/// for documentation.

lib/SymbolGraphGen/Symbol.cpp

+71-15
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,15 @@ using namespace swift;
2626
using namespace symbolgraphgen;
2727

2828
Symbol::Symbol(SymbolGraph *Graph, const ValueDecl *VD,
29-
const NominalTypeDecl *SynthesizedBaseTypeDecl)
29+
const NominalTypeDecl *SynthesizedBaseTypeDecl,
30+
Type BaseType)
3031
: Graph(Graph),
3132
VD(VD),
32-
SynthesizedBaseTypeDecl(SynthesizedBaseTypeDecl) {}
33+
BaseType(BaseType),
34+
SynthesizedBaseTypeDecl(SynthesizedBaseTypeDecl) {
35+
if (!BaseType && SynthesizedBaseTypeDecl)
36+
BaseType = SynthesizedBaseTypeDecl->getDeclaredInterfaceType();
37+
}
3338

3439
void Symbol::serializeKind(StringRef Identifier, StringRef DisplayName,
3540
llvm::json::OStream &OS) const {
@@ -40,6 +45,9 @@ void Symbol::serializeKind(StringRef Identifier, StringRef DisplayName,
4045
}
4146

4247
void Symbol::serializeKind(llvm::json::OStream &OS) const {
48+
// supportsKind and serializeKind must agree.
49+
assert(Symbol::supportsKind(VD->getKind()) && "unsupported decl kind");
50+
4351
AttributeRAII A("kind", OS);
4452
switch (VD->getKind()) {
4553
case swift::DeclKind::Class:
@@ -244,7 +252,8 @@ void Symbol::serializeFunctionSignature(llvm::json::OStream &OS) const {
244252
}
245253
Graph->serializeDeclarationFragments("declarationFragments",
246254
Symbol(Graph, Param,
247-
nullptr), OS);
255+
getSynthesizedBaseTypeDecl(),
256+
getBaseType()), OS);
248257
}); // end parameter object
249258
}
250259
}); // end parameters:
@@ -253,35 +262,62 @@ void Symbol::serializeFunctionSignature(llvm::json::OStream &OS) const {
253262

254263
// Returns
255264
if (const auto ReturnType = FD->getResultInterfaceType()) {
256-
Graph->serializeDeclarationFragments("returns", ReturnType, OS);
265+
Graph->serializeDeclarationFragments("returns", ReturnType, BaseType,
266+
OS);
257267
}
258268
});
259269
}
260270
}
261271

272+
static SubstitutionMap getSubMapForDecl(const ValueDecl *D, Type BaseType) {
273+
if (!BaseType || BaseType->isExistentialType())
274+
return {};
275+
276+
// Map from the base type into the this declaration's innermost type context,
277+
// or if we're dealing with an extention rather than a member, into its
278+
// extended nominal (the extension's own requirements shouldn't be considered
279+
// in the substitution).
280+
swift::DeclContext *DC;
281+
if (isa<swift::ExtensionDecl>(D))
282+
DC = cast<swift::ExtensionDecl>(D)->getExtendedNominal();
283+
else
284+
DC = D->getInnermostDeclContext()->getInnermostTypeContext();
285+
286+
swift::ModuleDecl *M = DC->getParentModule();
287+
if (isa<swift::NominalTypeDecl>(D) || isa<swift::ExtensionDecl>(D)) {
288+
return BaseType->getContextSubstitutionMap(M, DC);
289+
}
290+
291+
const swift::ValueDecl *SubTarget = D;
292+
if (isa<swift::ParamDecl>(D)) {
293+
auto *DC = D->getDeclContext();
294+
if (auto *FD = dyn_cast<swift::AbstractFunctionDecl>(DC))
295+
SubTarget = FD;
296+
}
297+
return BaseType->getMemberSubstitutionMap(M, SubTarget);
298+
}
299+
262300
void Symbol::serializeSwiftGenericMixin(llvm::json::OStream &OS) const {
301+
302+
SubstitutionMap SubMap;
303+
if (BaseType)
304+
SubMap = getSubMapForDecl(VD, BaseType);
305+
263306
if (const auto *GC = VD->getAsGenericContext()) {
264307
if (const auto Generics = GC->getGenericSignature()) {
265308

266309
SmallVector<const GenericTypeParamType *, 4> FilteredParams;
267310
SmallVector<Requirement, 4> FilteredRequirements;
268-
for (const auto Param : Generics->getGenericParams()) {
269-
if (const auto *D = Param->getDecl()) {
270-
if (D->isImplicit()) {
271-
continue;
272-
}
273-
FilteredParams.push_back(Param);
274-
}
275-
}
311+
filterGenericParams(Generics->getGenericParams(), FilteredParams,
312+
SubMap);
276313

277314
const auto *Self = dyn_cast<NominalTypeDecl>(VD);
278315
if (!Self) {
279316
Self = VD->getDeclContext()->getSelfNominalTypeDecl();
280317
}
281318

282-
filterGenericRequirements(Generics->getRequirements(),
283-
Self,
284-
FilteredRequirements);
319+
filterGenericRequirements(Generics->getRequirements(), Self,
320+
FilteredRequirements, SubMap, FilteredParams);
285321

286322
if (FilteredParams.empty() && FilteredRequirements.empty()) {
287323
return;
@@ -503,3 +539,23 @@ void Symbol::getUSR(SmallVectorImpl<char> &USR) const {
503539
ide::printDeclUSR(SynthesizedBaseTypeDecl, OS);
504540
}
505541
}
542+
543+
bool Symbol::supportsKind(DeclKind Kind) {
544+
switch (Kind) {
545+
case DeclKind::Class: LLVM_FALLTHROUGH;
546+
case DeclKind::Struct: LLVM_FALLTHROUGH;
547+
case DeclKind::Enum: LLVM_FALLTHROUGH;
548+
case DeclKind::EnumElement: LLVM_FALLTHROUGH;
549+
case DeclKind::Protocol: LLVM_FALLTHROUGH;
550+
case DeclKind::Constructor: LLVM_FALLTHROUGH;
551+
case DeclKind::Destructor: LLVM_FALLTHROUGH;
552+
case DeclKind::Func: LLVM_FALLTHROUGH;
553+
case DeclKind::Var: LLVM_FALLTHROUGH;
554+
case DeclKind::Subscript: LLVM_FALLTHROUGH;
555+
case DeclKind::TypeAlias: LLVM_FALLTHROUGH;
556+
case DeclKind::AssociatedType:
557+
return true;
558+
default:
559+
return false;
560+
}
561+
}

0 commit comments

Comments
 (0)