Skip to content

Commit 7270f09

Browse files
authored
Merge pull request #68210 from hamishknight/for-the-sake-of-argument
2 parents 55292e2 + f6664f0 commit 7270f09

File tree

3 files changed

+64
-69
lines changed

3 files changed

+64
-69
lines changed

include/swift/AST/ASTWalker.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
namespace swift {
2222

23+
class Argument;
2324
class ArgumentList;
2425
class Decl;
2526
class Expr;
@@ -643,6 +644,27 @@ class ASTWalker {
643644
return Action::Continue(ArgList);
644645
}
645646

647+
/// This method is called when first visiting an argument in an argument list,
648+
/// before walking into its expression.
649+
///
650+
/// \param Arg The argument to walk.
651+
///
652+
/// \returns The walking action to perform.
653+
///
654+
/// The default implementation returns \c Action::Continue().
655+
virtual PreWalkAction walkToArgumentPre(const Argument &Arg) {
656+
return Action::Continue();
657+
}
658+
659+
/// This method is called after visiting an argument in an argument list.
660+
///
661+
/// \returns The walking action to perform.
662+
///
663+
/// The default implementation returns \c Action::Continue().
664+
virtual PostWalkAction walkToArgumentPost(const Argument &Arg) {
665+
return Action::Continue();
666+
}
667+
646668
protected:
647669
ASTWalker() = default;
648670
ASTWalker(const ASTWalker &) = default;

lib/AST/ASTWalker.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1635,12 +1635,26 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
16351635
return false;
16361636
}
16371637

1638+
[[nodiscard]]
1639+
bool doIt(ArgumentList *ArgList, unsigned Idx) {
1640+
auto Arg = ArgList->get(Idx);
1641+
return traverse(
1642+
Walker.walkToArgumentPre(Arg),
1643+
[&]() {
1644+
auto *E = doIt(Arg.getExpr());
1645+
if (!E)
1646+
return true;
1647+
ArgList->setExpr(Idx, E);
1648+
return false;
1649+
},
1650+
[&]() { return Walker.walkToArgumentPost(Arg); });
1651+
}
1652+
16381653
[[nodiscard]]
16391654
ArgumentList *visit(ArgumentList *ArgList) {
16401655
for (auto Idx : indices(*ArgList)) {
1641-
auto *E = doIt(ArgList->getExpr(Idx));
1642-
if (!E) return nullptr;
1643-
ArgList->setExpr(Idx, E);
1656+
if (doIt(ArgList, Idx))
1657+
return nullptr;
16441658
}
16451659
return ArgList;
16461660
}

lib/IDE/SyntaxModel.cpp

Lines changed: 25 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -372,13 +372,6 @@ class ModelASTWalker : public ASTWalker {
372372
friend class InactiveClauseRAII;
373373
bool inInactiveClause = false;
374374

375-
struct ParentArgsTy {
376-
Expr *Parent = nullptr;
377-
llvm::DenseMap<Expr *, Argument> Args;
378-
};
379-
/// A mapping of argument expressions to their full argument info.
380-
SmallVector<ParentArgsTy, 4> ParentArgs;
381-
382375
public:
383376
SyntaxModelWalker &Walker;
384377
ArrayRef<SyntaxNode> TokenNodes;
@@ -401,10 +394,7 @@ class ModelASTWalker : public ASTWalker {
401394

402395
void visitSourceFile(SourceFile &SrcFile, ArrayRef<SyntaxNode> Tokens);
403396

404-
PreWalkResult<ArgumentList *>
405-
walkToArgumentListPre(ArgumentList *ArgList) override;
406-
PostWalkResult<ArgumentList *>
407-
walkToArgumentListPost(ArgumentList *ArgList) override;
397+
PreWalkAction walkToArgumentPre(const Argument &Arg) override;
408398

409399
PreWalkResult<Expr *> walkToExprPre(Expr *E) override;
410400
PostWalkResult<Expr *> walkToExprPost(Expr *E) override;
@@ -544,69 +534,38 @@ static bool shouldTreatAsSingleToken(const SyntaxStructureNode &Node,
544534
SM.getLineAndColumnInBuffer(Node.Range.getEnd()).first;
545535
}
546536

547-
ASTWalker::PreWalkResult<ArgumentList *>
548-
ModelASTWalker::walkToArgumentListPre(ArgumentList *ArgList) {
549-
Expr *ParentExpr = Parent.getAsExpr();
550-
if (!ParentExpr)
551-
return Action::Continue(ArgList);
552-
553-
ParentArgsTy Mapping;
554-
Mapping.Parent = ParentExpr;
555-
for (auto Arg : *ArgList) {
556-
auto res = Mapping.Args.try_emplace(Arg.getExpr(), Arg);
557-
assert(res.second && "Duplicate arguments?");
558-
(void)res;
559-
}
560-
ParentArgs.push_back(std::move(Mapping));
561-
return Action::Continue(ArgList);
562-
}
537+
ASTWalker::PreWalkAction
538+
ModelASTWalker::walkToArgumentPre(const Argument &Arg) {
539+
if (isVisitedBefore(Arg.getExpr()))
540+
return Action::SkipChildren();
563541

564-
ASTWalker::PostWalkResult<ArgumentList *>
565-
ModelASTWalker::walkToArgumentListPost(ArgumentList *ArgList) {
566-
if (Expr *ParentExpr = Parent.getAsExpr()) {
567-
assert(ParentExpr == ParentArgs.back().Parent &&
568-
"Unmatched walkToArgumentList(Pre|Post)");
569-
ParentArgs.pop_back();
542+
auto *Elem = Arg.getExpr();
543+
if (isa<DefaultArgumentExpr>(Elem))
544+
return Action::Continue();
545+
546+
auto NL = Arg.getLabelLoc();
547+
auto Name = Arg.getLabel();
548+
549+
SyntaxStructureNode SN;
550+
SN.Kind = SyntaxStructureKind::Argument;
551+
SN.BodyRange = charSourceRangeFromSourceRange(SM, Elem->getSourceRange());
552+
if (NL.isValid() && !Name.empty()) {
553+
SN.NameRange = CharSourceRange(NL, Name.getLength());
554+
SN.Range = charSourceRangeFromSourceRange(
555+
SM, SourceRange(NL, Elem->getEndLoc()));
556+
passTokenNodesUntil(NL, ExcludeNodeAtLocation);
557+
} else {
558+
SN.Range = SN.BodyRange;
570559
}
571-
return Action::Continue(ArgList);
560+
561+
pushStructureNode(SN, Elem);
562+
return Action::Continue();
572563
}
573564

574565
ASTWalker::PreWalkResult<Expr *> ModelASTWalker::walkToExprPre(Expr *E) {
575566
if (isVisitedBefore(E))
576567
return Action::SkipChildren(E);
577568

578-
auto addCallArgExpr = [&](const Argument &Arg) {
579-
auto *Elem = Arg.getExpr();
580-
if (isa<DefaultArgumentExpr>(Elem))
581-
return;
582-
583-
auto NL = Arg.getLabelLoc();
584-
auto Name = Arg.getLabel();
585-
586-
SyntaxStructureNode SN;
587-
SN.Kind = SyntaxStructureKind::Argument;
588-
SN.BodyRange = charSourceRangeFromSourceRange(SM, Elem->getSourceRange());
589-
if (NL.isValid() && !Name.empty()) {
590-
SN.NameRange = CharSourceRange(NL, Name.getLength());
591-
SN.Range = charSourceRangeFromSourceRange(
592-
SM, SourceRange(NL, Elem->getEndLoc()));
593-
passTokenNodesUntil(NL, ExcludeNodeAtLocation);
594-
} else {
595-
SN.Range = SN.BodyRange;
596-
}
597-
598-
pushStructureNode(SN, Elem);
599-
};
600-
601-
if (auto *ParentExpr = Parent.getAsExpr()) {
602-
if (!ParentArgs.empty() && ParentArgs.back().Parent == ParentExpr) {
603-
auto &ArgumentInfo = ParentArgs.back().Args;
604-
auto Arg = ArgumentInfo.find(E);
605-
if (Arg != ArgumentInfo.end())
606-
addCallArgExpr(Arg->second);
607-
}
608-
}
609-
610569
if (E->isImplicit())
611570
return Action::Continue(E);
612571

0 commit comments

Comments
 (0)