Skip to content

Commit

Permalink
Fix parsing code examples in documentation comments (#6377)
Browse files Browse the repository at this point in the history
  • Loading branch information
wawel37 authored Sep 13, 2024
1 parent c52b49d commit d6163bd
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 12 deletions.
54 changes: 45 additions & 9 deletions crates/cairo-lang-doc/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,16 @@ fn extract_item_outer_documentation(
// Get the text of the item (trivia + definition)
let raw_text =
item_id.stable_location(db.upcast())?.syntax_node(db.upcast()).get_text(db.upcast());
let doc = raw_text
let lines = raw_text
.lines()
.filter(|line| !line.trim().is_empty())
.take_while_ref(|line| is_comment_line(line))
.filter_map(|line| extract_comment_from_code_line(line, &["///"]))
.join(" ");
.collect::<Vec<_>>();

cleanup_doc(doc)
let result = join_lines_of_comments(&lines);

cleanup_doc(result)
}

/// Gets the module level comments of the item.
Expand All @@ -218,14 +220,16 @@ fn extract_item_module_level_documentation(

/// Only gets the comments inside the item.
fn extract_item_inner_documentation_from_raw_text(raw_text: String) -> Option<String> {
let doc = raw_text
let lines = raw_text
.lines()
.filter(|line| !line.trim().is_empty())
.skip_while(|line| is_comment_line(line))
.filter_map(|line| extract_comment_from_code_line(line, &["//!"]))
.join(" ");
.collect::<Vec<_>>();

let result = join_lines_of_comments(&lines);

cleanup_doc(doc)
cleanup_doc(result)
}

/// Formats markdown part of the documentation, and returns None, if the final documentation is
Expand All @@ -244,14 +248,15 @@ fn extract_item_module_level_documentation_from_file(
) -> Option<String> {
let file_content = db.file_content(file_id)?.to_string();

let doc = file_content
let lines = file_content
.lines()
.filter(|line| !line.trim().is_empty())
.take_while_ref(|line| is_comment_line(line))
.filter_map(|line| extract_comment_from_code_line(line, &["//!"]))
.join(" ");
.collect::<Vec<_>>();

cleanup_doc(doc)
let result = join_lines_of_comments(&lines);
cleanup_doc(result)
}

/// This function does 2 things to the line of comment:
Expand Down Expand Up @@ -279,3 +284,34 @@ fn extract_comment_from_code_line(line: &str, comment_markers: &[&'static str])
fn is_comment_line(line: &str) -> bool {
line.trim_start().starts_with("//")
}

/// Parses the lines of extracted comments so it can be displayed.
fn join_lines_of_comments(lines: &Vec<String>) -> String {
let mut in_code_block = false;
let mut result = String::new();

for line in lines {
let contains_delimiter = line.trim().starts_with("```");

if contains_delimiter {
// If we stumble upon the opening of a code block, we have to make a newline.
if !in_code_block {
result.push('\n');
}
in_code_block = !in_code_block;

result.push_str(line);
result.push('\n');
continue;
}

if in_code_block {
result.push_str(line);
result.push('\n');
} else {
result.push_str(line.trim());
result.push(' ');
}
}
result.trim_end().to_string()
}
27 changes: 24 additions & 3 deletions crates/cairo-lang-doc/src/tests/test-data/submodule.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,26 @@ hello = "src"

//! > cairo_code
//! This is a testing crate file. It's for the tests purposes only.
//! ```
//! let a = 5;
//! ```
//! This is also testing crate. After the code example.

//! We don't take responsibility for compiling this file.
//! So don't even try.

/// This one is just a prefix comment for a module.
/// ```rust
/// let a = String::from("This also works fine");
/// ```
/// As mentioned above.
mod cairo_submodule_code;

/// Main function.
fn main() {
//! Empty code example.
//! ```rust
//! ```
println!("Hello Cairo!");
}

Expand All @@ -37,10 +48,18 @@ mod inner_sub_module {
}

//! > Item #1
This is a testing crate file. It's for the tests purposes only. We don't take responsibility for compiling this file. So don't even try.
This is a testing crate file. It's for the tests purposes only.
```cairo
let a = 5;
```
This is also testing crate. After the code example. We don't take responsibility for compiling this file. So don't even try.

//! > Item #2
This is a submodule regarding the module_level_comments. It's used to make sure crate / module level comments are parsed in a correct way. Testing purposes only! This one is just a prefix comment for a module.
This is a submodule regarding the module_level_comments. It's used to make sure crate / module level comments are parsed in a correct way. Testing purposes only! This one is just a prefix comment for a module.
```rust
let a = String::from("This also works fine");
```
As mentioned above.

//! > Item #3
This comment just proves that it won't be considered as a file-module comment. It just refers to the inner_sub_module
Expand All @@ -49,4 +68,6 @@ This comment just proves that it won't be considered as a file-module comment. I
Hello function inside the inner module.

//! > Item #5
Main function.
Main function. Empty code example.
```rust
```

0 comments on commit d6163bd

Please sign in to comment.