Skip to content

Commit

Permalink
feat(typescript): disallow newline after modifiers in generic parameter
Browse files Browse the repository at this point in the history
Report error for newline(s) after 'in'/'out'/'const' modifier in generic
parameter.
  • Loading branch information
arieldon committed Dec 17, 2023
1 parent ab8e175 commit 94e2108
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 4 deletions.
4 changes: 4 additions & 0 deletions po/messages.pot
Original file line number Diff line number Diff line change
Expand Up @@ -1221,6 +1221,10 @@ msgstr ""
msgid "newline is not allowed before '<'"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "newline is not allowed after '{0}' modifier in generic parameter"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "number literal contains consecutive underscores"
msgstr ""
Expand Down
14 changes: 14 additions & 0 deletions src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3509,6 +3509,20 @@ const QLJS_CONSTINIT Diagnostic_Info all_diagnostic_infos[] = {
},
},

// Diag_Newline_Not_Allowed_After_In_Out_Const_Modifiers
{
.code = 433,
.severity = Diagnostic_Severity::error,
.message_formats = {
QLJS_TRANSLATABLE("newline is not allowed after '{0}' modifier in generic parameter"),
},
.message_args = {
{
Diagnostic_Message_Arg_Info(offsetof(Diag_Newline_Not_Allowed_After_In_Out_Const_Modifiers, modifier), Diagnostic_Arg_Type::source_code_span),
},
},
},

// Diag_Number_Literal_Contains_Consecutive_Underscores
{
.code = 28,
Expand Down
3 changes: 2 additions & 1 deletion src/quick-lint-js/diag/diagnostic-metadata-generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ namespace quick_lint_js {
QLJS_DIAG_TYPE_NAME(Diag_Newline_Not_Allowed_After_Type_Keyword) \
QLJS_DIAG_TYPE_NAME(Diag_Newline_Not_Allowed_Before_Assignment_Assertion_Operator) \
QLJS_DIAG_TYPE_NAME(Diag_Newline_Not_Allowed_Before_Generic_Arguments_In_Type) \
QLJS_DIAG_TYPE_NAME(Diag_Newline_Not_Allowed_After_In_Out_Const_Modifiers) \
QLJS_DIAG_TYPE_NAME(Diag_Number_Literal_Contains_Consecutive_Underscores) \
QLJS_DIAG_TYPE_NAME(Diag_Number_Literal_Contains_Trailing_Underscores) \
QLJS_DIAG_TYPE_NAME(Diag_Octal_Literal_May_Not_Have_Exponent) \
Expand Down Expand Up @@ -454,7 +455,7 @@ namespace quick_lint_js {
/* END */
// clang-format on

inline constexpr int Diag_Type_Count = 440;
inline constexpr int Diag_Type_Count = 441;

extern const Diagnostic_Info all_diagnostic_infos[Diag_Type_Count];
}
Expand Down
8 changes: 8 additions & 0 deletions src/quick-lint-js/diag/diagnostic-types-2.h
Original file line number Diff line number Diff line change
Expand Up @@ -1801,6 +1801,14 @@ struct Diag_Newline_Not_Allowed_Before_Generic_Arguments_In_Type {
Source_Code_Span less;
};

struct Diag_Newline_Not_Allowed_After_In_Out_Const_Modifiers {
[[qljs::diag("E0433", Diagnostic_Severity::error)]] //
[[qljs::message(
"newline is not allowed after '{0}' modifier in generic parameter",
ARG(modifier))]] //
Source_Code_Span modifier;
};

struct Diag_Number_Literal_Contains_Consecutive_Underscores {
[[qljs::diag("E0028", Diagnostic_Severity::error)]] //
[[qljs::message("number literal contains consecutive underscores",
Expand Down
5 changes: 5 additions & 0 deletions src/quick-lint-js/fe/parse-statement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1683,6 +1683,11 @@ void Parser::parse_and_visit_typescript_generic_parameters(
.token_type = this->peek().type,
});
this->skip();
if (this->lexer_.peek().has_leading_newline) {
this->diag_reporter_->report(
Diag_Newline_Not_Allowed_After_In_Out_Const_Modifiers{
.modifier = modifiers.back().identifier.span()});
}
break;

default:
Expand Down
2 changes: 2 additions & 0 deletions src/quick-lint-js/i18n/translation-table-generated.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ const Translation_Table translation_data = {
{0, 0, 0, 52, 0, 41}, //
{0, 0, 0, 0, 0, 36}, //
{0, 0, 0, 0, 0, 35}, //
{0, 0, 0, 0, 0, 65}, //
{0, 0, 0, 47, 0, 34}, //
{52, 31, 25, 61, 21, 54}, //
{0, 0, 0, 0, 0, 73}, //
Expand Down Expand Up @@ -2240,6 +2241,7 @@ const Translation_Table translation_data = {
u8"newline is not allowed after 'interface'\0"
u8"newline is not allowed after 'type'\0"
u8"newline is not allowed after '{0}'\0"
u8"newline is not allowed after '{0}' modifier in generic parameter\0"
u8"newline is not allowed before '<'\0"
u8"newline is not allowed between 'async' and 'function'\0"
u8"newline is not allowed between 'async' and arrow function parameter list\0"
Expand Down
5 changes: 3 additions & 2 deletions src/quick-lint-js/i18n/translation-table-generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ namespace quick_lint_js {
using namespace std::literals::string_view_literals;

constexpr std::uint32_t translation_table_locale_count = 5;
constexpr std::uint16_t translation_table_mapping_table_size = 545;
constexpr std::size_t translation_table_string_table_size = 80903;
constexpr std::uint16_t translation_table_mapping_table_size = 546;
constexpr std::size_t translation_table_string_table_size = 80968;
constexpr std::size_t translation_table_locale_table_size = 35;

QLJS_CONSTEVAL std::uint16_t translation_table_const_look_up(
Expand Down Expand Up @@ -439,6 +439,7 @@ QLJS_CONSTEVAL std::uint16_t translation_table_const_look_up(
"newline is not allowed after 'interface'"sv,
"newline is not allowed after 'type'"sv,
"newline is not allowed after '{0}'"sv,
"newline is not allowed after '{0}' modifier in generic parameter"sv,
"newline is not allowed before '<'"sv,
"newline is not allowed between 'async' and 'function'"sv,
"newline is not allowed between 'async' and arrow function parameter list"sv,
Expand Down
13 changes: 12 additions & 1 deletion src/quick-lint-js/i18n/translation-table-test-generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ struct Translated_String {
};

// clang-format off
inline const Translated_String test_translation_table[544] = {
inline const Translated_String test_translation_table[545] = {
{
"\"global-groups\" entries must be strings"_translatable,
u8"\"global-groups\" entries must be strings",
Expand Down Expand Up @@ -4571,6 +4571,17 @@ inline const Translated_String test_translation_table[544] = {
u8"newline is not allowed after '{0}'",
},
},
{
"newline is not allowed after '{0}' modifier in generic parameter"_translatable,
u8"newline is not allowed after '{0}' modifier in generic parameter",
{
u8"newline is not allowed after '{0}' modifier in generic parameter",
u8"newline is not allowed after '{0}' modifier in generic parameter",
u8"newline is not allowed after '{0}' modifier in generic parameter",
u8"newline is not allowed after '{0}' modifier in generic parameter",
u8"newline is not allowed after '{0}' modifier in generic parameter",
},
},
{
"newline is not allowed before '<'"_translatable,
u8"newline is not allowed before '<'",
Expand Down
27 changes: 27 additions & 0 deletions test/test-parse-typescript-generic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1333,6 +1333,33 @@ TEST_F(Test_Parse_TypeScript_Generic,
typescript_options);
}
}

TEST_F(Test_Parse_TypeScript_Generic,
newline_is_not_allowed_after_in_out_const_modifiers) {
{
test_parse_and_visit_module(
u8"class C<in\nT> {}"_sv, //
u8" ^^ Diag_Newline_Not_Allowed_After_In_Out_Const_Modifiers.modifier"_diag, //
typescript_options);
test_parse_and_visit_module(
u8"class C<out\nT> {}"_sv, //
u8" ^^^ Diag_Newline_Not_Allowed_After_In_Out_Const_Modifiers.modifier"_diag, //
typescript_options);
test_parse_and_visit_module(
u8"class C<const\nT> {}"_sv, //
u8" ^^^^^ Diag_Newline_Not_Allowed_After_In_Out_Const_Modifiers.modifier"_diag, //
typescript_options);
}

{
test_parse_and_visit_module(u8"class C<in T> {}"_sv, no_diags,
typescript_options);
test_parse_and_visit_module(u8"class C<out T> {}"_sv, no_diags,
typescript_options);
test_parse_and_visit_module(u8"class C<const T> {}"_sv, no_diags,
typescript_options);
}
}
}
}

Expand Down

0 comments on commit 94e2108

Please sign in to comment.