Skip to content
This repository was archived by the owner on Aug 31, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
refactor(rome_js_parser): Inroduce TypeContext
  • Loading branch information
MichaReiser committed Dec 30, 2022
commit daa804b9470896fe058b0bfb5e85677f9a9eca23
31 changes: 1 addition & 30 deletions crates/rome_js_parser/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,6 @@ impl ParserState {
.contains(ParsingContextFlags::BREAK_ALLOWED)
}

pub fn allow_conditional_type(&self) -> bool {
!self
.parsing_context
.contains(ParsingContextFlags::DISALLOW_CONDITIONAL_TYPE)
}

pub fn strict(&self) -> Option<&StrictMode> {
self.strict.as_ref()
}
Expand Down Expand Up @@ -377,7 +371,7 @@ bitflags! {
/// snapshots each individual boolean field to allow restoring the previous state. With bitflags, all that
/// is needed is to copy away the flags field and restore it after.
#[derive(Default)]
pub(crate) struct ParsingContextFlags: u16 {
pub(crate) struct ParsingContextFlags: u8 {
/// Whether the parser is in a generator function like `function* a() {}`
/// Matches the `Yield` parameter in the ECMA spec
const IN_GENERATOR = 1 << 0;
Expand All @@ -403,8 +397,6 @@ bitflags! {
/// Whatever the parser is in a TypeScript ambient context
const AMBIENT_CONTEXT = 1 << 7;

const DISALLOW_CONDITIONAL_TYPE = 1 << 8;

const LOOP = Self::BREAK_ALLOWED.bits | Self::CONTINUE_ALLOWED.bits;

/// Bitmask of all the flags that must be reset (shouldn't be inherited) when the parser enters a function
Expand Down Expand Up @@ -588,27 +580,6 @@ impl ChangeParserStateFlags for EnterType {
}
}

pub(crate) struct EnterConditionalTypes(bool);

impl EnterConditionalTypes {
pub(crate) const fn allow() -> Self {
Self(true)
}
pub(crate) const fn disallow() -> Self {
Self(false)
}
}

impl ChangeParserStateFlags for EnterConditionalTypes {
fn compute_new_flags(&self, existing: ParsingContextFlags) -> ParsingContextFlags {
if self.0 {
existing - ParsingContextFlags::DISALLOW_CONDITIONAL_TYPE
} else {
existing | ParsingContextFlags::DISALLOW_CONDITIONAL_TYPE
}
}
}

#[derive(Default)]
pub(crate) struct EnterAmbientContextSnapshot {
flags: ParsingContextFlags,
Expand Down
24 changes: 15 additions & 9 deletions crates/rome_js_parser/src/syntax/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use crate::syntax::typescript::ts_parse_error::{
use crate::syntax::typescript::{
is_reserved_type_name, parse_ts_implements_clause, parse_ts_return_type_annotation,
parse_ts_type_annotation, parse_ts_type_arguments, parse_ts_type_parameters,
skip_ts_decorators,
skip_ts_decorators, TypeContext,
};

use crate::JsSyntaxFeature::TypeScript;
Expand Down Expand Up @@ -253,9 +253,13 @@ fn parse_class(p: &mut JsParser, kind: ClassKind) -> CompletedMarker {
// test ts ts_class_type_parameters
// class BuildError<A, B, C> {}
TypeScript
.parse_exclusive_syntax(p, parse_ts_type_parameters, |p, type_parameters| {
ts_only_syntax_error(p, "class type parameters", type_parameters.range(p))
})
.parse_exclusive_syntax(
p,
|p| parse_ts_type_parameters(p, TypeContext::default()),
|p, type_parameters| {
ts_only_syntax_error(p, "class type parameters", type_parameters.range(p))
},
)
.ok();

eat_class_heritage_clause(p);
Expand Down Expand Up @@ -683,7 +687,7 @@ fn parse_class_member_impl(
// get a<A>(): A {}
// set a<A>(value: A) {}
// }
if let Present(type_parameters) = parse_ts_type_parameters(p) {
if let Present(type_parameters) = parse_ts_type_parameters(p, TypeContext::default()) {
p.error(ts_accessor_type_parameters_error(p, &type_parameters))
}

Expand Down Expand Up @@ -1148,9 +1152,11 @@ fn parse_method_class_member_rest(
let optional = optional_member_token(p);

TypeScript
.parse_exclusive_syntax(p, parse_ts_type_parameters, |p, marker| {
ts_only_syntax_error(p, "type parameters", marker.range(p))
})
.parse_exclusive_syntax(
p,
|p| parse_ts_type_parameters(p, TypeContext::default()),
|p, marker| ts_only_syntax_error(p, "type parameters", marker.range(p)),
)
.ok();

let parameter_context = if modifiers.is_signature() {
Expand Down Expand Up @@ -1431,7 +1437,7 @@ fn parse_constructor_class_member_body(

// test_err ts ts_constructor_type_parameters
// class A { constructor<A>(b) {} }
if let Present(type_parameters) = parse_ts_type_parameters(p) {
if let Present(type_parameters) = parse_ts_type_parameters(p, TypeContext::default()) {
p.error(ts_constructor_type_parameters_error(p, &type_parameters));
}

Expand Down
4 changes: 2 additions & 2 deletions crates/rome_js_parser/src/syntax/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ fn parse_binary_or_logical_expression_recursive(
// as;
// let precedence = "hello" as const + 3 as number as number;
if op == T![as] {
parse_ts_type(p).or_add_diagnostic(p, expected_ts_type);
parse_ts_type(p, TypeContext::default()).or_add_diagnostic(p, expected_ts_type);
let mut as_expression = m.complete(p, TS_AS_EXPRESSION);

if TypeScript.is_unsupported(p) {
Expand Down Expand Up @@ -621,7 +621,7 @@ fn parse_binary_or_logical_expression_recursive(
// test_err ts_satisfies_expression
// let x = "hello" satisfies string;
if op == T![satisfies] {
parse_ts_type(p).or_add_diagnostic(p, expected_ts_type);
parse_ts_type(p, TypeContext::default()).or_add_diagnostic(p, expected_ts_type);
let mut satisfies_expression = m.complete(p, TS_SATISFIES_EXPRESSION);

if TypeScript.is_unsupported(p) {
Expand Down
22 changes: 13 additions & 9 deletions crates/rome_js_parser/src/syntax/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::syntax::stmt::{is_semi, parse_block_impl, semi, StatementContext};
use crate::syntax::typescript::ts_parse_error::ts_only_syntax_error;
use crate::syntax::typescript::{
parse_ts_return_type_annotation, parse_ts_type_annotation, parse_ts_type_parameters,
skip_ts_decorators, try_parse,
skip_ts_decorators, try_parse, TypeContext,
};

use crate::JsSyntaxFeature::TypeScript;
Expand Down Expand Up @@ -229,12 +229,16 @@ fn parse_function(p: &mut JsParser, m: Marker, kind: FunctionKind) -> CompletedM
}

TypeScript
.parse_exclusive_syntax(p, parse_ts_type_parameters, |p, marker| {
p.err_builder(
"type parameters can only be used in TypeScript files",
marker.range(p),
)
})
.parse_exclusive_syntax(
p,
|p| parse_ts_type_parameters(p, TypeContext::default()),
|p, marker| {
p.err_builder(
"type parameters can only be used in TypeScript files",
marker.range(p),
)
},
)
.ok();

let parameter_context = if !kind.is_expression() && TypeScript.is_supported(p) {
Expand Down Expand Up @@ -407,7 +411,7 @@ fn parse_ambient_function(
let binding = parse_binding(p);
let binding_range = p.cur_range();

parse_ts_type_parameters(p).ok();
parse_ts_type_parameters(p, TypeContext::default()).ok();
parse_parameter_list(p, ParameterContext::Declaration, SignatureFlags::empty())
.or_add_diagnostic(p, expected_parameters);
parse_ts_return_type_annotation(p).ok();
Expand Down Expand Up @@ -536,7 +540,7 @@ fn try_parse_parenthesized_arrow_function_head(
};

if p.at(T![<]) {
parse_ts_type_parameters(p).ok();
parse_ts_type_parameters(p, TypeContext::default()).ok();

if ambiguity.is_disallowed() && p.last() != Some(T![>]) {
return Err(m);
Expand Down
15 changes: 10 additions & 5 deletions crates/rome_js_parser/src/syntax/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use crate::syntax::typescript::ts_parse_error::{
};
use crate::syntax::typescript::{
parse_ts_return_type_annotation, parse_ts_type_annotation, parse_ts_type_parameters,
TypeContext,
};
use crate::JsSyntaxFeature::TypeScript;
use crate::{JsParser, ParseRecovery};
Expand Down Expand Up @@ -258,7 +259,7 @@ fn parse_getter_object_member(p: &mut JsParser) -> ParsedSyntax {

// test_err ts ts_object_getter_type_parameters
// ({ get a<A>(): A {} });
if let Present(type_parameters) = parse_ts_type_parameters(p) {
if let Present(type_parameters) = parse_ts_type_parameters(p, TypeContext::default()) {
p.error(ts_accessor_type_parameters_error(p, &type_parameters))
}

Expand Down Expand Up @@ -290,7 +291,7 @@ fn parse_setter_object_member(p: &mut JsParser) -> ParsedSyntax {

// test_err ts ts_object_setter_type_parameters
// ({ set a<A>(value: A) {} });
if let Present(type_parameters) = parse_ts_type_parameters(p) {
if let Present(type_parameters) = parse_ts_type_parameters(p, TypeContext::default()) {
p.error(ts_accessor_type_parameters_error(p, &type_parameters))
}

Expand Down Expand Up @@ -432,9 +433,13 @@ fn parse_method_object_member(p: &mut JsParser) -> ParsedSyntax {
/// Parses the body of a method object member starting right after the member name.
fn parse_method_object_member_body(p: &mut JsParser, flags: SignatureFlags) {
TypeScript
.parse_exclusive_syntax(p, parse_ts_type_parameters, |p, type_parameters| {
ts_only_syntax_error(p, "type parameters", type_parameters.range(p))
})
.parse_exclusive_syntax(
p,
|p| parse_ts_type_parameters(p, TypeContext::default()),
|p, type_parameters| {
ts_only_syntax_error(p, "type parameters", type_parameters.range(p))
},
)
.ok();

parse_parameter_list(p, ParameterContext::Implementation, flags)
Expand Down
2 changes: 1 addition & 1 deletion crates/rome_js_parser/src/syntax/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1835,7 +1835,7 @@ fn parse_catch_declaration(p: &mut JsParser) -> ParsedSyntax {
let annotation = p.start();
p.bump(T![:]);

if let Some(ty) = parse_ts_type(p).or_add_diagnostic(p, expected_ts_type) {
if let Some(ty) = parse_ts_type(p, TypeContext::default()).or_add_diagnostic(p, expected_ts_type) {
if !matches!(ty.kind(p), TS_ANY_TYPE | TS_UNKNOWN_TYPE) {
p.error(
p
Expand Down
2 changes: 1 addition & 1 deletion crates/rome_js_parser/src/syntax/typescript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ pub(crate) fn parse_ts_type_assertion_expression(

let m = p.start();
p.bump(T![<]);
parse_ts_type(p).or_add_diagnostic(p, expected_ts_type);
parse_ts_type(p, TypeContext::default()).or_add_diagnostic(p, expected_ts_type);
p.expect(T![>]);
parse_unary_expr(p, context).or_add_diagnostic(p, expected_expression);
Present(m.complete(p, TS_TYPE_ASSERTION_EXPRESSION))
Expand Down
8 changes: 4 additions & 4 deletions crates/rome_js_parser/src/syntax/typescript/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::syntax::stmt::{semi, STMT_RECOVERY_SET};
use crate::syntax::typescript::ts_parse_error::expected_ts_type;
use crate::syntax::typescript::{
expect_ts_type_list, parse_ts_identifier_binding, parse_ts_implements_clause, parse_ts_name,
parse_ts_type, parse_ts_type_parameters, TypeMembers,
parse_ts_type, parse_ts_type_parameters, TypeContext, TypeMembers,
};
use crate::{syntax, Absent, JsParser, ParseRecovery, ParsedSyntax, Present};
use rome_js_syntax::{JsSyntaxKind::*, *};
Expand Down Expand Up @@ -207,9 +207,9 @@ pub(crate) fn parse_ts_type_alias_declaration(p: &mut JsParser) -> ParsedSyntax
p.expect(T![type]);
parse_ts_identifier_binding(p, super::TsIdentifierContext::Type)
.or_add_diagnostic(p, expected_identifier);
parse_ts_type_parameters(p).ok();
parse_ts_type_parameters(p, TypeContext::default()).ok();
p.expect(T![=]);
parse_ts_type(p).or_add_diagnostic(p, expected_ts_type);
parse_ts_type(p, TypeContext::default()).or_add_diagnostic(p, expected_ts_type);

semi(p, TextRange::new(start, p.cur_range().end()));

Expand Down Expand Up @@ -298,7 +298,7 @@ pub(crate) fn parse_ts_interface_declaration(p: &mut JsParser) -> ParsedSyntax {
p.expect(T![interface]);
parse_ts_identifier_binding(p, super::TsIdentifierContext::Type)
.or_add_diagnostic(p, expected_identifier);
parse_ts_type_parameters(p).ok();
parse_ts_type_parameters(p, TypeContext::default()).ok();
eat_interface_heritage_clause(p);
p.expect(T!['{']);
TypeMembers.parse_list(p);
Expand Down
Loading