Skip to content

Commit 01aa746

Browse files
authored
Merge pull request #82568 from hamishknight/mac-n-cheese
2 parents c0c7bf3 + 8d1c1bf commit 01aa746

File tree

2 files changed

+37
-14
lines changed

2 files changed

+37
-14
lines changed

lib/IDETool/IDEInspectionInstance.cpp

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,10 @@ swift::ide::makeCodeCompletionMemoryBuffer(const llvm::MemoryBuffer *origBuf,
6363
}
6464

6565
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.
6768
template <typename Range>
68-
unsigned findIndexInRange(Decl *D, const Range &Decls) {
69+
std::optional<unsigned> findIndexInRange(Decl *D, const Range &Decls) {
6970
unsigned N = 0;
7071
for (auto I = Decls.begin(), E = Decls.end(); I != E; ++I) {
7172
if ((*I)->isImplicit())
@@ -74,7 +75,7 @@ unsigned findIndexInRange(Decl *D, const Range &Decls) {
7475
return N;
7576
++N;
7677
}
77-
return ~0U;
78+
return std::nullopt;
7879
}
7980

8081
/// Return the element at \p N in \p Decls .
@@ -89,6 +90,23 @@ template <typename Range> Decl *getElementAt(const Range &Decls, unsigned N) {
8990
return nullptr;
9091
}
9192

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+
92110
/// Find the equivalent \c DeclContext with \p DC from \p SF AST.
93111
/// This assumes the AST which contains \p DC has exact the same structure with
94112
/// \p SF.
@@ -106,7 +124,7 @@ static DeclContext *getEquivalentDeclContextFromSourceFile(DeclContext *DC,
106124
if (!D)
107125
return nullptr;
108126
auto *parentDC = newDC->getParent();
109-
unsigned N = ~0U;
127+
std::optional<unsigned> N;
110128

111129
if (auto accessor = dyn_cast<AccessorDecl>(D)) {
112130
// The AST for accessors is like:
@@ -116,16 +134,21 @@ static DeclContext *getEquivalentDeclContextFromSourceFile(DeclContext *DC,
116134
auto *storage = accessor->getStorage();
117135
if (!storage)
118136
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);
121144
D = storage;
122145
}
123146

124147
if (auto parentSF = dyn_cast<SourceFile>(parentDC)) {
125148
N = findIndexInRange(D, parentSF->getTopLevelDecls());
126149
} else if (auto parentIDC = dyn_cast_or_null<IterableDeclContext>(
127150
parentDC->getAsDecl())) {
128-
N = findIndexInRange(D, parentIDC->getMembers());
151+
N = findIndexInRange(D, parentIDC->getParsedMembers());
129152
} else {
130153
#ifndef NDEBUG
131154
llvm_unreachable("invalid DC kind for finding equivalent DC (indexpath)");
@@ -134,11 +157,10 @@ static DeclContext *getEquivalentDeclContextFromSourceFile(DeclContext *DC,
134157
}
135158

136159
// Not found in the decl context tree.
137-
if (N == ~0U) {
160+
if (!N)
138161
return nullptr;
139-
}
140162

141-
IndexStack.push_back(N);
163+
IndexStack.push_back(*N);
142164
newDC = parentDC;
143165
} while (!newDC->isModuleScopeContext());
144166

@@ -153,15 +175,16 @@ static DeclContext *getEquivalentDeclContextFromSourceFile(DeclContext *DC,
153175
if (auto parentSF = dyn_cast<SourceFile>(newDC))
154176
D = getElementAt(parentSF->getTopLevelDecls(), N);
155177
else if (auto parentIDC = dyn_cast<IterableDeclContext>(newDC->getAsDecl()))
156-
D = getElementAt(parentIDC->getMembers(), N);
178+
D = getElementAt(parentIDC->getParsedMembers(), N);
157179
else
158180
llvm_unreachable("invalid DC kind for finding equivalent DC (query)");
159181

160182
if (auto storage = dyn_cast_or_null<AbstractStorageDecl>(D)) {
161183
if (IndexStack.empty())
162184
return nullptr;
163185
auto accessorN = IndexStack.pop_back_val();
164-
D = getElementAt(storage->getAllAccessors(), accessorN);
186+
SmallVector<AccessorDecl *, 4> scratch;
187+
D = getElementAt(getParsedAccessors(storage, scratch), accessorN);
165188
}
166189

167190
newDC = dyn_cast_or_null<DeclContext>(D);
@@ -356,7 +379,7 @@ bool IDEInspectionInstance::performCachedOperationIfPossible(
356379
nullptr
357380
}
358381
);
359-
SM.recordSourceFile(newBufferID, AFD->getParentSourceFile());
382+
SM.recordSourceFile(newBufferID, oldSF);
360383

361384
AFD->setBodyToBeReparsed(newBodyRange);
362385
oldSF->clearScope();

lib/Parse/Parser.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ bool IDEInspectionSecondPassRequest::evaluate(
116116
IDEInspectionCallbacksFactory *Factory) const {
117117
// If we didn't find the code completion token, bail.
118118
auto *parserState = SF->getDelayedParserState();
119-
if (!parserState->hasIDEInspectionDelayedDeclState())
119+
if (!parserState || !parserState->hasIDEInspectionDelayedDeclState())
120120
return true;
121121

122122
// Decrement the closure discriminator index by one so a top-level closure

0 commit comments

Comments
 (0)