[plantuml tooling] prepare uid refactor - #489
Merged
Merged
Conversation
hoe-jo
commented
Sep 30, 2026
Contributor
- create common helper functions for naming
- implement cross diagram test suite
- update docs
… checks in CI
- Add tools/metamodel/common/uid_utils crate: dependency-free identifier
normalization primitives (normalize, normalized_segments, join,
is_identifier_path, strip_anchor), with unit tests.
- Replace the duplicated normalize_fqn implementations in
class_parser.rs (IgnoredObjectRegistry) and class_resolver.rs
(ClassResolver) with calls to uid_utils::normalize. No behavior change.
- Give is_identifier_path its first real caller: class_resolver.rs's FQN
check now uses it instead of an ad hoc `name.contains('.') ||
name.contains("::")`. No behavior change.
- join() now filters out empty parts before allocating, instead of
joining them in as empty segments.
- strip_anchor() is rewritten to compare normalized path segments
instead of doing a raw string strip_prefix, fixing a bug where an
interior empty segment (e.g. "score.logging..x" with anchor
"score.logging") produced ".x" instead of "x".
- Add //tools/... to the tooling_checks CI job (clippy + test), which was
previously not covered by CI.
- Fix a pre-existing clippy::redundant_field_names in
sequence_serializer.rs, required for the new //tools/... clippy step
to pass cleanly.
- Add puml_utils::label_markup: single source of truth for recognizing and stripping PlantUML inline style markup (<b>, <i>, <color:...>, </color>, etc.) and decoding \n escapes, with unit tests. - creole_tag_length() in the activity-diagram normalizer now delegates to puml_utils::style_markup_tag_length instead of its own ~20-line duplicate, which only matched opening color:/back:/size: forms. The now-redundant wrapper function is removed; the call site calls puml_utils::style_markup_tag_length directly. - is_style_markup_tag is private to the module (no longer re-exported); no caller outside label_markup needs it. - normalize_rule_b_label is renamed to normalize_identity_label, since no caller of it exists yet in this PR and "Rule B" is premature terminology to expose at the module boundary. - KNOWN_TAGS/STYLED_TAGS are declared as `&[&str]` instead of `[&str; N]`, so their length doesn't need to be kept in sync manually. Behavior change (bug fix): closing style tags such as </color>, </back>, </size> used to leak into normalized activity labels as literal text; they are now correctly stripped. Added regression tests covering this and case-insensitivity/whitespace handling around style tags, and non-ASCII text in labels. No other diagram type is affected.
Add plantuml/parser/integration_test/cross_diagram: an end-to-end suite that shells out to the puml_cli binary and asserts on its --idmap-output-dir JSON output. Seed cases pin down today's idmap behavior with goldens, so later changes to identifier derivation show up as a readable golden-file diff instead of silent regressions: - component_nesting: nested package/component ids, including an unaliased nested component and a same-named sequence participant that today does not accidentally link to it - class_alias_wins: today's class id is the label, not the alias - namespace_and_package: namespace and package both contribute dotted scope - sequence_forms: sequence participants are always references, id == alias verbatim, independent of the display label - prose_without_alias: a prose participant label with no alias and an implicit participant created by referencing a display name in an arrow are both accepted today (no diagnostic yet) - linking_three_diagrams: component/class/sequence linking by matching alias at the top level - qualified_reference: a `::`-qualified relationship endpoint (e.g. `A --> a::B`) is rejected today instead of being resolved Cases requiring not-yet-implemented behavior (root anchor, sequence Rule B forms, qualified reference resolution, ExternalEndpoint) are intentionally deferred to the PRs that implement them. Harness hardening: - Golden entries are keyed by an IdSet (one or more ids per alias) instead of a single id, so an alias that resolves to more than one id can be expressed in a golden instead of silently collapsing. - resolve_ref() panics if a reference resolves to more than one id, or appears in both defines and references, instead of picking one silently. - validate_case_config() checks that every diagram_types key and every links/distinct file#Alias reference names a real file, and that every links/distinct group has at least two entries. - The suite is driven by test_framework::run_case (the same driver used by the other diagram parser/resolver suites): a PumlCliIdmapRunner (DiagramProcessor) shells out to puml_cli per file, and a CrossDiagramChecker (ExpectationChecker) adds the links/distinct cross-file id assertions via the new check_case hook on top of the framework's default per-file checks. Golden files follow the shared convention: output.json for success cases, output.yaml for cases where the file is expected to fail. - A cross_diagram_cases! macro generates one #[test] per case plus a guard test that compares the registered case names against the case directories actually on disk, so an added directory can't be forgotten. discover_case_names() only counts a directory as a case if it directly contains a .puml file, so it doesn't get confused by sibling directories the test runner places alongside the case directories at runtime.
- element-identifiers.md: add an 'Implementation status' section (new
section 0) that tracks, per topic, whether main implements the target
design described in the rest of the guide, with a Test case column
pointing at the corresponding cross_diagram case:
- Id normalization is implemented for scope paths inside one class
diagram, but `::` in class/component relationship endpoints (e.g.
`A --> ns::B`) is rejected rather than normalized.
- Label markup stripping is implemented for activity diagram labels
only, not yet for sequence participant labels.
- Sequence <-> component/class linking only works today when both
sides use a plain, un-nested alias, not "at the Bazel-package root"
as previously stated.
- Root anchor, class alias-wins, sequence Rule B, qualified reference
resolution, ExternalEndpoint, and the new diagnostics remain not
implemented.
- Fold section 9 ("Current limitations") into section 0: its two bug
entries (qualified name inside a nested declaration, non-identifier-
based sequence hyperlinks) now live in the status table, and section 9
is reduced to a pointer at section 0 instead of a second, divergent
list. The unsubstantiated "Cross-diagrams in Class Diagrams also have
a bug currently" bullet is dropped.
- Rename "The four forms" heading to "The label forms": the table under
it has five rows, not four.
- sequence-diagram.md: mark the two claims that describe rejection
behavior which does not exist yet (free-text participant without an
alias, and referencing a declared participant by its display name) as
not yet implemented, with a pointer to the new status section.
Docs only, no code change.
hoe-jo
requested review from
LittleHuba,
castler,
limdor and
ramceb
as code owners
September 30, 2026 10:57
castler
approved these changes
Sep 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.