diff options
author | mkosiba <mkosiba@chromium.org> | 2014-10-23 06:56:12 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-23 13:56:31 +0000 |
commit | dfdc7fb2bcde7ea4a9458967fdc5f7fa15abb3fa (patch) | |
tree | 70e58f32dc972dfcd31539a1cb50229e86599cc0 /build/android/gyp | |
parent | 4c3b98b5113ac2cd47be3cbe747f414d6f9df09f (diff) | |
download | chromium_src-dfdc7fb2bcde7ea4a9458967fdc5f7fa15abb3fa.zip chromium_src-dfdc7fb2bcde7ea4a9458967fdc5f7fa15abb3fa.tar.gz chromium_src-dfdc7fb2bcde7ea4a9458967fdc5f7fa15abb3fa.tar.bz2 |
Final step of the java_cpp_template -> java_cpp_enum migration.
This CL migrates the remaining gyp/gn rules away from the
java_cpp_template rule.
BUG=405532
Review URL: https://codereview.chromium.org/659493003
Cr-Commit-Position: refs/heads/master@{#300881}
Diffstat (limited to 'build/android/gyp')
-rwxr-xr-x | build/android/gyp/java_cpp_enum.py | 94 | ||||
-rwxr-xr-x | build/android/gyp/java_cpp_enum_tests.py | 138 |
2 files changed, 186 insertions, 46 deletions
diff --git a/build/android/gyp/java_cpp_enum.py b/build/android/gyp/java_cpp_enum.py index 6a1d5c1..8ae5f36 100755 --- a/build/android/gyp/java_cpp_enum.py +++ b/build/android/gyp/java_cpp_enum.py @@ -14,17 +14,23 @@ import sys from util import build_utils class EnumDefinition(object): - def __init__(self, class_name=None, class_package=None, entries=None): - self.class_name = class_name - self.class_package = class_package + def __init__(self, original_enum_name=None, class_name_override=None, + enum_package=None, entries=None): + self.original_enum_name = original_enum_name + self.class_name_override = class_name_override + self.enum_package = enum_package self.entries = collections.OrderedDict(entries or []) - self.prefix_to_strip = '' + self.prefix_to_strip = None def AppendEntry(self, key, value): if key in self.entries: raise Exception('Multiple definitions of key %s found.' % key) self.entries[key] = value + @property + def class_name(self): + return self.class_name_override or self.original_enum_name + def Finalize(self): self._Validate() self._AssignEntryIndices() @@ -32,7 +38,7 @@ class EnumDefinition(object): def _Validate(self): assert self.class_name - assert self.class_package + assert self.enum_package assert self.entries def _AssignEntryIndices(self): @@ -54,23 +60,59 @@ class EnumDefinition(object): def _StripPrefix(self): - if not self.prefix_to_strip: - prefix_to_strip = re.sub('(?!^)([A-Z]+)', r'_\1', self.class_name).upper() + prefix_to_strip = self.prefix_to_strip + if not prefix_to_strip: + prefix_to_strip = self.original_enum_name + prefix_to_strip = re.sub('(?!^)([A-Z]+)', r'_\1', prefix_to_strip).upper() prefix_to_strip += '_' if not all([w.startswith(prefix_to_strip) for w in self.entries.keys()]): prefix_to_strip = '' - else: - prefix_to_strip = self.prefix_to_strip - entries = ((k.replace(prefix_to_strip, '', 1), v) for (k, v) in - self.entries.iteritems()) - self.entries = collections.OrderedDict(entries) + + entries = collections.OrderedDict() + for (k, v) in self.entries.iteritems(): + stripped_key = k.replace(prefix_to_strip, '', 1) + if isinstance(v, basestring): + stripped_value = v.replace(prefix_to_strip, '', 1) + else: + stripped_value = v + entries[stripped_key] = stripped_value + + self.entries = entries + +class DirectiveSet(object): + class_name_override_key = 'CLASS_NAME_OVERRIDE' + enum_package_key = 'ENUM_PACKAGE' + prefix_to_strip_key = 'PREFIX_TO_STRIP' + + known_keys = [class_name_override_key, enum_package_key, prefix_to_strip_key] + + def __init__(self): + self._directives = {} + + def Update(self, key, value): + if key not in DirectiveSet.known_keys: + raise Exception("Unknown directive: " + key) + self._directives[key] = value + + @property + def empty(self): + return len(self._directives) == 0 + + def UpdateDefinition(self, definition): + definition.class_name_override = self._directives.get( + DirectiveSet.class_name_override_key, '') + definition.enum_package = self._directives.get( + DirectiveSet.enum_package_key) + definition.prefix_to_strip = self._directives.get( + DirectiveSet.prefix_to_strip_key) + class HeaderParser(object): single_line_comment_re = re.compile(r'\s*//') multi_line_comment_start_re = re.compile(r'\s*/\*') enum_start_re = re.compile(r'^\s*enum\s+(\w+)\s+{\s*$') enum_line_re = re.compile(r'^\s*(\w+)(\s*\=\s*([^,\n]+))?,?') - enum_end_re = re.compile(r'^\s*}\s*;\s*$') + enum_end_re = re.compile(r'^\s*}\s*;\.*$') generator_directive_re = re.compile( r'^\s*//\s+GENERATED_JAVA_(\w+)\s*:\s*([\.\w]+)$') @@ -79,7 +121,7 @@ class HeaderParser(object): self._enum_definitions = [] self._in_enum = False self._current_definition = None - self._generator_directives = {} + self._generator_directives = DirectiveSet() def ParseDefinitions(self): for line in self._lines: @@ -109,31 +151,23 @@ class HeaderParser(object): enum_value = enum_entry.groups()[2] self._current_definition.AppendEntry(enum_key, enum_value) - def _GetCurrentEnumPackageName(self): - return self._generator_directives.get('ENUM_PACKAGE') - - def _GetCurrentEnumPrefixToStrip(self): - return self._generator_directives.get('PREFIX_TO_STRIP', '') - def _ApplyGeneratorDirectives(self): - current_definition = self._current_definition - current_definition.class_package = self._GetCurrentEnumPackageName() - current_definition.prefix_to_strip = self._GetCurrentEnumPrefixToStrip() - self._generator_directives = {} + self._generator_directives.UpdateDefinition(self._current_definition) + self._generator_directives = DirectiveSet() def _ParseRegularLine(self, line): enum_start = HeaderParser.enum_start_re.match(line) generator_directive = HeaderParser.generator_directive_re.match(line) if enum_start: - if not self._GetCurrentEnumPackageName(): + if self._generator_directives.empty: return - self._current_definition = EnumDefinition() - self._current_definition.class_name = enum_start.groups()[0] + self._current_definition = EnumDefinition( + original_enum_name=enum_start.groups()[0]) self._in_enum = True elif generator_directive: directive_name = generator_directive.groups()[0] directive_value = generator_directive.groups()[1] - self._generator_directives[directive_name] = directive_value + self._generator_directives.Update(directive_name, directive_value) def GetScriptName(): @@ -147,7 +181,7 @@ def DoGenerate(options, source_paths): for source_path in source_paths: enum_definitions = DoParseHeaderFile(source_path) for enum_definition in enum_definitions: - package_path = enum_definition.class_package.replace('.', os.path.sep) + package_path = enum_definition.enum_package.replace('.', os.path.sep) file_name = enum_definition.class_name + '.java' output_path = os.path.join(options.output_dir, package_path, file_name) output_paths.append(output_path) @@ -193,7 +227,7 @@ ${ENUM_ENTRIES} values = { 'CLASS_NAME': enum_definition.class_name, 'ENUM_ENTRIES': enum_entries_string, - 'PACKAGE': enum_definition.class_package, + 'PACKAGE': enum_definition.enum_package, 'SCRIPT_NAME': GetScriptName(), 'SOURCE_PATH': source_path, } diff --git a/build/android/gyp/java_cpp_enum_tests.py b/build/android/gyp/java_cpp_enum_tests.py index 24da05f..bb8150d 100755 --- a/build/android/gyp/java_cpp_enum_tests.py +++ b/build/android/gyp/java_cpp_enum_tests.py @@ -9,13 +9,20 @@ This test suite containss various tests for the C++ -> Java enum generator. """ import collections +import optparse +import os +import sys import unittest + from java_cpp_enum import EnumDefinition, GenerateOutput, HeaderParser +sys.path.append(os.path.join(os.path.dirname(__file__), "gyp")) +from util import build_utils + class TestPreprocess(unittest.TestCase): def testOutput(self): - definition = EnumDefinition(class_name='ClassName', - class_package='some.package', + definition = EnumDefinition(original_enum_name='ClassName', + enum_package='some.package', entries=[('E1', 1), ('E2', '2 << 2')]) output = GenerateOutput('path/to/file', definition) expected = """ @@ -49,11 +56,54 @@ public class ClassName { self.assertEqual(1, len(definitions)) definition = definitions[0] self.assertEqual('EnumName', definition.class_name) - self.assertEqual('test.namespace', definition.class_package) + self.assertEqual('test.namespace', definition.enum_package) self.assertEqual(collections.OrderedDict([('VALUE_ZERO', 0), ('VALUE_ONE', 1)]), definition.entries) + def testParseBitShifts(self): + test_data = """ + // GENERATED_JAVA_ENUM_PACKAGE: test.namespace + enum EnumName { + VALUE_ZERO = 1 << 0, + VALUE_ONE = 1 << 1, + }; + """.split('\n') + definitions = HeaderParser(test_data).ParseDefinitions() + self.assertEqual(1, len(definitions)) + definition = definitions[0] + self.assertEqual('EnumName', definition.class_name) + self.assertEqual('test.namespace', definition.enum_package) + self.assertEqual(collections.OrderedDict([('VALUE_ZERO', '1 << 0'), + ('VALUE_ONE', '1 << 1')]), + definition.entries) + + def testParseClassNameOverride(self): + test_data = """ + // GENERATED_JAVA_ENUM_PACKAGE: test.namespace + // GENERATED_JAVA_CLASS_NAME_OVERRIDE: OverrideName + enum EnumName { + FOO + }; + + // GENERATED_JAVA_ENUM_PACKAGE: test.namespace + // GENERATED_JAVA_CLASS_NAME_OVERRIDE: OtherOverride + enum PrefixTest { + PREFIX_TEST_A, + PREFIX_TEST_B, + }; + """.split('\n') + definitions = HeaderParser(test_data).ParseDefinitions() + self.assertEqual(2, len(definitions)) + definition = definitions[0] + self.assertEqual('OverrideName', definition.class_name) + + definition = definitions[1] + self.assertEqual('OtherOverride', definition.class_name) + self.assertEqual(collections.OrderedDict([('A', 0), + ('B', 1)]), + definition.entries) + def testParseTwoEnums(self): test_data = """ // GENERATED_JAVA_ENUM_PACKAGE: test.namespace @@ -78,20 +128,30 @@ public class ClassName { self.assertEqual(2, len(definitions)) definition = definitions[0] self.assertEqual('EnumOne', definition.class_name) - self.assertEqual('test.namespace', definition.class_package) + self.assertEqual('test.namespace', definition.enum_package) self.assertEqual(collections.OrderedDict([('A', '1'), ('B', 'A')]), definition.entries) definition = definitions[1] self.assertEqual('EnumTwo', definition.class_name) - self.assertEqual('other.package', definition.class_package) + self.assertEqual('other.package', definition.enum_package) self.assertEqual(collections.OrderedDict([('A', 0), ('B', 1)]), definition.entries) + def testParseThrowsOnUnknownDirective(self): + test_data = """ + // GENERATED_JAVA_UNKNOWN: Value + enum EnumName { + VALUE_ONE, + }; + """.split('\n') + with self.assertRaises(Exception): + HeaderParser(test_data).ParseDefinitions() + def testEnumValueAssignmentNoneDefined(self): - definition = EnumDefinition('c', 'p', []) + definition = EnumDefinition(original_enum_name='c', enum_package='p') definition.AppendEntry('A', None) definition.AppendEntry('B', None) definition.AppendEntry('C', None) @@ -102,7 +162,7 @@ public class ClassName { definition.entries) def testEnumValueAssignmentAllDefined(self): - definition = EnumDefinition('c', 'p', []) + definition = EnumDefinition(original_enum_name='c', enum_package='p') definition.AppendEntry('A', '1') definition.AppendEntry('B', '2') definition.AppendEntry('C', '3') @@ -113,7 +173,7 @@ public class ClassName { definition.entries) def testEnumValueAssignmentReferences(self): - definition = EnumDefinition('c', 'p', []) + definition = EnumDefinition(original_enum_name='c', enum_package='p') definition.AppendEntry('A', None) definition.AppendEntry('B', 'A') definition.AppendEntry('C', None) @@ -125,39 +185,85 @@ public class ClassName { ('D', 1)]), definition.entries) + def testEnumValueAssignmentSet(self): + definition = EnumDefinition(original_enum_name='c', enum_package='p') + definition.AppendEntry('A', None) + definition.AppendEntry('B', '2') + definition.AppendEntry('C', None) + definition.Finalize() + self.assertEqual(collections.OrderedDict([('A', 0), + ('B', 2), + ('C', 3)]), + definition.entries) + + def testEnumValueAssignmentSetReferences(self): + definition = EnumDefinition(original_enum_name='c', enum_package='p') + definition.AppendEntry('A', None) + definition.AppendEntry('B', 'A') + definition.AppendEntry('C', 'B') + definition.AppendEntry('D', None) + definition.Finalize() + self.assertEqual(collections.OrderedDict([('A', 0), + ('B', 0), + ('C', 0), + ('D', 1)]), + definition.entries) + def testEnumValueAssignmentRaises(self): - definition = EnumDefinition('c', 'p', []) + definition = EnumDefinition(original_enum_name='c', enum_package='p') definition.AppendEntry('A', None) - definition.AppendEntry('B', '1') + definition.AppendEntry('B', 'foo') definition.AppendEntry('C', None) with self.assertRaises(Exception): definition.Finalize() def testExplicitPrefixStripping(self): - definition = EnumDefinition('c', 'p', []) + definition = EnumDefinition(original_enum_name='c', enum_package='p') definition.AppendEntry('P_A', None) definition.AppendEntry('B', None) definition.AppendEntry('P_C', None) + definition.AppendEntry('P_LAST', 'P_C') definition.prefix_to_strip = 'P_' definition.Finalize() - self.assertEqual(['A', 'B', 'C'], definition.entries.keys()) + self.assertEqual(collections.OrderedDict([('A', 0), + ('B', 1), + ('C', 2), + ('LAST', 2)]), + definition.entries) def testImplicitPrefixStripping(self): - definition = EnumDefinition('ClassName', 'p', []) + definition = EnumDefinition(original_enum_name='ClassName', + enum_package='p') definition.AppendEntry('CLASS_NAME_A', None) definition.AppendEntry('CLASS_NAME_B', None) definition.AppendEntry('CLASS_NAME_C', None) + definition.AppendEntry('CLASS_NAME_LAST', 'CLASS_NAME_C') definition.Finalize() - self.assertEqual(['A', 'B', 'C'], definition.entries.keys()) + self.assertEqual(collections.OrderedDict([('A', 0), + ('B', 1), + ('C', 2), + ('LAST', 2)]), + definition.entries) def testImplicitPrefixStrippingRequiresAllConstantsToBePrefixed(self): - definition = EnumDefinition('Name', 'p', []) + definition = EnumDefinition(original_enum_name='Name', + enum_package='p') definition.AppendEntry('A', None) definition.AppendEntry('B', None) definition.AppendEntry('NAME_LAST', None) definition.Finalize() self.assertEqual(['A', 'B', 'NAME_LAST'], definition.entries.keys()) +def main(argv): + parser = optparse.OptionParser() + parser.add_option("--stamp", help="File to touch on success.") + options, _ = parser.parse_args(argv) + + suite = unittest.TestLoader().loadTestsFromTestCase(TestPreprocess) + unittest.TextTestRunner(verbosity=0).run(suite) + + if options.stamp: + build_utils.Touch(options.stamp) if __name__ == '__main__': - unittest.main() + main(sys.argv[1:]) |