From f7f99af0a60ff80097377c1a041bcdeaf33c38de Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 Feb 2019 15:51:22 +0300 Subject: kill utils module --- 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 +-- 7 files changed, 96 insertions(+), 104 deletions(-) delete mode 100644 crates/ra_syntax/src/utils.rs (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/fuzz/fuzz_targets/parser.rs b/crates/ra_syntax/fuzz/fuzz_targets/parser.rs index 396c0ecaf..4667d5579 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 6982b9815..dc4b779e8 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 6957c26c0..19d8adcfb 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 a1bc0b499..1ca1c992b 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 2e1b42da0..000000000 --- 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 69958f0d7..69f344d65 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 168d0623d..458740c13 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() }); } -- cgit v1.2.3 From b51b71bf258c6520ee60f865a3658b30ce44ef18 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 Feb 2019 16:04:03 +0300 Subject: rearrange methods --- crates/ra_syntax/src/syntax_node.rs | 134 ++++++++++++++++++------------------ 1 file changed, 67 insertions(+), 67 deletions(-) (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/src/syntax_node.rs b/crates/ra_syntax/src/syntax_node.rs index 1ca1c992b..bcfacde72 100644 --- a/crates/ra_syntax/src/syntax_node.rs +++ b/crates/ra_syntax/src/syntax_node.rs @@ -96,13 +96,24 @@ unsafe impl TransparentNewType for SyntaxNode { type Repr = rowan::SyntaxNode; } -impl SyntaxNode { - pub(crate) fn new(green: GreenNode, errors: Vec) -> TreeArc { - let ptr = TreeArc(rowan::SyntaxNode::new(green, errors)); +impl ToOwned for SyntaxNode { + type Owned = TreeArc; + fn to_owned(&self) -> TreeArc { + let ptr = TreeArc(self.0.to_owned()); TreeArc::cast(ptr) } } +impl fmt::Debug for SyntaxNode { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "{:?}@{:?}", self.kind(), self.range())?; + if has_short_text(self.kind()) { + write!(fmt, " \"{}\"", self.text())?; + } + Ok(()) + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Direction { Next, @@ -110,24 +121,73 @@ pub enum Direction { } impl SyntaxNode { + pub(crate) fn new(green: GreenNode, errors: Vec) -> TreeArc { + let ptr = TreeArc(rowan::SyntaxNode::new(green, errors)); + TreeArc::cast(ptr) + } + + pub fn kind(&self) -> SyntaxKind { + self.0.kind() + } + + pub fn range(&self) -> TextRange { + self.0.range() + } + + pub fn text(&self) -> SyntaxText { + SyntaxText::new(self) + } + + pub fn is_leaf(&self) -> bool { + self.0.is_leaf() + } + pub fn leaf_text(&self) -> Option<&SmolStr> { self.0.leaf_text() } + + pub fn parent(&self) -> Option<&SyntaxNode> { + self.0.parent().map(SyntaxNode::from_repr) + } + + pub fn first_child(&self) -> Option<&SyntaxNode> { + self.0.first_child().map(SyntaxNode::from_repr) + } + + pub fn last_child(&self) -> Option<&SyntaxNode> { + self.0.last_child().map(SyntaxNode::from_repr) + } + + pub fn next_sibling(&self) -> Option<&SyntaxNode> { + self.0.next_sibling().map(SyntaxNode::from_repr) + } + + pub fn prev_sibling(&self) -> Option<&SyntaxNode> { + self.0.prev_sibling().map(SyntaxNode::from_repr) + } + + pub fn children(&self) -> SyntaxNodeChildren { + SyntaxNodeChildren(self.0.children()) + } + pub fn ancestors(&self) -> impl Iterator { crate::algo::generate(Some(self), |&node| node.parent()) } + pub fn descendants(&self) -> impl Iterator { self.preorder().filter_map(|event| match event { WalkEvent::Enter(node) => Some(node), WalkEvent::Leave(_) => None, }) } + pub fn siblings(&self, direction: Direction) -> impl Iterator { crate::algo::generate(Some(self), move |&node| match direction { Direction::Next => node.next_sibling(), Direction::Prev => node.prev_sibling(), }) } + pub fn preorder(&self) -> impl Iterator> { self.0.preorder().map(|event| match event { WalkEvent::Enter(n) => WalkEvent::Enter(SyntaxNode::from_repr(n)), @@ -135,6 +195,10 @@ impl SyntaxNode { }) } + pub fn memory_size_of_subtree(&self) -> usize { + self.0.memory_size_of_subtree() + } + pub fn debug_dump(&self) -> String { let mut errors: Vec<_> = match self.ancestors().find_map(SourceFile::cast) { Some(file) => file.errors(), @@ -178,17 +242,7 @@ impl SyntaxNode { buf } -} -impl ToOwned for SyntaxNode { - type Owned = TreeArc; - fn to_owned(&self) -> TreeArc { - let ptr = TreeArc(self.0.to_owned()); - TreeArc::cast(ptr) - } -} - -impl SyntaxNode { pub(crate) fn root_data(&self) -> &Vec { self.0.root_data() } @@ -196,60 +250,6 @@ impl SyntaxNode { pub(crate) fn replace_with(&self, replacement: GreenNode) -> GreenNode { self.0.replace_self(replacement) } - - pub fn kind(&self) -> SyntaxKind { - self.0.kind() - } - - pub fn range(&self) -> TextRange { - self.0.range() - } - - pub fn text(&self) -> SyntaxText { - SyntaxText::new(self) - } - - pub fn is_leaf(&self) -> bool { - self.0.is_leaf() - } - - pub fn parent(&self) -> Option<&SyntaxNode> { - self.0.parent().map(SyntaxNode::from_repr) - } - - pub fn first_child(&self) -> Option<&SyntaxNode> { - self.0.first_child().map(SyntaxNode::from_repr) - } - - pub fn last_child(&self) -> Option<&SyntaxNode> { - self.0.last_child().map(SyntaxNode::from_repr) - } - - pub fn next_sibling(&self) -> Option<&SyntaxNode> { - self.0.next_sibling().map(SyntaxNode::from_repr) - } - - pub fn prev_sibling(&self) -> Option<&SyntaxNode> { - self.0.prev_sibling().map(SyntaxNode::from_repr) - } - - pub fn children(&self) -> SyntaxNodeChildren { - SyntaxNodeChildren(self.0.children()) - } - - pub fn memory_size_of_subtree(&self) -> usize { - self.0.memory_size_of_subtree() - } -} - -impl fmt::Debug for SyntaxNode { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "{:?}@{:?}", self.kind(), self.range())?; - if has_short_text(self.kind()) { - write!(fmt, " \"{}\"", self.text())?; - } - Ok(()) - } } #[derive(Debug)] -- cgit v1.2.3 From 7060a39d5c8dc2c72fe207536fee649ff615860f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 Feb 2019 16:12:15 +0300 Subject: simplify trait bounds --- crates/ra_syntax/src/syntax_node.rs | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/src/syntax_node.rs b/crates/ra_syntax/src/syntax_node.rs index bcfacde72..4d54ae614 100644 --- a/crates/ra_syntax/src/syntax_node.rs +++ b/crates/ra_syntax/src/syntax_node.rs @@ -6,7 +6,10 @@ //! The *real* implementation is in the (language-agnostic) `rowan` crate, this //! modules just wraps its API. -use std::{fmt::{self, Write}, borrow::Borrow}; +use std::{ + fmt::{self, Write}, + borrow::Borrow, +}; use rowan::{Types, TransparentNewType}; @@ -24,14 +27,17 @@ impl Types for RaTypes { type RootData = Vec; } -pub type GreenNode = rowan::GreenNode; +pub(crate) type GreenNode = rowan::GreenNode; + +/// Marker trait for CST and AST nodes +pub trait SyntaxNodeWrapper: TransparentNewType> {} +impl>> SyntaxNodeWrapper for T {} +/// An owning smart pointer for CST or AST node. #[derive(PartialEq, Eq, Hash)] -pub struct TreeArc>>( - pub(crate) rowan::TreeArc, -); +pub struct TreeArc(pub(crate) rowan::TreeArc); -impl>> Borrow for TreeArc { +impl Borrow for TreeArc { fn borrow(&self) -> &T { &*self } @@ -39,11 +45,11 @@ impl>> Borrow for Tre impl TreeArc where - T: TransparentNewType>, + T: SyntaxNodeWrapper, { pub(crate) fn cast(this: TreeArc) -> TreeArc where - U: TransparentNewType>, + U: SyntaxNodeWrapper, { TreeArc(rowan::TreeArc::cast(this.0)) } @@ -51,7 +57,7 @@ where impl std::ops::Deref for TreeArc where - T: TransparentNewType>, + T: SyntaxNodeWrapper, { type Target = T; fn deref(&self) -> &T { @@ -61,7 +67,7 @@ where impl PartialEq for TreeArc where - T: TransparentNewType>, + T: SyntaxNodeWrapper, T: PartialEq, { fn eq(&self, other: &T) -> bool { @@ -72,7 +78,7 @@ where impl Clone for TreeArc where - T: TransparentNewType>, + T: SyntaxNodeWrapper, { fn clone(&self) -> TreeArc { TreeArc(self.0.clone()) @@ -81,7 +87,7 @@ where impl fmt::Debug for TreeArc where - T: TransparentNewType>, + T: SyntaxNodeWrapper, T: fmt::Debug, { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { -- cgit v1.2.3