Skip to content

Commit

Permalink
feat(typescript): parse overload signatures for class methods
Browse files Browse the repository at this point in the history
  • Loading branch information
strager committed Sep 22, 2023
1 parent 7aa65f0 commit b7367c0
Show file tree
Hide file tree
Showing 14 changed files with 1,384 additions and 31 deletions.
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Semantic Versioning.
* quick-lint-js now compiles correctly on big-endian architectures such as
S/390 (Linux s390x).
* TypeScript support (still experimental):
* Class method overload signatures are now parsed.
* [E0398][] is now reported when using both `abstract` and `static` on a
single class property.
* `,` is now allowed after interface fields. (Previously only `;` or a newline
Expand Down
48 changes: 48 additions & 0 deletions po/messages.pot
Original file line number Diff line number Diff line change
Expand Up @@ -417,10 +417,30 @@ msgstr ""
msgid "'{0}' is not allowed with '{1}'"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "'{0}' is missing on overloaded method"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "write '{1}' here or remove it from the overload signature"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "'{1}' is missing on overload signature"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "overload signature must match modifiers on this overload method"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "'{0}' must precede '{1}'"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "'{0}' is not allowed in TypeScript overload signatures"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "missing body for {1:headlinese}"
msgstr ""
Expand Down Expand Up @@ -669,6 +689,10 @@ msgstr ""
msgid "generator function '*' belongs before function name"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "getters and setters cannot have overload signatures"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "only one comma is allowed between or after generic parameters"
msgstr ""
Expand Down Expand Up @@ -1001,6 +1025,10 @@ msgstr ""
msgid "missing semicolon after statement"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "missing semicolon after method overload signature"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "missing semicolon after field"
msgstr ""
Expand Down Expand Up @@ -1065,6 +1093,10 @@ msgstr ""
msgid "'function' is here"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "newline is not allowed between '{0}' and the method name"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "newline is not allowed after 'abstract'"
msgstr ""
Expand Down Expand Up @@ -1485,6 +1517,14 @@ msgstr ""
msgid "prior spread element is here"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "overload signature must have the correct access specifier ('{1}')"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "overloaded method is marked '{0}'"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "parameter properties cannot be destructured"
msgstr ""
Expand Down Expand Up @@ -1693,6 +1733,14 @@ msgstr ""
msgid "unexpected '?' when destructuring"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "TypeScript overload signature can only have one semicolon"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "original semicolon is here"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "C-style for loops have only three semicolon-separated components"
msgstr ""
Expand Down
131 changes: 131 additions & 0 deletions src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1016,6 +1016,44 @@ const QLJS_CONSTINIT Diagnostic_Info all_diagnostic_infos[] = {
},
},

// Diag_Class_Modifier_Missing_On_Method_With_TypeScript_Overload_Signature
{
.code = 403,
.severity = Diagnostic_Severity::error,
.message_formats = {
QLJS_TRANSLATABLE("'{0}' is missing on overloaded method"),
QLJS_TRANSLATABLE("write '{1}' here or remove it from the overload signature"),
},
.message_args = {
{
Diagnostic_Message_Arg_Info(offsetof(Diag_Class_Modifier_Missing_On_Method_With_TypeScript_Overload_Signature, signature_modifier), Diagnostic_Arg_Type::source_code_span),
},
{
Diagnostic_Message_Arg_Info(offsetof(Diag_Class_Modifier_Missing_On_Method_With_TypeScript_Overload_Signature, missing_method_modifier), Diagnostic_Arg_Type::source_code_span),
Diagnostic_Message_Arg_Info(offsetof(Diag_Class_Modifier_Missing_On_Method_With_TypeScript_Overload_Signature, signature_modifier), Diagnostic_Arg_Type::source_code_span),
},
},
},

// Diag_Class_Modifier_Missing_On_TypeScript_Overload_Signature
{
.code = 404,
.severity = Diagnostic_Severity::error,
.message_formats = {
QLJS_TRANSLATABLE("'{1}' is missing on overload signature"),
QLJS_TRANSLATABLE("overload signature must match modifiers on this overload method"),
},
.message_args = {
{
Diagnostic_Message_Arg_Info(offsetof(Diag_Class_Modifier_Missing_On_TypeScript_Overload_Signature, missing_signature_modifier), Diagnostic_Arg_Type::source_code_span),
Diagnostic_Message_Arg_Info(offsetof(Diag_Class_Modifier_Missing_On_TypeScript_Overload_Signature, method_modifier), Diagnostic_Arg_Type::source_code_span),
},
{
Diagnostic_Message_Arg_Info(offsetof(Diag_Class_Modifier_Missing_On_TypeScript_Overload_Signature, method_modifier), Diagnostic_Arg_Type::source_code_span),
},
},
},

// Diag_Class_Modifier_Must_Preceed_Other_Modifier
{
.code = 395,
Expand All @@ -1031,6 +1069,20 @@ const QLJS_CONSTINIT Diagnostic_Info all_diagnostic_infos[] = {
},
},

// Diag_Class_Modifier_Not_Allowed_On_TypeScript_Overload_Signature
{
.code = 402,
.severity = Diagnostic_Severity::error,
.message_formats = {
QLJS_TRANSLATABLE("'{0}' is not allowed in TypeScript overload signatures"),
},
.message_args = {
{
Diagnostic_Message_Arg_Info(offsetof(Diag_Class_Modifier_Not_Allowed_On_TypeScript_Overload_Signature, modifier), Diagnostic_Arg_Type::source_code_span),
},
},
},

// Diag_Class_Statement_Not_Allowed_In_Body
{
.code = 149,
Expand Down Expand Up @@ -1857,6 +1909,20 @@ const QLJS_CONSTINIT Diagnostic_Info all_diagnostic_infos[] = {
},
},

// Diag_Getter_Or_Setter_Cannot_Have_TypeScript_Overload_Signature
{
.code = 401,
.severity = Diagnostic_Severity::error,
.message_formats = {
QLJS_TRANSLATABLE("getters and setters cannot have overload signatures"),
},
.message_args = {
{
Diagnostic_Message_Arg_Info(offsetof(Diag_Getter_Or_Setter_Cannot_Have_TypeScript_Overload_Signature, get_or_set_token), Diagnostic_Arg_Type::source_code_span),
},
},
},

// Diag_Multiple_Commas_In_Generic_Parameter_List
{
.code = 263,
Expand Down Expand Up @@ -2966,6 +3032,20 @@ const QLJS_CONSTINIT Diagnostic_Info all_diagnostic_infos[] = {
},
},

// Diag_Missing_Semicolon_After_TypeScript_Method_Overload_Signature
{
.code = 406,
.severity = Diagnostic_Severity::error,
.message_formats = {
QLJS_TRANSLATABLE("missing semicolon after method overload signature"),
},
.message_args = {
{
Diagnostic_Message_Arg_Info(offsetof(Diag_Missing_Semicolon_After_TypeScript_Method_Overload_Signature, expected_semicolon), Diagnostic_Arg_Type::source_code_span),
},
},
},

// Diag_Missing_Semicolon_After_Field
{
.code = 223,
Expand Down Expand Up @@ -3161,6 +3241,20 @@ const QLJS_CONSTINIT Diagnostic_Info all_diagnostic_infos[] = {
},
},

// Diag_Newline_Not_Allowed_Between_Modifier_And_Method_Name
{
.code = 399,
.severity = Diagnostic_Severity::error,
.message_formats = {
QLJS_TRANSLATABLE("newline is not allowed between '{0}' and the method name"),
},
.message_args = {
{
Diagnostic_Message_Arg_Info(offsetof(Diag_Newline_Not_Allowed_Between_Modifier_And_Method_Name, modifier), Diagnostic_Arg_Type::source_code_span),
},
},
},

// Diag_Newline_Not_Allowed_After_Abstract_Keyword
{
.code = 300,
Expand Down Expand Up @@ -4452,6 +4546,25 @@ const QLJS_CONSTINIT Diagnostic_Info all_diagnostic_infos[] = {
},
},

// Diag_TypeScript_Overload_Signature_Access_Specifier_Mismatch
{
.code = 405,
.severity = Diagnostic_Severity::error,
.message_formats = {
QLJS_TRANSLATABLE("overload signature must have the correct access specifier ('{1}')"),
QLJS_TRANSLATABLE("overloaded method is marked '{0}'"),
},
.message_args = {
{
Diagnostic_Message_Arg_Info(offsetof(Diag_TypeScript_Overload_Signature_Access_Specifier_Mismatch, signature_access_specifier), Diagnostic_Arg_Type::source_code_span),
Diagnostic_Message_Arg_Info(offsetof(Diag_TypeScript_Overload_Signature_Access_Specifier_Mismatch, method_access_specifier), Diagnostic_Arg_Type::source_code_span),
},
{
Diagnostic_Message_Arg_Info(offsetof(Diag_TypeScript_Overload_Signature_Access_Specifier_Mismatch, method_access_specifier), Diagnostic_Arg_Type::source_code_span),
},
},
},

// Diag_TypeScript_Parameter_Property_Cannot_Be_Destructured
{
.code = 372,
Expand Down Expand Up @@ -5142,6 +5255,24 @@ const QLJS_CONSTINIT Diagnostic_Info all_diagnostic_infos[] = {
},
},

// Diag_Unexpected_Semicolon_After_Overload_Signature
{
.code = 400,
.severity = Diagnostic_Severity::error,
.message_formats = {
QLJS_TRANSLATABLE("TypeScript overload signature can only have one semicolon"),
QLJS_TRANSLATABLE("original semicolon is here"),
},
.message_args = {
{
Diagnostic_Message_Arg_Info(offsetof(Diag_Unexpected_Semicolon_After_Overload_Signature, extra_semicolon), Diagnostic_Arg_Type::source_code_span),
},
{
Diagnostic_Message_Arg_Info(offsetof(Diag_Unexpected_Semicolon_After_Overload_Signature, original_semicolon), Diagnostic_Arg_Type::source_code_span),
},
},
},

// Diag_Unexpected_Semicolon_In_C_Style_For_Loop
{
.code = 102,
Expand Down
10 changes: 9 additions & 1 deletion src/quick-lint-js/diag/diagnostic-metadata-generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,10 @@ namespace quick_lint_js {
QLJS_DIAG_TYPE_NAME(Diag_Class_Accessor_On_Getter_Or_Setter) \
QLJS_DIAG_TYPE_NAME(Diag_Class_Accessor_On_Method) \
QLJS_DIAG_TYPE_NAME(Diag_Class_Conflicting_Modifiers) \
QLJS_DIAG_TYPE_NAME(Diag_Class_Modifier_Missing_On_Method_With_TypeScript_Overload_Signature) \
QLJS_DIAG_TYPE_NAME(Diag_Class_Modifier_Missing_On_TypeScript_Overload_Signature) \
QLJS_DIAG_TYPE_NAME(Diag_Class_Modifier_Must_Preceed_Other_Modifier) \
QLJS_DIAG_TYPE_NAME(Diag_Class_Modifier_Not_Allowed_On_TypeScript_Overload_Signature) \
QLJS_DIAG_TYPE_NAME(Diag_Class_Statement_Not_Allowed_In_Body) \
QLJS_DIAG_TYPE_NAME(Diag_Character_Disallowed_In_Identifiers) \
QLJS_DIAG_TYPE_NAME(Diag_Comma_Not_Allowed_After_Spread_Parameter) \
Expand Down Expand Up @@ -134,6 +137,7 @@ namespace quick_lint_js {
QLJS_DIAG_TYPE_NAME(Diag_Function_Statement_Not_Allowed_In_Body) \
QLJS_DIAG_TYPE_NAME(Diag_Generator_Function_Star_Belongs_After_Keyword_Function) \
QLJS_DIAG_TYPE_NAME(Diag_Generator_Function_Star_Belongs_Before_Name) \
QLJS_DIAG_TYPE_NAME(Diag_Getter_Or_Setter_Cannot_Have_TypeScript_Overload_Signature) \
QLJS_DIAG_TYPE_NAME(Diag_Multiple_Commas_In_Generic_Parameter_List) \
QLJS_DIAG_TYPE_NAME(Diag_In_Disallowed_In_C_Style_For_Loop) \
QLJS_DIAG_TYPE_NAME(Diag_Indexing_Requires_Expression) \
Expand Down Expand Up @@ -210,6 +214,7 @@ namespace quick_lint_js {
QLJS_DIAG_TYPE_NAME(Diag_Missing_Semicolon_After_Abstract_Method) \
QLJS_DIAG_TYPE_NAME(Diag_Missing_Semicolon_After_Declare_Class_Method) \
QLJS_DIAG_TYPE_NAME(Diag_Missing_Semicolon_After_Statement) \
QLJS_DIAG_TYPE_NAME(Diag_Missing_Semicolon_After_TypeScript_Method_Overload_Signature) \
QLJS_DIAG_TYPE_NAME(Diag_Missing_Semicolon_After_Field) \
QLJS_DIAG_TYPE_NAME(Diag_Missing_Semicolon_After_Index_Signature) \
QLJS_DIAG_TYPE_NAME(Diag_Missing_Semicolon_After_Interface_Method) \
Expand All @@ -223,6 +228,7 @@ namespace quick_lint_js {
QLJS_DIAG_TYPE_NAME(Diag_Missing_While_And_Condition_For_Do_While_Statement) \
QLJS_DIAG_TYPE_NAME(Diag_Newline_Not_Allowed_Between_Async_And_Parameter_List) \
QLJS_DIAG_TYPE_NAME(Diag_Newline_Not_Allowed_Between_Async_And_Function_Keyword) \
QLJS_DIAG_TYPE_NAME(Diag_Newline_Not_Allowed_Between_Modifier_And_Method_Name) \
QLJS_DIAG_TYPE_NAME(Diag_Newline_Not_Allowed_After_Abstract_Keyword) \
QLJS_DIAG_TYPE_NAME(Diag_Newline_Not_Allowed_After_Export_Declare) \
QLJS_DIAG_TYPE_NAME(Diag_Newline_Not_Allowed_After_Interface_Keyword) \
Expand Down Expand Up @@ -308,6 +314,7 @@ namespace quick_lint_js {
QLJS_DIAG_TYPE_NAME(Diag_TypeScript_Optional_Parameters_Not_Allowed_In_JavaScript) \
QLJS_DIAG_TYPE_NAME(Diag_TypeScript_Optional_Properties_Not_Allowed_In_JavaScript) \
QLJS_DIAG_TYPE_NAME(Diag_TypeScript_Optional_Tuple_Element_Cannot_Follow_Spread_Element) \
QLJS_DIAG_TYPE_NAME(Diag_TypeScript_Overload_Signature_Access_Specifier_Mismatch) \
QLJS_DIAG_TYPE_NAME(Diag_TypeScript_Parameter_Property_Cannot_Be_Destructured) \
QLJS_DIAG_TYPE_NAME(Diag_TypeScript_Parameter_Property_Cannot_Be_Rest) \
QLJS_DIAG_TYPE_NAME(Diag_TypeScript_Parameter_Property_Not_Allowed_In_Declare_Class) \
Expand Down Expand Up @@ -355,6 +362,7 @@ namespace quick_lint_js {
QLJS_DIAG_TYPE_NAME(Diag_Unexpected_Right_Curly_In_JSX_Text) \
QLJS_DIAG_TYPE_NAME(Diag_Unexpected_Question_In_Expression) \
QLJS_DIAG_TYPE_NAME(Diag_Unexpected_Question_When_Destructuring) \
QLJS_DIAG_TYPE_NAME(Diag_Unexpected_Semicolon_After_Overload_Signature) \
QLJS_DIAG_TYPE_NAME(Diag_Unexpected_Semicolon_In_C_Style_For_Loop) \
QLJS_DIAG_TYPE_NAME(Diag_Unexpected_Semicolon_In_For_In_Loop) \
QLJS_DIAG_TYPE_NAME(Diag_Unexpected_Semicolon_In_For_Of_Loop) \
Expand Down Expand Up @@ -415,7 +423,7 @@ namespace quick_lint_js {
/* END */
// clang-format on

inline constexpr int Diag_Type_Count = 401;
inline constexpr int Diag_Type_Count = 409;

extern const Diagnostic_Info all_diagnostic_infos[Diag_Type_Count];
}
Expand Down
Loading

0 comments on commit b7367c0

Please sign in to comment.