use crate::errors::{AnyError, ErrorNode};
use crate::{Location, Token};
use crate::union_types::*;
use colored::*;
pub(crate) fn prettify_prism_tree(input: &str) -> String {
let input = input.replace("+-- ", "├── ").replace("| ", "│ ");
let lines: Vec<&str> = input.lines().collect();
let mut result: Vec<String> = lines.iter().map(|l| l.to_string()).collect();
for i in 0..result.len() {
if let Some(position) = result[i].find("├── ") {
let indent = &result[i][..position];
let is_last = !lines[i + 1..].iter().any(|next| {
next.starts_with(&format!("{}├── ", indent)) || next.starts_with(&format!("{}│ ", indent))
});
if is_last {
result[i] = format!("{}└── {}", indent, &result[i][position + "├── ".len()..]);
}
}
}
result.join("\n")
}
fn escape_string(s: &str) -> String {
s.replace('\\', "\\\\")
.replace('\n', "\\n")
.replace('\r', "\\r")
.replace('\t', "\\t")
.replace('"', "\\\"")
}
fn format_string_value(value: &str) -> String {
format!("\"{}\"", escape_string(value)).green().to_string()
}
fn format_token_value(token: &Option<Token>) -> String {
token.as_ref().map(|t| t.tree_inspect()).unwrap_or_else(|| "∅".magenta().to_string())
}
fn format_bool_value(value: bool) -> String {
value.to_string().magenta().bold().to_string()
}
fn format_node_value<T: Node + ?Sized>(node: &Option<Box<T>>, prefix: &str, add_spacing: bool) -> String {
if let Some(ref n) = node {
let mut output = String::new();
output.push('\n');
output.push_str(&inspect_node_field(n.as_ref(), prefix));
if add_spacing {
output.push_str(&format!("{}\n", prefix));
}
output
} else {
format!("{}\n", "∅".magenta())
}
}
fn format_union_node_value<T>(node: &Option<T>, prefix: &str, add_spacing: bool, tree_inspect_fn: impl Fn(&T) -> String) -> String {
if let Some(ref n) = node {
let mut output = String::new();
output.push('\n');
let tree = tree_inspect_fn(n);
let lines: Vec<&str> = tree.lines().collect();
if !lines.is_empty() {
output.push_str(prefix);
output.push_str(&"└── ".white().to_string());
output.push_str(lines[0]);
output.push('\n');
for line in lines.iter().skip(1) {
if line.is_empty() {
output.push_str(prefix);
output.push('\n');
} else {
output.push_str(prefix);
output.push_str(" ");
output.push_str(line);
output.push('\n');
}
}
}
if add_spacing {
output.push_str(&format!("{}\n", prefix));
}
output
} else {
format!("{}\n", "∅".magenta())
}
}
fn format_array_value(array: &[AnyNode], prefix: &str) -> String {
inspect_array(array, prefix)
}
fn format_errors_field(errors: &[AnyError], prefix: &str) -> String {
inspect_errors(errors, prefix)
}
fn inspect_errors(errors: &[AnyError], prefix: &str) -> String {
if errors.is_empty() {
return String::new();
}
let mut output = String::new();
output.push_str(&format!("{} {}: {}\n",
"├──".white(),
"errors".red().bold(),
format!("({} error{})", errors.len(), if errors.len() == 1 { "" } else { "s" }).dimmed()
));
for (i, error) in errors.iter().enumerate() {
let is_last = i == errors.len() - 1;
let symbol = if is_last { "└── " } else { "├── " };
let next_prefix_str = if is_last { " " } else { "│ " };
let next_prefix = next_prefix_str.white().to_string();
let tree = error.tree_inspect();
let tree = tree.trim_end_matches('\n');
output.push_str(&format!("{}{}{}\n", prefix, symbol.white(), tree.replace('\n', &format!("\n{}{}", prefix, next_prefix))));
if !is_last {
output.push_str(&format!("{}{}\n", prefix, "│ ".white()));
}
}
output.push_str(&format!("{}\n", prefix));
output
}
fn inspect_array(array: &[AnyNode], prefix: &str) -> String {
if array.is_empty() {
return format!("{}\n", "[]".dimmed());
}
let mut output = String::new();
output.push_str(&format!("{}\n", format!("({} item{})", array.len(), if array.len() == 1 { "" } else { "s" }).dimmed()));
for (i, item) in array.iter().enumerate() {
let is_last = i == array.len() - 1;
let symbol = if is_last { "└── " } else { "├── " };
let next_prefix_str = if is_last { " " } else { "│ " };
let next_prefix = next_prefix_str.white().to_string();
let tree = item.tree_inspect();
let tree = tree.trim_end_matches('\n');
output.push_str(prefix);
output.push_str(&symbol.white().to_string());
output.push_str(&tree.replace('\n', &format!("\n{}{}", prefix, next_prefix)));
output.push('\n');
if !is_last {
output.push_str(prefix);
output.push_str(&next_prefix);
output.push('\n');
}
}
output
}
fn inspect_node_field<T: Node + ?Sized>(node: &T, prefix: &str) -> String {
let tree = node.tree_inspect();
let tree = tree.trim_end_matches('\n');
let lines: Vec<&str> = tree.split('\n').collect();
if lines.is_empty() {
return format!("{}\n", "∅".magenta());
}
let mut result = String::new();
result.push_str(prefix);
result.push_str(&"└── ".white().to_string());
result.push_str(lines[0]);
result.push('\n');
for line in lines.iter().skip(1) {
if line.is_empty() {
result.push_str(prefix);
result.push('\n');
} else {
result.push_str(prefix);
result.push_str(" ");
result.push_str(line);
result.push('\n');
}
}
result
}
pub trait Node {
fn node_type(&self) -> &str;
fn location(&self) -> &Location;
fn errors(&self) -> &[AnyError];
fn child_nodes(&self) -> Vec<&dyn Node>;
fn recursive_errors(&self) -> Vec<&dyn ErrorNode>;
fn tree_inspect(&self) -> String;
}
pub trait ERBNode {
fn tag_opening(&self) -> &Option<Token>;
fn content(&self) -> &Option<Token>;
fn tag_closing(&self) -> &Option<Token>;
fn location(&self) -> &Location;
}
#[derive(Debug, Clone)]
pub enum AnyNode {
DocumentNode(Box<DocumentNode>),
LiteralNode(Box<LiteralNode>),
HTMLOpenTagNode(Box<HTMLOpenTagNode>),
HTMLConditionalOpenTagNode(Box<HTMLConditionalOpenTagNode>),
HTMLCloseTagNode(Box<HTMLCloseTagNode>),
HTMLOmittedCloseTagNode(Box<HTMLOmittedCloseTagNode>),
HTMLVirtualCloseTagNode(Box<HTMLVirtualCloseTagNode>),
HTMLElementNode(Box<HTMLElementNode>),
HTMLConditionalElementNode(Box<HTMLConditionalElementNode>),
HTMLAttributeValueNode(Box<HTMLAttributeValueNode>),
HTMLAttributeNameNode(Box<HTMLAttributeNameNode>),
HTMLAttributeNode(Box<HTMLAttributeNode>),
RubyLiteralNode(Box<RubyLiteralNode>),
RubyHTMLAttributesSplatNode(Box<RubyHTMLAttributesSplatNode>),
ERBOpenTagNode(Box<ERBOpenTagNode>),
HTMLTextNode(Box<HTMLTextNode>),
HTMLCommentNode(Box<HTMLCommentNode>),
HTMLDoctypeNode(Box<HTMLDoctypeNode>),
XMLDeclarationNode(Box<XMLDeclarationNode>),
CDATANode(Box<CDATANode>),
WhitespaceNode(Box<WhitespaceNode>),
ERBContentNode(Box<ERBContentNode>),
ERBEndNode(Box<ERBEndNode>),
ERBElseNode(Box<ERBElseNode>),
ERBIfNode(Box<ERBIfNode>),
ERBBlockNode(Box<ERBBlockNode>),
ERBWhenNode(Box<ERBWhenNode>),
ERBCaseNode(Box<ERBCaseNode>),
ERBCaseMatchNode(Box<ERBCaseMatchNode>),
ERBWhileNode(Box<ERBWhileNode>),
ERBUntilNode(Box<ERBUntilNode>),
ERBForNode(Box<ERBForNode>),
ERBRescueNode(Box<ERBRescueNode>),
ERBEnsureNode(Box<ERBEnsureNode>),
ERBBeginNode(Box<ERBBeginNode>),
ERBUnlessNode(Box<ERBUnlessNode>),
RubyRenderLocalNode(Box<RubyRenderLocalNode>),
RubyRenderKeywordsNode(Box<RubyRenderKeywordsNode>),
ERBRenderNode(Box<ERBRenderNode>),
RubyParameterNode(Box<RubyParameterNode>),
ERBStrictLocalsNode(Box<ERBStrictLocalsNode>),
ERBYieldNode(Box<ERBYieldNode>),
ERBInNode(Box<ERBInNode>),
}
impl AnyNode {
pub fn node_type(&self) -> &str {
match self {
AnyNode::DocumentNode(n) => &n.node_type,
AnyNode::LiteralNode(n) => &n.node_type,
AnyNode::HTMLOpenTagNode(n) => &n.node_type,
AnyNode::HTMLConditionalOpenTagNode(n) => &n.node_type,
AnyNode::HTMLCloseTagNode(n) => &n.node_type,
AnyNode::HTMLOmittedCloseTagNode(n) => &n.node_type,
AnyNode::HTMLVirtualCloseTagNode(n) => &n.node_type,
AnyNode::HTMLElementNode(n) => &n.node_type,
AnyNode::HTMLConditionalElementNode(n) => &n.node_type,
AnyNode::HTMLAttributeValueNode(n) => &n.node_type,
AnyNode::HTMLAttributeNameNode(n) => &n.node_type,
AnyNode::HTMLAttributeNode(n) => &n.node_type,
AnyNode::RubyLiteralNode(n) => &n.node_type,
AnyNode::RubyHTMLAttributesSplatNode(n) => &n.node_type,
AnyNode::ERBOpenTagNode(n) => &n.node_type,
AnyNode::HTMLTextNode(n) => &n.node_type,
AnyNode::HTMLCommentNode(n) => &n.node_type,
AnyNode::HTMLDoctypeNode(n) => &n.node_type,
AnyNode::XMLDeclarationNode(n) => &n.node_type,
AnyNode::CDATANode(n) => &n.node_type,
AnyNode::WhitespaceNode(n) => &n.node_type,
AnyNode::ERBContentNode(n) => &n.node_type,
AnyNode::ERBEndNode(n) => &n.node_type,
AnyNode::ERBElseNode(n) => &n.node_type,
AnyNode::ERBIfNode(n) => &n.node_type,
AnyNode::ERBBlockNode(n) => &n.node_type,
AnyNode::ERBWhenNode(n) => &n.node_type,
AnyNode::ERBCaseNode(n) => &n.node_type,
AnyNode::ERBCaseMatchNode(n) => &n.node_type,
AnyNode::ERBWhileNode(n) => &n.node_type,
AnyNode::ERBUntilNode(n) => &n.node_type,
AnyNode::ERBForNode(n) => &n.node_type,
AnyNode::ERBRescueNode(n) => &n.node_type,
AnyNode::ERBEnsureNode(n) => &n.node_type,
AnyNode::ERBBeginNode(n) => &n.node_type,
AnyNode::ERBUnlessNode(n) => &n.node_type,
AnyNode::RubyRenderLocalNode(n) => &n.node_type,
AnyNode::RubyRenderKeywordsNode(n) => &n.node_type,
AnyNode::ERBRenderNode(n) => &n.node_type,
AnyNode::RubyParameterNode(n) => &n.node_type,
AnyNode::ERBStrictLocalsNode(n) => &n.node_type,
AnyNode::ERBYieldNode(n) => &n.node_type,
AnyNode::ERBInNode(n) => &n.node_type,
}
}
pub fn location(&self) -> &Location {
match self {
AnyNode::DocumentNode(n) => &n.location,
AnyNode::LiteralNode(n) => &n.location,
AnyNode::HTMLOpenTagNode(n) => &n.location,
AnyNode::HTMLConditionalOpenTagNode(n) => &n.location,
AnyNode::HTMLCloseTagNode(n) => &n.location,
AnyNode::HTMLOmittedCloseTagNode(n) => &n.location,
AnyNode::HTMLVirtualCloseTagNode(n) => &n.location,
AnyNode::HTMLElementNode(n) => &n.location,
AnyNode::HTMLConditionalElementNode(n) => &n.location,
AnyNode::HTMLAttributeValueNode(n) => &n.location,
AnyNode::HTMLAttributeNameNode(n) => &n.location,
AnyNode::HTMLAttributeNode(n) => &n.location,
AnyNode::RubyLiteralNode(n) => &n.location,
AnyNode::RubyHTMLAttributesSplatNode(n) => &n.location,
AnyNode::ERBOpenTagNode(n) => &n.location,
AnyNode::HTMLTextNode(n) => &n.location,
AnyNode::HTMLCommentNode(n) => &n.location,
AnyNode::HTMLDoctypeNode(n) => &n.location,
AnyNode::XMLDeclarationNode(n) => &n.location,
AnyNode::CDATANode(n) => &n.location,
AnyNode::WhitespaceNode(n) => &n.location,
AnyNode::ERBContentNode(n) => &n.location,
AnyNode::ERBEndNode(n) => &n.location,
AnyNode::ERBElseNode(n) => &n.location,
AnyNode::ERBIfNode(n) => &n.location,
AnyNode::ERBBlockNode(n) => &n.location,
AnyNode::ERBWhenNode(n) => &n.location,
AnyNode::ERBCaseNode(n) => &n.location,
AnyNode::ERBCaseMatchNode(n) => &n.location,
AnyNode::ERBWhileNode(n) => &n.location,
AnyNode::ERBUntilNode(n) => &n.location,
AnyNode::ERBForNode(n) => &n.location,
AnyNode::ERBRescueNode(n) => &n.location,
AnyNode::ERBEnsureNode(n) => &n.location,
AnyNode::ERBBeginNode(n) => &n.location,
AnyNode::ERBUnlessNode(n) => &n.location,
AnyNode::RubyRenderLocalNode(n) => &n.location,
AnyNode::RubyRenderKeywordsNode(n) => &n.location,
AnyNode::ERBRenderNode(n) => &n.location,
AnyNode::RubyParameterNode(n) => &n.location,
AnyNode::ERBStrictLocalsNode(n) => &n.location,
AnyNode::ERBYieldNode(n) => &n.location,
AnyNode::ERBInNode(n) => &n.location,
}
}
pub fn errors(&self) -> &[AnyError] {
match self {
AnyNode::DocumentNode(n) => &n.errors,
AnyNode::LiteralNode(n) => &n.errors,
AnyNode::HTMLOpenTagNode(n) => &n.errors,
AnyNode::HTMLConditionalOpenTagNode(n) => &n.errors,
AnyNode::HTMLCloseTagNode(n) => &n.errors,
AnyNode::HTMLOmittedCloseTagNode(n) => &n.errors,
AnyNode::HTMLVirtualCloseTagNode(n) => &n.errors,
AnyNode::HTMLElementNode(n) => &n.errors,
AnyNode::HTMLConditionalElementNode(n) => &n.errors,
AnyNode::HTMLAttributeValueNode(n) => &n.errors,
AnyNode::HTMLAttributeNameNode(n) => &n.errors,
AnyNode::HTMLAttributeNode(n) => &n.errors,
AnyNode::RubyLiteralNode(n) => &n.errors,
AnyNode::RubyHTMLAttributesSplatNode(n) => &n.errors,
AnyNode::ERBOpenTagNode(n) => &n.errors,
AnyNode::HTMLTextNode(n) => &n.errors,
AnyNode::HTMLCommentNode(n) => &n.errors,
AnyNode::HTMLDoctypeNode(n) => &n.errors,
AnyNode::XMLDeclarationNode(n) => &n.errors,
AnyNode::CDATANode(n) => &n.errors,
AnyNode::WhitespaceNode(n) => &n.errors,
AnyNode::ERBContentNode(n) => &n.errors,
AnyNode::ERBEndNode(n) => &n.errors,
AnyNode::ERBElseNode(n) => &n.errors,
AnyNode::ERBIfNode(n) => &n.errors,
AnyNode::ERBBlockNode(n) => &n.errors,
AnyNode::ERBWhenNode(n) => &n.errors,
AnyNode::ERBCaseNode(n) => &n.errors,
AnyNode::ERBCaseMatchNode(n) => &n.errors,
AnyNode::ERBWhileNode(n) => &n.errors,
AnyNode::ERBUntilNode(n) => &n.errors,
AnyNode::ERBForNode(n) => &n.errors,
AnyNode::ERBRescueNode(n) => &n.errors,
AnyNode::ERBEnsureNode(n) => &n.errors,
AnyNode::ERBBeginNode(n) => &n.errors,
AnyNode::ERBUnlessNode(n) => &n.errors,
AnyNode::RubyRenderLocalNode(n) => &n.errors,
AnyNode::RubyRenderKeywordsNode(n) => &n.errors,
AnyNode::ERBRenderNode(n) => &n.errors,
AnyNode::RubyParameterNode(n) => &n.errors,
AnyNode::ERBStrictLocalsNode(n) => &n.errors,
AnyNode::ERBYieldNode(n) => &n.errors,
AnyNode::ERBInNode(n) => &n.errors,
}
}
pub fn tree_inspect(&self) -> String {
match self {
AnyNode::DocumentNode(n) => n.tree_inspect(),
AnyNode::LiteralNode(n) => n.tree_inspect(),
AnyNode::HTMLOpenTagNode(n) => n.tree_inspect(),
AnyNode::HTMLConditionalOpenTagNode(n) => n.tree_inspect(),
AnyNode::HTMLCloseTagNode(n) => n.tree_inspect(),
AnyNode::HTMLOmittedCloseTagNode(n) => n.tree_inspect(),
AnyNode::HTMLVirtualCloseTagNode(n) => n.tree_inspect(),
AnyNode::HTMLElementNode(n) => n.tree_inspect(),
AnyNode::HTMLConditionalElementNode(n) => n.tree_inspect(),
AnyNode::HTMLAttributeValueNode(n) => n.tree_inspect(),
AnyNode::HTMLAttributeNameNode(n) => n.tree_inspect(),
AnyNode::HTMLAttributeNode(n) => n.tree_inspect(),
AnyNode::RubyLiteralNode(n) => n.tree_inspect(),
AnyNode::RubyHTMLAttributesSplatNode(n) => n.tree_inspect(),
AnyNode::ERBOpenTagNode(n) => n.tree_inspect(),
AnyNode::HTMLTextNode(n) => n.tree_inspect(),
AnyNode::HTMLCommentNode(n) => n.tree_inspect(),
AnyNode::HTMLDoctypeNode(n) => n.tree_inspect(),
AnyNode::XMLDeclarationNode(n) => n.tree_inspect(),
AnyNode::CDATANode(n) => n.tree_inspect(),
AnyNode::WhitespaceNode(n) => n.tree_inspect(),
AnyNode::ERBContentNode(n) => n.tree_inspect(),
AnyNode::ERBEndNode(n) => n.tree_inspect(),
AnyNode::ERBElseNode(n) => n.tree_inspect(),
AnyNode::ERBIfNode(n) => n.tree_inspect(),
AnyNode::ERBBlockNode(n) => n.tree_inspect(),
AnyNode::ERBWhenNode(n) => n.tree_inspect(),
AnyNode::ERBCaseNode(n) => n.tree_inspect(),
AnyNode::ERBCaseMatchNode(n) => n.tree_inspect(),
AnyNode::ERBWhileNode(n) => n.tree_inspect(),
AnyNode::ERBUntilNode(n) => n.tree_inspect(),
AnyNode::ERBForNode(n) => n.tree_inspect(),
AnyNode::ERBRescueNode(n) => n.tree_inspect(),
AnyNode::ERBEnsureNode(n) => n.tree_inspect(),
AnyNode::ERBBeginNode(n) => n.tree_inspect(),
AnyNode::ERBUnlessNode(n) => n.tree_inspect(),
AnyNode::RubyRenderLocalNode(n) => n.tree_inspect(),
AnyNode::RubyRenderKeywordsNode(n) => n.tree_inspect(),
AnyNode::ERBRenderNode(n) => n.tree_inspect(),
AnyNode::RubyParameterNode(n) => n.tree_inspect(),
AnyNode::ERBStrictLocalsNode(n) => n.tree_inspect(),
AnyNode::ERBYieldNode(n) => n.tree_inspect(),
AnyNode::ERBInNode(n) => n.tree_inspect(),
}
}
pub fn child_nodes(&self) -> Vec<&dyn Node> {
match self {
AnyNode::DocumentNode(n) => n.child_nodes(),
AnyNode::LiteralNode(n) => n.child_nodes(),
AnyNode::HTMLOpenTagNode(n) => n.child_nodes(),
AnyNode::HTMLConditionalOpenTagNode(n) => n.child_nodes(),
AnyNode::HTMLCloseTagNode(n) => n.child_nodes(),
AnyNode::HTMLOmittedCloseTagNode(n) => n.child_nodes(),
AnyNode::HTMLVirtualCloseTagNode(n) => n.child_nodes(),
AnyNode::HTMLElementNode(n) => n.child_nodes(),
AnyNode::HTMLConditionalElementNode(n) => n.child_nodes(),
AnyNode::HTMLAttributeValueNode(n) => n.child_nodes(),
AnyNode::HTMLAttributeNameNode(n) => n.child_nodes(),
AnyNode::HTMLAttributeNode(n) => n.child_nodes(),
AnyNode::RubyLiteralNode(n) => n.child_nodes(),
AnyNode::RubyHTMLAttributesSplatNode(n) => n.child_nodes(),
AnyNode::ERBOpenTagNode(n) => n.child_nodes(),
AnyNode::HTMLTextNode(n) => n.child_nodes(),
AnyNode::HTMLCommentNode(n) => n.child_nodes(),
AnyNode::HTMLDoctypeNode(n) => n.child_nodes(),
AnyNode::XMLDeclarationNode(n) => n.child_nodes(),
AnyNode::CDATANode(n) => n.child_nodes(),
AnyNode::WhitespaceNode(n) => n.child_nodes(),
AnyNode::ERBContentNode(n) => n.child_nodes(),
AnyNode::ERBEndNode(n) => n.child_nodes(),
AnyNode::ERBElseNode(n) => n.child_nodes(),
AnyNode::ERBIfNode(n) => n.child_nodes(),
AnyNode::ERBBlockNode(n) => n.child_nodes(),
AnyNode::ERBWhenNode(n) => n.child_nodes(),
AnyNode::ERBCaseNode(n) => n.child_nodes(),
AnyNode::ERBCaseMatchNode(n) => n.child_nodes(),
AnyNode::ERBWhileNode(n) => n.child_nodes(),
AnyNode::ERBUntilNode(n) => n.child_nodes(),
AnyNode::ERBForNode(n) => n.child_nodes(),
AnyNode::ERBRescueNode(n) => n.child_nodes(),
AnyNode::ERBEnsureNode(n) => n.child_nodes(),
AnyNode::ERBBeginNode(n) => n.child_nodes(),
AnyNode::ERBUnlessNode(n) => n.child_nodes(),
AnyNode::RubyRenderLocalNode(n) => n.child_nodes(),
AnyNode::RubyRenderKeywordsNode(n) => n.child_nodes(),
AnyNode::ERBRenderNode(n) => n.child_nodes(),
AnyNode::RubyParameterNode(n) => n.child_nodes(),
AnyNode::ERBStrictLocalsNode(n) => n.child_nodes(),
AnyNode::ERBYieldNode(n) => n.child_nodes(),
AnyNode::ERBInNode(n) => n.child_nodes(),
}
}
pub fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
match self {
AnyNode::DocumentNode(n) => n.recursive_errors(),
AnyNode::LiteralNode(n) => n.recursive_errors(),
AnyNode::HTMLOpenTagNode(n) => n.recursive_errors(),
AnyNode::HTMLConditionalOpenTagNode(n) => n.recursive_errors(),
AnyNode::HTMLCloseTagNode(n) => n.recursive_errors(),
AnyNode::HTMLOmittedCloseTagNode(n) => n.recursive_errors(),
AnyNode::HTMLVirtualCloseTagNode(n) => n.recursive_errors(),
AnyNode::HTMLElementNode(n) => n.recursive_errors(),
AnyNode::HTMLConditionalElementNode(n) => n.recursive_errors(),
AnyNode::HTMLAttributeValueNode(n) => n.recursive_errors(),
AnyNode::HTMLAttributeNameNode(n) => n.recursive_errors(),
AnyNode::HTMLAttributeNode(n) => n.recursive_errors(),
AnyNode::RubyLiteralNode(n) => n.recursive_errors(),
AnyNode::RubyHTMLAttributesSplatNode(n) => n.recursive_errors(),
AnyNode::ERBOpenTagNode(n) => n.recursive_errors(),
AnyNode::HTMLTextNode(n) => n.recursive_errors(),
AnyNode::HTMLCommentNode(n) => n.recursive_errors(),
AnyNode::HTMLDoctypeNode(n) => n.recursive_errors(),
AnyNode::XMLDeclarationNode(n) => n.recursive_errors(),
AnyNode::CDATANode(n) => n.recursive_errors(),
AnyNode::WhitespaceNode(n) => n.recursive_errors(),
AnyNode::ERBContentNode(n) => n.recursive_errors(),
AnyNode::ERBEndNode(n) => n.recursive_errors(),
AnyNode::ERBElseNode(n) => n.recursive_errors(),
AnyNode::ERBIfNode(n) => n.recursive_errors(),
AnyNode::ERBBlockNode(n) => n.recursive_errors(),
AnyNode::ERBWhenNode(n) => n.recursive_errors(),
AnyNode::ERBCaseNode(n) => n.recursive_errors(),
AnyNode::ERBCaseMatchNode(n) => n.recursive_errors(),
AnyNode::ERBWhileNode(n) => n.recursive_errors(),
AnyNode::ERBUntilNode(n) => n.recursive_errors(),
AnyNode::ERBForNode(n) => n.recursive_errors(),
AnyNode::ERBRescueNode(n) => n.recursive_errors(),
AnyNode::ERBEnsureNode(n) => n.recursive_errors(),
AnyNode::ERBBeginNode(n) => n.recursive_errors(),
AnyNode::ERBUnlessNode(n) => n.recursive_errors(),
AnyNode::RubyRenderLocalNode(n) => n.recursive_errors(),
AnyNode::RubyRenderKeywordsNode(n) => n.recursive_errors(),
AnyNode::ERBRenderNode(n) => n.recursive_errors(),
AnyNode::RubyParameterNode(n) => n.recursive_errors(),
AnyNode::ERBStrictLocalsNode(n) => n.recursive_errors(),
AnyNode::ERBYieldNode(n) => n.recursive_errors(),
AnyNode::ERBInNode(n) => n.recursive_errors(),
}
}
}
impl Node for AnyNode {
fn node_type(&self) -> &str {
self.node_type()
}
fn location(&self) -> &Location {
self.location()
}
fn errors(&self) -> &[AnyError] {
self.errors()
}
fn child_nodes(&self) -> Vec<&dyn Node> {
self.child_nodes()
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
self.recursive_errors()
}
fn tree_inspect(&self) -> String {
self.tree_inspect()
}
}
#[derive(Debug, Clone)]
pub struct DocumentNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub children: Vec<AnyNode>,
pub prism_node: Option<String>,
}
impl Node for DocumentNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.children.iter().map(|n| n as &dyn Node));
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.children {
all_errors.extend(child.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"DocumentNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
{ let is_last = self.prism_node.is_none(); let symbol = if is_last { "└── " } else { "├── " };
let child_prefix = if is_last { " " } else { "│ " };
output.push_str(&format!("{}{}: {}", symbol.white(), "children".white(), format_array_value(&self.children, &child_prefix.white().to_string())));
}
if let Some(ref prism_string) = self.prism_node {
let prefix = " ";
output.push_str(&format!("{}{}: \n", "└── ".white(), "prism_node".white()));
output.push_str(&format!("{}└── ", prefix));
let prettified = prettify_prism_tree(prism_string);
let indented = prettified.lines().enumerate().map(|(i, line)| {
if i == 0 { line.to_string() } else { format!("{} {}", prefix, line) }
}).collect::<Vec<_>>().join("\n");
output.push_str(&indented);
output.push('\n');
}
output
}
}
#[derive(Debug, Clone)]
pub struct LiteralNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub content: String,
}
impl Node for LiteralNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
Vec::new()
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
self.errors.iter().map(|e| e as &dyn ErrorNode).collect()
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"LiteralNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "└── ".white(), "content".white(), format_string_value(&self.content)));
output
}
}
#[derive(Debug, Clone)]
pub struct HTMLOpenTagNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub tag_name: Option<Token>,
pub tag_closing: Option<Token>,
pub children: Vec<AnyNode>,
pub is_void: bool,
}
impl Node for HTMLOpenTagNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.children.iter().map(|n| n as &dyn Node));
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.children {
all_errors.extend(child.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"HTMLOpenTagNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_name".white(), format_token_value(&self.tag_name)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
output.push_str(&format!("{}{}: {}", "├── ".white(), "children".white(), format_array_value(&self.children, &"│ ".white().to_string())));
output.push_str(&format!("{}{}: {}\n", "└── ".white(), "is_void".white(), format_bool_value(self.is_void)));
output
}
}
#[derive(Debug, Clone)]
pub struct HTMLConditionalOpenTagNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub conditional: Option<ERBIfNodeOrERBUnlessNode>,
pub tag_name: Option<Token>,
pub is_void: bool,
}
impl Node for HTMLConditionalOpenTagNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
if let Some(ref node) = self.conditional {
children.push(node.as_node());
}
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
if let Some(ref node) = self.conditional {
all_errors.extend(node.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"HTMLConditionalOpenTagNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}", "├── ".white(), "conditional".white(), format_union_node_value(&self.conditional, &"│ ".white().to_string(), true, |n: &ERBIfNodeOrERBUnlessNode| n.tree_inspect())));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_name".white(), format_token_value(&self.tag_name)));
output.push_str(&format!("{}{}: {}\n", "└── ".white(), "is_void".white(), format_bool_value(self.is_void)));
output
}
}
#[derive(Debug, Clone)]
pub struct HTMLCloseTagNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub tag_name: Option<Token>,
pub children: Vec<AnyNode>,
pub tag_closing: Option<Token>,
}
impl Node for HTMLCloseTagNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.children.iter().map(|n| n as &dyn Node));
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.children {
all_errors.extend(child.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"HTMLCloseTagNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_name".white(), format_token_value(&self.tag_name)));
output.push_str(&format!("{}{}: {}", "├── ".white(), "children".white(), format_array_value(&self.children, &"│ ".white().to_string())));
output.push_str(&format!("{}{}: {}\n", "└── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
output
}
}
#[derive(Debug, Clone)]
pub struct HTMLOmittedCloseTagNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_name: Option<Token>,
}
impl Node for HTMLOmittedCloseTagNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
Vec::new()
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
self.errors.iter().map(|e| e as &dyn ErrorNode).collect()
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"HTMLOmittedCloseTagNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "└── ".white(), "tag_name".white(), format_token_value(&self.tag_name)));
output
}
}
#[derive(Debug, Clone)]
pub struct HTMLVirtualCloseTagNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_name: Option<Token>,
}
impl Node for HTMLVirtualCloseTagNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
Vec::new()
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
self.errors.iter().map(|e| e as &dyn ErrorNode).collect()
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"HTMLVirtualCloseTagNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "└── ".white(), "tag_name".white(), format_token_value(&self.tag_name)));
output
}
}
#[derive(Debug, Clone)]
pub struct HTMLElementNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub open_tag: Option<ERBOpenTagNodeOrHTMLConditionalOpenTagNodeOrHTMLOpenTagNode>,
pub tag_name: Option<Token>,
pub body: Vec<AnyNode>,
pub close_tag: Option<ERBEndNodeOrHTMLCloseTagNodeOrHTMLOmittedCloseTagNodeOrHTMLVirtualCloseTagNode>,
pub is_void: bool,
pub element_source: String,
}
impl Node for HTMLElementNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
if let Some(ref node) = self.open_tag {
children.push(node.as_node());
}
children.extend(self.body.iter().map(|n| n as &dyn Node));
if let Some(ref node) = self.close_tag {
children.push(node.as_node());
}
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
if let Some(ref node) = self.open_tag {
all_errors.extend(node.recursive_errors());
}
for child in &self.body {
all_errors.extend(child.recursive_errors());
}
if let Some(ref node) = self.close_tag {
all_errors.extend(node.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"HTMLElementNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}", "├── ".white(), "open_tag".white(), format_union_node_value(&self.open_tag, &"│ ".white().to_string(), true, |n: &ERBOpenTagNodeOrHTMLConditionalOpenTagNodeOrHTMLOpenTagNode| n.tree_inspect())));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_name".white(), format_token_value(&self.tag_name)));
output.push_str(&format!("{}{}: {}", "├── ".white(), "body".white(), format_array_value(&self.body, &"│ ".white().to_string())));
output.push_str(&format!("{}{}: {}", "├── ".white(), "close_tag".white(), format_union_node_value(&self.close_tag, &"│ ".white().to_string(), true, |n: &ERBEndNodeOrHTMLCloseTagNodeOrHTMLOmittedCloseTagNodeOrHTMLVirtualCloseTagNode| n.tree_inspect())));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "is_void".white(), format_bool_value(self.is_void)));
output.push_str(&format!("{}{}: {}\n", "└── ".white(), "element_source".white(), format_string_value(&self.element_source)));
output
}
}
#[derive(Debug, Clone)]
pub struct HTMLConditionalElementNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub condition: String,
pub open_conditional: Option<ERBIfNodeOrERBUnlessNode>,
pub open_tag: Option<Box<HTMLOpenTagNode>>,
pub body: Vec<AnyNode>,
pub close_tag: Option<HTMLCloseTagNodeOrHTMLOmittedCloseTagNode>,
pub close_conditional: Option<ERBIfNodeOrERBUnlessNode>,
pub tag_name: Option<Token>,
pub element_source: String,
}
impl Node for HTMLConditionalElementNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
if let Some(ref node) = self.open_conditional {
children.push(node.as_node());
}
if let Some(ref node) = self.open_tag {
children.push(node.as_ref() as &dyn Node);
}
children.extend(self.body.iter().map(|n| n as &dyn Node));
if let Some(ref node) = self.close_tag {
children.push(node.as_node());
}
if let Some(ref node) = self.close_conditional {
children.push(node.as_node());
}
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
if let Some(ref node) = self.open_conditional {
all_errors.extend(node.recursive_errors());
}
if let Some(ref node) = self.open_tag {
all_errors.extend(node.recursive_errors());
}
for child in &self.body {
all_errors.extend(child.recursive_errors());
}
if let Some(ref node) = self.close_tag {
all_errors.extend(node.recursive_errors());
}
if let Some(ref node) = self.close_conditional {
all_errors.extend(node.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"HTMLConditionalElementNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "condition".white(), format_string_value(&self.condition)));
output.push_str(&format!("{}{}: {}", "├── ".white(), "open_conditional".white(), format_union_node_value(&self.open_conditional, &"│ ".white().to_string(), true, |n: &ERBIfNodeOrERBUnlessNode| n.tree_inspect())));
output.push_str(&format!("{}{}: {}", "├── ".white(), "open_tag".white(), format_node_value(&self.open_tag, &"│ ".white().to_string(), true)));
output.push_str(&format!("{}{}: {}", "├── ".white(), "body".white(), format_array_value(&self.body, &"│ ".white().to_string())));
output.push_str(&format!("{}{}: {}", "├── ".white(), "close_tag".white(), format_union_node_value(&self.close_tag, &"│ ".white().to_string(), true, |n: &HTMLCloseTagNodeOrHTMLOmittedCloseTagNode| n.tree_inspect())));
output.push_str(&format!("{}{}: {}", "├── ".white(), "close_conditional".white(), format_union_node_value(&self.close_conditional, &"│ ".white().to_string(), true, |n: &ERBIfNodeOrERBUnlessNode| n.tree_inspect())));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_name".white(), format_token_value(&self.tag_name)));
output.push_str(&format!("{}{}: {}\n", "└── ".white(), "element_source".white(), format_string_value(&self.element_source)));
output
}
}
#[derive(Debug, Clone)]
pub struct HTMLAttributeValueNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub open_quote: Option<Token>,
pub children: Vec<AnyNode>,
pub close_quote: Option<Token>,
pub quoted: bool,
}
impl Node for HTMLAttributeValueNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.children.iter().map(|n| n as &dyn Node));
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.children {
all_errors.extend(child.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"HTMLAttributeValueNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "open_quote".white(), format_token_value(&self.open_quote)));
output.push_str(&format!("{}{}: {}", "├── ".white(), "children".white(), format_array_value(&self.children, &"│ ".white().to_string())));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "close_quote".white(), format_token_value(&self.close_quote)));
output.push_str(&format!("{}{}: {}\n", "└── ".white(), "quoted".white(), format_bool_value(self.quoted)));
output
}
}
#[derive(Debug, Clone)]
pub struct HTMLAttributeNameNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub children: Vec<AnyNode>,
}
impl Node for HTMLAttributeNameNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.children.iter().map(|n| n as &dyn Node));
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.children {
all_errors.extend(child.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"HTMLAttributeNameNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}", "└── ".white(), "children".white(), format_array_value(&self.children, &" ".white().to_string())));
output
}
}
#[derive(Debug, Clone)]
pub struct HTMLAttributeNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub name: Option<Box<HTMLAttributeNameNode>>,
pub equals: Option<Token>,
pub value: Option<Box<HTMLAttributeValueNode>>,
}
impl Node for HTMLAttributeNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
if let Some(ref node) = self.name {
children.push(node.as_ref() as &dyn Node);
}
if let Some(ref node) = self.value {
children.push(node.as_ref() as &dyn Node);
}
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
if let Some(ref node) = self.name {
all_errors.extend(node.recursive_errors());
}
if let Some(ref node) = self.value {
all_errors.extend(node.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"HTMLAttributeNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}", "├── ".white(), "name".white(), format_node_value(&self.name, &"│ ".white().to_string(), true)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "equals".white(), format_token_value(&self.equals)));
output.push_str(&format!("{}{}: {}", "└── ".white(), "value".white(), format_node_value(&self.value, &" ".white().to_string(), false)));
output
}
}
#[derive(Debug, Clone)]
pub struct RubyLiteralNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub content: String,
}
impl Node for RubyLiteralNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
Vec::new()
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
self.errors.iter().map(|e| e as &dyn ErrorNode).collect()
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"RubyLiteralNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "└── ".white(), "content".white(), format_string_value(&self.content)));
output
}
}
#[derive(Debug, Clone)]
pub struct RubyHTMLAttributesSplatNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub content: String,
pub prefix: String,
}
impl Node for RubyHTMLAttributesSplatNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
Vec::new()
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
self.errors.iter().map(|e| e as &dyn ErrorNode).collect()
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"RubyHTMLAttributesSplatNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "content".white(), format_string_value(&self.content)));
output.push_str(&format!("{}{}: {}\n", "└── ".white(), "prefix".white(), format_string_value(&self.prefix)));
output
}
}
#[derive(Debug, Clone)]
pub struct ERBOpenTagNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub content: Option<Token>,
pub tag_closing: Option<Token>,
pub tag_name: Option<Token>,
pub children: Vec<AnyNode>,
}
impl Node for ERBOpenTagNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.children.iter().map(|n| n as &dyn Node));
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.children {
all_errors.extend(child.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"ERBOpenTagNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "content".white(), format_token_value(&self.content)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_name".white(), format_token_value(&self.tag_name)));
output.push_str(&format!("{}{}: {}", "└── ".white(), "children".white(), format_array_value(&self.children, &" ".white().to_string())));
output
}
}
impl ERBNode for ERBOpenTagNode {
fn tag_opening(&self) -> &Option<Token> {
&self.tag_opening
}
fn content(&self) -> &Option<Token> {
&self.content
}
fn tag_closing(&self) -> &Option<Token> {
&self.tag_closing
}
fn location(&self) -> &Location {
&self.location
}
}
#[derive(Debug, Clone)]
pub struct HTMLTextNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub content: String,
}
impl Node for HTMLTextNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
Vec::new()
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
self.errors.iter().map(|e| e as &dyn ErrorNode).collect()
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"HTMLTextNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "└── ".white(), "content".white(), format_string_value(&self.content)));
output
}
}
#[derive(Debug, Clone)]
pub struct HTMLCommentNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub comment_start: Option<Token>,
pub children: Vec<AnyNode>,
pub comment_end: Option<Token>,
}
impl Node for HTMLCommentNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.children.iter().map(|n| n as &dyn Node));
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.children {
all_errors.extend(child.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"HTMLCommentNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "comment_start".white(), format_token_value(&self.comment_start)));
output.push_str(&format!("{}{}: {}", "├── ".white(), "children".white(), format_array_value(&self.children, &"│ ".white().to_string())));
output.push_str(&format!("{}{}: {}\n", "└── ".white(), "comment_end".white(), format_token_value(&self.comment_end)));
output
}
}
#[derive(Debug, Clone)]
pub struct HTMLDoctypeNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub children: Vec<AnyNode>,
pub tag_closing: Option<Token>,
}
impl Node for HTMLDoctypeNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.children.iter().map(|n| n as &dyn Node));
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.children {
all_errors.extend(child.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"HTMLDoctypeNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}", "├── ".white(), "children".white(), format_array_value(&self.children, &"│ ".white().to_string())));
output.push_str(&format!("{}{}: {}\n", "└── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
output
}
}
#[derive(Debug, Clone)]
pub struct XMLDeclarationNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub children: Vec<AnyNode>,
pub tag_closing: Option<Token>,
}
impl Node for XMLDeclarationNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.children.iter().map(|n| n as &dyn Node));
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.children {
all_errors.extend(child.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"XMLDeclarationNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}", "├── ".white(), "children".white(), format_array_value(&self.children, &"│ ".white().to_string())));
output.push_str(&format!("{}{}: {}\n", "└── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
output
}
}
#[derive(Debug, Clone)]
pub struct CDATANode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub children: Vec<AnyNode>,
pub tag_closing: Option<Token>,
}
impl Node for CDATANode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.children.iter().map(|n| n as &dyn Node));
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.children {
all_errors.extend(child.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"CDATANode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}", "├── ".white(), "children".white(), format_array_value(&self.children, &"│ ".white().to_string())));
output.push_str(&format!("{}{}: {}\n", "└── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
output
}
}
#[derive(Debug, Clone)]
pub struct WhitespaceNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub value: Option<Token>,
}
impl Node for WhitespaceNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
Vec::new()
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
self.errors.iter().map(|e| e as &dyn ErrorNode).collect()
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"WhitespaceNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "└── ".white(), "value".white(), format_token_value(&self.value)));
output
}
}
#[derive(Debug, Clone)]
pub struct ERBContentNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub content: Option<Token>,
pub tag_closing: Option<Token>,
pub parsed: bool,
pub valid: bool,
pub prism_node: Option<String>,
}
impl Node for ERBContentNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
Vec::new()
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
self.errors.iter().map(|e| e as &dyn ErrorNode).collect()
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"ERBContentNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "content".white(), format_token_value(&self.content)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "parsed".white(), format_bool_value(self.parsed)));
{ let is_last = self.prism_node.is_none(); let symbol = if is_last { "└── " } else { "├── " };
output.push_str(&format!("{}{}: {}\n", symbol.white(), "valid".white(), format_bool_value(self.valid)));
}
if let Some(ref prism_string) = self.prism_node {
let prefix = " ";
output.push_str(&format!("{}{}: \n", "└── ".white(), "prism_node".white()));
output.push_str(&format!("{}└── ", prefix));
let prettified = prettify_prism_tree(prism_string);
let indented = prettified.lines().enumerate().map(|(i, line)| {
if i == 0 { line.to_string() } else { format!("{} {}", prefix, line) }
}).collect::<Vec<_>>().join("\n");
output.push_str(&indented);
output.push('\n');
}
output
}
}
impl ERBNode for ERBContentNode {
fn tag_opening(&self) -> &Option<Token> {
&self.tag_opening
}
fn content(&self) -> &Option<Token> {
&self.content
}
fn tag_closing(&self) -> &Option<Token> {
&self.tag_closing
}
fn location(&self) -> &Location {
&self.location
}
}
#[derive(Debug, Clone)]
pub struct ERBEndNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub content: Option<Token>,
pub tag_closing: Option<Token>,
}
impl Node for ERBEndNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
Vec::new()
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
self.errors.iter().map(|e| e as &dyn ErrorNode).collect()
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"ERBEndNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "content".white(), format_token_value(&self.content)));
output.push_str(&format!("{}{}: {}\n", "└── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
output
}
}
impl ERBNode for ERBEndNode {
fn tag_opening(&self) -> &Option<Token> {
&self.tag_opening
}
fn content(&self) -> &Option<Token> {
&self.content
}
fn tag_closing(&self) -> &Option<Token> {
&self.tag_closing
}
fn location(&self) -> &Location {
&self.location
}
}
#[derive(Debug, Clone)]
pub struct ERBElseNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub content: Option<Token>,
pub tag_closing: Option<Token>,
pub statements: Vec<AnyNode>,
}
impl Node for ERBElseNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.statements.iter().map(|n| n as &dyn Node));
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.statements {
all_errors.extend(child.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"ERBElseNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "content".white(), format_token_value(&self.content)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
output.push_str(&format!("{}{}: {}", "└── ".white(), "statements".white(), format_array_value(&self.statements, &" ".white().to_string())));
output
}
}
impl ERBNode for ERBElseNode {
fn tag_opening(&self) -> &Option<Token> {
&self.tag_opening
}
fn content(&self) -> &Option<Token> {
&self.content
}
fn tag_closing(&self) -> &Option<Token> {
&self.tag_closing
}
fn location(&self) -> &Location {
&self.location
}
}
#[derive(Debug, Clone)]
pub struct ERBIfNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub content: Option<Token>,
pub tag_closing: Option<Token>,
pub then_keyword: Option<Location>,
pub prism_node: Option<String>,
pub statements: Vec<AnyNode>,
pub subsequent: Option<ERBElseNodeOrERBIfNode>,
pub end_node: Option<Box<ERBEndNode>>,
}
impl Node for ERBIfNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.statements.iter().map(|n| n as &dyn Node));
if let Some(ref node) = self.subsequent {
children.push(node.as_node());
}
if let Some(ref node) = self.end_node {
children.push(node.as_ref() as &dyn Node);
}
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.statements {
all_errors.extend(child.recursive_errors());
}
if let Some(ref node) = self.subsequent {
all_errors.extend(node.recursive_errors());
}
if let Some(ref node) = self.end_node {
all_errors.extend(node.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"ERBIfNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "content".white(), format_token_value(&self.content)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "then_keyword".white(), self.then_keyword.as_ref().map(|l| format!("(location: {})", l).dimmed().to_string()).unwrap_or_else(|| "∅".magenta().to_string())));
if let Some(ref prism_string) = self.prism_node {
let prefix = "│ ";
output.push_str(&format!("{}{}: \n", "├── ".white(), "prism_node".white()));
output.push_str(&format!("{}└── ", prefix));
let prettified = prettify_prism_tree(prism_string);
let indented = prettified.lines().enumerate().map(|(i, line)| {
if i == 0 { line.to_string() } else { format!("{} {}", prefix, line) }
}).collect::<Vec<_>>().join("\n");
output.push_str(&indented);
output.push('\n');
}
output.push_str(&format!("{}{}: {}", "├── ".white(), "statements".white(), format_array_value(&self.statements, &"│ ".white().to_string())));
output.push_str(&format!("{}{}: {}", "├── ".white(), "subsequent".white(), format_union_node_value(&self.subsequent, &"│ ".white().to_string(), true, |n: &ERBElseNodeOrERBIfNode| n.tree_inspect())));
output.push_str(&format!("{}{}: {}", "└── ".white(), "end_node".white(), format_node_value(&self.end_node, &" ".white().to_string(), false)));
output
}
}
impl ERBNode for ERBIfNode {
fn tag_opening(&self) -> &Option<Token> {
&self.tag_opening
}
fn content(&self) -> &Option<Token> {
&self.content
}
fn tag_closing(&self) -> &Option<Token> {
&self.tag_closing
}
fn location(&self) -> &Location {
&self.location
}
}
#[derive(Debug, Clone)]
pub struct ERBBlockNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub content: Option<Token>,
pub tag_closing: Option<Token>,
pub prism_node: Option<String>,
pub body: Vec<AnyNode>,
pub block_arguments: Vec<AnyNode>,
pub rescue_clause: Option<Box<ERBRescueNode>>,
pub else_clause: Option<Box<ERBElseNode>>,
pub ensure_clause: Option<Box<ERBEnsureNode>>,
pub end_node: Option<Box<ERBEndNode>>,
}
impl Node for ERBBlockNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.body.iter().map(|n| n as &dyn Node));
children.extend(self.block_arguments.iter().map(|n| n as &dyn Node));
if let Some(ref node) = self.rescue_clause {
children.push(node.as_ref() as &dyn Node);
}
if let Some(ref node) = self.else_clause {
children.push(node.as_ref() as &dyn Node);
}
if let Some(ref node) = self.ensure_clause {
children.push(node.as_ref() as &dyn Node);
}
if let Some(ref node) = self.end_node {
children.push(node.as_ref() as &dyn Node);
}
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.body {
all_errors.extend(child.recursive_errors());
}
for child in &self.block_arguments {
all_errors.extend(child.recursive_errors());
}
if let Some(ref node) = self.rescue_clause {
all_errors.extend(node.recursive_errors());
}
if let Some(ref node) = self.else_clause {
all_errors.extend(node.recursive_errors());
}
if let Some(ref node) = self.ensure_clause {
all_errors.extend(node.recursive_errors());
}
if let Some(ref node) = self.end_node {
all_errors.extend(node.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"ERBBlockNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "content".white(), format_token_value(&self.content)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
if let Some(ref prism_string) = self.prism_node {
let prefix = "│ ";
output.push_str(&format!("{}{}: \n", "├── ".white(), "prism_node".white()));
output.push_str(&format!("{}└── ", prefix));
let prettified = prettify_prism_tree(prism_string);
let indented = prettified.lines().enumerate().map(|(i, line)| {
if i == 0 { line.to_string() } else { format!("{} {}", prefix, line) }
}).collect::<Vec<_>>().join("\n");
output.push_str(&indented);
output.push('\n');
}
output.push_str(&format!("{}{}: {}", "├── ".white(), "body".white(), format_array_value(&self.body, &"│ ".white().to_string())));
output.push_str(&format!("{}{}: {}", "├── ".white(), "block_arguments".white(), format_array_value(&self.block_arguments, &"│ ".white().to_string())));
output.push_str(&format!("{}{}: {}", "├── ".white(), "rescue_clause".white(), format_node_value(&self.rescue_clause, &"│ ".white().to_string(), true)));
output.push_str(&format!("{}{}: {}", "├── ".white(), "else_clause".white(), format_node_value(&self.else_clause, &"│ ".white().to_string(), true)));
output.push_str(&format!("{}{}: {}", "├── ".white(), "ensure_clause".white(), format_node_value(&self.ensure_clause, &"│ ".white().to_string(), true)));
output.push_str(&format!("{}{}: {}", "└── ".white(), "end_node".white(), format_node_value(&self.end_node, &" ".white().to_string(), false)));
output
}
}
impl ERBNode for ERBBlockNode {
fn tag_opening(&self) -> &Option<Token> {
&self.tag_opening
}
fn content(&self) -> &Option<Token> {
&self.content
}
fn tag_closing(&self) -> &Option<Token> {
&self.tag_closing
}
fn location(&self) -> &Location {
&self.location
}
}
#[derive(Debug, Clone)]
pub struct ERBWhenNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub content: Option<Token>,
pub tag_closing: Option<Token>,
pub then_keyword: Option<Location>,
pub statements: Vec<AnyNode>,
}
impl Node for ERBWhenNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.statements.iter().map(|n| n as &dyn Node));
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.statements {
all_errors.extend(child.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"ERBWhenNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "content".white(), format_token_value(&self.content)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "then_keyword".white(), self.then_keyword.as_ref().map(|l| format!("(location: {})", l).dimmed().to_string()).unwrap_or_else(|| "∅".magenta().to_string())));
output.push_str(&format!("{}{}: {}", "└── ".white(), "statements".white(), format_array_value(&self.statements, &" ".white().to_string())));
output
}
}
impl ERBNode for ERBWhenNode {
fn tag_opening(&self) -> &Option<Token> {
&self.tag_opening
}
fn content(&self) -> &Option<Token> {
&self.content
}
fn tag_closing(&self) -> &Option<Token> {
&self.tag_closing
}
fn location(&self) -> &Location {
&self.location
}
}
#[derive(Debug, Clone)]
pub struct ERBCaseNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub content: Option<Token>,
pub tag_closing: Option<Token>,
pub children: Vec<AnyNode>,
pub prism_node: Option<String>,
pub conditions: Vec<AnyNode>,
pub else_clause: Option<Box<ERBElseNode>>,
pub end_node: Option<Box<ERBEndNode>>,
}
impl Node for ERBCaseNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.children.iter().map(|n| n as &dyn Node));
children.extend(self.conditions.iter().map(|n| n as &dyn Node));
if let Some(ref node) = self.else_clause {
children.push(node.as_ref() as &dyn Node);
}
if let Some(ref node) = self.end_node {
children.push(node.as_ref() as &dyn Node);
}
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.children {
all_errors.extend(child.recursive_errors());
}
for child in &self.conditions {
all_errors.extend(child.recursive_errors());
}
if let Some(ref node) = self.else_clause {
all_errors.extend(node.recursive_errors());
}
if let Some(ref node) = self.end_node {
all_errors.extend(node.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"ERBCaseNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "content".white(), format_token_value(&self.content)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
output.push_str(&format!("{}{}: {}", "├── ".white(), "children".white(), format_array_value(&self.children, &"│ ".white().to_string())));
if let Some(ref prism_string) = self.prism_node {
let prefix = "│ ";
output.push_str(&format!("{}{}: \n", "├── ".white(), "prism_node".white()));
output.push_str(&format!("{}└── ", prefix));
let prettified = prettify_prism_tree(prism_string);
let indented = prettified.lines().enumerate().map(|(i, line)| {
if i == 0 { line.to_string() } else { format!("{} {}", prefix, line) }
}).collect::<Vec<_>>().join("\n");
output.push_str(&indented);
output.push('\n');
}
output.push_str(&format!("{}{}: {}", "├── ".white(), "conditions".white(), format_array_value(&self.conditions, &"│ ".white().to_string())));
output.push_str(&format!("{}{}: {}", "├── ".white(), "else_clause".white(), format_node_value(&self.else_clause, &"│ ".white().to_string(), true)));
output.push_str(&format!("{}{}: {}", "└── ".white(), "end_node".white(), format_node_value(&self.end_node, &" ".white().to_string(), false)));
output
}
}
impl ERBNode for ERBCaseNode {
fn tag_opening(&self) -> &Option<Token> {
&self.tag_opening
}
fn content(&self) -> &Option<Token> {
&self.content
}
fn tag_closing(&self) -> &Option<Token> {
&self.tag_closing
}
fn location(&self) -> &Location {
&self.location
}
}
#[derive(Debug, Clone)]
pub struct ERBCaseMatchNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub content: Option<Token>,
pub tag_closing: Option<Token>,
pub children: Vec<AnyNode>,
pub prism_node: Option<String>,
pub conditions: Vec<AnyNode>,
pub else_clause: Option<Box<ERBElseNode>>,
pub end_node: Option<Box<ERBEndNode>>,
}
impl Node for ERBCaseMatchNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.children.iter().map(|n| n as &dyn Node));
children.extend(self.conditions.iter().map(|n| n as &dyn Node));
if let Some(ref node) = self.else_clause {
children.push(node.as_ref() as &dyn Node);
}
if let Some(ref node) = self.end_node {
children.push(node.as_ref() as &dyn Node);
}
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.children {
all_errors.extend(child.recursive_errors());
}
for child in &self.conditions {
all_errors.extend(child.recursive_errors());
}
if let Some(ref node) = self.else_clause {
all_errors.extend(node.recursive_errors());
}
if let Some(ref node) = self.end_node {
all_errors.extend(node.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"ERBCaseMatchNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "content".white(), format_token_value(&self.content)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
output.push_str(&format!("{}{}: {}", "├── ".white(), "children".white(), format_array_value(&self.children, &"│ ".white().to_string())));
if let Some(ref prism_string) = self.prism_node {
let prefix = "│ ";
output.push_str(&format!("{}{}: \n", "├── ".white(), "prism_node".white()));
output.push_str(&format!("{}└── ", prefix));
let prettified = prettify_prism_tree(prism_string);
let indented = prettified.lines().enumerate().map(|(i, line)| {
if i == 0 { line.to_string() } else { format!("{} {}", prefix, line) }
}).collect::<Vec<_>>().join("\n");
output.push_str(&indented);
output.push('\n');
}
output.push_str(&format!("{}{}: {}", "├── ".white(), "conditions".white(), format_array_value(&self.conditions, &"│ ".white().to_string())));
output.push_str(&format!("{}{}: {}", "├── ".white(), "else_clause".white(), format_node_value(&self.else_clause, &"│ ".white().to_string(), true)));
output.push_str(&format!("{}{}: {}", "└── ".white(), "end_node".white(), format_node_value(&self.end_node, &" ".white().to_string(), false)));
output
}
}
impl ERBNode for ERBCaseMatchNode {
fn tag_opening(&self) -> &Option<Token> {
&self.tag_opening
}
fn content(&self) -> &Option<Token> {
&self.content
}
fn tag_closing(&self) -> &Option<Token> {
&self.tag_closing
}
fn location(&self) -> &Location {
&self.location
}
}
#[derive(Debug, Clone)]
pub struct ERBWhileNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub content: Option<Token>,
pub tag_closing: Option<Token>,
pub prism_node: Option<String>,
pub statements: Vec<AnyNode>,
pub end_node: Option<Box<ERBEndNode>>,
}
impl Node for ERBWhileNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.statements.iter().map(|n| n as &dyn Node));
if let Some(ref node) = self.end_node {
children.push(node.as_ref() as &dyn Node);
}
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.statements {
all_errors.extend(child.recursive_errors());
}
if let Some(ref node) = self.end_node {
all_errors.extend(node.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"ERBWhileNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "content".white(), format_token_value(&self.content)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
if let Some(ref prism_string) = self.prism_node {
let prefix = "│ ";
output.push_str(&format!("{}{}: \n", "├── ".white(), "prism_node".white()));
output.push_str(&format!("{}└── ", prefix));
let prettified = prettify_prism_tree(prism_string);
let indented = prettified.lines().enumerate().map(|(i, line)| {
if i == 0 { line.to_string() } else { format!("{} {}", prefix, line) }
}).collect::<Vec<_>>().join("\n");
output.push_str(&indented);
output.push('\n');
}
output.push_str(&format!("{}{}: {}", "├── ".white(), "statements".white(), format_array_value(&self.statements, &"│ ".white().to_string())));
output.push_str(&format!("{}{}: {}", "└── ".white(), "end_node".white(), format_node_value(&self.end_node, &" ".white().to_string(), false)));
output
}
}
impl ERBNode for ERBWhileNode {
fn tag_opening(&self) -> &Option<Token> {
&self.tag_opening
}
fn content(&self) -> &Option<Token> {
&self.content
}
fn tag_closing(&self) -> &Option<Token> {
&self.tag_closing
}
fn location(&self) -> &Location {
&self.location
}
}
#[derive(Debug, Clone)]
pub struct ERBUntilNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub content: Option<Token>,
pub tag_closing: Option<Token>,
pub prism_node: Option<String>,
pub statements: Vec<AnyNode>,
pub end_node: Option<Box<ERBEndNode>>,
}
impl Node for ERBUntilNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.statements.iter().map(|n| n as &dyn Node));
if let Some(ref node) = self.end_node {
children.push(node.as_ref() as &dyn Node);
}
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.statements {
all_errors.extend(child.recursive_errors());
}
if let Some(ref node) = self.end_node {
all_errors.extend(node.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"ERBUntilNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "content".white(), format_token_value(&self.content)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
if let Some(ref prism_string) = self.prism_node {
let prefix = "│ ";
output.push_str(&format!("{}{}: \n", "├── ".white(), "prism_node".white()));
output.push_str(&format!("{}└── ", prefix));
let prettified = prettify_prism_tree(prism_string);
let indented = prettified.lines().enumerate().map(|(i, line)| {
if i == 0 { line.to_string() } else { format!("{} {}", prefix, line) }
}).collect::<Vec<_>>().join("\n");
output.push_str(&indented);
output.push('\n');
}
output.push_str(&format!("{}{}: {}", "├── ".white(), "statements".white(), format_array_value(&self.statements, &"│ ".white().to_string())));
output.push_str(&format!("{}{}: {}", "└── ".white(), "end_node".white(), format_node_value(&self.end_node, &" ".white().to_string(), false)));
output
}
}
impl ERBNode for ERBUntilNode {
fn tag_opening(&self) -> &Option<Token> {
&self.tag_opening
}
fn content(&self) -> &Option<Token> {
&self.content
}
fn tag_closing(&self) -> &Option<Token> {
&self.tag_closing
}
fn location(&self) -> &Location {
&self.location
}
}
#[derive(Debug, Clone)]
pub struct ERBForNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub content: Option<Token>,
pub tag_closing: Option<Token>,
pub prism_node: Option<String>,
pub statements: Vec<AnyNode>,
pub end_node: Option<Box<ERBEndNode>>,
}
impl Node for ERBForNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.statements.iter().map(|n| n as &dyn Node));
if let Some(ref node) = self.end_node {
children.push(node.as_ref() as &dyn Node);
}
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.statements {
all_errors.extend(child.recursive_errors());
}
if let Some(ref node) = self.end_node {
all_errors.extend(node.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"ERBForNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "content".white(), format_token_value(&self.content)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
if let Some(ref prism_string) = self.prism_node {
let prefix = "│ ";
output.push_str(&format!("{}{}: \n", "├── ".white(), "prism_node".white()));
output.push_str(&format!("{}└── ", prefix));
let prettified = prettify_prism_tree(prism_string);
let indented = prettified.lines().enumerate().map(|(i, line)| {
if i == 0 { line.to_string() } else { format!("{} {}", prefix, line) }
}).collect::<Vec<_>>().join("\n");
output.push_str(&indented);
output.push('\n');
}
output.push_str(&format!("{}{}: {}", "├── ".white(), "statements".white(), format_array_value(&self.statements, &"│ ".white().to_string())));
output.push_str(&format!("{}{}: {}", "└── ".white(), "end_node".white(), format_node_value(&self.end_node, &" ".white().to_string(), false)));
output
}
}
impl ERBNode for ERBForNode {
fn tag_opening(&self) -> &Option<Token> {
&self.tag_opening
}
fn content(&self) -> &Option<Token> {
&self.content
}
fn tag_closing(&self) -> &Option<Token> {
&self.tag_closing
}
fn location(&self) -> &Location {
&self.location
}
}
#[derive(Debug, Clone)]
pub struct ERBRescueNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub content: Option<Token>,
pub tag_closing: Option<Token>,
pub statements: Vec<AnyNode>,
pub subsequent: Option<Box<ERBRescueNode>>,
}
impl Node for ERBRescueNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.statements.iter().map(|n| n as &dyn Node));
if let Some(ref node) = self.subsequent {
children.push(node.as_ref() as &dyn Node);
}
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.statements {
all_errors.extend(child.recursive_errors());
}
if let Some(ref node) = self.subsequent {
all_errors.extend(node.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"ERBRescueNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "content".white(), format_token_value(&self.content)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
output.push_str(&format!("{}{}: {}", "├── ".white(), "statements".white(), format_array_value(&self.statements, &"│ ".white().to_string())));
output.push_str(&format!("{}{}: {}", "└── ".white(), "subsequent".white(), format_node_value(&self.subsequent, &" ".white().to_string(), false)));
output
}
}
impl ERBNode for ERBRescueNode {
fn tag_opening(&self) -> &Option<Token> {
&self.tag_opening
}
fn content(&self) -> &Option<Token> {
&self.content
}
fn tag_closing(&self) -> &Option<Token> {
&self.tag_closing
}
fn location(&self) -> &Location {
&self.location
}
}
#[derive(Debug, Clone)]
pub struct ERBEnsureNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub content: Option<Token>,
pub tag_closing: Option<Token>,
pub statements: Vec<AnyNode>,
}
impl Node for ERBEnsureNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.statements.iter().map(|n| n as &dyn Node));
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.statements {
all_errors.extend(child.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"ERBEnsureNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "content".white(), format_token_value(&self.content)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
output.push_str(&format!("{}{}: {}", "└── ".white(), "statements".white(), format_array_value(&self.statements, &" ".white().to_string())));
output
}
}
impl ERBNode for ERBEnsureNode {
fn tag_opening(&self) -> &Option<Token> {
&self.tag_opening
}
fn content(&self) -> &Option<Token> {
&self.content
}
fn tag_closing(&self) -> &Option<Token> {
&self.tag_closing
}
fn location(&self) -> &Location {
&self.location
}
}
#[derive(Debug, Clone)]
pub struct ERBBeginNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub content: Option<Token>,
pub tag_closing: Option<Token>,
pub prism_node: Option<String>,
pub statements: Vec<AnyNode>,
pub rescue_clause: Option<Box<ERBRescueNode>>,
pub else_clause: Option<Box<ERBElseNode>>,
pub ensure_clause: Option<Box<ERBEnsureNode>>,
pub end_node: Option<Box<ERBEndNode>>,
}
impl Node for ERBBeginNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.statements.iter().map(|n| n as &dyn Node));
if let Some(ref node) = self.rescue_clause {
children.push(node.as_ref() as &dyn Node);
}
if let Some(ref node) = self.else_clause {
children.push(node.as_ref() as &dyn Node);
}
if let Some(ref node) = self.ensure_clause {
children.push(node.as_ref() as &dyn Node);
}
if let Some(ref node) = self.end_node {
children.push(node.as_ref() as &dyn Node);
}
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.statements {
all_errors.extend(child.recursive_errors());
}
if let Some(ref node) = self.rescue_clause {
all_errors.extend(node.recursive_errors());
}
if let Some(ref node) = self.else_clause {
all_errors.extend(node.recursive_errors());
}
if let Some(ref node) = self.ensure_clause {
all_errors.extend(node.recursive_errors());
}
if let Some(ref node) = self.end_node {
all_errors.extend(node.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"ERBBeginNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "content".white(), format_token_value(&self.content)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
if let Some(ref prism_string) = self.prism_node {
let prefix = "│ ";
output.push_str(&format!("{}{}: \n", "├── ".white(), "prism_node".white()));
output.push_str(&format!("{}└── ", prefix));
let prettified = prettify_prism_tree(prism_string);
let indented = prettified.lines().enumerate().map(|(i, line)| {
if i == 0 { line.to_string() } else { format!("{} {}", prefix, line) }
}).collect::<Vec<_>>().join("\n");
output.push_str(&indented);
output.push('\n');
}
output.push_str(&format!("{}{}: {}", "├── ".white(), "statements".white(), format_array_value(&self.statements, &"│ ".white().to_string())));
output.push_str(&format!("{}{}: {}", "├── ".white(), "rescue_clause".white(), format_node_value(&self.rescue_clause, &"│ ".white().to_string(), true)));
output.push_str(&format!("{}{}: {}", "├── ".white(), "else_clause".white(), format_node_value(&self.else_clause, &"│ ".white().to_string(), true)));
output.push_str(&format!("{}{}: {}", "├── ".white(), "ensure_clause".white(), format_node_value(&self.ensure_clause, &"│ ".white().to_string(), true)));
output.push_str(&format!("{}{}: {}", "└── ".white(), "end_node".white(), format_node_value(&self.end_node, &" ".white().to_string(), false)));
output
}
}
impl ERBNode for ERBBeginNode {
fn tag_opening(&self) -> &Option<Token> {
&self.tag_opening
}
fn content(&self) -> &Option<Token> {
&self.content
}
fn tag_closing(&self) -> &Option<Token> {
&self.tag_closing
}
fn location(&self) -> &Location {
&self.location
}
}
#[derive(Debug, Clone)]
pub struct ERBUnlessNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub content: Option<Token>,
pub tag_closing: Option<Token>,
pub then_keyword: Option<Location>,
pub prism_node: Option<String>,
pub statements: Vec<AnyNode>,
pub else_clause: Option<Box<ERBElseNode>>,
pub end_node: Option<Box<ERBEndNode>>,
}
impl Node for ERBUnlessNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.statements.iter().map(|n| n as &dyn Node));
if let Some(ref node) = self.else_clause {
children.push(node.as_ref() as &dyn Node);
}
if let Some(ref node) = self.end_node {
children.push(node.as_ref() as &dyn Node);
}
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.statements {
all_errors.extend(child.recursive_errors());
}
if let Some(ref node) = self.else_clause {
all_errors.extend(node.recursive_errors());
}
if let Some(ref node) = self.end_node {
all_errors.extend(node.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"ERBUnlessNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "content".white(), format_token_value(&self.content)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "then_keyword".white(), self.then_keyword.as_ref().map(|l| format!("(location: {})", l).dimmed().to_string()).unwrap_or_else(|| "∅".magenta().to_string())));
if let Some(ref prism_string) = self.prism_node {
let prefix = "│ ";
output.push_str(&format!("{}{}: \n", "├── ".white(), "prism_node".white()));
output.push_str(&format!("{}└── ", prefix));
let prettified = prettify_prism_tree(prism_string);
let indented = prettified.lines().enumerate().map(|(i, line)| {
if i == 0 { line.to_string() } else { format!("{} {}", prefix, line) }
}).collect::<Vec<_>>().join("\n");
output.push_str(&indented);
output.push('\n');
}
output.push_str(&format!("{}{}: {}", "├── ".white(), "statements".white(), format_array_value(&self.statements, &"│ ".white().to_string())));
output.push_str(&format!("{}{}: {}", "├── ".white(), "else_clause".white(), format_node_value(&self.else_clause, &"│ ".white().to_string(), true)));
output.push_str(&format!("{}{}: {}", "└── ".white(), "end_node".white(), format_node_value(&self.end_node, &" ".white().to_string(), false)));
output
}
}
impl ERBNode for ERBUnlessNode {
fn tag_opening(&self) -> &Option<Token> {
&self.tag_opening
}
fn content(&self) -> &Option<Token> {
&self.content
}
fn tag_closing(&self) -> &Option<Token> {
&self.tag_closing
}
fn location(&self) -> &Location {
&self.location
}
}
#[derive(Debug, Clone)]
pub struct RubyRenderLocalNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub name: Option<Token>,
pub value: Option<Box<RubyLiteralNode>>,
}
impl Node for RubyRenderLocalNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
if let Some(ref node) = self.value {
children.push(node.as_ref() as &dyn Node);
}
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
if let Some(ref node) = self.value {
all_errors.extend(node.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"RubyRenderLocalNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "name".white(), format_token_value(&self.name)));
output.push_str(&format!("{}{}: {}", "└── ".white(), "value".white(), format_node_value(&self.value, &" ".white().to_string(), false)));
output
}
}
#[derive(Debug, Clone)]
pub struct RubyRenderKeywordsNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub partial: Option<Token>,
pub template_path: Option<Token>,
pub layout: Option<Token>,
pub file: Option<Token>,
pub inline_template: Option<Token>,
pub body: Option<Token>,
pub plain: Option<Token>,
pub html: Option<Token>,
pub renderable: Option<Token>,
pub collection: Option<Token>,
pub object: Option<Token>,
pub as_name: Option<Token>,
pub spacer_template: Option<Token>,
pub formats: Option<Token>,
pub variants: Option<Token>,
pub handlers: Option<Token>,
pub content_type: Option<Token>,
pub locals: Vec<AnyNode>,
}
impl Node for RubyRenderKeywordsNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.locals.iter().map(|n| n as &dyn Node));
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.locals {
all_errors.extend(child.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"RubyRenderKeywordsNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "partial".white(), format_token_value(&self.partial)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "template_path".white(), format_token_value(&self.template_path)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "layout".white(), format_token_value(&self.layout)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "file".white(), format_token_value(&self.file)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "inline_template".white(), format_token_value(&self.inline_template)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "body".white(), format_token_value(&self.body)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "plain".white(), format_token_value(&self.plain)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "html".white(), format_token_value(&self.html)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "renderable".white(), format_token_value(&self.renderable)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "collection".white(), format_token_value(&self.collection)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "object".white(), format_token_value(&self.object)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "as_name".white(), format_token_value(&self.as_name)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "spacer_template".white(), format_token_value(&self.spacer_template)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "formats".white(), format_token_value(&self.formats)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "variants".white(), format_token_value(&self.variants)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "handlers".white(), format_token_value(&self.handlers)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "content_type".white(), format_token_value(&self.content_type)));
output.push_str(&format!("{}{}: {}", "└── ".white(), "locals".white(), format_array_value(&self.locals, &" ".white().to_string())));
output
}
}
#[derive(Debug, Clone)]
pub struct ERBRenderNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub content: Option<Token>,
pub tag_closing: Option<Token>,
pub prism_node: Option<String>,
pub keywords: Option<Box<RubyRenderKeywordsNode>>,
pub body: Vec<AnyNode>,
pub block_arguments: Vec<AnyNode>,
pub rescue_clause: Option<Box<ERBRescueNode>>,
pub else_clause: Option<Box<ERBElseNode>>,
pub ensure_clause: Option<Box<ERBEnsureNode>>,
pub end_node: Option<Box<ERBEndNode>>,
}
impl Node for ERBRenderNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
if let Some(ref node) = self.keywords {
children.push(node.as_ref() as &dyn Node);
}
children.extend(self.body.iter().map(|n| n as &dyn Node));
children.extend(self.block_arguments.iter().map(|n| n as &dyn Node));
if let Some(ref node) = self.rescue_clause {
children.push(node.as_ref() as &dyn Node);
}
if let Some(ref node) = self.else_clause {
children.push(node.as_ref() as &dyn Node);
}
if let Some(ref node) = self.ensure_clause {
children.push(node.as_ref() as &dyn Node);
}
if let Some(ref node) = self.end_node {
children.push(node.as_ref() as &dyn Node);
}
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
if let Some(ref node) = self.keywords {
all_errors.extend(node.recursive_errors());
}
for child in &self.body {
all_errors.extend(child.recursive_errors());
}
for child in &self.block_arguments {
all_errors.extend(child.recursive_errors());
}
if let Some(ref node) = self.rescue_clause {
all_errors.extend(node.recursive_errors());
}
if let Some(ref node) = self.else_clause {
all_errors.extend(node.recursive_errors());
}
if let Some(ref node) = self.ensure_clause {
all_errors.extend(node.recursive_errors());
}
if let Some(ref node) = self.end_node {
all_errors.extend(node.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"ERBRenderNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "content".white(), format_token_value(&self.content)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
if let Some(ref prism_string) = self.prism_node {
let prefix = "│ ";
output.push_str(&format!("{}{}: \n", "├── ".white(), "prism_node".white()));
output.push_str(&format!("{}└── ", prefix));
let prettified = prettify_prism_tree(prism_string);
let indented = prettified.lines().enumerate().map(|(i, line)| {
if i == 0 { line.to_string() } else { format!("{} {}", prefix, line) }
}).collect::<Vec<_>>().join("\n");
output.push_str(&indented);
output.push('\n');
}
output.push_str(&format!("{}{}: {}", "├── ".white(), "keywords".white(), format_node_value(&self.keywords, &"│ ".white().to_string(), true)));
output.push_str(&format!("{}{}: {}", "├── ".white(), "body".white(), format_array_value(&self.body, &"│ ".white().to_string())));
output.push_str(&format!("{}{}: {}", "├── ".white(), "block_arguments".white(), format_array_value(&self.block_arguments, &"│ ".white().to_string())));
output.push_str(&format!("{}{}: {}", "├── ".white(), "rescue_clause".white(), format_node_value(&self.rescue_clause, &"│ ".white().to_string(), true)));
output.push_str(&format!("{}{}: {}", "├── ".white(), "else_clause".white(), format_node_value(&self.else_clause, &"│ ".white().to_string(), true)));
output.push_str(&format!("{}{}: {}", "├── ".white(), "ensure_clause".white(), format_node_value(&self.ensure_clause, &"│ ".white().to_string(), true)));
output.push_str(&format!("{}{}: {}", "└── ".white(), "end_node".white(), format_node_value(&self.end_node, &" ".white().to_string(), false)));
output
}
}
impl ERBNode for ERBRenderNode {
fn tag_opening(&self) -> &Option<Token> {
&self.tag_opening
}
fn content(&self) -> &Option<Token> {
&self.content
}
fn tag_closing(&self) -> &Option<Token> {
&self.tag_closing
}
fn location(&self) -> &Location {
&self.location
}
}
#[derive(Debug, Clone)]
pub struct RubyParameterNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub name: Option<Token>,
pub default_value: Option<Box<RubyLiteralNode>>,
pub kind: String,
pub required: bool,
}
impl Node for RubyParameterNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
if let Some(ref node) = self.default_value {
children.push(node.as_ref() as &dyn Node);
}
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
if let Some(ref node) = self.default_value {
all_errors.extend(node.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"RubyParameterNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "name".white(), format_token_value(&self.name)));
output.push_str(&format!("{}{}: {}", "├── ".white(), "default_value".white(), format_node_value(&self.default_value, &"│ ".white().to_string(), true)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "kind".white(), format_string_value(&self.kind)));
output.push_str(&format!("{}{}: {}\n", "└── ".white(), "required".white(), format_bool_value(self.required)));
output
}
}
#[derive(Debug, Clone)]
pub struct ERBStrictLocalsNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub content: Option<Token>,
pub tag_closing: Option<Token>,
pub prism_node: Option<String>,
pub locals: Vec<AnyNode>,
}
impl Node for ERBStrictLocalsNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.locals.iter().map(|n| n as &dyn Node));
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.locals {
all_errors.extend(child.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"ERBStrictLocalsNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "content".white(), format_token_value(&self.content)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
if let Some(ref prism_string) = self.prism_node {
let prefix = "│ ";
output.push_str(&format!("{}{}: \n", "├── ".white(), "prism_node".white()));
output.push_str(&format!("{}└── ", prefix));
let prettified = prettify_prism_tree(prism_string);
let indented = prettified.lines().enumerate().map(|(i, line)| {
if i == 0 { line.to_string() } else { format!("{} {}", prefix, line) }
}).collect::<Vec<_>>().join("\n");
output.push_str(&indented);
output.push('\n');
}
output.push_str(&format!("{}{}: {}", "└── ".white(), "locals".white(), format_array_value(&self.locals, &" ".white().to_string())));
output
}
}
impl ERBNode for ERBStrictLocalsNode {
fn tag_opening(&self) -> &Option<Token> {
&self.tag_opening
}
fn content(&self) -> &Option<Token> {
&self.content
}
fn tag_closing(&self) -> &Option<Token> {
&self.tag_closing
}
fn location(&self) -> &Location {
&self.location
}
}
#[derive(Debug, Clone)]
pub struct ERBYieldNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub content: Option<Token>,
pub tag_closing: Option<Token>,
}
impl Node for ERBYieldNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
Vec::new()
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
self.errors.iter().map(|e| e as &dyn ErrorNode).collect()
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"ERBYieldNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "content".white(), format_token_value(&self.content)));
output.push_str(&format!("{}{}: {}\n", "└── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
output
}
}
impl ERBNode for ERBYieldNode {
fn tag_opening(&self) -> &Option<Token> {
&self.tag_opening
}
fn content(&self) -> &Option<Token> {
&self.content
}
fn tag_closing(&self) -> &Option<Token> {
&self.tag_closing
}
fn location(&self) -> &Location {
&self.location
}
}
#[derive(Debug, Clone)]
pub struct ERBInNode {
pub node_type: String,
pub location: Location,
pub errors: Vec<AnyError>,
pub tag_opening: Option<Token>,
pub content: Option<Token>,
pub tag_closing: Option<Token>,
pub then_keyword: Option<Location>,
pub statements: Vec<AnyNode>,
}
impl Node for ERBInNode {
fn node_type(&self) -> &str {
&self.node_type
}
fn location(&self) -> &Location {
&self.location
}
fn errors(&self) -> &[AnyError] {
&self.errors
}
fn child_nodes(&self) -> Vec<&dyn Node> {
let mut children: Vec<&dyn Node> = Vec::new();
children.extend(self.statements.iter().map(|n| n as &dyn Node));
children
}
fn recursive_errors(&self) -> Vec<&dyn ErrorNode> {
let mut all_errors: Vec<&dyn ErrorNode> = Vec::new();
all_errors.extend(self.errors.iter().map(|e| e as &dyn ErrorNode));
for child in &self.statements {
all_errors.extend(child.recursive_errors());
}
all_errors
}
fn tree_inspect(&self) -> String {
let mut output = String::new();
output.push_str(&format!("{} {} {}\n",
"@".white(),
"ERBInNode".yellow().bold(),
format!("(location: {})", self.location).dimmed()
));
output.push_str(&format_errors_field(&self.errors, &"│ ".white().to_string()));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_opening".white(), format_token_value(&self.tag_opening)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "content".white(), format_token_value(&self.content)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "tag_closing".white(), format_token_value(&self.tag_closing)));
output.push_str(&format!("{}{}: {}\n", "├── ".white(), "then_keyword".white(), self.then_keyword.as_ref().map(|l| format!("(location: {})", l).dimmed().to_string()).unwrap_or_else(|| "∅".magenta().to_string())));
output.push_str(&format!("{}{}: {}", "└── ".white(), "statements".white(), format_array_value(&self.statements, &" ".white().to_string())));
output
}
}
impl ERBNode for ERBInNode {
fn tag_opening(&self) -> &Option<Token> {
&self.tag_opening
}
fn content(&self) -> &Option<Token> {
&self.content
}
fn tag_closing(&self) -> &Option<Token> {
&self.tag_closing
}
fn location(&self) -> &Location {
&self.location
}
}