From 28b045984b3bbd209f936a4fc91bc163bb487abf Mon Sep 17 00:00:00 2001 From: sheng Date: Mon, 21 Sep 2026 09:00:35 +0800 Subject: [PATCH 1/3] add uid in parser --- .../examples/seooc/design/dynamic_design.puml | 4 +- .../examples/seooc/design/public_api.puml | 6 +- .../examples/seooc/design/static_design.puml | 2 +- .../sample_fmea_failure_modes.trlc | 4 +- .../private/architectural_design.bzl | 4 +- .../rules/rules_score/private/puml_utils.bzl | 15 + bazel/rules/rules_score/private/unit.bzl | 2 + .../rules/rules_score/private/unit_design.bzl | 3 + cpp/libclang/cpp_parser.bzl | 7 + cpp/libclang/src/main.rs | 41 +- .../output.json | 2 +- .../class_diagram_syntax_coverage/output.json | 2 +- .../output.yaml | 17 + ...fied_name_does_not_search_descendants.puml | 27 + .../relation_quoted_name/output.json | 6 +- .../combined_lifecycle_suffix/output.json | 6 +- .../output.json | 8 +- .../invalid_duplicate_participant_id.puml | 19 + .../output.yaml | 18 + ...alid_free_text_participant_identifier.puml | 21 + .../output.yaml | 19 + .../output.json | 3 +- .../output.json | 25 +- .../participant_identifier_examples.puml | 5 +- .../output.json | 6 +- .../sequence_arrow_direction/output.json | 36 +- .../sequence_branch_node/output.json | 6 +- .../sequence_early_exit_node/output.json | 6 +- .../sequence_group_container/output.json | 6 +- .../sequence_interaction_node/output.json | 6 +- .../sequence_lifecycle_nodes/output.json | 9 +- .../sequence_loop_node/output.json | 6 +- .../sequence_message_direction/output.json | 3 + .../sequence_parallel_node/output.json | 9 +- .../sequence_reference_node/output.json | 6 +- .../simple_sequence/output.json | 69 +-- .../integration_test/src/test_error_view.rs | 14 + plantuml/parser/puml_cli/src/main.rs | 88 +++- plantuml/parser/puml_idmap/src/lib.rs | 1 + plantuml/parser/puml_resolver/BUILD | 21 +- .../puml_resolver/src/class_diagram/BUILD | 2 + .../src/class_diagram/src/class_resolver.rs | 246 +++++++-- .../puml_resolver/src/component_diagram/BUILD | 4 + .../src/component_resolver.rs | 93 ++-- .../tests/component_resolver_test.rs | 5 + .../puml_resolver/src/sequence_diagram/BUILD | 4 + .../src/sequence_diagram/src/error.rs | 15 + .../sequence_diagram/src/participant_table.rs | 495 ++++++++++++++++-- .../sequence_diagram/src/sequence_resolver.rs | 34 +- .../src/statement_resolver.rs | 251 +++++++-- .../tests/sequence_resolver_test.rs | 12 +- .../puml_resolver/src/uid_normalization.rs | 248 +++++++++ tools/metamodel/common/BUILD | 15 +- tools/metamodel/common/uid_utils.rs | 76 +++ tools/metamodel/sequence/sequence_logic.rs | 2 + .../flatbuffers/sequence/sequence_diagram.fbs | 2 + .../sequence/sequence_serializer.rs | 6 + 57 files changed, 1765 insertions(+), 303 deletions(-) create mode 100644 plantuml/parser/integration_test/component_diagram/qualified_name_does_not_search_descendants/output.yaml create mode 100644 plantuml/parser/integration_test/component_diagram/qualified_name_does_not_search_descendants/qualified_name_does_not_search_descendants.puml create mode 100644 plantuml/parser/integration_test/sequence_diagram/invalid_duplicate_participant_id/invalid_duplicate_participant_id.puml create mode 100644 plantuml/parser/integration_test/sequence_diagram/invalid_duplicate_participant_id/output.yaml create mode 100644 plantuml/parser/integration_test/sequence_diagram/invalid_free_text_participant_identifier/invalid_free_text_participant_identifier.puml create mode 100644 plantuml/parser/integration_test/sequence_diagram/invalid_free_text_participant_identifier/output.yaml create mode 100644 plantuml/parser/puml_resolver/src/uid_normalization.rs create mode 100644 tools/metamodel/common/uid_utils.rs diff --git a/bazel/rules/rules_score/examples/seooc/design/dynamic_design.puml b/bazel/rules/rules_score/examples/seooc/design/dynamic_design.puml index 5fe8e442..4d364ecd 100644 --- a/bazel/rules/rules_score/examples/seooc/design/dynamic_design.puml +++ b/bazel/rules/rules_score/examples/seooc/design/dynamic_design.puml @@ -13,8 +13,8 @@ @startuml -participant "Unit 1" as unit_1 <> -participant "Unit 2" as unit_2 <> +participant "Unit 1 : safety_software_seooc_example::component_example::unit_1" as unit_1 <> +participant "Unit 2 : safety_software_seooc_example::component_example::unit_2" as unit_2 <> unit_1 -> unit_2 : GetData() return Data* diff --git a/bazel/rules/rules_score/examples/seooc/design/public_api.puml b/bazel/rules/rules_score/examples/seooc/design/public_api.puml index 61818294..760db8e3 100644 --- a/bazel/rules/rules_score/examples/seooc/design/public_api.puml +++ b/bazel/rules/rules_score/examples/seooc/design/public_api.puml @@ -13,10 +13,8 @@ @startuml -namespace safety_software_seooc_example { - interface "SampleLibraryAPI" as SampleLibraryAPI { - + GetNumber(): int - } +interface "SampleLibraryAPI" as SampleLibraryAPI <> { + + GetNumber(): int } @enduml diff --git a/bazel/rules/rules_score/examples/seooc/design/static_design.puml b/bazel/rules/rules_score/examples/seooc/design/static_design.puml index 1bb80210..ef85542f 100644 --- a/bazel/rules/rules_score/examples/seooc/design/static_design.puml +++ b/bazel/rules/rules_score/examples/seooc/design/static_design.puml @@ -21,7 +21,7 @@ package "Safety Software SEooC Example" as safety_software_seooc_example <, + + /// Resolver root anchor for IDs emitted by this parser (internal use only) + #[arg(long, hide = true, default_value = "")] + root_anchor: String, } #[derive(Default)] @@ -210,6 +214,37 @@ fn serialize_class_diagram( Ok(()) } +fn apply_root_anchor( + entities: &mut BTreeMap, + free_functions: &mut [FreeFunctionDecl], + root_anchor: &str, +) { + if root_anchor.is_empty() { + return; + } + + let mut anchored_entities = BTreeMap::new(); + for (_, mut entity) in std::mem::take(entities) { + entity.id = format!("{root_anchor}::{}", entity.id); + entity.enclosing_namespace_id = entity + .enclosing_namespace_id + .map(|namespace| format!("{root_anchor}::{namespace}")); + for relationship in &mut entity.relationships { + relationship.source = format!("{root_anchor}::{}", relationship.source); + relationship.target = format!("{root_anchor}::{}", relationship.target); + } + anchored_entities.insert(entity.id.clone(), entity); + } + *entities = anchored_entities; + + for free_function in free_functions { + free_function.enclosing_namespace_id = Some(match &free_function.enclosing_namespace_id { + Some(namespace) if !namespace.is_empty() => format!("{root_anchor}::{namespace}"), + _ => root_anchor.to_string(), + }); + } +} + fn ensure_output_parent_exists(path: &Path) -> Result<(), std::io::Error> { if let Some(parent) = path.parent() { fs::create_dir_all(parent)?; @@ -251,6 +286,11 @@ fn main() -> Result<(), Box> { ); } + apply_root_anchor( + &mut outputs.types, + &mut outputs.free_function_declarations, + &command_line_args.root_anchor, + ); if let Some(debug_json_output) = &command_line_args.debug_json_output { write_debug_json( debug_json_output, @@ -260,7 +300,6 @@ fn main() -> Result<(), Box> { &outputs.functions, )?; } - serialize_class_diagram( &command_line_args.class_fbs_output, outputs.types, diff --git a/plantuml/parser/integration_test/class_diagram/class_diagram_file_level_constructs/output.json b/plantuml/parser/integration_test/class_diagram/class_diagram_file_level_constructs/output.json index b58281b6..3fb46826 100644 --- a/plantuml/parser/integration_test/class_diagram/class_diagram_file_level_constructs/output.json +++ b/plantuml/parser/integration_test/class_diagram/class_diagram_file_level_constructs/output.json @@ -70,7 +70,7 @@ } }, { - "id": "sample.file_level.<