Skip to content

Commit

Permalink
feat(typescript): parse declare fields in classes
Browse files Browse the repository at this point in the history
  • Loading branch information
strager committed Sep 23, 2023
1 parent 4a0bc7c commit eebece1
Show file tree
Hide file tree
Showing 12 changed files with 402 additions and 22 deletions.
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Semantic Versioning.
(Implemented by [Samir Hamud][].)
* Type predicates are now supported in function types (e.g.
`(param) => param is Type`).
* `declare` fields are now parsed inside classes.

### Fixed

Expand Down
20 changes: 20 additions & 0 deletions po/messages.pot
Original file line number Diff line number Diff line change
Expand Up @@ -1501,6 +1501,22 @@ msgstr ""
msgid "'declare class' cannot contain static block"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "TypeScript 'declare' fields are now allowed in JavaScript"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "private identifiers are not allowed for 'declare' fields; use 'private' instead"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "assignment assertion is not allowed on fields be marked 'declare'"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "methods cannot be marked 'declare'"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "TypeScript's 'interface' feature is not allowed in JavaScript code"
msgstr ""
Expand Down Expand Up @@ -1905,6 +1921,10 @@ msgstr ""
msgid "'accessor' is not allowed for TypeScript interface fields"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "'declare' is not allowed for TypeScript interface fields"
msgstr ""

#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
msgid "TypeScript interface fields cannot be initalized"
msgstr ""
Expand Down
78 changes: 78 additions & 0 deletions src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4467,6 +4467,70 @@ const QLJS_CONSTINIT Diagnostic_Info all_diagnostic_infos[] = {
},
},

// Diag_TypeScript_Declare_Field_Not_Allowed_In_JavaScript
{
.code = 415,
.severity = Diagnostic_Severity::error,
.message_formats = {
QLJS_TRANSLATABLE("TypeScript 'declare' fields are now allowed in JavaScript"),
},
.message_args = {
{
Diagnostic_Message_Arg_Info(offsetof(Diag_TypeScript_Declare_Field_Not_Allowed_In_JavaScript, declare_keyword), Diagnostic_Arg_Type::source_code_span),
},
},
},

// Diag_TypeScript_Declare_Field_Cannot_Use_Private_Identifier
{
.code = 416,
.severity = Diagnostic_Severity::error,
.message_formats = {
QLJS_TRANSLATABLE("private identifiers are not allowed for 'declare' fields; use 'private' instead"),
QLJS_TRANSLATABLE("'declare' here"),
},
.message_args = {
{
Diagnostic_Message_Arg_Info(offsetof(Diag_TypeScript_Declare_Field_Cannot_Use_Private_Identifier, private_identifier_hash), Diagnostic_Arg_Type::source_code_span),
},
{
Diagnostic_Message_Arg_Info(offsetof(Diag_TypeScript_Declare_Field_Cannot_Use_Private_Identifier, declare_keyword), Diagnostic_Arg_Type::source_code_span),
},
},
},

// Diag_TypeScript_Declare_Field_Cannot_Be_Assignment_Asserted
{
.code = 418,
.severity = Diagnostic_Severity::error,
.message_formats = {
QLJS_TRANSLATABLE("assignment assertion is not allowed on fields be marked 'declare'"),
QLJS_TRANSLATABLE("'declare' here"),
},
.message_args = {
{
Diagnostic_Message_Arg_Info(offsetof(Diag_TypeScript_Declare_Field_Cannot_Be_Assignment_Asserted, bang), Diagnostic_Arg_Type::source_code_span),
},
{
Diagnostic_Message_Arg_Info(offsetof(Diag_TypeScript_Declare_Field_Cannot_Be_Assignment_Asserted, declare_keyword), Diagnostic_Arg_Type::source_code_span),
},
},
},

// Diag_TypeScript_Declare_Method
{
.code = 417,
.severity = Diagnostic_Severity::error,
.message_formats = {
QLJS_TRANSLATABLE("methods cannot be marked 'declare'"),
},
.message_args = {
{
Diagnostic_Message_Arg_Info(offsetof(Diag_TypeScript_Declare_Method, declare_keyword), Diagnostic_Arg_Type::source_code_span),
},
},
},

// Diag_TypeScript_Interfaces_Not_Allowed_In_JavaScript
{
.code = 213,
Expand Down Expand Up @@ -5776,6 +5840,20 @@ const QLJS_CONSTINIT Diagnostic_Info all_diagnostic_infos[] = {
},
},

// Diag_Interface_Field_Cannot_Be_Declare
{
.code = 419,
.severity = Diagnostic_Severity::error,
.message_formats = {
QLJS_TRANSLATABLE("'declare' is not allowed for TypeScript interface fields"),
},
.message_args = {
{
Diagnostic_Message_Arg_Info(offsetof(Diag_Interface_Field_Cannot_Be_Declare, declare_keyword), Diagnostic_Arg_Type::source_code_span),
},
},
},

// Diag_Interface_Fields_Cannot_Have_Initializers
{
.code = 221,
Expand Down
7 changes: 6 additions & 1 deletion src/quick-lint-js/diag/diagnostic-metadata-generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,10 @@ namespace quick_lint_js {
QLJS_DIAG_TYPE_NAME(Diag_TypeScript_Inline_Type_Import_Not_Allowed_In_Type_Only_Import) \
QLJS_DIAG_TYPE_NAME(Diag_TypeScript_Interfaces_Cannot_Contain_Static_Blocks) \
QLJS_DIAG_TYPE_NAME(Diag_TypeScript_Declare_Class_Cannot_Contain_Static_Block_Statement) \
QLJS_DIAG_TYPE_NAME(Diag_TypeScript_Declare_Field_Not_Allowed_In_JavaScript) \
QLJS_DIAG_TYPE_NAME(Diag_TypeScript_Declare_Field_Cannot_Use_Private_Identifier) \
QLJS_DIAG_TYPE_NAME(Diag_TypeScript_Declare_Field_Cannot_Be_Assignment_Asserted) \
QLJS_DIAG_TYPE_NAME(Diag_TypeScript_Declare_Method) \
QLJS_DIAG_TYPE_NAME(Diag_TypeScript_Interfaces_Not_Allowed_In_JavaScript) \
QLJS_DIAG_TYPE_NAME(Diag_TypeScript_Missing_Name_And_Colon_In_Named_Tuple_Type) \
QLJS_DIAG_TYPE_NAME(Diag_TypeScript_Missing_Name_In_Named_Tuple_Type) \
Expand Down Expand Up @@ -396,6 +400,7 @@ namespace quick_lint_js {
QLJS_DIAG_TYPE_NAME(Diag_Function_Call_Before_Declaration_In_Block_Scope) \
QLJS_DIAG_TYPE_NAME(Diag_Import_Cannot_Have_Declare_Keyword) \
QLJS_DIAG_TYPE_NAME(Diag_Interface_Field_Cannot_Be_Accessor) \
QLJS_DIAG_TYPE_NAME(Diag_Interface_Field_Cannot_Be_Declare) \
QLJS_DIAG_TYPE_NAME(Diag_Interface_Fields_Cannot_Have_Initializers) \
QLJS_DIAG_TYPE_NAME(Diag_Interface_Methods_Cannot_Be_Async) \
QLJS_DIAG_TYPE_NAME(Diag_Interface_Methods_Cannot_Be_Generators) \
Expand Down Expand Up @@ -432,7 +437,7 @@ namespace quick_lint_js {
/* END */
// clang-format on

inline constexpr int Diag_Type_Count = 418;
inline constexpr int Diag_Type_Count = 423;

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

struct Diag_TypeScript_Declare_Field_Not_Allowed_In_JavaScript {
[[qljs::diag("E0415", Diagnostic_Severity::error)]] //
[[qljs::message("TypeScript 'declare' fields are now allowed in JavaScript",
ARG(declare_keyword))]] //
Source_Code_Span declare_keyword;
};

struct Diag_TypeScript_Declare_Field_Cannot_Use_Private_Identifier {
[[qljs::diag("E0416", Diagnostic_Severity::error)]] //
[
[qljs::message("private identifiers are not allowed for 'declare' "
"fields; use 'private' instead",
ARG(private_identifier_hash))]] //
[[qljs::message("'declare' here", ARG(declare_keyword))]] //
Source_Code_Span private_identifier_hash;
Source_Code_Span declare_keyword;
};

struct Diag_TypeScript_Declare_Field_Cannot_Be_Assignment_Asserted {
[[qljs::diag("E0418", Diagnostic_Severity::error)]] //
[[qljs::message(
"assignment assertion is not allowed on fields be marked 'declare'",
ARG(bang))]] //
[[qljs::message("'declare' here", ARG(declare_keyword))]] //
Source_Code_Span bang;
Source_Code_Span declare_keyword;
};

struct Diag_TypeScript_Declare_Method {
[[qljs::diag("E0417", Diagnostic_Severity::error)]] //
[[qljs::message("methods cannot be marked 'declare'",
ARG(declare_keyword))]] //
Source_Code_Span declare_keyword;
};

struct Diag_TypeScript_Interfaces_Not_Allowed_In_JavaScript {
[[qljs::diag("E0213", Diagnostic_Severity::error)]] //
[[qljs::message(
Expand Down Expand Up @@ -2976,6 +3011,13 @@ struct Diag_Interface_Field_Cannot_Be_Accessor {
Source_Code_Span accessor_keyword;
};

struct Diag_Interface_Field_Cannot_Be_Declare {
[[qljs::diag("E0419", Diagnostic_Severity::error)]] //
[[qljs::message("'declare' is not allowed for TypeScript interface fields",
ARG(declare_keyword))]] //
Source_Code_Span declare_keyword;
};

struct Diag_Interface_Fields_Cannot_Have_Initializers {
[[qljs::diag("E0221", Diagnostic_Severity::error)]] //
[[qljs::message("TypeScript interface fields cannot be initalized",
Expand Down
4 changes: 4 additions & 0 deletions src/quick-lint-js/fe/identifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ class Identifier {
return String8_View(this->normalized_begin_, this->normalized_size_);
}

bool is_private_identifier() const {
return this->normalized_begin_[0] == u8'#';
}

private:
const Char8* span_begin_;
const Char8* normalized_begin_;
Expand Down
Loading

0 comments on commit eebece1

Please sign in to comment.