tree-sitter/cli/src/parse.rs

93 lines
2.6 KiB
Rust

use super::error::Result;
use super::util;
use std::fs;
use std::io::{self, Write};
use std::path::Path;
use tree_sitter::{Language, LogType, Parser};
pub fn parse_file_at_path(
language: Language,
path: &Path,
debug: bool,
debug_graph: bool,
) -> Result<()> {
let mut parser = Parser::new();
parser.set_language(language)?;
let source_code = fs::read_to_string(path)?;
let mut log_session = None;
if debug_graph {
log_session = Some(util::start_logging_graphs(&mut parser, "log.html")?);
} else if debug {
parser.set_logger(Some(Box::new(|log_type, message| {
if log_type == LogType::Lex {
io::stderr().write(b" ").unwrap();
}
write!(&mut io::stderr(), "{}\n", message).unwrap();
})));
}
let tree = parser
.parse_str(&source_code, None)
.expect("Incompatible language version");
if let Some(log_session) = log_session {
util::stop_logging_graphs(&mut parser, log_session)?;
}
let stdout = io::stdout();
let mut stdout = stdout.lock();
let mut cursor = tree.walk();
let mut needs_newline = false;
let mut indent_level = 0;
let mut did_visit_children = false;
loop {
let node = cursor.node();
let is_named = node.is_named();
if did_visit_children {
if is_named {
stdout.write(b")")?;
needs_newline = true;
}
if cursor.goto_next_sibling() {
did_visit_children = false;
} else if cursor.goto_parent() {
did_visit_children = true;
indent_level -= 1;
} else {
break;
}
} else {
if is_named {
if needs_newline {
stdout.write(b"\n")?;
}
for _ in 0..indent_level {
stdout.write(b" ")?;
}
let start = node.start_position();
let end = node.end_position();
write!(
&mut stdout,
"({} [{}, {}] - [{}, {}]",
node.kind(),
start.row,
start.column,
end.row,
end.column
)?;
needs_newline = true;
}
if cursor.goto_first_child() {
did_visit_children = false;
indent_level += 1;
} else {
did_visit_children = true;
}
}
}
println!("");
Ok(())
}