Lexer: Don't split an operator '.<' from '.<#placeholder#>'

'.<#placeholder#>' is actually an unresolved reference where the name is
an editor placeholder, not the operator '.<' followed by #placeholder#>.

rdar://problem/28457876
This commit is contained in:
David Farler
2017-01-25 13:47:32 -08:00
parent 3e671d2fe0
commit ede6bf7a80
2 changed files with 40 additions and 0 deletions

View File

@@ -678,6 +678,19 @@ static bool isRightBound(const char *tokEnd, bool isLeftBound,
}
}
static bool rangeContainsPlaceholderEnd(const char *CurPtr,
const char *End) {
while (CurPtr++ < End - 1) {
if (*CurPtr== '\n') {
return false;
}
if (CurPtr[0] == '#' && CurPtr[1] == '>') {
return true;
}
}
return false;
}
/// lexOperatorIdentifier - Match identifiers formed out of punctuation.
void Lexer::lexOperatorIdentifier() {
const char *TokStart = CurPtr-1;
@@ -697,6 +710,10 @@ void Lexer::lexOperatorIdentifier() {
// started with a '.'.
if (*CurPtr == '.' && *TokStart != '.')
break;
if (Identifier::isEditorPlaceholder(StringRef(CurPtr, 2)) &&
rangeContainsPlaceholderEnd(CurPtr + 2, BufferEnd)) {
break;
}
} while (advanceIfValidContinuationOfOperator(CurPtr, BufferEnd));
if (CurPtr-TokStart > 2) {

View File

@@ -13,3 +13,26 @@ struct I: _ExpressibleByImageLiteral {
// CHECK: <gvar>let <name>z</name>: I? = <object-literal-expression>#<name>imageLiteral</name>(<arg><name>resourceName</name>: "hello.png"</arg>)</object-literal-expression></gvar>
let z: I? = #imageLiteral(resourceName: "hello.png")
func before() {}
// CHECK-AFTER: <ffunc>func <name>before()</name> {}</ffunc>
_ = .<#line#>
_ = 1<#line
_ = 1<#line#>
_ = a.+<#file#>
_ = x.<; <# #>;
_ = 2.<#file(2)
<##>
x <##> y
_ = .<#placeholder#>
_ = #colorLiteral(red: 0.0, green: 0.0, blue: 0.0, alpha: 1.0)
.<# place #> #fileLiteral(resourceName: "sdfds") .<# holder #>
.<##>#imageLiteral(resourceName: <# name #>)x.<##>
func after() {}
// CHECK-AFTER: _ = <object-literal-expression>#<name>colorLiteral</name>(<arg><name>red</name>: 0.0</arg>, <arg><name>green</name>: 0.0</arg>, <arg><name>blue</name>: 0.0</arg>, <arg><name>alpha</name>: 1.0</arg>)</object-literal-expression>
// CHECK-AFTER: .<# place #> <object-literal-expression>#<name>fileLiteral</name>(<arg><name>resourceName</name>: "sdfds"</arg>)</object-literal-expression> .<# holder #>
// CHECK-AFTER: .<##><object-literal-expression>#<name>imageLiteral</name>(<arg><name>resourceName</name>: <# name #></arg>)</object-literal-expression>x.<##>
// CHECK-AFTER: <ffunc>func <name>after()</name> {}</ffunc>