mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 04:19:13 +00:00
internal: Thread edition through to parsing/tt-to-syntax-tree routines for macros
This commit is contained in:
parent
83370fe5d7
commit
a483d3bc37
39 changed files with 187 additions and 145 deletions
|
@ -255,7 +255,7 @@ pub fn diff(from: &SyntaxNode, to: &SyntaxNode) -> TreeDiff {
|
|||
mod tests {
|
||||
use expect_test::{expect, Expect};
|
||||
use itertools::Itertools;
|
||||
use parser::SyntaxKind;
|
||||
use parser::{Edition, SyntaxKind};
|
||||
use text_edit::TextEdit;
|
||||
|
||||
use crate::{AstNode, SyntaxElement};
|
||||
|
@ -607,8 +607,8 @@ fn main() {
|
|||
}
|
||||
|
||||
fn check_diff(from: &str, to: &str, expected_diff: Expect) {
|
||||
let from_node = crate::SourceFile::parse(from).tree().syntax().clone();
|
||||
let to_node = crate::SourceFile::parse(to).tree().syntax().clone();
|
||||
let from_node = crate::SourceFile::parse(from, Edition::CURRENT).tree().syntax().clone();
|
||||
let to_node = crate::SourceFile::parse(to, Edition::CURRENT).tree().syntax().clone();
|
||||
let diff = super::diff(&from_node, &to_node);
|
||||
|
||||
let line_number =
|
||||
|
|
|
@ -174,6 +174,7 @@ fn test_doc_comment_none() {
|
|||
// non-doc
|
||||
mod foo {}
|
||||
"#,
|
||||
parser::Edition::CURRENT,
|
||||
)
|
||||
.ok()
|
||||
.unwrap();
|
||||
|
@ -189,6 +190,7 @@ fn test_outer_doc_comment_of_items() {
|
|||
// non-doc
|
||||
mod foo {}
|
||||
"#,
|
||||
parser::Edition::CURRENT,
|
||||
)
|
||||
.ok()
|
||||
.unwrap();
|
||||
|
@ -204,6 +206,7 @@ fn test_inner_doc_comment_of_items() {
|
|||
// non-doc
|
||||
mod foo {}
|
||||
"#,
|
||||
parser::Edition::CURRENT,
|
||||
)
|
||||
.ok()
|
||||
.unwrap();
|
||||
|
@ -218,6 +221,7 @@ fn test_doc_comment_of_statics() {
|
|||
/// Number of levels
|
||||
static LEVELS: i32 = 0;
|
||||
"#,
|
||||
parser::Edition::CURRENT,
|
||||
)
|
||||
.ok()
|
||||
.unwrap();
|
||||
|
@ -237,6 +241,7 @@ fn test_doc_comment_preserves_indents() {
|
|||
/// ```
|
||||
mod foo {}
|
||||
"#,
|
||||
parser::Edition::CURRENT,
|
||||
)
|
||||
.ok()
|
||||
.unwrap();
|
||||
|
@ -257,6 +262,7 @@ fn test_doc_comment_preserves_newlines() {
|
|||
/// foo
|
||||
mod foo {}
|
||||
"#,
|
||||
parser::Edition::CURRENT,
|
||||
)
|
||||
.ok()
|
||||
.unwrap();
|
||||
|
@ -271,6 +277,7 @@ fn test_doc_comment_single_line_block_strips_suffix() {
|
|||
/** this is mod foo*/
|
||||
mod foo {}
|
||||
"#,
|
||||
parser::Edition::CURRENT,
|
||||
)
|
||||
.ok()
|
||||
.unwrap();
|
||||
|
@ -285,6 +292,7 @@ fn test_doc_comment_single_line_block_strips_suffix_whitespace() {
|
|||
/** this is mod foo */
|
||||
mod foo {}
|
||||
"#,
|
||||
parser::Edition::CURRENT,
|
||||
)
|
||||
.ok()
|
||||
.unwrap();
|
||||
|
@ -303,6 +311,7 @@ fn test_doc_comment_multi_line_block_strips_suffix() {
|
|||
*/
|
||||
mod foo {}
|
||||
"#,
|
||||
parser::Edition::CURRENT,
|
||||
)
|
||||
.ok()
|
||||
.unwrap();
|
||||
|
@ -316,7 +325,7 @@ fn test_doc_comment_multi_line_block_strips_suffix() {
|
|||
#[test]
|
||||
fn test_comments_preserve_trailing_whitespace() {
|
||||
let file = SourceFile::parse(
|
||||
"\n/// Representation of a Realm. \n/// In the specification these are called Realm Records.\nstruct Realm {}",
|
||||
"\n/// Representation of a Realm. \n/// In the specification these are called Realm Records.\nstruct Realm {}", parser::Edition::CURRENT,
|
||||
)
|
||||
.ok()
|
||||
.unwrap();
|
||||
|
@ -335,6 +344,7 @@ fn test_four_slash_line_comment() {
|
|||
/// doc comment
|
||||
mod foo {}
|
||||
"#,
|
||||
parser::Edition::CURRENT,
|
||||
)
|
||||
.ok()
|
||||
.unwrap();
|
||||
|
@ -360,6 +370,7 @@ where
|
|||
for<'a> F: Fn(&'a str)
|
||||
{}
|
||||
"#,
|
||||
parser::Edition::CURRENT,
|
||||
)
|
||||
.ok()
|
||||
.unwrap();
|
||||
|
|
|
@ -1054,6 +1054,7 @@ impl<N: AstNode + Clone> Indent for N {}
|
|||
mod tests {
|
||||
use std::fmt;
|
||||
|
||||
use parser::Edition;
|
||||
use stdx::trim_indent;
|
||||
use test_utils::assert_eq_text;
|
||||
|
||||
|
@ -1062,7 +1063,7 @@ mod tests {
|
|||
use super::*;
|
||||
|
||||
fn ast_mut_from_text<N: AstNode>(text: &str) -> N {
|
||||
let parse = SourceFile::parse(text);
|
||||
let parse = SourceFile::parse(text, Edition::CURRENT);
|
||||
parse.tree().syntax().descendants().find_map(N::cast).unwrap().clone_for_update()
|
||||
}
|
||||
|
||||
|
|
|
@ -89,6 +89,7 @@ fn if_block_condition() {
|
|||
else { "else" }
|
||||
}
|
||||
"#,
|
||||
parser::Edition::CURRENT,
|
||||
);
|
||||
let if_ = parse.tree().syntax().descendants().find_map(ast::IfExpr::cast).unwrap();
|
||||
assert_eq!(if_.then_branch().unwrap().syntax().text(), r#"{ "if" }"#);
|
||||
|
@ -123,6 +124,7 @@ fn if_condition_with_if_inside() {
|
|||
else { "else" }
|
||||
}
|
||||
"#,
|
||||
parser::Edition::CURRENT,
|
||||
);
|
||||
let if_ = parse.tree().syntax().descendants().find_map(ast::IfExpr::cast).unwrap();
|
||||
assert_eq!(if_.then_branch().unwrap().syntax().text(), r#"{ "if" }"#);
|
||||
|
@ -386,7 +388,8 @@ impl ast::BlockExpr {
|
|||
|
||||
#[test]
|
||||
fn test_literal_with_attr() {
|
||||
let parse = ast::SourceFile::parse(r#"const _: &str = { #[attr] "Hello" };"#);
|
||||
let parse =
|
||||
ast::SourceFile::parse(r#"const _: &str = { #[attr] "Hello" };"#, parser::Edition::CURRENT);
|
||||
let lit = parse.tree().syntax().descendants().find_map(ast::Literal::cast).unwrap();
|
||||
assert_eq!(lit.token().text(), r#""Hello""#);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
//! term, it will be replaced with direct tree manipulation.
|
||||
|
||||
use itertools::Itertools;
|
||||
use parser::T;
|
||||
use parser::{Edition, T};
|
||||
use rowan::NodeOrToken;
|
||||
use stdx::{format_to, format_to_acc, never};
|
||||
|
||||
|
@ -1127,7 +1127,7 @@ pub fn token_tree(
|
|||
|
||||
#[track_caller]
|
||||
fn ast_from_text<N: AstNode>(text: &str) -> N {
|
||||
let parse = SourceFile::parse(text);
|
||||
let parse = SourceFile::parse(text, Edition::CURRENT);
|
||||
let node = match parse.tree().syntax().descendants().find_map(N::cast) {
|
||||
Some(it) => it,
|
||||
None => {
|
||||
|
@ -1153,12 +1153,13 @@ pub fn token(kind: SyntaxKind) -> SyntaxToken {
|
|||
|
||||
pub mod tokens {
|
||||
use once_cell::sync::Lazy;
|
||||
use parser::Edition;
|
||||
|
||||
use crate::{ast, AstNode, Parse, SourceFile, SyntaxKind::*, SyntaxToken};
|
||||
|
||||
pub(super) static SOURCE_FILE: Lazy<Parse<SourceFile>> = Lazy::new(|| {
|
||||
SourceFile::parse(
|
||||
"const C: <()>::Item = ( true && true , true || true , 1 != 1, 2 == 2, 3 < 3, 4 <= 4, 5 > 5, 6 >= 6, !true, *p, &p , &mut p, { let a @ [] })\n;\n\nimpl A for B where: {}",
|
||||
"const C: <()>::Item = ( true && true , true || true , 1 != 1, 2 == 2, 3 < 3, 4 <= 4, 5 > 5, 6 >= 6, !true, *p, &p , &mut p, { let a @ [] })\n;\n\nimpl A for B where: {}", Edition::CURRENT,
|
||||
)
|
||||
});
|
||||
|
||||
|
@ -1186,13 +1187,13 @@ pub mod tokens {
|
|||
|
||||
pub fn whitespace(text: &str) -> SyntaxToken {
|
||||
assert!(text.trim().is_empty());
|
||||
let sf = SourceFile::parse(text).ok().unwrap();
|
||||
let sf = SourceFile::parse(text, Edition::CURRENT).ok().unwrap();
|
||||
sf.syntax().clone_for_update().first_child_or_token().unwrap().into_token().unwrap()
|
||||
}
|
||||
|
||||
pub fn doc_comment(text: &str) -> SyntaxToken {
|
||||
assert!(!text.trim().is_empty());
|
||||
let sf = SourceFile::parse(text).ok().unwrap();
|
||||
let sf = SourceFile::parse(text, Edition::CURRENT).ok().unwrap();
|
||||
sf.syntax().first_child_or_token().unwrap().into_token().unwrap()
|
||||
}
|
||||
|
||||
|
@ -1240,7 +1241,7 @@ pub mod tokens {
|
|||
|
||||
impl WsBuilder {
|
||||
pub fn new(text: &str) -> WsBuilder {
|
||||
WsBuilder(SourceFile::parse(text).ok().unwrap())
|
||||
WsBuilder(SourceFile::parse(text, Edition::CURRENT).ok().unwrap())
|
||||
}
|
||||
pub fn ws(&self) -> SyntaxToken {
|
||||
self.0.syntax().first_child_or_token().unwrap().into_token().unwrap()
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
use std::str::{self, FromStr};
|
||||
|
||||
use parser::Edition;
|
||||
use text_edit::Indel;
|
||||
|
||||
use crate::{validation, AstNode, SourceFile, TextRange};
|
||||
|
@ -14,7 +15,7 @@ fn check_file_invariants(file: &SourceFile) {
|
|||
}
|
||||
|
||||
pub fn check_parser(text: &str) {
|
||||
let file = SourceFile::parse(text);
|
||||
let file = SourceFile::parse(text, Edition::CURRENT);
|
||||
check_file_invariants(&file.tree());
|
||||
}
|
||||
|
||||
|
@ -48,11 +49,11 @@ impl CheckReparse {
|
|||
|
||||
#[allow(clippy::print_stderr)]
|
||||
pub fn run(&self) {
|
||||
let parse = SourceFile::parse(&self.text);
|
||||
let new_parse = parse.reparse(&self.edit);
|
||||
let parse = SourceFile::parse(&self.text, Edition::CURRENT);
|
||||
let new_parse = parse.reparse(&self.edit, Edition::CURRENT);
|
||||
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);
|
||||
let full_reparse = SourceFile::parse(&self.edited_text, Edition::CURRENT);
|
||||
for (a, b) in
|
||||
new_parse.tree().syntax().descendants().zip(full_reparse.tree().syntax().descendants())
|
||||
{
|
||||
|
|
|
@ -2,11 +2,13 @@
|
|||
//!
|
||||
//! Please avoid adding new usages of the functions in this module
|
||||
|
||||
use parser::Edition;
|
||||
|
||||
use crate::{ast, AstNode};
|
||||
|
||||
pub fn parse_expr_from_str(s: &str) -> Option<ast::Expr> {
|
||||
let s = s.trim();
|
||||
let file = ast::SourceFile::parse(&format!("const _: () = {s};"));
|
||||
let file = ast::SourceFile::parse(&format!("const _: () = {s};"), Edition::CURRENT);
|
||||
let expr = file.syntax_node().descendants().find_map(ast::Expr::cast)?;
|
||||
if expr.syntax().text() != s {
|
||||
return None;
|
||||
|
|
|
@ -141,8 +141,8 @@ impl Parse<SourceFile> {
|
|||
buf
|
||||
}
|
||||
|
||||
pub fn reparse(&self, indel: &Indel) -> Parse<SourceFile> {
|
||||
self.incremental_reparse(indel).unwrap_or_else(|| self.full_reparse(indel))
|
||||
pub fn reparse(&self, indel: &Indel, edition: Edition) -> Parse<SourceFile> {
|
||||
self.incremental_reparse(indel).unwrap_or_else(|| self.full_reparse(indel, edition))
|
||||
}
|
||||
|
||||
fn incremental_reparse(&self, indel: &Indel) -> Option<Parse<SourceFile>> {
|
||||
|
@ -159,10 +159,10 @@ impl Parse<SourceFile> {
|
|||
})
|
||||
}
|
||||
|
||||
fn full_reparse(&self, indel: &Indel) -> Parse<SourceFile> {
|
||||
fn full_reparse(&self, indel: &Indel, edition: Edition) -> Parse<SourceFile> {
|
||||
let mut text = self.tree().syntax().text().to_string();
|
||||
indel.apply(&mut text);
|
||||
SourceFile::parse(&text)
|
||||
SourceFile::parse(&text, edition)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,9 +170,9 @@ impl Parse<SourceFile> {
|
|||
pub use crate::ast::SourceFile;
|
||||
|
||||
impl SourceFile {
|
||||
pub fn parse(text: &str) -> Parse<SourceFile> {
|
||||
pub fn parse(text: &str, edition: Edition) -> Parse<SourceFile> {
|
||||
let _p = tracing::span!(tracing::Level::INFO, "SourceFile::parse").entered();
|
||||
let (green, errors) = parsing::parse_text(text, parser::Edition::CURRENT);
|
||||
let (green, errors) = parsing::parse_text(text, edition);
|
||||
let root = SyntaxNode::new_root(green.clone());
|
||||
|
||||
assert_eq!(root.kind(), SyntaxKind::SOURCE_FILE);
|
||||
|
@ -340,7 +340,7 @@ fn api_walkthrough() {
|
|||
//
|
||||
// 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);
|
||||
let parse = SourceFile::parse(source_code, parser::Edition::CURRENT);
|
||||
assert!(parse.errors().is_empty());
|
||||
|
||||
// The `tree` method returns an owned syntax node of type `SourceFile`.
|
||||
|
|
|
@ -177,6 +177,7 @@ fn merge_errors(
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use parser::Edition;
|
||||
use test_utils::{assert_eq_text, extract_range};
|
||||
|
||||
use super::*;
|
||||
|
@ -191,9 +192,9 @@ mod tests {
|
|||
after
|
||||
};
|
||||
|
||||
let fully_reparsed = SourceFile::parse(&after);
|
||||
let fully_reparsed = SourceFile::parse(&after, Edition::CURRENT);
|
||||
let incrementally_reparsed: Parse<SourceFile> = {
|
||||
let before = SourceFile::parse(&before);
|
||||
let before = SourceFile::parse(&before, Edition::CURRENT);
|
||||
let (green, new_errors, range) = incremental_reparse(
|
||||
before.tree().syntax(),
|
||||
&edit,
|
||||
|
|
|
@ -120,7 +120,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, }").ok().unwrap();
|
||||
let file = SourceFile::parse("struct Foo { f: u32, }", parser::Edition::CURRENT).ok().unwrap();
|
||||
let field = file.syntax().descendants().find_map(ast::RecordField::cast).unwrap();
|
||||
let ptr = SyntaxNodePtr::new(field.syntax());
|
||||
let field_syntax = ptr.to_node(file.syntax());
|
||||
|
|
|
@ -5,6 +5,7 @@ use std::{
|
|||
|
||||
use ast::HasName;
|
||||
use expect_test::expect_file;
|
||||
use parser::Edition;
|
||||
use rayon::prelude::*;
|
||||
use stdx::format_to_acc;
|
||||
use test_utils::{bench, bench_fixture, project_root};
|
||||
|
@ -19,7 +20,7 @@ fn main() {
|
|||
}
|
||||
"#;
|
||||
|
||||
let parse = SourceFile::parse(code);
|
||||
let parse = SourceFile::parse(code, Edition::CURRENT);
|
||||
// eprintln!("{:#?}", parse.syntax_node());
|
||||
assert!(parse.ok().is_ok());
|
||||
}
|
||||
|
@ -33,7 +34,7 @@ fn benchmark_parser() {
|
|||
let data = bench_fixture::glorious_old_parser();
|
||||
let tree = {
|
||||
let _b = bench("parsing");
|
||||
let p = SourceFile::parse(&data);
|
||||
let p = SourceFile::parse(&data, Edition::CURRENT);
|
||||
assert!(p.errors().is_empty());
|
||||
assert_eq!(p.tree().syntax.text_range().len(), 352474.into());
|
||||
p.tree()
|
||||
|
@ -50,7 +51,7 @@ fn benchmark_parser() {
|
|||
#[test]
|
||||
fn validation_tests() {
|
||||
dir_tests(&test_data_dir(), &["parser/validation"], "rast", |text, path| {
|
||||
let parse = SourceFile::parse(text);
|
||||
let parse = SourceFile::parse(text, Edition::CURRENT);
|
||||
let errors = parse.errors();
|
||||
assert_errors_are_present(&errors, path);
|
||||
parse.debug_dump()
|
||||
|
@ -110,7 +111,7 @@ fn self_hosting_parsing() {
|
|||
.into_par_iter()
|
||||
.filter_map(|file| {
|
||||
let text = read_text(&file);
|
||||
match SourceFile::parse(&text).ok() {
|
||||
match SourceFile::parse(&text, Edition::CURRENT).ok() {
|
||||
Ok(_) => None,
|
||||
Err(err) => Some((file, err)),
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue