Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/syntax_tree.rs')
-rw-r--r--crates/ide/src/syntax_tree.rs338
1 files changed, 0 insertions, 338 deletions
diff --git a/crates/ide/src/syntax_tree.rs b/crates/ide/src/syntax_tree.rs
deleted file mode 100644
index e241cb82bd..0000000000
--- a/crates/ide/src/syntax_tree.rs
+++ /dev/null
@@ -1,338 +0,0 @@
-use hir::Semantics;
-use ide_db::{FileId, RootDatabase};
-use syntax::{
- AstNode, NodeOrToken, SourceFile, SyntaxKind::STRING, SyntaxToken, TextRange, TextSize,
-};
-
-// Feature: Show Syntax Tree
-//
-// Shows the parse tree of the current file. It exists mostly for debugging
-// rust-analyzer itself.
-//
-// |===
-// | Editor | Action Name
-//
-// | VS Code | **rust-analyzer: Show Syntax Tree**
-// |===
-// image::https://user-images.githubusercontent.com/48062697/113065586-068bdb80-91b1-11eb-9507-fee67f9f45a0.gif[]
-pub(crate) fn syntax_tree(
- db: &RootDatabase,
- file_id: FileId,
- text_range: Option<TextRange>,
-) -> String {
- let sema = Semantics::new(db);
- let parse = sema.parse_guess_edition(file_id);
- if let Some(text_range) = text_range {
- let node = match parse.syntax().covering_element(text_range) {
- NodeOrToken::Node(node) => node,
- NodeOrToken::Token(token) => {
- if let Some(tree) = syntax_tree_for_string(&token, text_range) {
- return tree;
- }
- token.parent().unwrap()
- }
- };
-
- format!("{node:#?}")
- } else {
- format!("{:#?}", parse.syntax())
- }
-}
-
-/// Attempts parsing the selected contents of a string literal
-/// as rust syntax and returns its syntax tree
-fn syntax_tree_for_string(token: &SyntaxToken, text_range: TextRange) -> Option<String> {
- // When the range is inside a string
- // we'll attempt parsing it as rust syntax
- // to provide the syntax tree of the contents of the string
- match token.kind() {
- STRING => syntax_tree_for_token(token, text_range),
- _ => None,
- }
-}
-
-fn syntax_tree_for_token(node: &SyntaxToken, text_range: TextRange) -> Option<String> {
- // Range of the full node
- let node_range = node.text_range();
- let text = node.text().to_owned();
-
- // We start at some point inside the node
- // Either we have selected the whole string
- // or our selection is inside it
- let start = text_range.start() - node_range.start();
-
- // how many characters we have selected
- let len = text_range.len();
-
- let node_len = node_range.len();
-
- // We want to cap our length
- let len = len.min(node_len);
-
- // Ensure our slice is inside the actual string
- let end =
- if start + len < TextSize::of(&text) { start + len } else { TextSize::of(&text) - start };
-
- let text = &text[TextRange::new(start, end)];
-
- // Remove possible extra string quotes from the start
- // and the end of the string
- let text = text
- .trim_start_matches('r')
- .trim_start_matches('#')
- .trim_start_matches('"')
- .trim_end_matches('#')
- .trim_end_matches('"')
- .trim()
- // Remove custom markers
- .replace("$0", "");
-
- let parsed = SourceFile::parse(&text, span::Edition::CURRENT_FIXME);
-
- // If the "file" parsed without errors,
- // return its syntax
- if parsed.errors().is_empty() {
- return Some(format!("{:#?}", parsed.tree().syntax()));
- }
-
- None
-}
-
-#[cfg(test)]
-mod tests {
- use expect_test::expect;
-
- use crate::fixture;
-
- fn check(ra_fixture: &str, expect: expect_test::Expect) {
- let (analysis, file_id) = fixture::file(ra_fixture);
- let syn = analysis.syntax_tree(file_id, None).unwrap();
- expect.assert_eq(&syn)
- }
- fn check_range(ra_fixture: &str, expect: expect_test::Expect) {
- let (analysis, frange) = fixture::range(ra_fixture);
- let syn = analysis.syntax_tree(frange.file_id, Some(frange.range)).unwrap();
- expect.assert_eq(&syn)
- }
-
- #[test]
- fn test_syntax_tree_without_range() {
- // Basic syntax
- check(
- r#"fn foo() {}"#,
- expect![[r#"
- "#]],
- );
-
- check(
- r#"
-fn test() {
- assert!("
- fn foo() {
- }
- ", "");
-}"#,
- expect![[r#"
- [email protected] "\"\n fn foo() {\n ..."
- "#]],
- )
- }
-
- #[test]
- fn test_syntax_tree_with_range() {
- check_range(
- r#"$0fn foo() {}$0"#,
- expect![[r#"
- "#]],
- );
-
- check_range(
- r#"
-fn test() {
- $0assert!("
- fn foo() {
- }
- ", "");$0
-}"#,
- expect![[r#"
- [email protected] "\"\n fn foo() {\n ..."
- "#]],
- );
- }
-
- #[test]
- fn test_syntax_tree_inside_string() {
- check_range(
- r#"fn test() {
- assert!("
-$0fn foo() {
-}$0
-fn bar() {
-}
- ", "");
-}"#,
- expect![[r#"
- "#]],
- );
-
- // With a raw string
- check_range(
- r###"fn test() {
- assert!(r#"
-$0fn foo() {
-}$0
-fn bar() {
-}
- "#, "");
-}"###,
- expect![[r#"
- "#]],
- );
-
- // With a raw string
- check_range(
- r###"fn test() {
- assert!(r$0#"
-fn foo() {
-}
-fn bar() {
-}"$0#, "");
-}"###,
- expect![[r#"
- "#]],
- );
- }
-}