diff options
author | Aleksey Kladov <[email protected]> | 2018-09-08 16:34:41 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-09-08 16:34:41 +0100 |
commit | ba4a697d8cb577c03c84c0c91a25ecbeaa9c68e6 (patch) | |
tree | 8967481740bf2f7c097a056544cf5ef76d076ac3 /crates/libsyntax2 | |
parent | a60b9ad963db87c6431de7a9b57e0d2241efdeab (diff) |
move fuzz-invariants to the library
Diffstat (limited to 'crates/libsyntax2')
-rw-r--r-- | crates/libsyntax2/fuzz/fuzz_targets/parser.rs | 5 | ||||
-rw-r--r-- | crates/libsyntax2/src/lib.rs | 38 | ||||
-rw-r--r-- | crates/libsyntax2/src/utils.rs | 42 |
3 files changed, 44 insertions, 41 deletions
diff --git a/crates/libsyntax2/fuzz/fuzz_targets/parser.rs b/crates/libsyntax2/fuzz/fuzz_targets/parser.rs index f941855e8..da87180bb 100644 --- a/crates/libsyntax2/fuzz/fuzz_targets/parser.rs +++ b/crates/libsyntax2/fuzz/fuzz_targets/parser.rs | |||
@@ -4,9 +4,6 @@ extern crate libsyntax2; | |||
4 | 4 | ||
5 | fuzz_target!(|data: &[u8]| { | 5 | fuzz_target!(|data: &[u8]| { |
6 | if let Ok(text) = std::str::from_utf8(data) { | 6 | if let Ok(text) = std::str::from_utf8(data) { |
7 | let x = libsyntax2::File::parse(text); | 7 | libsyntax2::utils::check_fuzz_invariants(text) |
8 | let _ = x.ast(); | ||
9 | let _ = x.syntax(); | ||
10 | let _ = x.errors(); | ||
11 | } | 8 | } |
12 | }); | 9 | }); |
diff --git a/crates/libsyntax2/src/lib.rs b/crates/libsyntax2/src/lib.rs index 7a30f5d38..d955c01e7 100644 --- a/crates/libsyntax2/src/lib.rs +++ b/crates/libsyntax2/src/lib.rs | |||
@@ -66,7 +66,9 @@ impl File { | |||
66 | fn new(green: GreenNode, errors: Vec<SyntaxError>) -> File { | 66 | fn new(green: GreenNode, errors: Vec<SyntaxError>) -> File { |
67 | let root = SyntaxRoot::new(green, errors); | 67 | let root = SyntaxRoot::new(green, errors); |
68 | let root = SyntaxNode::new_owned(root); | 68 | let root = SyntaxNode::new_owned(root); |
69 | validate_block_structure(root.borrowed()); | 69 | if cfg!(debug_assertions) { |
70 | utils::validate_block_structure(root.borrowed()); | ||
71 | } | ||
70 | File { root } | 72 | File { root } |
71 | } | 73 | } |
72 | pub fn parse(text: &str) -> File { | 74 | pub fn parse(text: &str) -> File { |
@@ -112,40 +114,6 @@ impl File { | |||
112 | } | 114 | } |
113 | } | 115 | } |
114 | 116 | ||
115 | #[cfg(not(debug_assertions))] | ||
116 | fn validate_block_structure(_: SyntaxNodeRef) {} | ||
117 | |||
118 | #[cfg(debug_assertions)] | ||
119 | fn validate_block_structure(root: SyntaxNodeRef) { | ||
120 | let mut stack = Vec::new(); | ||
121 | for node in algo::walk::preorder(root) { | ||
122 | match node.kind() { | ||
123 | SyntaxKind::L_CURLY => { | ||
124 | stack.push(node) | ||
125 | } | ||
126 | SyntaxKind::R_CURLY => { | ||
127 | if let Some(pair) = stack.pop() { | ||
128 | assert_eq!( | ||
129 | node.parent(), | ||
130 | pair.parent(), | ||
131 | "\nunpaired curleys:\n{}\n{}\n", | ||
132 | root.text(), | ||
133 | utils::dump_tree(root), | ||
134 | ); | ||
135 | assert!( | ||
136 | node.next_sibling().is_none() && pair.prev_sibling().is_none(), | ||
137 | "\nfloating curlys at {:?}\nfile:\n{}\nerror:\n{}\n", | ||
138 | node, | ||
139 | root.text(), | ||
140 | node.text(), | ||
141 | ); | ||
142 | } | ||
143 | } | ||
144 | _ => (), | ||
145 | } | ||
146 | } | ||
147 | } | ||
148 | |||
149 | #[derive(Debug, Clone)] | 117 | #[derive(Debug, Clone)] |
150 | pub struct AtomEdit { | 118 | pub struct AtomEdit { |
151 | pub delete: TextRange, | 119 | pub delete: TextRange, |
diff --git a/crates/libsyntax2/src/utils.rs b/crates/libsyntax2/src/utils.rs index fbe48dd71..671dd7afa 100644 --- a/crates/libsyntax2/src/utils.rs +++ b/crates/libsyntax2/src/utils.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use std::fmt::Write; | 1 | use std::fmt::Write; |
2 | use { | 2 | use { |
3 | algo::walk::{walk, WalkEvent}, | 3 | algo::walk::{preorder, walk, WalkEvent}, |
4 | SyntaxNodeRef, TreeRoot, | 4 | SyntaxKind, File, SyntaxNodeRef, TreeRoot, |
5 | }; | 5 | }; |
6 | 6 | ||
7 | /// Parse a file and create a string representation of the resulting parse tree. | 7 | /// Parse a file and create a string representation of the resulting parse tree. |
@@ -45,3 +45,41 @@ pub fn dump_tree(syntax: SyntaxNodeRef) -> String { | |||
45 | 45 | ||
46 | return buf; | 46 | return buf; |
47 | } | 47 | } |
48 | |||
49 | pub fn check_fuzz_invariants(text: &str) { | ||
50 | let file = File::parse(text); | ||
51 | let root = file.syntax(); | ||
52 | validate_block_structure(root); | ||
53 | let _ = file.ast(); | ||
54 | let _ = file.errors(); | ||
55 | } | ||
56 | |||
57 | pub(crate) fn validate_block_structure(root: SyntaxNodeRef) { | ||
58 | let mut stack = Vec::new(); | ||
59 | for node in preorder(root) { | ||
60 | match node.kind() { | ||
61 | SyntaxKind::L_CURLY => { | ||
62 | stack.push(node) | ||
63 | } | ||
64 | SyntaxKind::R_CURLY => { | ||
65 | if let Some(pair) = stack.pop() { | ||
66 | assert_eq!( | ||
67 | node.parent(), | ||
68 | pair.parent(), | ||
69 | "\nunpaired curleys:\n{}\n{}\n", | ||
70 | root.text(), | ||
71 | dump_tree(root), | ||
72 | ); | ||
73 | assert!( | ||
74 | node.next_sibling().is_none() && pair.prev_sibling().is_none(), | ||
75 | "\nfloating curlys at {:?}\nfile:\n{}\nerror:\n{}\n", | ||
76 | node, | ||
77 | root.text(), | ||
78 | node.text(), | ||
79 | ); | ||
80 | } | ||
81 | } | ||
82 | _ => (), | ||
83 | } | ||
84 | } | ||
85 | } | ||