1#![allow(rustdoc::private_intra_doc_links)]
21#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]
22
23#[cfg(not(feature = "in-rust-tree"))]
24extern crate ra_ap_rustc_lexer as rustc_lexer;
25#[cfg(feature = "in-rust-tree")]
26extern crate rustc_lexer;
27
28mod event;
29mod grammar;
30mod input;
31mod lexed_str;
32mod output;
33mod parser;
34mod shortcuts;
35mod syntax_kind;
36mod token_set;
37
38pub use T_ as T;
39
40#[cfg(test)]
41mod tests;
42
43pub(crate) use token_set::TokenSet;
44
45pub use edition::Edition;
46
47pub use crate::{
48 input::Input,
49 lexed_str::LexedStr,
50 output::{Output, Step},
51 shortcuts::StrStep,
52 syntax_kind::SyntaxKind,
53};
54
55#[derive(Debug)]
77pub enum TopEntryPoint {
78 SourceFile,
79 MacroStmts,
80 MacroItems,
81 Pattern,
82 Type,
83 Expr,
84 MetaItem,
87}
88
89impl TopEntryPoint {
90 pub fn parse(&self, input: &Input, edition: Edition) -> Output {
91 let _p = tracing::info_span!("TopEntryPoint::parse", ?self).entered();
92 let entry_point: fn(&'_ mut parser::Parser<'_>) = match self {
93 TopEntryPoint::SourceFile => grammar::entry::top::source_file,
94 TopEntryPoint::MacroStmts => grammar::entry::top::macro_stmts,
95 TopEntryPoint::MacroItems => grammar::entry::top::macro_items,
96 TopEntryPoint::Pattern => grammar::entry::top::pattern,
97 TopEntryPoint::Type => grammar::entry::top::type_,
98 TopEntryPoint::Expr => grammar::entry::top::expr,
99 TopEntryPoint::MetaItem => grammar::entry::top::meta_item,
100 };
101 let mut p = parser::Parser::new(input, edition);
102 entry_point(&mut p);
103 let events = p.finish();
104 let res = event::process(events);
105
106 if cfg!(debug_assertions) {
107 let mut depth = 0;
108 let mut first = true;
109 for step in res.iter() {
110 assert!(depth > 0 || first);
111 first = false;
112 match step {
113 Step::Enter { .. } => depth += 1,
114 Step::Exit => depth -= 1,
115 Step::FloatSplit { ends_in_dot: has_pseudo_dot } => {
116 depth -= 1 + !has_pseudo_dot as usize
117 }
118 Step::Token { .. } | Step::Error { .. } => (),
119 }
120 }
121 assert!(!first, "no tree at all");
122 assert_eq!(depth, 0, "unbalanced tree");
123 }
124
125 res
126 }
127}
128
129#[derive(Debug)]
139pub enum PrefixEntryPoint {
140 Vis,
141 Block,
142 Stmt,
143 Pat,
144 PatTop,
145 Ty,
146 Expr,
147 Path,
148 Item,
149 MetaItem,
150}
151
152impl PrefixEntryPoint {
153 pub fn parse(&self, input: &Input, edition: Edition) -> Output {
154 let entry_point: fn(&'_ mut parser::Parser<'_>) = match self {
155 PrefixEntryPoint::Vis => grammar::entry::prefix::vis,
156 PrefixEntryPoint::Block => grammar::entry::prefix::block,
157 PrefixEntryPoint::Stmt => grammar::entry::prefix::stmt,
158 PrefixEntryPoint::Pat => grammar::entry::prefix::pat,
159 PrefixEntryPoint::PatTop => grammar::entry::prefix::pat_top,
160 PrefixEntryPoint::Ty => grammar::entry::prefix::ty,
161 PrefixEntryPoint::Expr => grammar::entry::prefix::expr,
162 PrefixEntryPoint::Path => grammar::entry::prefix::path,
163 PrefixEntryPoint::Item => grammar::entry::prefix::item,
164 PrefixEntryPoint::MetaItem => grammar::entry::prefix::meta_item,
165 };
166 let mut p = parser::Parser::new(input, edition);
167 entry_point(&mut p);
168 let events = p.finish();
169 event::process(events)
170 }
171}
172
173pub struct Reparser(fn(&mut parser::Parser<'_>));
175
176impl Reparser {
177 pub fn for_node(
179 node: SyntaxKind,
180 first_child: Option<SyntaxKind>,
181 parent: Option<SyntaxKind>,
182 ) -> Option<Reparser> {
183 grammar::reparser(node, first_child, parent).map(Reparser)
184 }
185
186 pub fn parse(self, tokens: &Input, edition: Edition) -> Output {
191 let Reparser(r) = self;
192 let mut p = parser::Parser::new(tokens, edition);
193 r(&mut p);
194 let events = p.finish();
195 event::process(events)
196 }
197}