diff --git a/config.yml b/config.yml index 38db0171f..9718ca6d8 100644 --- a/config.yml +++ b/config.yml @@ -12,7 +12,7 @@ errors: types: - name: UnexpectedError message: - template: "%s. Expected: `%s`, found: `%s`." + template: "%s. Expected: %s, found: %s." arguments: - description - expected @@ -30,10 +30,10 @@ errors: - name: UnexpectedTokenError message: - template: "Found `%s` when expecting `%s` at (%u:%u)." + template: "Found %s when expecting %s at (%u:%u)." arguments: - - token_type_to_string(found->type) - - token_type_to_string(expected_type) + - token_type_to_friendly_string(found->type) + - token_type_to_friendly_string(expected_type) - found->location.start.line - found->location.start.column diff --git a/javascript/packages/linter/test/__snapshots__/cli.test.ts.snap b/javascript/packages/linter/test/__snapshots__/cli.test.ts.snap index 30fdf699a..4d40050ba 100644 --- a/javascript/packages/linter/test/__snapshots__/cli.test.ts.snap +++ b/javascript/packages/linter/test/__snapshots__/cli.test.ts.snap @@ -277,7 +277,7 @@ test/fixtures/ignored.html.erb:6:14 `; exports[`CLI Output Formatting > diplays only parsers errors if one is present 1`] = ` -"[error] Unexpected Token. Expected: \`TOKEN_IDENTIFIER, TOKEN_AT, TOKEN_ERB_START,TOKEN_WHITESPACE, or TOKEN_NEWLINE\`, found: \`TOKEN_CHARACTER\`. (\`UNEXPECTED_ERROR\`) (parser-no-errors) +"[error] Unexpected Token. Expected: an identifier, \`@\`, \`<%\`, whitespace, or a newline, found: a character. (\`UNEXPECTED_ERROR\`) (parser-no-errors) test/fixtures/parser-errors.html.erb:2:16 diff --git a/src/include/parser_helpers.h b/src/include/parser_helpers.h index 537f7a5bc..2ceb60867 100644 --- a/src/include/parser_helpers.h +++ b/src/include/parser_helpers.h @@ -13,11 +13,21 @@ void parser_push_open_tag(const parser_T* parser, token_T* tag_name); bool parser_check_matching_tag(const parser_T* parser, hb_string_T tag_name); token_T* parser_pop_open_tag(const parser_T* parser); -void parser_append_unexpected_error( +void parser_append_unexpected_error_impl( parser_T* parser, + hb_array_T* errors, const char* description, - const char* expected, - hb_array_T* errors + token_type_T first_token, + ... +); +#define parser_append_unexpected_error(parser, errors, description, ...) \ + parser_append_unexpected_error_impl(parser, errors, description, __VA_ARGS__, TOKEN_SENTINEL) + +void parser_append_unexpected_error_string( + parser_T* parser, + hb_array_T* errors, + const char* description, + const char* expected ); void parser_append_unexpected_token_error(parser_T* parser, token_type_T expected_type, hb_array_T* errors); diff --git a/src/include/token.h b/src/include/token.h index 9680bbf6f..bac83268e 100644 --- a/src/include/token.h +++ b/src/include/token.h @@ -6,9 +6,16 @@ #include "token_struct.h" #include "util/hb_string.h" +#include + token_T* token_init(hb_string_T value, token_type_T type, lexer_T* lexer); hb_string_T token_to_string(const token_T* token); const char* token_type_to_string(token_type_T type); +const char* token_type_to_friendly_string(token_type_T type); +char* token_types_to_friendly_string_va(token_type_T first_token, ...); +char* token_types_to_friendly_string_valist(token_type_T first_token, va_list args); + +#define token_types_to_friendly_string(...) token_types_to_friendly_string_va(__VA_ARGS__, TOKEN_SENTINEL) token_T* token_copy(token_T* token); diff --git a/src/include/token_struct.h b/src/include/token_struct.h index 8ff44f04c..084cda258 100644 --- a/src/include/token_struct.h +++ b/src/include/token_struct.h @@ -49,6 +49,9 @@ typedef enum { TOKEN_EOF, } token_type_T; +// Sentinel value for variadic functions +#define TOKEN_SENTINEL 99999999 + typedef struct TOKEN_STRUCT { char* value; range_T range; diff --git a/src/parser.c b/src/parser.c index d65c2e93c..f82b355a3 100644 --- a/src/parser.c +++ b/src/parser.c @@ -260,17 +260,7 @@ static AST_HTML_TEXT_NODE_T* parser_parse_text_content(parser_T* parser, hb_arra if (token_is(parser, TOKEN_ERROR)) { free(content.value); - token_T* token = parser_consume_expected(parser, TOKEN_ERROR, document_errors); - append_unexpected_error( - "Token Error", - "not TOKEN_ERROR", - token->value, - token->location.start, - token->location.end, - document_errors - ); - - token_free(token); + parser_append_unexpected_error_string(parser, document_errors, "Token Error", "not an error token"); return NULL; } @@ -641,7 +631,7 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_html_attribute_value(parser append_unexpected_error( "Invalid quote character for HTML attribute", "single quote (') or double quote (\")", - "backtick (`)", + "a backtick", start, end, errors @@ -655,15 +645,19 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_html_attribute_value(parser return value; } + char* expected = token_types_to_friendly_string(TOKEN_IDENTIFIER, TOKEN_QUOTE, TOKEN_ERB_START); + append_unexpected_error( "Unexpected Token", - "TOKEN_IDENTIFIER, TOKEN_QUOTE, TOKEN_ERB_START", - token_type_to_string(parser->current_token->type), + expected, + token_type_to_friendly_string(parser->current_token->type), parser->current_token->location.start, parser->current_token->location.end, errors ); + free(expected); + AST_HTML_ATTRIBUTE_VALUE_NODE_T* value = ast_html_attribute_value_node_init( NULL, children, @@ -1057,9 +1051,13 @@ static AST_HTML_OPEN_TAG_NODE_T* parser_parse_html_open_tag(parser_T* parser) { parser_append_unexpected_error( parser, + errors, "Unexpected Token", - "TOKEN_IDENTIFIER, TOKEN_AT, TOKEN_ERB_START,TOKEN_WHITESPACE, or TOKEN_NEWLINE", - errors + TOKEN_IDENTIFIER, + TOKEN_AT, + TOKEN_ERB_START, + TOKEN_WHITESPACE, + TOKEN_NEWLINE ); } @@ -1474,10 +1472,17 @@ static void parser_parse_in_data_state(parser_T* parser, hb_array_T* children, h parser_append_unexpected_error( parser, + errors, "Unexpected token", - "TOKEN_ERB_START, TOKEN_HTML_DOCTYPE, TOKEN_HTML_COMMENT_START, TOKEN_IDENTIFIER, TOKEN_WHITESPACE, " - "TOKEN_NBSP, TOKEN_AT, TOKEN_BACKSLASH, or TOKEN_NEWLINE", - errors + TOKEN_ERB_START, + TOKEN_HTML_DOCTYPE, + TOKEN_HTML_COMMENT_START, + TOKEN_IDENTIFIER, + TOKEN_WHITESPACE, + TOKEN_NBSP, + TOKEN_AT, + TOKEN_BACKSLASH, + TOKEN_NEWLINE ); parser_synchronize(parser, errors); diff --git a/src/parser_helpers.c b/src/parser_helpers.c index b6a76f58c..5d309335d 100644 --- a/src/parser_helpers.c +++ b/src/parser_helpers.c @@ -8,6 +8,7 @@ #include "include/util/hb_buffer.h" #include "include/util/hb_string.h" +#include #include void parser_push_open_tag(const parser_T* parser, token_T* tag_name) { @@ -90,18 +91,45 @@ void parser_exit_foreign_content(parser_T* parser) { parser->foreign_content_type = FOREIGN_CONTENT_UNKNOWN; } -void parser_append_unexpected_error( +void parser_append_unexpected_error_impl( parser_T* parser, + hb_array_T* errors, const char* description, - const char* expected, - hb_array_T* errors + token_type_T first_token, + ... +) { + token_T* token = parser_advance(parser); + + va_list args; + va_start(args, first_token); + char* expected = token_types_to_friendly_string_valist(first_token, args); + va_end(args); + + append_unexpected_error( + description, + expected, + token_type_to_friendly_string(token->type), + token->location.start, + token->location.end, + errors + ); + + free(expected); + token_free(token); +} + +void parser_append_unexpected_error_string( + parser_T* parser, + hb_array_T* errors, + const char* description, + const char* expected ) { token_T* token = parser_advance(parser); append_unexpected_error( description, expected, - token_type_to_string(token->type), + token_type_to_friendly_string(token->type), token->location.start, token->location.end, errors diff --git a/src/token.c b/src/token.c index d584ac54f..ad1d95c08 100644 --- a/src/token.c +++ b/src/token.c @@ -3,7 +3,9 @@ #include "include/range.h" #include "include/token_struct.h" #include "include/util.h" +#include "include/util/hb_buffer.h" +#include #include #include #include @@ -78,8 +80,82 @@ const char* token_type_to_string(const token_type_T type) { case TOKEN_ERROR: return "TOKEN_ERROR"; case TOKEN_EOF: return "TOKEN_EOF"; } +} + +const char* token_type_to_friendly_string(const token_type_T type) { + switch (type) { + case TOKEN_WHITESPACE: return "whitespace"; + case TOKEN_NBSP: return "non-breaking space"; + case TOKEN_NEWLINE: return "a newline"; + case TOKEN_IDENTIFIER: return "an identifier"; + case TOKEN_HTML_DOCTYPE: return "``"; + case TOKEN_CDATA_START: return "``"; + case TOKEN_HTML_TAG_START: return "`<`"; + case TOKEN_HTML_TAG_END: return "`>`"; + case TOKEN_HTML_TAG_START_CLOSE: return "``"; + case TOKEN_HTML_COMMENT_START: return "``"; + case TOKEN_HTML_COMMENT_INVALID_END: return "`--!>`"; + case TOKEN_EQUALS: return "`=`"; + case TOKEN_QUOTE: return "a quote"; + case TOKEN_BACKTICK: return "a backtick"; + case TOKEN_BACKSLASH: return "`\\`"; + case TOKEN_DASH: return "`-`"; + case TOKEN_UNDERSCORE: return "`_`"; + case TOKEN_EXCLAMATION: return "`!`"; + case TOKEN_SLASH: return "`/`"; + case TOKEN_SEMICOLON: return "`;`"; + case TOKEN_COLON: return "`:`"; + case TOKEN_AT: return "`@`"; + case TOKEN_LT: return "`<`"; + case TOKEN_PERCENT: return "`%`"; + case TOKEN_AMPERSAND: return "`&`"; + case TOKEN_ERB_START: return "`<%`"; + case TOKEN_ERB_CONTENT: return "ERB content"; + case TOKEN_ERB_END: return "`%>`"; + case TOKEN_CHARACTER: return "a character"; + case TOKEN_ERROR: return "an error token"; + case TOKEN_EOF: return "end of file"; + } +} + +char* token_types_to_friendly_string_valist(token_type_T first_token, va_list args) { + if ((int) first_token == TOKEN_SENTINEL) { return herb_strdup(""); } + + size_t count = 0; + const char* names[32]; + token_type_T current = first_token; + + while ((int) current != TOKEN_SENTINEL && count < 32) { + names[count++] = token_type_to_friendly_string(current); + current = va_arg(args, token_type_T); + } + + hb_buffer_T buffer; + hb_buffer_init(&buffer, 128); + + for (size_t i = 0; i < count; i++) { + hb_buffer_append(&buffer, names[i]); + + if (i < count - 1) { + if (count > 2) { hb_buffer_append(&buffer, ", "); } + if (i == count - 2) { hb_buffer_append(&buffer, count == 2 ? " or " : "or "); } + } + } + + return hb_buffer_value(&buffer); +} - return "Unknown token_type_T"; +char* token_types_to_friendly_string_va(token_type_T first_token, ...) { + va_list args; + va_start(args, first_token); + char* result = token_types_to_friendly_string_valist(first_token, args); + va_end(args); + return result; } hb_string_T token_to_string(const token_T* token) { diff --git a/test/c/test_token.c b/test/c/test_token.c index 69335ad9c..3ed4a045d 100644 --- a/test/c/test_token.c +++ b/test/c/test_token.c @@ -7,6 +7,48 @@ TEST(test_token) ck_assert_str_eq(token_type_to_string(TOKEN_IDENTIFIER), "TOKEN_IDENTIFIER"); END +TEST(test_token_type_to_friendly_string) + ck_assert_str_eq(token_type_to_friendly_string(TOKEN_IDENTIFIER), "an identifier"); + ck_assert_str_eq(token_type_to_friendly_string(TOKEN_WHITESPACE), "whitespace"); + ck_assert_str_eq(token_type_to_friendly_string(TOKEN_NEWLINE), "a newline"); + ck_assert_str_eq(token_type_to_friendly_string(TOKEN_QUOTE), "a quote"); + ck_assert_str_eq(token_type_to_friendly_string(TOKEN_CHARACTER), "a character"); + ck_assert_str_eq(token_type_to_friendly_string(TOKEN_EOF), "end of file"); + ck_assert_str_eq(token_type_to_friendly_string(TOKEN_HTML_TAG_START), "`<`"); + ck_assert_str_eq(token_type_to_friendly_string(TOKEN_HTML_TAG_END), "`>`"); + ck_assert_str_eq(token_type_to_friendly_string(TOKEN_HTML_TAG_SELF_CLOSE), "`/>`"); + ck_assert_str_eq(token_type_to_friendly_string(TOKEN_HTML_TAG_START_CLOSE), "``"); + ck_assert_str_eq(token_type_to_friendly_string(TOKEN_EQUALS), "`=`"); + ck_assert_str_eq(token_type_to_friendly_string(TOKEN_SLASH), "`/`"); + ck_assert_str_eq(token_type_to_friendly_string(TOKEN_COLON), "`:`"); + ck_assert_str_eq(token_type_to_friendly_string(TOKEN_ERB_START), "`<%`"); + ck_assert_str_eq(token_type_to_friendly_string(TOKEN_ERB_END), "`%>`"); +END + +TEST(test_token_types_to_friendly_string) + char* result1 = token_types_to_friendly_string(TOKEN_IDENTIFIER); + ck_assert_str_eq(result1, "an identifier"); + free(result1); + + char* result2 = token_types_to_friendly_string(TOKEN_IDENTIFIER, TOKEN_QUOTE); + ck_assert_str_eq(result2, "an identifier or a quote"); + free(result2); + + char* result3 = token_types_to_friendly_string(TOKEN_IDENTIFIER, TOKEN_QUOTE, TOKEN_ERB_START); + ck_assert_str_eq(result3, "an identifier, a quote, or `<%`"); + free(result3); + + char* result4 = token_types_to_friendly_string(TOKEN_IDENTIFIER, TOKEN_ERB_START, TOKEN_WHITESPACE, TOKEN_NEWLINE); + ck_assert_str_eq(result4, "an identifier, `<%`, whitespace, or a newline"); + free(result4); + + char* result5 = token_types_to_friendly_string(TOKEN_HTML_TAG_START, TOKEN_HTML_TAG_END, TOKEN_EQUALS); + ck_assert_str_eq(result5, "`<`, `>`, or `=`"); + free(result5); +END + TEST(test_token_to_string) hb_buffer_T output; hb_buffer_init(&output, 1024); @@ -25,6 +67,8 @@ TCase *token_tests(void) { TCase *token = tcase_create("Token"); tcase_add_test(token, test_token); + tcase_add_test(token, test_token_type_to_friendly_string); + tcase_add_test(token, test_token_types_to_friendly_string); tcase_add_test(token, test_token_to_string); return token; diff --git a/test/snapshots/parser/attributes_test/test_0018_apostrophe_inside_single_quotes_e431474b58446f910c9425491add27a0.txt b/test/snapshots/parser/attributes_test/test_0018_apostrophe_inside_single_quotes_e431474b58446f910c9425491add27a0.txt index ce6a565a9..3b4a7ac2a 100644 --- a/test/snapshots/parser/attributes_test/test_0018_apostrophe_inside_single_quotes_e431474b58446f910c9425491add27a0.txt +++ b/test/snapshots/parser/attributes_test/test_0018_apostrophe_inside_single_quotes_e431474b58446f910c9425491add27a0.txt @@ -24,7 +24,7 @@ input: "
Text
" │ │ └── @ HTMLAttributeValueNode (location: (1:14)-(1:27)) │ │ ├── errors: (1 error) │ │ │ └── @ UnexpectedError (location: (1:18)-(1:19)) - │ │ │ ├── message: "Unescaped quote character in attribute value. Expected: `HTML entity ('/") or different quote style`, found: `'`." + │ │ │ ├── message: "Unescaped quote character in attribute value. Expected: HTML entity ('/") or different quote style, found: '." │ │ │ ├── description: "Unescaped quote character in attribute value" │ │ │ ├── expected: "HTML entity ('/") or different quote style" │ │ │ └── found: "'" diff --git a/test/snapshots/parser/attributes_test/test_0019_escaped_apostrophe_inside_single_quotes_73b1e8ba6af89da5d178df9a5b3781fc.txt b/test/snapshots/parser/attributes_test/test_0019_escaped_apostrophe_inside_single_quotes_73b1e8ba6af89da5d178df9a5b3781fc.txt index e3666bda5..f6d1cb265 100644 --- a/test/snapshots/parser/attributes_test/test_0019_escaped_apostrophe_inside_single_quotes_73b1e8ba6af89da5d178df9a5b3781fc.txt +++ b/test/snapshots/parser/attributes_test/test_0019_escaped_apostrophe_inside_single_quotes_73b1e8ba6af89da5d178df9a5b3781fc.txt @@ -24,7 +24,7 @@ input: "
Text
" │ │ └── @ HTMLAttributeValueNode (location: (1:14)-(1:28)) │ │ ├── errors: (1 error) │ │ │ └── @ UnexpectedError (location: (1:19)-(1:20)) - │ │ │ ├── message: "Unescaped quote character in attribute value. Expected: `HTML entity ('/") or different quote style`, found: `'`." + │ │ │ ├── message: "Unescaped quote character in attribute value. Expected: HTML entity ('/") or different quote style, found: '." │ │ │ ├── description: "Unescaped quote character in attribute value" │ │ │ ├── expected: "HTML entity ('/") or different quote style" │ │ │ └── found: "'" diff --git a/test/snapshots/parser/attributes_test/test_0020_escaped_double_quote_inside_double_quotes_1ad5f48462c267e84580003c8ac9abac.txt b/test/snapshots/parser/attributes_test/test_0020_escaped_double_quote_inside_double_quotes_1ad5f48462c267e84580003c8ac9abac.txt index 0537b2b50..dee4d2971 100644 --- a/test/snapshots/parser/attributes_test/test_0020_escaped_double_quote_inside_double_quotes_1ad5f48462c267e84580003c8ac9abac.txt +++ b/test/snapshots/parser/attributes_test/test_0020_escaped_double_quote_inside_double_quotes_1ad5f48462c267e84580003c8ac9abac.txt @@ -9,10 +9,10 @@ input: "
Text
" │ └── @ HTMLOpenTagNode (location: (1:0)-(1:35)) │ ├── errors: (1 error) │ │ └── @ UnexpectedError (location: (1:33)-(1:34)) - │ │ ├── message: "Unexpected Token. Expected: `TOKEN_IDENTIFIER, TOKEN_AT, TOKEN_ERB_START,TOKEN_WHITESPACE, or TOKEN_NEWLINE`, found: `TOKEN_QUOTE`." + │ │ ├── message: "Unexpected Token. Expected: an identifier, `@`, `<%`, whitespace, or a newline, found: a quote." │ │ ├── description: "Unexpected Token" - │ │ ├── expected: "TOKEN_IDENTIFIER, TOKEN_AT, TOKEN_ERB_START,TOKEN_WHITESPACE, or TOKEN_NEWLINE" - │ │ └── found: "TOKEN_QUOTE" + │ │ ├── expected: "an identifier, `@`, `<%`, whitespace, or a newline" + │ │ └── found: "a quote" │ │ │ ├── tag_opening: "<" (location: (1:0)-(1:1)) │ ├── tag_name: "div" (location: (1:1)-(1:4)) @@ -31,7 +31,7 @@ input: "
Text
" │ │ └── @ HTMLAttributeValueNode (location: (1:14)-(1:33)) │ │ ├── errors: (1 error) │ │ │ └── @ UnexpectedError (location: (1:25)-(1:26)) - │ │ │ ├── message: "Unescaped quote character in attribute value. Expected: `HTML entity ('/") or different quote style`, found: `\"`." + │ │ │ ├── message: "Unescaped quote character in attribute value. Expected: HTML entity ('/") or different quote style, found: \"." │ │ │ ├── description: "Unescaped quote character in attribute value" │ │ │ ├── expected: "HTML entity ('/") or different quote style" │ │ │ └── found: "\"" diff --git a/test/snapshots/parser/attributes_test/test_0033_attribute_with_backtick_quotes_(invalid)_8718691f5760feaae83ee2b77c476b95.txt b/test/snapshots/parser/attributes_test/test_0033_attribute_with_backtick_quotes_(invalid)_8718691f5760feaae83ee2b77c476b95.txt index 8932e736c..b09b2a70b 100644 --- a/test/snapshots/parser/attributes_test/test_0033_attribute_with_backtick_quotes_(invalid)_8718691f5760feaae83ee2b77c476b95.txt +++ b/test/snapshots/parser/attributes_test/test_0033_attribute_with_backtick_quotes_(invalid)_8718691f5760feaae83ee2b77c476b95.txt @@ -24,10 +24,10 @@ input: "
" │ │ │ └── @ HTMLAttributeValueNode (location: (1:11)-(1:12)) │ │ │ ├── errors: (1 error) │ │ │ │ └── @ UnexpectedError (location: (1:11)-(1:12)) - │ │ │ │ ├── message: "Invalid quote character for HTML attribute. Expected: `single quote (') or double quote (\")`, found: `backtick (`)`." + │ │ │ │ ├── message: "Invalid quote character for HTML attribute. Expected: single quote (') or double quote (\"), found: a backtick." │ │ │ │ ├── description: "Invalid quote character for HTML attribute" │ │ │ │ ├── expected: "single quote (') or double quote (\")" - │ │ │ │ └── found: "backtick (`)" + │ │ │ │ └── found: "a backtick" │ │ │ │ │ │ │ ├── open_quote: ∅ │ │ │ ├── children: [] diff --git a/test/snapshots/parser/attributes_test/test_0034_attribute_with_backtick_quotes_and_whitespace_(invalid)_237e4c11b70033b3f49f29b7e3c9cb70.txt b/test/snapshots/parser/attributes_test/test_0034_attribute_with_backtick_quotes_and_whitespace_(invalid)_237e4c11b70033b3f49f29b7e3c9cb70.txt index 8b837a85f..f32ee637e 100644 --- a/test/snapshots/parser/attributes_test/test_0034_attribute_with_backtick_quotes_and_whitespace_(invalid)_237e4c11b70033b3f49f29b7e3c9cb70.txt +++ b/test/snapshots/parser/attributes_test/test_0034_attribute_with_backtick_quotes_and_whitespace_(invalid)_237e4c11b70033b3f49f29b7e3c9cb70.txt @@ -24,10 +24,10 @@ input: "
" │ │ │ └── @ HTMLAttributeValueNode (location: (1:11)-(1:12)) │ │ │ ├── errors: (1 error) │ │ │ │ └── @ UnexpectedError (location: (1:11)-(1:12)) - │ │ │ │ ├── message: "Invalid quote character for HTML attribute. Expected: `single quote (') or double quote (\")`, found: `backtick (`)`." + │ │ │ │ ├── message: "Invalid quote character for HTML attribute. Expected: single quote (') or double quote (\"), found: a backtick." │ │ │ │ ├── description: "Invalid quote character for HTML attribute" │ │ │ │ ├── expected: "single quote (') or double quote (\")" - │ │ │ │ └── found: "backtick (`)" + │ │ │ │ └── found: "a backtick" │ │ │ │ │ │ │ ├── open_quote: ∅ │ │ │ ├── children: [] diff --git a/test/snapshots/parser/attributes_test/test_0035_multiple_attributes_with_mixed_quotes_including_backticks_(invalid)_5eb53ae0e5d34773abdd248e275f8c51.txt b/test/snapshots/parser/attributes_test/test_0035_multiple_attributes_with_mixed_quotes_including_backticks_(invalid)_5eb53ae0e5d34773abdd248e275f8c51.txt index 832070cdc..da59ef8a8 100644 --- a/test/snapshots/parser/attributes_test/test_0035_multiple_attributes_with_mixed_quotes_including_backticks_(invalid)_5eb53ae0e5d34773abdd248e275f8c51.txt +++ b/test/snapshots/parser/attributes_test/test_0035_multiple_attributes_with_mixed_quotes_including_backticks_(invalid)_5eb53ae0e5d34773abdd248e275f8c51.txt @@ -44,10 +44,10 @@ input: "
" │ │ │ └── @ HTMLAttributeValueNode (location: (1:22)-(1:23)) │ │ │ ├── errors: (1 error) │ │ │ │ └── @ UnexpectedError (location: (1:22)-(1:23)) - │ │ │ │ ├── message: "Invalid quote character for HTML attribute. Expected: `single quote (') or double quote (\")`, found: `backtick (`)`." + │ │ │ │ ├── message: "Invalid quote character for HTML attribute. Expected: single quote (') or double quote (\"), found: a backtick." │ │ │ │ ├── description: "Invalid quote character for HTML attribute" │ │ │ │ ├── expected: "single quote (') or double quote (\")" - │ │ │ │ └── found: "backtick (`)" + │ │ │ │ └── found: "a backtick" │ │ │ │ │ │ │ ├── open_quote: ∅ │ │ │ ├── children: [] diff --git a/test/snapshots/parser/attributes_test/test_0036_self-closing_tag_with_backtick_attribute_(invalid)_0545b512ba1dfae2fd7c90ec643b4cca.txt b/test/snapshots/parser/attributes_test/test_0036_self-closing_tag_with_backtick_attribute_(invalid)_0545b512ba1dfae2fd7c90ec643b4cca.txt index 55314fd2e..6c7951078 100644 --- a/test/snapshots/parser/attributes_test/test_0036_self-closing_tag_with_backtick_attribute_(invalid)_0545b512ba1dfae2fd7c90ec643b4cca.txt +++ b/test/snapshots/parser/attributes_test/test_0036_self-closing_tag_with_backtick_attribute_(invalid)_0545b512ba1dfae2fd7c90ec643b4cca.txt @@ -24,10 +24,10 @@ input: "" │ │ │ └── @ HTMLAttributeValueNode (location: (1:9)-(1:10)) │ │ │ ├── errors: (1 error) │ │ │ │ └── @ UnexpectedError (location: (1:9)-(1:10)) - │ │ │ │ ├── message: "Invalid quote character for HTML attribute. Expected: `single quote (') or double quote (\")`, found: `backtick (`)`." + │ │ │ │ ├── message: "Invalid quote character for HTML attribute. Expected: single quote (') or double quote (\"), found: a backtick." │ │ │ │ ├── description: "Invalid quote character for HTML attribute" │ │ │ │ ├── expected: "single quote (') or double quote (\")" - │ │ │ │ └── found: "backtick (`)" + │ │ │ │ └── found: "a backtick" │ │ │ │ │ │ │ ├── open_quote: ∅ │ │ │ ├── children: [] diff --git a/test/snapshots/parser/attributes_test/test_0037_attribute_with_backtick_containing_HTML_(invalid)_542130e358dadabeb4a1629bc9bcf4f3.txt b/test/snapshots/parser/attributes_test/test_0037_attribute_with_backtick_containing_HTML_(invalid)_542130e358dadabeb4a1629bc9bcf4f3.txt index a3b1b829f..268f425ef 100644 --- a/test/snapshots/parser/attributes_test/test_0037_attribute_with_backtick_containing_HTML_(invalid)_542130e358dadabeb4a1629bc9bcf4f3.txt +++ b/test/snapshots/parser/attributes_test/test_0037_attribute_with_backtick_containing_HTML_(invalid)_542130e358dadabeb4a1629bc9bcf4f3.txt @@ -29,10 +29,10 @@ input: "
Hello`>
" │ │ └── @ HTMLAttributeValueNode (location: (1:19)-(1:20)) │ │ ├── errors: (1 error) │ │ │ └── @ UnexpectedError (location: (1:19)-(1:20)) - │ │ │ ├── message: "Invalid quote character for HTML attribute. Expected: `single quote (') or double quote (\")`, found: `backtick (`)`." + │ │ │ ├── message: "Invalid quote character for HTML attribute. Expected: single quote (') or double quote (\"), found: a backtick." │ │ │ ├── description: "Invalid quote character for HTML attribute" │ │ │ ├── expected: "single quote (') or double quote (\")" - │ │ │ └── found: "backtick (`)" + │ │ │ └── found: "a backtick" │ │ │ │ │ ├── open_quote: ∅ │ │ ├── children: [] diff --git a/test/snapshots/parser/attributes_test/test_0042_Standalone_colon_with_space_is_invalid_c037b25064b31d22c6c195361999c5b8.txt b/test/snapshots/parser/attributes_test/test_0042_Standalone_colon_with_space_is_invalid_c037b25064b31d22c6c195361999c5b8.txt index c74760e4f..7b6035552 100644 --- a/test/snapshots/parser/attributes_test/test_0042_Standalone_colon_with_space_is_invalid_c037b25064b31d22c6c195361999c5b8.txt +++ b/test/snapshots/parser/attributes_test/test_0042_Standalone_colon_with_space_is_invalid_c037b25064b31d22c6c195361999c5b8.txt @@ -9,10 +9,10 @@ input: "
" │ └── @ HTMLOpenTagNode (location: (1:0)-(1:21)) │ ├── errors: (1 error) │ │ └── @ UnexpectedError (location: (1:5)-(1:6)) - │ │ ├── message: "Unexpected Token. Expected: `TOKEN_IDENTIFIER, TOKEN_AT, TOKEN_ERB_START,TOKEN_WHITESPACE, or TOKEN_NEWLINE`, found: `TOKEN_COLON`." + │ │ ├── message: "Unexpected Token. Expected: an identifier, `@`, `<%`, whitespace, or a newline, found: `:`." │ │ ├── description: "Unexpected Token" - │ │ ├── expected: "TOKEN_IDENTIFIER, TOKEN_AT, TOKEN_ERB_START,TOKEN_WHITESPACE, or TOKEN_NEWLINE" - │ │ └── found: "TOKEN_COLON" + │ │ ├── expected: "an identifier, `@`, `<%`, whitespace, or a newline" + │ │ └── found: "`:`" │ │ │ ├── tag_opening: "<" (location: (1:0)-(1:1)) │ ├── tag_name: "div" (location: (1:1)-(1:4)) diff --git a/test/snapshots/parser/attributes_test/test_0044_Double_colon_is_invalid_f2b2354b82896dec0458b506ae56eb58.txt b/test/snapshots/parser/attributes_test/test_0044_Double_colon_is_invalid_f2b2354b82896dec0458b506ae56eb58.txt index f61956658..6f9bdb92b 100644 --- a/test/snapshots/parser/attributes_test/test_0044_Double_colon_is_invalid_f2b2354b82896dec0458b506ae56eb58.txt +++ b/test/snapshots/parser/attributes_test/test_0044_Double_colon_is_invalid_f2b2354b82896dec0458b506ae56eb58.txt @@ -9,10 +9,10 @@ input: "
" │ └── @ HTMLOpenTagNode (location: (1:0)-(1:21)) │ ├── errors: (1 error) │ │ └── @ UnexpectedError (location: (1:5)-(1:6)) - │ │ ├── message: "Unexpected Token. Expected: `TOKEN_IDENTIFIER, TOKEN_AT, TOKEN_ERB_START,TOKEN_WHITESPACE, or TOKEN_NEWLINE`, found: `TOKEN_COLON`." + │ │ ├── message: "Unexpected Token. Expected: an identifier, `@`, `<%`, whitespace, or a newline, found: `:`." │ │ ├── description: "Unexpected Token" - │ │ ├── expected: "TOKEN_IDENTIFIER, TOKEN_AT, TOKEN_ERB_START,TOKEN_WHITESPACE, or TOKEN_NEWLINE" - │ │ └── found: "TOKEN_COLON" + │ │ ├── expected: "an identifier, `@`, `<%`, whitespace, or a newline" + │ │ └── found: "`:`" │ │ │ ├── tag_opening: "<" (location: (1:0)-(1:1)) │ ├── tag_name: "div" (location: (1:1)-(1:4)) diff --git a/test/snapshots/parser/attributes_test/test_0115_attribute_with_equals_followed_by_new_tag_start_53797bc03ba9eee20bb33d3346e15f50.txt b/test/snapshots/parser/attributes_test/test_0115_attribute_with_equals_followed_by_new_tag_start_53797bc03ba9eee20bb33d3346e15f50.txt index 527f1653d..cf5e766ef 100644 --- a/test/snapshots/parser/attributes_test/test_0115_attribute_with_equals_followed_by_new_tag_start_53797bc03ba9eee20bb33d3346e15f50.txt +++ b/test/snapshots/parser/attributes_test/test_0115_attribute_with_equals_followed_by_new_tag_start_53797bc03ba9eee20bb33d3346e15f50.txt @@ -29,10 +29,10 @@ input: "
test
" │ │ └── @ HTMLAttributeValueNode (location: (1:11)-(1:12)) │ │ ├── errors: (1 error) │ │ │ └── @ UnexpectedError (location: (1:11)-(1:12)) - │ │ │ ├── message: "Unexpected Token. Expected: `TOKEN_IDENTIFIER, TOKEN_QUOTE, TOKEN_ERB_START`, found: `TOKEN_HTML_TAG_START`." + │ │ │ ├── message: "Unexpected Token. Expected: an identifier, a quote, or `<%`, found: `<`." │ │ │ ├── description: "Unexpected Token" - │ │ │ ├── expected: "TOKEN_IDENTIFIER, TOKEN_QUOTE, TOKEN_ERB_START" - │ │ │ └── found: "TOKEN_HTML_TAG_START" + │ │ │ ├── expected: "an identifier, a quote, or `<%`" + │ │ │ └── found: "`<`" │ │ │ │ │ ├── open_quote: ∅ │ │ ├── children: [] diff --git a/test/snapshots/parser/attributes_test/test_0116_attribute_with_equals_and_space_followed_by_new_tag_start_c4d65ef876cd7488aa38dfab522aafbd.txt b/test/snapshots/parser/attributes_test/test_0116_attribute_with_equals_and_space_followed_by_new_tag_start_c4d65ef876cd7488aa38dfab522aafbd.txt index 8aa94b19f..b3770c1d5 100644 --- a/test/snapshots/parser/attributes_test/test_0116_attribute_with_equals_and_space_followed_by_new_tag_start_c4d65ef876cd7488aa38dfab522aafbd.txt +++ b/test/snapshots/parser/attributes_test/test_0116_attribute_with_equals_and_space_followed_by_new_tag_start_c4d65ef876cd7488aa38dfab522aafbd.txt @@ -29,10 +29,10 @@ input: "
test
" │ │ └── @ HTMLAttributeValueNode (location: (1:12)-(1:13)) │ │ ├── errors: (1 error) │ │ │ └── @ UnexpectedError (location: (1:12)-(1:13)) - │ │ │ ├── message: "Unexpected Token. Expected: `TOKEN_IDENTIFIER, TOKEN_QUOTE, TOKEN_ERB_START`, found: `TOKEN_HTML_TAG_START`." + │ │ │ ├── message: "Unexpected Token. Expected: an identifier, a quote, or `<%`, found: `<`." │ │ │ ├── description: "Unexpected Token" - │ │ │ ├── expected: "TOKEN_IDENTIFIER, TOKEN_QUOTE, TOKEN_ERB_START" - │ │ │ └── found: "TOKEN_HTML_TAG_START" + │ │ │ ├── expected: "an identifier, a quote, or `<%`" + │ │ │ └── found: "`<`" │ │ │ │ │ ├── open_quote: ∅ │ │ ├── children: [] diff --git a/test/snapshots/parser/attributes_test/test_0117_attribute_with_equals_at_EOF_899de3e17c281d1fbde88f0b3a016fc7.txt b/test/snapshots/parser/attributes_test/test_0117_attribute_with_equals_at_EOF_899de3e17c281d1fbde88f0b3a016fc7.txt index 83f27763c..b8a11b447 100644 --- a/test/snapshots/parser/attributes_test/test_0117_attribute_with_equals_at_EOF_899de3e17c281d1fbde88f0b3a016fc7.txt +++ b/test/snapshots/parser/attributes_test/test_0117_attribute_with_equals_at_EOF_899de3e17c281d1fbde88f0b3a016fc7.txt @@ -27,10 +27,10 @@ input: "
" │ └── @ HTMLOpenTagNode (location: (1:0)-(1:17)) │ ├── errors: (1 error) │ │ └── @ UnexpectedError (location: (1:14)-(1:15)) - │ │ ├── message: "Unexpected Token. Expected: `TOKEN_IDENTIFIER, TOKEN_AT, TOKEN_ERB_START,TOKEN_WHITESPACE, or TOKEN_NEWLINE`, found: `TOKEN_EQUALS`." + │ │ ├── message: "Unexpected Token. Expected: an identifier, `@`, `<%`, whitespace, or a newline, found: `=`." │ │ ├── description: "Unexpected Token" - │ │ ├── expected: "TOKEN_IDENTIFIER, TOKEN_AT, TOKEN_ERB_START,TOKEN_WHITESPACE, or TOKEN_NEWLINE" - │ │ └── found: "TOKEN_EQUALS" + │ │ ├── expected: "an identifier, `@`, `<%`, whitespace, or a newline" + │ │ └── found: "`=`" │ │ │ ├── tag_opening: "<" (location: (1:0)-(1:1)) │ ├── tag_name: "div" (location: (1:1)-(1:4)) diff --git a/test/snapshots/parser/attributes_test/test_0120_attribute_with_equals_followed_by_closing_tag_c8cfc11d3772c91f3dbb9a45f21c07a0.txt b/test/snapshots/parser/attributes_test/test_0120_attribute_with_equals_followed_by_closing_tag_c8cfc11d3772c91f3dbb9a45f21c07a0.txt index 0d1aace5e..7b3090400 100644 --- a/test/snapshots/parser/attributes_test/test_0120_attribute_with_equals_followed_by_closing_tag_c8cfc11d3772c91f3dbb9a45f21c07a0.txt +++ b/test/snapshots/parser/attributes_test/test_0120_attribute_with_equals_followed_by_closing_tag_c8cfc11d3772c91f3dbb9a45f21c07a0.txt @@ -29,10 +29,10 @@ input: "
" │ │ └── @ HTMLAttributeValueNode (location: (1:11)-(1:13)) │ │ ├── errors: (1 error) │ │ │ └── @ UnexpectedError (location: (1:11)-(1:13)) - │ │ │ ├── message: "Unexpected Token. Expected: `TOKEN_IDENTIFIER, TOKEN_QUOTE, TOKEN_ERB_START`, found: `TOKEN_HTML_TAG_START_CLOSE`." + │ │ │ ├── message: "Unexpected Token. Expected: an identifier, a quote, or `<%`, found: `
" │ └── @ HTMLOpenTagNode (location: (1:0)-(1:16)) │ ├── errors: (1 error) │ │ └── @ UnexpectedError (location: (1:5)-(1:6)) - │ │ ├── message: "Unexpected Token. Expected: `TOKEN_IDENTIFIER, TOKEN_AT, TOKEN_ERB_START,TOKEN_WHITESPACE, or TOKEN_NEWLINE`, found: `TOKEN_COLON`." + │ │ ├── message: "Unexpected Token. Expected: an identifier, `@`, `<%`, whitespace, or a newline, found: `:`." │ │ ├── description: "Unexpected Token" - │ │ ├── expected: "TOKEN_IDENTIFIER, TOKEN_AT, TOKEN_ERB_START,TOKEN_WHITESPACE, or TOKEN_NEWLINE" - │ │ └── found: "TOKEN_COLON" + │ │ ├── expected: "an identifier, `@`, `<%`, whitespace, or a newline" + │ │ └── found: "`:`" │ │ │ ├── tag_opening: "<" (location: (1:0)-(1:1)) │ ├── tag_name: "div" (location: (1:1)-(1:4))