Skip to content

Commit 9a0c43d

Browse files
authored
Merge pull request #34269 from slavapestov/did-set-cleanup
Sema: Move SimpleDidSetRequest::evaluate() to TypeCheckStorage.cpp
2 parents e843a16 + 3d160d9 commit 9a0c43d

File tree

2 files changed

+68
-67
lines changed

2 files changed

+68
-67
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 0 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,73 +1273,6 @@ EnumRawValuesRequest::evaluate(Evaluator &eval, EnumDecl *ED,
12731273
return std::make_tuple<>();
12741274
}
12751275

1276-
bool SimpleDidSetRequest::evaluate(Evaluator &evaluator,
1277-
AccessorDecl *decl) const {
1278-
1279-
class OldValueFinder : public ASTWalker {
1280-
const ParamDecl *OldValueParam;
1281-
bool foundOldValueRef = false;
1282-
1283-
public:
1284-
OldValueFinder(const ParamDecl *param) : OldValueParam(param) {}
1285-
1286-
virtual std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
1287-
if (!E)
1288-
return {true, E};
1289-
if (auto DRE = dyn_cast<DeclRefExpr>(E)) {
1290-
if (auto decl = DRE->getDecl()) {
1291-
if (decl == OldValueParam) {
1292-
foundOldValueRef = true;
1293-
return {false, nullptr};
1294-
}
1295-
}
1296-
}
1297-
1298-
return {true, E};
1299-
}
1300-
1301-
bool didFindOldValueRef() { return foundOldValueRef; }
1302-
};
1303-
1304-
// If this is not a didSet accessor, bail out.
1305-
if (decl->getAccessorKind() != AccessorKind::DidSet) {
1306-
return false;
1307-
}
1308-
1309-
// Always assume non-simple 'didSet' in code completion mode.
1310-
if (decl->getASTContext().SourceMgr.hasCodeCompletionBuffer())
1311-
return false;
1312-
1313-
// didSet must have a single parameter.
1314-
if (decl->getParameters()->size() != 1) {
1315-
return false;
1316-
}
1317-
1318-
auto param = decl->getParameters()->get(0);
1319-
// If this parameter is not implicit, then it means it has been explicitly
1320-
// provided by the user (i.e. 'didSet(oldValue)'). This means we cannot
1321-
// consider this a "simple" didSet because we have to fetch the oldValue
1322-
// regardless of whether it's referenced in the body or not.
1323-
if (!param->isImplicit()) {
1324-
return false;
1325-
}
1326-
1327-
// If we find a reference to the implicit 'oldValue' parameter, then it is
1328-
// not a "simple" didSet because we need to fetch it.
1329-
auto walker = OldValueFinder(param);
1330-
decl->getTypecheckedBody()->walk(walker);
1331-
auto hasOldValueRef = walker.didFindOldValueRef();
1332-
if (!hasOldValueRef) {
1333-
// If the body does not refer to implicit 'oldValue', it means we can
1334-
// consider this as a "simple" didSet. Let's also erase the implicit
1335-
// oldValue as it is never used.
1336-
auto &ctx = decl->getASTContext();
1337-
decl->setParameters(ParameterList::createEmpty(ctx));
1338-
return true;
1339-
}
1340-
return false;
1341-
}
1342-
13431276
const ConstructorDecl *
13441277
swift::findNonImplicitRequiredInit(const ConstructorDecl *CD) {
13451278
while (CD->isImplicit()) {

lib/Sema/TypeCheckStorage.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3186,3 +3186,71 @@ StorageImplInfoRequest::evaluate(Evaluator &evaluator,
31863186

31873187
return info;
31883188
}
3189+
3190+
bool SimpleDidSetRequest::evaluate(Evaluator &evaluator,
3191+
AccessorDecl *decl) const {
3192+
3193+
class OldValueFinder : public ASTWalker {
3194+
const ParamDecl *OldValueParam;
3195+
bool foundOldValueRef = false;
3196+
3197+
public:
3198+
OldValueFinder(const ParamDecl *param) : OldValueParam(param) {}
3199+
3200+
virtual std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
3201+
if (!E)
3202+
return {true, E};
3203+
if (auto DRE = dyn_cast<DeclRefExpr>(E)) {
3204+
if (auto decl = DRE->getDecl()) {
3205+
if (decl == OldValueParam) {
3206+
foundOldValueRef = true;
3207+
return {false, nullptr};
3208+
}
3209+
}
3210+
}
3211+
3212+
return {true, E};
3213+
}
3214+
3215+
bool didFindOldValueRef() { return foundOldValueRef; }
3216+
};
3217+
3218+
// If this is not a didSet accessor, bail out.
3219+
if (decl->getAccessorKind() != AccessorKind::DidSet) {
3220+
return false;
3221+
}
3222+
3223+
// Always assume non-simple 'didSet' in code completion mode.
3224+
if (decl->getASTContext().SourceMgr.hasCodeCompletionBuffer())
3225+
return false;
3226+
3227+
// didSet must have a single parameter.
3228+
if (decl->getParameters()->size() != 1) {
3229+
return false;
3230+
}
3231+
3232+
auto param = decl->getParameters()->get(0);
3233+
// If this parameter is not implicit, then it means it has been explicitly
3234+
// provided by the user (i.e. 'didSet(oldValue)'). This means we cannot
3235+
// consider this a "simple" didSet because we have to fetch the oldValue
3236+
// regardless of whether it's referenced in the body or not.
3237+
if (!param->isImplicit()) {
3238+
return false;
3239+
}
3240+
3241+
// If we find a reference to the implicit 'oldValue' parameter, then it is
3242+
// not a "simple" didSet because we need to fetch it.
3243+
auto walker = OldValueFinder(param);
3244+
decl->getTypecheckedBody()->walk(walker);
3245+
auto hasOldValueRef = walker.didFindOldValueRef();
3246+
if (!hasOldValueRef) {
3247+
// If the body does not refer to implicit 'oldValue', it means we can
3248+
// consider this as a "simple" didSet. Let's also erase the implicit
3249+
// oldValue as it is never used.
3250+
auto &ctx = decl->getASTContext();
3251+
decl->setParameters(ParameterList::createEmpty(ctx));
3252+
return true;
3253+
}
3254+
return false;
3255+
}
3256+

0 commit comments

Comments
 (0)