Feature: Language-aware traceability for Rust code
Description
In safety and security related contexts the usage of Rust is increasing.
Problem
Requirements cannot be parsed from Rust files yet.
Solution
Add parsing requirements from comments contained in Rust production code.
Additional Information
Relates to docs about language aware parsing of source code.
Hi, @fkromer (and @stanislaw and @mettta)!
I'm a member of the Safety-Critical Rust Consortium and have a tiny startup using Rust for aerospace.
I've been trial using StrictDoc internally for a little while and... wow... what a nice tool!
I've made a preliminary tool to extract @relations from Rust source code here.
Critically, it can automatically determine the context and scope of a @relation because Rust allows attaching attributes to most nodes of the Rust AST...
... and a common form of attribute is the "doc-comment".
An example of using the mapped relations to generate an interactive HTML source code map is via these links:
I'd appreciate your thoughts and any feedback you have on this approach.
(We're actually taking a similar approach to mapping object code back to source, and then source back to requirements...) 😄
@adfernandes Great initiative! ATM I'm not involved in functional safety critical code and no urgent need for the feature (I've more important things on my todo list). I've looked shortly over it. From a technological point of view lgtm.
Great - thanks for taking a look!
I just wanted set of experienced “eyeballs and brains” to glance at it and give me a quick “go / no-go” to make sure I didn’t overlook something obvious.
Everything we’re doing is open-source, so as it evolves it should be good for everyone.
Hi @adfernandes, thanks for sharing the links for your project. It looks very close/similar to what we were going to do for supporting Rust in StrictDoc.
The original plan was to use tree-sitter-rust for parsing Rust files because StrictDoc uses the other tree-sitter-* libraries for parsing ASTs of C/C++/Python/Robot framework. There is an initial work for using tree-sitter-ada for parsing Ada code. All these languages have Tree-sitter–based Python packages, which make it easy to obtain AST parsing for them.
Could you explain if you are considering to integrate your tool with StrictDoc, or you are planning to implement a tool similar to StrictDoc that uses the same languages conventions, e.g., the @relation marker syntax? Let's discuss what you are planning with your work and whether there is any overlap or a possible interface between parsing Rust with tree-sitter-rust and using your approach.
Could you explain if you are considering to integrate your tool with StrictDoc,
I had originally wanted to do that, but needed a proof-of-concept faster than I felt comfortable coming up to speed with the StrictDoc codebase.
In the future, I'd be happy to, if that ends up working out!
or you are planning to implement a tool similar to StrictDoc that uses the same languages conventions, e.g., the @relation marker syntax?
In addition to mapping source to/from requirements, we have to map object code back to source. That has nothing to do with @relation tags, but has a lot to do with writing syntax highlighting HTML (and PDF export) for another couple of mapping tools.
I actually want very much to adopt StrictDoc for our Rust-Avionics work, but it's early days and I'm just feeling things out, mostly, right now.
With regard to tree-sitter, I've used it in the past, and will definitely be using it for interop with the C world.
The reason I decided (for the moment) to go with the Rust syn crate, however, had to do with the confluence of:
- how comments are handled, and
- attaching
@relations to AST nodes.
In Rust's tree-sitter grammar, comments and doc-comments are (effectively) indistinguishable.
So at first, I thought to follow the idea of @relation(..., scope=function) from the StrictDoc C mapping.
However, unlike the C family (or even C++), Rust has much more complex scopes that are, nonetheless very well defined.
In particular, the idea of "doc-comment" to "#[doc] attribute", with attributes being attached to well-defined Rust-language nodes, meant that the scope= modifier could be made both explicit and redundant.
In other words, by putting @relation tags in Rust doc-comments, their scope is always explicit and well-defined, with no need for an additional scope=... modifier.
Trying to do the same with the tree-sitter grammar was not possible, since tree-sitter doesn't know what Rust-AST nodes are allowed to have #[...] attributes. This is the "scope" column in my demo page.
Oh - one thing I want to emphasize, because it may be lost in all my typing, is that sdoc-rs-relations by itself consumes Rust and produces JSON... that's it.
The idea is that that makes it easier for other tools to consume Rust/JSON, produce HTML or PDF or whatever.
Could you explain if you are considering to integrate your tool with StrictDoc,
I had originally wanted to do that, but needed a proof-of-concept faster than I felt comfortable coming up to speed with the StrictDoc codebase.
In the future, I'd be happy to, if that ends up working out!
The plan for adding Rust support includes writing a tree-sitter-rust-based reader class similar to the C reader and other reader classes. They all follow the same pattern: use tree-sitter-* to parse an AST, traverse it, generate SDoc Python objects that represent markers, functions, and source nodes. Examples:
- https://github.com/strictdoc-project/strictdoc/blob/main/strictdoc/backend/sdoc_source_code/reader_c.py
- https://github.com/strictdoc-project/strictdoc/blob/main/strictdoc/backend/sdoc_source_code/reader_python.py
- https://github.com/strictdoc-project/strictdoc/blob/main/strictdoc/backend/sdoc_source_code/reader_robot.py
There are also non Tree Sitter-based parsers, such as:
- https://github.com/strictdoc-project/strictdoc/blob/main/strictdoc/backend/sdoc_source_code/test_reports/junit_xml_reader.py
- https://github.com/strictdoc-project/strictdoc/blob/main/strictdoc/backend/sdoc_source_code/test_reports/robot_xml_reader.py
In all these readers, the same happens: Python objects, such as Function, FunctionMarker, etc., are created from parsed content.
or you are planning to implement a tool similar to StrictDoc that uses the same languages conventions, e.g., the @relation marker syntax?
In addition to mapping source to/from requirements, we have to map object code back to source. That has nothing to do with
@relationtags, but has a lot to do with writing syntax highlighting HTML (and PDF export) for another couple of mapping tools.
Parsing object code back to source is also on StrictDoc's roadmap, it is just has not been requested strongly enough by any existing users. The approach would be similar to what I described above: create a dedicated reader for binary files and then create corresponding SDoc Python objects, and link them into the traceability graph. The idea to implement this would be that a requirement that is traced to source code function would get an extra link to the binary file with that function. How to represent a binary in HTML nicely is something we would need to figure out.
One thing that StrictDoc wants to solve is to create a single traceability HTML space (static HTML or webserver-based HTML) where there would be no, or at least less, need to write separate isolated scripts that create disjoint HTML spaces. By now, StrictDoc can do a few things reasonably well:
- Connecting requirements to source code, calculating requirements coverage by source.
- Connection requirements to test files and test reports, calculating requirements coverage by test.
- In early works: connecting code coverage back to source and relevant requirements.
- TBD: connecting binaries and source and transitively to requirements.
I actually want very much to adopt StrictDoc for our Rust-Avionics work, but it's early days and I'm just feeling things out, mostly, right now.
With regard to tree-sitter, I've used it in the past, and will definitely be using it for interop with the C world.
The reason I decided (for the moment) to go with the Rust
syncrate, however, had to do with the confluence of:* how comments are handled, and * attaching `@relation`s to AST nodes.In Rust's tree-sitter grammar, comments and doc-comments are (effectively) indistinguishable. So at first, I thought to follow the idea of
@relation(..., scope=function)from the StrictDoc C mapping.However, unlike the C family (or even C++), Rust has much more complex scopes that are, nonetheless very well defined.
In particular, the idea of "doc-comment" to "
#[doc]attribute", with attributes being attached to well-defined Rust-language nodes, meant that thescope=modifier could be made both explicit and redundant.In other words, by putting
@relationtags in Rust doc-comments, their scope is always explicit and well-defined, with no need for an additionalscope=...modifier.Trying to do the same with the tree-sitter grammar was not possible, since tree-sitter doesn't know what Rust-AST nodes are allowed to have
#[...]attributes. This is the "scope" column in my demo page.
Our experience with tree-sitter-ada is a good example of how a package maintainer is happy to accept contributions.
Do you think it would be possible to open a PR or a discussion with tree-sitter-rust, and see if the grammar could be extended to support comments vs doc-comments?
Regarding scope=: It is true that even for C parsers, the scope can often, but not always, be derived from the position in the source code. For example, scope=function is redundant because it always refers to a Doxygen comment located directly above the function. However, scope=range_start or scope=line are less redundant because they shows exactly what the user is trying to achieve.
I have worked with tracing StrictDoc requirements to its source code and tests for quite a while now, and I can confirm that seeing scope=function above function comments and scope=file at the top of files, even if redundant, feels right to my brain, because the intended scope is visually (and mentally) very clear.
I did consider making scope= optional, but I couldn't figure out how to resolve the ambiguity when someone places a marker in a topmost comment above a function — would that be a function scope or a file scope?
Regarding tree-sitter-rust vs your solution: I would slightly lean towards the tree sitter version for the following reasons:
- All tree-sitter-* libraries are all based on a the same approach (grammar.js and tooling around it), and are either well maintained (-rust seems to be doing well) or at least maintained actively enough.
-
tree-sitter-rusthas a Python package and Python API with no subprocess calls required. All other readers based on tree-sitter have Pip packages obtain AST with this Python API.
With the last release, I am switching StrictDoc configuration to be Python-based which means it is even easier to configure all sorts of things before StrictDoc runs its main pipeline. If you would really want your solution over tree-sitter-rust and want to use StrictDoc at the same time, we could integrate a strictdoc reader with your sdoc-rs-relations in its backend and provide a config option that allows a user to select any reader set that they want.
https://github.com/strictdoc-project/strictdoc/blob/main/strictdoc_config.py
cc @haxtibal @thseiler
Rust in StrictDoc would be a strong point for the upcoming Linux kernel talks, as the code base is mostly C + Rust. So count me in for implementing a PoC. I wouldn't try to trace any possible element in Rust for a start, but stick with files, functions and ranges as we have it for C. An interesting question is how we would globally identify functions (e.g. to make them forward traceable). See e.g. Namespaces, Qualified paths, Canonical paths.
Do you think it would be possible to open a PR or a discussion with tree-sitter-rust, and see if the grammar could be extended to support comments vs doc-comments?
IIUC, the concern was about how to parse #[doc]. This works:
from tree_sitter import Language, Parser, Node, Tree, Query, QueryCursor
import tree_sitter_rust
rust_code = """
#[doc = "This is an outer doc comment"]
pub fn foo() -> i32 { 0 }
#[doc = "This is yet another outer doc comment"]
pub fn bar() -> i32 { 1 }
"""
rust_language = Language(tree_sitter_rust.language())
parser = Parser(rust_language)
tree = parser.parse(bytes(rust_code, "utf8"))
doc_attr_captures = QueryCursor(Query(rust_language, """
(
(attribute_item
(attribute
(identifier) @the-attribute-name
(string_literal) @the-doc
(#eq? @the-attribute-name "doc")))
(function_item
name: (identifier) @the-function-name)
)
""")).captures(tree.root_node)
for idx in range(len(doc_attr_captures["the-doc"])):
function_name = doc_attr_captures["the-function-name"][idx].text.decode()
doc = doc_attr_captures["the-doc"][idx].text.decode()
print(f"Function {function_name}: {doc}")
Output:
Function foo: "This is an outer doc comment"
Function bar: "This is yet another outer doc comment"
@adfernandes That was probably oversimplified. If it doesn't address your concerns, can you give an short-as possible snippet that demonstrates your concerns?
Regarding tree-sitter-rust vs your solution: I would slightly lean towards the tree sitter version
That's also my feeling about it. SourceFileTraceabilityReader_* are already kind of established internal API, so it would be good to continue and get a class SourceFileTraceabilityReader_Rust. We've good experience with tree-sitter, but could also use a different parser. For example, class SourceFileTraceabilityReader_Robot uses robot.api.parsing instead of tree-sitter.
@haxtibal you are absolutely welcome to move ahead and implement a tree-sitter-based PoC, unless there is a stronger proposal for an alternative solution by @adfernandes in this thread 👍
My immediate focus will likely be on SDoc node-, document-, and tree-level validations, as well as enabling users to define their own custom validation classes. The HTML/CSS work has already been there for quite a while, it is just waiting for the validation logic to be hooked in.
@haxtibal thank you for the thoughtful writeup, much appreciated!
IIUC, the concern was about how to parse #[doc].
Correct, but that's only part of the issue.
The first issue was differentiating between doc-comments and normal comments, which your example showed is effectively a non-issue.
But the second, trickier problem (I think) is figuring out what Rust-language construct the doc-comment (_a.k.a. "doc attribute") applies to.
can you give an short-as possible snippet that demonstrates your concerns?
Yes. Consider the following Rust snippet:
mod foo {
#[cfg(target_os = "qnx")]
/// @relation(REQ01, scope=module)
fn bar(x: i32) -> i32 {
x + 1
}
}
So the first problem is the the /// is an inner comment, which means that it applies to fn bar, not mod foo. Which is authoritative, the scope= or the Rust syntax?
So let's fix it to the below, and add an actual relation for the function:
mod foo {
#[cfg(target_os = "qnx")]
//! @relation(REQ01) // inner attribute applies to `mod foo`
/// @relation(REQ02) // outer attribute applies to `fn bar`
fn bar(x: i32) -> i32 {
x + 1
}
}
Does @relation(REQ02) cover the #[cfg(target_os = "qnx")] directive? That's a very real, very important question, especially since attributes are used extensively in Rust.
So problem two is: "Which Rust language 'item' does the doc-comment/attribute apply to?"
I do not know how closely the tree-sitter AST follows the official Rust grammar AST.
What I do know is that the syn crate does follow the official Rust grammar, so I always, unambiguously know what Rust-language items a doc attribute applies to, and this is enforced by the Rust compiler.
I think it's possible to get that or verify that with tree-sitter, but I get that for free right now using syn.
Just to be clear, I love, Love, LOVE the fact that StrictDoc is a single Python package that I can get running with with a single pipx install command.
I re-iterate: love, Love, LOVE
But I'm not certain that --- at least for us --- the benefits of using tree-sitter outweigh the amount of work it would take to bring it up to current feature parity.
There is a second reason for supporting external tools (much to my dismay).
In object-to-source mapping, the best exmaple I can give you right now is the type of output produced by the JSON output of llvm-symbolizer
We already have demo code that runs through the .text and .data bytes of an ELF image on Arm, and back-traces through all sources, including unwinding through multiple stacked inlines.
This is rather tricky to do properly and we make extensive use of the Rust ecosystem for parsing ELF and working through the byzantine DWARF debugging information.
As far as I know, there are lots of Python tools for dealing with ELF, but not many for dealing with DWARF.
So... it might be necessary to use external tools in the future. But that's just a guess on my part, you likely know the Python ecosystem for DWARF better if object-to-source mapping is on the StrictDoc roadmap.
mod foo { #[cfg(target_os = "qnx")] //! @relation(REQ01) // inner attribute applies to
mod foo/// @relation(REQ02) // outer attribute applies tofn bar
fn bar(x: i32) -> i32 { x + 1 } }Does
@relation(REQ02)cover the#[cfg(target_os = "qnx")]directive? That's a very real, very important question, especially since attributes are used extensively in Rust.So problem two is: "Which Rust language 'item' does the doc-comment/attribute apply to?"
StrictDoc's generic language model is currently very simple. It knows files, lines, functions and classes - that's it. Therefore the answer would be simple, REQ02 covers the function, since StrictDoc doesn't know what an attribute is. Any further discussion would imply we make StrictDoc's language model richer. Maybe we could map Rust-struct and Rust-trait to StrictDoc-class, but trying to have everything seems like a rabbit hole. But if there's huge benefit, well maybe? @stanislaw Your opinion?
Will try to understand your use case better and come back, sadly running out of time right now.
the answer would be simple, REQ02 covers the function, since StrictDoc doesn't know what an attribute is
Yeah, I totally get that.
It's just, following the "Safety-Critical Ethos", it is preferable if _"there is one, obvious and canonical 'source of truth', and it is difficult or impossible to mess up".
Unlike any other language that I can think of - which is a lot of them, because I'm old 👴🏽 😆 - Rust has very well-defined, core ways of attaching things like "doc" attributes to well-defined language nodes.
It seems a shame to downgrade that "batteries included" approach to a less robust one 😢
It becomes particularly important when documenting (tracing to requirements) Rust macros, because (again unlike other languages), Rust macros are (mostly) hygienic - meaning they are much more than just substitution engines like the C preprocessor.
sadly running out of time right now
Yeah, me too. Like I said, we're a small - very - shop that's trying to get off the ground, so I/we really have to maximize our "bang for the buck" development time.
Which is why I appreciate all the developers and development of StrictDoc all the more!
I'm going to continue with the JSON approach I've started with, and maybe we can circle back later and see how things are working in a month or two.
We should have our object-to-source mapper ready for "alpha" quality public preview then, too.
Unlike any other language that I can think of - which is a lot of them, because I'm old 👴🏽 😆 - Rust has very well-defined, core ways of attaching things like "doc" attributes to well-defined language nodes.
Tree-sitter gives us the exact position of each item, including attributes, in the tree. With tree position, the inner/outer rule and the allowed position rule at hand, it wouldn't be very hard to calculate the target item in the Rust-sense.
But then, what benefit is knowing, say, "this attribute is attached to that 2nd match expression arm" if StrictDoc doesn't know what a match expression arm is? The best StrictDoc could probably learn was to capture it as something like GenericLanguageItem { kind; name; line_ranges }.
It seems a shame to downgrade that "batteries included" approach to a less robust one 😢
Agreed, having the AST as the rust compiler sees it would be close to truth. Tree-sitter gives us only a concrete syntax tree. Processing macros is quite out of reach. I don't know much about cases where tracing with such rigor is required, so can't argue about the relevance. @stanislaw is more in that world.
I can only say that with tree-sitter it should be relatively simple to do a Rust implementation comparable to our current C implementation. We could even think about FFI-ing into syn. But I wouldn't change much about the StrictDoc model, the output would still be files, functions, lines.
@adfernandes @haxtibal this is a very good discussion! I can only summarize what I can from where I am with my limited knowledge and given your inputs.
-
I am not working with Rust myself at the moment, so the details you are talking about are already (slightly) beyond my immediate reach.
-
The project https://github.com/tree-sitter/tree-sitter-rust seems to be actively maintained. I cannot imagine that the maintainers would ignore your inputs if you reported them clearly with a GitHub issue. I do recognize that it is very often easier to implement your own tool that does exactly what you want, so I see both the advantages of using
tree-sitter-rust(arguments for using it were provided above by me and @haxtibal) and using your solution that goes deeper than what tree-sitter-rust does at the moment. -
StrictDoc is a moving target. There is nothing in the model that is hard-coded to last forever. If SDoc model is missing a construct beyond what's already there (there are Function, Range, File, Line markers), it should be possible to add a new concept. I am open to extensions with the only remark that we have to maintain them long-term, so they have to be pretty stable.
-
We are not blocked from interfacing JSON files (FFI is not necessarily a must!). Parsing JSON is what StrictDoc does with gcovr JSON files, and it pretty much works. Besides getting the immediate performance from parsing a single file, an equally important aspect is caching the parsed results. I was testing the SDoc document trees of 130+ documents, and there are challenges related to incremental parsing and caching of the intermediate artifacts (StrictDoc already does pickle all parsed results but there are more tricks that could be implemented).
-
So... it might be necessary to use external tools in the future. But that's just a guess on my part, you likely know the Python ecosystem for DWARF better if object-to-source mapping is on the StrictDoc roadmap.
No knowledge about this until now on my side, unfortunately. If the Python ecosystem does not provide a robust solution, we could switch to using Rust-based tools or any other tools through subprocess calls or similar. There are no strong drivers that would influence anything here just yet.
That said, before deciding whether to go with tree-sitter-rust or your solution, I would still like to see the missing aspects reported to the tree-sitter-rust team and get their feedback. Once we have a response from the maintainers, we could have a clearer idea of whether to choose one solution or attempt to support both. Whatever solution is ultimately used for parsing Rust, I am definitely open to extending StrictDoc's underlying model.
P.S. I am also writing this in between the intense days of my day job, so please let me know if I missed any key points from the discussion above.
@adfernandes, to make some progress here, let's do a quick check on the following:
- Are you yourself interested in 1) using StrictDoc and 2) contributing a reader based on your tool (sdoc-rs-relations)? If so, is there a chance your tool could be wrapped into a Python Pip package? Ideally, we would avoid introducing Rust tools to the
Getting startedinstructions just yet. - Could you summarize for me and @haxtibal in a single list, ideally with code snippets, which traceability examples you would like a Rust AST parser to handle? Alternatively, would you say that your example here is a complete list of features that StrictDoc must support: https://corten.systems/demo/sdoc-rs-relations/relations.html? The README has 4 examples but the files look similar and seem to be parsing the same things 🤔
- Would you be fine with using StrictDoc if it was based on tree-sitter-rust, not your tool, but all these features were supported? If you see showstoppers for tree-sitter-rust, please list them here in a single list.
- I feel like we need to start somewhere and starting with tree-sitter-rust seems to be a more natural choice but we are happy to slow down and give it more thoughts.
cc @haxtibal
@stanislaw Replies will be slow (sorry!) as I'm out of town for two weeks.
Are you yourself interested in 1) using StrictDoc and 2) contributing a reader based on your tool (sdoc-rs-relations)? If so, is there a chance your tool could be wrapped into a Python Pip package? Ideally, we would avoid introducing Rust tools to the Getting started instructions just yet.
Yes, I will be a user of StrictDoc (and already am, internally!)
Yes, I will be happy to contribute and maintain sdoc-rs-relations for/to the community.
Note the current temporary license is AGPL3.
I'm happy to re-license to Apache or MIT, I just hadn't done so because... well, I'm trying to make a living out of open-source and not use CLAs and not leave users at risk of "rug-pulls", so I'm being conservative with licensing for now.
Yes I'm happy to wrap the binaries up with pip and publish to PyPi - I've already done similar things (distrubute binaries) with the npm/nodejs community.
(There is the possibility of wrapping Rust source builds in a PyPi project, but that's a little more painful, but I'm still happy to do it, if required.)
Could you summarize for me and @haxtibal in a single list, ideally with code snippets, which traceability examples you would like a Rust AST parser to handle?
I will try - I can give more thorough examples later (I'm pressed for time right now).
Summary
- The only thing the
@relationstag need support is the name of the relation itself. - For the Rust case, the use of additional attributes such as
scope=are unnecessary. - The Rust language has a well-defined and heavily-used concept of "attributes" (unrelated to StrictDoc
@relationattributes).- Rust attributes are attached to well-defined "blocks of code", and these "blocks of code" are both well-defined and heavily used in the Rust language.
- Therefore a
@relation(...)tag, when used as a Rust#[doc = "... @relation(...) ..."]code attribute, is automatically explicitly associated with a Rust "code block". - No
scope=is necessary nor desireable because the core Rust language already specifies the scope.
-
tree-sitteris currently does not associate Rust#[...]attributes to code blocks.-
tree-sitteralso does not know what types of code blocks are allowed to have attributes as per the Rust language standard. - It seems (to me) to be highly non-trivial to properly associate Rust attributes to the correct type of Rust compilation "code blocks" in
tree-sitter.
-
The README has 4 examples but the files look similar and seem to be parsing the same things 🤔
Yes, sorry about that 😢. The examples look the same because they are.
I was exercising my @relations tag parser, allowing it to have attributes, so I made examples with and with out all sorts of tags.
Even though scope= is not needed, I wanted to test that @relation(REQ02-3, fizz=buzz, foo=bar) would work in the future, not just @relation(REQ02-3).
And I wrote proper parsers for it all. No regex-based "parsing" for me! 😄
Would you be fine with using StrictDoc if it was based on tree-sitter-rust, not your tool
Yes, more than happy! 😆 My ego is not involved in this at all.
If you see showstoppers for tree-sitter-rust, please list them here in a single list.
Showstoppers:
- Any ambiguity for what type of Rust "code block" the
@relationapplies to. - Any potential disagreement between the
@relationscope and the code-block attribute scope.
The reason is that Rust is designed, as much as possible, to be "safe by default", where (unlike the C family of languages) any ambiguity or inconsistency in the language is treated as an error.
I feel like we need to start somewhere and starting with tree-sitter-rust
Oh absolutely - I understand completely where you're coming from!
I basically landed on my current design because I was just implementing @relation with the scope= tag, exactly as documented currently by Strict Doc.
But then I started thinking about what values the scope= attribute could have.
Rust's notion of "functions" are rather more involved than C or C++.
And Rust's notion of "compilation unit" is not based on singe-files, like C/C++.
And Rust's notion of "modules" (only vaguely related to C++ namespaces) are more complex than C++.
Then I realized that Rust doc-comments are actually "compiler directives".
Since doc-comments are compiler directives - they're often used for conditional compilation, for example - they are the natural and only "meaningful block of code" that Rust has.
Then I realized that that meant the scope= attribute on @relation really wasn't needed, nor even desirable, in Rust.
At least, that's the mental journey I took.
(Reminder - replies will be delayed since I'll be away!)
I really can't stress how thankful I am for StrictDoc and how inspiring it has been for me/us in the safety-critical space.
The current Rust Safety-Critical Working Group is using sphinx-needs and... I'm much, much, much happier with StrictDoc... and really wanted to begin contributing back!
@adfernandes Thanks for this great explanations! Just a quick note, no immediate response required.
For the Rust case, the use of additional attributes such as scope= are unnecessary.
Have you seen Linking a requirement to a function in a source file? We'll want to support that similar to C and Python:
[REQUIREMENT]
UID: REQ-1
TITLE: Function and class forward reference
STATEMENT: This requirement references a function in a file and a class in another file.
RELATIONS:
- TYPE: File
VALUE: file.c
FUNCTION: Foo.hello_world_2
- TYPE: File
VALUE: file.py
CLASS: Foo
The FUNCTION and CLASS keywords are the scope, and they need to be defined in StrictDoc's textX grammar. Any idea how this should this look like in the Rust case?
@adfernandes I believe to have found a set of tree-sitter queries to query all kinds of doc comments (inner, outer, line, block, attribute) along with their associated target Rust item and tested it against your demo source code.
Could you review if output.txt matches your expectation?
I wish I could also do such a nice interactive demo, but my limited js skills stand against it ;-)