mirror of
https://github.com/danbulant/oxc
synced 2026-05-25 04:42:10 +00:00
refactor(ast): move StringLiteral definition higher up (#7270)
Pure refactor. `StringLiteral` definition was sandwiched in the middle of RegExp-related code. Move it higher up in `literal.rs`. All the rest of the diff is just re-ordering generated code.
This commit is contained in:
parent
834c94d9d2
commit
de472ca7c0
13 changed files with 132 additions and 132 deletions
|
|
@ -59,6 +59,21 @@ pub struct NumericLiteral<'a> {
|
|||
pub base: NumberBase,
|
||||
}
|
||||
|
||||
/// String literal
|
||||
///
|
||||
/// <https://tc39.es/ecma262/#sec-literals-string-literals>
|
||||
#[ast(visit)]
|
||||
#[derive(Debug, Clone)]
|
||||
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
|
||||
pub struct StringLiteral<'a> {
|
||||
/// Node location in source code
|
||||
pub span: Span,
|
||||
/// The value of the string.
|
||||
///
|
||||
/// Any escape sequences in the raw code are unescaped.
|
||||
pub value: Atom<'a>,
|
||||
}
|
||||
|
||||
/// BigInt literal
|
||||
#[ast(visit)]
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
@ -128,21 +143,6 @@ pub enum RegExpPattern<'a> {
|
|||
Pattern(Box<'a, Pattern<'a>>) = 2,
|
||||
}
|
||||
|
||||
/// String literal
|
||||
///
|
||||
/// <https://tc39.es/ecma262/#sec-literals-string-literals>
|
||||
#[ast(visit)]
|
||||
#[derive(Debug, Clone)]
|
||||
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
|
||||
pub struct StringLiteral<'a> {
|
||||
/// Node location in source code
|
||||
pub span: Span,
|
||||
/// The value of the string.
|
||||
///
|
||||
/// Any escape sequences in the raw code are unescaped.
|
||||
pub value: Atom<'a>,
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
/// Regular expression flags.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -25,6 +25,11 @@ const _: () = {
|
|||
assert!(offset_of!(NumericLiteral, raw) == 16usize);
|
||||
assert!(offset_of!(NumericLiteral, base) == 32usize);
|
||||
|
||||
assert!(size_of::<StringLiteral>() == 24usize);
|
||||
assert!(align_of::<StringLiteral>() == 8usize);
|
||||
assert!(offset_of!(StringLiteral, span) == 0usize);
|
||||
assert!(offset_of!(StringLiteral, value) == 8usize);
|
||||
|
||||
assert!(size_of::<BigIntLiteral>() == 32usize);
|
||||
assert!(align_of::<BigIntLiteral>() == 8usize);
|
||||
assert!(offset_of!(BigIntLiteral, span) == 0usize);
|
||||
|
|
@ -45,11 +50,6 @@ const _: () = {
|
|||
assert!(size_of::<RegExpPattern>() == 24usize);
|
||||
assert!(align_of::<RegExpPattern>() == 8usize);
|
||||
|
||||
assert!(size_of::<StringLiteral>() == 24usize);
|
||||
assert!(align_of::<StringLiteral>() == 8usize);
|
||||
assert!(offset_of!(StringLiteral, span) == 0usize);
|
||||
assert!(offset_of!(StringLiteral, value) == 8usize);
|
||||
|
||||
assert!(size_of::<Program>() == 160usize);
|
||||
assert!(align_of::<Program>() == 8usize);
|
||||
assert!(offset_of!(Program, span) == 0usize);
|
||||
|
|
@ -1581,6 +1581,11 @@ const _: () = {
|
|||
assert!(offset_of!(NumericLiteral, raw) == 16usize);
|
||||
assert!(offset_of!(NumericLiteral, base) == 24usize);
|
||||
|
||||
assert!(size_of::<StringLiteral>() == 16usize);
|
||||
assert!(align_of::<StringLiteral>() == 4usize);
|
||||
assert!(offset_of!(StringLiteral, span) == 0usize);
|
||||
assert!(offset_of!(StringLiteral, value) == 8usize);
|
||||
|
||||
assert!(size_of::<BigIntLiteral>() == 20usize);
|
||||
assert!(align_of::<BigIntLiteral>() == 4usize);
|
||||
assert!(offset_of!(BigIntLiteral, span) == 0usize);
|
||||
|
|
@ -1601,11 +1606,6 @@ const _: () = {
|
|||
assert!(size_of::<RegExpPattern>() == 12usize);
|
||||
assert!(align_of::<RegExpPattern>() == 4usize);
|
||||
|
||||
assert!(size_of::<StringLiteral>() == 16usize);
|
||||
assert!(align_of::<StringLiteral>() == 4usize);
|
||||
assert!(offset_of!(StringLiteral, span) == 0usize);
|
||||
assert!(offset_of!(StringLiteral, value) == 8usize);
|
||||
|
||||
assert!(size_of::<Program>() == 88usize);
|
||||
assert!(align_of::<Program>() == 4usize);
|
||||
assert!(offset_of!(Program, span) == 0usize);
|
||||
|
|
|
|||
|
|
@ -116,6 +116,36 @@ impl<'a> AstBuilder<'a> {
|
|||
Box::new_in(self.numeric_literal(span, value, raw, base), self.allocator)
|
||||
}
|
||||
|
||||
/// Build a [`StringLiteral`].
|
||||
///
|
||||
/// If you want the built node to be allocated in the memory arena, use [`AstBuilder::alloc_string_literal`] instead.
|
||||
///
|
||||
/// ## Parameters
|
||||
/// - span: Node location in source code
|
||||
/// - value: The value of the string.
|
||||
#[inline]
|
||||
pub fn string_literal<A>(self, span: Span, value: A) -> StringLiteral<'a>
|
||||
where
|
||||
A: IntoIn<'a, Atom<'a>>,
|
||||
{
|
||||
StringLiteral { span, value: value.into_in(self.allocator) }
|
||||
}
|
||||
|
||||
/// Build a [`StringLiteral`], and store it in the memory arena.
|
||||
///
|
||||
/// Returns a [`Box`] containing the newly-allocated node. If you want a stack-allocated node, use [`AstBuilder::string_literal`] instead.
|
||||
///
|
||||
/// ## Parameters
|
||||
/// - span: Node location in source code
|
||||
/// - value: The value of the string.
|
||||
#[inline]
|
||||
pub fn alloc_string_literal<A>(self, span: Span, value: A) -> Box<'a, StringLiteral<'a>>
|
||||
where
|
||||
A: IntoIn<'a, Atom<'a>>,
|
||||
{
|
||||
Box::new_in(self.string_literal(span, value), self.allocator)
|
||||
}
|
||||
|
||||
/// Build a [`BigIntLiteral`].
|
||||
///
|
||||
/// If you want the built node to be allocated in the memory arena, use [`AstBuilder::alloc_big_int_literal`] instead.
|
||||
|
|
@ -190,36 +220,6 @@ impl<'a> AstBuilder<'a> {
|
|||
Box::new_in(self.reg_exp_literal(span, regex, raw), self.allocator)
|
||||
}
|
||||
|
||||
/// Build a [`StringLiteral`].
|
||||
///
|
||||
/// If you want the built node to be allocated in the memory arena, use [`AstBuilder::alloc_string_literal`] instead.
|
||||
///
|
||||
/// ## Parameters
|
||||
/// - span: Node location in source code
|
||||
/// - value: The value of the string.
|
||||
#[inline]
|
||||
pub fn string_literal<A>(self, span: Span, value: A) -> StringLiteral<'a>
|
||||
where
|
||||
A: IntoIn<'a, Atom<'a>>,
|
||||
{
|
||||
StringLiteral { span, value: value.into_in(self.allocator) }
|
||||
}
|
||||
|
||||
/// Build a [`StringLiteral`], and store it in the memory arena.
|
||||
///
|
||||
/// Returns a [`Box`] containing the newly-allocated node. If you want a stack-allocated node, use [`AstBuilder::string_literal`] instead.
|
||||
///
|
||||
/// ## Parameters
|
||||
/// - span: Node location in source code
|
||||
/// - value: The value of the string.
|
||||
#[inline]
|
||||
pub fn alloc_string_literal<A>(self, span: Span, value: A) -> Box<'a, StringLiteral<'a>>
|
||||
where
|
||||
A: IntoIn<'a, Atom<'a>>,
|
||||
{
|
||||
Box::new_in(self.string_literal(span, value), self.allocator)
|
||||
}
|
||||
|
||||
/// Build a [`Program`].
|
||||
///
|
||||
/// If you want the built node to be allocated in the memory arena, use [`AstBuilder::alloc_program`] instead.
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ pub enum AstType {
|
|||
BooleanLiteral,
|
||||
NullLiteral,
|
||||
NumericLiteral,
|
||||
StringLiteral,
|
||||
BigIntLiteral,
|
||||
RegExpLiteral,
|
||||
StringLiteral,
|
||||
Program,
|
||||
IdentifierName,
|
||||
IdentifierReference,
|
||||
|
|
@ -183,9 +183,9 @@ pub enum AstKind<'a> {
|
|||
BooleanLiteral(&'a BooleanLiteral),
|
||||
NullLiteral(&'a NullLiteral),
|
||||
NumericLiteral(&'a NumericLiteral<'a>),
|
||||
StringLiteral(&'a StringLiteral<'a>),
|
||||
BigIntLiteral(&'a BigIntLiteral<'a>),
|
||||
RegExpLiteral(&'a RegExpLiteral<'a>),
|
||||
StringLiteral(&'a StringLiteral<'a>),
|
||||
Program(&'a Program<'a>),
|
||||
IdentifierName(&'a IdentifierName<'a>),
|
||||
IdentifierReference(&'a IdentifierReference<'a>),
|
||||
|
|
@ -354,9 +354,9 @@ impl<'a> GetSpan for AstKind<'a> {
|
|||
Self::BooleanLiteral(it) => it.span(),
|
||||
Self::NullLiteral(it) => it.span(),
|
||||
Self::NumericLiteral(it) => it.span(),
|
||||
Self::StringLiteral(it) => it.span(),
|
||||
Self::BigIntLiteral(it) => it.span(),
|
||||
Self::RegExpLiteral(it) => it.span(),
|
||||
Self::StringLiteral(it) => it.span(),
|
||||
Self::Program(it) => it.span(),
|
||||
Self::IdentifierName(it) => it.span(),
|
||||
Self::IdentifierReference(it) => it.span(),
|
||||
|
|
@ -548,6 +548,15 @@ impl<'a> AstKind<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_string_literal(self) -> Option<&'a StringLiteral<'a>> {
|
||||
if let Self::StringLiteral(v) = self {
|
||||
Some(v)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_big_int_literal(self) -> Option<&'a BigIntLiteral<'a>> {
|
||||
if let Self::BigIntLiteral(v) = self {
|
||||
|
|
@ -566,15 +575,6 @@ impl<'a> AstKind<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_string_literal(self) -> Option<&'a StringLiteral<'a>> {
|
||||
if let Self::StringLiteral(v) = self {
|
||||
Some(v)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_program(self) -> Option<&'a Program<'a>> {
|
||||
if let Self::Program(v) = self {
|
||||
|
|
|
|||
|
|
@ -44,6 +44,16 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for NumericLiteral<'old_alloc>
|
|||
}
|
||||
}
|
||||
|
||||
impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for StringLiteral<'old_alloc> {
|
||||
type Cloned = StringLiteral<'new_alloc>;
|
||||
fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned {
|
||||
StringLiteral {
|
||||
span: CloneIn::clone_in(&self.span, allocator),
|
||||
value: CloneIn::clone_in(&self.value, allocator),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for BigIntLiteral<'old_alloc> {
|
||||
type Cloned = BigIntLiteral<'new_alloc>;
|
||||
fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned {
|
||||
|
|
@ -87,16 +97,6 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for RegExpPattern<'old_alloc> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for StringLiteral<'old_alloc> {
|
||||
type Cloned = StringLiteral<'new_alloc>;
|
||||
fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned {
|
||||
StringLiteral {
|
||||
span: CloneIn::clone_in(&self.span, allocator),
|
||||
value: CloneIn::clone_in(&self.value, allocator),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for Program<'old_alloc> {
|
||||
type Cloned = Program<'new_alloc>;
|
||||
fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,12 @@ impl<'a> ContentEq for NumericLiteral<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ContentEq for StringLiteral<'a> {
|
||||
fn content_eq(&self, other: &Self) -> bool {
|
||||
ContentEq::content_eq(&self.value, &other.value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ContentEq for BigIntLiteral<'a> {
|
||||
fn content_eq(&self, other: &Self) -> bool {
|
||||
ContentEq::content_eq(&self.raw, &other.raw)
|
||||
|
|
@ -75,12 +81,6 @@ impl<'a> ContentEq for RegExpPattern<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ContentEq for StringLiteral<'a> {
|
||||
fn content_eq(&self, other: &Self) -> bool {
|
||||
ContentEq::content_eq(&self.value, &other.value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ContentEq for Program<'a> {
|
||||
fn content_eq(&self, other: &Self) -> bool {
|
||||
ContentEq::content_eq(&self.source_type, &other.source_type)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,12 @@ impl ContentHash for BooleanLiteral {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ContentHash for StringLiteral<'a> {
|
||||
fn content_hash<H: Hasher>(&self, state: &mut H) {
|
||||
ContentHash::content_hash(&self.value, state);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ContentHash for BigIntLiteral<'a> {
|
||||
fn content_hash<H: Hasher>(&self, state: &mut H) {
|
||||
ContentHash::content_hash(&self.raw, state);
|
||||
|
|
@ -55,12 +61,6 @@ impl<'a> ContentHash for RegExpPattern<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ContentHash for StringLiteral<'a> {
|
||||
fn content_hash<H: Hasher>(&self, state: &mut H) {
|
||||
ContentHash::content_hash(&self.value, state);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ContentHash for Program<'a> {
|
||||
fn content_hash<H: Hasher>(&self, state: &mut H) {
|
||||
ContentHash::content_hash(&self.source_type, state);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,16 @@ impl<'a> Serialize for NumericLiteral<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> Serialize for StringLiteral<'a> {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
let mut map = serializer.serialize_map(None)?;
|
||||
map.serialize_entry("type", "StringLiteral")?;
|
||||
self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?;
|
||||
map.serialize_entry("value", &self.value)?;
|
||||
map.end()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Serialize for BigIntLiteral<'a> {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
crate::serialize::ESTreeLiteral::from(self).serialize(serializer)
|
||||
|
|
@ -62,16 +72,6 @@ impl<'a> Serialize for RegExpPattern<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> Serialize for StringLiteral<'a> {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
let mut map = serializer.serialize_map(None)?;
|
||||
map.serialize_entry("type", "StringLiteral")?;
|
||||
self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?;
|
||||
map.serialize_entry("value", &self.value)?;
|
||||
map.end()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Serialize for Program<'a> {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
let mut map = serializer.serialize_map(None)?;
|
||||
|
|
|
|||
|
|
@ -34,6 +34,13 @@ impl<'a> GetSpan for NumericLiteral<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> GetSpan for StringLiteral<'a> {
|
||||
#[inline]
|
||||
fn span(&self) -> Span {
|
||||
self.span
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> GetSpan for BigIntLiteral<'a> {
|
||||
#[inline]
|
||||
fn span(&self) -> Span {
|
||||
|
|
@ -48,13 +55,6 @@ impl<'a> GetSpan for RegExpLiteral<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> GetSpan for StringLiteral<'a> {
|
||||
#[inline]
|
||||
fn span(&self) -> Span {
|
||||
self.span
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> GetSpan for Program<'a> {
|
||||
#[inline]
|
||||
fn span(&self) -> Span {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,13 @@ impl<'a> GetSpanMut for NumericLiteral<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> GetSpanMut for StringLiteral<'a> {
|
||||
#[inline]
|
||||
fn span_mut(&mut self) -> &mut Span {
|
||||
&mut self.span
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> GetSpanMut for BigIntLiteral<'a> {
|
||||
#[inline]
|
||||
fn span_mut(&mut self) -> &mut Span {
|
||||
|
|
@ -48,13 +55,6 @@ impl<'a> GetSpanMut for RegExpLiteral<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> GetSpanMut for StringLiteral<'a> {
|
||||
#[inline]
|
||||
fn span_mut(&mut self) -> &mut Span {
|
||||
&mut self.span
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> GetSpanMut for Program<'a> {
|
||||
#[inline]
|
||||
fn span_mut(&mut self) -> &mut Span {
|
||||
|
|
|
|||
|
|
@ -1494,6 +1494,11 @@ pub trait Traverse<'a> {
|
|||
#[inline]
|
||||
fn exit_numeric_literal(&mut self, node: &mut NumericLiteral<'a>, ctx: &mut TraverseCtx<'a>) {}
|
||||
|
||||
#[inline]
|
||||
fn enter_string_literal(&mut self, node: &mut StringLiteral<'a>, ctx: &mut TraverseCtx<'a>) {}
|
||||
#[inline]
|
||||
fn exit_string_literal(&mut self, node: &mut StringLiteral<'a>, ctx: &mut TraverseCtx<'a>) {}
|
||||
|
||||
#[inline]
|
||||
fn enter_big_int_literal(&mut self, node: &mut BigIntLiteral<'a>, ctx: &mut TraverseCtx<'a>) {}
|
||||
#[inline]
|
||||
|
|
@ -1504,11 +1509,6 @@ pub trait Traverse<'a> {
|
|||
#[inline]
|
||||
fn exit_reg_exp_literal(&mut self, node: &mut RegExpLiteral<'a>, ctx: &mut TraverseCtx<'a>) {}
|
||||
|
||||
#[inline]
|
||||
fn enter_string_literal(&mut self, node: &mut StringLiteral<'a>, ctx: &mut TraverseCtx<'a>) {}
|
||||
#[inline]
|
||||
fn exit_string_literal(&mut self, node: &mut StringLiteral<'a>, ctx: &mut TraverseCtx<'a>) {}
|
||||
|
||||
#[inline]
|
||||
fn enter_ts_this_parameter(
|
||||
&mut self,
|
||||
|
|
|
|||
|
|
@ -3606,6 +3606,15 @@ pub(crate) unsafe fn walk_numeric_literal<'a, Tr: Traverse<'a>>(
|
|||
traverser.exit_numeric_literal(&mut *node, ctx);
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn walk_string_literal<'a, Tr: Traverse<'a>>(
|
||||
traverser: &mut Tr,
|
||||
node: *mut StringLiteral<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
traverser.enter_string_literal(&mut *node, ctx);
|
||||
traverser.exit_string_literal(&mut *node, ctx);
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn walk_big_int_literal<'a, Tr: Traverse<'a>>(
|
||||
traverser: &mut Tr,
|
||||
node: *mut BigIntLiteral<'a>,
|
||||
|
|
@ -3624,15 +3633,6 @@ pub(crate) unsafe fn walk_reg_exp_literal<'a, Tr: Traverse<'a>>(
|
|||
traverser.exit_reg_exp_literal(&mut *node, ctx);
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn walk_string_literal<'a, Tr: Traverse<'a>>(
|
||||
traverser: &mut Tr,
|
||||
node: *mut StringLiteral<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
traverser.enter_string_literal(&mut *node, ctx);
|
||||
traverser.exit_string_literal(&mut *node, ctx);
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn walk_ts_this_parameter<'a, Tr: Traverse<'a>>(
|
||||
traverser: &mut Tr,
|
||||
node: *mut TSThisParameter<'a>,
|
||||
|
|
|
|||
10
npm/oxc-types/types.d.ts
vendored
10
npm/oxc-types/types.d.ts
vendored
|
|
@ -19,6 +19,11 @@ export interface NumericLiteral extends Span {
|
|||
raw: string;
|
||||
}
|
||||
|
||||
export interface StringLiteral extends Span {
|
||||
type: 'StringLiteral';
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface BigIntLiteral extends Span {
|
||||
type: 'Literal';
|
||||
raw: string;
|
||||
|
|
@ -40,11 +45,6 @@ export interface RegExp {
|
|||
|
||||
export type RegExpPattern = string | string | Pattern;
|
||||
|
||||
export interface StringLiteral extends Span {
|
||||
type: 'StringLiteral';
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface Program extends Span {
|
||||
type: 'Program';
|
||||
sourceType: SourceType;
|
||||
|
|
|
|||
Loading…
Reference in a new issue