refactor(plantuml): introduce Rust idmap generation and CLI source-aware output wiring#321
refactor(plantuml): introduce Rust idmap generation and CLI source-aware output wiring#321AAmbuj wants to merge 2 commits into
Conversation
| /// Stable workspace-relative source name baked into generated artifacts | ||
| /// (FlatBuffers/lobster/idmap ``source`` field). When omitted, the | ||
| /// filesystem basename is used as a fallback. | ||
| #[arg(long)] | ||
| source_name: Option<String>, |
There was a problem hiding this comment.
--source-name doesn't scale to multiple input files because a single CLI argument cannot be mapped unambiguously to multiple sources. The source field is a property of each input file and should be derived from the file path itself (preferably converted to a workspace-relative path), rather than being supplied independently by the caller.
There was a problem hiding this comment.
Addressed. I removed the CLI-level source override and now derive source per input file path, using workspace-relative paths when possible.
| ResolvedDiagram::Sequence(_) => LobsterModel::Empty, | ||
| }; | ||
| write_lobster_to_file(lobster_model, path, ldir)?; | ||
| write_lobster_to_file(lobster_model, path, Some(source_file), ldir)?; |
There was a problem hiding this comment.
path and source_file are effectively the same thing. I don't think we need to change fucntion write_lobster_to_file signature here.
There was a problem hiding this comment.
Addressed. I simplified the lobster writer API to take a direct source path string (not an optional override), and updated call sites accordingly.
| /// `true` when this diagram elaborates the element (i.e. it is listed | ||
| /// under `defines`). Omitted from the JSON for plain references. | ||
| #[serde(default, skip_serializing_if = "is_not_elaborated")] | ||
| pub elaborated: bool, |
There was a problem hiding this comment.
Is elaborated still needed here? The split between defines and references already conveys the same information. Unless there are cases where a define can be non-elaborated (or a reference elaborated), this field seems redundant.
There was a problem hiding this comment.
I removed elaborated from idmap entries. Define/reference role is now represented only by membership in defines vs references arrays.
| /// `parent_id` (i.e. it has children and is therefore elaborated here). | ||
| /// All remaining elements are **references** (top-level leaves that mention | ||
| /// something that may be detailed in another diagram). | ||
| fn comp_model_to_idmap( |
There was a problem hiding this comment.
One question: how should packages be handled in this case?
For example:
package P {
component A {
component AA
}
}
Since both package P and component A have children, the current rule "elements with children" seems to classify both as defines. Is that the intended behavior, or should packages be treated purely as containers/namespaces rather than emitted as definitions?
There was a problem hiding this comment.
Packages are now treated as containers/namespaces and are not emitted as idmap define/reference entrie
| let has_members = !entity.methods.is_empty() || !entity.variables.is_empty(); | ||
| let matches_diagram_name = diagram_name == Some(entity.name.as_str()); | ||
| let is_define = has_members || matches_diagram_name; | ||
| let entry = IdMapEntry { |
There was a problem hiding this comment.
I don't see any handling of entity.relationships here. Since the proposal defines references to include relation endpoints, shouldn't those be emitted as reference entries as well?
There was a problem hiding this comment.
I now add relationship source/target endpoints as references (deduplicated, and not duplicating defines).
| } | ||
|
|
||
| /// Collect the unique participant names from a sequence tree. | ||
| fn collect_participants(tree: &SequenceTree) -> HashSet<String> { |
There was a problem hiding this comment.
This currently derives participants from interaction endpoints (caller/callee). We have a planned follow-up to persist participant declarations in the AST, so this logic should be updated to use the explicit participant list instead of reconstructing it here.
There was a problem hiding this comment.
Partially addressed for now. The current SequenceTree model does not yet persist explicit participant declarations, so behavior remains endpoint-derived. I added a TODO marker to switch to declaration-based sourcing once the resolver/AST exposes participants explicitly.
| Class(&'a ClassDiagram), | ||
| Sequence(&'a SequenceTree), | ||
| Fta(&'a FtaModel), | ||
| Empty, |
There was a problem hiding this comment.
Do we really need the Empty variant here? It seems to conflate several different states (no model, unsupported diagram type, empty diagram, parse failure, etc.).
There was a problem hiding this comment.
I removed Empty from IdMapModel and introduced an explicit empty writer API used only where intentionally empty output is desired (for example activity diagrams).
Emits a per-source .idmap.json with defines[] / references[] entries used by the clickable_plantuml Sphinx extension to resolve cross-diagram links. Supports Component, Class, Sequence, Activity (empty), and FTA diagrams.
f551a99 to
eb2921f
Compare
Calls write_idmap_to_file() for every resolved diagram. Passes short_path as source_name so both idmap and lobster outputs use the stable workspace-relative path rather than the sandbox-local filesystem path.
eb2921f to
b4dcb24
Compare
This change introduces a Rust-native idmap generation flow in the PlantUML parser pipeline and wires the CLI to emit source-aware idmap outputs.
What is included:
Why: