From f7f99af0a60ff80097377c1a041bcdeaf33c38de Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 Feb 2019 15:51:22 +0300 Subject: [PATCH] kill utils module --- crates/ra_cli/src/main.rs | 6 +- crates/ra_ide_api/src/lib.rs | 5 +- crates/ra_ide_api_light/src/lib.rs | 4 - crates/ra_syntax/fuzz/fuzz_targets/parser.rs | 2 +- crates/ra_syntax/src/lib.rs | 11 ++- crates/ra_syntax/src/parsing/reparsing.rs | 6 +- crates/ra_syntax/src/syntax_node.rs | 48 ++++++++++- crates/ra_syntax/src/utils.rs | 83 -------------------- crates/ra_syntax/src/validation.rs | 41 ++++++++-- crates/ra_syntax/tests/test.rs | 9 +-- 10 files changed, 101 insertions(+), 114 deletions(-) delete mode 100644 crates/ra_syntax/src/utils.rs diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs index 72e6ae4d521..294f4b8af78 100644 --- a/crates/ra_cli/src/main.rs +++ b/crates/ra_cli/src/main.rs @@ -4,7 +4,7 @@ use std::{fs, io::Read, path::Path, time::Instant}; use clap::{App, Arg, SubCommand}; use join_to_string::join; -use ra_ide_api_light::{extend_selection, file_structure, syntax_tree}; +use ra_ide_api_light::{extend_selection, file_structure}; use ra_syntax::{SourceFile, TextRange, TreeArc, AstNode}; use tools::collect_tests; use flexi_logger::Logger; @@ -37,7 +37,7 @@ fn main() -> Result<()> { let file = file()?; let elapsed = start.elapsed(); if !matches.is_present("no-dump") { - println!("{}", syntax_tree(&file)); + println!("{}", file.syntax().debug_dump()); } eprintln!("parsing: {:?}", elapsed); ::std::mem::forget(file); @@ -94,7 +94,7 @@ fn render_test(file: &Path, line: usize) -> Result<(String, String)> { Some((_start_line, test)) => test, }; let file = SourceFile::parse(&test.text); - let tree = syntax_tree(&file); + let tree = file.syntax().debug_dump(); Ok((test.text, tree)) } diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 57a490fa75a..4b9fc9372e5 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs @@ -38,7 +38,7 @@ mod marks; use std::sync::Arc; -use ra_syntax::{SourceFile, TreeArc, TextRange, TextUnit}; +use ra_syntax::{SourceFile, TreeArc, TextRange, TextUnit, AstNode}; use ra_text_edit::TextEdit; use ra_db::{ SourceDatabase, CheckCanceled, @@ -244,8 +244,7 @@ impl Analysis { /// Returns a syntax tree represented as `String`, for debug purposes. // FIXME: use a better name here. pub fn syntax_tree(&self, file_id: FileId) -> String { - let file = self.db.parse(file_id); - ra_ide_api_light::syntax_tree(&file) + self.db.parse(file_id).syntax().debug_dump() } /// Returns an edit to remove all newlines in the range, cleaning up minor diff --git a/crates/ra_ide_api_light/src/lib.rs b/crates/ra_ide_api_light/src/lib.rs index 6d1ce8dbfb6..43cdd6ea4dd 100644 --- a/crates/ra_ide_api_light/src/lib.rs +++ b/crates/ra_ide_api_light/src/lib.rs @@ -123,10 +123,6 @@ pub fn highlight(root: &SyntaxNode) -> Vec { res } -pub fn syntax_tree(file: &SourceFile) -> String { - ::ra_syntax::utils::dump_tree(file.syntax()) -} - #[cfg(test)] mod tests { use ra_syntax::AstNode; diff --git a/crates/ra_syntax/fuzz/fuzz_targets/parser.rs b/crates/ra_syntax/fuzz/fuzz_targets/parser.rs index 396c0ecaf31..4667d5579fe 100644 --- a/crates/ra_syntax/fuzz/fuzz_targets/parser.rs +++ b/crates/ra_syntax/fuzz/fuzz_targets/parser.rs @@ -4,6 +4,6 @@ extern crate ra_syntax; fuzz_target!(|data: &[u8]| { if let Ok(text) = std::str::from_utf8(data) { - ra_syntax::utils::check_fuzz_invariants(text) + ra_syntax::check_fuzz_invariants(text) } }); diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index 6982b98150f..dc4b779e82f 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs @@ -27,8 +27,6 @@ mod ptr; pub mod algo; pub mod ast; -/// Utilities for simple uses of the parser. -pub mod utils; pub use rowan::{SmolStr, TextRange, TextUnit}; pub use ra_parser::SyntaxKind; @@ -51,7 +49,7 @@ impl SourceFile { fn new(green: GreenNode, errors: Vec) -> TreeArc { let root = SyntaxNode::new(green, errors); if cfg!(debug_assertions) { - utils::validate_block_structure(&root); + validation::validate_block_structure(&root); } assert_eq!(root.kind(), SyntaxKind::SOURCE_FILE); TreeArc::cast(root) @@ -82,3 +80,10 @@ impl SourceFile { errors } } + +pub fn check_fuzz_invariants(text: &str) { + let file = SourceFile::parse(text); + let root = file.syntax(); + validation::validate_block_structure(root); + let _ = file.errors(); +} diff --git a/crates/ra_syntax/src/parsing/reparsing.rs b/crates/ra_syntax/src/parsing/reparsing.rs index 6957c26c0e9..19d8adcfb37 100644 --- a/crates/ra_syntax/src/parsing/reparsing.rs +++ b/crates/ra_syntax/src/parsing/reparsing.rs @@ -143,7 +143,7 @@ fn merge_errors( mod tests { use test_utils::{extract_range, assert_eq_text}; - use crate::{SourceFile, AstNode, utils::dump_tree}; + use crate::{SourceFile, AstNode}; use super::*; fn do_check(before: &str, replace_with: &str, reparser: F) @@ -169,8 +169,8 @@ mod tests { }; assert_eq_text!( - &dump_tree(fully_reparsed.syntax()), - &dump_tree(incrementally_reparsed.syntax()), + &fully_reparsed.syntax().debug_dump(), + &incrementally_reparsed.syntax().debug_dump(), ) } diff --git a/crates/ra_syntax/src/syntax_node.rs b/crates/ra_syntax/src/syntax_node.rs index a1bc0b49946..1ca1c992bef 100644 --- a/crates/ra_syntax/src/syntax_node.rs +++ b/crates/ra_syntax/src/syntax_node.rs @@ -6,12 +6,12 @@ //! The *real* implementation is in the (language-agnostic) `rowan` crate, this //! modules just wraps its API. -use std::{fmt, borrow::Borrow}; +use std::{fmt::{self, Write}, borrow::Borrow}; use rowan::{Types, TransparentNewType}; use crate::{ - SmolStr, SyntaxKind, TextRange, SyntaxText, + SmolStr, SyntaxKind, TextRange, SyntaxText, SourceFile, AstNode, syntax_error::SyntaxError, }; @@ -134,6 +134,50 @@ impl SyntaxNode { WalkEvent::Leave(n) => WalkEvent::Leave(SyntaxNode::from_repr(n)), }) } + + pub fn debug_dump(&self) -> String { + let mut errors: Vec<_> = match self.ancestors().find_map(SourceFile::cast) { + Some(file) => file.errors(), + None => self.root_data().to_vec(), + }; + errors.sort_by_key(|e| e.offset()); + let mut err_pos = 0; + let mut level = 0; + let mut buf = String::new(); + macro_rules! indent { + () => { + for _ in 0..level { + buf.push_str(" "); + } + }; + } + + for event in self.preorder() { + match event { + WalkEvent::Enter(node) => { + indent!(); + writeln!(buf, "{:?}", node).unwrap(); + if node.first_child().is_none() { + let off = node.range().end(); + while err_pos < errors.len() && errors[err_pos].offset() <= off { + indent!(); + writeln!(buf, "err: `{}`", errors[err_pos]).unwrap(); + err_pos += 1; + } + } + level += 1; + } + WalkEvent::Leave(_) => level -= 1, + } + } + + assert_eq!(level, 0); + for err in errors[err_pos..].iter() { + writeln!(buf, "err: `{}`", err).unwrap(); + } + + buf + } } impl ToOwned for SyntaxNode { diff --git a/crates/ra_syntax/src/utils.rs b/crates/ra_syntax/src/utils.rs deleted file mode 100644 index 2e1b42da0f6..00000000000 --- a/crates/ra_syntax/src/utils.rs +++ /dev/null @@ -1,83 +0,0 @@ -use std::{str, fmt::Write}; - -use crate::{SourceFile, SyntaxKind, WalkEvent, AstNode, SyntaxNode}; - -/// Parse a file and create a string representation of the resulting parse tree. -pub fn dump_tree(syntax: &SyntaxNode) -> String { - let mut errors: Vec<_> = match syntax.ancestors().find_map(SourceFile::cast) { - Some(file) => file.errors(), - None => syntax.root_data().to_vec(), - }; - errors.sort_by_key(|e| e.offset()); - let mut err_pos = 0; - let mut level = 0; - let mut buf = String::new(); - macro_rules! indent { - () => { - for _ in 0..level { - buf.push_str(" "); - } - }; - } - - for event in syntax.preorder() { - match event { - WalkEvent::Enter(node) => { - indent!(); - writeln!(buf, "{:?}", node).unwrap(); - if node.first_child().is_none() { - let off = node.range().end(); - while err_pos < errors.len() && errors[err_pos].offset() <= off { - indent!(); - writeln!(buf, "err: `{}`", errors[err_pos]).unwrap(); - err_pos += 1; - } - } - level += 1; - } - WalkEvent::Leave(_) => level -= 1, - } - } - - assert_eq!(level, 0); - for err in errors[err_pos..].iter() { - writeln!(buf, "err: `{}`", err).unwrap(); - } - - buf -} - -pub fn check_fuzz_invariants(text: &str) { - let file = SourceFile::parse(text); - let root = file.syntax(); - validate_block_structure(root); - let _ = file.errors(); -} - -pub(crate) fn validate_block_structure(root: &SyntaxNode) { - let mut stack = Vec::new(); - for node in root.descendants() { - match node.kind() { - SyntaxKind::L_CURLY => stack.push(node), - SyntaxKind::R_CURLY => { - if let Some(pair) = stack.pop() { - assert_eq!( - node.parent(), - pair.parent(), - "\nunpaired curleys:\n{}\n{}\n", - root.text(), - dump_tree(root), - ); - assert!( - node.next_sibling().is_none() && pair.prev_sibling().is_none(), - "\nfloating curlys at {:?}\nfile:\n{}\nerror:\n{}\n", - node, - root.text(), - node.text(), - ); - } - } - _ => (), - } - } -} diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs index 69958f0d74f..69f344d6524 100644 --- a/crates/ra_syntax/src/validation.rs +++ b/crates/ra_syntax/src/validation.rs @@ -5,7 +5,8 @@ mod string; mod block; use crate::{ - SourceFile, SyntaxError, AstNode, + SourceFile, SyntaxError, AstNode, SyntaxNode, + SyntaxKind::{L_CURLY, R_CURLY}, ast, algo::visit::{visitor_ctx, VisitorCtx}, }; @@ -14,12 +15,40 @@ pub(crate) fn validate(file: &SourceFile) -> Vec { let mut errors = Vec::new(); for node in file.syntax().descendants() { let _ = visitor_ctx(&mut errors) - .visit::(self::byte::validate_byte_node) - .visit::(self::byte_string::validate_byte_string_node) - .visit::(self::char::validate_char_node) - .visit::(self::string::validate_string_node) - .visit::(self::block::validate_block_node) + .visit::(byte::validate_byte_node) + .visit::(byte_string::validate_byte_string_node) + .visit::(char::validate_char_node) + .visit::(string::validate_string_node) + .visit::(block::validate_block_node) .accept(node); } errors } + +pub(crate) fn validate_block_structure(root: &SyntaxNode) { + let mut stack = Vec::new(); + for node in root.descendants() { + match node.kind() { + L_CURLY => stack.push(node), + R_CURLY => { + if let Some(pair) = stack.pop() { + assert_eq!( + node.parent(), + pair.parent(), + "\nunpaired curleys:\n{}\n{}\n", + root.text(), + root.debug_dump(), + ); + assert!( + node.next_sibling().is_none() && pair.prev_sibling().is_none(), + "\nfloating curlys at {:?}\nfile:\n{}\nerror:\n{}\n", + node, + root.text(), + node.text(), + ); + } + } + _ => (), + } + } +} diff --git a/crates/ra_syntax/tests/test.rs b/crates/ra_syntax/tests/test.rs index 168d0623dc9..458740c138e 100644 --- a/crates/ra_syntax/tests/test.rs +++ b/crates/ra_syntax/tests/test.rs @@ -8,10 +8,7 @@ use std::{ }; use test_utils::{project_dir, dir_tests, read_text, collect_tests}; -use ra_syntax::{ - SourceFile, AstNode, - utils::{check_fuzz_invariants, dump_tree}, -}; +use ra_syntax::{SourceFile, AstNode, check_fuzz_invariants}; #[test] fn lexer_tests() { @@ -32,7 +29,7 @@ fn parser_tests() { "There should be no errors in the file {:?}", path.display() ); - dump_tree(file.syntax()) + file.syntax().debug_dump() }); dir_tests(&test_data_dir(), &["parser/err", "parser/inline/err"], |text, path| { let file = SourceFile::parse(text); @@ -43,7 +40,7 @@ fn parser_tests() { "There should be errors in the file {:?}", path.display() ); - dump_tree(file.syntax()) + file.syntax().debug_dump() }); }