Android: convert kEnumName to ENUM_NAME in java_cpp_enum.py.

Since the Blink rename, enum entry names now use the kCamelCase naming
convention instead of SHOUTY_CASE. This doesn't match well with Java
naming conventions and Java constants created by java_cpp_enum.py look
out of place with the rest of the Java codebase.

This CL modifies java_cpp_enum.py so that C++ enum naming conventions
don't leak into the Java side, specifically translating kCamelCase and
CamelCase enum entries to SHOUTY_CASE.

BUG=710335

Review-Url: https://codereview.chromium.org/2815103004
Cr-Original-Commit-Position: refs/heads/master@{#464661}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 23b8f65ce75fc2ff04a28cb5a940861c134e0797
This commit is contained in:
estevenson 2017-04-13 19:40:13 -07:00 коммит произвёл Commit bot
Родитель d9f7991400
Коммит 0875ea1284
2 изменённых файлов: 177 добавлений и 4 удалений

Просмотреть файл

@ -54,6 +54,7 @@ class EnumDefinition(object):
self._Validate()
self._AssignEntryIndices()
self._StripPrefix()
self._NormalizeNames()
def _Validate(self):
assert self.class_name
@ -92,10 +93,10 @@ class EnumDefinition(object):
def StripEntries(entries):
ret = collections.OrderedDict()
for (k, v) in entries.iteritems():
for k, v in entries.iteritems():
stripped_key = k.replace(prefix_to_strip, '', 1)
if isinstance(v, basestring):
stripped_value = v.replace(prefix_to_strip, '', 1)
stripped_value = v.replace(prefix_to_strip, '')
else:
stripped_value = v
ret[stripped_key] = stripped_value
@ -105,6 +106,44 @@ class EnumDefinition(object):
self.entries = StripEntries(self.entries)
self.comments = StripEntries(self.comments)
def _NormalizeNames(self):
self.entries = _TransformKeys(self.entries, _KCamelToShouty)
self.comments = _TransformKeys(self.comments, _KCamelToShouty)
def _TransformKeys(d, func):
"""Normalize keys in |d| and update references to old keys in |d| values."""
normal_keys = {k: func(k) for k in d}
ret = collections.OrderedDict()
for k, v in d.iteritems():
# Need to transform values as well when the entry value was explicitly set
# (since it could contain references to other enum entry values).
if isinstance(v, basestring):
for normal_key in normal_keys:
v = v.replace(normal_key, normal_keys[normal_key])
ret[normal_keys[k]] = v
return ret
def _KCamelToShouty(s):
"""Convert |s| from kCamelCase or CamelCase to SHOUTY_CASE.
kFooBar -> FOO_BAR
FooBar -> FOO_BAR
FooBAR9 -> FOO_BAR9
FooBARBaz -> FOO_BAR_BAZ
"""
if not re.match(r'^k?([A-Z][^A-Z]+|[A-Z0-9]+)+$', s):
return s
# Strip the leading k.
s = re.sub(r'^k', '', s)
# Add _ between title words and anything else.
s = re.sub(r'([^_])([A-Z][^A-Z_0-9]+)', r'\1_\2', s)
# Add _ between lower -> upper transitions.
s = re.sub(r'([^A-Z_0-9])([A-Z])', r'\1_\2', s)
return s.upper()
class DirectiveSet(object):
class_name_override_key = 'CLASS_NAME_OVERRIDE'
enum_package_key = 'ENUM_PACKAGE'

Просмотреть файл

@ -97,9 +97,16 @@ public @interface ClassName {
VALUE_ZERO = 1 << 0,
VALUE_ONE = 1 << 1,
};
// GENERATED_JAVA_ENUM_PACKAGE: test.namespace
enum EnumName {
ENUM_NAME_ZERO = 1 << 0,
ENUM_NAME_ONE = 1 << 1,
ENUM_NAME_TWO = ENUM_NAME_ZERO | ENUM_NAME_ONE,
};
""".split('\n')
definitions = HeaderParser(test_data).ParseDefinitions()
self.assertEqual(1, len(definitions))
self.assertEqual(2, len(definitions))
definition = definitions[0]
self.assertEqual('EnumName', definition.class_name)
self.assertEqual('test.namespace', definition.enum_package)
@ -107,6 +114,13 @@ public @interface ClassName {
('VALUE_ONE', '1 << 1')]),
definition.entries)
definition = definitions[1]
expected_entries = collections.OrderedDict([
('ZERO', '1 << 0'),
('ONE', '1 << 1'),
('TWO', 'ZERO | ONE')])
self.assertEqual(expected_entries, definition.entries)
def testParseMultilineEnumEntry(self):
test_data = """
// GENERATED_JAVA_ENUM_PACKAGE: bar.namespace
@ -289,6 +303,26 @@ public @interface ClassName {
('B', 1)]),
definition.entries)
def testParseWithStrippingAndRelativeReferences(self):
test_data = """
// GENERATED_JAVA_ENUM_PACKAGE: other.package
// GENERATED_JAVA_PREFIX_TO_STRIP: P_
enum EnumTwo {
P_A = 1,
// P_A is old-don't use P_A.
P_B = P_A,
};
""".split('\n')
definitions = HeaderParser(test_data).ParseDefinitions()
definition = definitions[0]
self.assertEqual('EnumTwo', definition.class_name)
self.assertEqual('other.package', definition.enum_package)
self.assertEqual(collections.OrderedDict([('A', '1'),
('B', 'A')]),
definition.entries)
self.assertEqual(collections.OrderedDict([('B', 'A is old-don\'t use A.')]),
definition.comments)
def testParseSingleLineAndRegularEnum(self):
test_data = """
// GENERATED_JAVA_ENUM_PACKAGE: test.namespace
@ -311,7 +345,7 @@ public @interface ClassName {
definition = definitions[0]
self.assertEqual(
collections.OrderedDict([('A', '1'), ('B', 'A')]), definition.entries)
self.assertEqual(collections.OrderedDict([('ENUM_ONE_B', 'Comment there')]),
self.assertEqual(collections.OrderedDict([('B', 'Comment there')]),
definition.comments)
self.assertEqual(3, len(definitions))
@ -322,6 +356,106 @@ public @interface ClassName {
definition = definitions[2]
self.assertEqual(collections.OrderedDict([('FOO', 0)]), definition.entries)
def testParseWithCamelCaseNames(self):
test_data = """
// GENERATED_JAVA_ENUM_PACKAGE: test.namespace
enum EnumTest {
EnumTestA = 1,
// comment for EnumTestB.
EnumTestB = 2,
};
// GENERATED_JAVA_ENUM_PACKAGE: test.namespace
// GENERATED_JAVA_PREFIX_TO_STRIP: Test
enum AnEnum {
TestHTTPOption,
TestHTTPSOption,
};
""".split('\n')
definitions = HeaderParser(test_data).ParseDefinitions()
definition = definitions[0]
self.assertEqual(
collections.OrderedDict([('ENUM_TEST_A', '1'), ('ENUM_TEST_B', '2')]),
definition.entries)
self.assertEqual(
collections.OrderedDict([('ENUM_TEST_B', 'comment for ENUM_TEST_B.')]),
definition.comments)
definition = definitions[1]
self.assertEqual(
collections.OrderedDict([('HTTP_OPTION', 0), ('HTTPS_OPTION', 1)]),
definition.entries)
def testParseWithKCamelCaseNames(self):
test_data = """
// GENERATED_JAVA_ENUM_PACKAGE: test.namespace
enum EnumOne {
kEnumOne = 1,
// comment for kEnumTwo.
kEnumTwo = 2,
};
// GENERATED_JAVA_ENUM_PACKAGE: test.namespace
// GENERATED_JAVA_CLASS_NAME_OVERRIDE: OverrideName
// GENERATED_JAVA_PREFIX_TO_STRIP: kEnumName
enum EnumName {
kEnumNameFoo,
kEnumNameBar
};
// GENERATED_JAVA_ENUM_PACKAGE: test.namespace
enum EnumName {
kEnumNameFoo,
kEnumBar,
};
// GENERATED_JAVA_ENUM_PACKAGE: test.namespace
enum Keys {
kSymbolKey = 1 << 0,
kAltKey = 1 << 1,
kUpKey = 1 << 2,
kKeyModifiers = kSymbolKey | kAltKey | kUpKey | kKeyModifiers,
};
// GENERATED_JAVA_ENUM_PACKAGE: test.namespace
enum Mixed {
kTestVal,
kCodecMPEG2
};
""".split('\n')
definitions = HeaderParser(test_data).ParseDefinitions()
definition = definitions[0]
self.assertEqual(
collections.OrderedDict([('ENUM_ONE', '1'), ('ENUM_TWO', '2')]),
definition.entries)
self.assertEqual(
collections.OrderedDict([('ENUM_TWO', 'comment for ENUM_TWO.')]),
definition.comments)
definition = definitions[1]
self.assertEqual(
collections.OrderedDict([('FOO', 0), ('BAR', 1)]),
definition.entries)
definition = definitions[2]
self.assertEqual(
collections.OrderedDict([('ENUM_NAME_FOO', 0), ('ENUM_BAR', 1)]),
definition.entries)
definition = definitions[3]
expected_entries = collections.OrderedDict([
('SYMBOL_KEY', '1 << 0'),
('ALT_KEY', '1 << 1'),
('UP_KEY', '1 << 2'),
('KEY_MODIFIERS', 'SYMBOL_KEY | ALT_KEY | UP_KEY | KEY_MODIFIERS')])
self.assertEqual(expected_entries, definition.entries)
definition = definitions[4]
self.assertEqual(
collections.OrderedDict([('TEST_VAL', 0), ('CODEC_MPEG2', 1)]),
definition.entries)
def testParseThrowsOnUnknownDirective(self):
test_data = """
// GENERATED_JAVA_UNKNOWN: Value