Skip to content

Commit a951a4f

Browse files
authored
Merge pull request swiftlang#26978 from apple/revert-26972-request-function-body-parse
Revert "Add a request to lazily parse function bodies."
2 parents bcf93c6 + 903eeb2 commit a951a4f

15 files changed

+93
-161
lines changed

include/swift/AST/Decl.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5594,8 +5594,6 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
55945594
SourceRange BodyRange;
55955595
};
55965596

5597-
friend class ParseAbstractFunctionBodyRequest;
5598-
55995597
CaptureInfo Captures;
56005598

56015599
/// Location of the 'throws' token.

include/swift/AST/ParseRequests.h

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -48,28 +48,6 @@ class ParseMembersRequest :
4848
bool isCached() const { return true; }
4949
};
5050

51-
/// Parse the body of a function, initializer, or deinitializer.
52-
class ParseAbstractFunctionBodyRequest :
53-
public SimpleRequest<ParseAbstractFunctionBodyRequest,
54-
BraceStmt *(AbstractFunctionDecl *),
55-
CacheKind::SeparatelyCached>
56-
{
57-
public:
58-
using SimpleRequest::SimpleRequest;
59-
60-
private:
61-
friend SimpleRequest;
62-
63-
// Evaluation.
64-
BraceStmt *evaluate(Evaluator &evaluator, AbstractFunctionDecl *afd) const;
65-
66-
public:
67-
// Caching
68-
bool isCached() const { return true; }
69-
Optional<BraceStmt *> getCachedResult() const;
70-
void cacheResult(BraceStmt *value) const;
71-
};
72-
7351
/// The zone number for the parser.
7452
#define SWIFT_TYPEID_ZONE Parse
7553
#define SWIFT_TYPEID_HEADER "swift/AST/ParseTypeIDZone.def"

include/swift/AST/ParseTypeIDZone.def

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,3 @@
1515
//===----------------------------------------------------------------------===//
1616

1717
SWIFT_REQUEST(Parse, ParseMembersRequest)
18-
SWIFT_REQUEST(Parse, ParseAbstractFunctionBodyRequest)

include/swift/Parse/Parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1124,7 +1124,7 @@ class Parser {
11241124
DeclAttributes &Attributes,
11251125
bool HasFuncKeyword = true);
11261126
void parseAbstractFunctionBody(AbstractFunctionDecl *AFD);
1127-
BraceStmt *parseAbstractFunctionBodyDelayed(AbstractFunctionDecl *AFD);
1127+
bool parseAbstractFunctionBodyDelayed(AbstractFunctionDecl *AFD);
11281128
ParserResult<ProtocolDecl> parseDeclProtocol(ParseDeclOptions Flags,
11291129
DeclAttributes &Attributes);
11301130

include/swift/Parse/PersistentParserState.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,14 @@ class PersistentParserState {
109109
PersistentParserState(ASTContext &ctx) : PersistentParserState() { }
110110
~PersistentParserState();
111111

112+
void delayFunctionBodyParsing(AbstractFunctionDecl *AFD,
113+
SourceRange BodyRange,
114+
SourceLoc PreviousLoc);
115+
std::unique_ptr<FunctionBodyState>
116+
takeFunctionBodyState(AbstractFunctionDecl *AFD);
117+
118+
bool hasFunctionBodyState(AbstractFunctionDecl *AFD);
119+
112120
void delayDecl(DelayedDeclKind Kind, unsigned Flags,
113121
DeclContext *ParentContext,
114122
SourceRange BodyRange, SourceLoc PreviousLoc);

lib/AST/ASTPrinter.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,9 @@ PrintOptions PrintOptions::printParseableInterfaceFile(bool preferTypeRepr) {
118118

119119
result.FunctionBody = [](const ValueDecl *decl, ASTPrinter &printer) {
120120
auto AFD = dyn_cast<AbstractFunctionDecl>(decl);
121-
if (!AFD)
122-
return;
121+
if (!AFD || !AFD->hasInlinableBodyText()) return;
123122
if (AFD->getResilienceExpansion() != ResilienceExpansion::Minimal)
124123
return;
125-
if (!AFD->hasInlinableBodyText())
126-
return;
127-
128124
SmallString<128> scratch;
129125
printer << " " << AFD->getInlinableBodyText(scratch);
130126
};

lib/AST/ASTScopeCreation.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,7 +1272,7 @@ void AbstractFunctionDeclScope::expandAScopeThatDoesNotCreateANewInsertionPoint(
12721272
// Create scope for the body.
12731273
// We create body scopes when there is no body for source kit to complete
12741274
// erroneous code in bodies. But don't let compiler synthesize one.
1275-
if (decl->getBodySourceRange().isValid() && decl->getBody(false)) {
1275+
if (decl->getBody(false) && decl->getBodySourceRange().isValid()) {
12761276
if (AbstractFunctionBodyScope::isAMethod(decl))
12771277
scopeCreator.constructExpandAndInsertUncheckable<MethodBodyScope>(leaf,
12781278
decl);
@@ -1771,10 +1771,10 @@ bool IterableTypeScope::isBodyCurrent() const {
17711771
}
17721772

17731773
void AbstractFunctionBodyScope::beCurrent() {
1774-
bodyWhenLastExpanded = decl->getBody(false);
1774+
bodyWhenLastExpanded = decl->getBody();
17751775
}
17761776
bool AbstractFunctionBodyScope::isCurrent() const {
1777-
return bodyWhenLastExpanded == decl->getBody(false);
1777+
return bodyWhenLastExpanded == decl->getBody();
17781778
;
17791779
}
17801780

lib/AST/Decl.cpp

Lines changed: 28 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
#include "swift/AST/NameLookup.h"
3434
#include "swift/AST/NameLookupRequests.h"
3535
#include "swift/AST/ParameterList.h"
36-
#include "swift/AST/ParseRequests.h"
3736
#include "swift/AST/Pattern.h"
3837
#include "swift/AST/PropertyWrappers.h"
3938
#include "swift/AST/ProtocolConformance.h"
@@ -6308,22 +6307,37 @@ bool AbstractFunctionDecl::argumentNameIsAPIByDefault() const {
63086307
}
63096308

63106309
BraceStmt *AbstractFunctionDecl::getBody(bool canSynthesize) const {
6311-
if ((getBodyKind() == BodyKind::Synthesize ||
6312-
getBodyKind() == BodyKind::Unparsed) &&
6313-
!canSynthesize)
6310+
switch (getBodyKind()) {
6311+
case BodyKind::Deserialized:
6312+
case BodyKind::MemberwiseInitializer:
6313+
case BodyKind::None:
6314+
case BodyKind::Skipped:
63146315
return nullptr;
63156316

6316-
ASTContext &ctx = getASTContext();
6317+
case BodyKind::Parsed:
6318+
case BodyKind::TypeChecked:
6319+
return Body;
63176320

6318-
// Don't allow getBody() to trigger parsing of an unparsed body containing the
6319-
// code completion location.
6320-
if (getBodyKind() == BodyKind::Unparsed &&
6321-
ctx.SourceMgr.rangeContainsCodeCompletionLoc(getBodySourceRange())) {
6321+
case BodyKind::Unparsed:
6322+
// FIXME: Go parse now!
63226323
return nullptr;
6323-
}
63246324

6325-
auto mutableThis = const_cast<AbstractFunctionDecl *>(this);
6326-
return evaluateOrDefault(ctx.evaluator, ParseAbstractFunctionBodyRequest{mutableThis}, nullptr);
6325+
case BodyKind::Synthesize: {
6326+
if (!canSynthesize)
6327+
return nullptr;
6328+
6329+
const_cast<AbstractFunctionDecl *>(this)->setBodyKind(BodyKind::None);
6330+
BraceStmt *body;
6331+
bool isTypeChecked;
6332+
6333+
auto mutableThis = const_cast<AbstractFunctionDecl *>(this);
6334+
std::tie(body, isTypeChecked) = (Synthesizer.Fn)(
6335+
mutableThis, Synthesizer.Context);
6336+
mutableThis->setBody(
6337+
body, isTypeChecked ? BodyKind::TypeChecked : BodyKind::Parsed);
6338+
return body;
6339+
}
6340+
}
63276341
}
63286342

63296343
SourceRange AbstractFunctionDecl::getBodySourceRange() const {
@@ -6790,15 +6804,11 @@ bool AbstractFunctionDecl::hasInlinableBodyText() const {
67906804
switch (getBodyKind()) {
67916805
case BodyKind::Deserialized:
67926806
return true;
6793-
6794-
case BodyKind::Unparsed:
67956807
case BodyKind::Parsed:
67966808
case BodyKind::TypeChecked:
6797-
if (auto body = getBody())
6798-
return !body->isImplicit();
6799-
return false;
6800-
6809+
return getBody() && !getBody()->isImplicit();
68016810
case BodyKind::None:
6811+
case BodyKind::Unparsed:
68026812
case BodyKind::Synthesize:
68036813
case BodyKind::Skipped:
68046814
case BodyKind::MemberwiseInitializer:
@@ -7666,49 +7676,3 @@ SourceLoc swift::extractNearestSourceLoc(const Decl *decl) {
76667676

76677677
return extractNearestSourceLoc(decl->getDeclContext());
76687678
}
7669-
7670-
Optional<BraceStmt *>
7671-
ParseAbstractFunctionBodyRequest::getCachedResult() const {
7672-
using BodyKind = AbstractFunctionDecl::BodyKind;
7673-
auto afd = std::get<0>(getStorage());
7674-
switch (afd->getBodyKind()) {
7675-
case BodyKind::Deserialized:
7676-
case BodyKind::MemberwiseInitializer:
7677-
case BodyKind::None:
7678-
case BodyKind::Skipped:
7679-
return nullptr;
7680-
7681-
case BodyKind::TypeChecked:
7682-
case BodyKind::Parsed:
7683-
return afd->Body;
7684-
7685-
case BodyKind::Synthesize:
7686-
case BodyKind::Unparsed:
7687-
return None;
7688-
}
7689-
}
7690-
7691-
void ParseAbstractFunctionBodyRequest::cacheResult(BraceStmt *value) const {
7692-
using BodyKind = AbstractFunctionDecl::BodyKind;
7693-
auto afd = std::get<0>(getStorage());
7694-
switch (afd->getBodyKind()) {
7695-
case BodyKind::Deserialized:
7696-
case BodyKind::MemberwiseInitializer:
7697-
case BodyKind::None:
7698-
case BodyKind::Skipped:
7699-
// The body is always empty, so don't cache anything.
7700-
assert(value == nullptr);
7701-
return;
7702-
7703-
case BodyKind::Parsed:
7704-
case BodyKind::TypeChecked:
7705-
afd->Body = value;
7706-
return;
7707-
7708-
case BodyKind::Synthesize:
7709-
case BodyKind::Unparsed:
7710-
llvm_unreachable("evaluate() did not set the body kind");
7711-
return;
7712-
}
7713-
7714-
}

lib/AST/UnqualifiedLookup.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ void UnqualifiedLookupFactory::lookupNamesIntroducedByFunctionDecl(
663663
const bool isCascadingUse =
664664
AFD->isCascadingContextForLookup(false) &&
665665
(isCascadingUseArg.getValueOr(
666-
Loc.isInvalid() || AFD->getBodySourceRange().isInvalid() ||
666+
Loc.isInvalid() || !AFD->getBody() ||
667667
!SM.rangeContainsTokenLoc(AFD->getBodySourceRange(), Loc)));
668668

669669
if (AFD->getDeclContext()->isTypeContext())
@@ -814,9 +814,7 @@ void UnqualifiedLookupFactory::lookForLocalVariablesIn(
814814
// FIXME: when we can parse and typecheck the function body partially
815815
// for code completion, AFD->getBody() check can be removed.
816816

817-
if (Loc.isInvalid() || AFD->getBodySourceRange().isInvalid() ||
818-
!SM.rangeContainsTokenLoc(AFD->getBodySourceRange(), Loc) ||
819-
!AFD->getBody()) {
817+
if (Loc.isInvalid() || !AFD->getBody()) {
820818
return;
821819
}
822820

lib/Parse/ParseDecl.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5390,6 +5390,8 @@ void Parser::consumeAbstractFunctionBody(AbstractFunctionDecl *AFD,
53905390
if (DelayedParseCB &&
53915391
DelayedParseCB->shouldDelayFunctionBodyParsing(*this, AFD, Attrs,
53925392
BodyRange)) {
5393+
State->delayFunctionBodyParsing(AFD, BodyRange,
5394+
BeginParserPosition.PreviousLoc);
53935395
AFD->setBodyDelayed(BodyRange);
53945396
} else {
53955397
AFD->setBodySkipped(BodyRange);
@@ -5670,12 +5672,15 @@ void Parser::parseAbstractFunctionBody(AbstractFunctionDecl *AFD) {
56705672
}
56715673
}
56725674

5673-
BraceStmt *Parser::parseAbstractFunctionBodyDelayed(AbstractFunctionDecl *AFD) {
5675+
bool Parser::parseAbstractFunctionBodyDelayed(AbstractFunctionDecl *AFD) {
5676+
assert(!AFD->getBody() && "function should not have a parsed body");
56745677
assert(AFD->getBodyKind() == AbstractFunctionDecl::BodyKind::Unparsed &&
56755678
"function body should be delayed");
56765679

5677-
auto bodyRange = AFD->getBodySourceRange();
5678-
auto BeginParserPosition = getParserPosition({bodyRange.Start,bodyRange.End});
5680+
auto FunctionParserState = State->takeFunctionBodyState(AFD);
5681+
assert(FunctionParserState.get() && "should have a valid state");
5682+
5683+
auto BeginParserPosition = getParserPosition(FunctionParserState->BodyPos);
56795684
auto EndLexerState = L->getStateForEndOfTokenLoc(AFD->getEndLoc());
56805685

56815686
// ParserPositionRAII needs a primed parser to restore to.
@@ -5695,12 +5700,20 @@ BraceStmt *Parser::parseAbstractFunctionBodyDelayed(AbstractFunctionDecl *AFD) {
56955700
restoreParserPosition(BeginParserPosition);
56965701

56975702
// Re-enter the lexical scope.
5698-
Scope TopLevelScope(this, ScopeKind::TopLevel);
5699-
Scope S(this, ScopeKind::FunctionBody);
5703+
Scope S(this, FunctionParserState->takeScope());
57005704
ParseFunctionBody CC(*this, AFD);
57015705
setLocalDiscriminatorToParamList(AFD->getParameters());
57025706

5703-
return parseBraceItemList(diag::func_decl_without_brace).getPtrOrNull();
5707+
ParserResult<BraceStmt> Body =
5708+
parseBraceItemList(diag::func_decl_without_brace);
5709+
if (Body.isNull()) {
5710+
// FIXME: Should do some sort of error recovery here?
5711+
return true;
5712+
} else {
5713+
AFD->setBodyParsed(Body.get());
5714+
}
5715+
5716+
return false;
57045717
}
57055718

57065719
/// Parse a 'enum' declaration, returning true (and doing no token

lib/Parse/ParseRequests.cpp

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -48,50 +48,6 @@ ParseMembersRequest::evaluate(Evaluator &evaluator,
4848
llvm::makeArrayRef(parser.parseDeclListDelayed(idc)));
4949
}
5050

51-
BraceStmt *ParseAbstractFunctionBodyRequest::evaluate(
52-
Evaluator &evaluator, AbstractFunctionDecl *afd) const {
53-
using BodyKind = AbstractFunctionDecl::BodyKind;
54-
55-
switch (afd->getBodyKind()) {
56-
case BodyKind::Deserialized:
57-
case BodyKind::MemberwiseInitializer:
58-
case BodyKind::None:
59-
case BodyKind::Skipped:
60-
return nullptr;
61-
62-
case BodyKind::TypeChecked:
63-
case BodyKind::Parsed:
64-
return afd->Body;
65-
66-
case BodyKind::Synthesize: {
67-
BraceStmt *body;
68-
bool isTypeChecked;
69-
70-
std::tie(body, isTypeChecked) = (afd->Synthesizer.Fn)(
71-
afd, afd->Synthesizer.Context);
72-
afd->setBodyKind(isTypeChecked ? BodyKind::TypeChecked : BodyKind::Parsed);
73-
return body;
74-
}
75-
76-
case BodyKind::Unparsed: {
77-
// FIXME: It should be fine to delay body parsing of local functions, so
78-
// the DelayBodyParsing should go away entirely
79-
// FIXME: How do we configure code completion?
80-
SourceFile &sf = *afd->getDeclContext()->getParentSourceFile();
81-
SourceManager &sourceMgr = sf.getASTContext().SourceMgr;
82-
unsigned bufferID = sourceMgr.findBufferContainingLoc(afd->getLoc());
83-
Parser parser(bufferID, sf, nullptr, nullptr, nullptr,
84-
/*DelayBodyParsing=*/false);
85-
parser.SyntaxContext->setDiscard();
86-
auto body = parser.parseAbstractFunctionBodyDelayed(afd);
87-
afd->setBodyKind(BodyKind::Parsed);
88-
return body;
89-
}
90-
}
91-
92-
}
93-
94-
9551
// Define request evaluation functions for each of the type checker requests.
9652
static AbstractRequestFunction *parseRequestFunctions[] = {
9753
#define SWIFT_REQUEST(Zone, Name) \

lib/Parse/Parser.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,6 @@ class ParseDelayedFunctionBodies : public ASTWalker {
138138

139139
private:
140140
void parseFunctionBody(AbstractFunctionDecl *AFD) {
141-
// FIXME: This duplicates the evaluation of
142-
// ParseAbstractFunctionBodyRequest, but installs a code completion
143-
// factory.
144141
assert(AFD->getBodyKind() == FuncDecl::BodyKind::Unparsed);
145142

146143
SourceFile &SF = *AFD->getDeclContext()->getParentSourceFile();
@@ -155,8 +152,8 @@ class ParseDelayedFunctionBodies : public ASTWalker {
155152
CodeCompletionFactory->createCodeCompletionCallbacks(TheParser));
156153
TheParser.setCodeCompletionCallbacks(CodeCompletion.get());
157154
}
158-
auto body = TheParser.parseAbstractFunctionBodyDelayed(AFD);
159-
AFD->setBodyParsed(body);
155+
if (ParserState.hasFunctionBodyState(AFD))
156+
TheParser.parseAbstractFunctionBodyDelayed(AFD);
160157

161158
if (CodeCompletion)
162159
CodeCompletion->doneParsing();

0 commit comments

Comments
 (0)