mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
feat(hir): add HirId and HirBuilder for facilitating lowering (#318)
This commit is contained in:
parent
2cd04811d1
commit
becc5d0a3b
5 changed files with 1850 additions and 20 deletions
|
|
@ -81,14 +81,17 @@ impl<'alloc, T: Hash> Hash for Box<'alloc, T> {
|
|||
pub struct Vec<'alloc, T>(collections::Vec<'alloc, T>);
|
||||
|
||||
impl<'alloc, T> Vec<'alloc, T> {
|
||||
#[inline]
|
||||
pub fn new_in(allocator: &'alloc Allocator) -> Self {
|
||||
Self(collections::Vec::new_in(allocator))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn with_capacity_in(capacity: usize, allocator: &'alloc Allocator) -> Self {
|
||||
Self(collections::Vec::with_capacity_in(capacity, allocator))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_iter_in<I: IntoIterator<Item = T>>(iter: I, allocator: &'alloc Allocator) -> Self {
|
||||
Self(collections::Vec::from_iter_in(iter, allocator))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,14 +10,16 @@ use oxc_ast::{Atom, SourceType, Span};
|
|||
#[cfg(feature = "serde")]
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Hash)]
|
||||
use crate::HirId;
|
||||
|
||||
#[derive(Debug, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type", rename_all = "camelCase"))]
|
||||
pub struct Program<'a> {
|
||||
#[cfg_attr(feature = "serde", serde(flatten))]
|
||||
pub span: Span,
|
||||
pub source_type: SourceType,
|
||||
pub directives: Vec<'a, Directive<'a>>,
|
||||
// pub body: Vec<'a, Statement<'a>>,
|
||||
pub body: Vec<'a, Statement<'a>>,
|
||||
}
|
||||
|
||||
// impl<'a> Program<'a> {
|
||||
|
|
@ -873,9 +875,10 @@ pub enum Statement<'a> {
|
|||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type"))]
|
||||
pub struct Directive<'a> {
|
||||
pub hir_id: HirId,
|
||||
#[cfg_attr(feature = "serde", serde(flatten))]
|
||||
pub span: Span,
|
||||
// pub expression: StringLiteral,
|
||||
pub expression: StringLiteral,
|
||||
// directives should always use the unescaped raw string
|
||||
pub directive: &'a str,
|
||||
}
|
||||
|
|
|
|||
1790
crates/oxc_hir/src/hir_builder.rs
Normal file
1790
crates/oxc_hir/src/hir_builder.rs
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,4 +1,27 @@
|
|||
#![feature(let_chains)]
|
||||
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
pub mod hir;
|
||||
pub mod hir_builder;
|
||||
pub mod lower;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize))]
|
||||
pub struct HirId(NonZeroU32);
|
||||
|
||||
impl Default for HirId {
|
||||
fn default() -> Self {
|
||||
Self(unsafe { NonZeroU32::new_unchecked(1) })
|
||||
}
|
||||
}
|
||||
|
||||
impl HirId {
|
||||
#[must_use]
|
||||
pub fn increment(&self) -> Self {
|
||||
Self(self.0.saturating_add(1))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,35 +1,46 @@
|
|||
use oxc_allocator::{Allocator, Vec};
|
||||
use oxc_ast::ast;
|
||||
|
||||
use crate::hir;
|
||||
use crate::{hir, hir_builder::HirBuilder};
|
||||
|
||||
pub struct LowerToHIR<'a> {
|
||||
allocator: &'a Allocator,
|
||||
hir: HirBuilder<'a>,
|
||||
}
|
||||
|
||||
impl<'a> LowerToHIR<'a> {
|
||||
pub fn new(allocator: &'a Allocator) -> Self {
|
||||
Self { hir: HirBuilder::new(allocator) }
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn build(self, program: ast::Program<'a>) -> hir::Program<'a> {
|
||||
pub fn build(mut self, program: &ast::Program<'a>) -> hir::Program<'a> {
|
||||
self.lower_program(program)
|
||||
}
|
||||
|
||||
fn lower_program(&self, program: ast::Program<'a>) -> hir::Program<'a> {
|
||||
hir::Program {
|
||||
span: program.span,
|
||||
source_type: program.source_type,
|
||||
directives: self.lower_directives(program.directives),
|
||||
// body: program.body,
|
||||
#[must_use]
|
||||
pub fn lower_vec<T, R, F>(&mut self, items: &Vec<'a, T>, cb: F) -> Vec<'a, R>
|
||||
where
|
||||
F: Fn(&mut Self, &T) -> R,
|
||||
{
|
||||
let mut vec = self.hir.new_vec_with_capacity(items.len());
|
||||
for item in items {
|
||||
vec.push(cb(self, item));
|
||||
}
|
||||
vec
|
||||
}
|
||||
|
||||
fn lower_directives(
|
||||
&self,
|
||||
directives: Vec<'a, ast::Directive<'a>>,
|
||||
) -> Vec<'a, hir::Directive<'a>> {
|
||||
let directives =
|
||||
directives.into_iter().map(|d| hir::Directive { span: d.span, directive: d.directive });
|
||||
Vec::from_iter_in(directives, self.allocator)
|
||||
fn lower_program(&mut self, program: &ast::Program<'a>) -> hir::Program<'a> {
|
||||
let directives = self.lower_vec(&program.directives, Self::lower_directive);
|
||||
let statements = self.lower_vec(&program.body, Self::lower_statement);
|
||||
self.hir.program(program.span, program.source_type, directives, statements)
|
||||
}
|
||||
|
||||
// manually type out everything ...
|
||||
fn lower_directive(&mut self, directive: &ast::Directive<'a>) -> hir::Directive<'a> {
|
||||
self.hir.directive(directive.span, directive.expression.clone(), directive.directive)
|
||||
}
|
||||
|
||||
#[allow(clippy::unused_self)]
|
||||
fn lower_statement(&mut self, _statement: &ast::Statement<'a>) -> hir::Statement<'a> {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue