mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
fix(semantic)!: ensure program outlives semantic (#8455)
fixes: #8437 In semantic builder make sure `Program` reference has a lifetime of the Arena. --------- Co-authored-by: overlookmotel <theoverlookmotel@gmail.com>
This commit is contained in:
parent
250bbd193b
commit
4ce63298e8
9 changed files with 18 additions and 20 deletions
|
|
@ -101,11 +101,7 @@ pub trait CompilerInterface {
|
|||
ControlFlow::Continue(())
|
||||
}
|
||||
|
||||
fn after_semantic(
|
||||
&mut self,
|
||||
_program: &mut Program<'_>,
|
||||
_semantic_return: &mut SemanticBuilderReturn,
|
||||
) -> ControlFlow<()> {
|
||||
fn after_semantic(&mut self, _semantic_return: &mut SemanticBuilderReturn) -> ControlFlow<()> {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
|
||||
|
|
@ -148,7 +144,7 @@ pub trait CompilerInterface {
|
|||
self.handle_errors(semantic_return.errors);
|
||||
return;
|
||||
}
|
||||
if self.after_semantic(&mut program, &mut semantic_return).is_break() {
|
||||
if self.after_semantic(&mut semantic_return).is_break() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -235,7 +231,7 @@ pub trait CompilerInterface {
|
|||
Parser::new(allocator, source_text, source_type).with_options(self.parse_options()).parse()
|
||||
}
|
||||
|
||||
fn semantic<'a>(&self, program: &Program<'a>) -> SemanticBuilderReturn<'a> {
|
||||
fn semantic<'a>(&self, program: &'a Program<'a>) -> SemanticBuilderReturn<'a> {
|
||||
let mut builder = SemanticBuilder::new();
|
||||
|
||||
if self.transform_options().is_some() {
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ impl Runtime {
|
|||
.with_scope_tree_child_ids(true)
|
||||
.with_build_jsdoc(true)
|
||||
.with_check_syntax_error(check_syntax_errors)
|
||||
.build(&ret.program);
|
||||
.build(allocator.alloc(ret.program));
|
||||
|
||||
if !semantic_ret.errors.is_empty() {
|
||||
return semantic_ret.errors.into_iter().map(|err| Message::new(err, None)).collect();
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ impl<'a> SemanticBuilder<'a> {
|
|||
/// Finalize the builder.
|
||||
///
|
||||
/// # Panics
|
||||
pub fn build(mut self, program: &Program<'a>) -> SemanticBuilderReturn<'a> {
|
||||
pub fn build(mut self, program: &'a Program<'a>) -> SemanticBuilderReturn<'a> {
|
||||
self.source_text = program.source_text;
|
||||
self.source_type = program.source_type;
|
||||
if self.build_jsdoc {
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ mod test {
|
|||
) -> Semantic<'a> {
|
||||
let source_type = source_type.unwrap_or_default();
|
||||
let ret = Parser::new(allocator, source_text, source_type).parse();
|
||||
SemanticBuilder::new().with_build_jsdoc(true).build(&ret.program).semantic
|
||||
SemanticBuilder::new().with_build_jsdoc(true).build(allocator.alloc(ret.program)).semantic
|
||||
}
|
||||
|
||||
fn get_jsdocs<'a>(
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ mod test {
|
|||
fn build_semantic<'a>(allocator: &'a Allocator, source_text: &'a str) -> Semantic<'a> {
|
||||
let source_type = SourceType::default();
|
||||
let ret = Parser::new(allocator, source_text, source_type).parse();
|
||||
SemanticBuilder::new().with_build_jsdoc(true).build(&ret.program).semantic
|
||||
SemanticBuilder::new().with_build_jsdoc(true).build(allocator.alloc(ret.program)).semantic
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ mod test {
|
|||
fn build_semantic<'a>(allocator: &'a Allocator, source_text: &'a str) -> Semantic<'a> {
|
||||
let source_type = SourceType::default();
|
||||
let ret = Parser::new(allocator, source_text, source_type).parse();
|
||||
SemanticBuilder::new().with_build_jsdoc(true).build(&ret.program).semantic
|
||||
SemanticBuilder::new().with_build_jsdoc(true).build(allocator.alloc(ret.program)).semantic
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ mod tests {
|
|||
) -> Semantic<'s> {
|
||||
let parse = oxc_parser::Parser::new(allocator, source, source_type).parse();
|
||||
assert!(parse.errors.is_empty());
|
||||
let semantic = SemanticBuilder::new().build(&parse.program);
|
||||
let semantic = SemanticBuilder::new().build(allocator.alloc(parse.program));
|
||||
assert!(semantic.errors.is_empty(), "Parse error: {}", semantic.errors[0]);
|
||||
semantic.semantic
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ impl<'a> SemanticTester<'a> {
|
|||
.with_check_syntax_error(true)
|
||||
.with_cfg(self.cfg)
|
||||
.with_scope_tree_child_ids(self.scope_tree_child_ids)
|
||||
.build(&parse.program)
|
||||
.build(self.allocator.alloc(parse.program))
|
||||
}
|
||||
|
||||
pub fn basic_blocks_count(&self) -> usize {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use rustc_hash::FxHashSet;
|
|||
|
||||
use oxc::{
|
||||
allocator::Allocator,
|
||||
ast::{ast::Program, Comment},
|
||||
ast::{ast::Program, AstKind, Comment},
|
||||
codegen::{CodegenOptions, CodegenReturn},
|
||||
diagnostics::OxcDiagnostic,
|
||||
minifier::CompressOptions,
|
||||
|
|
@ -80,12 +80,14 @@ impl CompilerInterface for Driver {
|
|||
ControlFlow::Continue(())
|
||||
}
|
||||
|
||||
fn after_semantic(
|
||||
&mut self,
|
||||
program: &mut Program<'_>,
|
||||
ret: &mut SemanticBuilderReturn,
|
||||
) -> ControlFlow<()> {
|
||||
fn after_semantic(&mut self, ret: &mut SemanticBuilderReturn) -> ControlFlow<()> {
|
||||
if self.check_semantic {
|
||||
let Some(root_node) = ret.semantic.nodes().root_node() else {
|
||||
return ControlFlow::Break(());
|
||||
};
|
||||
let AstKind::Program(program) = root_node.kind() else {
|
||||
return ControlFlow::Break(());
|
||||
};
|
||||
if let Some(errors) = check_semantic_ids(program) {
|
||||
self.errors.extend(errors);
|
||||
return ControlFlow::Break(());
|
||||
|
|
|
|||
Loading…
Reference in a new issue