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 authored and strager committed Dec 22, 2023
1 parent 0dd4143 commit 1ee2154
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 @@ -1373,6 +1373,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 @@ -3543,6 +3543,20 @@ const QLJS_CONSTINIT Diagnostic_Info all_diagnostic_infos[] = {
},
},

// Diag_Newline_Not_Allowed_After_In_Out_Const_Modifiers
{
.code = 440,
.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 @@ -247,6 +247,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 @@ -461,7 +462,7 @@ namespace quick_lint_js {
/* END */
// clang-format on

inline constexpr int Diag_Type_Count = 447;
inline constexpr int Diag_Type_Count = 448;

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 @@ -1820,6 +1820,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("E0440", 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 @@ -1694,6 +1694,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 @@ -461,6 +461,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 @@ -2316,6 +2317,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 = 590;
constexpr std::size_t translation_table_string_table_size = 81673;
constexpr std::uint16_t translation_table_mapping_table_size = 591;
constexpr std::size_t translation_table_string_table_size = 81738;
constexpr std::size_t translation_table_locale_table_size = 35;

QLJS_CONSTEVAL std::uint16_t translation_table_const_look_up(
Expand Down Expand Up @@ -475,6 +475,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[589] = {
inline const Translated_String test_translation_table[590] = {
{
"\"global-groups\" entries must be strings"_translatable,
u8"\"global-groups\" entries must be strings",
Expand Down Expand Up @@ -4967,6 +4967,17 @@ inline const Translated_String test_translation_table[589] = {
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 @@ -1385,6 +1385,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 1ee2154

Please sign in to comment.