Skip to content

Commit ea370ca

Browse files
authored
Merge pull request #18663 from rintaro/ide-rdar43135727
[IDE] Don't walk to ExplicitCast expr twice in ModelASTWalker
2 parents 5a1b0e7 + fedc36e commit ea370ca

File tree

3 files changed

+20
-7
lines changed

3 files changed

+20
-7
lines changed

lib/IDE/SyntaxModel.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,18 @@ std::pair<bool, Expr *> ModelASTWalker::walkToExprPre(Expr *E) {
425425
if (isVisitedBeforeInIfConfig(E))
426426
return {false, E};
427427

428+
// In SequenceExpr, explicit cast expressions (e.g. 'as', 'is') appear twice.
429+
// Skip pointers we've already seen.
430+
if (auto SE = dyn_cast<SequenceExpr>(E)) {
431+
SmallPtrSet<Expr *, 5> seenExpr;
432+
for (auto subExpr : SE->getElements()) {
433+
if (!seenExpr.insert(subExpr).second)
434+
continue;
435+
subExpr->walk(*this);
436+
}
437+
return { false, SE };
438+
}
439+
428440
auto addCallArgExpr = [&](Expr *Elem, TupleExpr *ParentTupleExpr) {
429441
if (isCurrentCallArgExpr(ParentTupleExpr)) {
430442
CharSourceRange NR = parameterNameRangeOfCallArg(ParentTupleExpr, Elem);
@@ -962,7 +974,8 @@ bool ModelASTWalker::walkToTypeReprPre(TypeRepr *T) {
962974
} else if (auto IdT = dyn_cast<ComponentIdentTypeRepr>(T)) {
963975
if (!passTokenNodesUntil(IdT->getIdLoc(), ExcludeNodeAtLocation))
964976
return false;
965-
if (TokenNodes.front().Range.getStart() != IdT->getIdLoc())
977+
if (TokenNodes.empty() ||
978+
TokenNodes.front().Range.getStart() != IdT->getIdLoc())
966979
return false;
967980
if (!passNode({SyntaxNodeKind::TypeId, TokenNodes.front().Range}))
968981
return false;

test/IDE/coloring.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,8 @@ class Observers {
285285

286286
// CHECK: <kw>func</kw> test3(o: <type>AnyObject</type>) {
287287
func test3(o: AnyObject) {
288-
// CHECK: <kw>let</kw> x = o <kw>as</kw>! <type>MyCls</type>
289-
let x = o as! MyCls
288+
// CHECK: <kw>_</kw> = o <kw>is</kw> <type>MyCls</type> ? o <kw>as</kw> <type>MyCls</type> : o <kw>as</kw>! <type>MyCls</type> <kw>as</kw> <type>MyCls</type> + <int>1</int>
289+
_ = o is MyCls ? o as MyCls : o as! MyCls as MyCls + 1
290290
}
291291

292292
// CHECK: <kw>class</kw> MySubClass : <type>MyCls</type> {

test/IDE/structure.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,9 @@ struct Tuples {
276276
}
277277
}
278278

279-
completion(a: 1) { (x: Int, y: Int) -> Int in
280-
return x + y
279+
completion(a: 1) { (x: Any, y: Int) -> Int in
280+
return x as! Int + y
281281
}
282-
// CHECK: <call><name>completion</name>(<arg><name>a</name>: 1</arg>) <arg><closure>{ (<param>x: <type>Int</type></param>, <param>y: <type>Int</type></param>) -> <type>Int</type> in
283-
// CHECK: return x + y
282+
// CHECK: <call><name>completion</name>(<arg><name>a</name>: 1</arg>) <arg><closure>{ (<param>x: <type>Any</type></param>, <param>y: <type>Int</type></param>) -> <type>Int</type> in
283+
// CHECK: return x as! Int + y
284284
// CHECK: }</closure></arg></call>

0 commit comments

Comments
 (0)