@@ -63,9 +63,10 @@ swift::ide::makeCodeCompletionMemoryBuffer(const llvm::MemoryBuffer *origBuf,
63
63
}
64
64
65
65
namespace {
66
- // / Returns index number of \p D in \p Decls . If it's not found, returns ~0.
66
+ // / Returns index number of \p D in \p Decls . If it's not found, returns
67
+ // / \c nullopt.
67
68
template <typename Range>
68
- unsigned findIndexInRange (Decl *D, const Range &Decls) {
69
+ std::optional< unsigned > findIndexInRange (Decl *D, const Range &Decls) {
69
70
unsigned N = 0 ;
70
71
for (auto I = Decls.begin (), E = Decls.end (); I != E; ++I) {
71
72
if ((*I)->isImplicit ())
@@ -74,7 +75,7 @@ unsigned findIndexInRange(Decl *D, const Range &Decls) {
74
75
return N;
75
76
++N;
76
77
}
77
- return ~ 0U ;
78
+ return std::nullopt ;
78
79
}
79
80
80
81
// / Return the element at \p N in \p Decls .
@@ -89,6 +90,23 @@ template <typename Range> Decl *getElementAt(const Range &Decls, unsigned N) {
89
90
return nullptr ;
90
91
}
91
92
93
+ static ArrayRef<AccessorDecl *>
94
+ getParsedAccessors (AbstractStorageDecl *ASD,
95
+ SmallVectorImpl<AccessorDecl *> &scratch) {
96
+ ASSERT (scratch.empty ());
97
+ ASD->visitParsedAccessors ([&](auto *AD) {
98
+ // Ignore accessors added by macro expansions.
99
+ // TODO: This ought to be the default behavior of `visitParsedAccessors`,
100
+ // we ought to have a different entrypoint for clients that care about
101
+ // the semantic set of "explicit" accessors.
102
+ if (AD->isInMacroExpansionInContext ())
103
+ return ;
104
+
105
+ scratch.push_back (AD);
106
+ });
107
+ return scratch;
108
+ }
109
+
92
110
// / Find the equivalent \c DeclContext with \p DC from \p SF AST.
93
111
// / This assumes the AST which contains \p DC has exact the same structure with
94
112
// / \p SF.
@@ -106,7 +124,7 @@ static DeclContext *getEquivalentDeclContextFromSourceFile(DeclContext *DC,
106
124
if (!D)
107
125
return nullptr ;
108
126
auto *parentDC = newDC->getParent ();
109
- unsigned N = ~ 0U ;
127
+ std::optional< unsigned > N ;
110
128
111
129
if (auto accessor = dyn_cast<AccessorDecl>(D)) {
112
130
// The AST for accessors is like:
@@ -116,16 +134,21 @@ static DeclContext *getEquivalentDeclContextFromSourceFile(DeclContext *DC,
116
134
auto *storage = accessor->getStorage ();
117
135
if (!storage)
118
136
return nullptr ;
119
- auto accessorN = findIndexInRange (accessor, storage->getAllAccessors ());
120
- IndexStack.push_back (accessorN);
137
+
138
+ SmallVector<AccessorDecl *, 4 > scratch;
139
+ auto accessorN =
140
+ findIndexInRange (accessor, getParsedAccessors (storage, scratch));
141
+ if (!accessorN)
142
+ return nullptr ;
143
+ IndexStack.push_back (*accessorN);
121
144
D = storage;
122
145
}
123
146
124
147
if (auto parentSF = dyn_cast<SourceFile>(parentDC)) {
125
148
N = findIndexInRange (D, parentSF->getTopLevelDecls ());
126
149
} else if (auto parentIDC = dyn_cast_or_null<IterableDeclContext>(
127
150
parentDC->getAsDecl ())) {
128
- N = findIndexInRange (D, parentIDC->getMembers ());
151
+ N = findIndexInRange (D, parentIDC->getParsedMembers ());
129
152
} else {
130
153
#ifndef NDEBUG
131
154
llvm_unreachable (" invalid DC kind for finding equivalent DC (indexpath)" );
@@ -134,11 +157,10 @@ static DeclContext *getEquivalentDeclContextFromSourceFile(DeclContext *DC,
134
157
}
135
158
136
159
// Not found in the decl context tree.
137
- if (N == ~ 0U ) {
160
+ if (!N)
138
161
return nullptr ;
139
- }
140
162
141
- IndexStack.push_back (N);
163
+ IndexStack.push_back (* N);
142
164
newDC = parentDC;
143
165
} while (!newDC->isModuleScopeContext ());
144
166
@@ -153,15 +175,16 @@ static DeclContext *getEquivalentDeclContextFromSourceFile(DeclContext *DC,
153
175
if (auto parentSF = dyn_cast<SourceFile>(newDC))
154
176
D = getElementAt (parentSF->getTopLevelDecls (), N);
155
177
else if (auto parentIDC = dyn_cast<IterableDeclContext>(newDC->getAsDecl ()))
156
- D = getElementAt (parentIDC->getMembers (), N);
178
+ D = getElementAt (parentIDC->getParsedMembers (), N);
157
179
else
158
180
llvm_unreachable (" invalid DC kind for finding equivalent DC (query)" );
159
181
160
182
if (auto storage = dyn_cast_or_null<AbstractStorageDecl>(D)) {
161
183
if (IndexStack.empty ())
162
184
return nullptr ;
163
185
auto accessorN = IndexStack.pop_back_val ();
164
- D = getElementAt (storage->getAllAccessors (), accessorN);
186
+ SmallVector<AccessorDecl *, 4 > scratch;
187
+ D = getElementAt (getParsedAccessors (storage, scratch), accessorN);
165
188
}
166
189
167
190
newDC = dyn_cast_or_null<DeclContext>(D);
@@ -356,7 +379,7 @@ bool IDEInspectionInstance::performCachedOperationIfPossible(
356
379
nullptr
357
380
}
358
381
);
359
- SM.recordSourceFile (newBufferID, AFD-> getParentSourceFile () );
382
+ SM.recordSourceFile (newBufferID, oldSF );
360
383
361
384
AFD->setBodyToBeReparsed (newBodyRange);
362
385
oldSF->clearScope ();
0 commit comments