@@ -199,22 +199,24 @@ TEST(SourceLoc, TupleExpr) {
199
199
TestContext C;
200
200
201
201
// In a TupleExpr, if the parens are both invalid, then you can only have a
202
- // valid range iff both the first element and last element have valid ranges.
202
+ // valid range if there exists at least one expr with a valid source range.
203
+ // The tuple's source range will be the upper bound of the inner source
204
+ // ranges.
203
205
// Source ranges also have the property:
204
206
// Start.isValid() == End.isValid()
205
207
// For example, given the buffer "one", of the form:
206
208
// (tuple_expr
207
209
// (declref_expr range=[test.swift:1:0 - line:1:2] ...)
208
210
// (declref_expr range=invalid ...))
209
- // the range of this TupleExpr is SourceLoc() (invalid) .
211
+ // the range of this TupleExpr is 1:0 - 1:2 .
210
212
// v invalid v invalid
211
213
// ( one, two )
212
214
// valid ^ invalid ^
213
215
// COL: xxxxxx012xxxxxxxxxxxxxxxxx
214
- // but the SourceRange of 'one' is 1:0 - 1:2.
216
+ // and the SourceRange of 'one' is 1:0 - 1:2.
215
217
216
- // 012
217
- auto bufferID = C.Ctx .SourceMgr .addMemBufferCopy (" one" );
218
+ // 01234567
219
+ auto bufferID = C.Ctx .SourceMgr .addMemBufferCopy (" one four " );
218
220
SourceLoc start = C.Ctx .SourceMgr .getLocForBufferStart (bufferID);
219
221
220
222
auto one = new (C.Ctx ) UnresolvedDeclRefExpr (
@@ -227,22 +229,61 @@ TEST(SourceLoc, TupleExpr) {
227
229
DeclRefKind::Ordinary,
228
230
DeclNameLoc ());
229
231
232
+ auto three = new (C.Ctx ) UnresolvedDeclRefExpr (
233
+ C.Ctx .getIdentifier (" three" ),
234
+ DeclRefKind::Ordinary,
235
+ DeclNameLoc ());
236
+
237
+ auto four = new (C.Ctx ) UnresolvedDeclRefExpr (
238
+ C.Ctx .getIdentifier (" four" ),
239
+ DeclRefKind::Ordinary,
240
+ DeclNameLoc (start.getAdvancedLoc (4 )));
241
+
242
+ EXPECT_EQ (start, one->getStartLoc ());
243
+ EXPECT_EQ (SourceLoc (), two->getStartLoc ());
244
+
245
+ // a tuple with only invalid elements
246
+ SmallVector<Expr *, 2 > subExprsInvalid ({ two, three });
247
+ SmallVector<Identifier, 2 > subExprNamesInvalid (2 , Identifier ());
248
+ auto allInvalid = TupleExpr::createImplicit (C.Ctx , subExprsInvalid, subExprNamesInvalid);
249
+
250
+ EXPECT_EQ (SourceLoc (), allInvalid->getStartLoc ());
251
+ EXPECT_EQ (SourceLoc (), allInvalid->getEndLoc ());
252
+ EXPECT_EQ (SourceRange (), allInvalid->getSourceRange ());
253
+
230
254
// the tuple from the example
231
255
SmallVector<Expr *, 2 > subExprsRight ({ one, two });
232
256
SmallVector<Identifier, 2 > subExprNamesRight (2 , Identifier ());
233
257
auto rightInvalidTuple = TupleExpr::createImplicit (C.Ctx , subExprsRight, subExprNamesRight);
234
258
235
- EXPECT_EQ (start, one->getStartLoc ());
236
- EXPECT_EQ (SourceLoc (), rightInvalidTuple->getStartLoc ());
237
- EXPECT_EQ (SourceLoc (), rightInvalidTuple->getEndLoc ());
238
- EXPECT_EQ (SourceRange (), rightInvalidTuple->getSourceRange ());
259
+ EXPECT_EQ (start, rightInvalidTuple->getStartLoc ());
260
+ EXPECT_EQ (start, rightInvalidTuple->getEndLoc ());
261
+ EXPECT_EQ (SourceRange (start, start), rightInvalidTuple->getSourceRange ());
239
262
240
263
SmallVector<Expr *, 2 > subExprsLeft ({ two, one });
241
264
SmallVector<Identifier, 2 > subExprNamesLeft (2 , Identifier ());
242
265
auto leftInvalidTuple = TupleExpr::createImplicit (C.Ctx , subExprsLeft, subExprNamesLeft);
243
266
244
- EXPECT_EQ (start, one->getStartLoc ());
245
- EXPECT_EQ (SourceLoc (), leftInvalidTuple->getStartLoc ());
246
- EXPECT_EQ (SourceLoc (), leftInvalidTuple->getEndLoc ());
247
- EXPECT_EQ (SourceRange (), leftInvalidTuple->getSourceRange ());
267
+ EXPECT_EQ (start, leftInvalidTuple->getStartLoc ());
268
+ EXPECT_EQ (start, leftInvalidTuple->getEndLoc ());
269
+ EXPECT_EQ (SourceRange (start, start), leftInvalidTuple->getSourceRange ());
270
+
271
+ // Some TupleExprs are triples. If only the middle expr has a valid SourceLoc
272
+ // then the TupleExpr's SourceLoc should point at that.
273
+ SmallVector<Expr *, 3 > subExprsTriple ({ two, one, two });
274
+ SmallVector<Identifier, 3 > subExprNamesTriple (3 , Identifier ());
275
+ auto tripleValidMid = TupleExpr::createImplicit (C.Ctx , subExprsTriple, subExprNamesTriple);
276
+ EXPECT_EQ (start, tripleValidMid->getStartLoc ());
277
+ EXPECT_EQ (start, tripleValidMid->getEndLoc ());
278
+ EXPECT_EQ (SourceRange (start, start), tripleValidMid->getSourceRange ());
279
+
280
+ // Some TupleExprs are quadruples. Quadruples should point at the range from
281
+ // the first to the last valid exprs.
282
+ SmallVector<Expr *, 4 > subExprsQuad ({ one, two, four, three });
283
+ SmallVector<Identifier, 4 > subExprNamesQuad (4 , Identifier ());
284
+ auto quadValidMids = TupleExpr::createImplicit (C.Ctx , subExprsQuad, subExprNamesQuad);
285
+ EXPECT_EQ (start, quadValidMids->getStartLoc ());
286
+ EXPECT_EQ (start.getAdvancedLoc (4 ), quadValidMids->getEndLoc ());
287
+ EXPECT_EQ (SourceRange (start, start.getAdvancedLoc (4 )), quadValidMids->getSourceRange ());
288
+
248
289
}
0 commit comments