|
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;
|
@@ -101,6 +103,63 @@ TEST(SourceLoc, AssignExpr) {
|
101 | 103 | EXPECT_EQ(SourceRange(), invalidAll->getSourceRange());
|
102 | 104 | }
|
103 | 105 |
|
| 106 | +TEST(SourceLoc, StmtConditionElement) { |
| 107 | + TestContext C; |
| 108 | + |
| 109 | + // In a pattern binding statement condition element the SourceRange is only |
| 110 | + // valid iff the Initializer has a valid end loc and either: |
| 111 | + // a. the IntroducerLoc has a valid start loc |
| 112 | + // b. if the IntroducerLoc is invalid, the pattern has a valid start loc |
| 113 | + // If neither of these hold, source range must be invalid. |
| 114 | + |
| 115 | + auto bufferID = C.Ctx.SourceMgr // 0123456789012345678901234567890 |
| 116 | + .addMemBufferCopy("if let x = Optional.some(1) { }"); |
| 117 | + SourceLoc start = C.Ctx.SourceMgr.getLocForBufferStart(bufferID); |
| 118 | + |
| 119 | + auto vardecl = new (C.Ctx) VarDecl( false, true, start.getAdvancedLoc(7) |
| 120 | + , C.Ctx.getIdentifier("x") |
| 121 | + , Type() |
| 122 | + , nullptr); |
| 123 | + auto pattern = new (C.Ctx) NamedPattern(vardecl); |
| 124 | + auto init = new (C.Ctx) IntegerLiteralExpr( "1", start.getAdvancedLoc(25) |
| 125 | + , false); |
| 126 | + |
| 127 | + // Case a, when the IntroducerLoc is valid. |
| 128 | + auto introducer = StmtConditionElement( start.getAdvancedLoc(3) |
| 129 | + , pattern, init); |
| 130 | + |
| 131 | + EXPECT_EQ(start.getAdvancedLoc(3), introducer.getStartLoc()); |
| 132 | + EXPECT_EQ(start.getAdvancedLoc(25), introducer.getEndLoc()); |
| 133 | + EXPECT_EQ( SourceRange(start.getAdvancedLoc(3), start.getAdvancedLoc(25)) |
| 134 | + , introducer.getSourceRange()); |
| 135 | + |
| 136 | + // Case b, when the IntroducerLoc is invalid, but the pattern has a valid loc. |
| 137 | + auto patternStmtCond = StmtConditionElement(SourceLoc(), pattern, init); |
| 138 | + |
| 139 | + EXPECT_EQ(start.getAdvancedLoc(7), patternStmtCond.getStartLoc()); |
| 140 | + EXPECT_EQ(start.getAdvancedLoc(25), patternStmtCond.getEndLoc()); |
| 141 | + EXPECT_EQ( SourceRange(start.getAdvancedLoc(7), start.getAdvancedLoc(25)) |
| 142 | + , patternStmtCond.getSourceRange()); |
| 143 | + |
| 144 | + // If the IntroducerLoc is valid but the stmt cond init is invalid. |
| 145 | + auto invalidInit = new (C.Ctx) IntegerLiteralExpr("1", SourceLoc(), false); |
| 146 | + auto introducerStmtInvalid = StmtConditionElement( start.getAdvancedLoc(3) |
| 147 | + , pattern, invalidInit); |
| 148 | + |
| 149 | + EXPECT_EQ(SourceLoc(), introducerStmtInvalid.getStartLoc()); |
| 150 | + EXPECT_EQ(SourceLoc(), introducerStmtInvalid.getEndLoc()); |
| 151 | + EXPECT_EQ(SourceRange(), introducerStmtInvalid.getSourceRange()); |
| 152 | + |
| 153 | + // If the IntroducerLoc is invalid, the pattern is valid, but the stmt cond |
| 154 | + // init is invalid. |
| 155 | + auto patternStmtInvalid = StmtConditionElement( SourceLoc(), pattern |
| 156 | + , invalidInit); |
| 157 | + |
| 158 | + EXPECT_EQ(SourceLoc(), patternStmtInvalid.getStartLoc()); |
| 159 | + EXPECT_EQ(SourceLoc(), patternStmtInvalid.getEndLoc()); |
| 160 | + EXPECT_EQ(SourceRange(), patternStmtInvalid.getSourceRange()); |
| 161 | +} |
| 162 | + |
104 | 163 | TEST(SourceLoc, TupleExpr) {
|
105 | 164 | TestContext C;
|
106 | 165 |
|
|
0 commit comments