End location of the SourceRange of a NumberLiteralExpr?


(David Rönnqvist) #1

I’m trying to solve SR-4715, which is about improving the fixit for the diagnostic about out-of-order arguments. Currently I’m stuck with an issue where I can’t figure out the end of an argument expression in the TupleExpr that I have.

It would seem that this should work:

auto tuple = cast<TupleExpr>(ArgExpr);
auto end = tuple->getElement(argIdx)->getEndLoc();

but I have one unit test that’s failing because the range of the argument is incorrect. The only difference I can see in that test, compared to the similar ones that are passing is that the argument is a number with more than one digit. Looking at NumberLiteralExpr (the superclass of IntegerLiteralExpr) I can see that getSourceRange() only returns the DigitsLoc source location, not a range with a length.

If I instead get the CharSourceRange for that range, and get the End source location from that, it get’s me the location that I’m after:

auto end = Lexer::getCharSourceRangeFromSourceRange(
    TC.Context.SourceMgr,
    tuple->getElement(argIdx)->getSourceRange()
).getEnd();

Is this the correct way to get the location of the end of a multi digit NumberLiteralExpr or should the first approach have worked?

Perhaps I don’t understand the distinction between SourceRange and CharSourceRange. Is SourceRange the location of the token (where Start and End would be the same) and CharSourceRange the location of the characters?

Kind regards,
David


(Jordan Rose) #2

Hi, David. From the docs for SourceRange:

/// SourceRange in swift is a pair of locations. However, note that the end
/// location is the start of the last token in the range, not the last character
/// in the range.

This is mainly an optimization for single-token expressions, like number literals: they only need to store one location to represent the entire range. So your code is the right way to go, though if you only need the end you can ask for just that:

auto end = Lexer::getLocForEndOfToken(TC.Context.SourceMgr, tuple->getElement(argIdx)->getEndLoc());

Hope that helps,
Jordan

···

On Jun 30, 2017, at 11:47, David Rönnqvist via swift-dev <swift-dev@swift.org> wrote:

I’m trying to solve SR-4715, which is about improving the fixit for the diagnostic about out-of-order arguments. Currently I’m stuck with an issue where I can’t figure out the end of an argument expression in the TupleExpr that I have.

It would seem that this should work:

auto tuple = cast<TupleExpr>(ArgExpr);
auto end = tuple->getElement(argIdx)->getEndLoc();

but I have one unit test that’s failing because the range of the argument is incorrect. The only difference I can see in that test, compared to the similar ones that are passing is that the argument is a number with more than one digit. Looking at NumberLiteralExpr (the superclass of IntegerLiteralExpr) I can see that getSourceRange() only returns the DigitsLoc source location, not a range with a length.

If I instead get the CharSourceRange for that range, and get the End source location from that, it get’s me the location that I’m after:

auto end = Lexer::getCharSourceRangeFromSourceRange(
    TC.Context.SourceMgr,
    tuple->getElement(argIdx)->getSourceRange()
).getEnd();

Is this the correct way to get the location of the end of a multi digit NumberLiteralExpr or should the first approach have worked?

Perhaps I don’t understand the distinction between SourceRange and CharSourceRange. Is SourceRange the location of the token (where Start and End would be the same) and CharSourceRange the location of the characters?

Kind regards,
David
_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev