Skip to content

Commit 38991ca

Browse files
authored
RangeInfo: unbox ifstmt to get the agreed-upon return type from selected statements. rdar://31691723 (#9380)
1 parent 3117e50 commit 38991ca

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

lib/IDE/SwiftSourceDocInfo.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,9 @@ struct RangeResolver::Implementation {
383383

384384
/// Collect the type that an ASTNode should be evaluated to.
385385
Type resolveNodeType(ASTNode N, RangeKind Kind) {
386+
auto VoidTy = Ctx.getVoidDecl()->getDeclaredInterfaceType();
387+
if (N.isNull())
388+
return VoidTy;
386389
switch(Kind) {
387390
case RangeKind::Invalid:
388391
case RangeKind::SingleDecl:
@@ -407,9 +410,24 @@ struct RangeResolver::Implementation {
407410
RangeKind::SingleStatement);
408411
}
409412
}
413+
414+
// Unbox the if statement to find its type.
415+
if (auto *IS = dyn_cast<IfStmt>(N.get<Stmt*>())) {
416+
auto ThenTy = resolveNodeType(IS->getThenStmt(),
417+
RangeKind::SingleStatement);
418+
auto ElseTy = resolveNodeType(IS->getElseStmt(),
419+
RangeKind::SingleStatement);
420+
421+
// If two branches agree on the return type, return that type.
422+
if (ThenTy->isEqual(ElseTy))
423+
return ThenTy;
424+
425+
// Otherwise, return the error type.
426+
return Ctx.TheErrorType;
427+
}
410428
}
411429
// For other statements, the type should be void.
412-
return Ctx.getVoidDecl()->getDeclaredInterfaceType();
430+
return VoidTy;
413431
}
414432
}
415433
}

test/IDE/range_info_branches.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
func foo(_ a: Bool) -> Int{
2+
if a {
3+
return 1
4+
} else {
5+
}
6+
if a {
7+
return 0
8+
} else {
9+
return 1
10+
}
11+
}
12+
13+
// RUN: %target-swift-ide-test -range -pos=2:1 -end-pos 5:4 -source-filename %s | %FileCheck %s -check-prefix=CHECK-ERR
14+
// RUN: %target-swift-ide-test -range -pos=6:1 -end-pos 10:4 -source-filename %s | %FileCheck %s -check-prefix=CHECK-INT
15+
16+
// CHECK-ERR: <Type><<error type>></Type>
17+
// CHECK-INT: <Type>Int</Type>

0 commit comments

Comments
 (0)