mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
feat(oxc_wasm): add verbse option to debug_dot (#5879)
1. Adding a new option to control displaying `implicit error` edge. **verbose**  **disable verbose** 
This commit is contained in:
parent
f360e2c6f8
commit
a111bb69af
3 changed files with 42 additions and 12 deletions
|
|
@ -7,8 +7,8 @@ use oxc_cfg::{
|
|||
dot::{Config, Dot},
|
||||
visit::EdgeRef,
|
||||
},
|
||||
BasicBlock, ControlFlowGraph, EdgeType, Instruction, InstructionKind, IterationInstructionKind,
|
||||
LabeledInstruction, ReturnInstructionKind,
|
||||
BasicBlock, ControlFlowGraph, EdgeType, ErrorEdgeKind, Instruction, InstructionKind,
|
||||
IterationInstructionKind, LabeledInstruction, ReturnInstructionKind,
|
||||
};
|
||||
use oxc_syntax::node::NodeId;
|
||||
|
||||
|
|
@ -23,15 +23,24 @@ pub trait DebugDot {
|
|||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct DebugDotContext<'a, 'b>(&'b AstNodes<'a>);
|
||||
pub struct DebugDotContext<'a, 'b> {
|
||||
nodes: &'b AstNodes<'a>,
|
||||
verbose: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'b> DebugDotContext<'a, 'b> {
|
||||
pub fn new(nodes: &'b AstNodes<'a>, verbose: bool) -> DebugDotContext<'a, 'b> {
|
||||
DebugDotContext { nodes, verbose }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> DebugDotContext<'a, 'b> {
|
||||
fn debug_ast_kind(self, id: NodeId) -> String {
|
||||
self.0.kind(id).debug_name().into_owned()
|
||||
self.nodes.kind(id).debug_name().into_owned()
|
||||
}
|
||||
|
||||
fn try_eval_literal(self, id: NodeId) -> Option<String> {
|
||||
match self.0.kind(id) {
|
||||
match self.nodes.kind(id) {
|
||||
AstKind::NumericLiteral(lit) => Some(lit.value.to_string()),
|
||||
AstKind::BooleanLiteral(lit) => Some(lit.value.to_string()),
|
||||
AstKind::StringLiteral(lit) => Some(lit.value.to_string()),
|
||||
|
|
@ -44,7 +53,7 @@ impl<'a, 'b> DebugDotContext<'a, 'b> {
|
|||
|
||||
impl<'a, 'b> From<&'b AstNodes<'a>> for DebugDotContext<'a, 'b> {
|
||||
fn from(value: &'b AstNodes<'a>) -> Self {
|
||||
Self(value)
|
||||
Self::new(value, true)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -57,6 +66,9 @@ impl DebugDot for ControlFlowGraph {
|
|||
&[Config::EdgeNoLabel, Config::NodeNoLabel],
|
||||
&|_graph, edge| {
|
||||
let weight = edge.weight();
|
||||
if !ctx.verbose && matches!(weight, EdgeType::Error(ErrorEdgeKind::Implicit)) {
|
||||
return String::new();
|
||||
}
|
||||
let label = format!("label = \"{weight:?}\" ");
|
||||
if matches!(weight, EdgeType::Unreachable)
|
||||
|| self.basic_block(edge.source()).unreachable
|
||||
|
|
@ -118,11 +130,11 @@ impl DebugDot for Instruction {
|
|||
}
|
||||
InstructionKind::Break(LabeledInstruction::Labeled) => {
|
||||
let Some(AstKind::BreakStatement(BreakStatement { label: Some(label), .. })) =
|
||||
self.node_id.map(|id| ctx.0.get_node(id)).map(AstNode::kind)
|
||||
self.node_id.map(|id| ctx.nodes.get_node(id)).map(AstNode::kind)
|
||||
else {
|
||||
unreachable!(
|
||||
"Expected a label node to be associated with an labeled break instruction. {:?}",
|
||||
ctx.0.kind(self.node_id.unwrap())
|
||||
ctx.nodes.kind(self.node_id.unwrap())
|
||||
)
|
||||
};
|
||||
format!("break <{}>", label.name)
|
||||
|
|
@ -131,11 +143,11 @@ impl DebugDot for Instruction {
|
|||
InstructionKind::Continue(LabeledInstruction::Labeled) => {
|
||||
let Some(AstKind::ContinueStatement(ContinueStatement {
|
||||
label: Some(label), ..
|
||||
})) = self.node_id.map(|id| ctx.0.get_node(id)).map(AstNode::kind)
|
||||
})) = self.node_id.map(|id| ctx.nodes.get_node(id)).map(AstNode::kind)
|
||||
else {
|
||||
unreachable!(
|
||||
"Expected a label node to be associated with an labeled continue instruction. {:?}",
|
||||
ctx.0.kind(self.node_id.unwrap())
|
||||
ctx.nodes.kind(self.node_id.unwrap())
|
||||
)
|
||||
};
|
||||
format!("continue <{}>", label.name)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,10 @@ use oxc::{
|
|||
diagnostics::Error,
|
||||
minifier::{CompressOptions, Minifier, MinifierOptions},
|
||||
parser::{ParseOptions, Parser, ParserReturn},
|
||||
semantic::{dot::DebugDot, ScopeFlags, ScopeId, ScopeTree, SemanticBuilder, SymbolTable},
|
||||
semantic::{
|
||||
dot::{DebugDot, DebugDotContext},
|
||||
ScopeFlags, ScopeId, ScopeTree, SemanticBuilder, SymbolTable,
|
||||
},
|
||||
span::SourceType,
|
||||
transformer::{EnvOptions, Targets, TransformOptions, Transformer},
|
||||
};
|
||||
|
|
@ -153,6 +156,7 @@ impl Oxc {
|
|||
transformer: transform_options,
|
||||
codegen: codegen_options,
|
||||
minifier: minifier_options,
|
||||
control_flow: control_flow_options,
|
||||
} = options;
|
||||
let run_options = run_options.unwrap_or_default();
|
||||
let parser_options = parser_options.unwrap_or_default();
|
||||
|
|
@ -160,6 +164,7 @@ impl Oxc {
|
|||
let minifier_options = minifier_options.unwrap_or_default();
|
||||
let _codegen_options = codegen_options.unwrap_or_default();
|
||||
let _transform_options = transform_options.unwrap_or_default();
|
||||
let control_flow_options = control_flow_options.unwrap_or_default();
|
||||
|
||||
let allocator = Allocator::default();
|
||||
|
||||
|
|
@ -205,7 +210,10 @@ impl Oxc {
|
|||
.build(&program);
|
||||
|
||||
self.control_flow_graph = semantic_ret.semantic.cfg().map_or_else(String::default, |cfg| {
|
||||
cfg.debug_dot(semantic_ret.semantic.nodes().into())
|
||||
cfg.debug_dot(DebugDotContext::new(
|
||||
semantic_ret.semantic.nodes(),
|
||||
control_flow_options.verbose.unwrap_or_default(),
|
||||
))
|
||||
});
|
||||
if run_options.syntax.unwrap_or_default() {
|
||||
self.save_diagnostics(
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ pub struct OxcOptions {
|
|||
pub codegen: Option<OxcCodegenOptions>,
|
||||
#[tsify(optional)]
|
||||
pub minifier: Option<OxcMinifierOptions>,
|
||||
#[tsify(optional)]
|
||||
pub control_flow: Option<OxcControlFlowOptions>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Deserialize, Tsify)]
|
||||
|
|
@ -82,6 +84,14 @@ pub struct OxcCodegenOptions {
|
|||
pub enable_typescript: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Deserialize, Tsify)]
|
||||
#[tsify(from_wasm_abi)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct OxcControlFlowOptions {
|
||||
#[tsify(optional)]
|
||||
pub verbose: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Deserialize, Tsify)]
|
||||
#[tsify(from_wasm_abi)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
|
|
|||
Loading…
Reference in a new issue