It might be simpler to pass `SourceLocation` object instead of splitting it into `start` and `end`, and creating another SourceLocation object using the same `start` and `end` later.
In all but one case the function was called with the default argument value.
And when it was location, the location should be valid (see Parser::parseElementaryOperation()).
The function SourceLocation::isEmpty() had somewhat dual role.
Sometimes it indicates that the SourceLocation is invalid.
Sometimes it means that there is no corresponding source text.
Hence the proposal is to replace it with two functions, isValid() and hasText().
I also removed Scanner::sourceAt(). (Do we have a rule of thumb to remove unused code?)
Since hasText() checks that start and end are valid indices for source, I adjusted a couple of tests to avoid empty source strings.
- unique_ptr is more flexible and generally recommended for factory methods. It gets automatically converted to shared_ptr if necessary. Returning shared_ptr, on the other hand, forces the caller to use shared_ptr because a conversion to unique_ptr is not possible.