Skip to content

Commit 0ef5a5a

Browse files
authored
Merge pull request #14866 from nkcsgexi/digester-default-args
2 parents f0549bb + 60bd6b9 commit 0ef5a5a

File tree

4 files changed

+120
-37
lines changed

4 files changed

+120
-37
lines changed

include/swift/IDE/DigesterEnums.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ KEY(declKind)
9090
KEY(ownership)
9191
KEY(superclassUsr)
9292
KEY(parentExtensionReqs)
93+
KEY(hasDefaultArg)
9394

9495
KNOWN_TYPE(Optional)
9596
KNOWN_TYPE(ImplicitlyUnwrappedOptional)

test/api-digester/Inputs/cake.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,7 @@ public extension C0 where T1 == S1, T2 == S1, T3 == S1 {
2121

2222
public extension C0 {
2323
func unconditionalFooExt() {}
24-
}
24+
}
25+
26+
public func foo1(_ a: Int = 1, b: S1) {}
27+
public func foo2(_ a: Int = #line, b: S1) {}

test/api-digester/Outputs/cake.json

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,60 @@
335335
]
336336
}
337337
]
338+
},
339+
{
340+
"kind": "Function",
341+
"name": "foo1",
342+
"printedName": "foo1(_:b:)",
343+
"declKind": "Func",
344+
"usr": "s:4cake4foo1_1bySi_AA2S1VtF",
345+
"location": "",
346+
"moduleName": "cake",
347+
"children": [
348+
{
349+
"kind": "TypeNominal",
350+
"name": "Void",
351+
"printedName": "()"
352+
},
353+
{
354+
"kind": "TypeNominal",
355+
"name": "Int",
356+
"printedName": "Int",
357+
"hasDefaultArg": true
358+
},
359+
{
360+
"kind": "TypeNominal",
361+
"name": "S1",
362+
"printedName": "S1"
363+
}
364+
]
365+
},
366+
{
367+
"kind": "Function",
368+
"name": "foo2",
369+
"printedName": "foo2(_:b:)",
370+
"declKind": "Func",
371+
"usr": "s:4cake4foo2_1bySi_AA2S1VtF",
372+
"location": "",
373+
"moduleName": "cake",
374+
"children": [
375+
{
376+
"kind": "TypeNominal",
377+
"name": "Void",
378+
"printedName": "()"
379+
},
380+
{
381+
"kind": "TypeNominal",
382+
"name": "Int",
383+
"printedName": "Int",
384+
"hasDefaultArg": true
385+
},
386+
{
387+
"kind": "TypeNominal",
388+
"name": "S1",
389+
"printedName": "S1"
390+
}
391+
]
338392
}
339393
]
340394
}

tools/swift-api-digester/swift-api-digester.cpp

Lines changed: 61 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,14 @@ class ParentExtensionInfo {
308308
ArrayRef<StringRef> getGenericRequirements() const { return Requirements; }
309309
};
310310

311+
/// The additional information we need to create a type node.
312+
struct TypeInitInfo {
313+
bool IsImplicitlyUnwrappedOptional = false;
314+
/// When this type node represents a function parameter, this boolean value
315+
/// indicates whether the parameter has default argument.
316+
bool hasDefaultArgument = false;
317+
};
318+
311319
struct SDKNodeInitInfo {
312320
SDKContext &Ctx;
313321
StringRef Name;
@@ -325,11 +333,11 @@ struct SDKNodeInitInfo {
325333
std::vector<TypeAttrKind> TypeAttrs;
326334
StringRef SuperclassUsr;
327335
ParentExtensionInfo *ExtInfo = nullptr;
336+
TypeInitInfo TypeInfo;
328337

329338
SDKNodeInitInfo(SDKContext &Ctx) : Ctx(Ctx) {}
330339
SDKNodeInitInfo(SDKContext &Ctx, ValueDecl *VD);
331-
SDKNodeInitInfo(SDKContext &Ctx, Type Ty,
332-
bool IsImplicitlyUnwrappedOptional =false);
340+
SDKNodeInitInfo(SDKContext &Ctx, Type Ty, TypeInitInfo Info = TypeInitInfo());
333341
SDKNode* createSDKNode(SDKNodeKind Kind);
334342
};
335343

@@ -465,17 +473,23 @@ NodePtr UpdatedNodesMap::findUpdateCounterpart(const SDKNode *Node) const {
465473

466474
class SDKNodeType : public SDKNode {
467475
std::vector<TypeAttrKind> TypeAttributes;
476+
bool HasDefaultArg;
468477

469478
protected:
470479
bool hasTypeAttribute(TypeAttrKind DAKind) const;
471480
SDKNodeType(SDKNodeInitInfo Info, SDKNodeKind Kind) : SDKNode(Info, Kind),
472-
TypeAttributes(Info.TypeAttrs) {}
481+
TypeAttributes(Info.TypeAttrs),
482+
HasDefaultArg(Info.TypeInfo.hasDefaultArgument) {}
473483

474484
public:
475485
KnownTypeKind getTypeKind() const;
476486
void addTypeAttribute(TypeAttrKind AttrKind);
477487
ArrayRef<TypeAttrKind> getTypeAttributes() const;
478488
SDKNodeDecl *getClosestParentDecl() const;
489+
490+
// When the type node represents a function parameter, this function returns
491+
// whether the parameter has a default value.
492+
bool hasDefaultArgument() const { return HasDefaultArg; }
479493
static bool classof(const SDKNode *N);
480494
};
481495

@@ -947,6 +961,9 @@ SDKNode* SDKNode::constructSDKNode(SDKContext &Ctx,
947961
case KeyKind::KK_mutating:
948962
Info.IsMutating = true;
949963
break;
964+
case KeyKind::KK_hasDefaultArg:
965+
Info.TypeInfo.hasDefaultArgument = true;
966+
break;
950967
case KeyKind::KK_static:
951968
Info.IsStatic = true;
952969
break;
@@ -1219,9 +1236,10 @@ static Ownership getOwnership(ValueDecl *VD) {
12191236
}
12201237

12211238
SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, Type Ty,
1222-
bool IsImplicitlyUnwrappedOptional) :
1223-
Ctx(Ctx), Name(getTypeName(Ctx, Ty, IsImplicitlyUnwrappedOptional)),
1224-
PrintedName(getPrintedName(Ctx, Ty, IsImplicitlyUnwrappedOptional)) {
1239+
TypeInitInfo TypeInfo) :
1240+
Ctx(Ctx), Name(getTypeName(Ctx, Ty, TypeInfo.IsImplicitlyUnwrappedOptional)),
1241+
PrintedName(getPrintedName(Ctx, Ty, TypeInfo.IsImplicitlyUnwrappedOptional)),
1242+
TypeInfo(TypeInfo) {
12251243
if (isFunctionTypeNoEscape(Ty))
12261244
TypeAttrs.push_back(TypeAttrKind::TAK_noescape);
12271245
}
@@ -1270,8 +1288,8 @@ case SDKNodeKind::X: \
12701288
// Recursively construct a node that represents a type, for instance,
12711289
// representing the return value type of a function decl.
12721290
static SDKNode *constructTypeNode(SDKContext &Ctx, Type T,
1273-
bool IsImplicitlyUnwrappedOptional =false) {
1274-
SDKNode* Root = SDKNodeInitInfo(Ctx, T, IsImplicitlyUnwrappedOptional)
1291+
TypeInitInfo InitInfo = TypeInitInfo()) {
1292+
SDKNode* Root = SDKNodeInitInfo(Ctx, T, InitInfo)
12751293
.createSDKNode(SDKNodeKind::TypeNominal);
12761294

12771295
if (auto NAT = dyn_cast<NameAliasType>(T.getPointer())) {
@@ -1313,42 +1331,46 @@ static SDKNode *constructTypeNode(SDKContext &Ctx, Type T,
13131331
return Root;
13141332
}
13151333

1334+
static std::vector<SDKNode*>
1335+
createParameterNodes(SDKContext &Ctx, ArrayRef<ParameterList*> AllParamLists) {
1336+
std::vector<SDKNode*> Result;
1337+
for (auto PL: AllParamLists) {
1338+
for (auto param: *PL) {
1339+
if (param->isSelfParameter())
1340+
continue;
1341+
TypeInitInfo TypeInfo;
1342+
TypeInfo.IsImplicitlyUnwrappedOptional = param->getAttrs().
1343+
hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
1344+
TypeInfo.hasDefaultArgument = param->getDefaultArgumentKind() !=
1345+
DefaultArgumentKind::None;
1346+
Result.push_back(constructTypeNode(Ctx, param->getInterfaceType(),
1347+
TypeInfo));
1348+
}
1349+
}
1350+
return Result;
1351+
}
1352+
13161353
// Construct a node for a function decl. The first child of the function decl
13171354
// is guaranteed to be the return value type of this function.
13181355
// We sometimes skip the first parameter because it can be metatype of dynamic
13191356
// this if the function is a member function.
13201357
static SDKNode *constructFunctionNode(SDKContext &Ctx, FuncDecl* FD,
13211358
SDKNodeKind Kind) {
13221359
auto Func = SDKNodeInitInfo(Ctx, FD).createSDKNode(Kind);
1323-
bool resultIsImplicitlyUnwrappedOptional = false;
1324-
if (FD->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
1325-
resultIsImplicitlyUnwrappedOptional = true;
1326-
Func->addChild(constructTypeNode(Ctx, FD->getResultInterfaceType(),
1327-
resultIsImplicitlyUnwrappedOptional));
1328-
for (auto *paramList : FD->getParameterLists()) {
1329-
for (auto param : *paramList) {
1330-
bool paramIsImplicitlyUnwrappedOptional = false;
1331-
if (param->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
1332-
paramIsImplicitlyUnwrappedOptional = true;
1333-
1334-
if (!param->isSelfParameter())
1335-
Func->addChild(constructTypeNode(Ctx, param->getInterfaceType(),
1336-
paramIsImplicitlyUnwrappedOptional));
1337-
}
1338-
}
1360+
TypeInitInfo TypeInfo;
1361+
TypeInfo.IsImplicitlyUnwrappedOptional = FD->getAttrs().
1362+
hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
1363+
Func->addChild(constructTypeNode(Ctx, FD->getResultInterfaceType(), TypeInfo));
1364+
for (auto *Node : createParameterNodes(Ctx, FD->getParameterLists()))
1365+
Func->addChild(Node);
13391366
return Func;
13401367
}
13411368

13421369
static SDKNode* constructInitNode(SDKContext &Ctx, ConstructorDecl *CD) {
13431370
auto Func = SDKNodeInitInfo(Ctx, CD).createSDKNode(SDKNodeKind::Constructor);
13441371
Func->addChild(constructTypeNode(Ctx, CD->getResultInterfaceType()));
1345-
for (auto *paramList : CD->getParameterLists()) {
1346-
for (auto param : *paramList)
1347-
Func->addChild(constructTypeNode(Ctx, param->getInterfaceType()));
1348-
}
1349-
1350-
// Always remove the first parameter in init.
1351-
Func->removeChild(Func->getChildBegin() + 1);
1372+
for (auto *Node : createParameterNodes(Ctx, CD->getParameterLists()))
1373+
Func->addChild(Node);
13521374
return Func;
13531375
}
13541376

@@ -1405,11 +1427,10 @@ static SDKNode *constructTypeDeclNode(SDKContext &Ctx, NominalTypeDecl *NTD) {
14051427

14061428
static SDKNode *constructVarNode(SDKContext &Ctx, ValueDecl *VD) {
14071429
auto Var = SDKNodeInitInfo(Ctx, VD).createSDKNode(SDKNodeKind::Var);
1408-
auto isImplicitlyUnwrappedOptional = false;
1409-
if (VD->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
1410-
isImplicitlyUnwrappedOptional = true;
1411-
Var->addChild(constructTypeNode(Ctx, VD->getInterfaceType(),
1412-
isImplicitlyUnwrappedOptional));
1430+
TypeInitInfo TypeInfo;
1431+
TypeInfo.IsImplicitlyUnwrappedOptional = VD->getAttrs().
1432+
hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
1433+
Var->addChild(constructTypeNode(Ctx, VD->getInterfaceType(), TypeInfo));
14131434
if (auto VAD = dyn_cast<AbstractStorageDecl>(VD)) {
14141435
if (auto Getter = VAD->getGetter())
14151436
Var->addChild(constructFunctionNode(Ctx, Getter, SDKNodeKind::Getter));
@@ -1650,6 +1671,10 @@ namespace swift {
16501671
if (!Attributes.empty())
16511672
out.mapRequired(getKeyContent(Ctx, KeyKind::KK_typeAttributes).data(),
16521673
Attributes);
1674+
if (bool HasDefault = T->hasDefaultArgument()) {
1675+
out.mapRequired(getKeyContent(Ctx, KeyKind::KK_hasDefaultArg).data(),
1676+
HasDefault);
1677+
}
16531678
}
16541679
if (!value->isLeaf()) {
16551680
ArrayRef<SDKNode *> Children = value->getChildren();

0 commit comments

Comments
 (0)