kill utils module

This commit is contained in:
Aleksey Kladov 2019-02-21 15:51:22 +03:00
parent 9be7426aae
commit f7f99af0a6
10 changed files with 101 additions and 114 deletions

View file

@ -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<SyntaxError>) -> TreeArc<SourceFile> {
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();
}

View file

@ -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<F>(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(),
)
}

View file

@ -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 {

View file

@ -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(),
);
}
}
_ => (),
}
}
}

View file

@ -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<SyntaxError> {
let mut errors = Vec::new();
for node in file.syntax().descendants() {
let _ = visitor_ctx(&mut errors)
.visit::<ast::Byte, _>(self::byte::validate_byte_node)
.visit::<ast::ByteString, _>(self::byte_string::validate_byte_string_node)
.visit::<ast::Char, _>(self::char::validate_char_node)
.visit::<ast::String, _>(self::string::validate_string_node)
.visit::<ast::Block, _>(self::block::validate_block_node)
.visit::<ast::Byte, _>(byte::validate_byte_node)
.visit::<ast::ByteString, _>(byte_string::validate_byte_string_node)
.visit::<ast::Char, _>(char::validate_char_node)
.visit::<ast::String, _>(string::validate_string_node)
.visit::<ast::Block, _>(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(),
);
}
}
_ => (),
}
}
}