Skip to content

Commit 219872f

Browse files
authored
Fix method name collisions for getProperties() (#434)
* Fix method name collisions for getProperties() * Add a specialized method to fix name collisions for getProperties().
1 parent ae56c9d commit 219872f

File tree

5 files changed

+59
-2
lines changed

5 files changed

+59
-2
lines changed

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ source env/bin/activate
5454
pip3 install -e /path/to/cloudformation-cli-java-plugin
5555
```
5656

57+
Install `pytest-cov`, used when running unit tests for this plugin:
58+
59+
```shell
60+
pip3 install pytest-cov
61+
```
62+
5763
You may also want to check out the [CloudFormation CLI](https://github.com/aws-cloudformation/cloudformation-cli) if you wish to make edits to that. In this case, installing them in one operation works well:
5864

5965
```shell

python/rpdk/java/codegen.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@
1717

1818
from . import __version__
1919
from .resolver import UNDEFINED, translate_type
20-
from .utils import safe_reserved, validate_codegen_model, validate_namespace
20+
from .utils import (
21+
safe_reserved,
22+
safe_reserved_hook_target,
23+
validate_codegen_model,
24+
validate_namespace,
25+
)
2126

2227
LOG = logging.getLogger(__name__)
2328

@@ -86,6 +91,7 @@ def __init__(self):
8691
self.codegen_template_path = None
8792
self.env.filters["translate_type"] = translate_type
8893
self.env.filters["safe_reserved"] = safe_reserved
94+
self.env.filters["safe_reserved_hook_target"] = safe_reserved_hook_target
8995
self.namespace = None
9096
self.package_name = None
9197

python/rpdk/java/templates/generate/hook/ResourceHookTarget.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public class {{ model_name|uppercase_first_letter }} extends ResourceHookTarget
4747

4848
{% for name, type in properties.items() %}
4949
@JsonProperty("{{ name }}")
50-
private {{ type|translate_type }} {{ name|lowercase_first_letter|safe_reserved }};
50+
private {{ type|translate_type }} {{ name|lowercase_first_letter|safe_reserved_hook_target }};
5151

5252
{% endfor %}
5353
@JsonIgnore

python/rpdk/java/utils.py

+36
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,48 @@
5858
}
5959

6060

61+
# Keywords used in the context of AWS CloudFormation Hooks, when
62+
# classes are generated, by this plugin, for target resource
63+
# types. For example, the `properties` item below is marked as a
64+
# keyword because if a target resource type has a property called
65+
# `Properties` (see the `AWS::ApiGateway::DocumentationPart` resource
66+
# type as one of the examples), the generated class code for the
67+
# target resource type will contain a getter, `getProperties()`, that
68+
# will collide with `getProperties()` that is already defined for
69+
# `ResourceHookTarget`. By marking `properties` as a keyword, the
70+
# generated code for the class will still have a relevant, private
71+
# variable for the resource type target's property, but whose name
72+
# will contain an underscore as a suffix: the Lombok-generated getter
73+
# (and setter) for that private variable will, in turn, contain an
74+
# underscore suffix as well; see `safe_reserved_hook_target()` below
75+
# for more information (`safe_reserved_hook_target()` is, in turn,
76+
# consumed by other parts of a hook's code generation logic in this
77+
# plugin).
78+
HOOK_TARGET_KEYWORDS = {
79+
"properties",
80+
}
81+
82+
6183
def safe_reserved(token):
6284
if token in LANGUAGE_KEYWORDS:
6385
return token + "_"
6486
return token
6587

6688

89+
# This is a specialized method for hooks only. In addition to using
90+
# LANGUAGE_KEYWORDS (used by safe_reserved()), this function uses
91+
# HOOK_TARGET_KEYWORDS: the reason for having such a specialized
92+
# method is that since excluding `properties` will alter an affected
93+
# target's getters and setters (see this specific case explained in
94+
# comments for `HOOK_TARGET_KEYWORDS`), we do not want to have the
95+
# same behavior for resource type extensions, that you also model with
96+
# this plugin of the CloudFormation CLI.
97+
def safe_reserved_hook_target(token):
98+
if token in LANGUAGE_KEYWORDS or token in HOOK_TARGET_KEYWORDS:
99+
return token + "_"
100+
return token
101+
102+
67103
def validate_namespace(default):
68104
pattern = r"^[_a-z][_a-z0-9]+$"
69105

tests/test_utils.py

+9
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from rpdk.core.exceptions import WizardValidationError
55
from rpdk.java.utils import (
66
safe_reserved,
7+
safe_reserved_hook_target,
78
validate_codegen_model as validate_codegen_model_factory,
89
validate_namespace as validate_namespace_factory,
910
)
@@ -29,6 +30,14 @@ def test_safe_reserved_unsafe_string():
2930
assert safe_reserved("class") == "class_"
3031

3132

33+
def test_safe_reserved_hook_target_safe_string():
34+
assert safe_reserved_hook_target("foo") == "foo"
35+
36+
37+
def test_safe_reserved_hook_target_unsafe_string():
38+
assert safe_reserved_hook_target("properties") == "properties_"
39+
40+
3241
def test_validate_namespace_empty(validate_namespace):
3342
assert validate_namespace("") == DEFAULT
3443

0 commit comments

Comments
 (0)