Skip to content

Commit b0cdae3

Browse files
DougGregorbenlangmuir
authored andcommitted
[Index] Handle memberwise initializers with defaulted arguments.
1 parent 6c3cac7 commit b0cdae3

File tree

3 files changed

+33
-4
lines changed

3 files changed

+33
-4
lines changed

include/swift/Sema/IDETypeChecking.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,10 @@ namespace swift {
214214
/// \param DC The DeclContext from which the subscript is being referenced.
215215
Optional<Type> getRootTypeOfKeypathDynamicMember(SubscriptDecl *subscript,
216216
const DeclContext *DC);
217+
218+
/// Determine whether the given property is part of the memberwise initializer
219+
/// for a struct.
220+
bool isMemberwiseInitialized(VarDecl *var);
217221
}
218222

219223
#endif

lib/Index/Index.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -334,34 +334,47 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
334334
// get label locations
335335
auto *MemberwiseInit = DeclRef->getDecl();
336336
std::vector<SourceLoc> LabelLocs;
337+
ArrayRef<Identifier> Labels;
337338
auto NameLoc = DeclRef->getNameLoc();
338339
if (NameLoc.isCompound()) {
339340
size_t LabelIndex = 0;
340341
SourceLoc ArgLoc;
341342
while ((ArgLoc = NameLoc.getArgumentLabelLoc(LabelIndex++)).isValid()) {
342343
LabelLocs.push_back(ArgLoc);
343344
}
345+
Labels = MemberwiseInit->getFullName().getArgumentNames();
344346
} else if (auto *CallParent = dyn_cast_or_null<CallExpr>(getParentExpr())) {
345347
LabelLocs = CallParent->getArgumentLabelLocs();
348+
Labels = CallParent->getArgumentLabels();
346349
}
347350

348351
if (LabelLocs.empty())
349352
return;
350353

354+
assert(Labels.size() == LabelLocs.size());
355+
351356
// match labels to properties
352357
auto *TypeContext =
353358
MemberwiseInit->getDeclContext()->getSelfNominalTypeDecl();
354359
if (!TypeContext || !shouldIndex(TypeContext, false))
355360
return;
356361

357-
auto LabelIt = LabelLocs.begin();
362+
unsigned CurLabel = 0;
358363
for (auto Prop : TypeContext->getStoredProperties()) {
359-
if (Prop->getParentInitializer() && Prop->isLet())
364+
if (auto Original = Prop->getOriginalDelegatedProperty())
365+
Prop = Original;
366+
367+
if (!isMemberwiseInitialized(Prop))
368+
continue;
369+
370+
if (CurLabel == LabelLocs.size())
371+
break;
372+
373+
if (Labels[CurLabel] != Prop->getName())
360374
continue;
361375

362-
assert(LabelIt != LabelLocs.end());
363376
IndexSymbol Info;
364-
if (initIndexSymbol(Prop, *LabelIt++, /*IsRef=*/true, Info))
377+
if (initIndexSymbol(Prop, LabelLocs[CurLabel++], /*IsRef=*/true, Info))
365378
continue;
366379
if (startEntity(Prop, Info, /*IsRef=*/true))
367380
finishCurrentEntity();

test/Index/roles.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,3 +503,15 @@ _ = \StructWithKeypath.[0]
503503
// CHECK: [[@LINE-1]]:24 | instance-property/subscript/Swift | subscript(_:) | s:14swift_ide_test17StructWithKeypathVyS2icip | Ref,Read | rel: 0
504504
// CHECK: [[@LINE-2]]:24 | instance-method/acc-get/Swift | getter:subscript(_:) | s:14swift_ide_test17StructWithKeypathVyS2icig | Ref,Call,Impl | rel: 0
505505

506+
507+
struct BStruct {
508+
var x = 17
509+
var y = true
510+
var z = "hello"
511+
}
512+
513+
func useDefaultInits() {
514+
_ = BStruct(y: false)
515+
// CHECK: [[@LINE-1]]:15 | instance-property/Swift | y | s:14swift_ide_test7BStructV1ySbvp | Ref,RelCont
516+
// CHECK: [[@LINE-2]]:7 | constructor/Swift | init(x:y:z:) | s:14swift_ide_test7BStructV1x1y1zACSi_SbSStcfc | Ref,Call,RelCall,RelCont | rel: 1
517+
}

0 commit comments

Comments
 (0)