[IDE] Don't walk to ExplicitCast expr twice in ModelASTWalker

Explict cast expressions (i.e. 'as', 'as!`, 'as?', and 'is') appear twice in
'SequenceExpr'. For instance, 'a as B' is parsed as:
  (sequence_expr
    (unresolved_declref_expr name='a')
    (coerce_expr writtenType='B')
    (coerce_expr writtenType='B'))
This patch prevents ModelASTWalker from walking into them twice.

rdar://problem/43135727
This commit is contained in:
Rintaro Ishizaki
2018-08-13 14:42:34 +09:00
parent 4369b36f21
commit fedc36e4fb
3 changed files with 20 additions and 7 deletions

View File

@@ -425,6 +425,18 @@ std::pair<bool, Expr *> ModelASTWalker::walkToExprPre(Expr *E) {
if (isVisitedBeforeInIfConfig(E))
return {false, E};
// In SequenceExpr, explicit cast expressions (e.g. 'as', 'is') appear twice.
// Skip pointers we've already seen.
if (auto SE = dyn_cast<SequenceExpr>(E)) {
SmallPtrSet<Expr *, 5> seenExpr;
for (auto subExpr : SE->getElements()) {
if (!seenExpr.insert(subExpr).second)
continue;
subExpr->walk(*this);
}
return { false, SE };
}
auto addCallArgExpr = [&](Expr *Elem, TupleExpr *ParentTupleExpr) {
if (isCurrentCallArgExpr(ParentTupleExpr)) {
CharSourceRange NR = parameterNameRangeOfCallArg(ParentTupleExpr, Elem);
@@ -962,7 +974,8 @@ bool ModelASTWalker::walkToTypeReprPre(TypeRepr *T) {
} else if (auto IdT = dyn_cast<ComponentIdentTypeRepr>(T)) {
if (!passTokenNodesUntil(IdT->getIdLoc(), ExcludeNodeAtLocation))
return false;
if (TokenNodes.front().Range.getStart() != IdT->getIdLoc())
if (TokenNodes.empty() ||
TokenNodes.front().Range.getStart() != IdT->getIdLoc())
return false;
if (!passNode({SyntaxNodeKind::TypeId, TokenNodes.front().Range}))
return false;