Skip to content

Commit 33bc38c

Browse files
committed
[IDE] SourceEntityWalker should walk all explicit declarations
`SourceEntityWalker` had an unbalanced `walkToDeclPre` and `walkToDeclPost`, ie. `walkToDeclPost` could be called even though `walkToDeclPre` was not. Specifically, this would occur for both `OperatorDecl` and `PrecedenceGroupDecl` declarations. These could both be added to the `if` in `walkToDeclPost`, but this seems fairly errorprone in general - especially as new decls are added. Indeed, there's already declarations that are being skipped because they aren't explicitly tested for in `walkToDeclPre`, ie. `PatternBindingDecl`. Instead of skipping if not explcitly handled, only skip running the `SEWalker` walk methods if the declaration is implicit (and not a constructor decl, see TODO). This should probably also always visit children, with various decls changed to become implicit (eg. TopLevelCodeDecl), but we can do that later - breaks too many tests for now. This change exposed a few parameter declarations that were missing their implicit flag, as well as unbalanced walk methods in `RangeResolver`.
1 parent e2e78c6 commit 33bc38c

11 files changed

+41
-23
lines changed

lib/AST/Decl.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -6088,6 +6088,9 @@ ParamDecl *ParamDecl::cloneWithoutType(const ASTContext &Ctx, ParamDecl *PD) {
60886088

60896089
Clone->setSpecifier(PD->getSpecifier());
60906090
Clone->setImplicitlyUnwrappedOptional(PD->isImplicitlyUnwrappedOptional());
6091+
if (PD->isImplicit()) {
6092+
Clone->setImplicit();
6093+
}
60916094
return Clone;
60926095
}
60936096

lib/IDE/IDERequests.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -995,16 +995,24 @@ bool RangeResolver::walkToDeclPre(Decl *D, CharSourceRange Range) {
995995
}
996996

997997
bool RangeResolver::walkToExprPost(Expr *E) {
998+
if (!Impl->shouldEnter(E))
999+
return true;
9981000
Impl->leave(E);
9991001
return !Impl->hasResult();
10001002
}
10011003

10021004
bool RangeResolver::walkToStmtPost(Stmt *S) {
1005+
if (!Impl->shouldEnter(S))
1006+
return true;
10031007
Impl->leave(S);
10041008
return !Impl->hasResult();
10051009
};
10061010

10071011
bool RangeResolver::walkToDeclPost(Decl *D) {
1012+
if (D->isImplicit())
1013+
return true;
1014+
if (!Impl->shouldEnter(D))
1015+
return true;
10081016
Impl->leave(D);
10091017
return !Impl->hasResult();
10101018
}

lib/IDE/Refactoring.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -4761,7 +4761,9 @@ class AsyncConversionStringBuilder : private SourceEntityWalker {
47614761
}
47624762

47634763
private:
4764-
bool walkToDeclPre(Decl *D, CharSourceRange Range) override { return false; }
4764+
bool walkToDeclPre(Decl *D, CharSourceRange Range) override {
4765+
return isa<PatternBindingDecl>(D);
4766+
}
47654767

47664768
#define PLACEHOLDER_START "<#"
47674769
#define PLACEHOLDER_END "#>"

lib/IDE/SourceEntityWalker.cpp

+17-22
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ class SemaAnnotator : public ASTWalker {
8484

8585
bool passCallArgNames(Expr *Fn, TupleExpr *TupleE);
8686

87-
bool shouldIgnore(Decl *D, bool &ShouldVisitChildren);
87+
bool shouldIgnore(Decl *D);
8888

8989
ValueDecl *extractDecl(Expr *Fn) const {
9090
Fn = Fn->getSemanticsProvidingExpr();
@@ -106,9 +106,8 @@ bool SemaAnnotator::walkToDeclPre(Decl *D) {
106106
if (isDone())
107107
return false;
108108

109-
bool ShouldVisitChildren;
110-
if (shouldIgnore(D, ShouldVisitChildren))
111-
return ShouldVisitChildren;
109+
if (shouldIgnore(D))
110+
return isa<PatternBindingDecl>(D);
112111

113112
if (!handleCustomAttributes(D)) {
114113
Cancelled = true;
@@ -177,14 +176,12 @@ bool SemaAnnotator::walkToDeclPre(Decl *D) {
177176
}
178177
return false;
179178
}
180-
} else {
181-
return true;
182179
}
183180

184181
CharSourceRange Range = (Loc.isValid()) ? CharSourceRange(Loc, NameLen)
185182
: CharSourceRange();
186-
ShouldVisitChildren = SEWalker.walkToDeclPre(D, Range);
187-
if (ShouldVisitChildren && IsExtension) {
183+
bool ShouldVisitChildren = SEWalker.walkToDeclPre(D, Range);
184+
if (IsExtension) {
188185
ExtDecls.push_back(static_cast<ExtensionDecl*>(D));
189186
}
190187
return ShouldVisitChildren;
@@ -194,19 +191,21 @@ bool SemaAnnotator::walkToDeclPost(Decl *D) {
194191
if (isDone())
195192
return false;
196193

197-
bool ShouldVisitChildren;
198-
if (shouldIgnore(D, ShouldVisitChildren))
194+
if (shouldIgnore(D))
199195
return true;
200196

197+
// Note: This should match any early (non-cancelling) returns in
198+
// `walkToDeclPre` above
199+
if (auto *ICD = dyn_cast<IfConfigDecl>(D)) {
200+
if (SEWalker.shouldWalkInactiveConfigRegion())
201+
return true;
202+
}
203+
201204
if (isa<ExtensionDecl>(D)) {
202205
assert(ExtDecls.back() == D);
203206
ExtDecls.pop_back();
204207
}
205208

206-
if (!isa<ValueDecl>(D) && !isa<ExtensionDecl>(D) && !isa<ImportDecl>(D) &&
207-
!isa<IfConfigDecl>(D))
208-
return true;
209-
210209
bool Continue = SEWalker.walkToDeclPost(D);
211210
if (!Continue)
212211
Cancelled = true;
@@ -772,14 +771,10 @@ bool SemaAnnotator::passCallArgNames(Expr *Fn, TupleExpr *TupleE) {
772771
return true;
773772
}
774773

775-
bool SemaAnnotator::shouldIgnore(Decl *D, bool &ShouldVisitChildren) {
776-
if (D->isImplicit() &&
777-
!isa<PatternBindingDecl>(D) &&
778-
!isa<ConstructorDecl>(D)) {
779-
ShouldVisitChildren = false;
780-
return true;
781-
}
782-
return false;
774+
bool SemaAnnotator::shouldIgnore(Decl *D) {
775+
// TODO: There should really be a separate field controlling whether
776+
// constructors are visited or not
777+
return D->isImplicit() && !isa<ConstructorDecl>(D);
783778
}
784779

785780
bool SourceEntityWalker::walk(SourceFile &SrcFile) {

lib/Sema/CSApply.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -1481,6 +1481,7 @@ namespace {
14811481
selfParamDecl->setSpecifier(
14821482
ParamDecl::getParameterSpecifierForValueOwnership(
14831483
selfParam.getValueOwnership()));
1484+
selfParamDecl->setImplicit();
14841485

14851486
auto *outerParams =
14861487
ParameterList::create(context, SourceLoc(), selfParamDecl,
@@ -4803,6 +4804,7 @@ namespace {
48034804
/*parameter name*/ SourceLoc(), ctx.getIdentifier("$0"), closure);
48044805
param->setInterfaceType(baseTy->mapTypeOutOfContext());
48054806
param->setSpecifier(ParamSpecifier::Default);
4807+
param->setImplicit();
48064808

48074809
// The outer closure.
48084810
//
@@ -4819,6 +4821,7 @@ namespace {
48194821
ctx.getIdentifier("$kp$"), outerClosure);
48204822
outerParam->setInterfaceType(keyPathTy->mapTypeOutOfContext());
48214823
outerParam->setSpecifier(ParamSpecifier::Default);
4824+
outerParam->setImplicit();
48224825

48234826
// let paramRef = "$0"
48244827
auto *paramRef = new (ctx)

lib/Sema/DerivedConformanceActor.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ static ValueDecl *deriveActor_enqueuePartialTask(DerivedConformance &derived) {
143143
SourceLoc(), ctx.Id_partialTask, parentDC);
144144
partialTaskParamDecl->setInterfaceType(partialTaskType);
145145
partialTaskParamDecl->setSpecifier(ParamSpecifier::Default);
146+
partialTaskParamDecl->setImplicit();
146147

147148
// enqueue(partialTask:) method.
148149
ParameterList *params = ParameterList::createWithoutLoc(partialTaskParamDecl);

lib/Sema/DerivedConformanceAdditiveArithmetic.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ static ValueDecl *deriveMathOperator(DerivedConformance &derived,
181181
C.getIdentifier(name), parentDC);
182182
param->setSpecifier(ParamDecl::Specifier::Default);
183183
param->setInterfaceType(type);
184+
param->setImplicit();
184185
return param;
185186
};
186187

lib/Sema/DerivedConformanceCodable.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,7 @@ static FuncDecl *deriveEncodable_encode(DerivedConformance &derived) {
627627
SourceLoc(), C.Id_encoder, conformanceDC);
628628
encoderParam->setSpecifier(ParamSpecifier::Default);
629629
encoderParam->setInterfaceType(encoderType);
630+
encoderParam->setImplicit();
630631

631632
ParameterList *params = ParameterList::createWithoutLoc(encoderParam);
632633

lib/Sema/DerivedConformanceComparable.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ deriveComparable_lt(
235235
C.getIdentifier(s), parentDC);
236236
param->setSpecifier(ParamSpecifier::Default);
237237
param->setInterfaceType(selfIfaceTy);
238+
param->setImplicit();
238239
return param;
239240
};
240241

lib/Sema/DerivedConformanceDifferentiable.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ static ValueDecl *deriveDifferentiable_method(
305305
SourceLoc(), parameterName, parentDC);
306306
param->setSpecifier(ParamDecl::Specifier::Default);
307307
param->setInterfaceType(parameterType);
308+
param->setImplicit();
308309
ParameterList *params = ParameterList::create(C, {param});
309310

310311
DeclName declName(C, methodName, params);

lib/Sema/DerivedConformanceEquatableHashable.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ deriveEquatable_eq(
387387
C.getIdentifier(s), parentDC);
388388
param->setSpecifier(ParamSpecifier::Default);
389389
param->setInterfaceType(selfIfaceTy);
390+
param->setImplicit();
390391
return param;
391392
};
392393

@@ -537,6 +538,7 @@ deriveHashable_hashInto(
537538
C.Id_hasher, parentDC);
538539
hasherParamDecl->setSpecifier(ParamSpecifier::InOut);
539540
hasherParamDecl->setInterfaceType(hasherType);
541+
hasherParamDecl->setImplicit();
540542

541543
ParameterList *params = ParameterList::createWithoutLoc(hasherParamDecl);
542544

0 commit comments

Comments
 (0)