Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/debugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ The Neovim instance in the Dev Container is pre-configured to detect the

### 3. Verify Connection
To ensure the debugger is working and the server is responding:
1. Set a breakpoint in the Rust code (e.g., in `src/parser/docsymbol.rs`).
1. Set a breakpoint in the Rust code (e.g., in `src/document/docsymbol.rs`).
2. In Neovim, trigger an LSP request, such as fetching document symbols:
```vim
:lua vim.lsp.buf.document_symbol()
Expand Down
20 changes: 11 additions & 9 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
use serde::{Deserialize, Serialize};

pub mod workspace;
mod workspace;

fn default_clang_format_path() -> String {
"clang-format".to_string()
}
pub use workspace::WorkspaceProtoConfigs;

fn default_protoc_path() -> String {
"protoc".to_string()
}
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug, Clone, Default)]
#[serde(default)]
Expand Down Expand Up @@ -50,3 +44,11 @@ pub struct RenameConfig {
/// convention.
pub chain_rpc_request_response: bool,
}

fn default_clang_format_path() -> String {
"clang-format".to_string()
}

fn default_protoc_path() -> String {
"protoc".to_string()
}
4 changes: 2 additions & 2 deletions src/config/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ use std::{
use async_lsp::lsp_types::{Url, WorkspaceFolder};
use pkg_config::Config;

use crate::formatter::clang::ClangFormatter;
use crate::formatter::ClangFormatter;

use super::ProtolsConfig;
use crate::config::ProtolsConfig;

const CONFIG_FILE_NAMES: [&str; 2] = [".protols.toml", "protols.toml"];

Expand Down
4 changes: 0 additions & 4 deletions src/context/jumpable.rs

This file was deleted.

1 change: 0 additions & 1 deletion src/context/mod.rs

This file was deleted.

4 changes: 2 additions & 2 deletions src/docs.rs → src/docs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ use std::{collections::HashMap, sync::LazyLock};

macro_rules! docmap_builtin {
($name:literal) => {
($name, include_str!(concat!("docs/builtin/", $name, ".md")))
($name, include_str!(concat!("builtin/", $name, ".md")))
};
}

macro_rules! docmap_wellknown {
($name:literal) => {
(
concat!("google.protobuf.", $name),
include_str!(concat!("docs/wellknown/", $name, ".md")),
include_str!(concat!("wellknown/", $name, ".md")),
)
};
}
Expand Down
18 changes: 18 additions & 0 deletions src/document/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use async_lsp::lsp_types::{Diagnostic, DiagnosticSeverity};

use super::parser::ProtoDocument;

impl ProtoDocument {
pub fn collect_import_diagnostics(&self, import: &[&str]) -> Vec<Diagnostic> {
self.import_path_ranges(import)
.into_iter()
.map(|r| Diagnostic {
range: r,
severity: Some(DiagnosticSeverity::ERROR),
source: Some(String::from("protols")),
message: "failed to find proto file".to_string(),
..Default::default()
})
.collect()
}
}
22 changes: 11 additions & 11 deletions src/parser/docsymbol.rs → src/document/docsymbol.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
//! Document Symbol hierarchy compilation layer for protobuf abstract syntax
//! trees.
//! documents.
//!
//! This module translates a flat, vector-backed metamodel registry into a fully
//! nested, tree-structured representation matching the LSP [`DocumentSymbol`]
//! nested, document-structured representation matching the LSP [`DocumentSymbol`]
//! specification.

use async_lsp::lsp_types::{DocumentSymbol, Range, SymbolKind, SymbolTag};

use crate::model::{ElementKind, ElementMeta, ModelElement};

use super::ParsedTree;
use super::parser::ProtoDocument;

impl ParsedTree {
/// Compiles a fully resolved hierarchical tree of document symbols from the
impl ProtoDocument {
/// Compiles a fully resolved hierarchical document of document symbols from the
/// internal flat elements registry.
///
/// # Returns
Expand Down Expand Up @@ -172,8 +172,8 @@ mod test {
state.upsert_file(&uri, contents, &ipath, 3, &Config::default(), false);

state
.get_tree(&uri)
.map(|tree| tree.document_symbols())
.get_document(&uri)
.map(|document| document.document_symbols())
.unwrap_or_default()
}

Expand Down Expand Up @@ -214,8 +214,8 @@ mod test {
state.upsert_file(&uri, "", &ipath, 3, &Config::default(), false);

let symbols = state
.get_tree(&uri)
.map(|tree| tree.document_symbols())
.get_document(&uri)
.map(|document| document.document_symbols())
.unwrap_or_default();

assert!(symbols.is_empty());
Expand All @@ -231,8 +231,8 @@ mod test {
);

let symbols_minimal = state_minimal
.get_tree(&uri)
.map(|tree| tree.document_symbols())
.get_document(&uri)
.map(|document| document.document_symbols())
.unwrap_or_default();

assert!(symbols_minimal.is_empty());
Expand Down
10 changes: 5 additions & 5 deletions src/parser/hover.rs → src/document/hover.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! Spatial coordinate resolution and hover query layer for protobuf parsed
//! trees.
//! documents.
//!
//! This module implements high-performance geometric intersection algorithms
//! that map a precise cursor point (line and character) to memory-cached
Expand All @@ -9,9 +9,9 @@ use async_lsp::lsp_types::Position;

use crate::model::SpatialEntry;

use super::ParsedTree;
use super::parser::ProtoDocument;

impl ParsedTree {
impl ProtoDocument {
/// Performs a search to locate the innermost spatial index block
/// intersecting with the specified LSP [`Position`].
///
Expand Down Expand Up @@ -62,10 +62,10 @@ mod test {

let mut hover_results = Vec::new();

if let Some(parsed_tree) = state.get_tree(&uri) {
if let Some(parsed_document) = state.get_document(&uri) {
let mut tested_positions = std::collections::HashSet::new();

for element in &parsed_tree.elements {
for element in &parsed_document.elements {
let mut targets = vec![(element.meta.selection_range.start, "definition")];

match &element.kind {
Expand Down
9 changes: 9 additions & 0 deletions src/document/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
mod parser;

mod diagnostics;
mod docsymbol;
mod hover;
mod rename;
mod syntax;

pub use parser::{ProtoDocument, ProtoParser};
55 changes: 40 additions & 15 deletions src/parser.rs → src/document/parser.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,23 @@
use std::sync::Arc;

use async_lsp::lsp_types::Url;
use async_lsp::lsp_types::{Range, Url};
use tree_sitter::{Parser, Query, Tree};

use crate::model::{ModelElement, SpatialEntry, build_meta_model};

mod definition;
mod diagnostics;
mod docsymbol;
mod hover;
mod rename;
mod tree;

use crate::model::{ElementKind, ModelElement, SpatialEntry, build_meta_model};
pub struct ProtoParser {
parser: tree_sitter::Parser,
}

#[derive(Clone)]
pub struct ParsedTree {
pub struct ProtoDocument {
pub uri: Url,
pub package: String,
pub elements: Vec<ModelElement>,
pub spatial_index: Vec<SpatialEntry>,
tree: Arc<Tree>,
pub tree: Arc<Tree>,
}

impl ParsedTree {
impl ProtoDocument {
/// Attempts to parse a raw protobuf document and compile its optimized
/// pure-memory metamodel and sorted spatial index.
///
Expand Down Expand Up @@ -71,6 +63,39 @@ impl ParsedTree {
tree: Arc::new(tree),
})
}

/// Returns the package namespace, defaulting to `"."` when undeclared.
pub fn package_name(&self) -> &str {
if self.package.is_empty() {
"."
} else {
&self.package
}
}

/// Returns the paths of all `import` statements declared in source.
pub fn import_paths(&self) -> Vec<String> {
self.elements
.iter()
.filter_map(|element| match &element.kind {
ElementKind::Import { path } => Some(path.clone()),
_ => None,
})
.collect()
}

/// Returns the ranges of import statements whose path is in `import`.
pub fn import_path_ranges(&self, import: &[&str]) -> Vec<Range> {
self.elements
.iter()
.filter_map(|element| match &element.kind {
ElementKind::Import { path } if import.contains(&path.as_str()) => {
Some(element.meta.selection_range)
}
_ => None,
})
.collect()
}
}

impl ProtoParser {
Expand All @@ -95,7 +120,7 @@ impl ProtoParser {
uri: Url,
contents: impl AsRef<[u8]>,
metamodel_query: &Query,
) -> Option<ParsedTree> {
ParsedTree::try_from_input(uri, contents.as_ref(), metamodel_query, &mut self.parser)
) -> Option<ProtoDocument> {
ProtoDocument::try_from_input(uri, contents.as_ref(), metamodel_query, &mut self.parser)
}
}
Loading