From cd7f11634501f1f3833fee38bc46bbecacf83fc4 Mon Sep 17 00:00:00 2001 From: Elijah Potter Date: Thu, 25 Jan 2024 11:01:39 -0700 Subject: [PATCH] Added many more TreeSitter parsers --- Cargo.lock | 110 ++++++++++++++++++ harper-ls/Cargo.toml | 10 ++ harper-ls/src/backend.rs | 8 +- harper-ls/src/main.rs | 2 +- .../{rust_parser.rs => tree_sitter_parser.rs} | 37 +++++- 5 files changed, 158 insertions(+), 9 deletions(-) rename harper-ls/src/{rust_parser.rs => tree_sitter_parser.rs} (65%) diff --git a/Cargo.lock b/Cargo.lock index 7624845c..7ffe8be8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -444,7 +444,17 @@ dependencies = [ "tokio", "tower-lsp", "tree-sitter", + "tree-sitter-c", + "tree-sitter-c-sharp", + "tree-sitter-cpp", + "tree-sitter-go", + "tree-sitter-javascript", + "tree-sitter-lua", + "tree-sitter-python", + "tree-sitter-ruby", "tree-sitter-rust", + "tree-sitter-swift", + "tree-sitter-toml", "tree-sitter-typescript", ] @@ -1285,6 +1295,86 @@ dependencies = [ "regex", ] +[[package]] +name = "tree-sitter-c" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a578ec34a18175c5a3922db2bceb132c82391f5b232375d6bb6531d1bfcf497" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-c-sharp" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ab3dc608f34924fa9e10533a95f62dbc14b6de0ddd7107722eba66fe19ae31" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-cpp" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b4b625f46a7370544b9cf0545532c26712ae49bfc02eb09825db358b9f79e1" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-go" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad6d11f19441b961af2fda7f12f5d0dac325f6d6de83836a1d3750018cc5114" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-javascript" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edbc663376bdd294bd1f0a6daf859aedb9aa5bdb72217d7ad8ba2d5314102cf7" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-lua" +version = "0.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0968cf4962ead1d26da28921dde1fd97407e7bbcf2f959cd20cf04ba2daa9421" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-python" +version = "0.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c93b1b1fbd0d399db3445f51fd3058e43d0b4dcff62ddbdb46e66550978aa5" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-ruby" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ac30cbb1560363ae76e1ccde543d6d99087421e228cc47afcec004b86bb711a" +dependencies = [ + "cc", + "tree-sitter", +] + [[package]] name = "tree-sitter-rust" version = "0.20.4" @@ -1295,6 +1385,26 @@ dependencies = [ "tree-sitter", ] +[[package]] +name = "tree-sitter-swift" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "452e6ee0a14b82a0dcd93400b8d3fe3784fdbd775191a89ef84586e5ccec6be7" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-toml" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca517f578a98b23d20780247cc2688407fa81effad5b627a5a364ec3339b53e8" +dependencies = [ + "cc", + "tree-sitter", +] + [[package]] name = "tree-sitter-typescript" version = "0.20.3" diff --git a/harper-ls/Cargo.toml b/harper-ls/Cargo.toml index 849fd0ec..1a25ce64 100644 --- a/harper-ls/Cargo.toml +++ b/harper-ls/Cargo.toml @@ -14,3 +14,13 @@ once_cell = "1.19.0" tree-sitter = "0.20.10" tree-sitter-rust = "0.20.4" tree-sitter-typescript = "0.20.3" +tree-sitter-python = "0.20.4" +tree-sitter-javascript = "0.20.1" +tree-sitter-go = "0.20.0" +tree-sitter-c = "0.20.7" +tree-sitter-cpp = "0.20.3" +tree-sitter-ruby = "0.20.0" +tree-sitter-swift = "0.4.0" +tree-sitter-c-sharp = "0.20.0" +tree-sitter-toml = "0.20.0" +tree-sitter-lua = "0.0.19" diff --git a/harper-ls/src/backend.rs b/harper-ls/src/backend.rs index e7a17d25..0c247251 100644 --- a/harper-ls/src/backend.rs +++ b/harper-ls/src/backend.rs @@ -21,7 +21,7 @@ use tower_lsp::{ use crate::{ diagnostics::{lint_to_code_actions, lints_to_diagnostics}, pos_conv::range_to_span, - rust_parser::RustParser, + tree_sitter_parser::TreeSitterParser, }; pub struct Backend { @@ -40,9 +40,9 @@ impl Backend { let mut parser: Box = Box::new(MarkdownParser); if let Some(extension) = url.to_file_path().unwrap().extension() { - if extension == "rs" { - parser = Box::new(RustParser) - } + parser = TreeSitterParser::new_from_extension(&extension.to_string_lossy()) + .map::, _>(|v| Box::new(v)) + .unwrap_or(Box::new(MarkdownParser)); } let doc = Document::new(text, parser); diff --git a/harper-ls/src/main.rs b/harper-ls/src/main.rs index 5cfebe35..f7b68086 100644 --- a/harper-ls/src/main.rs +++ b/harper-ls/src/main.rs @@ -2,7 +2,7 @@ use tokio::net::TcpListener; mod backend; mod diagnostics; mod pos_conv; -mod rust_parser; +mod tree_sitter_parser; use backend::Backend; use clap::Parser; diff --git a/harper-ls/src/rust_parser.rs b/harper-ls/src/tree_sitter_parser.rs similarity index 65% rename from harper-ls/src/rust_parser.rs rename to harper-ls/src/tree_sitter_parser.rs index af4f118c..2c522b4c 100644 --- a/harper-ls/src/rust_parser.rs +++ b/harper-ls/src/tree_sitter_parser.rs @@ -2,17 +2,46 @@ use harper_core::{ parsers::{Parser, PlainEnglishParser}, Span, }; -use tree_sitter::TreeCursor; +use tree_sitter::{Language, TreeCursor}; -pub struct RustParser; +pub struct TreeSitterParser { + language: Language, +} + +impl TreeSitterParser { + pub fn new(language: Language) -> Self { + Self { language } + } + + pub fn new_from_extension(file_extension: &str) -> Option { + let language = match file_extension { + "rs" => tree_sitter_rust::language(), + "tsx" => tree_sitter_typescript::language_tsx(), + "ts" => tree_sitter_typescript::language_typescript(), + "py" => tree_sitter_python::language(), + "js" => tree_sitter_javascript::language(), + "go" => tree_sitter_go::language(), + "c" => tree_sitter_c::language(), + "cpp" => tree_sitter_cpp::language(), + "rb" => tree_sitter_ruby::language(), + "swift" => tree_sitter_ruby::language(), + "cs" => tree_sitter_c_sharp::language(), + "toml" => tree_sitter_toml::language(), + "lua" => tree_sitter_lua::language(), + _ => return None, + }; + + Some(Self { language }) + } +} -impl Parser for RustParser { +impl Parser for TreeSitterParser { fn parse(&mut self, source: &[char]) -> Vec { let text: String = source.iter().collect(); let mut english_parser = PlainEnglishParser; let mut parser = tree_sitter::Parser::new(); - parser.set_language(tree_sitter_rust::language()).unwrap(); + parser.set_language(self.language).unwrap(); // TODO: Use incremental parsing let Some(root) = parser.parse(&text, None) else {