@@ -220,3 +220,125 @@ TEST_F(SemaTest, TestMultiStmtClosureBodyParentAndDepth) {
220
220
ASSERT_EQ (cs.getParentExpr (result), closure);
221
221
ASSERT_EQ (cs.getExprDepth (result), 1 );
222
222
}
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