Skip to content

Commit e6f263f

Browse files
authored
[SyntaxColor] Respect keywords' syntax kind when they appear in conditions. (#5076)
Keywords like 'let' can serve as argument labels. When they do so, we should highlight them as identifiers instead of keywords. However, the check for this situation seems overly lenient so that when 'let', 'var' appear in conditions of IfStmt or GuardStmt, they are wrongly highlighted as identifiers too. This commit strengthens the checking to preserve keywords' identity in these statements. rdar://28297337
1 parent c84d8c4 commit e6f263f

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

lib/IDE/SyntaxModel.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,23 @@ struct SyntaxModelContext::Implementation {
4646
SrcMgr(SrcFile.getASTContext().SourceMgr) {}
4747
};
4848

49+
static bool canFindSurroundingParens(ArrayRef<Token> Toks,
50+
const unsigned Current) {
51+
bool LeftOk = false;
52+
bool RightOk = false;
53+
for (unsigned Offset = 1; ; Offset ++) {
54+
if (Current < Offset || Current + Offset >= Toks.size())
55+
return false;
56+
auto &L = Toks[Current - Offset];
57+
auto &R = Toks[Current + Offset];
58+
LeftOk |= L.getKind() == tok::l_paren;
59+
RightOk |= R.getKind() == tok::r_paren;
60+
if (LeftOk && RightOk)
61+
return true;
62+
}
63+
llvm_unreachable("unreachable exit condition");
64+
}
65+
4966
SyntaxModelContext::SyntaxModelContext(SourceFile &SrcFile)
5067
: Impl(*new Implementation(SrcFile)) {
5168
const bool IsPlayground = Impl.LangOpts.Playground;
@@ -103,7 +120,8 @@ SyntaxModelContext::SyntaxModelContext(SourceFile &SrcFile)
103120
Tokens[I-1].getKind() == tok::comma) &&
104121
(Tokens[I+1].getKind() == tok::colon ||
105122
Tokens[I+1].getKind() == tok::identifier ||
106-
Tokens[I+1].isKeyword())) {
123+
Tokens[I+1].isKeyword()) &&
124+
canFindSurroundingParens(Tokens, I)) {
107125
// Keywords are allowed as argument labels and should be treated as
108126
// identifiers. The exception is '_' which is not a name.
109127
Kind = SyntaxNodeKind::Identifier;

test/IDE/coloring.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,13 @@ func foo1() {
545545
// CHECK: <kw>_</kw> = (<kw>_</kw>: <int>0</int>, <kw>_</kw>: <int>2</int>)
546546
}
547547

548+
func foo2(O1 : Int?, O2: Int?, O3: Int?) {
549+
guard let _ = O1, var _ = O2, let _ = O3 else { }
550+
// CHECK: <kw>guard</kw> <kw>let</kw> <kw>_</kw> = O1, <kw>var</kw> <kw>_</kw> = O2, <kw>let</kw> <kw>_</kw> = O3 <kw>else</kw> { }
551+
if let _ = O1, var _ = O2, let _ = O3 {}
552+
// CHECK: <kw>if</kw> <kw>let</kw> <kw>_</kw> = O1, <kw>var</kw> <kw>_</kw> = O2, <kw>let</kw> <kw>_</kw> = O3 {}
553+
}
554+
548555
// Keep this as the last test
549556
/**
550557
Trailing off ...

0 commit comments

Comments
 (0)