diff --git a/src/sequence_diagram/model/diagram.cc b/src/sequence_diagram/model/diagram.cc index 434a7538..5e691f47 100644 --- a/src/sequence_diagram/model/diagram.cc +++ b/src/sequence_diagram/model/diagram.cc @@ -497,18 +497,18 @@ bool diagram::inline_lambda_operator_call(const common::id_t id, get_participant(parent_class_id); if (maybe_parent_class && maybe_parent_class.value().is_lambda()) { - // auto new_message{m}; - // new_message.set_ - auto lambda_operator_activity = get_activity(m.to()); + if (has_activity(m.to())) { + auto lambda_operator_activity = get_activity(m.to()); - // For each call in that lambda activity - reattach this - // call to the current activity - for (auto &mm : lambda_operator_activity.messages()) { - if (!inline_lambda_operator_call(id, new_activity, mm)) { - auto new_message{mm}; + // For each call in that lambda activity - reattach this + // call to the current activity + for (auto &mm : lambda_operator_activity.messages()) { + if (!inline_lambda_operator_call(id, new_activity, mm)) { + auto new_message{mm}; - new_message.set_from(id); - new_activity.add_message(new_message); + new_message.set_from(id); + new_activity.add_message(new_message); + } } } diff --git a/tests/t20053/.clang-uml b/tests/t20053/.clang-uml new file mode 100644 index 00000000..1387e310 --- /dev/null +++ b/tests/t20053/.clang-uml @@ -0,0 +1,12 @@ +diagrams: + t20053_sequence: + type: sequence + glob: + - t20053.cc + include: + namespaces: + - clanguml::t20053 + using_namespace: clanguml::t20053 + inline_lambda_messages: true + from: + - function: "clanguml::t20053::tmain()" \ No newline at end of file diff --git a/tests/t20053/t20053.cc b/tests/t20053/t20053.cc new file mode 100644 index 00000000..03b1c39a --- /dev/null +++ b/tests/t20053/t20053.cc @@ -0,0 +1,28 @@ +namespace clanguml { +namespace t20053 { +template int a1(F &&f) { return f(42); } + +int a2(int x) { return 2; } + +int a3(int x) { return 3; } + +int tmain() +{ + // Call expression in a nested lambda + auto v1 = [](auto &&arg1) { + return [](auto &&arg2) { return a2(arg2); }(arg1); + }(0); + + // Nested lambda call without any actual calls + auto v2 = [](auto &&arg1) { + return [](auto &&arg2) { return arg2 + 2; }(arg1); + }(0); + + // Call expression in a nested lambda in call expression + auto v4 = a1( + [](auto &&arg1) { return [](auto &&arg2) { return a3(arg2); }(arg1); }); + + return 0; +} +} +} \ No newline at end of file diff --git a/tests/t20053/test_case.h b/tests/t20053/test_case.h new file mode 100644 index 00000000..29dab3e6 --- /dev/null +++ b/tests/t20053/test_case.h @@ -0,0 +1,70 @@ +/** + * tests/t20053/test_case.h + * + * Copyright (c) 2021-2024 Bartek Kryza + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +TEST_CASE("t20053", "[test-case][sequence]") +{ + auto [config, db] = load_config("t20053"); + + auto diagram = config.diagrams["t20053_sequence"]; + + REQUIRE(diagram->name == "t20053_sequence"); + + auto model = generate_sequence_diagram(*db, diagram); + + REQUIRE(model->name() == "t20053_sequence"); + + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); + + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); + + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("a2(int)"), "")); + + REQUIRE_THAT(src, + HasCall(_A("tmain()"), + _A("a1<(lambda at t20053.cc:23:9)>((lambda at t20053.cc:23:9) " + "&&)"), + "")); + + REQUIRE_THAT(src, + HasCall(_A("a1<(lambda at t20053.cc:23:9)>((lambda at " + "t20053.cc:23:9) &&)"), + _A("a3(int)"), "")); + + save_puml(config.output_directory(), diagram->name + ".puml", src); + } + + { + auto j = generate_sequence_json(diagram, *model); + + using namespace json; + + save_json(config.output_directory(), diagram->name + ".json", j); + } + + { + auto src = generate_sequence_mermaid(diagram, *model); + + mermaid::AliasMatcher _A(src); + using mermaid::IsClass; + + save_mermaid(config.output_directory(), diagram->name + ".mmd", src); + } +} \ No newline at end of file diff --git a/tests/test_cases.cc b/tests/test_cases.cc index 80ea3778..524f994e 100644 --- a/tests/test_cases.cc +++ b/tests/test_cases.cc @@ -481,6 +481,7 @@ using namespace clanguml::test::matchers; #include "t20051/test_case.h" #endif #include "t20052/test_case.h" +#include "t20053/test_case.h" /// /// Package diagram tests diff --git a/tests/test_cases.yaml b/tests/test_cases.yaml index 9e61d031..573e6998 100644 --- a/tests/test_cases.yaml +++ b/tests/test_cases.yaml @@ -377,7 +377,10 @@ test_cases: title: Test case for CUDA calls callee_type filter description: - name: t20052 - title: Test case for CUDA calls callee_type filter + title: Test case for inlining lambda operator calls + description: + - name: t20053 + title: Test case for inlining nested lambda operator calls description: Package diagrams: - name: t30001