From 20fcffb393fdeac8f09ec42b7d6433dee68b4aaf Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 7 Jan 2019 17:57:36 -0800 Subject: [PATCH] Add parse subcommand Co-Authored-By: Timothy Clem --- cli/src/main.rs | 9 +++++++ cli/src/parse.rs | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 cli/src/parse.rs diff --git a/cli/src/main.rs b/cli/src/main.rs index 87f9e26d..6a0cf9ec 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -86,6 +86,15 @@ fn run() -> error::Result<()> { eprintln!("No language found"); } } + + if let Some(matches) = matches.subcommand_matches("parse") { + loader.find_parsers(&vec![home_dir.join("github")])?; + let source_path = Path::new(matches.value_of("path").unwrap()); + if let Some((language, _)) = loader.language_for_file_name(source_path)? { + parse::parse_file_at_path(language, source_path)?; + } else { + eprintln!("No language found"); + } } Ok(()) diff --git a/cli/src/parse.rs b/cli/src/parse.rs new file mode 100644 index 00000000..26fe9b9a --- /dev/null +++ b/cli/src/parse.rs @@ -0,0 +1,69 @@ +use super::error::Result; +use std::fs; +use std::path::Path; +use tree_sitter::{Language, Parser}; +use std::io::{self, Write}; + +pub fn parse_file_at_path(language: Language, path: &Path) -> Result<()> { + let mut parser = Parser::new(); + parser.set_language(language)?; + let source_code = fs::read_to_string(path)?; + let tree = parser + .parse_str(&source_code, None) + .expect("Incompatible language version"); + + 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(()) +}