diff --git a/Cargo.lock b/Cargo.lock index 677a9db1c8..f09cf98c88 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1100,6 +1100,7 @@ dependencies = [ "drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ra_parser 0.1.0", "ra_text_edit 0.1.0", "rowan 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "smol_str 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/crates/ra_parser/src/lib.rs b/crates/ra_parser/src/lib.rs index fbbac4c69b..7931b5189f 100644 --- a/crates/ra_parser/src/lib.rs +++ b/crates/ra_parser/src/lib.rs @@ -53,12 +53,12 @@ impl Reparser { ) -> Option { grammar::reparser(node, first_child, parent).map(Reparser) } -} -pub fn reparse(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink, reparser: Reparser) { - let Reparser(r) = reparser; - let mut p = parser::Parser::new(token_source); - r(&mut p); - let events = p.finish(); - event::process(tree_sink, events); + pub fn parse(self, token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) { + let Reparser(r) = self; + let mut p = parser::Parser::new(token_source); + r(&mut p); + let events = p.finish(); + event::process(tree_sink, events); + } } diff --git a/crates/ra_syntax/Cargo.toml b/crates/ra_syntax/Cargo.toml index 7ce26b7c4d..7e70dad3ff 100644 --- a/crates/ra_syntax/Cargo.toml +++ b/crates/ra_syntax/Cargo.toml @@ -21,6 +21,7 @@ text_unit = { version = "0.1.6", features = ["serde"] } smol_str = { version = "0.1.9", features = ["serde"] } ra_text_edit = { path = "../ra_text_edit" } +ra_parser = { path = "../ra_parser" } [dev-dependencies] test_utils = { path = "../test_utils" } diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index b12282b394..c788bddec8 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs @@ -16,7 +16,6 @@ #![allow(missing_docs)] //#![warn(unreachable_pub)] // rust-lang/rust#47816 -mod syntax_kinds; mod syntax_node; mod syntax_text; mod syntax_error; @@ -31,9 +30,9 @@ pub mod ast; pub mod utils; pub use rowan::{SmolStr, TextRange, TextUnit}; +pub use ra_parser::SyntaxKind; pub use crate::{ ast::AstNode, - syntax_kinds::SyntaxKind, syntax_error::{SyntaxError, SyntaxErrorKind, Location}, syntax_text::SyntaxText, syntax_node::{Direction, SyntaxNode, WalkEvent, TreeArc}, diff --git a/crates/ra_syntax/src/parsing.rs b/crates/ra_syntax/src/parsing.rs index 7e1b32035b..0a11600e19 100644 --- a/crates/ra_syntax/src/parsing.rs +++ b/crates/ra_syntax/src/parsing.rs @@ -1,50 +1,28 @@ -#[macro_use] -mod token_set; mod builder; mod lexer; -mod event; mod input; -mod parser; -mod grammar; mod reparsing; +use ra_parser::{parse, ParseError}; + use crate::{ SyntaxKind, SyntaxError, parsing::{ builder::TreeBuilder, input::ParserInput, - event::process, - parser::Parser, }, syntax_node::GreenNode, }; pub use self::lexer::{tokenize, Token}; -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct ParseError(pub String); - pub(crate) use self::reparsing::incremental_reparse; pub(crate) fn parse_text(text: &str) -> (GreenNode, Vec) { let tokens = tokenize(&text); - let tree_sink = TreeBuilder::new(text, &tokens); - parse_with(tree_sink, text, &tokens, grammar::root) -} - -fn parse_with( - mut tree_sink: S, - text: &str, - tokens: &[Token], - f: fn(&mut Parser), -) -> S::Tree { - let events = { - let input = ParserInput::new(text, &tokens); - let mut p = Parser::new(&input); - f(&mut p); - p.finish() - }; - process(&mut tree_sink, events); + let token_source = ParserInput::new(text, &tokens); + let mut tree_sink = TreeBuilder::new(text, &tokens); + parse(&token_source, &mut tree_sink); tree_sink.finish() } diff --git a/crates/ra_syntax/src/parsing/builder.rs b/crates/ra_syntax/src/parsing/builder.rs index 1041c6a7be..0775b09006 100644 --- a/crates/ra_syntax/src/parsing/builder.rs +++ b/crates/ra_syntax/src/parsing/builder.rs @@ -1,7 +1,9 @@ +use ra_parser::{TreeSink, ParseError}; + use crate::{ SmolStr, SyntaxError, SyntaxErrorKind, TextUnit, TextRange, SyntaxKind::{self, *}, - parsing::{TreeSink, ParseError, Token}, + parsing::Token, syntax_node::{GreenNode, RaTypes}, }; @@ -17,8 +19,6 @@ pub(crate) struct TreeBuilder<'a> { } impl<'a> TreeSink for TreeBuilder<'a> { - type Tree = (GreenNode, Vec); - fn leaf(&mut self, kind: SyntaxKind, n_tokens: u8) { self.eat_trivias(); let n_tokens = n_tokens as usize; @@ -65,10 +65,6 @@ impl<'a> TreeSink for TreeBuilder<'a> { let error = SyntaxError::new(SyntaxErrorKind::ParseError(error), self.text_pos); self.errors.push(error) } - - fn finish(self) -> (GreenNode, Vec) { - (self.inner.finish(), self.errors) - } } impl<'a> TreeBuilder<'a> { @@ -82,6 +78,11 @@ impl<'a> TreeBuilder<'a> { inner: GreenNodeBuilder::new(), } } + + pub(super) fn finish(self) -> (GreenNode, Vec) { + (self.inner.finish(), self.errors) + } + fn eat_trivias(&mut self) { while let Some(&token) = self.tokens.get(self.token_pos) { if !token.kind.is_trivia() { diff --git a/crates/ra_syntax/src/parsing/input.rs b/crates/ra_syntax/src/parsing/input.rs index 96c03bb118..58be795bc3 100644 --- a/crates/ra_syntax/src/parsing/input.rs +++ b/crates/ra_syntax/src/parsing/input.rs @@ -1,9 +1,8 @@ +use ra_parser::TokenSource; + use crate::{ SyntaxKind, SyntaxKind::EOF, TextRange, TextUnit, - parsing::{ - TokenSource, - lexer::Token, - }, + parsing::lexer::Token, }; impl<'t> TokenSource for ParserInput<'t> { diff --git a/crates/ra_syntax/src/parsing/reparsing.rs b/crates/ra_syntax/src/parsing/reparsing.rs index 2c860b3df0..ffcb512adf 100644 --- a/crates/ra_syntax/src/parsing/reparsing.rs +++ b/crates/ra_syntax/src/parsing/reparsing.rs @@ -1,18 +1,18 @@ +use ra_text_edit::AtomTextEdit; +use ra_parser::Reparser; + use crate::{ SyntaxKind::*, TextRange, TextUnit, algo, syntax_node::{GreenNode, SyntaxNode}, syntax_error::SyntaxError, parsing::{ - grammar, parse_with, + input::ParserInput, builder::TreeBuilder, - parser::Parser, lexer::{tokenize, Token}, } }; -use ra_text_edit::AtomTextEdit; - pub(crate) fn incremental_reparse( node: &SyntaxNode, edit: &AtomTextEdit, @@ -61,8 +61,10 @@ fn reparse_block<'node>( if !is_balanced(&tokens) { return None; } - let tree_sink = TreeBuilder::new(&text, &tokens); - let (green, new_errors) = parse_with(tree_sink, &text, &tokens, reparser); + let token_source = ParserInput::new(&text, &tokens); + let mut tree_sink = TreeBuilder::new(&text, &tokens); + reparser.parse(&token_source, &mut tree_sink); + let (green, new_errors) = tree_sink.finish(); Some((node, green, new_errors)) } @@ -78,15 +80,12 @@ fn is_contextual_kw(text: &str) -> bool { } } -fn find_reparsable_node( - node: &SyntaxNode, - range: TextRange, -) -> Option<(&SyntaxNode, fn(&mut Parser))> { +fn find_reparsable_node(node: &SyntaxNode, range: TextRange) -> Option<(&SyntaxNode, Reparser)> { let node = algo::find_covering_node(node, range); node.ancestors().find_map(|node| { let first_child = node.first_child().map(|it| it.kind()); let parent = node.parent().map(|it| it.kind()); - grammar::reparser(node.kind(), first_child, parent).map(|r| (node, r)) + Reparser::for_node(node.kind(), first_child, parent).map(|r| (node, r)) }) } diff --git a/crates/ra_syntax/src/syntax_error.rs b/crates/ra_syntax/src/syntax_error.rs index 1a00fcc27a..bdd4317422 100644 --- a/crates/ra_syntax/src/syntax_error.rs +++ b/crates/ra_syntax/src/syntax_error.rs @@ -1,6 +1,8 @@ use std::fmt; -use crate::{TextRange, TextUnit, parsing::ParseError}; +use ra_parser::ParseError; + +use crate::{TextRange, TextUnit}; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct SyntaxError {