Skip to content

Commit 9d1a3fc

Browse files
committed
[Lexer] Trim comments off operator-identifier before tokenize
Previously, builtin operators followed by comment block were tokenized as normal operators (e.g. tok::oper_binary_spaced) instead of dedicated token(e.g. tok::equal). That used to cause strange parse errors: test.swift:1:3: error: use of unresolved operator '=' _ =/* */2 ^
1 parent c487c38 commit 9d1a3fc

File tree

2 files changed

+27
-19
lines changed

2 files changed

+27
-19
lines changed

lib/Parse/Lexer.cpp

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,26 @@ void Lexer::lexOperatorIdentifier() {
703703
bool leftBound = isLeftBound(TokStart, BufferStart);
704704
bool rightBound = isRightBound(CurPtr, leftBound, CodeCompletionPtr);
705705

706+
if (CurPtr-TokStart > 2) {
707+
// If there is a "//" in the middle of an identifier token, it starts
708+
// a single-line comment.
709+
auto Pos = StringRef(TokStart, CurPtr-TokStart).find("//");
710+
if (Pos != StringRef::npos) {
711+
CurPtr = TokStart+Pos;
712+
// Next token is a comment, which counts as whitespace.
713+
rightBound = false;
714+
}
715+
716+
// If there is a "/*" in the middle of an identifier token, it starts
717+
// a multi-line comment.
718+
Pos = StringRef(TokStart, CurPtr-TokStart).find("/*");
719+
if (Pos != StringRef::npos) {
720+
CurPtr = TokStart+Pos;
721+
// Next token is a comment, which counts as whitespace.
722+
rightBound = false;
723+
}
724+
}
725+
706726
// Match various reserved words.
707727
if (CurPtr-TokStart == 1) {
708728
switch (TokStart[0]) {
@@ -771,27 +791,9 @@ void Lexer::lexOperatorIdentifier() {
771791
return formToken(tok::unknown, TokStart);
772792
}
773793
} else {
774-
// If there is a "//" in the middle of an identifier token, it starts
775-
// a single-line comment.
776-
auto Pos = StringRef(TokStart, CurPtr-TokStart).find("//");
777-
if (Pos != StringRef::npos) {
778-
CurPtr = TokStart+Pos;
779-
// Next token is a comment, which counts as whitespace.
780-
rightBound = false;
781-
}
782-
783-
// If there is a "/*" in the middle of an identifier token, it starts
784-
// a multi-line comment.
785-
Pos = StringRef(TokStart, CurPtr-TokStart).find("/*");
786-
if (Pos != StringRef::npos) {
787-
CurPtr = TokStart+Pos;
788-
// Next token is a comment, which counts as whitespace.
789-
rightBound = false;
790-
}
791-
792794
// Verify there is no "*/" in the middle of the identifier token, we reject
793795
// it as potentially ending a block comment.
794-
Pos = StringRef(TokStart, CurPtr-TokStart).find("*/");
796+
auto Pos = StringRef(TokStart, CurPtr-TokStart).find("*/");
795797
if (Pos != StringRef::npos) {
796798
diagnose(TokStart+Pos, diag::lex_unexpected_block_comment_end);
797799
return formToken(tok::unknown, TokStart);

test/Parse/comment_operator.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,9 @@ func test6() { _ = 1+/* */2 } // expected-error {{'+' is not a p
2727
_ = foo!// this is dangerous
2828
_ = 1 +/**/ 2
2929
_ = 1 +/* hi */2
30+
31+
// Ensure built-in operators are properly tokenized.
32+
_ =/**/2
33+
_/**/= 2
34+
typealias A = () ->/* */()
35+
func test7(x: Int) { _ = x./* desc */ } // expected-error {{expected member name following '.'}}

0 commit comments

Comments
 (0)