remove old parsing methods

This commit is contained in:
Aleksey Kladov 2019-05-28 17:34:28 +03:00
parent 310bfe57bd
commit 0efbcdf435
7 changed files with 54 additions and 62 deletions

View file

@ -80,7 +80,9 @@ fn test_doc_comment_none() {
// non-doc
mod foo {}
"#,
);
)
.ok()
.unwrap();
let module = file.syntax().descendants().find_map(Module::cast).unwrap();
assert!(module.doc_comment_text().is_none());
}
@ -93,7 +95,9 @@ fn test_doc_comment_of_items() {
// non-doc
mod foo {}
"#,
);
)
.ok()
.unwrap();
let module = file.syntax().descendants().find_map(Module::cast).unwrap();
assert_eq!("doc", module.doc_comment_text().unwrap());
}
@ -110,7 +114,9 @@ fn test_doc_comment_preserves_indents() {
/// ```
mod foo {}
"#,
);
)
.ok()
.unwrap();
let module = file.syntax().descendants().find_map(Module::cast).unwrap();
assert_eq!("doc1\n```\nfn foo() {\n // ...\n}\n```", module.doc_comment_text().unwrap());
}
@ -133,7 +139,9 @@ where
for<'a> F: Fn(&'a str)
{}
"#,
);
)
.ok()
.unwrap();
let where_clause = file.syntax().descendants().find_map(WhereClause::cast).unwrap();
let mut predicates = where_clause.predicates();

View file

@ -5,12 +5,11 @@ use std::str::{self, FromStr};
fn check_file_invariants(file: &SourceFile) {
let root = file.syntax();
validation::validate_block_structure(root);
let _ = file.errors();
}
pub fn check_parser(text: &str) {
let file = SourceFile::parse(text);
check_file_invariants(&file);
check_file_invariants(&file.tree);
}
#[derive(Debug, Clone)]
@ -44,16 +43,18 @@ impl CheckReparse {
}
pub fn run(&self) {
let file = SourceFile::parse(&self.text);
let new_file = file.reparse(&self.edit);
check_file_invariants(&new_file);
assert_eq!(&new_file.syntax().text().to_string(), &self.edited_text);
let parse = SourceFile::parse(&self.text);
let new_parse = parse.reparse(&self.edit);
check_file_invariants(&new_parse.tree);
assert_eq!(&new_parse.tree.syntax().text().to_string(), &self.edited_text);
let full_reparse = SourceFile::parse(&self.edited_text);
for (a, b) in new_file.syntax().descendants().zip(full_reparse.syntax().descendants()) {
for (a, b) in
new_parse.tree.syntax().descendants().zip(full_reparse.tree.syntax().descendants())
{
if (a.kind(), a.range()) != (b.kind(), b.range()) {
eprint!("original:\n{}", file.syntax().debug_dump());
eprint!("reparsed:\n{}", new_file.syntax().debug_dump());
eprint!("full reparse:\n{}", full_reparse.syntax().debug_dump());
eprint!("original:\n{}", parse.tree.syntax().debug_dump());
eprint!("reparsed:\n{}", new_parse.tree.syntax().debug_dump());
eprint!("full reparse:\n{}", full_reparse.tree.syntax().debug_dump());
assert_eq!(
format!("{:?}", a),
format!("{:?}", b),

View file

@ -69,6 +69,10 @@ impl Parse {
}
}
pub fn reparse(&self, edit: &AtomTextEdit) -> Parse {
self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit))
}
pub fn debug_dump(&self) -> String {
let mut buf = self.tree.syntax().debug_dump();
for err in self.errors.iter() {
@ -76,6 +80,21 @@ impl Parse {
}
buf
}
fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option<Parse> {
// FIXME: validation errors are not handled here
parsing::incremental_reparse(self.tree.syntax(), edit, self.errors.to_vec()).map(
|(green_node, errors, _reparsed_range)| Parse {
tree: SourceFile::new(green_node),
errors: Arc::new(errors),
},
)
}
fn full_reparse(&self, edit: &AtomTextEdit) -> Parse {
let text = edit.apply(self.tree.syntax().text().to_string());
SourceFile::parse(&text)
}
}
/// `SourceFile` represents a parse tree for a single Rust file.
@ -91,37 +110,12 @@ impl SourceFile {
TreeArc::cast(root)
}
pub fn parse2(text: &str) -> Parse {
pub fn parse(text: &str) -> Parse {
let (green, mut errors) = parsing::parse_text(text);
let tree = SourceFile::new(green);
errors.extend(validation::validate(&tree));
Parse { tree, errors: Arc::new(errors) }
}
pub fn parse(text: &str) -> TreeArc<SourceFile> {
let (green, _errors) = parsing::parse_text(text);
SourceFile::new(green)
}
pub fn reparse(&self, edit: &AtomTextEdit) -> TreeArc<SourceFile> {
self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit))
}
pub fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option<TreeArc<SourceFile>> {
parsing::incremental_reparse(self.syntax(), edit, self.errors())
.map(|(green_node, _errors, _reparsed_range)| SourceFile::new(green_node))
}
fn full_reparse(&self, edit: &AtomTextEdit) -> TreeArc<SourceFile> {
let text = edit.apply(self.syntax().text().to_string());
SourceFile::parse(&text)
}
pub fn errors(&self) -> Vec<SyntaxError> {
let mut errors = self.syntax.root_data().to_vec();
errors.extend(validation::validate(self));
errors
}
}
/// This test does not assert anything and instead just shows off the crate's
@ -137,14 +131,15 @@ fn api_walkthrough() {
";
// `SourceFile` is the main entry point.
//
// Note how `parse` does not return a `Result`: even completely invalid
// source code might be parsed.
let file = SourceFile::parse(source_code);
// The `parse` method returns a `Parse` -- a pair of syntax tree and a list
// of errors. That is, syntax tree is constructed even in presence of errors.
let parse = SourceFile::parse(source_code);
assert!(parse.errors.is_empty());
// Due to the way ownership is set up, owned syntax Nodes always live behind
// a `TreeArc` smart pointer. `TreeArc` is roughly an `std::sync::Arc` which
// points to the whole file instead of an individual node.
let file: TreeArc<SourceFile> = file;
let file: TreeArc<SourceFile> = parse.tree;
// `SourceFile` is the root of the syntax tree. We can iterate file's items:
let mut func = None;

View file

@ -178,12 +178,12 @@ mod tests {
let edit = AtomTextEdit::replace(range, replace_with.to_owned());
let after = edit.apply(before.clone());
let fully_reparsed = SourceFile::parse2(&after);
let fully_reparsed = SourceFile::parse(&after);
let incrementally_reparsed = {
let f = SourceFile::parse(&before);
let edit = AtomTextEdit { delete: range, insert: replace_with.to_string() };
let (green, new_errors, range) =
incremental_reparse(f.syntax(), &edit, f.errors()).unwrap();
incremental_reparse(f.tree.syntax(), &edit, f.errors.to_vec()).unwrap();
assert_eq!(range.len(), reparsed_len.into(), "reparsed fragment has wrong length");
Parse { tree: SourceFile::new(green), errors: Arc::new(new_errors) }
};

View file

@ -76,7 +76,7 @@ impl<N: AstNode> From<AstPtr<N>> for SyntaxNodePtr {
fn test_local_syntax_ptr() {
use crate::{ast, AstNode, SourceFile};
let file = SourceFile::parse("struct Foo { f: u32, }");
let file = SourceFile::parse("struct Foo { f: u32, }").ok().unwrap();
let field = file.syntax().descendants().find_map(ast::NamedFieldDef::cast).unwrap();
let ptr = SyntaxNodePtr::new(field.syntax());
let field_syntax = ptr.to_node(file.syntax());

View file

@ -280,16 +280,6 @@ impl SyntaxNode {
buf
}
pub(crate) fn root_data(&self) -> &[SyntaxError] {
match self.0.root_data() {
None => &[],
Some(data) => {
let data: &Vec<SyntaxError> = std::any::Any::downcast_ref(data).unwrap();
data.as_slice()
}
}
}
pub(crate) fn replace_with(&self, replacement: GreenNode) -> GreenNode {
self.0.replace_with(replacement)
}

View file

@ -21,7 +21,7 @@ fn lexer_tests() {
#[test]
fn parser_tests() {
dir_tests(&test_data_dir(), &["parser/inline/ok", "parser/ok"], |text, path| {
let parse = SourceFile::parse2(text);
let parse = SourceFile::parse(text);
let errors = parse.errors.as_slice();
assert_eq!(
errors,
@ -32,7 +32,7 @@ fn parser_tests() {
parse.debug_dump()
});
dir_tests(&test_data_dir(), &["parser/err", "parser/inline/err"], |text, path| {
let parse = SourceFile::parse2(text);
let parse = SourceFile::parse(text);
let errors = parse.errors.as_slice();
assert!(!errors.is_empty(), "There should be errors in the file {:?}", path.display());
parse.debug_dump()
@ -78,9 +78,7 @@ fn self_hosting_parsing() {
{
count += 1;
let text = read_text(entry.path());
let node = SourceFile::parse(&text);
let errors = node.errors();
assert_eq!(&*errors, &[], "There should be no errors in the file {:?}", entry);
SourceFile::parse(&text).ok().expect("There should be no errors in the file");
}
assert!(
count > 30,