Skip to content

Commit 8030d44

Browse files
committed
[SyntaxMap] Fold unary minus into numeric literals
Unlike other prefix operators, unary minus is folded into the NumberLiteralExpr in the parser. This commit recreates this effect in the lexer-based syntax map so that token ranges will include the leading minus. rdar://problem/20205885
1 parent 4cd82bf commit 8030d44

File tree

4 files changed

+48
-3
lines changed

4 files changed

+48
-3
lines changed

lib/IDE/SyntaxModel.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ SyntaxModelContext::SyntaxModelContext(SourceFile &SrcFile)
5858
/*TokenizeInterpolatedString=*/true);
5959
std::vector<SyntaxNode> Nodes;
6060
SourceLoc AttrLoc;
61+
SourceLoc UnaryMinusLoc;
6162
auto LiteralStartLoc = Optional<SourceLoc>();
6263
for (unsigned I = 0, E = Tokens.size(); I != E; ++I) {
6364
auto &Tok = Tokens[I];
@@ -119,9 +120,28 @@ SyntaxModelContext::SyntaxModelContext(SourceFile &SrcFile)
119120
Kind = SyntaxNodeKind::Identifier;
120121
break;
121122
case tok::dollarident: Kind = SyntaxNodeKind::DollarIdent; break;
122-
case tok::integer_literal: Kind = SyntaxNodeKind::Integer; break;
123-
case tok::floating_literal: Kind = SyntaxNodeKind::Floating; break;
124123
case tok::string_literal: Kind = SyntaxNodeKind::String; break;
124+
125+
case tok::integer_literal:
126+
Kind = SyntaxNodeKind::Integer;
127+
if (UnaryMinusLoc.isValid()) {
128+
Loc = UnaryMinusLoc;
129+
Length = *Length + SM.getByteDistance(UnaryMinusLoc, Tok.getLoc());
130+
}
131+
break;
132+
case tok::floating_literal:
133+
Kind = SyntaxNodeKind::Floating;
134+
if (UnaryMinusLoc.isValid()) {
135+
Loc = UnaryMinusLoc;
136+
Length = *Length + SM.getByteDistance(UnaryMinusLoc, Tok.getLoc());
137+
}
138+
break;
139+
140+
case tok::oper_prefix:
141+
if (Tok.getText() == "-")
142+
UnaryMinusLoc = Loc;
143+
continue;
144+
125145
case tok::comment:
126146
if (Tok.getText().startswith("///") ||
127147
(IsPlayground && Tok.getText().startswith("//:")))
@@ -179,6 +199,8 @@ SyntaxModelContext::SyntaxModelContext(SourceFile &SrcFile)
179199
}
180200
}
181201

202+
UnaryMinusLoc = SourceLoc(); // Reset.
203+
182204
assert(Loc.isValid());
183205
assert(Nodes.empty() || SM.isBeforeInBuffer(Nodes.back().Range.getStart(),
184206
Loc));

test/IDE/coloring.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,17 @@ func funcTakingFor(for internalName: Int) {}
454454
func funcTakingIn(in internalName: Int) {}
455455
// CHECK: <kw>func</kw> funcTakingIn(in internalName: <type>Int</type>) {}
456456

457+
_ = 123
458+
// CHECK: <int>123</int>
459+
_ = -123
460+
// CHECK: <int>-123</int>
461+
_ = -1
462+
// CHECK: <int>-1</int>
463+
_ = -0x123
464+
// CHECK: <int>-0x123</int>
465+
_ = -3.1e-5
466+
// CHECK: <float>-3.1e-5</float>
467+
457468
"--\"\(x) --"
458469
// CHECK: <str>"--\"</str>\<anchor>(</anchor>x<anchor>)</anchor><str> --"</str>
459470

test/SourceKit/SyntaxMapData/Inputs/syntaxmap.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,5 @@ func bar() {}
4747
// radar:1234567
4848
// mailto:thisisnotmail
4949
// unknownprotocol://awesomeguy.com
50+
51+
_ = -123

test/SourceKit/SyntaxMapData/syntaxmap.swift.response

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
key.offset: 0,
3-
key.length: 849,
3+
key.length: 859,
44
key.diagnostic_stage: source.diagnostic.stage.swift.parse,
55
key.syntaxmap: [
66
{
@@ -412,6 +412,16 @@
412412
key.kind: source.lang.swift.syntaxtype.comment,
413413
key.offset: 813,
414414
key.length: 36
415+
},
416+
{
417+
key.kind: source.lang.swift.syntaxtype.keyword,
418+
key.offset: 850,
419+
key.length: 1
420+
},
421+
{
422+
key.kind: source.lang.swift.syntaxtype.number,
423+
key.offset: 854,
424+
key.length: 4
415425
}
416426
]
417427
}

0 commit comments

Comments
 (0)