summaryrefslogtreecommitdiffstats
path: root/src/tools/rust-analyzer/crates/syntax/src/parsing.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/rust-analyzer/crates/syntax/src/parsing.rs')
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/parsing.rs46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/tools/rust-analyzer/crates/syntax/src/parsing.rs b/src/tools/rust-analyzer/crates/syntax/src/parsing.rs
new file mode 100644
index 000000000..047e670c9
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/syntax/src/parsing.rs
@@ -0,0 +1,46 @@
+//! Lexing, bridging to parser (which does the actual parsing) and
+//! incremental reparsing.
+
+mod reparsing;
+
+use rowan::TextRange;
+
+use crate::{syntax_node::GreenNode, SyntaxError, SyntaxTreeBuilder};
+
+pub(crate) use crate::parsing::reparsing::incremental_reparse;
+
+pub(crate) fn parse_text(text: &str) -> (GreenNode, Vec<SyntaxError>) {
+ let lexed = parser::LexedStr::new(text);
+ let parser_input = lexed.to_input();
+ let parser_output = parser::TopEntryPoint::SourceFile.parse(&parser_input);
+ let (node, errors, _eof) = build_tree(lexed, parser_output);
+ (node, errors)
+}
+
+pub(crate) fn build_tree(
+ lexed: parser::LexedStr<'_>,
+ parser_output: parser::Output,
+) -> (GreenNode, Vec<SyntaxError>, bool) {
+ let mut builder = SyntaxTreeBuilder::default();
+
+ let is_eof = lexed.intersperse_trivia(&parser_output, &mut |step| match step {
+ parser::StrStep::Token { kind, text } => builder.token(kind, text),
+ parser::StrStep::Enter { kind } => builder.start_node(kind),
+ parser::StrStep::Exit => builder.finish_node(),
+ parser::StrStep::Error { msg, pos } => {
+ builder.error(msg.to_string(), pos.try_into().unwrap())
+ }
+ });
+
+ let (node, mut errors) = builder.finish_raw();
+ for (i, err) in lexed.errors() {
+ let text_range = lexed.text_range(i);
+ let text_range = TextRange::new(
+ text_range.start.try_into().unwrap(),
+ text_range.end.try_into().unwrap(),
+ );
+ errors.push(SyntaxError::new(err, text_range))
+ }
+
+ (node, errors, is_eof)
+}