From 11405c513961b9c3ea274d9e07ede4b4caf6c4cc Mon Sep 17 00:00:00 2001 From: Paul Redmond Date: Tue, 26 May 2020 13:00:30 -0400 Subject: [PATCH] LibJS: Fix incorrect token column values (#2401) - initializing m_line_column to 1 in the lexer results in incorrect column values in tokens on the first line of input. - not incrementing m_line_column when EOF is reached results in an incorrect column value on the last token. --- Libraries/LibJS/Lexer.cpp | 8 ++++++-- Libraries/LibJS/Lexer.h | 8 ++++---- Libraries/LibJS/MarkupGenerator.cpp | 6 ++---- Userland/js.cpp | 10 +++------- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/Libraries/LibJS/Lexer.cpp b/Libraries/LibJS/Lexer.cpp index dc094f4f5de..f67d8ff9bb4 100644 --- a/Libraries/LibJS/Lexer.cpp +++ b/Libraries/LibJS/Lexer.cpp @@ -149,8 +149,12 @@ Lexer::Lexer(StringView source) void Lexer::consume() { - if (m_position >= m_source.length()) { - m_position = m_source.length() + 1; + if (m_position > m_source.length()) + return; + + if (m_position == m_source.length()) { + m_position++; + m_line_column++; m_current_char = EOF; return; } diff --git a/Libraries/LibJS/Lexer.h b/Libraries/LibJS/Lexer.h index e60c2dd654b..71f22b05352 100644 --- a/Libraries/LibJS/Lexer.h +++ b/Libraries/LibJS/Lexer.h @@ -55,11 +55,11 @@ private: bool match(char, char, char, char) const; StringView m_source; - size_t m_position = 0; + size_t m_position { 0 }; Token m_current_token; - int m_current_char = 0; - size_t m_line_number = 1; - size_t m_line_column = 1; + int m_current_char { 0 }; + size_t m_line_number { 1 }; + size_t m_line_column { 0 }; struct TemplateState { bool in_expr; diff --git a/Libraries/LibJS/MarkupGenerator.cpp b/Libraries/LibJS/MarkupGenerator.cpp index 2b0e583611d..001bf3971a4 100644 --- a/Libraries/LibJS/MarkupGenerator.cpp +++ b/Libraries/LibJS/MarkupGenerator.cpp @@ -43,9 +43,7 @@ String MarkupGenerator::html_from_source(const StringView& source) auto lexer = Lexer(source); for (auto token = lexer.next(); token.type() != TokenType::Eof; token = lexer.next()) { auto length = token.value().length(); - auto start = token.line_column(); - // FIXME: Why do we need to do this magic math? This math isn't even accurate enough, code like "let x = 10" renders incorrectly. - start = start < 2 ? 0 : start - 2; + auto start = token.line_column() - 1; if (start > source_cursor) { builder.append(source.substring_view(source_cursor, start - source_cursor)); @@ -321,4 +319,4 @@ String MarkupGenerator::wrap_string_in_style(String source, StyleType type) return String::format("%s", style_from_style_type(type).characters(), source.characters()); } -} \ No newline at end of file +} diff --git a/Userland/js.cpp b/Userland/js.cpp index a4adc7d084f..24b8ff8e602 100644 --- a/Userland/js.cpp +++ b/Userland/js.cpp @@ -528,19 +528,15 @@ int main(int argc, char** argv) editor.stylize(span, styles); }; editor.strip_styles(); - StringBuilder builder; - builder.append(editor.line()); - // FIXME: The lexer returns weird position information without this - builder.append(" "); - String str = builder.build(); size_t open_indents = s_repl_line_level; - JS::Lexer lexer(str); + auto line = editor.line(); + JS::Lexer lexer(line); bool indenters_starting_line = true; for (JS::Token token = lexer.next(); token.type() != JS::TokenType::Eof; token = lexer.next()) { auto length = token.value().length(); - auto start = token.line_column() - 2; + auto start = token.line_column() - 1; auto end = start + length; if (indenters_starting_line) { if (token.type() != JS::TokenType::ParenClose && token.type() != JS::TokenType::BracketClose && token.type() != JS::TokenType::CurlyClose) {