Skip to content
Open
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/source/components/analyse.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Limitations

**Current Limitations:**

- **Language Support**: C/C++ (``//``, ``/* */``), C# (``//``, ``/* */``, ``///``), Python (``#``) and YAML (``#``) comment styles are supported
- **Language Support**: C/C++ (``//``, ``/* */``), C# (``//``, ``/* */``, ``///``), Python (``#``), YAML (``#``) and Rust (``//``, ``/* */``, ``///``) comment styles are supported
- **Single Comment Style**: Each analysis run processes only one comment style at a time

Extraction Examples
Expand Down
11 changes: 9 additions & 2 deletions docs/source/components/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ Specifies the comment syntax style used in the source code files. This determine

**Type:** ``str``
**Default:** ``"cpp"``
**Supported values:** ``"cpp"``, ``"python"``, ``"cs"``, ``"yaml"``
**Supported values:** ``"cpp"``, ``"python"``, ``"cs"``, ``"yaml"``, ``"rust"``

.. code-block:: toml

Expand Down Expand Up @@ -304,8 +304,15 @@ Specifies the comment syntax style used in the source code files. This determine
- ``"yaml"``
- ``#`` (single-line)
- ``.yaml``, ``.yml``
* - Rust
- ``"rust"``
- ``//`` (single-line),
``/* */`` (multi-line),
``///`` (doc comments),
``//!`` (inner doc comments)
- ``.rs``

.. note:: Future versions may support additional programming languages. Currently, only C/C++ and Python comment styles are supported.
.. note:: Future versions may support additional programming languages.

gitignore
^^^^^^^^^
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ dependencies = [
"tree-sitter~=0.25.1",
"tree-sitter-c-sharp>=0.23.1",
"tree-sitter-yaml>=0.7.1",
"tree-sitter-rust>=0.23.0",
]

[build-system]
Expand Down
18 changes: 18 additions & 0 deletions src/sphinx_codelinks/analyse/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@
CommentType.cpp: {"function_definition", "class_definition"},
CommentType.cs: {"method_declaration", "class_declaration", "property_declaration"},
CommentType.yaml: {"block_mapping_pair", "block_sequence_item", "document"},
# @Rust Scope Node Types, IMPL_RUST_2, impl, [FE_RUST];
CommentType.rust: {
"function_item",
"struct_item",
"enum_item",
"impl_item",
"trait_item",
"mod_item",
},
}

# initialize logger
Expand Down Expand Up @@ -47,6 +56,10 @@
CPP_QUERY = """(comment) @comment"""
C_SHARP_QUERY = """(comment) @comment"""
YAML_QUERY = """(comment) @comment"""
RUST_QUERY = """
(line_comment) @comment
(block_comment) @comment
"""


def is_text_file(filepath: Path, sample_size: int = 2048) -> bool:
Expand Down Expand Up @@ -86,6 +99,11 @@ def init_tree_sitter(comment_type: CommentType) -> tuple[Parser, Query]:

parsed_language = Language(tree_sitter_yaml.language())
query = Query(parsed_language, YAML_QUERY)
elif comment_type == CommentType.rust:
import tree_sitter_rust # noqa: PLC0415

parsed_language = Language(tree_sitter_rust.language())
query = Query(parsed_language, RUST_QUERY)
else:
raise ValueError(f"Unsupported comment style: {comment_type}")
parser = Parser(parsed_language)
Expand Down
3 changes: 3 additions & 0 deletions src/sphinx_codelinks/source_discover/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"python": ["py"],
"cs": ["cs"],
"yaml": ["yml", "yaml"],
"rust": ["rs"],
}


Expand All @@ -18,6 +19,8 @@ class CommentType(str, Enum):
cpp = "cpp"
cs = "cs"
yaml = "yaml"
# @Support Rust style comments, IMPL_RUST_1, impl, [FE_RUST];
rust = "rust"


class SourceDiscoverSectionConfigType(TypedDict, total=False):
Expand Down
31 changes: 31 additions & 0 deletions tests/data/rust/demo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// demo.rs

/// This is a doc comment for the main function
/// @Main function implementation, main_demo, impl, [REQ_001]
fn main() {
println!("Hello from Rust!");
process_data();
}

// @Data processing function, process_func, impl, [REQ_002]
fn process_data() {
let data = vec![1, 2, 3];
for item in data {
println!("Processing: {}", item);
}
}

/* Block comment with marker
@User data structure, struct_def, impl, [REQ_003]
*/
struct User {
name: String,
age: u32,
}

impl User {
// @User constructor method, new_user, impl, [REQ_004]
fn new(name: String, age: u32) -> Self {
User { name, age }
}
}
14 changes: 14 additions & 0 deletions tests/test_analyse.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,20 @@ def test_analyse(src_dir, src_paths, tmp_path, snapshot_marks):
"warnings_path_exists": True,
},
),
(
TEST_DIR / "data" / "rust",
[
TEST_DIR / "data" / "rust" / "demo.rs",
],
ONELINE_COMMENT_STYLE_DEFAULT,
{
"num_src_files": 1,
"num_uncached_files": 1,
"num_cached_files": 0,
"num_comments": 6,
"num_oneline_warnings": 0,
},
),
],
)
def test_analyse_oneline_needs(
Expand Down
81 changes: 81 additions & 0 deletions tests/test_analyse_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import tree_sitter_c_sharp
import tree_sitter_cpp
import tree_sitter_python
import tree_sitter_rust
import tree_sitter_yaml

from sphinx_codelinks.analyse import utils
Expand Down Expand Up @@ -48,6 +49,14 @@ def init_yaml_tree_sitter() -> tuple[Parser, Query]:
return parser, query


@pytest.fixture(scope="session")
def init_rust_tree_sitter() -> tuple[Parser, Query]:
parsed_language = Language(tree_sitter_rust.language())
query = Query(parsed_language, utils.RUST_QUERY)
parser = Parser(parsed_language)
return parser, query


@pytest.mark.parametrize(
("code", "result"),
[
Expand Down Expand Up @@ -284,6 +293,78 @@ def test_find_associated_scope_yaml(code, result, init_yaml_tree_sitter):
assert result in yaml_structure


@pytest.mark.parametrize(
("code", "result"),
[
(
b"""
// @req-id: need_001
fn dummy_func1() {
}
""",
"fn dummy_func1()",
),
(
b"""
fn dummy_func2() {
}
// @req-id: need_001
fn dummy_func1() {
}
""",
"fn dummy_func1()",
),
(
b"""
fn dummy_func1() {
let a = 1;
/* @req-id: need_001 */
}
""",
"fn dummy_func1()",
),
(
b"""
fn dummy_func1() {
// @req-id: need_001
let a = 1;
}
fn dummy_func2() {
}
""",
"fn dummy_func1()",
),
(
b"""
/// @req-id: need_001
fn dummy_func1() {
}
""",
"fn dummy_func1()",
),
(
b"""
struct MyStruct {
// @req-id: need_001
field: i32,
}
""",
"struct MyStruct",
),
],
)
def test_find_associated_scope_rust(code, result, init_rust_tree_sitter):
parser, query = init_rust_tree_sitter
comments = utils.extract_comments(code, parser, query)
node: TreeSitterNode | None = utils.find_associated_scope(
comments[0], CommentType.rust
)
assert node
assert node.text
rust_def = node.text.decode("utf-8")
assert result in rust_def


@pytest.mark.parametrize(
("code", "result"),
[
Expand Down
2 changes: 1 addition & 1 deletion tests/test_source_discover.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"comment_type": "java",
},
[
"Schema validation error in field 'comment_type': 'java' is not one of ['cpp', 'cs', 'python', 'yaml']"
"Schema validation error in field 'comment_type': 'java' is not one of ['cpp', 'cs', 'python', 'rust', 'yaml']"
],
),
(
Expand Down
2 changes: 1 addition & 1 deletion tests/test_src_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
[
"Project 'dcdc' has the following errors:",
"Schema validation error in field 'exclude': 123 is not of type 'string'",
"Schema validation error in field 'comment_type': 'java' is not one of ['cpp', 'cs', 'python', 'yaml']",
"Schema validation error in field 'comment_type': 'java' is not one of ['cpp', 'cs', 'python', 'rust', 'yaml']",
"Schema validation error in field 'gitignore': '_true' is not of type 'boolean'",
"Schema validation error in field 'include': 345 is not of type 'string'",
"Schema validation error in field 'src_dir': ['../dcdc'] is not of type 'string'",
Expand Down