Skip to content

Commit

Permalink
refactor(biome_js_parser/syntax): use enumflags2 for TypeContext (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Javimtib92 committed Sep 5, 2024
1 parent e2171d3 commit 8dcfff0
Showing 1 changed file with 66 additions and 28 deletions.
94 changes: 66 additions & 28 deletions crates/biome_js_parser/src/syntax/typescript/types.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::ops::{BitOr, Sub};

use crate::parser::{RecoveryError, RecoveryResult};
use crate::prelude::*;
use crate::state::{EnterType, SignatureFlags};
Expand Down Expand Up @@ -27,7 +29,7 @@ use crate::syntax::typescript::ts_parse_error::{
ts_in_out_modifier_cannot_appear_on_a_type_parameter,
};
use biome_parser::parse_lists::{ParseNodeList, ParseSeparatedList};
use bitflags::bitflags;
use enumflags2::{bitflags, make_bitflags, BitFlags};
use smallvec::SmallVec;

use crate::lexer::{JsLexContext, JsReLexContext};
Expand All @@ -41,34 +43,54 @@ use biome_js_syntax::{JsSyntaxKind::*, *};

use super::{expect_ts_index_signature_member, is_at_ts_index_signature_member, MemberParent};

bitflags! {
/// Context tracking state that applies to the parsing of all types
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
pub(crate) struct TypeContext: u8 {
/// Whether conditional types `extends string ? string : number` are allowed in the current context.
///
/// By default, conditional types are allowed.
const DISALLOW_CONDITIONAL_TYPES = 1 << 0;
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[bitflags]
#[repr(u8)]
enum ContextFlag {
DisallowConditionalTypes = 1 << 0,
AllowInOutModifier = 1 << 1,
AllowConstModifier = 1 << 2,
InConditionalExtends = 1 << 3,
TypeOrInterfaceDeclaration = 1 << 4,
}

/// Context tracking state that applies to the parsing of all types
#[derive(Debug, Default, Copy, Clone)]
pub(crate) struct TypeContext(BitFlags<ContextFlag>);

impl TypeContext {
/// Whether conditional types `extends string ? string : number` are allowed in the current context.
///
/// By default, conditional types are allowed.
pub const DISALLOW_CONDITIONAL_TYPES: Self =
Self(make_bitflags!(ContextFlag::{DisallowConditionalTypes}));

/// Whether 'in' and 'out' modifiers are allowed in the current context.
///
/// By default, 'in' and 'out' modifiers are not allowed.
pub const ALLOW_IN_OUT_MODIFIER: Self = Self(make_bitflags!(ContextFlag::{AllowInOutModifier}));

/// Whether 'in' and 'out' modifiers are allowed in the current context.
///
/// By default, 'in' and 'out' modifiers are not allowed.
const ALLOW_IN_OUT_MODIFIER = 1 << 1;
/// Whether 'const' modifier is allowed in the current context.
///
/// By default, 'const' modifier is not allowed.
pub const ALLOW_CONST_MODIFIER: Self = Self(make_bitflags!(ContextFlag::{AllowConstModifier}));

/// Whether 'const' modifier is allowed in the current context.
///
/// By default, 'const' modifier is not allowed.
const ALLOW_CONST_MODIFIER = 1 << 2;
/// Whether the parser is inside a conditional extends
pub const IN_CONDITIONAL_EXTENDS: Self =
Self(make_bitflags!(ContextFlag::{InConditionalExtends}));

/// Whether the parser is inside a conditional extends
const IN_CONDITIONAL_EXTENDS = 1 << 3;
/// Whether the current context is within a type or interface declaration
pub const TYPE_OR_INTERFACE_DECLARATION: Self =
Self(make_bitflags!(ContextFlag::{TypeOrInterfaceDeclaration}));

/// Whether the current context is within a type or interface declaration
const TYPE_OR_INTERFACE_DECLARATION = 1 << 4;
pub const fn empty() -> Self {
Self(BitFlags::EMPTY)
}

pub fn contains(&self, other: impl Into<TypeContext>) -> bool {
self.0.contains(other.into().0)
}
}

impl TypeContext {
pub(crate) fn and_allow_conditional_types(self, allow: bool) -> Self {
self.and(TypeContext::DISALLOW_CONDITIONAL_TYPES, !allow)
}
Expand All @@ -89,23 +111,23 @@ impl TypeContext {
self.and(TypeContext::TYPE_OR_INTERFACE_DECLARATION, allow)
}

pub(crate) const fn is_conditional_type_allowed(&self) -> bool {
pub(crate) fn is_conditional_type_allowed(&self) -> bool {
!self.contains(TypeContext::DISALLOW_CONDITIONAL_TYPES)
}

pub(crate) const fn is_in_out_modifier_allowed(&self) -> bool {
pub(crate) fn is_in_out_modifier_allowed(&self) -> bool {
self.contains(TypeContext::ALLOW_IN_OUT_MODIFIER)
}

pub(crate) const fn is_const_modifier_allowed(&self) -> bool {
pub(crate) fn is_const_modifier_allowed(&self) -> bool {
self.contains(TypeContext::ALLOW_CONST_MODIFIER)
}

pub(crate) const fn in_conditional_extends(&self) -> bool {
pub(crate) fn in_conditional_extends(&self) -> bool {
self.contains(TypeContext::IN_CONDITIONAL_EXTENDS)
}

pub(crate) const fn is_in_type_or_interface_declaration(&self) -> bool {
pub(crate) fn is_in_type_or_interface_declaration(&self) -> bool {
self.contains(TypeContext::TYPE_OR_INTERFACE_DECLARATION)
}

Expand All @@ -119,6 +141,22 @@ impl TypeContext {
}
}

impl BitOr for TypeContext {
type Output = Self;

fn bitor(self, rhs: Self) -> Self::Output {
Self(self.0 | rhs.0)
}
}

impl Sub for TypeContext {
type Output = Self;

fn sub(self, rhs: Self) -> Self::Output {
Self(self.0 & !rhs.0)
}
}

pub(crate) fn is_reserved_type_name(name: &str) -> bool {
name.len() <= 6
&& name.len() >= 3
Expand Down

0 comments on commit 8dcfff0

Please sign in to comment.