|
12 | 12 |
|
13 | 13 | #include "TestContext.h"
|
14 | 14 | #include "swift/AST/Expr.h"
|
| 15 | +#include "swift/AST/Pattern.h" |
| 16 | +#include "swift/AST/Stmt.h" |
15 | 17 | #include "gtest/gtest.h"
|
16 | 18 |
|
17 | 19 | using namespace swift;
|
@@ -136,6 +138,63 @@ TEST(SourceLoc, AssignExpr) {
|
136 | 138 | EXPECT_EQ(SourceRange(), invalidAll->getSourceRange());
|
137 | 139 | }
|
138 | 140 |
|
| 141 | +TEST(SourceLoc, StmtConditionElement) { |
| 142 | + TestContext C; |
| 143 | + |
| 144 | + // In a pattern binding statement condition element the SourceRange is only |
| 145 | + // valid iff the Initializer has a valid end loc and either: |
| 146 | + // a. the IntroducerLoc has a valid start loc |
| 147 | + // b. if the IntroducerLoc is invalid, the pattern has a valid start loc |
| 148 | + // If neither of these hold, source range must be invalid. |
| 149 | + |
| 150 | + auto bufferID = C.Ctx.SourceMgr // 0123456789012345678901234567890 |
| 151 | + .addMemBufferCopy("if let x = Optional.some(1) { }"); |
| 152 | + SourceLoc start = C.Ctx.SourceMgr.getLocForBufferStart(bufferID); |
| 153 | + |
| 154 | + auto vardecl = new (C.Ctx) VarDecl( false, true, start.getAdvancedLoc(7) |
| 155 | + , C.Ctx.getIdentifier("x") |
| 156 | + , Type() |
| 157 | + , nullptr); |
| 158 | + auto pattern = new (C.Ctx) NamedPattern(vardecl); |
| 159 | + auto init = new (C.Ctx) IntegerLiteralExpr( "1", start.getAdvancedLoc(25) |
| 160 | + , false); |
| 161 | + |
| 162 | + // Case a, when the IntroducerLoc is valid. |
| 163 | + auto introducer = StmtConditionElement( start.getAdvancedLoc(3) |
| 164 | + , pattern, init); |
| 165 | + |
| 166 | + EXPECT_EQ(start.getAdvancedLoc(3), introducer.getStartLoc()); |
| 167 | + EXPECT_EQ(start.getAdvancedLoc(25), introducer.getEndLoc()); |
| 168 | + EXPECT_EQ( SourceRange(start.getAdvancedLoc(3), start.getAdvancedLoc(25)) |
| 169 | + , introducer.getSourceRange()); |
| 170 | + |
| 171 | + // Case b, when the IntroducerLoc is invalid, but the pattern has a valid loc. |
| 172 | + auto patternStmtCond = StmtConditionElement(SourceLoc(), pattern, init); |
| 173 | + |
| 174 | + EXPECT_EQ(start.getAdvancedLoc(7), patternStmtCond.getStartLoc()); |
| 175 | + EXPECT_EQ(start.getAdvancedLoc(25), patternStmtCond.getEndLoc()); |
| 176 | + EXPECT_EQ( SourceRange(start.getAdvancedLoc(7), start.getAdvancedLoc(25)) |
| 177 | + , patternStmtCond.getSourceRange()); |
| 178 | + |
| 179 | + // If the IntroducerLoc is valid but the stmt cond init is invalid. |
| 180 | + auto invalidInit = new (C.Ctx) IntegerLiteralExpr("1", SourceLoc(), false); |
| 181 | + auto introducerStmtInvalid = StmtConditionElement( start.getAdvancedLoc(3) |
| 182 | + , pattern, invalidInit); |
| 183 | + |
| 184 | + EXPECT_EQ(SourceLoc(), introducerStmtInvalid.getStartLoc()); |
| 185 | + EXPECT_EQ(SourceLoc(), introducerStmtInvalid.getEndLoc()); |
| 186 | + EXPECT_EQ(SourceRange(), introducerStmtInvalid.getSourceRange()); |
| 187 | + |
| 188 | + // If the IntroducerLoc is invalid, the pattern is valid, but the stmt cond |
| 189 | + // init is invalid. |
| 190 | + auto patternStmtInvalid = StmtConditionElement( SourceLoc(), pattern |
| 191 | + , invalidInit); |
| 192 | + |
| 193 | + EXPECT_EQ(SourceLoc(), patternStmtInvalid.getStartLoc()); |
| 194 | + EXPECT_EQ(SourceLoc(), patternStmtInvalid.getEndLoc()); |
| 195 | + EXPECT_EQ(SourceRange(), patternStmtInvalid.getSourceRange()); |
| 196 | +} |
| 197 | + |
139 | 198 | TEST(SourceLoc, TupleExpr) {
|
140 | 199 | TestContext C;
|
141 | 200 |
|
|
0 commit comments