feat(hir): add HirId and HirBuilder for facilitating lowering (#318)

This commit is contained in:
Boshen 2023-04-25 23:16:04 +08:00 committed by GitHub
parent 2cd04811d1
commit becc5d0a3b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 1850 additions and 20 deletions

View file

@ -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))
}

View file

@ -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,
}

File diff suppressed because it is too large Load diff

View file

@ -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))
}
}

View file

@ -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!()
}
}