pub mod await_expression_node;
pub mod connect_to_block;
pub mod connect_to_declarations;
pub mod connect_to_next;
pub mod end_node;
pub mod if_node;
pub mod method_invocation_node;
pub mod multi_path;
pub mod multifile;
pub mod object_node;
pub mod pair_node;
pub mod step_by_step;
pub mod switch_body;
pub mod switch_section;
pub mod variable_declaration_node;
use crate::syntax::cfg::CfgBuilder;
#[must_use]
#[allow(
clippy::too_many_lines,
reason = "exhaustive 1:1 dispatch table: one arm per node label, nothing to extract"
)]
pub fn dispatcher(node_type: &str) -> Option<CfgBuilder> {
match node_type {
"Class" | "Declaration" | "DoStatement" | "ElseClause" | "ForEachStatement"
| "ForStatement" | "MethodDeclaration" | "Namespace" | "SwitchStatement"
| "UsingStatement" | "WhileStatement" => Some(connect_to_block::build),
"ArgumentList" | "BinaryOperation" | "ClassBody" | "DeclarationBlock" | "File"
| "TryStatement" => Some(multi_path::build),
"ExecutionBlock" | "ExpressionStatement" | "ParameterList" => Some(step_by_step::build),
"If" | "TernaryOperation" => Some(if_node::build),
"SwitchBody" => Some(switch_body::build),
"SwitchSection" => Some(switch_section::build),
"MethodInvocation" => Some(method_invocation_node::build),
"VariableDeclaration" => Some(variable_declaration_node::build),
"AwaitExpression" => Some(await_expression_node::build),
"Export" | "Return" => Some(connect_to_declarations::build),
"ModuleImport" => Some(end_node::build),
"Object" => Some(object_node::build),
"Pair" => Some(pair_node::build),
"Annotation"
| "Argument"
| "ArrayInitializer"
| "Assignment"
| "Attribute"
| "Break"
| "CatchClause"
| "CatchDeclaration"
| "Comment"
| "Continue"
| "ElementAccess"
| "FinallyClause"
| "Import"
| "JsxElement"
| "Literal"
| "MemberAccess"
| "MissingNode"
| "Modifiers"
| "NamedArgument"
| "NewExpression"
| "ObjectCreation"
| "Parameter"
| "ParenthesizedExpression"
| "ReservedWord"
| "RestPattern"
| "Selector"
| "SpreadElement"
| "SymbolLookup"
| "This"
| "ThrowStatement"
| "UnaryExpression" => Some(connect_to_next::build),
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::dispatcher;
#[test]
fn maps_one_representative_label_per_cfg_builder() {
let representatives = [
"Class",
"File",
"ExecutionBlock",
"If",
"SwitchBody",
"SwitchSection",
"MethodInvocation",
"VariableDeclaration",
"AwaitExpression",
"Return",
"ModuleImport",
"Object",
"Pair",
"Assignment",
];
for label in representatives {
assert!(dispatcher(label).is_some(), "unmapped label: {label}");
}
}
#[test]
fn unmapped_node_types_have_no_builder() {
assert!(dispatcher("Metadata").is_none());
assert!(dispatcher("LambdaFunctionType").is_none());
assert!(dispatcher("").is_none());
}
}