mirror of
https://github.com/RGBCube/serenity
synced 2025-05-18 08:55:07 +00:00
LibJS: Replace 'size_t line, size_t column' with 'Optional<Position>'
This is a bit nicer for two reasons: - The absence of line number/column information isn't based on 'values are zero' anymore but on Optional's value - When reporting syntax errors with position information other than the current token's position we had to store line and column ourselves, like this: auto foo_start_line = m_parser_state.m_current_token.line_number(); auto foo_start_column = m_parser_state.m_current_token.line_column(); ... syntax_error("...", foo_start_line, foo_start_column); Which now becomes: auto foo_start= position(); ... syntax_error("...", foo_start); This makes it easier to report correct positions for syntax errors that only emerge a few tokens later :^)
This commit is contained in:
parent
ed5469c1c2
commit
e07a39c816
2 changed files with 34 additions and 29 deletions
|
@ -100,21 +100,25 @@ public:
|
|||
NonnullRefPtr<Expression> parse_property_key();
|
||||
NonnullRefPtr<AssignmentExpression> parse_assignment_expression(AssignmentOp, NonnullRefPtr<Expression> lhs, int min_precedence, Associativity);
|
||||
|
||||
struct Error {
|
||||
String message;
|
||||
struct Position {
|
||||
size_t line;
|
||||
size_t column;
|
||||
};
|
||||
|
||||
struct Error {
|
||||
String message;
|
||||
Optional<Position> position;
|
||||
|
||||
String to_string() const
|
||||
{
|
||||
if (line == 0 || column == 0)
|
||||
if (!position.has_value())
|
||||
return message;
|
||||
return String::formatted("{} (line: {}, column: {})", message, line, column);
|
||||
return String::formatted("{} (line: {}, column: {})", message, position.value().line, position.value().column);
|
||||
}
|
||||
|
||||
String source_location_hint(const StringView& source, const char spacer = ' ', const char indicator = '^') const
|
||||
{
|
||||
if (line == 0 || column == 0)
|
||||
if (!position.has_value())
|
||||
return {};
|
||||
// We need to modify the source to match what the lexer considers one line - normalizing
|
||||
// line terminators to \n is easier than splitting using all different LT characters.
|
||||
|
@ -124,9 +128,9 @@ public:
|
|||
source_string.replace(LINE_SEPARATOR, "\n");
|
||||
source_string.replace(PARAGRAPH_SEPARATOR, "\n");
|
||||
StringBuilder builder;
|
||||
builder.append(source_string.split_view('\n', true)[line - 1]);
|
||||
builder.append(source_string.split_view('\n', true)[position.value().line - 1]);
|
||||
builder.append('\n');
|
||||
for (size_t i = 0; i < column - 1; ++i)
|
||||
for (size_t i = 0; i < position.value().column - 1; ++i)
|
||||
builder.append(spacer);
|
||||
builder.append(indicator);
|
||||
return builder.build();
|
||||
|
@ -156,13 +160,14 @@ private:
|
|||
bool match(TokenType type) const;
|
||||
bool done() const;
|
||||
void expected(const char* what);
|
||||
void syntax_error(const String& message, size_t line = 0, size_t column = 0);
|
||||
void syntax_error(const String& message, Optional<Position> = {});
|
||||
Token consume();
|
||||
Token consume(TokenType type);
|
||||
Token consume_and_validate_numeric_literal();
|
||||
void consume_or_insert_semicolon();
|
||||
void save_state();
|
||||
void load_state();
|
||||
Position position() const;
|
||||
|
||||
struct ParserState {
|
||||
Lexer m_lexer;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue