Skip to content

Commit 479ac68

Browse files
authored
Merge pull request #71308 from hamishknight/add-test
[test] Add a couple of locator tests for if/switch exprs
2 parents d021c54 + e723049 commit 479ac68

File tree

1 file changed

+122
-0
lines changed

1 file changed

+122
-0
lines changed

unittests/Sema/ConstraintGenerationTests.cpp

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,3 +220,125 @@ TEST_F(SemaTest, TestMultiStmtClosureBodyParentAndDepth) {
220220
ASSERT_EQ(cs.getParentExpr(result), closure);
221221
ASSERT_EQ(cs.getExprDepth(result), 1);
222222
}
223+
224+
TEST_F(SemaTest, TestIfExprLocator) {
225+
// Test to make sure we get the expected conjunction and locators.
226+
227+
// if true { 1 } else { 2 }
228+
auto *ifCond = new (Context) BooleanLiteralExpr(true, SourceLoc());
229+
auto *thenBrace = BraceStmt::createImplicit(
230+
Context,
231+
{IntegerLiteralExpr::createFromUnsigned(Context, 1, SourceLoc())});
232+
auto *elseBrace = BraceStmt::createImplicit(
233+
Context,
234+
{IntegerLiteralExpr::createFromUnsigned(Context, 2, SourceLoc())});
235+
auto *ifStmt =
236+
new (Context) IfStmt(SourceLoc(), ifCond, thenBrace, SourceLoc(),
237+
elseBrace, /*implicit*/ true, Context);
238+
auto *ifExpr = SingleValueStmtExpr::createWithWrappedBranches(
239+
Context, ifStmt, DC, /*mustBeExpr*/ true);
240+
241+
SyntacticElementTarget target(ifExpr, DC, ContextualTypeInfo(),
242+
/*isDiscarded*/ true);
243+
244+
ConstraintSystem cs(DC, ConstraintSystemOptions());
245+
auto hadError = cs.generateConstraints(target);
246+
ASSERT_FALSE(hadError);
247+
248+
auto *conjunction = &cs.getConstraints().front();
249+
ASSERT_EQ(conjunction->getKind(), ConstraintKind::Conjunction);
250+
251+
auto nested = conjunction->getNestedConstraints();
252+
ASSERT_EQ(nested.size(), 4);
253+
254+
auto *condConstraint = nested[0];
255+
auto *thenConstraint = nested[1];
256+
auto *elseConstraint = nested[2];
257+
auto *joinConstraint = nested[3];
258+
259+
auto *ifStmtLoc =
260+
cs.getConstraintLocator(ifExpr, LocatorPathElt::SyntacticElement(ifStmt));
261+
262+
auto *condLoc =
263+
cs.getConstraintLocator(ifStmtLoc, LocatorPathElt::Condition());
264+
ASSERT_EQ(condConstraint->getLocator(), condLoc);
265+
266+
auto *thenLoc =
267+
cs.getConstraintLocator(ifStmtLoc, LocatorPathElt::TernaryBranch(true));
268+
ASSERT_EQ(thenConstraint->getLocator(), thenLoc);
269+
270+
auto *elseLoc =
271+
cs.getConstraintLocator(ifStmtLoc, LocatorPathElt::TernaryBranch(false));
272+
ASSERT_EQ(elseConstraint->getLocator(), elseLoc);
273+
274+
auto *joinLoc = cs.getConstraintLocator(
275+
ifStmtLoc,
276+
LocatorPathElt::SyntacticElement(joinConstraint->getSyntacticElement()));
277+
ASSERT_EQ(joinConstraint->getLocator(), joinLoc);
278+
}
279+
280+
TEST_F(SemaTest, TestSwitchExprLocator) {
281+
// Test to make sure we get the expected conjunction and locators.
282+
283+
// case true: 1
284+
auto *trueBrace = BraceStmt::createImplicit(
285+
Context,
286+
{IntegerLiteralExpr::createFromUnsigned(Context, 1, SourceLoc())});
287+
auto *truePattern = ExprPattern::createImplicit(
288+
Context, new (Context) BooleanLiteralExpr(true, SourceLoc()), DC);
289+
auto *trueCase =
290+
CaseStmt::create(Context, CaseParentKind::Switch, SourceLoc(),
291+
{CaseLabelItem(truePattern)}, SourceLoc(), SourceLoc(),
292+
trueBrace, /*caseBodyVars*/ llvm::None);
293+
294+
// case false: 2
295+
auto *falseBrace = BraceStmt::createImplicit(
296+
Context,
297+
{IntegerLiteralExpr::createFromUnsigned(Context, 2, SourceLoc())});
298+
auto *falsePattern = ExprPattern::createImplicit(
299+
Context, new (Context) BooleanLiteralExpr(false, SourceLoc()), DC);
300+
auto *falseCase =
301+
CaseStmt::create(Context, CaseParentKind::Switch, SourceLoc(),
302+
{CaseLabelItem(falsePattern)}, SourceLoc(), SourceLoc(),
303+
falseBrace, /*caseBodyVars*/ llvm::None);
304+
305+
auto *subject = new (Context) BooleanLiteralExpr(true, SourceLoc());
306+
307+
// switch true { case true: 1 case false: 2 }
308+
auto *switchStmt = SwitchStmt::create(LabeledStmtInfo(), SourceLoc(), subject,
309+
SourceLoc(), {trueCase, falseCase},
310+
SourceLoc(), SourceLoc(), Context);
311+
auto *switchExpr = SingleValueStmtExpr::createWithWrappedBranches(
312+
Context, switchStmt, DC, /*mustBeExpr*/ true);
313+
314+
SyntacticElementTarget target(switchExpr, DC, ContextualTypeInfo(),
315+
/*isDiscarded*/ true);
316+
317+
ConstraintSystem cs(DC, ConstraintSystemOptions());
318+
auto hadError = cs.generateConstraints(target);
319+
ASSERT_FALSE(hadError);
320+
321+
auto *conjunction = &cs.getConstraints().front();
322+
ASSERT_EQ(conjunction->getKind(), ConstraintKind::Conjunction);
323+
324+
auto nested = conjunction->getNestedConstraints();
325+
ASSERT_EQ(nested.size(), 4);
326+
327+
auto *subjectConstraint = nested[0];
328+
auto *trueConstraint = nested[1];
329+
auto *falseConstraint = nested[2];
330+
auto *joinConstraint = nested[3];
331+
332+
auto *switchStmtLoc = cs.getConstraintLocator(
333+
switchExpr, LocatorPathElt::SyntacticElement(switchStmt));
334+
335+
// These currently all get the switch statement locator.
336+
ASSERT_EQ(subjectConstraint->getLocator(), switchStmtLoc);
337+
ASSERT_EQ(trueConstraint->getLocator(), switchStmtLoc);
338+
ASSERT_EQ(falseConstraint->getLocator(), switchStmtLoc);
339+
340+
auto *joinLoc = cs.getConstraintLocator(
341+
switchStmtLoc,
342+
LocatorPathElt::SyntacticElement(joinConstraint->getSyntacticElement()));
343+
ASSERT_EQ(joinConstraint->getLocator(), joinLoc);
344+
}

0 commit comments

Comments
 (0)