[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
This commit is contained in:
Ben Langmuir
2016-03-15 10:35:34 -07:00
parent 4cd82bff93
commit 8030d44826
4 changed files with 48 additions and 3 deletions

View File

@@ -58,6 +58,7 @@ SyntaxModelContext::SyntaxModelContext(SourceFile &SrcFile)
/*TokenizeInterpolatedString=*/true);
std::vector<SyntaxNode> Nodes;
SourceLoc AttrLoc;
SourceLoc UnaryMinusLoc;
auto LiteralStartLoc = Optional<SourceLoc>();
for (unsigned I = 0, E = Tokens.size(); I != E; ++I) {
auto &Tok = Tokens[I];
@@ -119,9 +120,28 @@ SyntaxModelContext::SyntaxModelContext(SourceFile &SrcFile)
Kind = SyntaxNodeKind::Identifier;
break;
case tok::dollarident: Kind = SyntaxNodeKind::DollarIdent; break;
case tok::integer_literal: Kind = SyntaxNodeKind::Integer; break;
case tok::floating_literal: Kind = SyntaxNodeKind::Floating; break;
case tok::string_literal: Kind = SyntaxNodeKind::String; break;
case tok::integer_literal:
Kind = SyntaxNodeKind::Integer;
if (UnaryMinusLoc.isValid()) {
Loc = UnaryMinusLoc;
Length = *Length + SM.getByteDistance(UnaryMinusLoc, Tok.getLoc());
}
break;
case tok::floating_literal:
Kind = SyntaxNodeKind::Floating;
if (UnaryMinusLoc.isValid()) {
Loc = UnaryMinusLoc;
Length = *Length + SM.getByteDistance(UnaryMinusLoc, Tok.getLoc());
}
break;
case tok::oper_prefix:
if (Tok.getText() == "-")
UnaryMinusLoc = Loc;
continue;
case tok::comment:
if (Tok.getText().startswith("///") ||
(IsPlayground && Tok.getText().startswith("//:")))
@@ -179,6 +199,8 @@ SyntaxModelContext::SyntaxModelContext(SourceFile &SrcFile)
}
}
UnaryMinusLoc = SourceLoc(); // Reset.
assert(Loc.isValid());
assert(Nodes.empty() || SM.isBeforeInBuffer(Nodes.back().Range.getStart(),
Loc));