Skip to content

Commit cb0eaeb

Browse files
shengzhangscorehoe-jo
authored andcommitted
add gMock MOCK_METHOD support
1 parent 1838e68 commit cb0eaeb

23 files changed

Lines changed: 602 additions & 6 deletions

File tree

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# *******************************************************************************
2+
# Copyright (c) 2026 Contributors to the Eclipse Foundation
3+
#
4+
# See the NOTICE file(s) distributed with this work for additional
5+
# information regarding copyright ownership.
6+
#
7+
# This program and the accompanying materials are made available under the
8+
# terms of the Apache License Version 2.0 which is available at
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# SPDX-License-Identifier: Apache-2.0
12+
# *******************************************************************************
13+
load("//cpp/libclang/integration_test:test_rules.bzl", "cpp_parser_integration_test")
14+
15+
cc_library(
16+
name = "method_modifier_final",
17+
srcs = ["final_sample.cpp"],
18+
visibility = ["//cpp/libclang:__subpackages__"],
19+
)
20+
21+
cpp_parser_integration_test(
22+
name = "test_method_modifier_final",
23+
expected_output = ["expected.json"],
24+
target = ":method_modifier_final",
25+
)
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
{
2+
"types": {
3+
"FinalMethodBase": {
4+
"id": "FinalMethodBase",
5+
"name": "FinalMethodBase",
6+
"enclosing_namespace_id": null,
7+
"stereotypes": [],
8+
"entity_type": "Class",
9+
"type_aliases": [],
10+
"variables": [],
11+
"methods": [
12+
{
13+
"name": "sealedHere",
14+
"return_type": "void",
15+
"visibility": "public",
16+
"parameters": [],
17+
"template_parameters": null,
18+
"modifiers": [
19+
"Virtual",
20+
"Final"
21+
],
22+
"source_location": {
23+
"file": "cpp/libclang/integration_test/cases/method_modifier_final/final_sample.cpp",
24+
"line": 16
25+
}
26+
},
27+
{
28+
"name": "overridable",
29+
"return_type": "void",
30+
"visibility": "public",
31+
"parameters": [],
32+
"template_parameters": null,
33+
"modifiers": [
34+
"Virtual"
35+
],
36+
"source_location": {
37+
"file": "cpp/libclang/integration_test/cases/method_modifier_final/final_sample.cpp",
38+
"line": 17
39+
}
40+
}
41+
],
42+
"template_parameters": null,
43+
"enum_literals": [],
44+
"relationships": [],
45+
"source_location": {
46+
"file": "cpp/libclang/integration_test/cases/method_modifier_final/final_sample.cpp",
47+
"line": 14
48+
}
49+
},
50+
"FinalMethodDerived": {
51+
"id": "FinalMethodDerived",
52+
"name": "FinalMethodDerived",
53+
"enclosing_namespace_id": null,
54+
"stereotypes": [],
55+
"entity_type": "Class",
56+
"type_aliases": [],
57+
"variables": [],
58+
"methods": [
59+
{
60+
"name": "overridable",
61+
"return_type": "void",
62+
"visibility": "public",
63+
"parameters": [],
64+
"template_parameters": null,
65+
"modifiers": [
66+
"Virtual",
67+
"Override",
68+
"Final"
69+
],
70+
"source_location": {
71+
"file": "cpp/libclang/integration_test/cases/method_modifier_final/final_sample.cpp",
72+
"line": 22
73+
}
74+
}
75+
],
76+
"template_parameters": null,
77+
"enum_literals": [],
78+
"relationships": [
79+
{
80+
"source": "FinalMethodDerived",
81+
"target": "FinalMethodBase",
82+
"relation_type": "Inheritance",
83+
"source_multiplicity": null,
84+
"target_multiplicity": null,
85+
"source_location": {
86+
"file": "cpp/libclang/integration_test/cases/method_modifier_final/final_sample.cpp",
87+
"line": 20
88+
}
89+
}
90+
],
91+
"source_location": {
92+
"file": "cpp/libclang/integration_test/cases/method_modifier_final/final_sample.cpp",
93+
"line": 20
94+
}
95+
}
96+
},
97+
"functions": []
98+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/********************************************************************************
2+
* Copyright (c) 2026 Contributors to the Eclipse Foundation
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information regarding copyright ownership.
6+
*
7+
* This program and the accompanying materials are made available under the
8+
* terms of the Apache License Version 2.0 which is available at
9+
* https://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* SPDX-License-Identifier: Apache-2.0
12+
********************************************************************************/
13+
14+
class FinalMethodBase {
15+
public:
16+
virtual void sealedHere() final;
17+
virtual void overridable();
18+
};
19+
20+
class FinalMethodDerived : public FinalMethodBase {
21+
public:
22+
void overridable() override final;
23+
};
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// *******************************************************************************
2+
// Copyright (c) 2026 Contributors to the Eclipse Foundation
3+
//
4+
// See the NOTICE file(s) distributed with this work for additional
5+
// information regarding copyright ownership.
6+
//
7+
// This program and the accompanying materials are made available under the
8+
// terms of the Apache License Version 2.0 which is available at
9+
// <https://www.apache.org/licenses/LICENSE-2.0>
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
// *******************************************************************************
13+
14+
use test_framework::run_parser_case;
15+
16+
#[test]
17+
fn test_method_modifier_final() {
18+
run_parser_case();
19+
}

‎cpp/libclang/src/visitor/src/class_visitor.rs‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,10 @@ fn parse_method(entity: &Entity, parsed_method_type: &ParsedMethodType) -> Optio
250250
.get_overridden_methods()
251251
.map(|methods| !methods.is_empty())
252252
.unwrap_or(false);
253+
let is_final_method = entity
254+
.get_children()
255+
.into_iter()
256+
.any(|child| child.get_kind() == EntityKind::FinalAttr);
253257

254258
// Only the bare `noexcept` specifier is modeled (mirrors the PlantUML grammar, which has
255259
// no support for the conditional `noexcept(expr)` form). Requiring `BasicNoexcept` filters
@@ -326,6 +330,7 @@ fn parse_method(entity: &Entity, parsed_method_type: &ParsedMethodType) -> Optio
326330
(is_noexcept_method, MethodModifier::Noexcept),
327331
(kind == EntityKind::Constructor, MethodModifier::Constructor),
328332
(kind == EntityKind::Destructor, MethodModifier::Destructor),
333+
(is_final_method, MethodModifier::Final),
329334
]),
330335
source_location: parse_source_location(entity),
331336
})

‎plantuml/parser/puml_parser/src/class_diagram/src/class_parser.rs‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -456,9 +456,8 @@ impl ClassParseSession<'_> {
456456
| Rule::override_modifier
457457
| Rule::const_method_qualifier
458458
| Rule::noexcept_method_qualifier
459-
| Rule::trailing_override_qualifier => {
460-
method.modifiers.push(p.as_str().to_string())
461-
}
459+
| Rule::trailing_override_qualifier
460+
| Rule::final_method_qualifier => method.modifiers.push(p.as_str().to_string()),
462461
Rule::friend_specifier => method.is_friend = true,
463462
Rule::pure_virtual_suffix => ensure_abstract_modifier(&mut method),
464463
Rule::class_visibility => vis = Some(p),
@@ -524,6 +523,8 @@ impl ClassParseSession<'_> {
524523
}
525524
Rule::class_body => {
526525
for inner in pair.into_inner() {
526+
// Intentionally visit only Rule::class_member; mock_method_invocation pairs
527+
// are modeled as absent from the class diagram, not as real methods.
527528
if let Rule::class_member = inner.as_rule() {
528529
for member in inner.into_inner() {
529530
self.parse_class_member_into(member, def)?;

‎plantuml/parser/puml_parser/src/class_diagram/test/integration_test.rs‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,16 @@ fn test_method_modifier_placement() {
105105
run_class_diagram_parser_case("method_modifier_placement");
106106
}
107107

108+
#[test]
109+
fn test_mock_method_variants_ignored() {
110+
run_class_diagram_parser_case("mock_method_variants_ignored");
111+
}
112+
113+
#[test]
114+
fn test_mock_method_interleaved_members_survive() {
115+
run_class_diagram_parser_case("mock_method_interleaved_members_survive");
116+
}
117+
108118
#[test]
109119
fn test_multiline_note() {
110120
run_class_diagram_parser_case("multiline_note");

0 commit comments

Comments
 (0)